Переглянути джерело

feat(customer-detail): add red packet tab and component for customer details

- Introduced a new tab for "红包" (Red Packet) in the customer detail view.
- Created a new component for displaying red packet information, including source, amount, threshold, and order details.
- Enhanced the customer detail functionality to dynamically load red packet data based on the selected customer.
ylong 1 тиждень тому
батько
коміт
097a7b559a

+ 4 - 0
src/views/customer/list/components/customer-detail.vue

@@ -57,6 +57,9 @@
             <el-tab-pane label="搜索记录" name="searchLog">
                 <search-log :row="currentRow" />
             </el-tab-pane>
+            <el-tab-pane label="红包" name="redPacket">
+                <red-packet :row="currentRow" />
+            </el-tab-pane>
         </el-tabs>
     </ele-drawer>
 </template>
@@ -66,6 +69,7 @@
     import accountChange from '@/views/customer/list/components/detail/account-change.vue';
     import scanLog from '@/views/customer/list/components/detail/scan-log.vue';
     import searchLog from '@/views/customer/list/components/detail/search-log.vue';
+    import redPacket from '@/views/customer/list/components/detail/red-packet.vue';
     import recommendInfo from '@/views/customer/list/components/detail/recommend-info.vue';
     import fallbackInfo from '@/views/customer/list/components/detail/fallback-info.vue';
     import request from '@/utils/request';

+ 147 - 0
src/views/customer/list/components/detail/red-packet.vue

@@ -0,0 +1,147 @@
+<template>
+    <div>
+        <common-table
+            ref="pageRef"
+            :pageConfig="pageConfig"
+            :columns="columns"
+            :tools="false"
+            :bodyStyle="{ padding: 0 }"
+        >
+            <template #orderNo="{ row }">
+                <el-button
+                    v-if="orderNoOf(row)"
+                    type="primary"
+                    link
+                    @click="openOrder(row)"
+                >
+                    {{ orderNoOf(row) }}
+                </el-button>
+            </template>
+        </common-table>
+        <order-detail ref="orderDetailRef" />
+    </div>
+</template>
+
+<script setup>
+    import { ref, reactive, watch } from 'vue';
+    import CommonTable from '@/components/CommonPage/CommonTable.vue';
+    import OrderDetail from '@/views/mallOrder/all/components/order-detail.vue';
+
+    defineOptions({ name: 'CustomerRedPacket' });
+
+    const props = defineProps({
+        row: {
+            type: Object,
+            default() {
+                return {};
+            }
+        }
+    });
+
+    const pageRef = ref(null);
+    const orderDetailRef = ref(null);
+
+    const pageConfig = reactive({
+        fileName: '客户红包',
+        cacheKey: 'customerRedPacketTable',
+        pageUrl: '',
+        params: {}
+    });
+
+    const sourceMap = {
+        1: '普通红包',
+        2: '惊喜红包',
+        3: '红包码红包'
+    };
+
+    function formatSource(row) {
+        const text = row.sourceName || row.couponSourceName;
+        if (text) return text;
+        const type = row.type ?? row.redType ?? row.couponType;
+        if (type == null || type === '') return '';
+        return sourceMap[type] || sourceMap[String(type)] || type;
+    }
+
+    function formatThreshold(row) {
+        if (row.thresholdText) return row.thresholdText;
+        const money = row.thresholdMoney;
+        if (money === 0 || money === '0') return '无门槛';
+        if (money == null || money === '') return '';
+        return `满${money}可用`;
+    }
+
+    function formatAmount(row) {
+        const money = row.faceMoney ?? row.redPrice ?? row.amount;
+        if (money == null || money === '') return '';
+        return money;
+    }
+
+    function orderNoOf(row) {
+        return row.orderId || row.orderNo || '';
+    }
+
+    const columns = ref([
+        { label: '序号', type: 'index', align: 'center', width: 70 },
+        {
+            label: '红包来源',
+            prop: 'type',
+            align: 'center',
+            minWidth: 120,
+            formatter: (row) => formatSource(row)
+        },
+        {
+            label: '红包金额',
+            prop: 'faceMoney',
+            align: 'center',
+            minWidth: 100,
+            formatter: (row) => formatAmount(row)
+        },
+        {
+            label: '红包门槛',
+            prop: 'thresholdMoney',
+            align: 'center',
+            minWidth: 140,
+            formatter: (row) => formatThreshold(row)
+        },
+        {
+            label: '领取时间',
+            prop: 'createTime',
+            align: 'center',
+            minWidth: 170,
+            formatter: (row) => row.createTime || row.drawTime || ''
+        },
+        {
+            label: '使用时间',
+            prop: 'useTime',
+            align: 'center',
+            minWidth: 170
+        },
+        {
+            label: '订单编号',
+            prop: 'orderId',
+            align: 'center',
+            minWidth: 120,
+            slot: 'orderNo'
+        }
+    ]);
+
+    watch(
+        () => props.row,
+        (row) => {
+            if (!row?.id) return;
+            pageConfig.pageUrl = '/shop/couponInfo/getClaimPagelist';
+            pageConfig.params = { userId: row.id };
+            pageRef.value?.reload();
+        },
+        {
+            immediate: true,
+            deep: true
+        }
+    );
+
+    function openOrder(row) {
+        const orderId = orderNoOf(row);
+        if (!orderId) return;
+        orderDetailRef.value?.handleOpen({ orderId });
+    }
+</script>