Răsfoiți Sursa

style: 格式化代码并优化样式

- 移除空样式标签并压缩为单行
- 调整代码缩进和格式
- 拆分长条件表达式为多行
- 统一箭头函数格式
- 优化表格和弹窗的布局样式
- 添加物流信息展示功能
ylong 1 săptămână în urmă
părinte
comite
9c65a3ebda

+ 1 - 2
src/views/mallOrder/all/components/push-sms-dialog.vue

@@ -82,5 +82,4 @@
     });
 </script>
 
-<style scoped>
-</style>
+<style scoped></style>

+ 13 - 4
src/views/mallOrder/all/components/refund-dialog.vue

@@ -140,8 +140,14 @@
 
     const isAllSelected = computed(() => {
         if (!order.value?.detailList) return false;
-        const totalItems = order.value.detailList.reduce((sum, item) => sum + item.num, 0);
-        const selectedItems = selectedRows.value.reduce((sum, item) => sum + (item.refundQty || 0), 0);
+        const totalItems = order.value.detailList.reduce(
+            (sum, item) => sum + item.num,
+            0
+        );
+        const selectedItems = selectedRows.value.reduce(
+            (sum, item) => sum + (item.refundQty || 0),
+            0
+        );
         return totalItems > 0 && totalItems === selectedItems;
     });
 
@@ -150,7 +156,8 @@
         if (isAllSelected.value) {
             // 如果全部退款,商品退款金额 = 订单实付金额 - 订单运费
             // 避免因单价精度导致的 1 分钱差值
-            const originalProductTotal = originalTotal.value - maxShippingFee.value;
+            const originalProductTotal =
+                originalTotal.value - maxShippingFee.value;
             return originalProductTotal > 0 ? originalProductTotal : 0;
         }
 
@@ -169,7 +176,9 @@
     });
 
     const totalRefundAmount = computed(() => {
-        const shippingCents = Math.round((parseFloat(shippingRefund.value) || 0) * 100);
+        const shippingCents = Math.round(
+            (parseFloat(shippingRefund.value) || 0) * 100
+        );
         const productCents = Math.round(productRefundAmount.value * 100);
         return (productCents + shippingCents) / 100;
     });

+ 5 - 1
src/views/mallOrder/refund/components/negotiation-apply-dialog.vue

@@ -76,7 +76,11 @@
                             >* 拒绝原因</div
                         >
                         <dict-data
-                            :code="refundType == 2 ? 'shop_refund_money_reason' : 'shop_refund_reason'"
+                            :code="
+                                refundType == 2
+                                    ? 'shop_refund_money_reason'
+                                    : 'shop_refund_reason'
+                            "
                             v-model="form.reason"
                             placeholder="请选择拒绝原因"
                             class="w-full"

+ 1 - 2
src/views/mallOrder/refund/components/push-sms-dialog.vue

@@ -84,5 +84,4 @@
     });
 </script>
 
-<style scoped>
-</style>
+<style scoped></style>

+ 157 - 16
src/views/mallOrder/refund/components/refund-detail-dialog.vue

@@ -162,6 +162,34 @@
                             <CopyDocument />
                         </el-icon>
                     </div>
+                    <div class="info-item" v-if="form.waybillCode">
+                        <span class="label">退货物流:</span>
+                        <span class="value">
+                            <div>
+                                {{ form.expressName || '-' }}
+                                {{ form.waybillCode }}
+                                <el-button
+                                    link
+                                    type="success"
+                                    class="ml-2"
+                                    @click="
+                                        openTracking(
+                                            '退货物流动态',
+                                            form.trackingVoList
+                                        )
+                                    "
+                                    >查看</el-button
+                                >
+                            </div>
+                            <div
+                                v-if="returnLatestTrack"
+                                class="text-xs text-gray-500 mt-1"
+                            >
+                                {{ returnLatestTrack.context }}
+                                {{ returnLatestTrack.ftime }}
+                            </div>
+                        </span>
+                    </div>
                 </div>
 
                 <!-- 中间:交易信息 -->
@@ -246,24 +274,59 @@
                     </div>
 
                     <div class="logistics-info mt-4 p-3 bg-gray-50 rounded">
-                        <div class="font-bold mb-2">发货物流信息:</div>
-                        <div v-if="form.waybillCode">
-                            <div class="text-sm mb-1">
-                                {{ form.expressName }} {{ form.waybillCode }}
-                                <el-icon
-                                    class="copy-icon"
-                                    @click="handleCopy(form.waybillCode)"
+                        <div class="font-bold mb-2">原始订单物流信息:</div>
+                        <template
+                            v-if="
+                                form.originTrackingList &&
+                                form.originTrackingList.length
+                            "
+                        >
+                            <div
+                                v-for="(item, idx) in form.originTrackingList"
+                                :key="idx"
+                                class="mb-3"
+                            >
+                                <div class="text-sm mb-1 flex items-center">
+                                    <span>
+                                        {{ item.originExpressName || '-' }}
+                                        {{ item.originWaybillCode || '-' }}
+                                    </span>
+                                    <el-icon
+                                        v-if="item.originWaybillCode"
+                                        class="copy-icon ml-1"
+                                        @click="handleCopy(item.originWaybillCode)"
+                                    >
+                                        <CopyDocument />
+                                    </el-icon>
+                                    <el-button
+                                        link
+                                        type="success"
+                                        class="ml-2"
+                                        v-if="item.originWaybillCode"
+                                        @click="
+                                            openTracking(
+                                                '原始订单物流动态',
+                                                item.originTrackingVoList
+                                            )
+                                        "
+                                        >查看</el-button
+                                    >
+                                </div>
+                                <div
+                                    v-if="
+                                        item.originTrackingVoList &&
+                                        item.originTrackingVoList.length
+                                    "
+                                    class="text-xs text-gray-500"
                                 >
