100 lines
2.9 KiB
TypeScript
100 lines
2.9 KiB
TypeScript
import { computed, ref } from 'vue';
|
|
import { fetchGetDeptSimpleList } from '@/service/api';
|
|
import { buildMenuTree } from '@/views/system/shared/menu-tree';
|
|
|
|
export type TreeCheckState = 'none' | 'partial' | 'all';
|
|
|
|
export function useDeptSource(
|
|
userOptions: () => Api.SystemManage.UserSimple[],
|
|
selectedIds: () => Set<string>,
|
|
disabledUserIdSet: () => Set<string>
|
|
) {
|
|
const tree = ref<Api.SystemManage.DeptSimple[]>([]);
|
|
const loading = ref(false);
|
|
let loaded = false;
|
|
|
|
async function ensureLoaded() {
|
|
if (loaded) return;
|
|
loading.value = true;
|
|
try {
|
|
const { data } = await fetchGetDeptSimpleList();
|
|
tree.value = data ? buildMenuTree(data) : [];
|
|
loaded = true;
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
}
|
|
|
|
function collectDeptIds(node: Api.SystemManage.DeptSimple): string[] {
|
|
const ids: string[] = [String(node.id)];
|
|
if (node.children) {
|
|
for (const c of node.children) ids.push(...collectDeptIds(c));
|
|
}
|
|
return ids;
|
|
}
|
|
|
|
function getNodeUserIds(node: Api.SystemManage.DeptSimple): string[] {
|
|
const deptIds = new Set(collectDeptIds(node));
|
|
return userOptions()
|
|
.filter(u => u.deptId !== null && u.deptId !== undefined && deptIds.has(String(u.deptId)))
|
|
.map(u => String(u.id));
|
|
}
|
|
|
|
function getNodeCheckState(node: Api.SystemManage.DeptSimple): TreeCheckState {
|
|
const ids = getNodeUserIds(node).filter(id => !disabledUserIdSet().has(id));
|
|
if (!ids.length) return 'none';
|
|
const sel = ids.filter(id => selectedIds().has(id)).length;
|
|
if (sel === 0) return 'none';
|
|
if (sel === ids.length) return 'all';
|
|
return 'partial';
|
|
}
|
|
|
|
function findNode(list: Api.SystemManage.DeptSimple[], key: string): Api.SystemManage.DeptSimple | null {
|
|
for (const n of list) {
|
|
if (String(n.id) === key) return n;
|
|
if (n.children) {
|
|
const r = findNode(n.children, key);
|
|
if (r) return r;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function matchKeyword(node: Api.SystemManage.DeptSimple, kw: string): boolean {
|
|
if (!kw) return true;
|
|
if (node.name.toLowerCase().includes(kw)) return true;
|
|
if (node.children) return node.children.some(c => matchKeyword(c, kw));
|
|
return false;
|
|
}
|
|
|
|
function filterByKeyword(kw: string) {
|
|
const lower = kw.trim().toLowerCase();
|
|
if (!lower) return tree.value;
|
|
return tree.value.filter(n => matchKeyword(n, lower));
|
|
}
|
|
|
|
function getMetaText(node: Api.SystemManage.DeptSimple): string {
|
|
const total = getNodeUserIds(node).length;
|
|
return total > 0 ? `${total} 人` : '';
|
|
}
|
|
|
|
function nodeKey(node: Api.SystemManage.DeptSimple): string {
|
|
return String(node.id);
|
|
}
|
|
|
|
const treeProps = computed(() => ({ children: 'children', label: 'name' }) as const);
|
|
|
|
return {
|
|
tree,
|
|
loading,
|
|
treeProps,
|
|
ensureLoaded,
|
|
getNodeUserIds,
|
|
getNodeCheckState,
|
|
findNode,
|
|
filterByKeyword,
|
|
getMetaText,
|
|
nodeKey
|
|
};
|
|
}
|