orderDetail.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. <route lang="json5" type="page">
  2. {
  3. layout: 'default',
  4. needLogin: true,
  5. style: {
  6. navigationBarTitleText: '%orderDetail.title%',
  7. navigationBarBackgroundColor: '#fff',
  8. },
  9. }
  10. </route>
  11. <script lang="ts" setup>
  12. import { getConfigByCode } from '@/api/common'
  13. import { orderCancel, orderDetail, orderPink, orderStatusEnum, payOrder } from '@/api/order'
  14. import { getWalletAccountInfo } from '@/api/wallet'
  15. import DialogBox from '@/components/DialogBox/DialogBox.vue'
  16. import { DialogUtils } from '@/components/DialogBox/utils'
  17. import { t } from '@/locale'
  18. import { formatNumber } from '@/utils'
  19. import { toPage } from '@/utils/page'
  20. import { toast } from '@/utils/toast'
  21. defineOptions({
  22. name: 'OrderDetail', // 订单详情
  23. })
  24. // z-paging
  25. const paging = ref(null)
  26. const id = ref<any>()
  27. const orderNo = ref<string>()
  28. const isPayOrder = ref<boolean>(false)
  29. const isPageLoading = ref(true) // 页面加载状态
  30. const detail = ref<any>({})
  31. const orderStatusEnumData = ref<any>([])
  32. const openRedEnvelopeRate = ref<any>()
  33. const joinRedEnvelopeRate = ref<any>()
  34. const countdown = ref('00:00')
  35. const timer = ref()
  36. const hasCountdownEnded = ref(false) // 标记倒计时是否已结束并查询过
  37. // DialogBox 函数式调用配置
  38. const dialogConfig = ref<any>({})
  39. const dialogType = ref<'cancel' | 'pay' | 'recharge' | ''>('')
  40. async function getConfig(code: string) {
  41. try {
  42. const res = await getConfigByCode({ code })
  43. if (res.code === '200') {
  44. switch (code) {
  45. case 'open_red_envelope_rate':
  46. openRedEnvelopeRate.value = res.data.valueInfo
  47. break
  48. case 'join_red_envelope_rate':
  49. joinRedEnvelopeRate.value = res.data.valueInfo
  50. break
  51. default:
  52. break
  53. }
  54. }
  55. }
  56. catch {
  57. }
  58. }
  59. async function getOrderStatus() {
  60. try {
  61. const res = await orderStatusEnum({ id: 1 })
  62. if (res.code === '200') {
  63. orderStatusEnumData.value = res.data
  64. }
  65. }
  66. catch {
  67. }
  68. }
  69. function startCountdown() {
  70. // 清除之前的定时器
  71. if (timer.value)
  72. clearInterval(timer.value)
  73. if (!detail.value?.createTime || detail.value?.status !== 1) {
  74. countdown.value = '00:00'
  75. return
  76. }
  77. // 重置倒计时结束标记
  78. hasCountdownEnded.value = false
  79. // 计算过期时间(创建时间 + 20分钟)
  80. const createTime = new Date(detail.value.createTime).getTime()
  81. const expireTime = createTime + 20 * 60 * 1000
  82. timer.value = setInterval(() => {
  83. const now = Date.now()
  84. const diff = expireTime - now
  85. if (diff <= 0) {
  86. clearInterval(timer.value)
  87. countdown.value = '00:00'
  88. // 只在第一次倒计时结束时查询一次
  89. if (!hasCountdownEnded.value) {
  90. hasCountdownEnded.value = true
  91. getDetail() // 刷新订单状态
  92. }
  93. return
  94. }
  95. const minutes = Math.floor(diff / 1000 / 60)
  96. const seconds = Math.floor((diff / 1000) % 60)
  97. countdown.value = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
  98. }, 1000)
  99. }
  100. // 用户主动刷新时调用此函数
  101. async function handleRefresh() {
  102. // 重置倒计时结束标记,允许重新查询
  103. hasCountdownEnded.value = false
  104. await getDetail()
  105. }
  106. async function getDetail() {
  107. try {
  108. isPageLoading.value = true
  109. // 根据参数类型构建请求参数
  110. const params = orderNo.value ? { orderNo: orderNo.value } : { id: id.value }
  111. const res = await orderDetail(params)
  112. if (res.code === '200') {
  113. detail.value = res.data
  114. // 如果通过 orderNo 查询,更新 id 值用于其他接口调用
  115. if (orderNo.value && detail.value?.orderId) {
  116. id.value = detail.value.orderId
  117. }
  118. if (detail.value?.status === 1) {
  119. // 只有在倒计时未结束时才启动倒计时,防止倒计时结束后重复查询
  120. if (!hasCountdownEnded.value) {
  121. startCountdown() // 开始倒计时
  122. }
  123. // if (isPayOrder.value) {
  124. // // 自动调用支付接口
  125. // await goPay()
  126. // }
  127. }
  128. else {
  129. // 状态已变化,重置标记
  130. hasCountdownEnded.value = false
  131. }
  132. await getPink()
  133. paging.value.complete()
  134. }
  135. }
  136. finally {
  137. isPageLoading.value = false
  138. }
  139. }
  140. const pinkList = ref<any>([])
  141. async function getPink() {
  142. try {
  143. const res = await orderPink({ orderNo: orderNo.value })
  144. if (res.code === '200') {
  145. pinkList.value = res.data
  146. }
  147. }
  148. catch {
  149. }
  150. }
  151. // 跳转到地址簿选择地址
  152. function selectAddress() {
  153. toPage({ url: '/pages/mine/addressBook', params: {
  154. selectMode: '1',
  155. orderId: detail.value?.orderId,
  156. } })
  157. }
  158. // 显示取消订单确认对话框
  159. function showCancelOrderDialog() {
  160. dialogType.value = 'cancel'
  161. Object.assign(dialogConfig.value, DialogUtils.info(
  162. t('orderDetail.dialog.cancel.title'),
  163. {
  164. showCancel: true,
  165. confirmText: t('orderDetail.dialog.cancel.confirm'),
  166. cancelText: t('orderDetail.dialog.cancel.keep'),
  167. confirmPlain: true,
  168. },
  169. ))
  170. }
  171. // 取消订单
  172. async function cancelOrder() {
  173. try {
  174. uni.showLoading({
  175. title: t('orderDetail.cancel.loading'),
  176. mask: true,
  177. })
  178. const res = await orderCancel({ orderNo: orderNo.value })
  179. if (res.code === '200') {
  180. // 显示成功提示
  181. toast.success(t('orderDetail.cancel.success'))
  182. // 刷新订单详情
  183. getDetail()
  184. }
  185. else {
  186. // 显示错误提示
  187. toast.error(res.message || t('orderDetail.cancel.error'))
  188. }
  189. }
  190. catch (error: any) {
  191. console.error('Cancel order error:', error)
  192. // 显示错误提示
  193. toast.error(t('orderDetail.cancel.error'))
  194. }
  195. finally {
  196. uni.hideLoading()
  197. }
  198. }
  199. // 处理对话框确认事件
  200. function handleDialogConfirm() {
  201. if (dialogType.value === 'cancel') {
  202. cancelOrder()
  203. }
  204. else if (dialogType.value === 'pay') {
  205. goPay()
  206. }
  207. else if (dialogType.value === 'recharge') {
  208. toPage({ url: '/pages/wallet/recharge', params: { price: detail.value?.payPrice }, isRedirect: true })
  209. }
  210. // 关闭对话框
  211. handleDialogClose()
  212. }
  213. // 处理对话框关闭事件
  214. function handleDialogClose() {
  215. dialogConfig.value.show = false
  216. }
  217. // 支付
  218. // 显示支付余额去充值提示
  219. function showRechargeDialog() {
  220. dialogType.value = 'recharge'
  221. Object.assign(dialogConfig.value, DialogUtils.info(
  222. t('orderDetail.rechargeDialog.title'),
  223. {
  224. showCancel: false,
  225. confirmText: t('orderDetail.rechargeDialog.confirm'),
  226. cancelText: '',
  227. confirmPlain: true,
  228. },
  229. ))
  230. }
  231. // 显示支付确认对话框
  232. function showPayOrderDialog() {
  233. dialogType.value = 'pay'
  234. Object.assign(dialogConfig.value, DialogUtils.info(
  235. t('orderDetail.payDialog.title'),
  236. {
  237. showCancel: false,
  238. cancelText: '',
  239. confirmText: t('orderDetail.payDialog.confirm'),
  240. confirmPlain: false,
  241. },
  242. ))
  243. }
  244. async function goPay() {
  245. uni.showLoading({
  246. title: t('orderDetail.payment.loading'),
  247. mask: true,
  248. })
  249. try {
  250. const payRes = await payOrder({
  251. orderId: detail.value?.orderId,
  252. type: detail.value?.storePink?.kId ? 'join' : 'open',
  253. })
  254. console.log(payRes)
  255. if (payRes.code === '200') {
  256. toast.success(t('orderDetail.payment.success'))
  257. getDetail()
  258. }
  259. }
  260. finally {
  261. uni.hideLoading()
  262. }
  263. }
  264. function handleClick() {
  265. if (detail.value?.status === 1) {
  266. // 去支付
  267. showPayOrderDialog()
  268. }
  269. else {
  270. // 去分享
  271. }
  272. }
  273. const timeMap = {
  274. create_order: t('orderDetail.time.placed'),
  275. pay_success: t('orderDetail.time.paid'),
  276. delivery: t('orderDetail.time.shipped'),
  277. receive: t('orderDetail.time.completed'),
  278. }
  279. function copyDelivery() {
  280. uni.setClipboardData({
  281. data: `${detail.value.deliveryName}: ${detail.value.deliveryId}`,
  282. })
  283. }
  284. onLoad(async (options) => {
  285. getConfig('open_red_envelope_rate')
  286. getConfig('join_red_envelope_rate')
  287. const params = options
  288. orderNo.value = params.orderNo
  289. isPayOrder.value = params.isPayOrder
  290. await getOrderStatus()
  291. })
  292. const balance = ref<number>(0)
  293. onShow(async () => {
  294. // 重置倒计时结束标记,允许重新查询
  295. hasCountdownEnded.value = false
  296. await getDetail()
  297. if (isPayOrder.value && detail.value?.status === 1) {
  298. const res = await getWalletAccountInfo()
  299. console.log(res)
  300. balance.value = res?.data?.balance
  301. if (balance.value < detail.value?.payPrice) {
  302. // 余额不足,提示去充值
  303. showRechargeDialog()
  304. }
  305. else {
  306. // 余额充足,显示支付对话框
  307. showPayOrderDialog()
  308. }
  309. }
  310. })
  311. onUnmounted(() => {
  312. if (timer.value)
  313. clearInterval(timer.value)
  314. })
  315. </script>
  316. <template>
  317. <z-paging ref="paging" refresher-only @refresh="handleRefresh">
  318. <!-- 页面加载时显示骨架屏 -->
  319. <template v-if="isPageLoading">
  320. <view class="pt-20rpx">
  321. <!-- 状态卡片骨架屏(模拟状态显示区域) -->
  322. <view class="mb-20rpx bg-white py-20rpx text-center">
  323. <wd-skeleton
  324. :row-col="[{ width: '180rpx', height: '28rpx', marginLeft: 'auto', marginRight: 'auto' }]"
  325. animation="gradient"
  326. />
  327. </view>
  328. <!-- 地址信息骨架屏(模拟地址选择区域) -->
  329. <view class="mb-20rpx bg-white px-24rpx py-20rpx">
  330. <wd-skeleton
  331. :row-col="[
  332. { width: '150rpx', height: '28rpx' }, // 地址标题或添加地址
  333. { width: '200rpx', height: '24rpx', marginTop: '12rpx' }, // 收货人信息
  334. { width: '100%', height: '22rpx', marginTop: '8rpx' }, // 详细地址
  335. ]"
  336. animation="gradient"
  337. />
  338. </view>
  339. <!-- 商品信息骨架屏(使用实际的 wd-card 结构) -->
  340. <wd-card type="rectangle" custom-class="px-24rpx! py-6rpx!" custom-content-class="py-18rpx!" custom-title-class="py-18rpx!">
  341. <template #title>
  342. <!-- 订单头部:订单号 + 状态 -->
  343. <wd-skeleton
  344. :row-col="[
  345. [{ width: '250rpx', height: '28rpx' }, { width: '60rpx', height: '26rpx', marginLeft: 'auto' }],
  346. ]"
  347. animation="gradient"
  348. />
  349. </template>
  350. <!-- 商品区域:图片 + 信息 -->
  351. <wd-skeleton
  352. :row-col="[
  353. [
  354. { width: '140rpx', height: '140rpx', type: 'rect' },
  355. [
  356. { width: '100%', height: '40rpx' }, // 商品标题第一行
  357. { width: '80%', height: '40rpx', marginTop: '8rpx' }, // 商品标题第二行
  358. { width: '120rpx', height: '24rpx', marginTop: '4rpx' }, // 颜色规格
  359. [{ width: '100rpx', height: '24rpx' }, { width: '80rpx', height: '24rpx', marginLeft: 'auto' }], // 价格和数量
  360. ],
  361. ],
  362. ]"
  363. animation="gradient"
  364. />
  365. </wd-card>
  366. <!-- 订单信息骨架屏 -->
  367. <view class="bg-white px-24rpx">
  368. <!-- 订单摘要 -->
  369. <view class="border-b-1 border-b-#e8e8e8 border-b-solid py-24rpx">
  370. <wd-skeleton
  371. :row-col="[
  372. { width: '120rpx', height: '28rpx' }, // 摘要标题
  373. [{ width: '80rpx', height: '24rpx' }, { width: '100rpx', height: '24rpx', marginLeft: 'auto' }], // SubTotal 行
  374. ]"
  375. animation="gradient"
  376. />
  377. </view>
  378. <!-- 支付方式 -->
  379. <view class="border-b-1 border-b-#e8e8e8 border-b-solid py-24rpx">
  380. <wd-skeleton
  381. :row-col="[
  382. [{ width: '100rpx', height: '28rpx' }, { width: '140rpx', height: '24rpx', marginLeft: 'auto' }],
  383. ]"
  384. animation="gradient"
  385. />
  386. </view>
  387. <!-- 订单状态记录 -->
  388. <view class="py-24rpx">
  389. <wd-skeleton
  390. :row-col="[
  391. [{ width: '90rpx', height: '24rpx' }, { width: '150rpx', height: '24rpx', marginLeft: 'auto' }],
  392. [{ width: '80rpx', height: '24rpx' }, { width: '150rpx', height: '24rpx', marginLeft: 'auto' }],
  393. ]"
  394. animation="gradient"
  395. />
  396. </view>
  397. </view>
  398. </view>
  399. </template>
  400. <!-- 实际内容 -->
  401. <template v-else>
  402. <view class="pt-20rpx">
  403. <!-- 状态显示 lId=1是中奖0是未中奖。storePink?.status是拼团状态 detail?.status是订单状态 -->
  404. <template v-if="detail.status !== 4 && detail?.status !== 2">
  405. <view v-if="detail?.status === 9" class="mb-20rpx bg-#17AA68/80 py-20rpx text-center text-28rpx text-white">
  406. {{ t('orderDetail.status9.sellBackPrefix') }}
  407. <text class="text-[var(--wot-color-theme)]">
  408. ৳{{ formatNumber(detail?.recycleAmount) }}
  409. </text>
  410. <br>
  411. {{ t('orderDetail.status9.receivePrefix') }}
  412. <text class="text-[var(--wot-color-theme)]">
  413. ৳{{ formatNumber(detail?.brokerage) }}
  414. </text>
  415. {{ t('orderDetail.status9.rewardSuffix') }}
  416. </view>
  417. <!-- 已中奖 -->
  418. <view v-else-if="detail?.storePink?.status === 2 && detail?.storePink?.lId === 1" class="mb-20rpx bg-#17AA68/80 py-20rpx text-center text-28rpx text-white">
  419. {{ t('orderDetail.congrats') }}
  420. <br>
  421. {{ t('orderDetail.receiveReward') }}
  422. <text class="text-[var(--wot-color-theme)]">
  423. ৳{{ detail.brokerage }}
  424. </text>
  425. </view>
  426. <!-- 未中奖 -->
  427. <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">
  428. {{ t('orderDetail.sorry') }}
  429. <br>
  430. {{ t('orderDetail.receiveReward') }}
  431. <text class="text-#66C59B">
  432. ৳{{ detail.brokerage }}
  433. </text>
  434. </view>
  435. <!-- 未开奖||未支付 -->
  436. <view v-else-if="detail?.storePink?.status === 1 || detail?.status === 1" class="mb-20rpx bg-#fff py-20rpx text-center text-28rpx text-white">
  437. <text v-if="detail?.storePink?.status === 1 && detail?.status !== 1" class="text-[var(--wot-color-theme)]">
  438. {{ t('orderDetail.waiting') }}
  439. </text>
  440. <text v-else class="text-[var(--wot-color-theme)]">
  441. {{ t('orderDetail.paymentCountdown') }} {{ countdown }}
  442. </text>
  443. </view>
  444. <!-- 拼团头像 -->
  445. <view v-if="pinkList && pinkList.length" class="mb-20rpx bg-white px-20rpx py-20rpx text-center">
  446. <image v-for="i in pinkList" :key="i" class="mx-4rpx mb-8rpx h-80rpx w-80rpx border-1 border-transparent rounded-full border-solid" :style="{ borderColor: i.lId ? 'var(--wot-color-theme)' : 'transparent' }" :src="i.avatar" />
  447. </view>
  448. </template>
  449. <!-- 地址 -->
  450. <view v-if="detail?.storePink?.status === 2 && detail?.storePink?.lId === 1 && detail?.status !== 9" class="mb-20rpx bg-white px-24rpx py-20rpx">
  451. <!-- 无地址 -->
  452. <template v-if="!detail.orderAddressVO">
  453. <view class="flex items-center justify-between" @click="selectAddress">
  454. <view class="text-28rpx text-[var(--wot-color-theme)]">
  455. {{ t('orderDetail.address.add') }}
  456. </view>
  457. <wd-icon name="arrow-right" color="#7D7D7D" size="28rpx" />
  458. </view>
  459. </template>
  460. <!-- 有地址 -->
  461. <template v-else>
  462. <view v-if="detail.deliveryId" class="mb-18rpx flex justify-between border-b-1 border-b-#e8e8e8 border-b-solid pb-18rpx text-24rpx">
  463. <!-- 物流信息 -->
  464. <view>{{ $t('orderDetail.deliveryPartner') }}</view>
  465. <view class="flex items-center gap-8rpx" @click="copyDelivery">
  466. <text>{{ detail.deliveryName }}: {{ detail.deliveryId || '-' }}</text>
  467. <wd-icon name="file-copy" size="28rpx" />
  468. </view>
  469. </view>
  470. <view class="mb-20rpx text-24rpx">
  471. <text class="mr-20rpx">
  472. {{ detail?.orderAddressVO?.realName }}
  473. </text>
  474. <text>{{ detail?.orderAddressVO?.phone }}</text>
  475. </view>
  476. <view class="text-22rpx text-#3A444C">
  477. {{ detail?.orderAddressVO?.province }} {{ detail?.orderAddressVO?.city }} {{ detail?.orderAddressVO?.district }} {{ detail?.orderAddressVO?.detail }} {{ detail?.orderAddressVO?.postCode }}
  478. </view>
  479. </template>
  480. </view>
  481. <!-- 商品信息 -->
  482. <wd-card type="rectangle" custom-class="px-24rpx! py-6rpx!" custom-content-class="py-18rpx!" custom-title-class="py-18rpx!" @click="toPage({ url: '/pages/productDetail/productDetail', params: { productId: detail?.orderInfoVO?.[0].productId } })">
  483. <template #title>
  484. <view class="flex items-center justify-between">
  485. <view class="text-28rpx text-#000">
  486. {{ t('orderDetail.address.orderNo') }}:{{ detail?.orderInfoVO?.[0].orderNo }}
  487. </view>
  488. <wd-text size="26rpx" type="primary" :text="orderStatusEnumData.find((i:any) => i.code === detail?.status)?.name" />
  489. </view>
  490. </template>
  491. <view class="flex items-center gap-24rpx">
  492. <view class="h-140rpx w-140rpx shrink-0">
  493. <image
  494. :src="detail?.orderInfoVO?.[0]?.image"
  495. class="h-full w-full"
  496. mode="aspectFit"
  497. />
  498. </view>
  499. <view class="flex-1">
  500. <view class="line-clamp-2 h-80rpx break-all text-28rpx text-#000">
  501. {{ detail?.orderInfoVO?.[0].productName }}
  502. </view>
  503. <view class="py-4rpx text-24rpx text-#3A444C">
  504. {{ t('orderDetail.address.color') }}:{{ detail?.orderInfoVO?.[0].sku }}
  505. </view>
  506. <view class="flex items-center justify-between text-24rpx">
  507. <view class="text-[var(--wot-color-theme)]">
  508. ৳ {{ formatNumber(detail?.orderInfoVO?.[0].price) }}
  509. </view>
  510. <view class="text-#3A444C">
  511. {{ t('orderDetail.address.quantity') }}:{{ detail?.orderInfoVO?.[0].payNum }}
  512. </view>
  513. </view>
  514. </view>
  515. </view>
  516. </wd-card>
  517. <!-- 订单信息 -->
  518. <view class="bg-white px-24rpx">
  519. <view class="border-b-1 border-b-#e8e8e8 border-b-solid py-24rpx">
  520. <view class="mb-12rpx text-28rpx">
  521. {{ t('orderDetail.summary.title') }}
  522. </view>
  523. <view class="flex flex-col gap-16rpx text-#3A444C">
  524. <view class="flex items-center justify-between text-24rpx">
  525. <text>{{ $t('orderDetail.subTotal') }}</text>
  526. <text>৳{{ formatNumber(detail.totalPrice) }}</text>
  527. </view>
  528. </view>
  529. </view>
  530. <view v-if="detail?.status !== 1" class="border-b-1 border-b-#e8e8e8 border-b-solid py-24rpx">
  531. <view class="mb-12rpx text-28rpx">
  532. {{ t('orderDetail.payment.title') }}
  533. </view>
  534. <view class="flex flex-col gap-16rpx text-#3A444C">
  535. <view class="flex items-center justify-between text-24rpx">
  536. <text>{{ detail.payType }}</text>
  537. <text>৳{{ formatNumber(detail.payPrice) }}</text>
  538. </view>
  539. </view>
  540. </view>
  541. <view v-if="detail?.orderStatusVO?.length" class="py-24rpx">
  542. <template v-for="i in detail?.orderStatusVO" :key="i.id">
  543. <view v-if="timeMap[i.changeType]" class="mb-16rpx flex flex-col text-#3A444C">
  544. <view class="flex items-center justify-between text-24rpx">
  545. <text>{{ timeMap[i.changeType] }}</text>
  546. <text>{{ i.createTime }}</text>
  547. </view>
  548. </view>
  549. </template>
  550. </view>
  551. </view>
  552. </view>
  553. </template>
  554. <template #bottom>
  555. <view v-if="detail?.status === 1" class="flex items-center justify-end bg-white/60 px-28rpx py-30rpx backdrop-blur-20">
  556. <!-- 取消订单按钮 -->
  557. <wd-button
  558. v-if="detail?.status === 1"
  559. custom-class="mr-16rpx!"
  560. plain
  561. @click="showCancelOrderDialog"
  562. >
  563. {{ t('orderDetail.button.cancel') }}
  564. </wd-button>
  565. <wd-button @click="handleClick">
  566. {{ t('orderDetail.button.pay') }}
  567. </wd-button>
  568. </view>
  569. </template>
  570. <!-- DialogBox 函数式调用 -->
  571. <DialogBox
  572. v-bind="dialogConfig"
  573. @confirm="handleDialogConfirm"
  574. @cancel="handleDialogClose"
  575. @close="handleDialogClose"
  576. >
  577. <view v-if="dialogType === 'pay'">
  578. <view class="font-blod relative text-32rpx">
  579. <text> {{ $t('orderDetail.paymentMethod') }}</text>
  580. <wd-icon name="close-normal" custom-class="absolute right-0 top-1/2 -translate-y-1/2" size="40rpx" @click="handleDialogClose" />
  581. </view>
  582. <view class="py-60rpx">
  583. <text class="text-40rpx">
  584. </text>
  585. <text class="text-60rpx">
  586. {{ formatNumber(detail.payPrice) }}
  587. </text>
  588. </view>
  589. <view class="pb-28rpx text-left">
  590. <view class="text-24rpx font-bold">
  591. {{ $t('orderDetail.paymentMethod') }}
  592. </view>
  593. <view class="my-14rpx border-b-1px border-b-#EBEBEB border-b-solid" />
  594. <view class="flex items-center justify-between text-24rpx">
  595. <view class="flex items-center">
  596. <view class="text-24rpx">
  597. <text>{{ $t('orderDetail.bandhuBuyWallet') }} (</text>
  598. <text class="text-[var(--wot-color-theme)]">
  599. {{ $t('orderDetail.walletBalanceText') }}: ৳{{ formatNumber(balance) }}
  600. </text>
  601. <text>)</text>
  602. </view>
  603. </view>
  604. <view>
  605. <image
  606. src="/static/icons/circle-check.png"
  607. class="h-36rpx w-36rpx"
  608. />
  609. </view>
  610. </view>
  611. </view>
  612. </view>
  613. </DialogBox>
  614. </z-paging>
  615. </template>
  616. <style lang="scss" scoped>
  617. //
  618. </style>