-                                    <CopyDocument />
-                                </el-icon>
-                            </div>
-                            <div class="text-xs text-gray-500">
-                                您已在云南财大南苑荟华1栋菜鸟驿站完成取件,感谢使用菜鸟驿站,期待再次为您服务。
+                                    {{ item.originTrackingVoList[0].context }}
+                                    {{ item.originTrackingVoList[0].ftime }}
+                                </div>
                             </div>
+                        </template>
+                        <div v-else class="text-sm text-gray-400">
+                            暂无物流信息
                         </div>
-                        <div v-else class="text-sm text-gray-400"
-                            >暂无物流信息</div
-                        >
                     </div>
                 </div>
 
@@ -376,6 +439,12 @@
                 <el-button @click="handleAgree" :disabled="!canOperate">{{
                     isRefundOnly ? '同意退款' : '同意退货'
                 }}</el-button>
+                <el-button
+                    v-if="isPlatformConfirmReceipt"
+                    type="primary"
+                    @click="handleConfirmReceiptRefund"
+                    >确认收货,同意退款</el-button
+                >
                 <el-button
                     v-if="isRefundOnly"
                     type="primary"
@@ -429,6 +498,48 @@
             ref="leaveMessageDialogRef"
             @success="handleNegotiationSuccess"
         />
+        <ele-modal
+            :width="600"
+            v-model="trackingVisible"
+            :title="trackingTitle"
+            :body-style="{ padding: '20px' }"
+        >
+            <el-timeline
+                style="max-height: 500px; overflow-y: auto"
+                v-if="trackingRecords && trackingRecords.length > 0"
+            >
+                <el-timeline-item
+                    v-for="(activity, index) in trackingRecords"
+                    :key="index"
+                    :timestamp="activity.ftime"
+                    :type="index === 0 ? 'success' : ''"
+                    :color="index === 0 ? '#0bbd87' : ''"
+                >
+                    <div>
+                        <div style="margin-bottom: 5px" v-if="activity.status">
+                            <el-tag
+                                size="small"
+                                :type="index === 0 ? 'success' : 'info'"
+                                >{{ activity.status }}</el-tag
+                            >
+                        </div>
+                        <div
+                            style="
+                                color: #606266;
+                                font-size: 13px;
+                                line-height: 1.5;
+                            "
+                            >{{ activity.context }}</div
+                        >
+                    </div>
+                </el-timeline-item>
+            </el-timeline>
+            <el-empty
+                v-else
+                description="暂无物流信息"
+                :image-size="60"
+            />
+        </ele-modal>
     </ele-modal>
 </template>
 
@@ -457,6 +568,9 @@
     const confirmRefundDialogRef = ref(null);
     const negotiateReturnDialogRef = ref(null);
     const leaveMessageDialogRef = ref(null);
+    const trackingVisible = ref(false);
+    const trackingTitle = ref('物流动态');
+    const trackingRecords = ref([]);
 
     const deadline = ref(0);
 
@@ -507,6 +621,23 @@
         return ['1', '3'].includes(String(form.value.status));
     });
 
