normal-modal.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <script setup lang="ts">
  2. import { computed, ref, useTemplateRef } from 'vue';
  3. import dayjs from 'dayjs';
  4. import { fetchGetNomalOrderInfo } from '@/service/api/delivery/normal-orde';
  5. import { useAppStore } from '@/store/modules/app';
  6. import { copyTextToClipboard } from '@/utils/zt';
  7. import { useModal } from '@/components/zt/Modal/hooks/useModal';
  8. import { closeStatus, dvyStatus, orderColumns, orderStatusEnum } from '../normal-order';
  9. import DeliveryModal from './delivery-modal.vue';
  10. const [registerModal, { openModal, setModalLoading }] = useModal({
  11. title: '订单详情',
  12. isShowHeaderText: false,
  13. showFooter: false,
  14. width: 1200,
  15. height: 800
  16. });
  17. const orderInfo = ref<Api.delivery.deliveryOrder>();
  18. const appStore = useAppStore();
  19. const TimeDown = ref<number>(0);
  20. const ShipmentRef = useTemplateRef('Shipment');
  21. const emit = defineEmits<{
  22. (e: 'finish'): void;
  23. }>();
  24. async function open(orderNumber: string) {
  25. openModal();
  26. setModalLoading(true);
  27. const { data, error } = await fetchGetNomalOrderInfo(orderNumber);
  28. if (!error) {
  29. orderInfo.value = data;
  30. if (orderInfo.value.hbLogisticStatus == orderStatusEnum.WAIT_PAY) {
  31. const createTime = dayjs(orderInfo.value.createTime);
  32. const currentTime = dayjs();
  33. const elapsed = currentTime.diff(createTime);
  34. const fifteenMinutesInMillis = 15 * 60 * 1000;
  35. TimeDown.value = fifteenMinutesInMillis - elapsed;
  36. }
  37. }
  38. setModalLoading(false);
  39. }
  40. defineExpose({ open });
  41. function handleFinish() {
  42. open(String(orderInfo.value?.orderNumber));
  43. emit('finish');
  44. }
  45. const isRefund = computed(() => {
  46. const goodsData = orderInfo.value?.orderItems?.find(it => it.refundIngCount == 1);
  47. return Boolean(goodsData);
  48. });
  49. function handleShipment() {
  50. if (isRefund.value) {
  51. window.$message?.error('当前订单正在申请退款中');
  52. return;
  53. }
  54. ShipmentRef.value?.handleOpenOrder(String(orderInfo.value?.orderNumber));
  55. }
  56. const currentSteps = computed(() => {
  57. switch (orderInfo.value?.hbOrderStatus) {
  58. case orderStatusEnum.WAIT_PAY:
  59. return 1;
  60. case orderStatusEnum.ORDER_ACCEPT:
  61. return 2;
  62. case orderStatusEnum.ORDER_WAIT_DELIVERY:
  63. return 2;
  64. case orderStatusEnum.WAIT_DELIVERY:
  65. return 2;
  66. case orderStatusEnum.ORDER_DELIVERY:
  67. return 3;
  68. case orderStatusEnum.ORDER_ARRIVE:
  69. return 3;
  70. case orderStatusEnum.ORDER_COMPLETE:
  71. return 4;
  72. default:
  73. return 1;
  74. }
  75. });
  76. function handleCopy() {
  77. copyTextToClipboard(String(orderInfo.value?.orderNumber));
  78. }
  79. </script>
  80. <template>
  81. <div>
  82. <BasicModal @register="registerModal" @after-leave="orderInfo = undefined">
  83. <div v-if="orderInfo">
  84. <NFlex justify="space-between" align="center">
  85. <NFlex>
  86. <NTag>
  87. <div class="flex items-center">
  88. 订单编号: {{ orderInfo?.orderNumber }}
  89. <div @click="handleCopy">
  90. <SvgIcon icon="bxs:copy" class="mx-3 cursor-pointer text-[#f97316]"></SvgIcon>
  91. </div>
  92. </div>
  93. </NTag>
  94. <NTag>下单时间: {{ orderInfo?.createTime }}</NTag>
  95. </NFlex>
  96. <NFlex vertical>
  97. <template v-if="orderInfo.hbOrderStatus == orderStatusEnum.WAIT_PAY">
  98. <div class="text-16px font-semibold">商品已拍下,等待买家付款</div>
  99. <div class="text-gray">
  100. 如买家未在
  101. <NTag :type="TimeDown > 300094 ? 'success' : 'error'">
  102. <NCountdown :duration="TimeDown" @finish="handleFinish" />
  103. </NTag>
  104. 内付款,订单将 自动关闭。
  105. </div>
  106. </template>
  107. <template v-if="!orderInfo.dvyFlowId">
  108. <template
  109. v-if="
  110. orderInfo.hbOrderStatus == orderStatusEnum.WAIT_DELIVERY ||
  111. orderInfo.hbOrderStatus == orderStatusEnum.ORDER_ACCEPT ||
  112. orderInfo.hbOrderStatus == orderStatusEnum.ORDER_DELIVERY
  113. "
  114. >
  115. <div class="text-16px font-semibold">等待商家发货</div>
  116. <NButton size="small" type="primary" @click="handleShipment">发货</NButton>
  117. </template>
  118. </template>
  119. <template v-if="orderInfo.hbOrderStatus == orderStatusEnum.ORDER_ARRIVE">
  120. <div class="text-16px font-semibold">等待买家收货</div>
  121. <div>商家已发货,等待确认收货</div>
  122. </template>
  123. <template v-if="orderInfo.hbOrderStatus == orderStatusEnum.ORDER_CANCEL">
  124. <div class="text-16px font-semibold">已取消</div>
  125. <div>取消原因:{{ closeStatus[orderInfo.closeType as keyof typeof closeStatus] || '未知取消原因' }}</div>
  126. </template>
  127. <template v-if="orderInfo.hbOrderStatus == orderStatusEnum.ORDER_COMPLETE">
  128. <div class="text-16px font-semibold">交易成功</div>
  129. <div>买家已收货</div>
  130. </template>
  131. </NFlex>
  132. </NFlex>
  133. <NDivider />
  134. <template v-if="orderInfo.hbOrderStatus != orderStatusEnum.ORDER_CANCEL">
  135. <div class="p3">
  136. <NSteps :current="currentSteps" :vertical="appStore.isMobile">
  137. <NStep title="用户下单" :description="orderInfo.createTime" />
  138. <NStep title="买家已付款" :description="orderInfo.payTime" />
  139. <NStep title="卖家已发货" :description="orderInfo.dvyTime" />
  140. <NStep title="买家已收货" :description="orderInfo.finallyTime" />
  141. </NSteps>
  142. </div>
  143. <NDivider />
  144. </template>
  145. <NDescriptions bordered :column="appStore.isMobile ? 1 : 4">
  146. <NDescriptionsItem label="收货人信息">
  147. <div>收货人姓名:{{ orderInfo?.userAddrOrder?.receiver || '---' }}</div>
  148. <div>收货人手机号:{{ orderInfo?.userAddrOrder?.mobile || '---' }}</div>
  149. <div>收货地址:{{ orderInfo?.userAddrOrder?.address || '---' }}</div>
  150. </NDescriptionsItem>
  151. <NDescriptionsItem label="配送信息">
  152. <div>配送方式: {{ dvyStatus[orderInfo.dvyType as keyof typeof dvyStatus] || '暂无' }}</div>
  153. </NDescriptionsItem>
  154. <NDescriptionsItem label="付款信息">
  155. <div>实付金额:{{ orderInfo.actualTotal }}元</div>
  156. <div>
  157. 付款方式:{{
  158. orderInfo.hbOrderStatus == orderStatusEnum.WAIT_PAY ||
  159. orderInfo.hbOrderStatus == orderStatusEnum.ORDER_CANCEL
  160. ? '暂无'
  161. : '微信'
  162. }}
  163. </div>
  164. <div>付款时间:{{ orderInfo.payTime || '暂无' }}</div>
  165. </NDescriptionsItem>
  166. <NDescriptionsItem label="买家信息">
  167. <div>买家昵称:{{ orderInfo?.nickName || '---' }}</div>
  168. <div>买家电话:{{ orderInfo?.userMobile || '---' }}</div>
  169. <div>买家留言:{{ orderInfo?.remarks || '暂无' }}</div>
  170. </NDescriptionsItem>
  171. </NDescriptions>
  172. <NDivider />
  173. <NCard title="订单信息" :bordered="false">
  174. <NDataTable :columns="orderColumns" :data="orderInfo.orderItems" :bordered="false" />
  175. </NCard>
  176. <NCard title="费用信息" :bordered="false">
  177. <NTable :single-line="false">
  178. <NThead>
  179. <NTr>
  180. <NTh>费用类型</NTh>
  181. <NTh>金额/元</NTh>
  182. </NTr>
  183. </NThead>
  184. <NTbody>
  185. <NTr>
  186. <NTd>商品总额</NTd>
  187. <NTd>{{ orderInfo.total }}</NTd>
  188. </NTr>
  189. <NTr>
  190. <NTd>配送费(快递)</NTd>
  191. <NTd>{{ orderInfo.freightAmount }}</NTd>
  192. </NTr>
  193. <NTr>
  194. <NTd>积分</NTd>
  195. <NTd>-{{ (Number(orderInfo.offsetPoints) / 100).toFixed(2) || 0 }}</NTd>
  196. </NTr>
  197. <NTr>
  198. <NTd v-if="orderInfo.hbOrderStatus == orderStatusEnum.WAIT_PAY">需付款</NTd>
  199. <NTd
  200. v-if="
  201. orderInfo.hbOrderStatus != orderStatusEnum.WAIT_PAY &&
  202. orderInfo.hbOrderStatus != orderStatusEnum.ORDER_CANCEL
  203. "
  204. >
  205. 实际付款
  206. </NTd>
  207. <NTd v-if="orderInfo.hbOrderStatus == orderStatusEnum.ORDER_CANCEL">应付款</NTd>
  208. <NTd>{{ orderInfo.actualTotal }}</NTd>
  209. </NTr>
  210. </NTbody>
  211. </NTable>
  212. </NCard>
  213. </div>
  214. </BasicModal>
  215. <DeliveryModal ref="Shipment" @finish="emit('finish')"></DeliveryModal>
  216. </div>
  217. </template>
  218. <style scoped></style>