|
@@ -20,17 +20,14 @@
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<a-card :bordered="false" class="status-card">
|
|
<a-card :bordered="false" class="status-card">
|
|
|
- <a-steps
|
|
|
|
|
|
|
+ <OrderProgressSteps
|
|
|
|
|
+ class="steps"
|
|
|
|
|
+ :mobile="isMobile"
|
|
|
:current="stepCurrent"
|
|
:current="stepCurrent"
|
|
|
:status="stepStatus"
|
|
:status="stepStatus"
|
|
|
- direction="horizontal"
|
|
|
|
|
- label-placement="vertical"
|
|
|
|
|
- class="steps"
|
|
|
|
|
- >
|
|
|
|
|
- <a-step :description="displayStepDescriptions[0]">{{ stepLabels[0] }}</a-step>
|
|
|
|
|
- <a-step :description="displayStepDescriptions[1]">{{ stepLabels[1] }}</a-step>
|
|
|
|
|
- <a-step :description="displayStepDescriptions[2]">{{ stepLabels[2] }}</a-step>
|
|
|
|
|
- </a-steps>
|
|
|
|
|
|
|
+ :labels="stepLabels"
|
|
|
|
|
+ :descriptions="stepDescriptions"
|
|
|
|
|
+ />
|
|
|
<div class="status-badge-wrap">
|
|
<div class="status-badge-wrap">
|
|
|
<OrderStateTag :state="data?.state ?? 0" />
|
|
<OrderStateTag :state="data?.state ?? 0" />
|
|
|
</div>
|
|
</div>
|
|
@@ -85,6 +82,7 @@ import { orderDeatil } from '@/api/order'
|
|
|
import { useRoute } from 'vue-router'
|
|
import { useRoute } from 'vue-router'
|
|
|
import { Notification, Message } from '@arco-design/web-vue'
|
|
import { Notification, Message } from '@arco-design/web-vue'
|
|
|
import OrderStateTag from '@/components/store/OrderStateTag.vue'
|
|
import OrderStateTag from '@/components/store/OrderStateTag.vue'
|
|
|
|
|
+import OrderProgressSteps from '@/components/store/OrderProgressSteps.vue'
|
|
|
import {
|
|
import {
|
|
|
formatStoreTimeFull,
|
|
formatStoreTimeFull,
|
|
|
getPayTypeLabel,
|
|
getPayTypeLabel,
|
|
@@ -108,12 +106,9 @@ const stepCurrent = ref(1)
|
|
|
const stepStatus = ref('process')
|
|
const stepStatus = ref('process')
|
|
|
const stepLabels = ref(['待支付', '待处理', '已完成'])
|
|
const stepLabels = ref(['待支付', '待处理', '已完成'])
|
|
|
const stepDescriptions = ref(['', '', ''])
|
|
const stepDescriptions = ref(['', '', ''])
|
|
|
-const displayStepDescriptions = computed(() =>
|
|
|
|
|
- isMobile.value ? ['', '', ''] : stepDescriptions.value
|
|
|
|
|
-)
|
|
|
|
|
-
|
|
|
|
|
const PAY_TIMEOUT_SEC = 300
|
|
const PAY_TIMEOUT_SEC = 300
|
|
|
-let timer = null
|
|
|
|
|
|
|
+let pollTimer = null
|
|
|
|
|
+let countdownTimer = null
|
|
|
let resizeHandler = null
|
|
let resizeHandler = null
|
|
|
|
|
|
|
|
const updateStepState = () => {
|
|
const updateStepState = () => {
|
|
@@ -126,25 +121,26 @@ const updateStepState = () => {
|
|
|
stepStatus.value = 'process'
|
|
stepStatus.value = 'process'
|
|
|
stepLabels.value = ['待支付', '待处理', '已完成']
|
|
stepLabels.value = ['待支付', '待处理', '已完成']
|
|
|
updatePaymentCountdown()
|
|
updatePaymentCountdown()
|
|
|
|
|
+ startCountdownTicker()
|
|
|
break
|
|
break
|
|
|
case 1:
|
|
case 1:
|
|
|
stepCurrent.value = 2
|
|
stepCurrent.value = 2
|
|
|
stepStatus.value = 'process'
|
|
stepStatus.value = 'process'
|
|
|
stepDescriptions.value[1] = '支付成功,等待系统处理'
|
|
stepDescriptions.value[1] = '支付成功,等待系统处理'
|
|
|
- stopPolling()
|
|
|
|
|
|
|
+ stopPendingOrderTimers()
|
|
|
break
|
|
break
|
|
|
case 2:
|
|
case 2:
|
|
|
stepCurrent.value = 3
|
|
stepCurrent.value = 3
|
|
|
stepStatus.value = 'finish'
|
|
stepStatus.value = 'finish'
|
|
|
stepDescriptions.value[2] = '权益已发放至账户'
|
|
stepDescriptions.value[2] = '权益已发放至账户'
|
|
|
- stopPolling()
|
|
|
|
|
|
|
+ stopPendingOrderTimers()
|
|
|
break
|
|
break
|
|
|
case 3:
|
|
case 3:
|
|
|
stepCurrent.value = 1
|
|
stepCurrent.value = 1
|
|
|
stepStatus.value = 'error'
|
|
stepStatus.value = 'error'
|
|
|
stepLabels.value = ['已关闭', '待处理', '已完成']
|
|
stepLabels.value = ['已关闭', '待处理', '已完成']
|
|
|
stepDescriptions.value[0] = '订单超时或已取消'
|
|
stepDescriptions.value[0] = '订单超时或已取消'
|
|
|
- stopPolling()
|
|
|
|
|
|
|
+ stopPendingOrderTimers()
|
|
|
break
|
|
break
|
|
|
default:
|
|
default:
|
|
|
break
|
|
break
|
|
@@ -191,9 +187,27 @@ const getOrderDetail = async () => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const startCountdownTicker = () => {
|
|
|
|
|
+ if (countdownTimer) return
|
|
|
|
|
+ countdownTimer = setInterval(() => {
|
|
|
|
|
+ if (data.value?.state !== 0) {
|
|
|
|
|
+ stopCountdownTicker()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ updatePaymentCountdown()
|
|
|
|
|
+ }, 1000)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const stopCountdownTicker = () => {
|
|
|
|
|
+ if (countdownTimer) {
|
|
|
|
|
+ clearInterval(countdownTimer)
|
|
|
|
|
+ countdownTimer = null
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
const startPolling = () => {
|
|
const startPolling = () => {
|
|
|
- if (timer) return
|
|
|
|
|
- timer = setInterval(async () => {
|
|
|
|
|
|
|
+ if (pollTimer) return
|
|
|
|
|
+ pollTimer = setInterval(async () => {
|
|
|
if (data.value?.state !== 0) {
|
|
if (data.value?.state !== 0) {
|
|
|
stopPolling()
|
|
stopPolling()
|
|
|
return
|
|
return
|
|
@@ -203,12 +217,17 @@ const startPolling = () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const stopPolling = () => {
|
|
const stopPolling = () => {
|
|
|
- if (timer) {
|
|
|
|
|
- clearInterval(timer)
|
|
|
|
|
- timer = null
|
|
|
|
|
|
|
+ if (pollTimer) {
|
|
|
|
|
+ clearInterval(pollTimer)
|
|
|
|
|
+ pollTimer = null
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const stopPendingOrderTimers = () => {
|
|
|
|
|
+ stopCountdownTicker()
|
|
|
|
|
+ stopPolling()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
|
const syncMobile = () => {
|
|
const syncMobile = () => {
|
|
|
isMobile.value = window.innerWidth <= 768
|
|
isMobile.value = window.innerWidth <= 768
|
|
@@ -223,7 +242,7 @@ onMounted(async () => {
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
onUnmounted(() => {
|
|
|
- stopPolling()
|
|
|
|
|
|
|
+ stopPendingOrderTimers()
|
|
|
if (resizeHandler) window.removeEventListener('resize', resizeHandler)
|
|
if (resizeHandler) window.removeEventListener('resize', resizeHandler)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
@@ -313,11 +332,6 @@ function openPaymentWindow(payUrl, formData) {
|
|
|
box-shadow: @store-shadow;
|
|
box-shadow: @store-shadow;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.steps {
|
|
|
|
|
- max-width: 100%;
|
|
|
|
|
- margin: 8px 0 16px;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
.status-badge-wrap {
|
|
.status-badge-wrap {
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
}
|
|
}
|
|
@@ -361,35 +375,6 @@ function openPaymentWindow(payUrl, formData) {
|
|
|
padding: 14px 12px;
|
|
padding: 14px 12px;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- .steps {
|
|
|
|
|
- margin: 4px 0 10px;
|
|
|
|
|
- overflow: visible;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .steps :deep(.arco-steps-item) {
|
|
|
|
|
- flex: 1 1 0;
|
|
|
|
|
- min-width: 0;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .steps :deep(.arco-steps-item-content) {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- flex-direction: column;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
- text-align: center;
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- min-width: 0;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .steps :deep(.arco-steps-item-title) {
|
|
|
|
|
- font-size: 11px;
|
|
|
|
|
- white-space: nowrap;
|
|
|
|
|
- text-align: center;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .steps :deep(.arco-steps-item-description) {
|
|
|
|
|
- display: none;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
.detail-actions {
|
|
.detail-actions {
|
|
|
display: grid;
|
|
display: grid;
|
|
|
grid-template-columns: 1fr;
|
|
grid-template-columns: 1fr;
|