Procházet zdrojové kódy

客服管理 修改

wks před 1 rokem
rodič
revize
676f8cff05

+ 3 - 3
src/http/moudules/customer/customerManage.js

@@ -45,7 +45,7 @@ export const pageQuery = (data) => {
 // 编辑客服
 export const getCustomer = (customerId) => {
   return axios({
-    url: '/wechat/customer/manage' + customerId,
+    url: '/wechat/customer/manage/' + customerId,
     method: 'get',
   })
 }
@@ -62,7 +62,7 @@ export const addCustomer = (data) => {
 // 删除客服
 export const deleteCustomer = (customerId) => {
   return axios({
-    url: '/wechat/customer/manage' + customerId,
+    url: '/wechat/customer/manage/' + customerId,
     method: 'delete',
   })
 }
@@ -70,7 +70,7 @@ export const deleteCustomer = (customerId) => {
 // 修改客服
 export const reviseCustomer = (customerId, data) => {
   return axios({
-    url: '/wechat/customer/manage' + customerId,
+    url: '/wechat/customer/manage/' + customerId,
     method: 'put',
     data
   })

+ 226 - 112
src/views/PeopleManage/Customer/CustomerServiceAccount.vue

@@ -1,6 +1,5 @@
 <script setup>
-
-import {getDeptTree} from "../../../http/moudules/customer/customerManage";
+import {getCustomer} from "../../../http/moudules/customer/customerManage";
 
 export default {
   data() {
@@ -11,22 +10,48 @@ export default {
         pageNum: 1,
         pageSize: 20,
       },
-      // 弹框
+      imageUrl: "",
       dialogVisible: false,
+      dialogType: 'add',
+      uploadProgress: 0,
+      submitting: false,
+      userLoading: false,
+
+      // 表单数据
       form: {
+        id: null,
         nickname: '',
         avatar: '',
-        backendUser: '',
-        wechatUser: ''
+        userId: null,
+        departmentId: null,
+        receptionist: '',
+        receptionistId: null
       },
-      backendUsers: [],
+
+      // 选项数据
+      backendOptions: [],
       departmentTree: [],
-      wechatUsers: [],
+      wecomUsers: [],
+
+      // 树配置
       treeProps: {
-        label: 'name',
-        children: 'children',
-        isLeaf: 'leaf'
-      }
+        label: 'deptName',
+        children: 'childDept',
+      },
+
+      // 验证规则
+      rules: {
+        nickname: [
+          {required: true, message: '请输入客服昵称', trigger: 'blur'},
+          {min: 2, max: 20, message: '长度在2到20个字符', trigger: 'blur'}
+        ],
+        departmentId: [
+          {required: true, message: '请选择部门', trigger: 'change'}
+        ],
+        receptionistId: [
+          {required: true, message: '请选择企微用户', trigger: 'change'}
+        ]
+      },
     }
   },
   created() {
@@ -36,7 +61,7 @@ export default {
     queryPage() {
       this.$api.customerManage.pageQuery(this.queryCondition).then((res) => {
         if (res.code === 200) {
-          this.pageResult = res.data
+          this.pageResult = res.data.content
         }
       })
     },
@@ -65,84 +90,149 @@ export default {
       })
     },
 
-    // 头像上传成功处理
-    handleAvatarSuccess(res, file) {
-      this.form.avatar = URL.createObjectURL(file.raw)
+    // 打开弹窗(新增)
+    handleAdd() {
+      this.dialogType = 'add'
+      this.dialogVisible = true
+      this.resetForm()
+      this.loadDepartment();
     },
 
-    // 头像上传前验证
-    beforeAvatarUpload(file) {
-      const isImage = file.type.startsWith('image/')
-      const isLt2M = file.size / 1024 / 1024 < 2
+    // 打开弹窗(编辑)
+    handleEdit(row) {
+      this.dialogType = 'edit'
+      this.dialogVisible = true
+      this.$nextTick(() => {
+        this.loadEditData(row)
+      })
+    },
 
-      if (!isImage) {
-        this.$message.error('只能上传图片文件!')
-      }
-      if (!isLt2M) {
-        this.$message.error('图片大小不能超过2MB!')
+    // 加载编辑数据
+    async loadEditData(data) {
+      this.loadDepartment()
+      // 加载部门路径
+      if (data.id) {
+        // await this.$api.customerManage.getDeptUser(data.departmentId)
+        await this.$api.customerManage.getCustomer(data.id).then((res) => {
+          data = res.data
+          this.from = {
+            id: data.id,
+            nickname: data.nickname,
+            avatar: data.avatar,
+            userId: data.userId,
+            departmentId: data.departmentId,
+            receptionist: data.receptionist,
+            receptionistId: data.receptionistId
+          }
+          this.imageUrl = res.data.avatarUrl
+        })
+        this.$refs.deptTree.setCurrentKey(data.departmentId)
+        this.loadDepartmentUsers(data.departmentId)
       }
-      return isImage && isLt2M
     },
 
-    // 加载后线人员
-    async loadBackendUsers() {
+    // 加载后线人员选项
+    async loadBackendOptions() {
+      if (this.backendOptions.length) return
+      const {data} = await this.$api.user.findBackListByDeptId(99)
+      this.backendOptions = data
+    },
+
+    // 部门懒加载
+    loadDepartment() {
+      this.$api.customerManage.getDeptTree().then((rep) => {
+        this.departmentTree = rep.data
+      })
+    },
+
+    // 部门点击事件
+    async handleDeptClick(data) {
+      this.form.departmentId = data.deptId
+      await this.loadDepartmentUsers(data.deptId)
+    },
+
+    // 加载部门用户
+    async loadDepartmentUsers(departmentId) {
+      this.userLoading = true
       try {
-        const res = await this.$api.user.findBackListByDeptId(99)
-        this.backendUsers = res.data.map(item => ({
-          value: item.id,
-          label: item.name
-        }))
-      } catch (error) {
-        this.$message.error('获取后线人员失败')
+        const {data} = await this.$api.customerManage.getDeptUser(departmentId)
+        this.wecomUsers = data
+      } finally {
+        this.userLoading = false
       }
     },
 
-    // 加载部门数据(懒加载)
-    async loadDepartment(node, resolve) {
-      try {
-        const res = await this.$api.customerManage.getDeptTree();
-        const departments = res.data.map(d => ({
-          ...d,
-          leaf: d.childDept.size !== 0
-        }))
-        resolve(departments)
-      } catch (error) {
-        this.$message.error('加载部门失败')
-        resolve([])
+    // 上传图片
+    imageUpload(file) {
+      this.$refs.upload1.clearFiles();
+      const isImage = /\.(jpg|png)$/i.test(file.name)
+      const isLt2M = file.size / 1024 / 1024 < 2
+      if (!isImage) {
+        this.$message.error('只能上传png,jpg格式图片!')
+        return false
       }
+      if (!isLt2M) {
+        this.$message.error('图片大小不能超过2MB!')
+        return false
+      }
+      let file1 = file.raw;
+      //转临时路径
+      this.imageUrl = window.URL.createObjectURL(file1);
+      const params = new FormData();
+      params.append("multipartFile", file1);
+      params.append("type", "avatar");
+      this.$api.letter.uploadFile(params).then((res) => {
+        if (res.code === 200) {
+          this.form.avatar = res.data.id;
+        } else {
+          this.$message.error(res.msg);
+        }
+      });
+      return true
     },
 
-    // 部门点击事件
-    async handleDepartmentClick(department) {
+    // 表单提交
+    async handleSubmit() {
       try {
-        const res = await this.$api.customerManage.getDeptUser(department.id).then((res) => {
-          if (res.code === 200) {
-            this.wechatUsers = res.data
-          }else {
-            this.$message.error(res.message)
-          }
-        })
+        await this.$refs.formRef.validate()
+        this.submitting = true
+        this.form.receptionist = this.wecomUsers.filter((item) => item.userId==this.form.receptionistId)[0].name
+        if(this.dialogType === 'add'){
+          await this.$api.customerManage.addCustomer(this.form)
+        }else if(this.dialogType === 'edit'){
+          await this.$api.customerManage.reviseCustomer(this.form.id, this.form)
+        }
+        this.$emit('success')
+        this.dialogVisible = false
+        this.$message.success('操作成功')
       } catch (error) {
-        this.$message.error('获取部门用户失败')
+        console.error(error)
+      } finally {
+        this.submitting = false
+        this.imageUrl = ""
+      }
+    },
+
+    // 重置表单
+    resetForm() {
+      this.form = {
+        id: null,
+        nickname: '',
+        avatar: '',
+        userId: null,
+        departmentId: null,
+        receptionist: '',
+        receptionistId: null
       }
+      this.wecomUsers = []
     },
 
-    // 确认提交
-    handleConfirm() {
-      // 这里添加验证逻辑
-      this.$api.customerManage.addCustomer.post(this.form)
-          .then((res) => {
-            if (res.code === 200) {
-              this.$message.success('保存成功')
-            }else {
-              this.$message.error(res.message)
-            }
-            this.dialogVisible = false
-          })
-          .catch(() => {
-            this.$message.error('保存失败')
-          })
+    // 弹窗关闭处理
+    handleClose() {
+      this.resetForm()
+      this.uploadProgress = 0
     }
+
   }
 }
 </script>
@@ -156,7 +246,7 @@ export default {
           <el-input v-model="queryCondition.nickname" placeholder="请输入昵称" class="widths" clearable></el-input>
         </el-form-item>
         <el-button type="primary" size="small" @click="queryPage">查询</el-button>
-        <el-button type="primary" size="small" @click="dialogVisible=true">添加客服</el-button>
+        <el-button type="primary" size="small" @click="handleAdd">添加客服</el-button>
       </el-row>
     </el-form>
     <el-table :data="pageResult" style="width: 100%" height="580" border highlight-current-row stripe
@@ -175,88 +265,112 @@ export default {
       <el-table-column prop="dutyCustomer" label="值班时间"></el-table-column>
       <el-table-column label="操作" align="center" width="200" fixed="right">
         <template slot-scope="scope">
-          <el-button type="text" size="small" @click="editCustomer(scope.row.id)">编辑</el-button>
+          <el-button type="text" size="small" @click="handleEdit(scope.row)">编辑</el-button>
           <el-button type="text" size="small" @click="">删除</el-button>
-          <el-button type="text" size="small" @click="scope.row.id">值班配置</el-button>
+          <el-button type="text" size="small" @click="">值班配置</el-button>
           <el-button type="text" size="small" @click="">清除值班配置</el-button>
         </template>
       </el-table-column>
+
     </el-table>
 
-    <!-- 添加客服弹框 -->
+    <!-- 弹窗主体 -->
     <el-dialog
-        title="客服信息设置"
+        :title="dialogType === 'add' ? '新增客服' : '编辑客服'"
         :visible.sync="dialogVisible"
-        width="600px"
-    >
-      <el-form :model="form" label-width="100px">
+        width="700px"
+        @closed="handleClose">
+      <el-form
+          ref="formRef"
+          :model="form"
+          :rules="rules"
+          label-width="100px"
+          label-position="right">
+
         <!-- 客服昵称 -->
-        <el-form-item label="客服昵称">
-          <el-input v-model="form.nickname" placeholder="请输入客服昵称"></el-input>
+        <el-form-item label="客服昵称" prop="nickname">
+          <el-input
+              v-model="form.nickname"
+              placeholder="请输入2-20个字符"
+              clearable
+              maxlength="20"/>
         </el-form-item>
 
-        <!-- 客服头像上传 -->
-        <el-form-item label="客服头像">
+        <!-- 客服头像 -->
+        <el-form-item label="客服头像" prop="avatar">
           <el-upload
-              class="avatar-uploader"
-              action="/api/upload"
+              style="margin-bottom: 10px"
+              class="upload-demo"
+              action="#"
+              :limit="1"
+              accept=".png, .jpg, .jpeg"
+              :auto-upload="false"
+              :on-change="imageUpload"
               :show-file-list="false"
-              :on-success="handleAvatarSuccess"
-              :before-upload="beforeAvatarUpload">
-            <img v-if="form.avatar" :src="form.avatar" class="avatar">
+              list-type="picture-card"
+              ref="upload1"
+          >
+            <img v-if="imageUrl" :src="imageUrl" class="avatar" style="width: 100px; height: 100px" alt=""/>
             <i v-else class="el-icon-plus avatar-uploader-icon"></i>
           </el-upload>
+          <span>支持png,jpg格式图片,大小不超过2MB</span>
         </el-form-item>
 
-        <!-- 后线人员选择 -->
-        <el-form-item label="后线人员">
+        <!-- 后线人员 -->
+        <el-form-item label="后线人员" prop="userId">
           <el-select
-              v-model="form.backendUser"
+              v-model="form.userId"
               filterable
+              clearable
               placeholder="请选择后线人员"
-              @focus="loadBackendUsers">
+              @focus="loadBackendOptions">
             <el-option
-                v-for="item in backendUsers"
-                :key="item.value"
-                :label="item.label"
-                :value="item.value">
-            </el-option>
+                v-for="item in backendOptions"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"/>
           </el-select>
         </el-form-item>
 
         <!-- 企微部门树 -->
-        <el-form-item label="企微部门">
+        <el-form-item label="企微部门" prop="departmentId">
           <el-tree
+              ref="deptTree"
               :data="departmentTree"
               :props="treeProps"
-              :load="loadDepartment"
-              lazy
-              @node-click="handleDepartmentClick"
-              highlight-current>
-          </el-tree>
+              node-key="deptId"
+              highlight-current
+              @node-click="handleDeptClick"/>
         </el-form-item>
 
-        <!-- 企微用户选择 -->
-        <el-form-item label="企微用户">
+        <!-- 企微用户 -->
+        <el-form-item label="企微用户" prop="receptionistId">
           <el-select
-              v-model="form.wechatUser"
+              v-model="form.receptionistId"
+              :loading="userLoading"
               filterable
-              placeholder="请先选择部门">
+              clearable
+              placeholder="请先选择企微用户">
             <el-option
-                v-for="user in wechatUsers"
-                :key="user.id"
+                v-for="user in wecomUsers"
+                :key="user.userId"
                 :label="user.name"
-                :value="user.id">
-            </el-option>
+                :value="user.userId"/>
           </el-select>
         </el-form-item>
       </el-form>
 
       <div slot="footer" class="dialog-footer">
         <el-button @click="dialogVisible = false">取 消</el-button>
-        <el-button type="primary" @click="handleConfirm">确 定</el-button>
+        <el-button
+            type="primary"
+            :loading="submitting"
+            @click="handleSubmit">
+          确 定
+        </el-button>
       </div>
     </el-dialog>
+
   </div>
 
 </template>