|
@@ -2,7 +2,7 @@
|
|
{
|
|
{
|
|
layout: 'default',
|
|
layout: 'default',
|
|
style: {
|
|
style: {
|
|
- navigationBarTitleText: 'My Orders',
|
|
|
|
|
|
+ navigationBarTitleText: '%orderDetail.title%',
|
|
navigationBarBackgroundColor: '#fff',
|
|
navigationBarBackgroundColor: '#fff',
|
|
},
|
|
},
|
|
}
|
|
}
|
|
@@ -13,13 +13,15 @@ import { getConfigByCode } from '@/api/common'
|
|
import { orderCancel, orderDetail, orderPink, orderStatusEnum, payOrder } from '@/api/order'
|
|
import { orderCancel, orderDetail, orderPink, orderStatusEnum, payOrder } from '@/api/order'
|
|
import DialogBox from '@/components/DialogBox/DialogBox.vue'
|
|
import DialogBox from '@/components/DialogBox/DialogBox.vue'
|
|
import { DialogUtils } from '@/components/DialogBox/utils'
|
|
import { DialogUtils } from '@/components/DialogBox/utils'
|
|
|
|
+import { t } from '@/locale'
|
|
import { formatNumber } from '@/utils'
|
|
import { formatNumber } from '@/utils'
|
|
import { getPageParams, toPage } from '@/utils/page'
|
|
import { getPageParams, toPage } from '@/utils/page'
|
|
-import { toast } from '@/utils/toast'
|
|
|
|
|
|
+import { showToast, toast } from '@/utils/toast'
|
|
|
|
|
|
defineOptions({
|
|
defineOptions({
|
|
name: 'OrderDetail', // 订单详情
|
|
name: 'OrderDetail', // 订单详情
|
|
})
|
|
})
|
|
|
|
+
|
|
// z-paging
|
|
// z-paging
|
|
const paging = ref(null)
|
|
const paging = ref(null)
|
|
|
|
|
|
@@ -28,6 +30,8 @@ const detail = ref<any>({})
|
|
const orderStatusEnumData = ref<any>([])
|
|
const orderStatusEnumData = ref<any>([])
|
|
const openRedEnvelopeRate = ref<any>()
|
|
const openRedEnvelopeRate = ref<any>()
|
|
const joinRedEnvelopeRate = ref<any>()
|
|
const joinRedEnvelopeRate = ref<any>()
|
|
|
|
+const countdown = ref('00:00')
|
|
|
|
+const timer = ref()
|
|
|
|
|
|
// DialogBox 函数式调用配置
|
|
// DialogBox 函数式调用配置
|
|
const dialogConfig = ref<any>({})
|
|
const dialogConfig = ref<any>({})
|
|
@@ -64,21 +68,58 @@ async function getOrderStatus() {
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+function startCountdown() {
|
|
|
|
+ // 清除之前的定时器
|
|
|
|
+ if (timer.value)
|
|
|
|
+ clearInterval(timer.value)
|
|
|
|
+
|
|
|
|
+ if (!detail.value?.createTime || detail.value?.status !== 1) {
|
|
|
|
+ countdown.value = '00:00'
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 计算过期时间(创建时间 + 20分钟)
|
|
|
|
+ const createTime = new Date(detail.value.createTime).getTime()
|
|
|
|
+ const expireTime = createTime + 20 * 60 * 1000
|
|
|
|
+
|
|
|
|
+ timer.value = setInterval(() => {
|
|
|
|
+ const now = Date.now()
|
|
|
|
+ const diff = expireTime - now
|
|
|
|
+
|
|
|
|
+ if (diff <= 0) {
|
|
|
|
+ clearInterval(timer.value)
|
|
|
|
+ countdown.value = '00:00'
|
|
|
|
+ getDetail() // 刷新订单状态
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const minutes = Math.floor(diff / 1000 / 60)
|
|
|
|
+ const seconds = Math.floor((diff / 1000) % 60)
|
|
|
|
+ countdown.value = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
|
|
|
|
+ }, 1000)
|
|
|
|
+}
|
|
|
|
+
|
|
async function getDetail() {
|
|
async function getDetail() {
|
|
- getPink()
|
|
|
|
|
|
+ uni.showLoading({
|
|
|
|
+ title: t('orderDetail.loading'),
|
|
|
|
+ })
|
|
try {
|
|
try {
|
|
const res = await orderDetail({ id: id.value })
|
|
const res = await orderDetail({ id: id.value })
|
|
if (res.code === '200') {
|
|
if (res.code === '200') {
|
|
detail.value = res.data
|
|
detail.value = res.data
|
|
|
|
+ startCountdown() // 开始倒计时
|
|
|
|
+ await getPink()
|
|
paging.value.complete()
|
|
paging.value.complete()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- catch {}
|
|
|
|
|
|
+ finally {
|
|
|
|
+ uni.hideLoading()
|
|
|
|
+ }
|
|
}
|
|
}
|
|
const pinkList = ref<any>([])
|
|
const pinkList = ref<any>([])
|
|
async function getPink() {
|
|
async function getPink() {
|
|
try {
|
|
try {
|
|
- const res = await orderPink({ id: id.value })
|
|
|
|
|
|
+ const res = await orderPink({ id: detail.value?.storePink?.id })
|
|
if (res.code === '200') {
|
|
if (res.code === '200') {
|
|
pinkList.value = res.data
|
|
pinkList.value = res.data
|
|
}
|
|
}
|
|
@@ -87,33 +128,23 @@ async function getPink() {
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-onLoad(async (options) => {
|
|
|
|
- getConfig('open_red_envelope_rate')
|
|
|
|
- getConfig('join_red_envelope_rate')
|
|
|
|
- const params = getPageParams(options)
|
|
|
|
- id.value = params.id
|
|
|
|
- await getOrderStatus()
|
|
|
|
-})
|
|
|
|
-onShow(() => {
|
|
|
|
- getDetail()
|
|
|
|
-})
|
|
|
|
|
|
|
|
// 跳转到地址簿选择地址
|
|
// 跳转到地址簿选择地址
|
|
function selectAddress() {
|
|
function selectAddress() {
|
|
toPage('/pages/mine/addressBook', {
|
|
toPage('/pages/mine/addressBook', {
|
|
selectMode: true,
|
|
selectMode: true,
|
|
- orderId: id.value,
|
|
|
|
|
|
+ orderId: detail.value?.orderId,
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
// 显示取消订单确认对话框
|
|
// 显示取消订单确认对话框
|
|
function showCancelOrderDialog() {
|
|
function showCancelOrderDialog() {
|
|
Object.assign(dialogConfig.value, DialogUtils.info(
|
|
Object.assign(dialogConfig.value, DialogUtils.info(
|
|
- 'Are you sure you want to cancel this order?',
|
|
|
|
|
|
+ t('orderDetail.dialog.cancel.title'),
|
|
{
|
|
{
|
|
showCancel: true,
|
|
showCancel: true,
|
|
- confirmText: 'Yes, Cancel',
|
|
|
|
- cancelText: 'Keep Order',
|
|
|
|
|
|
+ confirmText: t('orderDetail.dialog.cancel.confirm'),
|
|
|
|
+ cancelText: t('orderDetail.dialog.cancel.keep'),
|
|
},
|
|
},
|
|
))
|
|
))
|
|
}
|
|
}
|
|
@@ -122,27 +153,28 @@ function showCancelOrderDialog() {
|
|
async function cancelOrder() {
|
|
async function cancelOrder() {
|
|
try {
|
|
try {
|
|
uni.showLoading({
|
|
uni.showLoading({
|
|
- title: 'Cancelling order...',
|
|
|
|
|
|
+ title: t('orderDetail.cancel.loading'),
|
|
|
|
+ mask: true,
|
|
})
|
|
})
|
|
|
|
|
|
const res = await orderCancel({ id: id.value })
|
|
const res = await orderCancel({ id: id.value })
|
|
|
|
|
|
if (res.code === '200') {
|
|
if (res.code === '200') {
|
|
// 显示成功提示
|
|
// 显示成功提示
|
|
- toast.success('Order cancelled successfully!')
|
|
|
|
|
|
+ toast.success(t('orderDetail.cancel.success'))
|
|
|
|
|
|
// 刷新订单详情
|
|
// 刷新订单详情
|
|
getDetail()
|
|
getDetail()
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
// 显示错误提示
|
|
// 显示错误提示
|
|
- toast.error(res.message || 'Failed to cancel order. Please try again.')
|
|
|
|
|
|
+ toast.error(res.message || t('orderDetail.cancel.error'))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (error: any) {
|
|
catch (error: any) {
|
|
console.error('Cancel order error:', error)
|
|
console.error('Cancel order error:', error)
|
|
// 显示错误提示
|
|
// 显示错误提示
|
|
- toast.error('Network error. Please check your connection and try again.')
|
|
|
|
|
|
+ toast.error(t('orderDetail.cancel.network'))
|
|
}
|
|
}
|
|
finally {
|
|
finally {
|
|
uni.hideLoading()
|
|
uni.hideLoading()
|
|
@@ -176,50 +208,76 @@ async function handleClick() {
|
|
type: detail.value?.storePink?.kId ? 'open' : 'join',
|
|
type: detail.value?.storePink?.kId ? 'open' : 'join',
|
|
})
|
|
})
|
|
console.log(payRes)
|
|
console.log(payRes)
|
|
|
|
+ if (payRes.code === '200') {
|
|
|
|
+ showToast({
|
|
|
|
+ message: t('orderDetail.payment.success'),
|
|
|
|
+ icon: 'success',
|
|
|
|
+ })
|
|
|
|
+ getDetail()
|
|
|
|
+ }
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
// 去分享
|
|
// 去分享
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+const timeMap = {
|
|
|
|
+ create_order: 'placed on',
|
|
|
|
+ pay_success: 'paid on',
|
|
|
|
+ delivery: 'shipped on',
|
|
|
|
+ receive: 'completed on',
|
|
|
|
+}
|
|
|
|
+onLoad(async (options) => {
|
|
|
|
+ getConfig('open_red_envelope_rate')
|
|
|
|
+ getConfig('join_red_envelope_rate')
|
|
|
|
+ const params = getPageParams(options)
|
|
|
|
+ id.value = params.id
|
|
|
|
+ await getOrderStatus()
|
|
|
|
+})
|
|
|
|
+onShow(() => {
|
|
|
|
+ getDetail()
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+onUnmounted(() => {
|
|
|
|
+ if (timer.value)
|
|
|
|
+ clearInterval(timer.value)
|
|
|
|
+})
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<template>
|
|
<template>
|
|
<z-paging ref="paging" refresher-only @refresh="getDetail">
|
|
<z-paging ref="paging" refresher-only @refresh="getDetail">
|
|
<view class="pt-20rpx">
|
|
<view class="pt-20rpx">
|
|
<!-- 状态显示 -->
|
|
<!-- 状态显示 -->
|
|
- <template v-if="detail.status !== 4">
|
|
|
|
|
|
+ <template v-if="detail.status !== 4 && detail?.status !== 2">
|
|
<!-- 已中奖 -->
|
|
<!-- 已中奖 -->
|
|
<view v-if="detail?.storePink?.status === 2 && detail?.storePink?.lId === 1" class="mb-20rpx bg-#17AA68/80 py-20rpx text-center text-28rpx text-white">
|
|
<view v-if="detail?.storePink?.status === 2 && detail?.storePink?.lId === 1" class="mb-20rpx bg-#17AA68/80 py-20rpx text-center text-28rpx text-white">
|
|
- Congrats,You won the prize in this group!已中奖
|
|
|
|
|
|
+ {{ t('orderDetail.congrats') }}
|
|
<br>
|
|
<br>
|
|
- You have received
|
|
|
|
|
|
+ {{ t('orderDetail.receiveReward') }}
|
|
<text class="text-[var(--wot-color-theme)]">
|
|
<text class="text-[var(--wot-color-theme)]">
|
|
৳{{ 10 }}
|
|
৳{{ 10 }}
|
|
</text>
|
|
</text>
|
|
- group opening reward
|
|
|
|
</view>
|
|
</view>
|
|
<!-- 未中奖 -->
|
|
<!-- 未中奖 -->
|
|
<view v-else-if="detail?.storePink?.status === 2 && detail?.storePink?.lId === 0" class="mb-20rpx bg-#E61B28/80 py-20rpx text-center text-28rpx text-white">
|
|
<view v-else-if="detail?.storePink?.status === 2 && detail?.storePink?.lId === 0" class="mb-20rpx bg-#E61B28/80 py-20rpx text-center text-28rpx text-white">
|
|
- So sorry, You didn't win in this group
|
|
|
|
|
|
+ {{ t('orderDetail.sorry') }}
|
|
<br>
|
|
<br>
|
|
- You have received
|
|
|
|
|
|
+ {{ t('orderDetail.receiveReward') }}
|
|
<text class="text-#66C59B">
|
|
<text class="text-#66C59B">
|
|
৳8
|
|
৳8
|
|
</text>
|
|
</text>
|
|
- group opening reward
|
|
|
|
</view>
|
|
</view>
|
|
<!-- 未开奖||未支付 -->
|
|
<!-- 未开奖||未支付 -->
|
|
<view v-else-if="detail?.storePink?.status === 1 || detail?.status === 1" class="mb-20rpx bg-#fff py-20rpx text-center text-28rpx text-white">
|
|
<view v-else-if="detail?.storePink?.status === 1 || detail?.status === 1" class="mb-20rpx bg-#fff py-20rpx text-center text-28rpx text-white">
|
|
<text v-if="detail?.storePink?.status === 1 && detail?.status !== 1" class="text-[var(--wot-color-theme)]">
|
|
<text v-if="detail?.storePink?.status === 1 && detail?.status !== 1" class="text-[var(--wot-color-theme)]">
|
|
- Please wait for the draw of this group
|
|
|
|
|
|
+ {{ t('orderDetail.waiting') }}
|
|
</text>
|
|
</text>
|
|
<text v-else class="text-[var(--wot-color-theme)]">
|
|
<text v-else class="text-[var(--wot-color-theme)]">
|
|
- Please make payment within:29:59
|
|
|
|
|
|
+ {{ t('orderDetail.paymentCountdown') }} {{ countdown }}
|
|
</text>
|
|
</text>
|
|
</view>
|
|
</view>
|
|
<!-- 拼团头像 -->
|
|
<!-- 拼团头像 -->
|
|
- <view class="mb-20rpx bg-white px-20rpx py-20rpx text-center">
|
|
|
|
- <image v-for="i in 10" :key="i" class="mx-4rpx mb-8rpx h-80rpx w-80rpx rounded-full" src="/static/images/avatar.jpg" />
|
|
|
|
|
|
+ <view v-if="pinkList.length" class="mb-20rpx bg-white px-20rpx py-20rpx text-center">
|
|
|
|
+ <image v-for="i in pinkList" :key="i" class="mx-4rpx mb-8rpx h-80rpx w-80rpx rounded-full" :src="i.avatar" />
|
|
</view>
|
|
</view>
|
|
</template>
|
|
</template>
|
|
<!-- 地址 -->
|
|
<!-- 地址 -->
|
|
@@ -228,14 +286,14 @@ async function handleClick() {
|
|
<template v-if="!detail.orderAddressVO">
|
|
<template v-if="!detail.orderAddressVO">
|
|
<view class="flex items-center justify-between" @click="selectAddress">
|
|
<view class="flex items-center justify-between" @click="selectAddress">
|
|
<view class="text-28rpx text-[var(--wot-color-theme)]">
|
|
<view class="text-28rpx text-[var(--wot-color-theme)]">
|
|
- Please provide your shipping address
|
|
|
|
|
|
+ {{ t('orderDetail.address.add') }}
|
|
</view>
|
|
</view>
|
|
<wd-icon name="arrow-right" color="#7D7D7D" size="28rpx" />
|
|
<wd-icon name="arrow-right" color="#7D7D7D" size="28rpx" />
|
|
</view>
|
|
</view>
|
|
</template>
|
|
</template>
|
|
<!-- 有地址 -->
|
|
<!-- 有地址 -->
|
|
<template v-else>
|
|
<template v-else>
|
|
- <view class="mb-18rpx flex justify-between border-b-1 border-b-#E1E1E1 border-b-solid pb-18rpx text-24rpx">
|
|
|
|
|
|
+ <view v-if="detail.deliveryCode" class="mb-18rpx flex justify-between border-b-1 border-b-#E1E1E1 border-b-solid pb-18rpx text-24rpx">
|
|
<!-- 物流信息 -->
|
|
<!-- 物流信息 -->
|
|
<view>{{ detail.deliveryName }}</view>
|
|
<view>{{ detail.deliveryName }}</view>
|
|
<view> DHL:{{ detail.deliveryCode || '-' }}</view>
|
|
<view> DHL:{{ detail.deliveryCode || '-' }}</view>
|
|
@@ -256,7 +314,7 @@ async function handleClick() {
|
|
<template #title>
|
|
<template #title>
|
|
<view class="flex items-center justify-between">
|
|
<view class="flex items-center justify-between">
|
|
<view class="text-28rpx text-#000">
|
|
<view class="text-28rpx text-#000">
|
|
- Order ID:{{ detail?.orderInfoVO?.[0].orderNo }}
|
|
|
|
|
|
+ {{ t('orderDetail.address.orderNo') }}:{{ detail?.orderInfoVO?.[0].orderNo }}
|
|
</view>
|
|
</view>
|
|
<wd-text size="26rpx" type="primary" :text="orderStatusEnumData.find((i:any) => i.code === detail?.status)?.name" />
|
|
<wd-text size="26rpx" type="primary" :text="orderStatusEnumData.find((i:any) => i.code === detail?.status)?.name" />
|
|
</view>
|
|
</view>
|
|
@@ -274,14 +332,14 @@ async function handleClick() {
|
|
{{ detail?.orderInfoVO?.[0].productName }}
|
|
{{ detail?.orderInfoVO?.[0].productName }}
|
|
</view>
|
|
</view>
|
|
<view class="py-4rpx text-24rpx text-#3A444C">
|
|
<view class="py-4rpx text-24rpx text-#3A444C">
|
|
- Color:{{ detail?.orderInfoVO?.[0].sku }}
|
|
|
|
|
|
+ {{ t('orderDetail.address.color') }}:{{ detail?.orderInfoVO?.[0].sku }}
|
|
</view>
|
|
</view>
|
|
<view class="flex items-center justify-between text-24rpx">
|
|
<view class="flex items-center justify-between text-24rpx">
|
|
<view class="text-[var(--wot-color-theme)]">
|
|
<view class="text-[var(--wot-color-theme)]">
|
|
৳ {{ formatNumber(detail?.orderInfoVO?.[0].price) }}
|
|
৳ {{ formatNumber(detail?.orderInfoVO?.[0].price) }}
|
|
</view>
|
|
</view>
|
|
<view class="text-#3A444C">
|
|
<view class="text-#3A444C">
|
|
- Quantity:{{ detail?.orderInfoVO?.[0].payNum }}
|
|
|
|
|
|
+ {{ t('orderDetail.address.quantity') }}:{{ detail?.orderInfoVO?.[0].payNum }}
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
@@ -291,7 +349,7 @@ async function handleClick() {
|
|
<view class="bg-white px-24rpx">
|
|
<view class="bg-white px-24rpx">
|
|
<view class="border-b-1 border-b-#E1E1E1 border-b-solid py-24rpx">
|
|
<view class="border-b-1 border-b-#E1E1E1 border-b-solid py-24rpx">
|
|
<view class="mb-12rpx text-28rpx">
|
|
<view class="mb-12rpx text-28rpx">
|
|
- Oder Summary
|
|
|
|
|
|
+ {{ t('orderDetail.summary.title') }}
|
|
</view>
|
|
</view>
|
|
<view class="flex flex-col gap-16rpx text-#3A444C">
|
|
<view class="flex flex-col gap-16rpx text-#3A444C">
|
|
<view class="flex items-center justify-between text-24rpx">
|
|
<view class="flex items-center justify-between text-24rpx">
|
|
@@ -302,7 +360,7 @@ async function handleClick() {
|
|
</view>
|
|
</view>
|
|
<view class="border-b-1 border-b-#E1E1E1 border-b-solid py-24rpx">
|
|
<view class="border-b-1 border-b-#E1E1E1 border-b-solid py-24rpx">
|
|
<view class="mb-12rpx text-28rpx">
|
|
<view class="mb-12rpx text-28rpx">
|
|
- Paid by
|
|
|
|
|
|
+ {{ t('orderDetail.payment.title') }}
|
|
</view>
|
|
</view>
|
|
<view class="flex flex-col gap-16rpx text-#3A444C">
|
|
<view class="flex flex-col gap-16rpx text-#3A444C">
|
|
<view class="flex items-center justify-between text-24rpx">
|
|
<view class="flex items-center justify-between text-24rpx">
|
|
@@ -311,13 +369,15 @@ async function handleClick() {
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
- <view class="py-24rpx">
|
|
|
|
- <view class="flex flex-col gap-16rpx text-#3A444C">
|
|
|
|
- <view class="flex items-center justify-between text-24rpx">
|
|
|
|
- <text>Placed on</text>
|
|
|
|
- <text>{{ detail.createTime }}</text>
|
|
|
|
|
|
+ <view v-if="detail?.orderStatusVO.length" class="py-24rpx">
|
|
|
|
+ <template v-for="i in detail?.orderStatusVO" :key="i.id">
|
|
|
|
+ <view v-if="timeMap[i.changeType]" class="mb-16rpx flex flex-col text-#3A444C">
|
|
|
|
+ <view class="flex items-center justify-between text-24rpx">
|
|
|
|
+ <text>{{ timeMap[i.changeType] }}</text>
|
|
|
|
+ <text>{{ i.createTime }}</text>
|
|
|
|
+ </view>
|
|
</view>
|
|
</view>
|
|
- </view>
|
|
|
|
|
|
+ </template>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
@@ -330,10 +390,10 @@ async function handleClick() {
|
|
plain
|
|
plain
|
|
@click="showCancelOrderDialog"
|
|
@click="showCancelOrderDialog"
|
|
>
|
|
>
|
|
- Cancel
|
|
|
|
|
|
+ {{ t('orderDetail.button.cancel') }}
|
|
</wd-button>
|
|
</wd-button>
|
|
<wd-button @click="handleClick">
|
|
<wd-button @click="handleClick">
|
|
- {{ detail?.status !== 1 ? 'Share Now' : 'Pay Now' }}
|
|
|
|
|
|
+ {{ detail?.status !== 1 ? t('orderDetail.button.share') : t('orderDetail.button.pay') }}
|
|
</wd-button>
|
|
</wd-button>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
</template>
|