ct vor 14 Stunden
Ursprung
Commit
182bac00d8

+ 93 - 0
src/api/store/complaint.js

@@ -0,0 +1,93 @@
+import request from '@/utils/request'
+
+
+// 查询用户投诉列表
+export function listComplaint(data) {
+  return request({
+    url: 'store/complaint/list',
+    method: 'post',
+    data: data
+  })
+}
+
+// 查询用户投诉详细
+export function getComplaint(id) {
+  return request({
+    url: 'store/complaint/' + id,
+    method: 'get'
+  })
+}
+
+
+
+// 修改用户投诉
+export function updateComplaint(data) {
+  return request({
+    url: 'store/complaint',
+    method: 'put',
+    data: data
+  })
+}
+
+
+
+// 导出用户投诉
+export function exportComplaint(query) {
+  return request({
+    url: 'store/complaint/export',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询投诉消息记录列表
+export function listMsg(query) {
+  return request({
+    url: 'store/msg/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询投诉消息记录详细
+export function getMsg(id) {
+  return request({
+    url: 'store/msg/' + id,
+    method: 'get'
+  })
+}
+
+// 新增投诉消息记录
+export function addMsg(data) {
+  return request({
+    url: 'store/msg',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改投诉消息记录
+export function updateMsg(data) {
+  return request({
+    url: 'store/msg',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除投诉消息记录
+export function delMsg(id) {
+  return request({
+    url: 'store/msg/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出投诉消息记录
+export function exportMsg(query) {
+  return request({
+    url: 'store/msg/export',
+    method: 'get',
+    params: query
+  })
+}

+ 3 - 3
src/components/ImageUpload/index.vue

@@ -11,7 +11,7 @@
       name="file"
       :on-remove="handleRemove"
       :show-file-list="true"
-      :headers="headers"
+      
       :file-list="fileList"
       :on-preview="handlePictureCardPreview"
       :class="{hide: this.fileList.length >= this.limit}"
@@ -74,7 +74,7 @@ export default {
       dialogVisible: false,
       hideUpload: false,
       baseUrl: process.env.VUE_APP_BASE_API,
-      uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
+      uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/uploadOSS", // 上传的图片服务器地址
       headers: {
         Authorization: "Bearer " + getToken(),
       },
@@ -124,7 +124,7 @@ export default {
     },
     // 上传成功回调
     handleUploadSuccess(res) {
-      this.fileList.push({ name: res.fileName, url: res.fileName });
+      this.fileList.push({ name: res.url, url: res.url });
       this.$emit("input", this.listToString(this.fileList));
       this.loading.close();
     },

+ 15 - 1
src/router/index.js

@@ -133,6 +133,19 @@ export const constantRoutes = [
       }
     ]
   },
+  {
+    path: '/operation',
+    component: Layout,
+    redirect: 'noredirect',
+    children: [
+      {
+        path: 'complaint',
+        component: (resolve) => require(['@/views/store/complaint/index'], resolve),
+        name: '投诉管理',
+        meta: { title: '投诉管理', icon: 'textarea', noCache: true, affix: false }
+      },
+    ]
+ },
   {
      path: '/finance',
      component: Layout,
@@ -172,7 +185,8 @@ export const constantRoutes = [
           meta: { title: '药品销售统计', icon: 'textarea', noCache: true, affix: false }
         }
       ]
-   }/* ,
+   }
+   /* ,
     {
       path: '/storeLog',
       component: Layout,

+ 814 - 0
src/views/store/complaint/index.vue

@@ -0,0 +1,814 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="用户" prop="userId">
+        <el-input
+          v-model="queryParams.userId"
+          placeholder="请输入用户id"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="联系方式" prop="phone">
+        <el-input
+          v-model="queryParams.phone"
+          placeholder="请输入联系方式"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <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>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          :loading="exportLoading"
+          @click="handleExport"
+        >导出</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="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-tag
+            :type="(scope.row.isHandleStore == 1)? 'success' : 'warning'"
+            disable-transitions
+          >
+            {{ formatHandleStatus(scope.row.isHandle) }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <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-edit"
+            @click="handleUpdate(scope.row)"
+          >投诉详情</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 修改用户投诉对话框 -->
+    <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="投诉详情" 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
+                  />
+                </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"/>  
+
+                </el-form-item>
+
+                <el-form-item>
+                  <el-button type="primary" size="small" @click="submitReply" :loading="replyLoading">
+                    <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-tab-pane>
+      </el-tabs>
+
+      <div slot="footer" class="dialog-footer">
+        <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="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>
+      <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,listMsg,addMsg } from "@/api/store/complaint";
+import ImageUpload from '@/components/ImageUpload/index';
+export default {
+  name: "Complaint",
+  components: {
+     ImageUpload
+  },
+  data() {
+    return {
+      replyImageList: [],
+      uploadUrl:process.env.VUE_APP_BASE_API+"/common/uploadOSS",
+      complaintId:null,
+      activeName:"0",
+      typeOptions:[
+        {
+          dictValue:'0',
+          dictLabel:'默认'
+        },
+        {
+          dictValue:'1',
+          dictLabel:'店铺'
+        },
+        {
+          dictValue:'2',
+          dictLabel:'商品'
+        },
+      ],
+      complaintTypeOptions:[
+        {
+          dictValue:1,
+          dictLabel:'咨询'
+        },
+        {
+          dictValue:2,
+          dictLabel:'投诉/举报'
+        },
+      ],
+      complaintTime:null,
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 用户投诉表格数据
+      complaintList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 当前激活的标签页
+      activeTab: 'complaint',
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        userId: null,
+        userName: null,
+        templateId: null,
+        content: 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: ''
+      }
+    };
+  },
+  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 ? '已处理' : '未处理';
+    },
+    /** 查询用户投诉列表 */
+    getList() {
+      this.loading = true;
+      listComplaint(this.queryParams).then(response => {
+        this.complaintList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+      this.resetReplyData();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+        id: null,
+        userId: null,
+        templateId: null,
+        content: null,
+        phone: null,
+        urls: null,
+        account: null,
+        createTime: 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;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.complaintTime = null;
+      this.queryParams.complaintsTime=null;
+      this.queryParams.complainteTime=null;
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset();
+      this.open = true;
+      this.title = "添加用户投诉";
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      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.getReplyList();
+      });
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != null) {
+            updateComplaint(this.form).then(response => {
+              this.msgSuccess("修改成功");
+              this.open = false;
+              this.getList();
+            });
+          } else {
+            addComplaint(this.form).then(response => {
+              this.msgSuccess("新增成功");
+              this.open = false;
+              this.getList();
+            });
+          }
+        }
+      });
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const ids = row.id || this.ids;
+      this.$confirm('是否确认删除用户投诉编号为"' + ids + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function() {
+          return delComplaint(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(() => {});
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      const queryParams = this.queryParams;
+      this.$confirm('是否确认导出所有用户投诉数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(() => {
+          this.exportLoading = true;
+          return exportComplaint(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+          this.exportLoading = false;
+        }).catch(() => {});
+    },
+    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;
+      }
+    },
+    // 获取回复列表
+    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();
+    },
+    // 回复当前页改变
+    handleReplyCurrentChange(val) {
+      this.replyQueryParams.pageNum = val;
+      this.getReplyList();
+    },
+    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;
+    },
+  }
+};
+</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>