Jelajahi Sumber

投诉页面优化

yjwang 3 hari lalu
induk
melakukan
d28cf8f4cb
3 mengubah file dengan 685 tambahan dan 225 penghapusan
  1. 10 1
      src/api/user/complaint.js
  2. 18 0
      src/api/user/complaintMsg.js
  3. 657 224
      src/views/user/complaint/index.vue

+ 10 - 1
src/api/user/complaint.js

@@ -50,4 +50,13 @@ export function exportComplaint(query) {
     method: 'get',
     params: query
   })
-}
+}
+
+// 查询用户投诉列表
+export function completeComplaint(data) {
+  return request({
+    url: '/user/complaint/completeComplaint',
+    method: 'post',
+    data: data
+  })
+}

+ 18 - 0
src/api/user/complaintMsg.js

@@ -18,4 +18,22 @@ export function addComplaintMsg(data) {
   })
 }
 
+// 查询投诉消息记录列表
+export function listMsg(query) {
+  return request({
+    url: '/user/msg/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 新增投诉消息记录
+export function addMsg(data) {
+  return request({
+    url: '/user/msg',
+    method: 'post',
+    data: data
+  })
+}
+
 

+ 657 - 224
src/views/user/complaint/index.vue

@@ -1,29 +1,38 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="投诉用户" prop="fsUserId">
+      <el-form-item label="用户" prop="userId">
         <el-input
-          v-model="queryParams.nickName"
-          placeholder="请输入投诉用户"
+          v-model="queryParams.userId"
+          placeholder="请输入用户id"
           clearable
           size="small"
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="投诉标题" prop="title">
+      <el-form-item label="联系方式" prop="phone">
         <el-input
-          v-model="queryParams.title"
-          placeholder="请输入投诉标题"
+          v-model="queryParams.phone"
+          placeholder="请输入联系方式"
           clearable
           size="small"
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="投诉类型" prop="type">
-        <el-select v-model="queryParams.type" placeholder="请选择投诉类型" clearable size="small">
-          <el-option v-for="item in typeList" :label="item.value" :value="item.type" />
+      <el-form-item label="处理状态" prop="isHandleStore">
+        <el-select
+          v-model="queryParams.isHandleStore"
+          placeholder="请选择处理状态"
+          clearable
+          size="small"
+        >
+          <el-option label="未处理" value="0"></el-option>
+          <el-option label="已处理" value="1"></el-option>
         </el-select>
       </el-form-item>
+      <el-form-item label="投诉时间" prop="complaintTime">
+        <el-date-picker v-model="complaintTime" size="small" style="width: 220px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" @change="changeTime"></el-date-picker>
+      </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -31,101 +40,84 @@
     </el-form>
 
     <el-row :gutter="10" class="mb8">
-<!--      <el-col :span="1.5">-->
-<!--        <el-button-->
-<!--          type="primary"-->
-<!--          plain-->
-<!--          icon="el-icon-plus"-->
-<!--          size="mini"-->
-<!--          @click="handleAdd"-->
-<!--          v-hasPermi="['user:complaint:add']"-->
-<!--        >新增</el-button>-->
-<!--      </el-col>-->
-<!--      <el-col :span="1.5">-->
-<!--        <el-button-->
-<!--          type="success"-->
-<!--          plain-->
-<!--          icon="el-icon-edit"-->
-<!--          size="mini"-->
-<!--          :disabled="single"-->
-<!--          @click="handleUpdate"-->
-<!--          v-hasPermi="['user:complaint:edit']"-->
-<!--        >修改</el-button>-->
-<!--      </el-col>-->
       <el-col :span="1.5">
         <el-button
-          type="danger"
+          type="warning"
           plain
-          icon="el-icon-delete"
+          icon="el-icon-download"
           size="mini"
-          :disabled="multiple"
-          @click="handleDelete"
-          v-hasPermi="['user:complaint:remove']"
-        >删除</el-button>
+          :loading="exportLoading"
+          @click="handleExport"
+        >导出</el-button>
       </el-col>
-<!--      <el-col :span="1.5">-->
-<!--        <el-button-->
-<!--          type="warning"-->
-<!--          plain-->
-<!--          icon="el-icon-download"-->
-<!--          size="mini"-->
-<!--          :loading="exportLoading"-->
-<!--          @click="handleExport"-->
-<!--          v-hasPermi="['user:complaint:export']"-->
-<!--        >导出</el-button>-->
-<!--      </el-col>-->
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
     <el-table border v-loading="loading" :data="complaintList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="id" align="center" prop="id" />
-      <el-table-column label="投诉用户" align="center" prop="nickName" />
-      <el-table-column label="投诉标题" align="center" prop="title" />
-      <el-table-column label="投诉内容" align="center" prop="content" />
-      <el-table-column label="商品图片" align="center" width="120">
+      <el-table-column label="用户" align="center" prop="nickName" />
+      <el-table-column label="投诉方式" align="center" prop="complaintType" >
+        <template slot-scope="scope">
+          <template v-for="item in complaintTypeOptions">
+            <el-tag v-if="item.dictValue === scope.row.complaintType" :key="item.dictValue">
+              {{ item.dictLabel }}
+            </el-tag>
+          </template>
+        </template>
+      </el-table-column>
+      <el-table-column label="投诉类型" align="center" prop="type" >
+        <template slot-scope="scope">
+          <dict-tag :options="typeOptions" :value="scope.row.type"/>
+        </template>
+      </el-table-column>
+      <el-table-column label="投诉时间" align="center" prop="createTime" />
+      <el-table-column
+        label="店铺消息是否处理"
+        align="center"
+        prop="isHandlePlatform"
+        :render-header="renderHandleHeader"
+      >
         <template slot-scope="scope">
-          <el-popover
-            placement="right"
-            title=""
-            trigger="hover">
-            <img slot="reference"  :src="scope.row.images" width="100">
-            <img :src="scope.row.images" style="max-width: 150px;">
-          </el-popover>
+          <el-tag
+            :type="(scope.row.isHandleStore === 1)? 'success' : 'warning'"
+            disable-transitions
+          >
+            {{ formatHandleStatus(scope.row.isHandleStore) }}
+          </el-tag>
         </template>
       </el-table-column>
-      <el-table-column label="投诉类型" align="center">
+      <el-table-column
+        label="处理状态"
+        align="center"
+        prop="isHandlePlatform"
+        :render-header="renderHandleHeader"
+      >
         <template slot-scope="scope">
-          <span v-for="item in typeList" :key="item.type">
-            <template v-if="item.type === scope.row.type">
-                {{ item.value }}
-            </template>
-          </span>
+          <el-tag
+            :type="(scope.row.isProcessCompleted === 1)? 'success' : 'danger'"
+            disable-transitions
+          >
+            {{ formatHandleProcessCompleted(scope.row.isProcessCompleted) }}
+          </el-tag>
         </template>
       </el-table-column>
-      <el-table-column label="备注" align="center" prop="remark" />
+      <el-table-column label="备注" align="center" prop="remarks" />
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button
             size="mini"
             type="text"
-            icon="el-icon-chat-dot-round"
-            @click="reply(scope.row)"
-          >回复</el-button>
+            icon="el-icon-check"
+            @click="handlecompleteComplaint(scope.row)"
+            v-if="scope.row.isProcessCompleted !== 1"
+          >完成投诉</el-button>
           <el-button
             size="mini"
             type="text"
             icon="el-icon-edit"
             @click="handleUpdate(scope.row)"
-            v-hasPermi="['user:complaint:edit']"
-          >修改</el-button>
-          <el-button
-            size="mini"
-            type="text"
-            icon="el-icon-delete"
-            @click="handleDelete(scope.row)"
-            v-hasPermi="['user:complaint:remove']"
-          >删除</el-button>
+          >投诉详情</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -138,125 +130,267 @@
       @pagination="getList"
     />
 
-    <!-- 添加或修改用户投诉对话框 -->
-    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
-      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="投诉用户" prop="nickName">
-          <el-input v-model="form.nickName" placeholder="请输入投诉用户" />
-        </el-form-item>
-        <el-form-item label="投诉标题" prop="title">
-          <el-input v-model="form.title" placeholder="请输入投诉标题" />
-        </el-form-item>
-        <el-form-item label="投诉内容">
-          <el-input type="textarea" :rows="3" v-model="form.content" :min-height="192" disabled/>
-        </el-form-item>
-        <el-form-item label="投诉图片" prop="images">
-          <div class="demo-image__preview">
-            <el-image
-              style="width: 100px; height: 100px"
-              :src="form.images"
-              @click="imageClick(form.images)"
-              :preview-src-list="srcList">
-            </el-image>
+    <!-- 修改用户投诉对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body>
+      <!-- 修改tab-click事件处理器名称 -->
+      <el-tabs v-model="activeTab" type="card" @tab-click="handleClick">
+        <!-- 投诉详情标签页 -->
+        <el-tab-pane :label="complaintType === 1?'咨询详情':'投诉详情'" name="complaint">
+          <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+            <el-form-item label="投诉内容" prop="name">
+              <el-input v-model="form.name" :disabled="true" />
+            </el-form-item>
+            <el-form-item label="详细内容" v-if="form.content && form.content!=''">
+              <el-input type="textarea" v-model="form.content" :disabled="true"/>
+            </el-form-item>
+            <el-form-item label="联系方式" prop="phone" v-if="form.phone && form.phone!=''">
+              <el-input v-model="form.phone" :disabled="true"/>
+            </el-form-item>
+            <el-form-item label="图片" v-if="form.images && form.images!=''">
+              <div v-for="(url, index) in imageUrls(form.images)" :key="index" class="image-container">
+                <el-image :src="url" :preview-src-list="[url]" style="width: 100px; height: 100px;"></el-image>
+              </div>
+            </el-form-item>
+            <!-- <el-form-item label="交易截图" v-if="form.tradeImage && form.tradeImage!=''">
+              <div v-for="(url, index) in imageUrls(form.tradeImage)" :key="index" class="image-container">
+                <el-image :src="url" :preview-src-list="[url]" style="width: 100px; height: 100px;"></el-image>
+              </div>
+            </el-form-item> -->
+            <el-form-item label="用户" prop="nickName">
+              <el-input v-model="form.nickName" :disabled="true"/>
+            </el-form-item>
+            <el-form-item label="是否处理" prop="isHandleStore">
+              <el-select v-model="form.isHandleStore" placeholder="请选择处理状态" :disabled="true">
+                <el-option label="未处理" :value="0"></el-option>
+                <el-option label="已处理" :value="1"></el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="备注" prop="remarks" >
+              <el-input type="textarea" v-model="form.remarks" :maxlength="250" :disabled="true"/>
+            </el-form-item>
+          </el-form>
+        </el-tab-pane>
+
+        <!-- 回复详情标签页 -->
+        <el-tab-pane label="回复详情" name="replies">
+          <div class="reply-section">
+            <!-- 添加回复表单 -->
+            <el-card class="add-reply-card" shadow="never">
+              <div slot="header">
+                <span>添加回复</span>
+              </div>
+              <el-form :model="replyForm" ref="replyForm" label-width="80px">
+                <el-form-item label="回复内容" prop="content" :rules="[{ required: true, message: '请输入回复内容', trigger: 'blur' }]" >
+                  <el-input
+                    type="textarea"
+                    v-model="replyForm.content"
+                    placeholder="请输入回复内容"
+                    :rows="3"
+                    maxlength="500"
+                    show-word-limit
+                    :disabled="isProcessCompleted === 1"
+                  />
+                </el-form-item>
+
+                <!-- 添加图片上传功能 -->
+                <el-form-item label="上传图片" prop="images">
+                  <!-- <div class="image-upload-container">
+                     <el-upload
+                      ref="imageUpload"
+                      :action="uploadUrl"
+                      :show-file-list="false"
+                      :file-list="replyImageList"
+                      :on-success="handleSuccess"
+                      :before-upload="beforeUpload"
+                      :limit="4"
+                      list-type="picture-card"
+                      accept="image/*"
+                    >
+                      <i class="el-icon-plus"></i>
+                      <div slot="tip" class="el-upload__tip">
+                        最多上传4张图片,单张图片不超过2MB
+                      </div>
+                    </el-upload>
+                  </div> -->
+                  <ImageUpload v-model="replyForm.images" type="image" :num="4" :width="150" :height="150" v-if="isProcessCompleted !== 1"/>
+                  <el-upload
+                    ref="imageUpload"
+                    :action="uploadUrl"
+                    :show-file-list="false"
+                    :file-list="replyImageList"
+                    :on-success="handleSuccess"
+                    :before-upload="beforeUpload"
+                    :limit="4"
+                    list-type="picture-card"
+                    accept="image/*"
+                    :disabled="isProcessCompleted === 1"
+                    v-else
+                  >
+                    <i class="el-icon-plus"></i>
+                  </el-upload>
+                </el-form-item>
+
+                <el-form-item>
+                  <el-button type="primary" size="small" @click="submitReply" :loading="replyLoading" :disabled="isProcessCompleted === 1">
+                    <i class="el-icon-s-promotion"></i> 发送回复
+                  </el-button>
+                </el-form-item>
+              </el-form>
+            </el-card>
+
+            <!-- 回复列表 -->
+            <el-card class="reply-list-card" shadow="never">
+              <div slot="header">
+                <span>回复记录 ({{ replyTotal }}条)</span>
+              </div>
+
+              <div v-loading="replyLoading" class="reply-list">
+                <div v-if="replyList.length === 0" class="empty-replies">
+                  <el-empty description="暂无回复记录" :image-size="100"></el-empty>
+                </div>
+
+                <div v-else>
+                  <div v-for="reply in replyList" :key="reply.id" class="reply-item">
+                    <div class="reply-header">
+                      <div class="reply-user">
+                        <el-avatar :size="32" :src="reply.avatar || '/default-avatar.png'">
+                          {{ reply.userName ? reply.userName.charAt(0) : 'U' }}
+                        </el-avatar>
+                        <!-- <span class="user-name">{{ reply.userName || '系统管理员' }}</span> -->
+                        <el-tag size="mini" :type="reply.sendType != 1 ? 'success' : 'info'">
+                          {{ reply.sendType === 1 ? '用户' : reply.sendType === 2 ? '系统平台':'店铺平台' }}
+                        </el-tag>
+                      </div>
+                      <div class="reply-time">
+                        {{ reply.createTime }}
+                      </div>
+                    </div>
+                    <div class="reply-content">
+                      {{ reply.content }}
+                    </div>
+
+                    <!-- 显示回复中的图片 -->
+                    <div class="reply-images" v-if="reply.images && reply.images !== ''">
+                      <div v-for="(url, index) in imageUrls(reply.images)" :key="index" class="reply-image-container">
+                        <el-image
+                          :src="url"
+                          :preview-src-list="imageUrls(reply.images)"
+                          style="width: 80px; height: 80px;"
+                          fit="cover"
+                        ></el-image>
+                      </div>
+                    </div>
+
+                    <div class="reply-actions" v-if="reply.userType === 'admin'">
+                      <el-button type="text" size="mini" @click="editReply(reply)">
+                        <i class="el-icon-edit"></i> 编辑
+                      </el-button>
+                      <el-button type="text" size="mini" @click="deleteReply(reply)" style="color: #f56c6c;">
+                        <i class="el-icon-delete"></i> 删除
+                      </el-button>
+                    </div>
+                  </div>
+                </div>
+              </div>
+
+              <!-- 回复分页 -->
+              <div class="reply-pagination" v-if="replyTotal > 0">
+                <el-pagination
+                  @size-change="handleReplySizeChange"
+                  @current-change="handleReplyCurrentChange"
+                  :current-page="replyQueryParams.pageNum"
+                  :page-sizes="[5, 10, 20]"
+                  :page-size="replyQueryParams.pageSize"
+                  layout="total, sizes, prev, pager, next, jumper"
+                  :total="replyTotal"
+                  small
+                />
+              </div>
+            </el-card>
           </div>
-        </el-form-item>
-        <el-form-item label="投诉类型" prop="type">
-          <el-select v-model="form.type" placeholder="请选择投诉类型" clearable size="small">
-            <el-option v-for="item in typeList" :label="item.value" :value="item.type" />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="备注" prop="remark">
-          <el-input v-model="form.remark" placeholder="请输入备注" />
-        </el-form-item>
-      </el-form>
+        </el-tab-pane>
+      </el-tabs>
+
       <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button type="primary" @click="submitForm" v-if="activeTab === 'complaint' && form.id==null">确 定</el-button>
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
 
-    <el-dialog
-      title="投诉消息回复"
-      :visible.sync="replyVisible"
-      width="50%"
-      :before-close="handleClose"
-      center>
-      <el-form label-width="80px">
-        <el-row>
-          <el-col>
-            <el-form-item label="投诉标题">
-              <el-input v-model="complaint.title" disabled></el-input>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col>
-            <el-form-item label="投诉内容">
-              <el-input type="textarea" v-model="complaint.content" :rows="2" disabled></el-input>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="凭证图片">
-              <el-image
-                style="width: 100px; height: 100px"
-                :src="replyInfo.url"
-                :preview-src-list="replyInfo.urlList">
-              </el-image>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="投诉类型">
-              <span v-for="item in typeList" :key="item.type">
-                 <template v-if="item.type === complaint.type">
-                    {{ item.value }}
-                </template>
-              </span>
-            </el-form-item>
-          </el-col>
-        </el-row>
+
+    <!-- 编辑回复对话框 -->
+    <el-dialog title="编辑回复" :visible.sync="editReplyVisible" width="500px" append-to-body>
+      <el-form :model="editReplyForm" ref="editReplyForm" label-width="80px">
+        <el-form-item label="回复内容" prop="content" :rules="[{ required: true, message: '请输入回复内容', trigger: 'blur' }]">
+          <el-input
+            type="textarea"
+            v-model="editReplyForm.content"
+            placeholder="请输入回复内容"
+            :rows="4"
+            maxlength="500"
+            show-word-limit
+          />
+        </el-form-item>
       </el-form>
-      <replyIndex v-if="isReplyOpen" ref="replyRef" :complaint-id="complaintId"></replyIndex>
-      <span slot="footer" class="dialog-footer">
-        <el-button @click="replyClose">关 闭</el-button>
-      </span>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="updateReply" :loading="replyLoading">确 定</el-button>
+        <el-button @click="editReplyVisible = false">取 消</el-button>
+      </div>
     </el-dialog>
   </div>
 </template>
 
 <script>
-import { listComplaint, getComplaint, delComplaint, addComplaint, updateComplaint, exportComplaint } from "@/api/user/complaint";
-import Index from '@/views/user/complaint/reply/index.vue'
+import {
+  listComplaint,
+  getComplaint,
+  delComplaint,
+  addComplaint,
+  updateComplaint,
+  exportComplaint,
+  completeComplaint
+} from '@/api/user/complaint';
+
+import {listMsg,addMsg} from '@/api/user/complaintMsg';
+import ImageUpload from '@/components/ImageUpload/index';
 export default {
   name: "Complaint",
+  components: {
+    ImageUpload
+  },
   data() {
     return {
-      isReplyOpen:false,
-      complaint:{
-        title:"",
-        content:"",
-        type:'1',
-      },
-      replyInfo:{
-        url:null,
-        urlList:[],
-      },
+      complaintType:0,
+      isProcessCompleted:0,
+      replyImageList: [],
+      uploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadOSS",
       complaintId:null,
-      srcList:[],
-      typeList:[
+      activeName:"0",
+      typeOptions:[
+        {
+          dictValue:'0',
+          dictLabel:'默认'
+        },
         {
-          type:1,
-          value:'店铺'
-        },{
-          type:2,
-          value:'商品'
-        },{
-          type:0,
-          value:'其它'
+          dictValue:'1',
+          dictLabel:'店铺'
+        },
+        {
+          dictValue:'2',
+          dictLabel:'商品'
         },
       ],
-      replyVisible:false,
+      complaintTypeOptions:[
+        {
+          dictValue:1,
+          dictLabel:'咨询'
+        },
+        {
+          dictValue:2,
+          dictLabel:'投诉/举报'
+        },
+      ],
+      complaintTime:null,
       // 遮罩层
       loading: true,
       // 导出遮罩层
@@ -277,32 +411,105 @@ export default {
       title: "",
       // 是否显示弹出层
       open: false,
+      // 当前激活的标签页
+      activeTab: 'complaint',
       // 查询参数
       queryParams: {
         pageNum: 1,
         pageSize: 10,
-        fsUserId: null,
-        title: null,
+        userId: null,
+        userName: null,
+        templateId: null,
         content: null,
-        images: null,
-        type:null,
-        linkId: null,
-        nickName: null,
+        phone: null,
+        urls: null,
+        account: null,
+        isHandle: null
       },
       // 表单参数
       form: {},
       // 表单校验
       rules: {
+        userId: [
+          { required: true, message: "用户id不能为空", trigger: "blur" }
+        ],
+        templateId: [
+          { required: true, message: "投诉模板id不能为空", trigger: "blur" }
+        ],
+      },
+      // 回复相关数据
+      replyList: [],
+      replyTotal: 0,
+      replyLoading: false,
+      replyQueryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        complaintId: null
+      },
+      replyForm: {
+        content: '',
+        complaintId: null
+      },
+      // 编辑回复
+      editReplyVisible: false,
+      editReplyForm: {
+        id: null,
+        content: ''
       }
     };
   },
-  components:{
-    replyIndex: Index
-  },
   created() {
     this.getList();
   },
   methods: {
+    handleClick(tab) {
+      if (tab.name === 'replies') {
+        this.getReplyList();
+      }
+    },
+    renderHandleHeader(h, { column }) {
+      if (column.label === '是否处理') {
+        return h('div', [
+          '是否处理',
+          h('el-tooltip', {
+            props: {
+              content: '仅需要处理投诉/举报类',
+              placement: 'top'
+            }
+          }, [
+            h('i', {
+              class: 'el-icon-question',
+              style: 'margin-left: 5px; cursor: pointer; color: #909399;'
+            })
+          ])
+        ]);
+      } else if (column.label === '店铺是否处理') {
+        return h('div', [
+          '店铺是否处理',
+          h('el-tooltip', {
+            props: {
+              content: '仅需要处理咨询类',
+              placement: 'top'
+            }
+          }, [
+            h('i', {
+              class: 'el-icon-question',
+              style: 'margin-left: 5px; cursor: pointer; color: #909399;'
+            })
+          ])
+        ]);
+      }
+      return column.label;
+    },
+    imageUrls(urls) {
+      return String(urls).split(",");
+    },
+    formatHandleStatus(status) {
+      return status === 1 ? '已回复' : '未回复';
+    },
+    formatHandleProcessCompleted(processCompleted) {
+      return processCompleted === 1 ? '已完成' : '处理中';
+    },
     /** 查询用户投诉列表 */
     getList() {
       this.loading = true;
@@ -316,26 +523,42 @@ export default {
     cancel() {
       this.open = false;
       this.reset();
+      this.resetReplyData();
     },
     // 表单重置
     reset() {
       this.form = {
         id: null,
-        fsUserId: null,
-        title: null,
+        userId: null,
+        templateId: null,
         content: null,
-        images: null,
-        type: null,
-        linkId: null,
+        phone: null,
+        urls: null,
+        account: null,
         createTime: null,
-        createBy: null,
-        updateTime: null,
-        updateBy: null,
-        remark: null,
-        nickName: null,
+        isHandle: 0,
+        remarks:null
       };
       this.resetForm("form");
     },
+    // 重置回复数据
+    resetReplyData() {
+      this.activeTab = 'complaint';
+      this.replyList = [];
+      this.replyTotal = 0;
+      this.replyQueryParams = {
+        pageNum: 1,
+        pageSize: 10,
+        complaintId: null
+      };
+      this.replyForm = {
+        content: '',
+        complaintId: null,
+        images: '' // 重置图片字段
+      };
+      this.replyImageList = [];
+      this.editReplyImageList = [];
+    },
     /** 搜索按钮操作 */
     handleQuery() {
       this.queryParams.pageNum = 1;
@@ -343,14 +566,16 @@ export default {
     },
     /** 重置按钮操作 */
     resetQuery() {
+      this.complaintTime = null;
+      this.queryParams.complaintsTime=null;
+      this.queryParams.complainteTime=null;
       this.resetForm("queryForm");
-      this.queryParams.nickName = null;
       this.handleQuery();
     },
     // 多选框选中数据
     handleSelectionChange(selection) {
       this.ids = selection.map(item => item.id)
-      this.single = selection.length!==1
+      this.single = selection.length !== 1
       this.multiple = !selection.length
     },
     /** 新增按钮操作 */
@@ -361,12 +586,21 @@ export default {
     },
     /** 修改按钮操作 */
     handleUpdate(row) {
+      this.complaintType = row.complaintType;
+      this.isProcessCompleted = row.isProcessCompleted;
       this.reset();
-      const id = row.id || this.ids
-      getComplaint(id).then(response => {
+      this.resetReplyData();
+      // const id = row.id || this.ids
+      const complaintId = row.id || this.complaintId
+      this.complaintId = complaintId;
+      getComplaint(complaintId).then(response => {
         this.form = response.data;
+        this.replyForm.complaintId = complaintId;
+        this.replyQueryParams.complaintId = complaintId;
         this.open = true;
-        this.title = "修改用户投诉";
+        this.title = "投诉详情";
+        // 加载回复列表
+        this.getReplyList();
       });
     },
     /** 提交按钮 */
@@ -418,34 +652,233 @@ export default {
         this.exportLoading = false;
       }).catch(() => {});
     },
-    imageClick(url){
-      this.srcList=[];
-      this.srcList.push(url)
+    changeTime(){
+      if(this.complaintTime!=null){
+        this.queryParams.complaintsTime=this.complaintTime[0];
+        this.queryParams.complainteTime=this.complaintTime[1];
+      }else{
+        this.queryParams.complaintsTime=null;
+        this.queryParams.complainteTime=null;
+      }
     },
-    handleClose(done) {
-      this.$confirm('确认关闭?')
-        .then(_ => {
-          this.isReplyOpen=false;
-          done();
-        })
-        .catch(_ => {});
+    // 获取回复列表
+    getReplyList() {
+      this.replyLoading = true;
+      // 模拟API调用 - 你需要替换为实际的API
+      setTimeout(() => {
+        // 模拟数据
+        listMsg(this.replyQueryParams).then(response => {
+          this.replyList = response.rows;
+          this.replyTotal = response.total;
+          this.replyLoading = false;
+        });
+      }, 500);
+    },
+    // 提交回复
+    submitReply() {
+      this.$refs.replyForm.validate(valid => {
+        if (valid) {
+          this.replyLoading = true;
+          // const imageUrls = this.replyImageList.map(file => file.url || file.response?.url).filter(url => url);
+          // this.replyForm.images = imageUrls.join(',');
+          // 模拟API调用
+          setTimeout(() => {
+            const newReply = {
+              content: this.replyForm.content,
+              complaintId:this.replyForm.complaintId,
+              images: this.replyForm.images, // 包含图片数据
+              sendType: 2
+            };
+            addMsg(newReply).then(response => {
+              this.replyLoading = false;
+              this.$message.success('回复发送成功');
+              this.replyForm.content = '';
+              this.replyForm.images = ''; // 重置图片字段
+              this.replyImageList = []; // 重置图片列表
+              this.getReplyList()
+            });
+
+          }, 500);
+        }
+      });
+    },
+    // 编辑回复
+    editReply(reply) {
+      this.editReplyForm = {
+        id: reply.id,
+        content: reply.content,
+        images: reply.images || '' // 包含图片数据
+      };
+      this.editReplyImageList = reply.images ?
+        reply.images.split(',').map((url, index) => ({
+          uid: index,
+          name: `image-${index}`,
+          url: url
+        })) : [];
+      this.editReplyVisible = true;
+    },
+
+    // 更新回复
+    updateReply() {
+      this.$refs.editReplyForm.validate(valid => {
+        if (valid) {
+          this.replyLoading = true;
+          // const imageUrls = this.editReplyImageList.map(file => file.url || file.response?.url).filter(url => url);
+          // this.editReplyForm.images = imageUrls.join(',');
+
+          // 模拟API调用
+          setTimeout(() => {
+            const index = this.replyList.findIndex(item => item.id === this.editReplyForm.id);
+            if (index !== -1) {
+              this.replyList[index].content = this.editReplyForm.content;
+              this.replyList[index].images = this.editReplyForm.images; // 更新图片
+            }
+            this.editReplyVisible = false;
+            this.replyLoading = false;
+            this.$message.success('回复更新成功');
+          }, 500);
+        }
+      });
+    },
+    // 删除回复
+    deleteReply(reply) {
+      this.$confirm('确定要删除这条回复吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        const index = this.replyList.findIndex(item => item.id === reply.id);
+        if (index !== -1) {
+          this.replyList.splice(index, 1);
+          this.replyTotal--;
+          this.$message.success('删除成功');
+        }
+      });
+    },
+    // 回复分页大小改变
+    handleReplySizeChange(val) {
+      this.replyQueryParams.pageSize = val;
+      this.getReplyList();
     },
-    //消息回复页面
-    reply(row){
-      this.isReplyOpen=true;
-      this.complaintId=row.id;
-      this.replyInfo.url = row.images;
-      this.replyInfo.urlList=[];
-      this.replyInfo.urlList.push(row.images);
-      this.complaint.title = row.title;
-      this.complaint.content = row.content;
-      this.complaint.type = row.type;
-      this.replyVisible = true;
+    // 回复当前页改变
+    handleReplyCurrentChange(val) {
+      this.replyQueryParams.pageNum = val;
+      this.getReplyList();
     },
-    replyClose(){
-      this.isReplyOpen=false;
-      this.replyVisible = false;
+    handleSuccess(res, file) {
+      if(res.code==200){
+        this.form.licenseImages=res.url;
+        this.$forceUpdate()
+      }
+      else{
+        this.msgError(res.msg);
+      }
+    },
+
+    beforeUpload(file) {
+      const isLt1M = file.size / 1024 / 1024 < 1;
+      if (!isLt1M) {
+        this.$message.error('上传图片大小不能超过 1MB!');
+      }
+      return   isLt1M;
+    },
+    handlecompleteComplaint(row) {
+      this.$confirm('是否完成当前投诉处理, 是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        completeComplaint({id:row.id}).then(response => {
+          this.getList();
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消删除'
+        });
+      });
     }
   }
 };
 </script>
+
+<style scoped>
+.reply-section {
+  margin-top: 10px;
+}
+
+.add-reply-card {
+  margin-bottom: 20px;
+}
+
+.reply-list-card {
+  min-height: 400px;
+}
+
+.reply-list {
+  min-height: 300px;
+}
+
+.empty-replies {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 200px;
+}
+
+.reply-item {
+  border-bottom: 1px solid #f0f0f0;
+  padding: 15px 0;
+}
+
+.reply-item:last-child {
+  border-bottom: none;
+}
+
+.reply-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 10px;
+}
+
+.reply-user {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.user-name {
+  font-weight: 500;
+  color: #303133;
+}
+
+.reply-time {
+  color: #909399;
+  font-size: 12px;
+}
+
+.reply-content {
+  background-color: #f8f9fa;
+  padding: 12px;
+  border-radius: 6px;
+  margin-bottom: 8px;
+  line-height: 1.5;
+  color: #606266;
+}
+
+.reply-actions {
+  text-align: right;
+}
+
+.reply-pagination {
+  margin-top: 20px;
+  text-align: center;
+}
+
+.image-container {
+  display: inline-block;
+  margin-right: 10px;
+  margin-bottom: 10px;
+}
+</style>