+    const isPlatformConfirmReceipt = computed(() => {
+        return String(form.value.status) === '7';
+    });
+
+    const returnLatestTrack = computed(() => {
+        if (form.value.trackingVoList && form.value.trackingVoList.length > 0) {
+            return form.value.trackingVoList[0];
+        }
+        return null;
+    });
+
+    const openTracking = (title, records) => {
+        trackingTitle.value = title || '物流动态';
+        trackingRecords.value = records || [];
+        trackingVisible.value = true;
+    };
+
     const handleOpen = (row) => {
         if (row && row.refundOrderId) {
             visible.value = true;
@@ -668,7 +799,10 @@
 
     const handleRefuse = () => {
         if (refuseDialogRef.value) {
-            refuseDialogRef.value.open(form.value.refundOrderId, Number(form.value.refundType));
+            refuseDialogRef.value.open(
+                form.value.refundOrderId,
+                Number(form.value.refundType)
+            );
         }
     };
 
@@ -683,6 +817,13 @@
         agreeDialogRef.value?.open(form.value.refundOrderId);
     };
 
+    const handleConfirmReceiptRefund = () => {
+        confirmRefundDialogRef.value?.open(
+            form.value.refundOrderId,
+            form.value.refundMoneyFinal || form.value.refundMoney
+        );
+    };
+
     const handleLeaveMessage = () => {
         if (leaveMessageDialogRef.value) {
             leaveMessageDialogRef.value.open(form.value.refundOrderId);

+ 5 - 1
src/views/mallOrder/refund/components/refuse-dialog.vue

@@ -8,7 +8,11 @@
         <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
             <el-form-item label="驳回原因" prop="reason">
                 <dict-data
-                    :code="refundType == 2 ? 'shop_refund_money_reason' : 'shop_refund_reason'"
+                    :code="
+                        refundType == 2
+                            ? 'shop_refund_money_reason'
+                            : 'shop_refund_reason'
+                    "
                     v-model="form.reason"
                     placeholder="请选择"
                     class="w-full"

+ 3 - 2
src/views/marketing/shareDiscount/rules/index.vue

@@ -200,11 +200,12 @@
         try {
             const res = await request.get('/activity/reduce/manage/rule/get');
             console.log(res, 'xxxx');
-            
+
             if (res.data.code === 200) {
                 const data = res.data.data;
                 Object.assign(form, data);
-                form.reduceValidScenario = data.reduceValidScenario?.map((v) => v.toString()) || [];
+                form.reduceValidScenario =
+                    data.reduceValidScenario?.map((v) => v.toString()) || [];
                 form.reduceScope = data.reduceScope + '';
                 if (form.mobile) {
                     needVerification.value = true;

+ 13 - 15
src/views/salesOps/booklist/components/booklist-bind.vue

@@ -57,7 +57,7 @@
 
             selectedBooks.value = mappedList;
             originalIsbns.value = mappedList.map((b) => b.isbn);
-            mappedList.forEach(b => {
+            mappedList.forEach((b) => {
                 originalBooksMap.value[b.isbn] = b;
             });
         } catch (e) {}
@@ -70,19 +70,17 @@
         try {
             const currentIsbns = rows.map((b) => b.isbn);
 
-            const toAdd = rows.filter(
-                (b) => {
-                    if (!originalIsbns.value.includes(b.isbn)) {
-                        return true;
-                    }
-                    // Check if description changed
-                    const orig = originalBooksMap.value[b.isbn];
-                    if (orig && (orig.bookDesc || '') !== (b.bookDesc || '')) {
-                        return true;
-                    }
-                    return false;
+            const toAdd = rows.filter((b) => {
+                if (!originalIsbns.value.includes(b.isbn)) {
+                    return true;
                 }
-            );
+                // Check if description changed
+                const orig = originalBooksMap.value[b.isbn];
+                if (orig && (orig.bookDesc || '') !== (b.bookDesc || '')) {
+                    return true;
+                }
+                return false;
+            });
 
             const toRemove = originalIsbns.value.filter(
                 (isbn) => !currentIsbns.includes(isbn)
@@ -91,11 +89,11 @@
             const promises = [];
 
             if (toAdd.length > 0) {
-                const bindBookList = toAdd.map(b => ({
+                const bindBookList = toAdd.map((b) => ({
                     bookIsbn: b.isbn,
                     bookDesc: b.bookDesc || ''
                 }));
-                const bookIsbnList = toAdd.map(b => b.isbn);
+                const bookIsbnList = toAdd.map((b) => b.isbn);
 
                 promises.push(
                     request.post('/book/showIndex/bindBook', {

+ 156 - 52
src/views/salesOps/components/GoodsSelectDialog.vue

@@ -35,18 +35,28 @@
         <div class="flex justify-between items-end mb-4">
             <!-- Tabs -->
             <div class="flex space-x-6 border-b border-gray-200 w-64 mr-4">
-                <div 
+                <div
                     class="cursor-pointer pb-2 px-2 whitespace-nowrap"
-                    :class="activeTab === 'all' ? 'text-primary border-b-2 border-primary font-medium' : 'text-gray-600'"
+                    :class="
+                        activeTab === 'all'
+                            ? 'text-primary border-b-2 border-primary font-medium'
+                            : 'text-gray-600'
+                    "
                     @click="activeTab = 'all'"
-                >全部</div>
-                <div 
+                    >全部</div
+                >
+                <div
                     class="cursor-pointer pb-2 px-2 whitespace-nowrap"
-                    :class="activeTab === 'selected' ? 'text-primary border-b-2 border-primary font-medium' : 'text-gray-600'"
+                    :class="
+                        activeTab === 'selected'
+                            ? 'text-primary border-b-2 border-primary font-medium'
+                            : 'text-gray-600'
+                    "
                     @click="activeTab = 'selected'"
-                >已选择 ({{ selectedCount }})</div>
+                    >已选择 ({{ selectedCount }})</div
+                >
             </div>
-            
+
             <!-- Pagination -->
             <el-pagination
                 v-if="activeTab === 'all'"
@@ -74,7 +84,12 @@
             border
             height="400px"
         >
-            <el-table-column type="selection" width="55" align="center" :reserve-selection="true" />
+            <el-table-column
+                type="selection"
+                width="55"
+                align="center"
+                :reserve-selection="true"
+            />
             <el-table-column label="图示" width="80" align="center">
                 <template #default="{ row }">
                     <el-image
@@ -84,22 +99,44 @@
                         preview-teleported
                     >
                         <template #error>
-                            <div class="w-10 h-10 bg-gray-100 flex items-center justify-center text-gray-400">
+                            <div
+                                class="w-10 h-10 bg-gray-100 flex items-center justify-center text-gray-400"
+                            >
                                 <el-icon><Picture /></el-icon>
                             </div>
                         </template>
                     </el-image>
                 </template>
             </el-table-column>
-            <el-table-column prop="isbn" label="ISBN" width="140" align="center" />
-            <el-table-column prop="bookName" label="书名" min-width="200" show-overflow-tooltip />
-            
+            <el-table-column
+                prop="isbn"
+                label="ISBN"
+                width="140"
+                align="center"
+            />
+            <el-table-column
+                prop="bookName"
+                label="书名"
+                min-width="200"
+                show-overflow-tooltip
+            />
+
             <template v-if="showDescription">
                 <el-table-column label="商品描述" min-width="200">
                     <template #default="{ row }">
-                        <div v-if="!row._editingDesc" class="cursor-pointer flex items-center" @click="row._editingDesc = true">
-                            <span class="truncate flex-1" :title="row.bookDesc || '点击输入描述'">{{ row.bookDesc || '点击输入描述' }}</span>
-                            <el-icon class="ml-1 text-gray-400"><Edit /></el-icon>
+                        <div
+                            v-if="!row._editingDesc"
+                            class="cursor-pointer flex items-center"
+                            @click="row._editingDesc = true"
+                        >
+                            <span
+                                class="truncate flex-1"
+                                :title="row.bookDesc || '点击输入描述'"
+                                >{{ row.bookDesc || '点击输入描述' }}</span
+                            >
+                            <el-icon class="ml-1 text-gray-400"
+                                ><Edit
+                            /></el-icon>
                         </div>
                         <el-input
                             v-else
@@ -108,15 +145,25 @@
                             size="small"
                             @blur="row._editingDesc = false"
                             @keyup.enter="row._editingDesc = false"
-                            @input="val => updateSelectionDesc(row, val)"
+                            @input="(val) => updateSelectionDesc(row, val)"
                             autofocus
                         />
                     </template>
                 </el-table-column>
             </template>
             <template v-else>
-                <el-table-column prop="author" label="作者" width="120" show-overflow-tooltip />
-                <el-table-column prop="price" label="价格" width="100" align="center" />
+                <el-table-column
+                    prop="author"
+                    label="作者"
+                    width="120"
+                    show-overflow-tooltip
+                />
+                <el-table-column
+                    prop="price"
+                    label="价格"
+                    width="100"
+                    align="center"
+                />
             </template>
         </el-table>
 
@@ -130,10 +177,16 @@
         >
             <el-table-column width="55" align="center">
                 <template #header>
-                    <el-checkbox :model-value="true" @change="handleClearAllSelections" />
+                    <el-checkbox
+                        :model-value="true"
+                        @change="handleClearAllSelections"
+                    />
                 </template>
                 <template #default="{ row }">
-                    <el-checkbox :model-value="true" @change="() => handleRemoveSelection(row)" />
+                    <el-checkbox
+                        :model-value="true"
+                        @change="() => handleRemoveSelection(row)"
+                    />
                 </template>
             </el-table-column>
             <el-table-column label="图示" width="80" align="center">
@@ -145,22 +198,44 @@
                         preview-teleported
                     >
                         <template #error>
-                            <div class="w-10 h-10 bg-gray-100 flex items-center justify-center text-gray-400">
+                            <div
+                                class="w-10 h-10 bg-gray-100 flex items-center justify-center text-gray-400"
+                            >
                                 <el-icon><Picture /></el-icon>
                             </div>
                         </template>
                     </el-image>
                 </template>
             </el-table-column>
-            <el-table-column prop="isbn" label="ISBN" width="140" align="center" />
-            <el-table-column prop="bookName" label="书名" min-width="200" show-overflow-tooltip />
-            
+            <el-table-column
+                prop="isbn"
+                label="ISBN"
+                width="140"
+                align="center"
+            />
+            <el-table-column
+                prop="bookName"
+                label="书名"
+                min-width="200"
+                show-overflow-tooltip
+            />
+
             <template v-if="showDescription">
                 <el-table-column label="商品描述" min-width="200">
                     <template #default="{ row }">
-                        <div v-if="!row._editingDesc" class="cursor-pointer flex items-center" @click="row._editingDesc = true">
-                            <span class="truncate flex-1" :title="row.bookDesc || '点击输入描述'">{{ row.bookDesc || '点击输入描述' }}</span>
-                            <el-icon class="ml-1 text-gray-400"><Edit /></el-icon>
+                        <div
+                            v-if="!row._editingDesc"
+                            class="cursor-pointer flex items-center"
+                            @click="row._editingDesc = true"
+                        >
+                            <span
+                                class="truncate flex-1"
+                                :title="row.bookDesc || '点击输入描述'"
+                                >{{ row.bookDesc || '点击输入描述' }}</span
+                            >
+                            <el-icon class="ml-1 text-gray-400"
+                                ><Edit
+                            /></el-icon>
                         </div>
                         <el-input
                             v-else
@@ -169,15 +244,25 @@
                             size="small"
                             @blur="row._editingDesc = false"
                             @keyup.enter="row._editingDesc = false"
-                            @input="val => updateSelectionDesc(row, val)"
+                            @input="(val) => updateSelectionDesc(row, val)"
                             autofocus
                         />
                     </template>
                 </el-table-column>
             </template>
             <template v-else>
-                <el-table-column prop="author" label="作者" width="120" show-overflow-tooltip />
-                <el-table-column prop="price" label="价格" width="100" align="center" />
+                <el-table-column
+                    prop="author"
+                    label="作者"
+                    width="120"
+                    show-overflow-tooltip
+                />
+                <el-table-column
+                    prop="price"
+                    label="价格"
+                    width="100"
+                    align="center"
+                />
             </template>
         </el-table>
 
@@ -228,7 +313,7 @@
         if (activeTab.value === 'selected') {
             return;
         }
-        
+
         loading.value = true;
         try {
             const params = {
@@ -242,14 +327,18 @@
             if (res.data.code === 200) {
                 const data = res.data.data || res.data;
                 const rows = data.rows || data;
-                
+
                 const updateRowDesc = (row) => {
-                    const selectedItem = currentSelections.value.find(s => s.isbn === row.isbn);
+                    const selectedItem = currentSelections.value.find(
+                        (s) => s.isbn === row.isbn
+                    );
                     if (selectedItem && selectedItem.bookDesc !== undefined) {
                         row.bookDesc = selectedItem.bookDesc;
                         return;
                     }
-                    const defaultItem = props.defaultSelected.find(d => d.isbn === row.isbn);
+                    const defaultItem = props.defaultSelected.find(
+                        (d) => d.isbn === row.isbn
+                    );
                     if (defaultItem) {
                         row.bookDesc = defaultItem.bookDesc;
                     }
@@ -258,14 +347,21 @@
                 rows.forEach(updateRowDesc);
                 tableData.value = rows;
                 total.value = data.total || rows.length;
-                console.log('Updated tableData:', tableData.value.length, 'rows, total:', total.value);
+                console.log(
+                    'Updated tableData:',
+                    tableData.value.length,
+                    'rows, total:',
+                    total.value
+                );
 
                 // Sync selections to table
                 nextTick(() => {
                     if (tableRef.value) {
                         tableRef.value.clearSelection();
-                        rows.forEach(row => {
-                            const isSelected = currentSelections.value.some(s => s.isbn === row.isbn);
+                        rows.forEach((row) => {
+                            const isSelected = currentSelections.value.some(
+                                (s) => s.isbn === row.isbn
+                            );
                             if (isSelected) {
                                 tableRef.value.toggleRowSelection(row, true);
                             }
@@ -311,24 +407,26 @@
 
     const handleSelectionChange = (rows) => {
         // Get all selected rows from the table (only current page)
-        const currentPageSelectedIsbns = new Set(rows.map(row => row.isbn));
-        
+        const currentPageSelectedIsbns = new Set(rows.map((row) => row.isbn));
+
         // Remove rows that are no longer selected on current page
-        currentSelections.value = currentSelections.value.filter(s => 
-            currentPageSelectedIsbns.has(s.isbn) || 
-            !tableData.value.some(r => r.isbn === s.isbn)
+        currentSelections.value = currentSelections.value.filter(
+            (s) =>
+                currentPageSelectedIsbns.has(s.isbn) ||
+                !tableData.value.some((r) => r.isbn === s.isbn)
         );
-        
+
         // Add newly selected rows from current page
-        rows.forEach(row => {
-            if (!currentSelections.value.some(s => s.isbn === row.isbn)) {
+        rows.forEach((row) => {
+            if (!currentSelections.value.some((s) => s.isbn === row.isbn)) {
                 currentSelections.value.push({ ...row });
             }
         });
     };
 
     const handleClearAllSelections = (val) => {
-        if (!val) { // User clicked to uncheck
+        if (!val) {
+            // User clicked to uncheck
             currentSelections.value = [];
             if (tableRef.value) {
                 tableRef.value.clearSelection();
@@ -337,13 +435,15 @@
     };
 
     const handleRemoveSelection = (row) => {
-        const idx = currentSelections.value.findIndex(s => s.isbn === row.isbn);
+        const idx = currentSelections.value.findIndex(
+            (s) => s.isbn === row.isbn
+        );
         if (idx !== -1) {
             currentSelections.value.splice(idx, 1);
         }
         // Also untoggle in table if it's currently loaded
         if (tableRef.value) {
-            const tableRow = tableData.value.find(r => r.isbn === row.isbn);
+            const tableRow = tableData.value.find((r) => r.isbn === row.isbn);
             if (tableRow) {
                 tableRef.value.toggleRowSelection(tableRow, false);
             }
@@ -351,12 +451,14 @@
     };
 
     const updateSelectionDesc = (row, val) => {
-        const selected = currentSelections.value.find(s => s.isbn === row.isbn);
+        const selected = currentSelections.value.find(
+            (s) => s.isbn === row.isbn
+        );
         if (selected) {
             selected.bookDesc = val;
         }
         // Also update the row in tableData if it exists
-        const tableRow = tableData.value.find(r => r.isbn === row.isbn);
+        const tableRow = tableData.value.find((r) => r.isbn === row.isbn);
         if (tableRow) {
             tableRow.bookDesc = val;
         }
@@ -375,7 +477,9 @@
         if (val) {
             nextTick(() => {
                 if (props.defaultSelected && props.defaultSelected.length > 0) {
-                    currentSelections.value = JSON.parse(JSON.stringify(props.defaultSelected));
+                    currentSelections.value = JSON.parse(
+                        JSON.stringify(props.defaultSelected)
+                    );
                 } else {
                     currentSelections.value = [];
                 }
@@ -384,7 +488,7 @@
             });
         }
     });
-    
+
     defineExpose({
         reset
     });

+ 2 - 2
src/views/salesOps/decoration/components/HotSalesEdit.vue

@@ -162,8 +162,8 @@
             console.log(product, 'xxxx');
             items.value[activeIndex.value] = {
                 id: product.id, // Assuming product object has id
-                title: product.bookName, 
-                imgUrl: product.cover, 
+                title: product.bookName,
+                imgUrl: product.cover,
                 price: product.price,
                 jumpUrl: `/pages-sell/pages/detail?isbn=${product.isbn}` // Construct jumpUrl
             };

+ 13 - 15
src/views/salesOps/topics/components/topics-bind.vue

@@ -57,7 +57,7 @@
 
             selectedBooks.value = mappedList;
             originalIsbns.value = mappedList.map((b) => b.isbn);
-            mappedList.forEach(b => {
+            mappedList.forEach((b) => {
                 originalBooksMap.value[b.isbn] = b;
             });
         } catch (e) {}
@@ -70,19 +70,17 @@
         try {
             const currentIsbns = rows.map((b) => b.isbn);
 
-            const toAdd = rows.filter(
-                (b) => {
-                    if (!originalIsbns.value.includes(b.isbn)) {
-                        return true;
-                    }
-                    // Check if description changed
-                    const orig = originalBooksMap.value[b.isbn];
-                    if (orig && (orig.bookDesc || '') !== (b.bookDesc || '')) {
-                        return true;
-                    }
-                    return false;
+            const toAdd = rows.filter((b) => {
+                if (!originalIsbns.value.includes(b.isbn)) {
+                    return true;
                 }
-            );
+                // Check if description changed
+                const orig = originalBooksMap.value[b.isbn];
+                if (orig && (orig.bookDesc || '') !== (b.bookDesc || '')) {
+                    return true;
+                }
+                return false;
+            });
 
             const toRemove = originalIsbns.value.filter(
                 (isbn) => !currentIsbns.includes(isbn)
@@ -91,11 +89,11 @@
             const promises = [];
 
             if (toAdd.length > 0) {
-                const bindBookList = toAdd.map(b => ({
+                const bindBookList = toAdd.map((b) => ({
                     bookIsbn: b.isbn,
                     bookDesc: b.bookDesc || ''
                 }));
-                const bookIsbnList = toAdd.map(b => b.isbn);
+                const bookIsbnList = toAdd.map((b) => b.isbn);
 
                 promises.push(
                     request.post('/book/showIndex/bindBook', {

+ 93 - 64
src/views/salesOps/trendsRank/index.vue

@@ -1,94 +1,123 @@
 <template>
     <ele-page flex-table>
-        <common-table ref="tableRef" :pageConfig="pageConfig" :columns="columns" :tools="false" :pagination="false"
-            :datasource="fetchData">
+        <common-table
+            ref="tableRef"
+            :pageConfig="pageConfig"
+            :columns="columns"
+            :tools="false"
+            :pagination="false"
+            :datasource="fetchData"
+        >
             <template #index="{ $index }">
                 {{ $index + 1 }}
             </template>
 
             <template #image="{ row }">
-                <el-image :src="row.cover" class="w-16 h-16 rounded" fit="cover" :preview-src-list="[row.cover]"
-                    preview-teleported />
+                <el-image
+                    :src="row.cover"
+                    class="w-16 h-16 rounded"
+                    fit="cover"
+                    :preview-src-list="[row.cover]"
+                    preview-teleported
+                />
             </template>
 
             <template #info="{ row }">
                 <div>
-                    <div class="font-bold text-blue-500 hover:underline cursor-pointer">{{ row.bookName }}</div>
-                    <div class="text-xs text-gray-500 mt-1">作者: {{ row.author }}</div>
-                    <div class="text-xs text-gray-500">ISBN: {{ row.isbn }}</div>
-                    <div class="text-xs text-gray-500">出版社: {{ row.publish }}</div>
+                    <div
+                        class="font-bold text-blue-500 hover:underline cursor-pointer"
+                        >{{ row.bookName }}</div
+                    >
+                    <div class="text-xs text-gray-500 mt-1"
+                        >作者: {{ row.author }}</div
+                    >
+                    <div class="text-xs text-gray-500"
+                        >ISBN: {{ row.isbn }}</div
+                    >
+                    <div class="text-xs text-gray-500"
+                        >出版社: {{ row.publish }}</div
+                    >
                 </div>
             </template>
 
             <template #isOnSale="{ row }">
-                <el-switch :model-value="row.isOnSale === 1" @change="(val) => handleStatusChange(row, val)" />
+                <el-switch
+                    :model-value="row.isOnSale === 1"
+                    @change="(val) => handleStatusChange(row, val)"
+                />
             </template>
         </common-table>
     </ele-page>
 </template>
 
 <script setup>
-import { ref, reactive, getCurrentInstance } from 'vue';
-import CommonTable from '@/components/CommonPage/CommonTable.vue';
-import { EleMessage } from 'ele-admin-plus/es';
+    import { ref, reactive, getCurrentInstance } from 'vue';
+    import CommonTable from '@/components/CommonPage/CommonTable.vue';
+    import { EleMessage } from 'ele-admin-plus/es';
 
-defineOptions({ name: 'TrendsRank' });
+    defineOptions({ name: 'TrendsRank' });
 
-const { proxy } = getCurrentInstance();
-const tableRef = ref(null);
+    const { proxy } = getCurrentInstance();
+    const tableRef = ref(null);
 
-const pageConfig = reactive({
-    pageUrl: '/shop/shopbook/getBestsellerList',
-    fileName: '热搜榜单',
-    cacheKey: 'trends-rank-list',
-    params: {}
-});
+    const pageConfig = reactive({
+        pageUrl: '/shop/shopbook/getBestsellerList',
+        fileName: '热搜榜单',
+        cacheKey: 'trends-rank-list',
+        params: {}
+    });
 
-const columns = ref([
-    { label: '排序', type: 'index', width: 80, align: 'center' },
-    { label: '商品图', slot: 'image', width: 120, align: 'center' },
-    { label: '商品信息', slot: 'info', minWidth: 250 },
-    { label: '销量', prop: 'salesNum', align: 'center', minWidth: 100 },
-    { label: '库存', prop: 'stock', align: 'center', minWidth: 100 },
-    { label: '是否启用', slot: 'isOnSale', align: 'center', minWidth: 100 },
-    { label: '更新时间', prop: 'updateTime', align: 'center', minWidth: 180 }
-]);
-
-const fetchData = async () => {
-    try {
-        const res = await proxy.$http.get(pageConfig.pageUrl, {
-            params: pageConfig.params
-        });
-        if (res.data.code === 200) {
-            return res.data.data || [];
+    const columns = ref([
+        { label: '排序', type: 'index', width: 80, align: 'center' },
+        { label: '商品图', slot: 'image', width: 120, align: 'center' },
+        { label: '商品信息', slot: 'info', minWidth: 250 },
+        { label: '销量', prop: 'salesNum', align: 'center', minWidth: 100 },
+        { label: '库存', prop: 'stock', align: 'center', minWidth: 100 },
+        { label: '是否启用', slot: 'isOnSale', align: 'center', minWidth: 100 },
+        {
+            label: '更新时间',
+            prop: 'updateTime',
+            align: 'center',
+            minWidth: 180
         }
-        return Promise.reject(new Error(res.data.msg || '获取数据失败'));
-    } catch (e) {
-        return Promise.reject(e);
-    }
-};
-
-const reload = () => {
-    tableRef.value?.reload();
-};
+    ]);
 
-const handleStatusChange = (row, val) => {
-    const newStatus = val ? 1 : 0;
-    proxy.$http.post('/shop/shopbook/setShelfStatus', {
-        isbn: row.isbn,
-        sellStatus: newStatus
-    })
-        .then((res) => {
+    const fetchData = async () => {
+        try {
+            const res = await proxy.$http.get(pageConfig.pageUrl, {
+                params: pageConfig.params
+            });
             if (res.data.code === 200) {
-                EleMessage.success(
-                    `${row.bookName} ${newStatus === 1 ? '已启用' : '已禁用'}`
-                );
-            } else {
-                EleMessage.error(res.data.msg || '操作失败');
+                return res.data.data || [];
             }
-        })
-        .catch(() => {
-            reload();
-        });
-};
+            return Promise.reject(new Error(res.data.msg || '获取数据失败'));
+        } catch (e) {
+            return Promise.reject(e);
+        }
+    };
+
+    const reload = () => {
+        tableRef.value?.reload();
+    };
+
+    const handleStatusChange = (row, val) => {
+        const newStatus = val ? 1 : 0;
+        proxy.$http
+            .post('/shop/shopbook/setShelfStatus', {
+                isbn: row.isbn,
+                sellStatus: newStatus
+            })
+            .then((res) => {
+                if (res.data.code === 200) {
+                    EleMessage.success(
+                        `${row.bookName} ${newStatus === 1 ? '已启用' : '已禁用'}`
+                    );
+                } else {
+                    EleMessage.error(res.data.msg || '操作失败');
+                }
+            })
+            .catch(() => {
+                reload();
+            });
+    };
 </script>

+ 62 - 62
src/views/salesOps/trendsSearch/components/trends-search-edit.vue

@@ -12,74 +12,74 @@
 </template>
 
 <script setup>
-import { ref, computed } from 'vue';
-import SimpleFormModal from '@/components/CommonPage/SimpleFormModal.vue';
+    import { ref, computed } from 'vue';
+    import SimpleFormModal from '@/components/CommonPage/SimpleFormModal.vue';
 
-const emit = defineEmits(['success']);
-const modalRef = ref(null);
-const title = ref('添加热搜词');
+    const emit = defineEmits(['success']);
+    const modalRef = ref(null);
+    const title = ref('添加热搜词');
 
-const baseUrl = {
-    add: '/shop/searchHot/setHotWorld',
-    update: '/shop/searchHot/setHotWorld'
-};
+    const baseUrl = {
+        add: '/shop/searchHot/setHotWorld',
+        update: '/shop/searchHot/setHotWorld'
+    };
 
-const formatData = (data) => {
-    if (!data.source) {
-        data.source = 1;
-    }
-    return data;
-};
-
-const formItems = computed(() => [
-    {
-        label: '热搜词',
-        prop: 'world',
-        type: 'input',
-        required: true,
-        attrs: {
-            placeholder: '请输入'
-        }
-    },
-    {
-        label: '权重',
-        prop: 'priority',
-        type: 'input',
-        required: true,
-        attrs: {
-            placeholder: '请输入'
+    const formatData = (data) => {
+        if (!data.source) {
+            data.source = 1;
         }
-    },
-    {
-        label: '类型',
-        prop: 'type',
-        type: 'select',
-        required: true,
-        options: [
-            { label: '热搜词', value: 1 },
-            { label: '搜索框默认词', value: 2 }
-        ],
-        attrs: {
-            placeholder: '请选择类型'
+        return data;
+    };
+
+    const formItems = computed(() => [
+        {
+            label: '热搜词',
+            prop: 'world',
+            type: 'input',
+            required: true,
+            attrs: {
+                placeholder: '请输入'
+            }
+        },
+        {
+            label: '权重',
+            prop: 'priority',
+            type: 'input',
+            required: true,
+            attrs: {
+                placeholder: '请输入'
+            }
+        },
+        {
+            label: '类型',
+            prop: 'type',
+            type: 'select',
+            required: true,
+            options: [
+                { label: '热搜词', value: 1 },
+                { label: '搜索框默认词', value: 2 }
+            ],
+            attrs: {
+                placeholder: '请选择类型'
+            }
+        },
+        {
+            prop: 'source',
+            type: 'hidden',
+            defaultValue: 1
         }
-    },
-    {
-        prop: 'source',
-        type: 'hidden',
-        defaultValue: 1
-    }
-]);
+    ]);
 
-const handleOpen = (data) => {
-    title.value = data && data.id ? '编辑热搜词' : '添加热搜词';
-    modalRef.value.handleOpen(data);
-};
+    const handleOpen = (data) => {
+        title.value = data && data.id ? '编辑热搜词' : '添加热搜词';
+        modalRef.value.handleOpen(data);
+    };
 
-const handleSuccess = (data) => {
-    emit('success', data);
-};
+    const handleSuccess = (data) => {
+        emit('success', data);
+    };
 
-defineExpose({
-    handleOpen
-});
+    defineExpose({
+        handleOpen
+    });
 </script>

+ 137 - 94
src/views/salesOps/trendsSearch/index.vue

@@ -1,6 +1,11 @@
 <template>
     <ele-page flex-table>
-        <common-table ref="tableRef" :pageConfig="pageConfig" :columns="columns" :tools="false">
+        <common-table
+            ref="tableRef"
+            :pageConfig="pageConfig"
+            :columns="columns"
+            :tools="false"
+        >
             <template #toolbar>
                 <el-button type="primary" @click="handleAdd">添加</el-button>
             </template>
@@ -18,13 +23,21 @@
             </template>
 
             <template #enableStatus="{ row }">
-                <el-switch v-model="row.enableStatus" :active-value="1" :inactive-value="0"
-                    @change="handleStatusChange(row)" />
+                <el-switch
+                    v-model="row.enableStatus"
+                    :active-value="1"
+                    :inactive-value="0"
+                    @change="handleStatusChange(row)"
+                />
             </template>
 
             <template #action="{ row }">
-                <el-button link type="primary" @click="handleEdit(row)">编辑</el-button>
-                <el-button link type="danger" @click="handleDelete(row)">删除</el-button>
+                <el-button link type="primary" @click="handleEdit(row)"
+                    >编辑</el-button
+                >
+                <el-button link type="danger" @click="handleDelete(row)"
+                    >删除</el-button
+                >
             </template>
         </common-table>
 
@@ -33,94 +46,124 @@
 </template>
 
 <script setup>
-import { ref, reactive, getCurrentInstance } from 'vue';
-import CommonTable from '@/components/CommonPage/CommonTable.vue';
-import TrendsSearchEdit from './components/trends-search-edit.vue';
-import { EleMessage } from 'ele-admin-plus/es';
-
-defineOptions({ name: 'TrendsSearch' });
-
-const { proxy } = getCurrentInstance();
-const tableRef = ref(null);
-const editDialogRef = ref(null);
-
-const pageConfig = reactive({
-    pageUrl: '/shop/searchHot/pagelist',
-    fileName: '热搜管理',
-    cacheKey: 'trends-search-list',
-    params: {}
-});
-
-const columns = ref([
-    { label: '热搜词', prop: 'world', align: 'center', minWidth: 150 },
-    { label: '管理类型', prop: 'type', align: 'center', minWidth: 120,slot:'type' },
-    { label: '来源', prop: 'source', slot: 'source', align: 'center', minWidth: 120 },
-    { label: '搜索次数', prop: 'searchTimes', align: 'center', minWidth: 120 },
-    { label: '权重', prop: 'priority', align: 'center', minWidth: 100 },
-    { label: '是否启用', prop: 'enableStatus', slot: 'enableStatus', align: 'center', minWidth: 100 },
-    { label: '更新时间', prop: 'updateTime', align: 'center', minWidth: 180 },
-    {
-        label: '操作',
-        prop: 'action',
-        slot: 'action',
-        align: 'center',
-        width: 150
-    }
-]);
-
-const reload = () => {
-    tableRef.value?.reload();
-};
-
-const handleAdd = () => {
-    editDialogRef.value?.handleOpen();
-};
-
-const handleEdit = (row) => {
-    editDialogRef.value?.handleOpen(row);
-};
-
-const handleDelete = (row) => {
-    EleMessage.confirm(`确定要删除 ${row.world} 吗?`)
-        .then(() => {
-            proxy.$http.post('/shop/searchHot/delete', { id: row.id })
-                .then((res) => {
-                    if (res.data.code === 200) {
-                        EleMessage.success('删除成功');
-                        reload();
-                    } else {
-                        EleMessage.error(res.data.msg);
-                    }
-                })
-                .catch((e) => {
-                    EleMessage.error(e.message);
-                });
-        })
-        .catch(() => { });
-};
-
-const handleSuccess = () => {
-    reload();
-};
-
-const handleStatusChange = (row) => {
-    proxy.$http.post('/shop/searchHot/setStatus', {
-        id: row.id,
-        enableStatus: row.enableStatus
-    })
-        .then((res) => {
-            if (res.data.code === 200) {
-                EleMessage.success(
-                    `${row.world} ${row.enableStatus === 1 ? '已启用' : '已禁用'}`
-                );
-            } else {
+    import { ref, reactive, getCurrentInstance } from 'vue';
+    import CommonTable from '@/components/CommonPage/CommonTable.vue';
+    import TrendsSearchEdit from './components/trends-search-edit.vue';
+    import { EleMessage } from 'ele-admin-plus/es';
+
+    defineOptions({ name: 'TrendsSearch' });
+
+    const { proxy } = getCurrentInstance();
+    const tableRef = ref(null);
+    const editDialogRef = ref(null);
+
+    const pageConfig = reactive({
+        pageUrl: '/shop/searchHot/pagelist',
+        fileName: '热搜管理',
+        cacheKey: 'trends-search-list',
+        params: {}
+    });
+
+    const columns = ref([
+        { label: '热搜词', prop: 'world', align: 'center', minWidth: 150 },
+        {
+            label: '管理类型',
+            prop: 'type',
+            align: 'center',
+            minWidth: 120,
+            slot: 'type'
+        },
+        {
+            label: '来源',
+            prop: 'source',
+            slot: 'source',
+            align: 'center',
+            minWidth: 120
+        },
+        {
+            label: '搜索次数',
+            prop: 'searchTimes',
+            align: 'center',
+            minWidth: 120
+        },
+        { label: '权重', prop: 'priority', align: 'center', minWidth: 100 },
+        {
+            label: '是否启用',
+            prop: 'enableStatus',
+            slot: 'enableStatus',
+            align: 'center',
+            minWidth: 100
+        },
+        {
+            label: '更新时间',
+            prop: 'updateTime',
+            align: 'center',
+            minWidth: 180
+        },
+        {
+            label: '操作',
+            prop: 'action',
+            slot: 'action',
+            align: 'center',
+            width: 150
+        }
+    ]);
+
+    const reload = () => {
+        tableRef.value?.reload();
+    };
+
+    const handleAdd = () => {
+        editDialogRef.value?.handleOpen();
+    };
+
+    const handleEdit = (row) => {
+        editDialogRef.value?.handleOpen(row);
+    };
+
+    const handleDelete = (row) => {
+        EleMessage.confirm(`确定要删除 ${row.world} 吗?`)
+            .then(() => {
+                proxy.$http
+                    .post('/shop/searchHot/delete', { id: row.id })
+                    .then((res) => {
+                        if (res.data.code === 200) {
+                            EleMessage.success('删除成功');
+                            reload();
+                        } else {
+                            EleMessage.error(res.data.msg);
+                        }
+                    })
+                    .catch((e) => {
+                        EleMessage.error(e.message);
+                    });
+            })
+            .catch(() => {});
+    };
+
+    const handleSuccess = () => {
+        reload();
+    };
+
+    const handleStatusChange = (row) => {
+        proxy.$http
+            .post('/shop/searchHot/setStatus', {
+                id: row.id,
+                enableStatus: row.enableStatus
+            })
+            .then((res) => {
+                if (res.data.code === 200) {
+                    EleMessage.success(
+                        `${row.world} ${row.enableStatus === 1 ? '已启用' : '已禁用'}`
+                    );
+                } else {
+                    row.enableStatus = row.enableStatus === 1 ? 0 : 1;
+                    EleMessage.error(res.data.msg);
+                }
+            })
+            .catch((e) => {
                 row.enableStatus = row.enableStatus === 1 ? 0 : 1;
-                EleMessage.error(res.data.msg);
-            }
-        })
-        .catch((e) => {
-            row.enableStatus = row.enableStatus === 1 ? 0 : 1;
-            EleMessage.error(e.message);
-        });
-};
+                EleMessage.error(e.message);
+            });
+    };
 </script>