Forráskód Böngészése

feat(searchFeedback): 完善搜索反馈管理功能

ylong 20 órája
szülő
commit
02ee66eb05

+ 53 - 58
src/views/data/searchFeedback/components/handle-dialog.vue

@@ -1,10 +1,5 @@
 <template>
-    <ele-modal
-        v-model="visible"
-        title="处理反馈"
-        :width="800"
-        :footer="null"
-    >
+    <ele-modal v-model="visible" title="处理反馈" :width="800" :footer="null">
         <div class="p-4">
             <el-form :model="form" label-width="120px">
                 <el-form-item label="体验打分:">
@@ -12,36 +7,24 @@
                         <template #append>分</template>
                     </el-input>
                 </el-form-item>
-                
+
                 <el-form-item label="反馈信息:">
-                    <el-input
-                        v-model="form.content"
-                        type="textarea"
-                        :rows="6"
-                        readonly
-                        resize="none"
-                    />
+                    <el-input v-model="form.content" type="textarea" :rows="6" readonly resize="none" />
                 </el-form-item>
-                
+
                 <el-form-item label="反馈图片/视频:">
                     <div class="flex gap-2" v-if="form.images && form.images.length">
-                        <el-image
-                            v-for="(img, index) in form.images"
-                            :key="index"
-                            :src="img"
-                            :preview-src-list="form.images"
-                            :initial-index="index"
-                            fit="cover"
-                            style="width: 100px; height: 100px; border-radius: 4px;"
-                        />
+                        <el-image v-for="(img, index) in form.images" :key="index" :src="img"
+                            :preview-src-list="form.images" :initial-index="index" fit="cover"
+                            style="width: 100px; height: 100px; border-radius: 4px;" />
                     </div>
                     <div v-else class="text-gray-400">无图片/视频</div>
                 </el-form-item>
             </el-form>
-            
+
             <div class="flex justify-center gap-4 mt-8">
-                <el-button type="success" @click="handleComplete">处理完成</el-button>
-                <el-button color="#000080" style="color: white" @click="handleFollowUp">跟进</el-button>
+                <el-button v-if="form.status != 3" type="success" @click="handleComplete">处理完成</el-button>
+                <el-button v-if="form.status != 3" color="#000080" style="color: white" @click="handleFollowUp">跟进</el-button>
                 <el-button type="info" plain @click="visible = false">关闭</el-button>
             </div>
         </div>
@@ -49,40 +32,52 @@
 </template>
 
 <script setup>
-import { ref, reactive } from 'vue';
-import { ElMessage } from 'element-plus';
+    import { ref, reactive, getCurrentInstance } from 'vue';
+    import { ElMessage } from 'element-plus';
+
+    const { proxy } = getCurrentInstance();
+    const visible = ref(false);
+    const emit = defineEmits(['success']);
+
+    const form = reactive({
+        id: null,
+        score: '',
+        content: '',
+        status: null,
+        images: []
+    });
 
-const visible = ref(false);
-const form = reactive({
-    id: null,
-    score: '',
-    content: '',
-    images: []
-});
+    const handleOpen = (row) => {
+        if (row) {
+            form.id = row.id;
+            form.score = row.score;
+            form.status = row.status;
+            form.content = row.description;
+            form.images = row.feedbackImgList || [];
+        }
+        visible.value = true;
+    };
 
-const handleOpen = (row) => {
-    if (row) {
-        form.id = row.id;
-        form.score = row.score;
-        form.content = row.content;
-        form.images = row.images || [];
-    }
-    visible.value = true;
-};
+    const submitCheck = (status) => {
+        proxy.$http.post('/shop/shopSearch/searchFeedbackCheck', {
+            id: form.id,
+            status: status
+        }).then(() => {
+            ElMessage.success(status === 2 ? '已跟进' : '处理完成');
+            visible.value = false;
+            emit('success');
+        });
+    };
 
-const handleComplete = () => {
-    // Mock API call
-    ElMessage.success('处理完成');
-    visible.value = false;
-};
+    const handleComplete = () => {
+        submitCheck(3);
+    };
 
