refactor(notification): 优化消息编辑页面用户选择功能

- 移除部门树的搜索框
- 默认展开部门树的所有节点
- 使用 InputTag 组件显示已选用户
- 限制显示的用户数量为 5 个
- 优化用户选择的逻辑,支持全选和单选
-重构代码,提高可维护性和可读性
This commit is contained in:
Kven 2025-02-10 23:58:45 +08:00
parent a9e39fd950
commit f5f436e90e
2 changed files with 44 additions and 122 deletions

View File

@ -33,9 +33,10 @@
]"
>
<a-input-tag
v-model="formData.userIds"
v-model="selectedNames"
placeholder='请选择用戶'
:value=formData.userIds
:max-tag-count="5"
readonly
@click="queryDeptTree"
/>
</a-form-item>
@ -143,27 +144,26 @@
@cancel="deptTreeCancel"
>
<template #title>发送用户</template>
<div style="display: flex;height: 520px">
<div style="display: flex;">
<a-card style="margin-right: 10px;width: 30%">
<a-tree
:data="deptTreeData"
:field-names="{ title: 'name', key: 'id', children: 'children' }"
style="margin-bottom: 8px; max-width: 240px"
@select="handleClickTree"
@check="handleCheckTree"
>
</a-tree>
</a-card>
<a-card style="flex: 1">
<a-button type="primary" style="margin-bottom: 10px" @click="handleCheckAllUsers">全选</a-button>
<a-table
:data="selectedDepartmentMembers"
:data="renderData"
:columns="columns"
style="height: 520px">
>
<template #id="{ record }">
<a-checkbox v-model="selectedIds" :value="record.userId"> </a-checkbox>
<a-checkbox v-model="selectedIds" :value="record.id"> </a-checkbox>
</template>
<template #username="{ record }">
<template #name="{ record }">
{{ record.username }}
</template>
</a-table>
@ -183,7 +183,7 @@
import { CreateRecord } from '@/api/user';
import { FormInstance } from '@arco-design/web-vue/es/form';
import { Message } from '@arco-design/web-vue';
import { useMessageStore } from '@/store';
import { useMessageStore, useUserStore } from '@/store';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { IEditorConfig } from '@wangeditor/editor'
import '@wangeditor/editor/dist/css/style.css'
@ -196,6 +196,7 @@
isCreate: Boolean,
});
//
const userStore = useUserStore();
const deptVisible=ref(false);
const emit = defineEmits(['refresh']);
const modalTitle = computed(() => {
@ -217,6 +218,8 @@
const isFullScreen = ref(false);
const mode = 'default';
const selectedIds= ref<number[]>([]);
const selectedNames= ref<string[]>([]);
const toolbarConfig = { excludeKeys: ['uploadVideo', 'insertImage','insertVideo']}
const columns = computed<any[]>(()=>[
{
@ -230,45 +233,6 @@
},
])
// const fieIds = ref(
// {
// userId:{
// label: '',
// component: 'input',
// type:'text'
// },
// title:{
// label: '',
// component: 'input',
// type:'text'
// },
// remark:{
// label: '',
// component: 'input',
// type:'text'
// },
// sms:{
// label: '',
// component: 'switch',
// type:'switch'
// },
// email:{
// label: '',
// component:'switch',
// type:'switch'
// },
// attachmentIds:{
// label: '',
// component: 'input',
// type:'text'
// },
// richEditor:{
// label: '',
// component: 'input',
// type:'text'
// },
// },
// );
const deptTreeData = ref([
{
id: '1',
@ -301,7 +265,6 @@
]
}
]);
const selectedDepartmentMembers: any = ref([]);
const renderData = ref<any[]>([]);
const messageType = computed(() => [
{
@ -314,8 +277,8 @@
},
]);
//
const getDeptTree = async () => {
const res = await getAllDeptTree(1);
const getDeptTree = async (deptId: number) => {
const res = await getAllDeptTree(deptId || 0);
if (res.status === 200) {
deptTreeData.value = res.data;
}
@ -325,76 +288,26 @@
deptVisible.value = true;
}
// 广
const getSelectedMembers = (treeData: any[], selectedKeys: number[]) => {
const queue:any = [...treeData];
const selectedMembers: any[] = [];
while (queue.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const node = queue.shift()!;
if (selectedKeys.includes(node.id)) {
if (node.members) {
selectedMembers.push(...node.members);
}
}
if (node.children) {
queue.push(...node.children);
}
}
return selectedMembers;
//
const fetchData = async (deptId: number) => {
try {
const res = await userStore.getUserList({
deptId,
});
renderData.value = res.data.records;
console.log(renderData);
} catch (err) {
// you can report use errorHandler or other
}
};
//
const handleClickTree = (id: number[]) => {
// '1'
if (id[0] === 1 && id.length === 1) {
// 广
const allMembers: any[] = [];
const queue:any = [...deptTreeData.value];
while (queue.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const node = queue.shift()!;
if (node.members) {
allMembers.push(...node.members);
const [deptId] = id;
fetchData(deptId);
}
if (node.children) {
queue.push(...node.children);
}
}
selectedDepartmentMembers.value = allMembers;
renderData.value = selectedDepartmentMembers.value;
return;
}
const Members = getSelectedMembers(deptTreeData.value, id);
selectedDepartmentMembers.value = Members;
}
//
const handleCheckTree = (id: number[]) => {
if (id[0] === 1 ) { // '1'
const allKeys: number[] = [];
const traverseTree = (node: any) => {
if (node.members) {
node.members.forEach((member: any) => {
allKeys.push(member.userId);
});
}
if (node.children) {
node.children.forEach((child: any) => {
traverseTree(child);
});
}
};
deptTreeData.value.forEach((node: any) => {
traverseTree(node);
});
selectedIds.value = allKeys;
} else {
const selectedKeys = getSelectedMembers(deptTreeData.value, id);
selectedIds.value = selectedKeys.map(item => item.userId);
}
};
//
const handleClick = () => {
@ -446,18 +359,26 @@
setVisible(false);
};
const getNamesByIds = (ids: number[]) => {
return ids.map(id => renderData.value.find(dept => dept.id === id)?.username).filter(username => username !== undefined) as string[];
};
//
const deptTreeSubmit = () => {
deptVisible.value = false;
formData.value.userIds = selectedIds.value;
selectedNames.value = getNamesByIds(selectedIds.value);
console.log(selectedNames.value);
};
//
const handleCheckAllUsers = () => {
if(selectedIds.value.length ===0 ) {
handleCheckTree([1]);
// renderData id
selectedIds.value = renderData.value.map(user => user.id);
} else {
selectedIds.value = [];
}
};
@ -468,7 +389,7 @@
deptVisible.value = false;
};
onMounted(async () => {
await getDeptTree();
await getDeptTree(0);
});
</script>

View File

@ -1,11 +1,12 @@
<template>
<a-input-search
v-model="searchKey"
placeholder="搜索"
style="margin-bottom: 8px; max-width: 240px"
/>
<!-- <a-input-search-->
<!-- v-model="searchKey"-->
<!-- placeholder="搜索"-->
<!-- style="margin-bottom: 8px; max-width: 240px"-->
<!-- />-->
<a-tree
:data="treeData"
:tree-default-expand-all="true"
:field-names="{
key: 'id',
title: 'name',