提交 fbb744cc 作者: 施汉文

🌈 style: 客服标签添加

上级 272b2066
......@@ -64,7 +64,7 @@ export default {
},
data() {
return {
show: true,
show: false,
inputValue: "",
defaultCheckedIds: [],
list: [], //默认选中
......@@ -107,7 +107,7 @@ export default {
await this.getRoleLabel();
await this.handleChange();
},
open() {
open(list) {
this.show = true;
},
close() {
......
<template>
<div>
<div class="item rowFlex columnCenter spaceBetween zyouTag">
<div class="rowFlex columnCenter">
<div class="item spaceBetween zyouTag grid grid-cols-12">
<div class="rowFlex col-span-3">
<span class="label">掌游标签:</span>
<i
:class="['el-icon-arrow-' + (showZyouTag ? 'down' : 'right'), 'tag-icon']"
<!-- <i
:class="[
'el-icon-arrow-' + (showZyouTag ? 'down' : 'right'),
'tag-icon',
]"
@click="toggleZyouTag"
></i>
></i> -->
</div>
<div class="space-y-[8px] col-span-9 flex flex-col">
<div
v-for="(item, index) in roleLabelList"
:key="index"
class="self-start flex group"
>
<div
class="px-[6px] rounded-[4px] bg-[#F5F5F5] gap-[4px] flex items-center h-[22px]"
>
<div>{{ tagNmae[item.label_type] }}</div>
<div class="h-[9px] w-[1px] bg-[#D0D1D3]"></div>
<div v-if="item.label.length > 1" class="flex-1 truncate">
{{
`${item.label[0].label_group_name} / ${item.label[0].label_name}`
}}
</div>
<div v-else-if="item.label.length > 0" class="flex-1 truncate">
{{
`${item.label[0].label_group_name} / ${item.label[0].label_name}`
}}
</div>
<div v-else class="flex-1 truncate">--</div>
<el-tooltip
effect="dark"
placement="top"
v-if="item.label.length > 1"
>
<div
slot="content"
class="grid grid-cols-2 gap-[4px] max-w-[200px]"
>
<div
v-for="value in item.label"
class="px-[6px] w-full rounded-[4px] bg-[rgba(255,255,255,0.2)] flex items-center h-[22px] overflow-hidden"
>
<span class="truncate">
{{ `${value.label_group_name} / ${value.label_name}` }}
</span>
</div>
</div>
<el-button type="text" size="small"
>+{{ item.label.length }}
</el-button>
</el-tooltip>
</div>
<iconpark-icon
name="ziliao-tianjia"
class="group-hover:visible invisible text-primary text-[14px] ml-[6px]"
@click="addTag(item.label)"
></iconpark-icon>
</div>
</div>
</div>
<!-- 掌游标签列表 -->
<!-- 掌游标签列表 -->
<div v-if="showZyouTag" class="zyou-tag-list">
<div v-for="(item, index) in roleLabelList" :key="index" class="tag-group">
<div
v-for="(item, index) in roleLabelList"
:key="index"
class="tag-group"
>
<div class="tag-group-header">
<div class="tag-type-name">{{ item.label_type_name }}</div>
<i v-if="item.label_type ==2" class="el-icon-circle-plus" style="color: var(--el-color-primary)" @click="toggleAddTag(index)"></i>
<i
v-if="item.label_type == 2"
class="el-icon-circle-plus"
style="color: var(--el-color-primary)"
@click="toggleAddTag(index)"
></i>
</div>
<!-- 新增标签区域 -->
<div v-if="showAddTagIndex === index" class="add-tag-area">
......@@ -39,8 +106,15 @@
></el-cascader>
<div class="button-group">
<el-button type="text" size="small" @click="handleSelectChange(searchValue)">确定</el-button>
<el-button type="text" size="small" @click="toggleAddTag(-1)">取消</el-button>
<el-button
type="text"
size="small"
@click="handleSelectChange(searchValue)"
>确定</el-button
>
<el-button type="text" size="small" @click="toggleAddTag(-1)"
>取消</el-button
>
</div>
</div>
</div>
......@@ -53,7 +127,7 @@
trigger="click"
@show="getTagCreateInfo(tag.id)"
>
<div style="height: 50px;">
<div style="height: 50px">
<div v-if="tagInfo.create_user" class="tag-info-item">
<span class="tag-info-label">操作人:</span>
<span class="tag-info-value">{{ tagInfo.create_user }}</span>
......@@ -64,253 +138,289 @@
</div>
</div>
<el-tag slot="reference" class="tag-item">
<span v-if="tag.label_group_name">{{ tag.label_group_name || '' }} / </span>
<span>{{ tag.label_name || '' }}</span>
<span v-if="tag.label_group_name"
>{{ tag.label_group_name || "" }} /
</span>
<span>{{ tag.label_name || "" }}</span>
</el-tag>
</el-popover>
</div>
</div>
</div>
<AddTagsDrawer ref="addTagsDrawer" :game-user-info="gameUserInfo" />
</div>
</template>
</template>
<script>
import { editRoleLabel, roleGetRoleLabel, roleLabelSearch, selectSearch, getRoleLabelCreate } from '@/api/game'
import { mapState,mapActions } from 'vuex'
import { debounce } from '@/utils'
export default {
name: 'ZyouTag',
<script>
import {
editRoleLabel,
roleGetRoleLabel,
roleLabelSearch,
selectSearch,
getRoleLabelCreate,
} from "@/api/game";
import { mapState, mapActions } from "vuex";
import { debounce } from "@/utils";
import AddTagsDrawer from "@/views/popup/AddTagsDrawer/index.vue";
export default {
name: "ZyouTag",
components: {
AddTagsDrawer,
},
props: {
accountSelect: {
type: [String, Number],
default: ''
default: "",
},
gameUserInfo: {
type: Object,
default: () => ({})
}
default: () => ({}),
},
},
data() {
return {
tagNmae: {
1: "运营",
2: "客服",
3: "GS",
},
showZyouTag: false, // 控制标签显示隐藏
roleLabelList: [], // 角色标签列表
showAddTagIndex: -1, // 当前显示新增标签的索引
searchValue: '', // 搜索框的值
searchValue: "", // 搜索框的值
searchOptions: [], // 搜索选项
labelTypeList: [], // 标签类型列表
loading: false, // 加载状态
tagInfo: {} // 标签创建信息
}
tagInfo: {}, // 标签创建信息
};
},
computed: {
...mapState('user', ['cser_id','cser_name','corp_id','weixin_blongs_id_list']),
...mapState("user", [
"cser_id",
"cser_name",
"corp_id",
"weixin_blongs_id_list",
]),
},
watch: {
accountSelect: {
handler(newVal) {
if (newVal) {
this.getRoleLabelList()
this.getRoleLabelList();
}
},
immediate: true
}
immediate: true,
},
},
async mounted() {
await this.requestCompanyviewConfig({corp_id:this.corp_id})
this.getLabelType()
this.getRoleLabelList()
this.searchLabel('')
await this.requestCompanyviewConfig({ corp_id: this.corp_id });
this.getLabelType();
this.getRoleLabelList();
this.searchLabel("");
},
methods: {
...mapActions('user', ['requestCompanyviewConfig']),
...mapActions("user", ["requestCompanyviewConfig"]),
// 获取标签类型
async getLabelType() {
try {
const res = await selectSearch({
type: 'label_type'
})
type: "label_type",
});
if (res.status_code === 1) {
console.log('getLabelType')
this.labelTypeList = res.data.data || []
console.log("getLabelType");
this.labelTypeList = res.data.data || [];
}
} catch (error) {
console.error('获取标签类型失败:', error)
console.error("获取标签类型失败:", error);
}
},
getRoleLabelList: debounce(function() {
this.getRoleLabelListFn()
getRoleLabelList: debounce(function () {
this.getRoleLabelListFn();
}, 500),
// 获取角色标签列表
async getRoleLabelListFn() {
console.log('延迟')
if (!this.accountSelect) return
this.loading = true
console.log("延迟");
if (!this.accountSelect) return;
this.loading = true;
try {
const weixin_blongs_id = this.weixin_blongs_id_list.map(item => item.value)
const weixin_blongs_id = this.weixin_blongs_id_list.map(
(item) => item.value
);
const res = await roleGetRoleLabel({
member_id: this.accountSelect,
weixin_blongs_id: weixin_blongs_id
})
weixin_blongs_id: weixin_blongs_id,
});
if (res.status_code === 1 && res.data.data.length > 0) {
const labelData = res.data.data || []
const groupedLabels = {}
labelData.forEach(item => {
const labelData = res.data.data || [];
const groupedLabels = {};
labelData.forEach((item) => {
if (item.label && item.label.length > 0) {
item.label.forEach(label => {
label.label_type = Number(item.label_type)
})
item.label.forEach((label) => {
label.label_type = Number(item.label_type);
});
}
})
});
// 初始化标签组
this.labelTypeList.forEach(type => {
this.labelTypeList.forEach((type) => {
groupedLabels[type.value] = {
label_type: type.value,
label_type_name: type.label,
label: []
}
})
label: [],
};
});
// 分组标签数据
labelData.forEach(item => {
labelData.forEach((item) => {
if (item.label && item.label.length > 0) {
const labelType = item.label[0].label_type
const labelType = item.label[0].label_type;
if (groupedLabels[labelType]) {
groupedLabels[labelType].label = item.label
groupedLabels[labelType].label = item.label;
}
}
})
});
// 转换为数组格式
this.roleLabelList = Object.values(groupedLabels)
console.log(this.roleLabelList, 'roleLabelList')
this.roleLabelList = Object.values(groupedLabels);
console.log(this.roleLabelList, "roleLabelList");
} else {
this.roleLabelList = this.labelTypeList.map(item => {
this.roleLabelList = this.labelTypeList.map((item) => {
return {
label_type: item.value,
label_type_name: item.label,
label: []
}
})
label: [],
};
});
}
} catch (error) {
console.error('获取角色标签列表失败:', error)
console.error("获取角色标签列表失败:", error);
} finally {
this.loading = false
this.loading = false;
}
},
addTag(list) {
this.$refs.addTagsDrawer.open(list);
},
// 搜索标签
async searchLabel(query) {
try {
const weixin_blongs_id = this.weixin_blongs_id_list.map(item => item.value)
const weixin_blongs_id = this.weixin_blongs_id_list.map(
(item) => item.value
);
const res = await roleLabelSearch({
label_name: query.trim() || '',
label_name: query.trim() || "",
weixin_blongs_id: weixin_blongs_id || [],
label_type: 2
})
label_type: 2,
});
if (res.status_code === 1) {
this.searchOptions = res.data.data || []
this.searchOptions = res.data.data || [];
// 找出 label_group_id 相同的 然后 把 children 合并
const groupedItems = this.searchOptions.reduce((acc, curr) => {
const key = curr.label_group_id
const key = curr.label_group_id;
if (!acc[key]) {
acc[key] = {
label_name: curr.label_group_name,
label_id: curr.label_group_id,
select_type: Number(curr.select_type),
children: []
}
children: [],
};
}
// 将标签添加到对应标签组的children中
acc[key].children.push({
label_name: curr.label_name,
label_id: curr.id,
disabled: false // 默认不禁用
})
return acc
}, {})
disabled: false, // 默认不禁用
});
return acc;
}, {});
// 处理单选标签组,为已选中项以外的选项添加disabled属性
Object.values(groupedItems).forEach(group => {
Object.values(groupedItems).forEach((group) => {
if (group.select_type === 1) {
// 如果是单选标签组,需要禁用其他选项
const selectedIds = Array.isArray(this.searchValue) ? this.searchValue : []
const hasSelectedInThisGroup = group.children.some(child =>
const selectedIds = Array.isArray(this.searchValue)
? this.searchValue
: [];
const hasSelectedInThisGroup = group.children.some((child) =>
selectedIds.includes(child.label_id)
)
);
if (hasSelectedInThisGroup) {
group.children.forEach(child => {
group.children.forEach((child) => {
// 如果当前选项不在已选中列表中,则禁用
if (!selectedIds.includes(child.label_id)) {
child.disabled = true
child.disabled = true;
}
})
});
}
}
})
});
this.searchOptions = Object.values(groupedItems)
this.searchOptions = Object.values(groupedItems);
}
} catch (error) {
console.error('搜索标签失败:', error)
console.error("搜索标签失败:", error);
}
},
// 添加标签
async addLabel(selectedLabels) {
console.log(selectedLabels, 'selectedLabels')
const labelId = selectedLabels.map(label => label.label_id)
console.log(selectedLabels, "selectedLabels");
const labelId = selectedLabels.map((label) => label.label_id);
if (!this.accountSelect || !labelId) {
this.$message.error('请选择标签')
return
this.$message.error("请选择标签");
return;
}
if (!this.gameUserInfo || !this.gameUserInfo.role_info || !this.gameUserInfo.role_info.role_id) {
this.$message.error('该账号未创角无法添加标签')
return
if (
!this.gameUserInfo ||
!this.gameUserInfo.role_info ||
!this.gameUserInfo.role_info.role_id
) {
this.$message.error("该账号未创角无法添加标签");
return;
}
try {
const res = await editRoleLabel({
role_id: this.gameUserInfo.role_info.role_id || '',
role_id: this.gameUserInfo.role_info.role_id || "",
member_id: this.accountSelect,
label_id: labelId,
user_id: this.cser_id,
user_name: this.cser_name,
role_name: this.gameUserInfo.role_info.role_name || '',
cp_role_id: this.gameUserInfo.role_info.cp_role_id || ''
})
role_name: this.gameUserInfo.role_info.role_name || "",
cp_role_id: this.gameUserInfo.role_info.cp_role_id || "",
});
if (res.status_code === 1) {
this.$message.success(res.msg)
this.searchValue = ''
this.showAddTagIndex = -1
this.$message.success(res.msg);
this.searchValue = "";
this.showAddTagIndex = -1;
// 暂时隐藏
// this.roleLabelList[1].label.push(...selectedLabels)
// 重置所有标签的禁用状态
this.searchOptions.forEach(group => {
this.searchOptions.forEach((group) => {
if (group.children) {
group.children.forEach(child => {
child.disabled = false
})
group.children.forEach((child) => {
child.disabled = false;
});
}
})
});
// 刷新标签列表
setTimeout(() => {
this.getRoleLabelList()
}, 500)
this.getRoleLabelList();
}, 500);
}
} catch (error) {
console.error('添加标签失败:', error)
console.error("添加标签失败:", error);
}
},
// 切换标签显示
toggleZyouTag() {
this.showZyouTag = !this.showZyouTag
this.showZyouTag = !this.showZyouTag;
},
// 切换新增标签区域显示
toggleAddTag(index) {
this.showAddTagIndex = this.showAddTagIndex === index ? -1 : index
this.showAddTagIndex = this.showAddTagIndex === index ? -1 : index;
if (this.showAddTagIndex === -1) {
this.searchValue = ''
this.searchValue = "";
// this.searchOptions = []
}
},
......@@ -319,101 +429,113 @@
handleSelectChange(value) {
if (value && Array.isArray(value) && value.length > 0) {
// 获取当前标签组的标签
const currentGroupLabels = this.roleLabelList.find(item => Number(item.label_type) === 2).label
const currentGroupLabels = this.roleLabelList.find(
(item) => Number(item.label_type) === 2
).label;
// 获取所有选中标签的信息
const selectedLabels = []
const selectedLabels = [];
// 遍历所有标签组
this.searchOptions.forEach(group => {
this.searchOptions.forEach((group) => {
// 找出该组中被选中的标签
const selectedInGroup = group.children.filter(child =>
const selectedInGroup = group.children.filter((child) =>
value.includes(child.label_id)
)
);
// 如果是单选标签组且选中了多个,只保留第一个
if (group.select_type === 1 && selectedInGroup.length > 1) {
this.$message.warning(`标签组"${group.label_name}"为单选,只能选择一个标签`)
this.$message.warning(
`标签组"${group.label_name}"为单选,只能选择一个标签`
);
// 只添加第一个选中的标签
selectedLabels.push(selectedInGroup[0])
selectedLabels.push(selectedInGroup[0]);
} else {
// 多选标签组或单选标签组只选了一个,全部添加
selectedLabels.push(...selectedInGroup)
selectedLabels.push(...selectedInGroup);
}
})
});
if (!selectedLabels || selectedLabels.length === 0) {
this.$message.warning('请选择有效的标签')
return
this.$message.warning("请选择有效的标签");
return;
}
// 检查selectedLabels中的标签组是否与currentGroupLabels中的标签组重复
if (currentGroupLabels && currentGroupLabels.length > 0) {
const existingGroupIds = currentGroupLabels.map(label => label.label_group_id)
const existingGroupIds = currentGroupLabels.map(
(label) => label.label_group_id
);
const hasConflict = selectedLabels.some(label =>
const hasConflict = selectedLabels.some((label) =>
existingGroupIds.includes(label.label_group_id)
)
);
if (hasConflict) {
this.$message.warning('一标签组下只能选择一个标签')
return
this.$message.warning("一标签组下只能选择一个标签");
return;
}
this.addLabel(selectedLabels)
this.addLabel(selectedLabels);
} else {
this.addLabel(selectedLabels)
this.addLabel(selectedLabels);
}
} else {
this.$message.warning('请选择标签')
this.$message.warning("请选择标签");
}
},
// 处理级联选择器选择变化
handleCascaderChange(value) {
// 每次选择变化时,重新处理searchOptions
// 重置所有选项的disabled状态
this.searchOptions.forEach(group => {
this.searchOptions.forEach((group) => {
if (group.children) {
group.children.forEach(child => {
child.disabled = false
})
group.children.forEach((child) => {
child.disabled = false;
});
}
})
});
if (Array.isArray(value) && value.length > 0) {
// 检查是否有全选操作
const prevValue = [...this.searchValue || []]
const prevValue = [...(this.searchValue || [])];
// 找出所有单选标签组
const singleSelectGroups = this.searchOptions.filter(group => group.select_type === 1)
const singleSelectGroups = this.searchOptions.filter(
(group) => group.select_type === 1
);
// 检查单选标签组是否有全选操作
for (const group of singleSelectGroups) {
// 获取当前组中的所有标签ID
const groupLabelIds = group.children.map(child => child.label_id)
const groupLabelIds = group.children.map((child) => child.label_id);
// 检查当前组中选中的标签数量
const selectedInThisGroup = groupLabelIds.filter(id => value.includes(id))
const selectedInThisGroup = groupLabelIds.filter((id) =>
value.includes(id)
);
// 如果选中的标签数量大于1,说明可能是全选操作
if (selectedInThisGroup.length > 1) {
// 提示用户只能选择一个标签
this.$message.warning(`标签组"${group.label_name}"为单选,只能选择一个标签`)
this.$message.warning(
`标签组"${group.label_name}"为单选,只能选择一个标签`
);
// 清空该组的选择
const newValue = value.filter(id => !groupLabelIds.includes(id))
const newValue = value.filter((id) => !groupLabelIds.includes(id));
// 更新选择值
this.searchValue = newValue
return
this.searchValue = newValue;
return;
}
// 如果该单选标签组有选中的标签,则禁用其他标签
if (selectedInThisGroup.length === 1) {
group.children.forEach(child => {
group.children.forEach((child) => {
if (!value.includes(child.label_id)) {
child.disabled = true
child.disabled = true;
}
})
});
}
// 如果没有选中的标签,则不需要禁用任何标签,已经在前面重置了
}
......@@ -422,27 +544,27 @@
},
// 获取标签创建信息
async getTagCreateInfo(id) {
this.tagInfo = {}
this.tagInfo = {};
try {
const res = await getRoleLabelCreate({
id: id
})
id: id,
});
if (res.status_code === 1) {
this.tagInfo = res.data.data || {}
this.tagInfo = res.data.data || {};
} else {
this.$message.error(res.msg || '获取标签信息失败')
this.$message.error(res.msg || "获取标签信息失败");
}
} catch (error) {
console.error('获取标签创建信息失败:', error)
this.$message.error('获取标签信息失败')
console.error("获取标签创建信息失败:", error);
this.$message.error("获取标签信息失败");
}
}
}
}
</script>
},
},
};
</script>
<style lang="scss" scoped>
.item {
<style lang="scss" scoped>
.item {
width: 100%;
height: auto;
font-size: 14px;
......@@ -465,14 +587,14 @@
color: #333333;
margin-right: 8px;
}
}
.zyou-tag-list {
}
.zyou-tag-list {
.tag-group {
margin-bottom: 10px;
padding: 10px;
padding-top: 0;
width: 100%;
background: #F7F8FA;
background: #f7f8fa;
border-radius: 4px;
&:last-child {
margin-bottom: 0;
......@@ -484,17 +606,17 @@
font-family: PingFangSC, PingFang SC;
font-weight: 400;
text-align: left;
padding-top:10px;
padding-top: 10px;
margin-bottom: 10px;
.tag-type-name {
font-size: 14px;
color: #323335;
font-weight: 500;
}
.el-icon-circle-plus{
.el-icon-circle-plus {
font-size: 16px;
cursor: pointer;
color: #3491FA !important;
color: #3491fa !important;
}
}
.tag-list {
......@@ -503,7 +625,7 @@
color: #323335;
background-color: #fff;
border-radius: 4px;
border: 1px solid #D6D9E0;
border: 1px solid #d6d9e0;
margin-bottom: 5px;
}
}
......@@ -520,20 +642,19 @@
display: flex;
justify-content: flex-end;
}
}
}
}
}
.tag-icon {
}
.tag-icon {
margin-left: 8px;
cursor: pointer;
color: #909399;
&:hover {
color: #409EFF;
color: #409eff;
}
}
.tag-info-item {
}
.tag-info-item {
margin-bottom: 8px;
font-size: 12px;
......@@ -546,5 +667,5 @@
color: #333;
font-weight: 500;
}
}
</style>
\ No newline at end of file
}
</style>
......@@ -300,8 +300,6 @@
</div>
</div>
</div>
<AddTagsDrawer ref="addTagsDrawer" :game-user-info="gameUserInfo" />
</div>
</template>
<script>
......@@ -313,14 +311,13 @@ import moment from "moment";
import ZyouTag from "./ZyouTag.vue";
import { debounce } from "@/utils";
import LastLogin from "@/views/components/quickSendGame/sendGame/lastLogin.vue";
import AddTagsDrawer from "@/views/popup/AddTagsDrawer/index.vue";
export default {
name: "gameUserInfo",
components: {
ZyouTag,
MarketingPanel,
LastLogin,
AddTagsDrawer,
},
props: ["gameUserInfo", "chatUserDetails"],
data() {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论