|
|
@@ -12,7 +12,7 @@ export default {
|
|
|
queryCondition: {
|
|
|
nickname: "",
|
|
|
pageNum: 1,
|
|
|
- pageSize: 20,
|
|
|
+ pageSize: 10,
|
|
|
},
|
|
|
imageUrl: "",
|
|
|
dialogVisible: false,
|
|
|
@@ -20,7 +20,7 @@ export default {
|
|
|
uploadProgress: 0,
|
|
|
submitting: false,
|
|
|
userLoading: false,
|
|
|
-
|
|
|
+ defaultId: "",
|
|
|
// 表单数据
|
|
|
form: {
|
|
|
id: null,
|
|
|
@@ -72,6 +72,9 @@ export default {
|
|
|
{required: true, message: '请输入客服昵称', trigger: 'blur'},
|
|
|
{min: 2, max: 20, message: '长度在2到20个字符', trigger: 'blur'}
|
|
|
],
|
|
|
+ userId: [
|
|
|
+ {required: true, message: '请选择后线人员', trigger: 'change'},
|
|
|
+ ],
|
|
|
departmentId: [
|
|
|
{required: true, message: '请选择部门', trigger: 'change'}
|
|
|
],
|
|
|
@@ -82,6 +85,7 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
created() {
|
|
|
+ this.uploadDefaultImage()
|
|
|
this.queryPage();
|
|
|
},
|
|
|
methods: {
|
|
|
@@ -167,15 +171,15 @@ export default {
|
|
|
this.dialogVisible = true
|
|
|
this.resetForm()
|
|
|
this.loadDepartment();
|
|
|
- this.pageResult()
|
|
|
+ this.loadBackendOptions();
|
|
|
},
|
|
|
// 打开弹窗(编辑)
|
|
|
handleEdit({row}) {
|
|
|
- console.log(row)
|
|
|
this.dialogType = 'edit'
|
|
|
this.dialogVisible = true
|
|
|
this.$nextTick(() => {
|
|
|
this.loadEditData(row)
|
|
|
+ this.loadBackendOptions();
|
|
|
})
|
|
|
},
|
|
|
imgFormatter(row) {
|
|
|
@@ -208,10 +212,10 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
// 加载后线人员选项
|
|
|
- async loadBackendOptions() {
|
|
|
- if (this.backendOptions.length) return
|
|
|
- const {data} = await this.$api.user.findHxUserList()
|
|
|
- this.backendOptions = data
|
|
|
+ loadBackendOptions() {
|
|
|
+ this.$api.user.findHxUserList().then((res) => {
|
|
|
+ this.backendOptions = res.data
|
|
|
+ })
|
|
|
},
|
|
|
// 部门加载
|
|
|
loadDepartment() {
|
|
|
@@ -262,27 +266,56 @@ export default {
|
|
|
});
|
|
|
return true
|
|
|
},
|
|
|
+ async getLocalImageAsFile(imagePath) {
|
|
|
+ const response = await fetch(imagePath);
|
|
|
+ const blob = await response.blob();
|
|
|
+ return new File([blob], 'default-image.png', {type: blob.type});
|
|
|
+ },
|
|
|
+ //上传默认图片
|
|
|
+ async uploadDefaultImage() {
|
|
|
+ const imagePath = require('@/assets/customerAvatar.png'); // 本地图片路径
|
|
|
+ const file = await this.getLocalImageAsFile(imagePath);
|
|
|
+ const params = new FormData();
|
|
|
+ params.append("multipartFile", file);
|
|
|
+ params.append("type", "avatar");
|
|
|
+ this.$api.letter.uploadFile(params).then((res) => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.defaultId = res.data.id;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
// 表单提交
|
|
|
async handleSubmit() {
|
|
|
- try {
|
|
|
- await this.$refs.formRef.validate()
|
|
|
+ await this.$refs.formRef.validate()
|
|
|
+ if (this.form.avatar == null || this.form.avatar.length === 0) {
|
|
|
+ this.form.avatar = this.defaultId
|
|
|
+ }
|
|
|
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)
|
|
|
+ this.$api.customerManage.addCustomer(this.form).then(res => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.$message.success('操作成功')
|
|
|
+ this.$emit('success')
|
|
|
+ this.dialogVisible = false
|
|
|
+ this.queryPage()
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.msg);
|
|
|
+ }
|
|
|
+ })
|
|
|
} else if (this.dialogType === 'edit') {
|
|
|
- await this.$api.customerManage.reviseCustomer(this.form.id, this.form)
|
|
|
+ this.$api.customerManage.reviseCustomer(this.form.id, this.form).then(res => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.$message.success('操作成功')
|
|
|
+ this.$emit('success')
|
|
|
+ this.dialogVisible = false
|
|
|
+ this.queryPage()
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.msg);
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
- this.queryPage()
|
|
|
- this.$emit('success')
|
|
|
- this.dialogVisible = false
|
|
|
- this.$message.success('操作成功')
|
|
|
- } catch (error) {
|
|
|
- console.error(error)
|
|
|
- } finally {
|
|
|
this.submitting = false
|
|
|
- this.imageUrl = ""
|
|
|
- }
|
|
|
},
|
|
|
// 重置表单
|
|
|
resetForm() {
|
|
|
@@ -321,10 +354,11 @@ export default {
|
|
|
this.allServiceList = res.data
|
|
|
})
|
|
|
},
|
|
|
+
|
|
|
// 获取详情数据
|
|
|
getDutyConfig(customerId) {
|
|
|
this.$api.customerManage.getDutyConfig(customerId).then(res => {
|
|
|
- this.formData.dutyCustomerId = res.data.dutyCustomerId
|
|
|
+ this.formData.dutyCustomerId = Number(res.data.dutyCustomerId)
|
|
|
res.data.dutyDateTimeList.map(item => {
|
|
|
this.startTime = dayjs(item.startTime).valueOf()
|
|
|
this.endTime = dayjs(item.endTime).valueOf()
|
|
|
@@ -374,25 +408,24 @@ export default {
|
|
|
|
|
|
// 提交逻辑(示例)
|
|
|
this.$api.customerManage.dutyConfig(this.dutyConfigData())
|
|
|
- .then((res) => {
|
|
|
- if (res.code === 200) {
|
|
|
- this.$message.success('保存成功');
|
|
|
- this.dialogVisibleDuty = false;
|
|
|
- this.queryPage()
|
|
|
- } else {
|
|
|
- this.$message.error(res.msg);
|
|
|
- }
|
|
|
+ .then((res) => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.$message.success('保存成功');
|
|
|
+ this.dialogVisibleDuty = false;
|
|
|
this.queryPage()
|
|
|
- })
|
|
|
- .catch(error => {
|
|
|
- this.$message.error(`保存失败: ${error.message}`);
|
|
|
- });
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.msg);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(error => {
|
|
|
+ this.$message.error(`保存失败: ${error.message}`);
|
|
|
+ });
|
|
|
},
|
|
|
|
|
|
// 时间有效性校验
|
|
|
validateTime() {
|
|
|
for (const time of this.formData.dutyDateTimeList) {
|
|
|
- if (new Date(time.start) >= new Date(time.end)) {
|
|
|
+ if (new Date(time.startTime) >= new Date(time.endTime)) {
|
|
|
this.$message.error('结束时间必须晚于开始时间');
|
|
|
return false;
|
|
|
}
|
|
|
@@ -438,39 +471,40 @@ export default {
|
|
|
|
|
|
<!-- 弹窗主体 -->
|
|
|
<el-dialog
|
|
|
- :title="dialogType === 'add' ? '新增客服' : '编辑客服'"
|
|
|
- :visible.sync="dialogVisible"
|
|
|
- width="700px"
|
|
|
- @closed="handleClose">
|
|
|
+ :title="dialogType === 'add' ? '新增客服' : '编辑客服'"
|
|
|
+ :visible.sync="dialogVisible"
|
|
|
+ width="700px"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ @closed="handleClose">
|
|
|
<el-form
|
|
|
- ref="formRef"
|
|
|
- :model="form"
|
|
|
- :rules="rules"
|
|
|
- label-width="100px"
|
|
|
- label-position="right">
|
|
|
+ ref="formRef"
|
|
|
+ :model="form"
|
|
|
+ :rules="rules"
|
|
|
+ label-width="100px"
|
|
|
+ label-position="right">
|
|
|
|
|
|
<!-- 客服昵称 -->
|
|
|
<el-form-item label="客服昵称" prop="nickname">
|
|
|
<el-input
|
|
|
- v-model="form.nickname"
|
|
|
- placeholder="请输入2-20个字符"
|
|
|
- clearable
|
|
|
- maxlength="20"/>
|
|
|
+ v-model.trim="form.nickname"
|
|
|
+ placeholder="请输入2-20个字符"
|
|
|
+ clearable
|
|
|
+ maxlength="20"/>
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 客服头像 -->
|
|
|
<el-form-item label="客服头像" prop="avatar">
|
|
|
<el-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"
|
|
|
- list-type="picture-card"
|
|
|
- ref="upload1"
|
|
|
+ style="margin-bottom: 10px"
|
|
|
+ class="upload-demo"
|
|
|
+ action="#"
|
|
|
+ :limit="1"
|
|
|
+ accept=".png, .jpg, .jpeg"
|
|
|
+ :auto-upload="false"
|
|
|
+ :on-change="imageUpload"
|
|
|
+ :show-file-list="false"
|
|
|
+ list-type="picture-card"
|
|
|
+ ref="upload1"
|
|
|
>
|
|
|
<img v-if="imageUrl" :src="imageUrl" class="avatar" style="width: 148px; height: 148px" alt=""/>
|
|
|
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
|
|
@@ -481,43 +515,42 @@ export default {
|
|
|
<!-- 后线人员 -->
|
|
|
<el-form-item label="后线人员" prop="userId">
|
|
|
<el-select
|
|
|
- v-model="form.userId"
|
|
|
- filterable
|
|
|
- clearable
|
|
|
- placeholder="请选择后线人员"
|
|
|
- @focus="loadBackendOptions">
|
|
|
+ v-model="form.userId"
|
|
|
+ filterable
|
|
|
+ clearable
|
|
|
+ placeholder="请选择后线人员">
|
|
|
<el-option
|
|
|
- v-for="item in backendOptions"
|
|
|
- :key="item.id"
|
|
|
- :label="item.name"
|
|
|
- :value="item.id"/>
|
|
|
+ v-for="item in backendOptions"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"/>
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 企微部门树 -->
|
|
|
<el-form-item label="企微部门" prop="departmentId">
|
|
|
<el-tree
|
|
|
- ref="deptTree"
|
|
|
- :data="departmentTree"
|
|
|
- :props="treeProps"
|
|
|
- node-key="deptId"
|
|
|
- highlight-current
|
|
|
- @node-click="handleDeptClick"/>
|
|
|
+ ref="deptTree"
|
|
|
+ :data="departmentTree"
|
|
|
+ :props="treeProps"
|
|
|
+ node-key="deptId"
|
|
|
+ highlight-current
|
|
|
+ @node-click="handleDeptClick"/>
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 企微用户 -->
|
|
|
<el-form-item label="企微用户" prop="receptionistId">
|
|
|
<el-select
|
|
|
- v-model="form.receptionistId"
|
|
|
- :loading="userLoading"
|
|
|
- filterable
|
|
|
- clearable
|
|
|
- placeholder="请先选择企微用户">
|
|
|
+ v-model="form.receptionistId"
|
|
|
+ :loading="userLoading"
|
|
|
+ filterable
|
|
|
+ clearable
|
|
|
+ placeholder="请先选择企微用户">
|
|
|
<el-option
|
|
|
- v-for="user in wecomUsers"
|
|
|
- :key="user.userId"
|
|
|
- :label="user.name"
|
|
|
- :value="user.userId"/>
|
|
|
+ v-for="user in wecomUsers"
|
|
|
+ :key="user.userId"
|
|
|
+ :label="user.name"
|
|
|
+ :value="user.userId"/>
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
@@ -525,16 +558,16 @@ export default {
|
|
|
<div slot="footer" class="dialog-footer">
|
|
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
|
|
<el-button
|
|
|
- type="primary"
|
|
|
- :loading="submitting"
|
|
|
- @click="handleSubmit">
|
|
|
+ type="primary"
|
|
|
+ :loading="submitting"
|
|
|
+ @click="handleSubmit">
|
|
|
确 定
|
|
|
</el-button>
|
|
|
</div>
|
|
|
</el-dialog>
|
|
|
|
|
|
<!-- 值班客服配置 -->
|
|
|
- <el-dialog :visible.sync="dialogVisibleDuty" title="值班配置">
|
|
|
+ <el-dialog :visible.sync="dialogVisibleDuty" title="值班配置" :close-on-click-modal="false">
|
|
|
<el-form :model="formData" label-width="100px" label-position="right">
|
|
|
<!-- 当前客服(只读) -->
|
|
|
<el-form-item label="当前客服">
|
|
|
@@ -545,10 +578,10 @@ export default {
|
|
|
<el-form-item label="值班客服">
|
|
|
<el-select v-model="formData.dutyCustomerId" placeholder="请选择">
|
|
|
<el-option
|
|
|
- v-for="item in allServiceList"
|
|
|
- :key="item.id"
|
|
|
- :label="item.nickname"
|
|
|
- :value="item.id">
|
|
|
+ v-for="item in allServiceList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.nickname"
|
|
|
+ :value="item.id">
|
|
|
</el-option>
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
@@ -556,33 +589,33 @@ export default {
|
|
|
<!-- 值班时间列表 -->
|
|
|
<el-form-item label="值班时间" v-for="(time, index) in formData.dutyDateTimeList" :key="index">
|
|
|
<el-date-picker
|
|
|
- v-model="time.startTime"
|
|
|
- type="datetime"
|
|
|
- format="yyyy-MM-dd HH:mm:ss"
|
|
|
- placeholder="开始时间">
|
|
|
+ v-model="time.startTime"
|
|
|
+ type="datetime"
|
|
|
+ format="yyyy-MM-dd HH:mm:ss"
|
|
|
+ placeholder="开始时间">
|
|
|
</el-date-picker>
|
|
|
<span>至</span>
|
|
|
<el-date-picker
|
|
|
- v-model="time.endTime"
|
|
|
- type="datetime"
|
|
|
- format="yyyy-MM-dd HH:mm:ss"
|
|
|
- placeholder="结束时间">
|
|
|
+ v-model="time.endTime"
|
|
|
+ type="datetime"
|
|
|
+ format="yyyy-MM-dd HH:mm:ss"
|
|
|
+ placeholder="结束时间">
|
|
|
</el-date-picker>
|
|
|
<!-- 删除按钮(首行隐藏) -->
|
|
|
<el-button
|
|
|
- v-if="index !== 0"
|
|
|
- @click="removeTime(index)"
|
|
|
- icon="el-icon-close"
|
|
|
- circle>
|
|
|
+ v-if="index !== 0"
|
|
|
+ @click="removeTime(index)"
|
|
|
+ icon="el-icon-close"
|
|
|
+ circle>
|
|
|
</el-button>
|
|
|
</el-form-item>
|
|
|
|
|
|
<!-- 添加按钮(动态隐藏) -->
|
|
|
<el-button
|
|
|
- v-if="showAddButton"
|
|
|
- @click="addTime"
|
|
|
- type="text"
|
|
|
- icon="el-icon-plus">
|
|
|
+ v-if="showAddButton"
|
|
|
+ @click="addTime"
|
|
|
+ type="text"
|
|
|
+ icon="el-icon-plus">
|
|
|
添加值班时间
|
|
|
</el-button>
|
|
|
</el-form>
|