Преглед изворни кода

feat:公司码相关功能、客服管理模块

caoliqin пре 1 дан
родитељ
комит
a816b65a4d
2 измењених фајлова са 281 додато и 82 уклоњено
  1. 180 31
      src/views/app/customerMember/index.vue
  2. 101 51
      src/views/app/invitationCode/index.vue

+ 180 - 31
src/views/app/customerMember/index.vue

@@ -68,10 +68,11 @@
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
-    <el-table v-loading="loading" :data="memberList" @selection-change="handleSelectionChange" border>
+    <el-table v-loading="loading" :data="memberList" row-key="roleMemberId" @selection-change="handleSelectionChange" border>
       <el-table-column type="selection" width="55" align="center" />
       <el-table-column label="所属客服组" align="center" prop="roleName" min-width="140" />
-      <el-table-column label="成员名称" align="center" prop="memberName" min-width="120" />
+<!--      <el-table-column label="成员名称" align="center" prop="memberName" min-width="120" />-->
+      <el-table-column label="绑定销售" align="center" prop="companyUserName" min-width="140" show-overflow-tooltip />
       <el-table-column label="头像" align="center" prop="avatar" width="100">
         <template slot-scope="scope">
           <el-image
@@ -131,9 +132,19 @@
             />
           </el-select>
         </el-form-item>
-        <el-form-item label="成员名称" prop="memberName">
-          <el-input v-model="form.memberName" placeholder="请输入成员名称" />
+        <el-form-item label="绑定销售" prop="companyUserId">
+          <el-input
+            v-model="form.companyUserName"
+            placeholder="请选择绑定销售"
+            readonly
+            @click.native="openBindCompanyUserDialog"
+          >
+            <i slot="suffix" class="el-input__icon el-icon-search" @click.stop="openBindCompanyUserDialog"></i>
+          </el-input>
         </el-form-item>
+<!--        <el-form-item label="成员名称" prop="memberName">-->
+<!--          <el-input v-model="form.memberName" placeholder="请输入成员名称" />-->
+<!--        </el-form-item>-->
         <el-form-item label="头像" prop="avatar">
           <ImageUpload
             v-model="form.avatar"
@@ -153,6 +164,46 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
+
+    <el-dialog title="选择绑定销售" :visible.sync="bindCompanyUserOpen" width="500px" append-to-body>
+      <el-form ref="bindCompanyUserForm" :model="bindCompanyUserForm" :rules="bindCompanyUserRules" label-width="100px">
+        <el-form-item label="选择公司" prop="companyId">
+          <el-select
+            v-model="bindCompanyUserForm.companyId"
+            placeholder="请选择公司"
+            filterable
+            style="width: 100%;"
+            @change="handleBindCompanyChange"
+          >
+            <el-option
+              v-for="item in companyOptions"
+              :key="item.companyId"
+              :label="item.companyName"
+              :value="item.companyId"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="选择销售" prop="companyUserId">
+          <el-select
+            v-model="bindCompanyUserForm.companyUserId"
+            placeholder="请选择销售"
+            filterable
+            style="width: 100%;"
+          >
+            <el-option
+              v-for="item in companyUserOptions"
+              :key="item.userId"
+              :label="item.nickName + '_' + item.userName"
+              :value="item.userId"
+            />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitBindCompanyUserForm">确 定</el-button>
+        <el-button @click="cancelBindCompanyUser">取 消</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
@@ -164,6 +215,7 @@ import {
   delCustomerMember
 } from '@/api/app/customerMember'
 import { listCustomerRoleOptions } from '@/api/app/customerRole'
