14_穿梭框决定下拉列表
实现效果
需求说明
客服分配设置-客服分组设置
- 接待客服:选择客服为穿梭框样式
- 左侧为系统账号 | 渠道主号下的所有子账号
- 右侧为被分配到该分组的客服
- 个别客服接待上限
- 可多选客服,可选的范围为【接待客服】中右侧列表里的客服
- 点击 “+ 添加” 添加一行数据
- 选项互斥
代码实现
<Form :model="formData">
<FormItem label="接待客服:" prop="ids">
<Transfer
:titles="['所有成员', '接待客服']"
:data="kefuList"
:target-keys="formData.ids"
filterable
@on-change="onKefuTransfer"
></Transfer>
</FormItem>
<FormItem label="个别客服接待上限:">
<div v-for="(item, index) of formData.otherKefuList" :key="index">
<Select v-model="item.kf_id" placeholder="请选择客服" @on-change="getOtherKefuList">
<Option
v-for="(optItem, optIndex) in item.options"
:value="optItem.kf_id"
:key="optIndex"
>{{ optItem.admin_alias }}</Option>
</Select>
<InputNumber :min="1" v-model="item.num" class="mx-5" />
<Icon type="ios-close-circle" :size="22" style="cursor: pointer" color="#ed4014" @click="onRemoveOneOtherKefu(index)" />
</div>
<div style="color: #2c8cf0; cursor: pointer;" @click="onAddOtherKefu">
<Icon type="ios-add-circle" :size="20" />
<span class="px-5">添加</span>
</div>
</FormItem>
</Form>
props: {
kefuList: Array
},
data() {
return {
formData: {
// ...
ids: [],
kefuList: [], // 客服接待
otherKefuList: [], // 个别客服接待 数据列表
optsList: [] // 个别客服接待所有 options 组合的数组
}
}
}
// methods
// 初始化获取表单数据
async getEditInfo(id) {
const { data } = await this.$axios(this.apis.edit, { id });
const { customer_data, other_customer_data } = data;
customer_data.length && (this.formData.ids = customer_data.map(item => item.kf_id));
this.formData.kefuList = customer_data;
this.formData.otherKefuList = other_customer_data;
// 初始化 个别客服接待 列表
this.getOtherKefuList();
}
// 穿梭框数据变化时触发
onKefuTransfer(keys, direction, moveKeys) {
this.formData.ids = keys;
const kefuListFilter = this.kefuList.filter(item => {
return keys.includes(item.key);
});
const kefuList = kefuListFilter.map(item => ({
kf_id: item.key,
admin_alias: item.label
}));
this.formData.kefuList = kefuList; // 更新 kefuList
this.formData.optsList = [kefuList]; // 初始化 optsList
// 更新 个别客服接待 列表
this.getOtherKefuList();
// 处理下拉框列表
if (direction === 'left') {
const otherKefuList = this.formData.otherKefuList;
const removeList = [];
otherKefuList.map((item, index) => {
if (moveKeys.includes(item.kf_id) || item.kf_id === null) {
removeList.push(index);
}
});
removeList.reverse().map(index => this.onRemoveOneOtherKefu(index));
}
}
// 处理 个别客服接待 数据列表 otherKefuList & 所有 options 组合的数组 optsList
getOtherKefuList() {
const { kefuList, otherKefuList } = this.formData;
const list = [kefuList];
// options 需要逐项递减,使用 optsList 存储所有的 options 列表
otherKefuList.forEach((item, index) => {
this.$set(item, 'options', list[index]);
const options = deepClone(list[index]).filter(option => item.kf_id !== option.kf_id);
list.push(options);
})
this.formData.optsList = list;
}
// 移除
onRemoveOneOtherKefu(index) {
this.formData.otherKefuList.splice(index, 1);
this.getOtherKefuList();
}
// 新增
onAddOtherKefu() {
const { optsList, kefuList, otherKefuList } = this.formData;
const len = kefuList.length;
if(len === 0) {
this.$Message.warning('请先选择接待客服');
return;
}
if (kefuList.length === otherKefuList.length) {
this.$Message.warning('接待客服上限设置数已达最大值');
return;
}
const options = deepClone(optsList[optsList.length - 1]);
this.formData.otherKefuList.push({
options,
kf_id: null,
num: 1
});
}
async onSave() {
const data = this.dealParams();
await this.$asyncFun(this.apis.save, { method: 'POST', data });
}
// 处理入参
dealParams() {
const datas = {};
const { num, kefuList, otherKefuList } = this.formData;
// 组内客服接待上限 列表
const list = kefuList.map(item => {
return {
id: item.kf_id,
num
};
});
// 个别客服接待上限 列表
const otherList = otherKefuList.map(item => {
return {
id: item.kf_id,
num: item.num
};
});
// 去重,若重复保留个别客服设置项
const map = new Map();
const concatList = [...otherList, ...list].filter(item => {
return !map.has(item.id) && map.set(item.id, 1);
});
const resArr = concatList
.filter(item => item.id) // 过滤空白数据项
.map(item => {
return `${item.id}_${item.num}`;
});
return datas;
},