From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目
---
src/views/mall/trade/order/components/OrderTableColumn.vue | 303 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 303 insertions(+), 0 deletions(-)
diff --git a/src/views/mall/trade/order/components/OrderTableColumn.vue b/src/views/mall/trade/order/components/OrderTableColumn.vue
new file mode 100644
index 0000000..6e387cf
--- /dev/null
+++ b/src/views/mall/trade/order/components/OrderTableColumn.vue
@@ -0,0 +1,303 @@
+<template>
+ <el-table-column class-name="order-table-col">
+ <template #header>
+ <div class="flex items-center" style="width: 100%">
+ <div :style="{ width: orderTableHeadWidthList[0] + 'px' }" class="flex justify-center">
+ 鍟嗗搧淇℃伅
+ </div>
+ <div :style="{ width: orderTableHeadWidthList[1] + 'px' }" class="flex justify-center">
+ 鍗曚环(鍏�)/鏁伴噺
+ </div>
+ <div :style="{ width: orderTableHeadWidthList[2] + 'px' }" class="flex justify-center">
+ 鍞悗鐘舵��
+ </div>
+ <div :style="{ width: orderTableHeadWidthList[3] + 'px' }" class="flex justify-center">
+ 瀹炰粯閲戦(鍏�)
+ </div>
+ <div :style="{ width: orderTableHeadWidthList[4] + 'px' }" class="flex justify-center">
+ 涔板/鏀惰揣浜�
+ </div>
+ <div :style="{ width: orderTableHeadWidthList[5] + 'px' }" class="flex justify-center">
+ 閰嶉�佹柟寮�
+ </div>
+ <div :style="{ width: orderTableHeadWidthList[6] + 'px' }" class="flex justify-center">
+ 璁㈠崟鐘舵��
+ </div>
+ <div :style="{ width: orderTableHeadWidthList[7] + 'px' }" class="flex justify-center">
+ 鎿嶄綔
+ </div>
+ </div>
+ </template>
+ <template #default="scope">
+ <el-table
+ :ref="setOrderTableRef"
+ :border="true"
+ :data="scope.row.items"
+ :header-cell-style="headerStyle"
+ :span-method="spanMethod"
+ style="width: 100%"
+ >
+ <el-table-column min-width="300" prop="spuName">
+ <template #header>
+ <div
+ class="h-[35px] flex items-center -mx-[10px] px-[20px]"
+ style="background-color: var(--app-content-bg-color)"
+ >
+ <span class="mr-20px">璁㈠崟鍙凤細{{ scope.row.no }} </span>
+ <span class="mr-20px">涓嬪崟鏃堕棿锛歿{ formatDate(scope.row.createTime) }}</span>
+ <span>璁㈠崟鏉ユ簮锛�</span>
+ <dict-tag :type="DICT_TYPE.TERMINAL" :value="scope.row.terminal" class="mr-20px" />
+ <span>鏀粯鏂瑰紡锛�</span>
+ <dict-tag
+ v-if="scope.row.payChannelCode"
+ :type="DICT_TYPE.PAY_CHANNEL_CODE"
+ :value="scope.row.payChannelCode"
+ class="mr-20px"
+ />
+ <span v-else class="mr-20px">鏈敮浠�</span>
+ <span v-if="scope.row.payTime" class="mr-20px">
+ 鏀粯鏃堕棿锛歿{ formatDate(scope.row.payTime) }}
+ </span>
+ <span>璁㈠崟绫诲瀷锛�</span>
+ <dict-tag :type="DICT_TYPE.TRADE_ORDER_TYPE" :value="scope.row.type" />
+ </div>
+ </template>
+ <template #default="{ row }">
+ <div class="flex flex-wrap">
+ <div class="mb-[10px] mr-[10px] flex items-start">
+ <div class="mr-[10px]">
+ <el-image
+ :src="row.picUrl"
+ class="!h-[45px] !w-[45px]"
+ fit="contain"
+ @click="imagePreview(row.picUrl)"
+ >
+ <template #error>
+ <div class="image-slot">
+ <icon icon="ep:picture" />
+ </div>
+ </template>
+ </el-image>
+ </div>
+ <ElTooltip :content="row.spuName" placement="top">
+ <span class="overflow-ellipsis max-h-[45px] overflow-hidden">
+ {{ row.spuName }}
+ </span>
+ </ElTooltip>
+ </div>
+ <el-tag
+ v-for="property in row.properties"
+ :key="property.propertyId"
+ class="mb-[10px] mr-[10px]"
+ >
+ {{ property.propertyName }}: {{ property.valueName }}
+ </el-tag>
+ </div>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍟嗗搧鍘熶环*鏁伴噺" prop="price" width="150">
+ <template #default="{ row }">
+ {{ floatToFixed2(row.price) }} 鍏� / {{ row.count }}
+ </template>
+ </el-table-column>
+ <el-table-column label="鍞悗鐘舵��" prop="afterSaleStatus" width="120">
+ <template #default="{ row }">
+ <dict-tag
+ :type="DICT_TYPE.TRADE_ORDER_ITEM_AFTER_SALE_STATUS"
+ :value="row.afterSaleStatus"
+ />
+ </template>
+ </el-table-column>
+ <el-table-column align="center" label="瀹為檯鏀粯" min-width="120" prop="payPrice">
+ <template #default>
+ {{ floatToFixed2(scope.row.payPrice) + '鍏�' }}
+ </template>
+ </el-table-column>
+ <el-table-column label="涔板/鏀惰揣浜�" min-width="160">
+ <template #default>
+ <!-- 蹇�掑彂璐� -->
+ <div
+ v-if="scope.row.deliveryType === DeliveryTypeEnum.EXPRESS.type"
+ class="flex flex-col"
+ >
+ <span>涔板锛歿{ scope.row.user?.nickname }}</span>
+ <span>
+ 鏀惰揣浜猴細{{ scope.row.receiverName }} {{ scope.row.receiverMobile }}
+ {{ scope.row.receiverAreaName }} {{ scope.row.receiverDetailAddress }}
+ </span>
+ </div>
+ <!-- 鑷彁 -->
+ <div
+ v-if="scope.row.deliveryType === DeliveryTypeEnum.PICK_UP.type"
+ class="flex flex-col"
+ >
+ <span>
+ 闂ㄥ簵鍚嶇О锛�
+ {{ pickUpStoreList.find((p) => p.id === scope.row.pickUpStoreId)?.name }}
+ </span>
+ <span>
+ 闂ㄥ簵鎵嬫満锛�
+ {{ pickUpStoreList.find((p) => p.id === scope.row.pickUpStoreId)?.phone }}
+ </span>
+ <span>
+ 鑷彁闂ㄥ簵:
+ {{ pickUpStoreList.find((p) => p.id === scope.row.pickUpStoreId)?.detailAddress }}
+ </span>
+ </div>
+ </template>
+ </el-table-column>
+ <el-table-column align="center" label="閰嶉�佹柟寮�" width="120">
+ <template #default>
+ <dict-tag :type="DICT_TYPE.TRADE_DELIVERY_TYPE" :value="scope.row.deliveryType" />
+ </template>
+ </el-table-column>
+ <el-table-column align="center" label="璁㈠崟鐘舵��" width="120">
+ <template #default>
+ <dict-tag :type="DICT_TYPE.TRADE_ORDER_STATUS" :value="scope.row.status" />
+ </template>
+ </el-table-column>
+ <el-table-column align="center" fixed="right" label="鎿嶄綔" width="160">
+ <template #default>
+ <slot :row="scope.row"></slot>
+ </template>
+ </el-table-column>
+ </el-table>
+ </template>
+ </el-table-column>
+</template>
+<script lang="ts" setup>
+import { nextTick, onMounted, onUnmounted, watch } from 'vue'
+import { DICT_TYPE } from '@/utils/dict'
+import { DeliveryTypeEnum } from '@/utils/constants'
+import { formatDate } from '@/utils/formatTime'
+import { floatToFixed2 } from '@/utils'
+import * as TradeOrderApi from '@/api/mall/trade/order'
+import { OrderVO } from '@/api/mall/trade/order'
+import type { TableColumnCtx, TableInstance } from 'element-plus'
+import { createImageViewer } from '@/components/ImageViewer'
+import type { DeliveryPickUpStoreVO } from '@/api/mall/trade/delivery/pickUpStore'
+
+defineOptions({ name: 'OrderTableColumn' })
+
+const props = defineProps<{
+ list: OrderVO[]
+ pickUpStoreList: DeliveryPickUpStoreVO[]
+}>()
+
+const headerStyle = ({ row, columnIndex }: any) => {
+ // 琛ㄥご绗竴琛岀涓�鍒楀崰 8
+ if (columnIndex === 0) {
+ row[columnIndex].colSpan = 8
+ } else {
+ // 鍏朵綑鐨勪笉瑕�
+ row[columnIndex].colSpan = 0
+ return {
+ display: 'none'
+ }
+ }
+}
+
+interface SpanMethodProps {
+ row: TradeOrderApi.OrderItemRespVO
+ column: TableColumnCtx<TradeOrderApi.OrderItemRespVO>
+ rowIndex: number
+ columnIndex: number
+}
+
+type spanMethodResp = number[] | { rowspan: number; colspan: number } | undefined
+const spanMethod = ({ row, rowIndex, columnIndex }: SpanMethodProps): spanMethodResp => {
+ const len = props.list.find(
+ (order) => order.items?.findIndex((item) => item.id === row.id) !== -1
+ )?.items?.length
+ // 瑕佸悎骞剁殑鍒楋紝浠庨浂寮�濮�
+ const colIndex = [3, 4, 5, 6, 7]
+ if (colIndex.includes(columnIndex)) {
+ // 闄や簡绗竴琛屽叾浣欑殑涓嶈
+ if (rowIndex !== 0) {
+ return {
+ rowspan: 0,
+ colspan: 0
+ }
+ }
+ // 鍔ㄦ�佸悎骞惰
+ return {
+ rowspan: len!,
+ colspan: 1
+ }
+ }
+}
+
+const orderTableHeadWidthList = ref([300, 150, 120, 120, 160, 120, 120, 160]) // 澶撮儴 col 瀹藉害鍒濆鍖�
+let isFirstTable = false // 鏍囪鏄惁宸插鐞嗙涓�涓〃鏍�
+let firstTableInstance: TableInstance | null = null
+
+/** 瑙e喅 ref 鍦� v-for 涓殑鑾峰彇闂*/
+const setOrderTableRef = async (el: TableInstance) => {
+ if (!el) return
+ // 鍙鐞嗙涓�涓〃鏍煎疄渚�
+ if (!isFirstTable) {
+ isFirstTable = true
+ firstTableInstance = el
+ // 浣跨敤 nextTick 纭繚 DOM 宸插畬鍏ㄦ覆鏌�
+ await nextTick()
+ tableHeadWidthAuto(el)
+ }
+}
+
+/** 澶撮儴瀹藉害鑷�傚簲 */
+const tableHeadWidthAuto = (el: TableInstance) => {
+ if (!el) return
+ const columns = el.store.states.columns.value
+ if (columns.length === 0) {
+ return
+ }
+ columns.forEach((col: TableColumnCtx<TableInstance>, index: number) => {
+ if (col.realWidth) {
+ orderTableHeadWidthList.value[index] = col.realWidth
+ }
+ })
+}
+
+/** 鐩戝惉绐楀彛澶у皬鍙樺寲锛岄噸鏂拌绠楄〃澶村搴� */
+const handleResize = async () => {
+ if (firstTableInstance) {
+ await nextTick()
+ tableHeadWidthAuto(firstTableInstance!)
+ }
+}
+
+/** 鐩戝惉鍒楄〃鏁版嵁鍙樺寲锛岄噸鏂拌绠楄〃澶村搴� */
+watch(
+ () => props.list,
+ async () => {
+ // 鏁版嵁鍙樺寲鍚庯紝绛夊緟 DOM 鏇存柊瀹屾垚鍐嶉噸鏂拌绠楀搴�
+ await nextTick()
+ if (firstTableInstance) {
+ // 寤惰繜涓�灏忔鏃堕棿锛岀‘淇濊〃鏍煎凡瀹屽叏娓叉煋
+ await new Promise((resolve) => setTimeout(resolve, 100))
+ tableHeadWidthAuto(firstTableInstance!)
+ }
+ },
+ { deep: true }
+)
+
+onMounted(() => {
+ window.addEventListener('resize', handleResize)
+})
+
+onUnmounted(() => {
+ window.removeEventListener('resize', handleResize)
+})
+
+/** 鍟嗗搧鍥鹃瑙� */
+const imagePreview = (imgUrl: string) => {
+ createImageViewer({
+ urlList: [imgUrl]
+ })
+}
+</script>
+<style lang="scss" scoped>
+:deep(.order-table-col > .cell) {
+ padding: 0;
+}
+</style>
--
Gitblit v1.8.0