orderDetail.vue 21 KB

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