Prechádzať zdrojové kódy

feat(热搜管理): 更新热搜词和榜单管理功能

- 修改热搜词管理接口路径和字段映射
- 添加热搜词数据格式化处理
- 更新热搜榜单商品字段映射和状态切换接口
- 实现热搜词和榜单的删除和状态切换功能
ylong 1 týždeň pred
rodič
commit
dae4255c72

+ 51 - 38
src/views/salesOps/trendsRank/index.vue

@@ -5,30 +5,26 @@
             :pageConfig="pageConfig"
             :columns="columns"
             :tools="false"
-            :datasource="mockDatasource"
         >
-            <!-- 序号 -->
             <template #index="{ $index }">
                 {{ $index + 1 }}
             </template>
 
-            <!-- 商品图 -->
             <template #image="{ row }">
                 <el-image
-                    :src="row.image"
+                    :src="row.cover"
                     class="w-16 h-16 rounded"
                     fit="cover"
-                    :preview-src-list="[row.image]"
+                    :preview-src-list="[row.cover]"
                     preview-teleported
                 />
             </template>
 
-            <!-- 商品信息 -->
             <template #info="{ row }">
                 <div>
                     <div
                         class="font-bold text-blue-500 hover:underline cursor-pointer"
-                        >{{ row.title }}</div
+                        >{{ row.bookName }}</div
                     >
                     <div class="text-xs text-gray-500 mt-1"
                         >作者: {{ row.author }}</div
@@ -37,15 +33,14 @@
                         >ISBN: {{ row.isbn }}</div
                     >
                     <div class="text-xs text-gray-500"
-                        >出版社: {{ row.publisher }}</div
+                        >出版社: {{ row.publish }}</div
                     >
                 </div>
             </template>
 
-            <!-- 是否启用 -->
-            <template #status="{ row }">
+            <template #isOnSale="{ row }">
                 <el-switch
-                    v-model="row.status"
+                    v-model="row.isOnSale"
                     :active-value="1"
                     :inactive-value="0"
                     @change="handleStatusChange(row)"
@@ -56,36 +51,54 @@
 </template>
 
 <script setup>
-    import { ref, reactive } 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 tableRef = ref(null);
+const { proxy } = getCurrentInstance();
+const tableRef = ref(null);
 
-    const pageConfig = reactive({
-        pageUrl: '/salesOps/trendsRank/list',
-        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: 'sales', align: 'center' },
-        { label: '库存', prop: 'stock', align: 'center' },
-        { label: '是否启用', slot: 'status', align: 'center' },
-        { label: '更新时间', prop: 'updateTime', align: 'center', width: 180 }
-    ]);
+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 handleStatusChange = (row) => {
-        // TODO: Call API to update status
-        // tableRef.value?.operatBatch({ method: 'post', row, url: '/salesOps/trendsRank/updateStatus' });
-        EleMessage.success(
-            `${row.title} ${row.status === 1 ? '已启用' : '已禁用'}`
-        );
-    };
+const reload = () => {
+    tableRef.value?.reload();
+};
+
+const handleStatusChange = (row) => {
+    proxy.$http.post('/shop/shopbook/setShelfStatus', {
+        id: row.id,
+        isOnSale: row.isOnSale
+    })
+        .then((res) => {
+            if (res.data.code === 200) {
+                EleMessage.success(
+                    `${row.bookName} ${row.isOnSale === 1 ? '已启用' : '已禁用'}`
+                );
+            } else {
+                row.isOnSale = row.isOnSale === 1 ? 0 : 1;
+                EleMessage.error(res.data.msg);
+            }
+        })
+        .catch((e) => {
+            row.isOnSale = row.isOnSale === 1 ? 0 : 1;
+            EleMessage.error(e.message);
+        });
+};
 </script>

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

@@ -7,72 +7,79 @@
         :title="title"
         width="520px"
         labelWidth="100px"
+        :formatData="formatData"
     />
 </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: '/salesOps/trendsSearch/add',
-        update: '/salesOps/trendsSearch/update'
-    };
+const baseUrl = {
+    add: '/shop/searchHot/setHotWorld',
+    update: '/shop/searchHot/setHotWorld'
+};
 
