detail.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <template>
  2. <div class="mt-16">
  3. <div class="default-width pb-5">
  4. <v-banner color="primary" :text="formatOrderStatusDescription(order)" style="background-color: #00897B; color: #fff;"></v-banner>
  5. <!-- 商品列表 -->
  6. <v-card class="my-3 pa-5">
  7. <h3 class="mb-3">商品列表</h3>
  8. <v-divider></v-divider>
  9. <CtTable
  10. class="mt-3"
  11. :items="order.items"
  12. :headers="headers"
  13. :loading="false"
  14. :elevation="0"
  15. :isTools="false"
  16. :showPage="false"
  17. itemKey="id"
  18. >
  19. <template #picUrl="{ item }">
  20. <v-img :src="item.picUrl" width="90" height="90" class="my-1"></v-img>
  21. </template>
  22. <template #spuName="{ item }">
  23. <span class="color-primary cursor-pointer" @click="handleToGoodsDetail(item)">{{ item.spuName }}</span>
  24. <p v-if="order.lottery && order.lottery.length" class="color-999">赠品:{{ order.lottery.map(e => e.prize.name).join('、') }}</p>
  25. </template>
  26. <template #actions="{ item }">
  27. <div v-if="[10, 20, 30].includes(order.status) && item.extend && item.extend.fileUrls && item.extend.fileUrls.length > 0">
  28. <v-btn variant="text" color="primary" prepend-icon="mdi-eye-outline" @click="previewFile(item.extend.fileUrls[0])">预览</v-btn>
  29. <v-btn variant="text" color="primary" prepend-icon="mdi-arrow-down-bold-outline" @click="handleDownload(item.extend.fileUrls[0], item.spuName)">下载</v-btn>
  30. </div>
  31. </template>
  32. </CtTable>
  33. <div class="text-end color-primary mr-3 mt-5 font-size-20">
  34. 共{{ order.productCount }}件商品,合计:¥{{ fen2yuan(order.payPrice) }}
  35. </div>
  36. </v-card>
  37. <v-row no-gutters class="mt-3">
  38. <v-col span="6">
  39. <!-- 订单信息 -->
  40. <v-card class="pa-5">
  41. <h3>订单信息</h3>
  42. <v-divider class="my-3"></v-divider>
  43. <div class="font-size-15 color-666">
  44. <p>订单编号:{{ order.no }}</p>
  45. <p class="my-3">下单时间:{{ timesTampChange(order.createTime) }}</p>
  46. <p>支付时间:{{ timesTampChange(order.payTime) }}</p>
  47. <p class="mt-3">支付方式:{{ order.payChannelName }}</p>
  48. <p class="mt-3">订单备注:{{ order.userRemark }}</p>
  49. </div>
  50. </v-card>
  51. </v-col>
  52. <v-col span="6" class="ml-3">
  53. <!-- 物流信息 -->
  54. <v-card class="pa-5" style="height: 100%">
  55. <h3>物流信息</h3>
  56. <v-divider class="my-3"></v-divider>
  57. <div class="font-size-15 color-666">
  58. <p>收货地址:<span v-if="order.receiverName && order.receiverMobile">{{ order.receiverName }},{{ order.receiverMobile }},{{ order.receiverAreaName }} {{ order.receiverDetailAddress }}</span></p>
  59. <p class="my-3">物流公司:{{ order.logisticsName }}</p>
  60. <p>运单号:{{ order.logisticsNo }}</p>
  61. </div>
  62. </v-card>
  63. </v-col>
  64. </v-row>
  65. </div>
  66. </div>
  67. </template>
  68. <script setup>
  69. defineOptions({ name: 'mall-user-order-detail'})
  70. import { ref, onMounted, computed } from 'vue'
  71. import { useRouter } from 'vue-router'
  72. import { getMallOrderDetail } from '@/api/mall/user'
  73. import Snackbar from '@/plugins/snackbar'
  74. import { timesTampChange } from '@/utils/date'
  75. import { fen2yuan, formatOrderStatusDescription } from '@/hooks/web/useGoods'
  76. import { getBlob, saveAs, previewFile } from '@/utils'
  77. import { getLuckLotteryRecordByOrderId } from '@/api/mall/prize'
  78. const router = useRouter()
  79. const { id } = router.currentRoute.value.params
  80. const order = ref({})
  81. const headers = [
  82. { title: '', key: 'picUrl', sortable: false },
  83. { title: '商品名称', key: 'spuName', sortable: false },
  84. { title: '规格', key: 'contactAddress', sortable: false, value: item => item.properties.map((property) => property.valueName).join(' ') },
  85. { title: '单价', key: 'price', sortable: false, value: item => '¥' + fen2yuan(item.price) },
  86. { title: '数量', key: 'count', sortable: false },
  87. { title: '操作', sortable: false, key: 'actions' }
  88. ]
  89. onMounted(async () =>{
  90. const data = await getMallOrderDetail(id)
  91. const result = await getLuckLotteryRecordByOrderId(id)
  92. if (!data) {
  93. Snackbar.warning('订单不存在')
  94. setTimeout(() => {
  95. window.close()
  96. }, 1000)
  97. return
  98. }
  99. order.value = data
  100. order.value.lottery = result // 赠品信息
  101. })
  102. const showBanner = computed(() => (order) => {
  103. return order?.items?.length ? order.items.every(k => k.spuType === '0') : false
  104. })
  105. // 下载附件
  106. const handleDownload = (url, name) => {
  107. getBlob(url).then(blob => {
  108. saveAs(blob, name)
  109. })
  110. }
  111. // 跳转商品详情
  112. const handleToGoodsDetail = (item) => {
  113. window.open(`/mall/goodsDetail/${item.spuId}`)
  114. }
  115. </script>
  116. <style scoped lang="scss">
  117. </style>