-const handleFollowUp = () => {
-    // Mock API call
-    ElMessage.success('已跟进');
-    visible.value = false;
-};
+    const handleFollowUp = () => {
+        submitCheck(2);
+    };
 
-defineExpose({
-    handleOpen
-});
+    defineExpose({
+        handleOpen
+    });
 </script>

+ 5 - 4
src/views/data/searchFeedback/components/page-search.vue

@@ -17,7 +17,7 @@ const emit = defineEmits(['search']);
 const searchRef = ref(null);
 
 const formItems = reactive([
-    { type: 'input', label: '请输入用户昵称', prop: 'nickname', placeholder: '请输入用户昵称' },
+    { type: 'input', label: '请输入用户昵称', prop: 'userName', placeholder: '请输入用户昵称' },
     { type: 'input', label: '请输入用户ID', prop: 'userId', placeholder: '请输入用户ID' },
     { 
         type: 'select', 
@@ -25,14 +25,15 @@ const formItems = reactive([
         prop: 'status', 
         placeholder: '请选择状态',
         options: [
-            { label: '待处理', value: 0 },
-            { label: '已处理', value: 1 }
+            { label: '待处理', value: 1 },
+            { label: '已跟进', value: 2 },
+            { label: '已处理', value: 3 }
         ]
     }
 ]);
 
 const initKeys = reactive({
-    nickname: '',
+    userName: '',
     userId: '',
     status: void 0
 });

+ 45 - 76
src/views/data/searchFeedback/index.vue

@@ -1,106 +1,75 @@
 <template>
     <ele-page flex-table>
         <page-search @search="reload" />
-        
-        <common-table
-            ref="pageRef"
-            :pageConfig="pageConfig"
-            :columns="columns"
-            :datasource="datasource"
-            :tools="false"
-        >
+
+        <common-table ref="pageRef" :pageConfig="pageConfig" :columns="columns" :tools="false">
             <!-- 状态列 -->
             <template #status="{ row }">
-                {{ row.status === 0 ? '待处理' : '已处理' }}
+                {{ row.status === 1 ? '待处理' : row.status === 2 ? '已跟进' : '已处理' }}
             </template>
 
             <!-- 图片/视频列 -->
             <template #media="{ row }">
-                <div class="flex gap-1" v-if="row.images && row.images.length">
-                    <el-image
-                        v-for="(img, idx) in row.images.slice(0, 2)"
-                        :key="idx"
-                        :src="img"
-                        :preview-src-list="row.images"
-                        :initial-index="idx"
-                        preview-teleported
-                        style="width: 40px; height: 40px; border-radius: 4px;"
-                    />
+                <div class="flex gap-1" v-if="row.feedbackImgList && row.feedbackImgList.length">
+                    <el-image v-for="(img, idx) in row.feedbackImgList.slice(0, 2)" :key="idx" :src="img"
+                        :preview-src-list="row.feedbackImgList" :initial-index="idx" preview-teleported
+                        style="width: 40px; height: 40px; border-radius: 4px;" />
                 </div>
             </template>
 
             <!-- 操作列 -->
             <template #action="{ row }">
-                <el-button link type="primary" @click="handleProcess(row)">[去处理]</el-button>
-                <el-button link type="primary" @click="handleDetail(row)">[详情]</el-button>
+                <el-button link type="primary" @click="handleProcess(row)" v-if="row.status != 3">[去处理]</el-button>
+                <el-button link type="primary" @click="handleDetail(row)" v-else>[详情]</el-button>
             </template>
         </common-table>
 
-        <handle-dialog ref="handleDialogRef" />
+        <handle-dialog ref="handleDialogRef" @success="reload" />
     </ele-page>
 </template>
 
 <script setup>
-import { ref, reactive } from 'vue';
-import CommonTable from '@/components/CommonPage/CommonTable.vue';
-import PageSearch from './components/page-search.vue';
-import HandleDialog from './components/handle-dialog.vue';
+    import { ref, reactive } from 'vue';
+    import CommonTable from '@/components/CommonPage/CommonTable.vue';
+    import PageSearch from './components/page-search.vue';
+    import HandleDialog from './components/handle-dialog.vue';
 
-defineOptions({ name: 'SearchFeedback' });
+    defineOptions({ name: 'SearchFeedback' });
 
-const pageRef = ref(null);
-const handleDialogRef = ref(null);
+    const pageRef = ref(null);
+    const handleDialogRef = ref(null);
 
-const pageConfig = reactive({
-    fileName: '搜索反馈记录',
-    cacheKey: 'searchFeedbackTable',
-    rowKey: 'id'
-});
+    const pageConfig = reactive({
+        fileName: '搜索反馈记录',
+        cacheKey: 'searchFeedbackTable',
+        rowKey: 'id',
+        pageUrl: '/shop/shopSearch/searchFeedbackList'
+    });
 
-const columns = ref([
-    { label: '序号', width: 60, type: 'index', align: 'center' },
-    { label: '状态', prop: 'status', width: 100, slot: 'status', align: 'center' },
-    { label: '反馈日期', prop: 'createTime', width: 160, align: 'center' },
-    { label: '用户名', prop: 'nickname', width: 150, align: 'center' },
-    { label: '反馈信息', prop: 'content', minWidth: 300, showOverflowTooltip: true },
-    { label: '打分', prop: 'score', width: 80, align: 'center' },
-    { label: '图片/视频', prop: 'media', width: 120, slot: 'media', align: 'center' },
-    { label: '操作', prop: 'action', width: 150, slot: 'action', fixed: 'right', align: 'center' }
-]);
+    const columns = ref([
+        { label: '序号', width: 60, type: 'index', align: 'center' },
+        { label: '状态', prop: 'status', minWidth: 100, slot: 'status', align: 'center' },
+        { label: '反馈日期', prop: 'createTime', minWidth: 160, align: 'center' },
+        { label: '用户ID', prop: 'userId', minWidth: 150, align: 'center' },
+        { label: '用户名', prop: 'userName', minWidth: 150, align: 'center' },
+        { label: '反馈信息', prop: 'description', minWidth: 300, showOverflowTooltip: true },
+        { label: '打分', prop: 'score', minWidth: 80, align: 'center' },
+        { label: '图片/视频', prop: 'feedbackImgList', minWidth: 120, slot: 'media', align: 'center' },
+        { label: '操作', prop: 'action', minWidth: 150, slot: 'action', fixed: 'right', align: 'center' }
+    ]);
 
-// Mock Datasource
-const datasource = ({ page, limit, where }) => {
-    return Promise.resolve({
-        code: 0,
-        msg: 'success',
-        count: 1,
-        data: [
-            {
-                id: 1,
-                status: 0,
-                createTime: '2024-06-15 15:00:66',
-                nickname: '书嗨12121634',
-                content: '出VB发货顺序该方法出VB发货顺序该方法出VB发货顺序该方法11454545454456767',
-                score: 3,
-                images: [
-                    'https://img1.baidu.com/it/u=2356551695,3062334057&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=707',
-                    'https://img1.baidu.com/it/u=2356551695,3062334057&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=707'
-                ]
-            }
-        ]
-    });
-};
+    // Mock Datasource removed, using pageUrl in pageConfig
 
-const reload = (where) => {
-    pageRef.value?.reload(where);
-};
+    const reload = (where) => {
+        pageRef.value?.reload(where);
+    };
 
-const handleProcess = (row) => {
-    handleDialogRef.value?.handleOpen(row);
-};
+    const handleProcess = (row) => {
+        handleDialogRef.value?.handleOpen(row);
+    };
 
-const handleDetail = (row) => {
-    // 详情逻辑与处理逻辑类似,可能只是只读或者打开同一个弹窗
-    handleDialogRef.value?.handleOpen(row);
-};
+    const handleDetail = (row) => {
+        // 详情逻辑与处理逻辑类似,可能只是只读或者打开同一个弹窗
+        handleDialogRef.value?.handleOpen(row);
+    };
 </script>