feat(projects): 工作台小组件设计
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
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
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user