+import { getCompanyList, getCompanyUserList } from '@/api/company/companyUser'
 import ImageUpload from '@/views/qw/sop/ImageUpload'
 
 export default {
@@ -179,6 +231,21 @@ export default {
       multiple: true,
       memberList: [],
       roleOptions: [],
+      companyOptions: [],
+      companyUserOptions: [],
+      bindCompanyUserOpen: false,
+      bindCompanyUserForm: {
+        companyId: null,
+        companyUserId: null
+      },
+      bindCompanyUserRules: {
+        companyId: [
+          { required: true, message: '请选择公司', trigger: 'change' }
+        ],
+        companyUserId: [
+          { required: true, message: '请选择销售', trigger: 'change' }
+        ]
+      },
       title: '',
       open: false,
       queryParams: {
@@ -192,9 +259,12 @@ export default {
         appCustomerId: [
           { required: true, message: '请选择所属客服组', trigger: 'change' }
         ],
-        memberName: [
-          { required: true, message: '成员名称不能为空', trigger: 'blur' }
-        ]
+        companyUserId: [
+          { required: true, message: '请选择绑定销售', trigger: 'change' }
+        ],
+        // memberName: [
+        //   { required: true, message: '成员名称不能为空', trigger: 'blur' }
+        // ]
       }
     }
   },
@@ -210,11 +280,6 @@ export default {
       const num = Number(value)
       return Number.isNaN(num) ? value : num
     },
-    getRowAppCustomerId(row) {
-      return this.parseRoleId(
-        row.appCustomerId ?? row.roleId ?? row.cusRoleId ?? row.customerRoleId
-      )
-    },
     loadRoleOptions() {
       listCustomerRoleOptions().then(response => {
         this.roleOptions = (response.rows || []).map(item => ({
@@ -233,15 +298,77 @@ export default {
         this.loading = false
       })
     },
+    resetBindCompanyUserForm() {
+      this.bindCompanyUserForm = {
+        companyId: null,
+        companyUserId: null
+      }
+      this.companyUserOptions = []
+      this.$nextTick(() => {
+        this.$refs.bindCompanyUserForm && this.$refs.bindCompanyUserForm.clearValidate()
+      })
+    },
+    openBindCompanyUserDialog() {
+      getCompanyList().then(response => {
+        if (response.code === 200) {
+          this.companyOptions = response.data || []
+          this.resetBindCompanyUserForm()
+          this.bindCompanyUserOpen = true
+        } else {
+          this.msgError(response.msg || '获取公司列表失败')
+        }
+      }).catch(() => {
+        this.msgError('获取公司列表失败')
+      })
+    },
+    handleBindCompanyChange(companyId) {
+      this.bindCompanyUserForm.companyUserId = null
+      if (!companyId) {
+        this.companyUserOptions = []
+        return
+      }
+      getCompanyUserList({ companyId }).then(response => {
+        if (response.code === 200) {
+          this.companyUserOptions = response.data || []
+        } else {
+          this.msgError(response.msg || '获取销售列表失败')
+          this.companyUserOptions = []
+        }
+      }).catch(() => {
+        this.msgError('获取销售列表失败')
+        this.companyUserOptions = []
+      })
+    },
+    submitBindCompanyUserForm() {
+      this.$refs.bindCompanyUserForm.validate(valid => {
+        if (!valid) {
+          return
+        }
+        const selected = this.companyUserOptions.find(
+          item => item.userId === this.bindCompanyUserForm.companyUserId
+        )
+        this.form.companyUserId = this.bindCompanyUserForm.companyUserId
+        this.form.companyUserName = selected
+          ? `${selected.nickName}_${selected.userName}`
+          : ''
+        this.bindCompanyUserOpen = false
+        this.$refs.form && this.$refs.form.validateField('companyUserId')
+      })
+    },
+    cancelBindCompanyUser() {
+      this.bindCompanyUserOpen = false
+      this.resetBindCompanyUserForm()
+    },
     cancel() {
       this.open = false
       this.reset()
     },
     reset() {
       this.form = {
-        id: null,
+        roleMemberId: null,
         appCustomerId: null,
-        memberName: null,
+        companyUserId: null,
+        companyUserName: null,
         avatar: null,
         remark: null
       }
@@ -261,7 +388,7 @@ export default {
       this.handleQuery()
     },
     handleSelectionChange(selection) {
-      this.ids = selection.map(item => item.id)
+      this.ids = selection.map(item => item.roleMemberId)
       this.single = selection.length !== 1
       this.multiple = !selection.length
     },
@@ -271,14 +398,17 @@ export default {
       this.title = '新增客服'
     },
     handleUpdate(row) {
-      const target = row || this.memberList.find(item => item.id === this.ids[0])
+      const target = row || this.memberList.find(item => item.roleMemberId === this.ids[0])
       if (!target) {
         return
       }
       this.form = {
-        id: target.id,
-        appCustomerId: this.getRowAppCustomerId(target),
-        memberName: target.memberName,
+        roleMemberId: target.roleMemberId,
+        appCustomerId: target.appCustomerId != null && target.appCustomerId !== ''
+          ? this.parseRoleId(target.appCustomerId)
+          : null,
+        companyUserId: target.companyUserId,
+        companyUserName: target.companyUserName,
         avatar: target.avatar,
         remark: target.remark
       }
@@ -289,7 +419,7 @@ export default {
       })
     },
     handleDelete(row) {
-      const ids = row ? row.id : this.ids.join(',')
+      const ids = row ? row.roleMemberId : this.ids.join(',')
       this.$confirm('是否确认删除选中的客服数据?', '警告', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
@@ -301,26 +431,45 @@ export default {
         this.msgSuccess('删除成功')
       }).catch(() => {})
     },
+    buildSubmitData() {
+      const data = {
+        appCustomerId: this.parseRoleId(this.form.appCustomerId),
+        avatar: this.form.avatar,
+        remark: this.form.remark,
+        companyUserId: this.form.companyUserId,
+        companyUserName: this.form.companyUserName
+      }
+      if (this.form.roleMemberId != null) {
+        data.roleMemberId = this.form.roleMemberId
+      }
+      return data
+    },
     submitForm() {
       this.$refs.form.validate(valid => {
         if (!valid) {
           return
         }
-        if (this.form.id != null) {
-          updateCustomerMember(this.form).then(() => {
-            this.msgSuccess('修改成功')
-            this.open = false
-            this.getList()
-          })
-        } else {
-          addCustomerMember(this.form).then(() => {
-            this.msgSuccess('新增成功')
+        const data = this.buildSubmitData()
+        const request = this.form.roleMemberId != null
+          ? updateCustomerMember(data)
+          : addCustomerMember(data)
+        request.then(response => {
+          if (response.code === 200) {
+            this.msgSuccess(this.form.roleMemberId != null ? '修改成功' : '新增成功')
             this.open = false
             this.getList()
-          })
-        }
+          } else {
+            this.msgError(response.msg || '保存失败')
+          }
+        })
       })
     }
   }
 }
 </script>
+
+<style scoped>
+.el-input__icon {
+  cursor: pointer;
+}
+</style>

+ 101 - 51
src/views/app/invitationCode/index.vue

@@ -99,8 +99,57 @@
     </el-row>
 
     <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
-      <el-tab-pane label="个人码" name="person">
-        <!-- 个人邀请码表格 -->
+<!--      <el-tab-pane label="个人码" name="person">-->
+<!--        &lt;!&ndash; 个人邀请码表格 &ndash;&gt;-->
+<!--        <el-table-->
+<!--          v-loading="loading"-->
+<!--          :data="tableInfo.list"-->
+<!--          @selection-change="handleSelectionChange"-->
+<!--          border-->
+<!--        >-->
+<!--          <el-table-column type="selection" width="55" align="center" />-->
+<!--          <el-table-column label="邀请码" align="center" prop="invitationCode" min-width="150"/>-->
+<!--          <el-table-column label="部门" align="left" prop="deptName" min-width="150"/>-->
+<!--          <el-table-column label="备注" align="center" prop="remark"/>-->
+<!--          <el-table-column label="创建时间" align="center" prop="createTime" min-width="150" />-->
+<!--          <el-table-column label="修改时间" align="center" prop="createTime" min-width="150" />-->
+<!--          <el-table-column label="客服" align="center" min-width="200px" prop="customerNames">-->
+<!--            <template slot-scope="scope">-->
+<!--              <div v-for="i in (scope.row.customerNames ? scope.row.customerNames.split(',') : [])" :key="i" style="display: inline;">-->
+<!--                <el-tag type="primary" style="margin: 3px;">{{i}}</el-tag>-->
+<!--              </div>-->
+<!--            </template>-->
+<!--          </el-table-column>-->
+<!--          <el-table-column label="标签" align="center" min-width="200" prop="tagsName">-->
+<!--            <template slot-scope="scope">-->
+<!--              <div v-for="i in (scope.row.tagNames ? scope.row.tagNames.split(',') : [])" :key="i" style="display: inline;">-->
+<!--                <el-tag type="success" style="margin: 3px;">{{i}}</el-tag>-->
+<!--              </div>-->
+<!--            </template>-->
+<!--          </el-table-column>-->
+<!--          <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="190">-->
+<!--            <template slot-scope="scope">-->
+<!--              <el-button-->
+<!--                size="mini"-->
+<!--                type="text"-->
+<!--                icon="el-icon-edit"-->
+<!--                @click="handleUpdate(scope.row)"-->
+<!--                v-hasPermi="['app:invite:edit']"-->
+<!--              >修改</el-button>-->
+<!--              <el-button-->
+<!--                size="mini"-->
+<!--                type="text"-->
+<!--                icon="el-icon-delete"-->
+<!--                @click="handleDelete(scope.row)"-->
+<!--                v-hasPermi="['app:invite:delete']"-->
+<!--                style="color: red;"-->
+<!--              >删除</el-button>-->
+<!--            </template>-->
+<!--          </el-table-column>-->
+<!--        </el-table>-->
+<!--      </el-tab-pane>-->
+      <el-tab-pane label="公司码" name="company">
+        <!-- 公司邀请码表格 -->
         <el-table
           v-loading="loading"
           :data="tableInfo.list"
@@ -109,56 +158,32 @@
         >
           <el-table-column type="selection" width="55" align="center" />
           <el-table-column label="邀请码" align="center" prop="invitationCode" min-width="150"/>
-          <el-table-column label="部门" align="left" prop="deptName" min-width="150"/>
-          <el-table-column label="备注" align="center" prop="remark"/>
-          <el-table-column label="创建时间" align="center" prop="createTime" min-width="150" />
-          <el-table-column label="修改时间" align="center" prop="createTime" min-width="150" />
-          <el-table-column label="客服" align="center" min-width="200px" prop="customerNames">
-            <template slot-scope="scope">
-              <div v-for="i in (scope.row.customerNames ? scope.row.customerNames.split(',') : [])" :key="i" style="display: inline;">
-                <el-tag type="primary" style="margin: 3px;">{{i}}</el-tag>
-              </div>
-            </template>
-          </el-table-column>
-          <el-table-column label="标签" align="center" min-width="200" prop="tagsName">
+          <el-table-column label="公司" align="left" prop="companyName" min-width="150"/>
+          <el-table-column label="二维码" align="center" prop="qrCode" width="120">
             <template slot-scope="scope">
-              <div v-for="i in (scope.row.tagNames ? scope.row.tagNames.split(',') : [])" :key="i" style="display: inline;">
-                <el-tag type="success" style="margin: 3px;">{{i}}</el-tag>
+              <div v-if="getQrCodeUrl(scope.row)" class="qrcode-cell">
+                <el-popover placement="right" trigger="hover" width="220">
+                  <el-image
+                    :src="getQrCodeUrl(scope.row)"
+                    style="width: 200px; height: 200px;"
+                    fit="contain"
+                  />
+                  <el-image
+                    slot="reference"
+                    style="width: 60px; height: 60px; cursor: pointer;"
+                    :src="getQrCodeUrl(scope.row)"
+                    :preview-src-list="[getQrCodeUrl(scope.row)]"
+                    fit="contain"
+                  >
+                    <div slot="error" class="image-slot">
+                      <i class="el-icon-picture-outline"></i>
+                    </div>
+                  </el-image>
+                </el-popover>
               </div>
+              <span v-else>-</span>
             </template>
           </el-table-column>
-          <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="190">
-            <template slot-scope="scope">
-              <el-button
-                size="mini"
-                type="text"
-                icon="el-icon-edit"
-                @click="handleUpdate(scope.row)"
-                v-hasPermi="['app:invite:edit']"
-              >修改</el-button>
-              <el-button
-                size="mini"
-                type="text"
-                icon="el-icon-delete"
-                @click="handleDelete(scope.row)"
-                v-hasPermi="['app:invite:delete']"
-                style="color: red;"
-              >删除</el-button>
-            </template>
-          </el-table-column>
-        </el-table>
-      </el-tab-pane>
-      <el-tab-pane label="公司码" name="company">
-        <!-- 公司邀请码表格 -->
-        <el-table
-          v-loading="loading"
-          :data="tableInfo.list"
-          @selection-change="handleSelectionChange"
-          border
-        >
-          <el-table-column type="selection" width="55" align="center" />
-          <el-table-column label="邀请码" align="center" prop="invitationCode" min-width="150"/>
-          <el-table-column label="公司" align="left" prop="companyName" min-width="150"/>
           <el-table-column label="备注" align="center" prop="remark"/>
           <el-table-column label="创建时间" align="center" prop="createTime" min-width="150" />
           <el-table-column label="修改时间" align="center" prop="createTime" min-width="150" />
@@ -336,7 +361,7 @@ export default {
         list: [],
         total: 0,
       },
-      activeName: 'person',
+      activeName: 'company',
       // 查询参数
       queryParams: {
         pageSize: 10,
@@ -401,6 +426,13 @@ export default {
     this.getDeptList();
   },
   methods: {
+    /**
+     * 获取二维码地址
+     */
+    getQrCodeUrl(row) {
+      return row.qrCode || row.qrCodeUrl || row.codeUrl || null
+    },
+
     /**
      * 查询邀请码列表
      */
@@ -543,8 +575,8 @@ export default {
     },
     /**
      * tab切换
-     * @param tab 
-     * @param event 
+     * @param tab
+     * @param event
      */
     handleClick(tab, event) {
       this.handleQuery();
@@ -855,4 +887,22 @@ export default {
 .el-tag + .el-tag {
   margin-left: 10px;
 }
+
+.qrcode-cell {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+
+.qrcode-cell .image-slot {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+  height: 100%;
+  background: #f5f7fa;
+  color: #909399;
+  font-size: 20px;
+}
 </style>