-    const formItems = computed(() => [
-        {
-            label: '热搜词',
-            prop: 'keyword',
-            type: 'input',
-            required: true,
-            attrs: {
-                placeholder: '请输入'
-            }
-        },
-        {
-            label: '权重',
-            prop: 'weight',
-            type: 'input',
-            required: true,
-            attrs: {
-                placeholder: '请输入'
-            }
-        },
-        {
-            label: '类型',
-            prop: 'type',
-            type: 'select',
-            required: true,
-            options: [
-                { label: '热搜词', value: 'hot' },
-                { label: '搜索框默认词', value: 'default' }
-            ],
-            attrs: {
-                placeholder: '请选择类型'
-            }
-        },
-        {
-            label: '是否启用',
-            prop: 'status',
-            type: 'switch',
-            defaultValue: true
+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: '请输入'
+        }
+    },
+    {
+        label: '类型',
+        prop: 'type',
+        type: 'select',
+        required: true,
+        options: [
+            { label: '热搜词', value: 1 },
+            { label: '搜索框默认词', value: 2 }
+        ],
+        attrs: {
+            placeholder: '请选择类型'
         }
-    ]);
+    },
+    {
+        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>

+ 104 - 91
src/views/salesOps/trendsSearch/index.vue

@@ -1,39 +1,30 @@
 <template>
     <ele-page flex-table>
-        <common-table
-            ref="tableRef"
-            :pageConfig="pageConfig"
-            :columns="columns"
-            :tools="false"
-            :datasource="mockDatasource"
-        >
+        <common-table ref="tableRef" :pageConfig="pageConfig" :columns="columns" :tools="false">
             <template #toolbar>
                 <el-button type="primary" @click="handleAdd">添加</el-button>
             </template>
 
-            <!-- 序号 -->
             <template #index="{ $index }">
                 {{ $index + 1 }}
             </template>
 
-            <!-- 是否启用 -->
-            <template #status="{ row }">
-                <el-switch
-                    v-model="row.status"
-                    :active-value="1"
-                    :inactive-value="0"
-                    @change="handleStatusChange(row)"
-                />
+            <template #source="{ row }">
+                {{ row.source === 1 ? '人工干预' : '系统测算' }}
+            </template>
+
+            <template #type="{ row }">
+                {{ row.type === 1 ? '热搜词' : '搜索框默认词' }}
+            </template>
+
+            <template #enableStatus="{ 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>
 
@@ -42,72 +33,94 @@
 </template>
 
 <script setup>
-    import { ref, reactive } 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 tableRef = ref(null);
-    const editDialogRef = ref(null);
-
-    const pageConfig = reactive({
-        pageUrl: '/salesOps/trendsSearch/list',
-        fileName: '热搜管理',
-        cacheKey: 'trends-search-list',
-        params: {}
-    });
-
-    const columns = ref([
-        { label: '热搜词', prop: 'keyword', align: 'center' },
-        { label: '管理类型', prop: 'typeLabel', align: 'center' },
-        { label: '来源', prop: 'source', align: 'center' },
-        { label: '搜索次数', prop: 'count', align: 'center' },
-        { label: '权重', prop: 'weight', align: 'center' },
-        { label: '是否启用', prop: 'status', slot: 'status', align: 'center' },
-        { label: '更新时间', prop: 'updateTime', align: 'center', width: 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.keyword} 吗?`)
-            .then(() => {
-                // TODO: Call API to delete
-                // tableRef.value?.operatBatch({ method: 'delete', row, url: '/salesOps/trendsSearch/delete' });
-                EleMessage.success('删除成功');
-                reload();
-            })
-            .catch(() => {});
-    };
-
-    const handleSuccess = () => {
-        reload();
-    };
-
-    const handleStatusChange = (row) => {
-        // TODO: Call API to update status
-        // tableRef.value?.operatBatch({ method: 'post', row, url: '/salesOps/trendsSearch/updateStatus' });
-        EleMessage.success(
-            `${row.keyword} ${row.status === 1 ? '已启用' : '已禁用'}`
-        );
-    };
+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(e.message);
+        });
+};
 </script>