import { pinyin } from 'pinyin-pro'; // ---- 类型 ---- export interface PermGroup { modelName: string; apiPerms: API.PermItem[]; dataPerms: API.PermItem[]; fieldPerms: API.PermItem[]; } // ---- 排序 ---- export const sortPerms = (perms: API.PermItem[]): API.PermItem[] => [...perms].sort((a, b) => { const partsA = a.code.split(':'); const partsB = b.code.split(':'); const modelA = partsA[1] ?? ''; const modelB = partsB[1] ?? ''; if (modelA !== modelB) return modelA.localeCompare(modelB); const isFieldA = partsA.length === 4; const isFieldB = partsB.length === 4; if (isFieldA !== isFieldB) return isFieldA ? 1 : -1; return a.code.localeCompare(b.code); }); // ---- 分组 ---- export const groupPerms = (perms: API.PermItem[]): PermGroup[] => { const map = new Map(); for (const p of perms) { const parts = p.code.split(':'); const type = parts[0]; const model = parts[1] ?? 'unknown'; if (!map.has(model)) { map.set(model, { modelName: model, apiPerms: [], dataPerms: [], fieldPerms: [] }); } const g = map.get(model)!; if (type === 'api') { g.apiPerms.push(p); } else if (parts.length === 4) { g.fieldPerms.push(p); } else { g.dataPerms.push(p); } } return [...map.values()].sort((a, b) => a.modelName.localeCompare(b.modelName)); }; // ---- 搜索(缓存拼音结果) ---- const pinyinCache = new Map(); const getPermPinyin = (name: string) => { let cached = pinyinCache.get(name); if (!cached) { cached = { full: pinyin(name, { toneType: 'none', type: 'array' }).join('').toLowerCase(), initials: pinyin(name, { pattern: 'first', toneType: 'none', type: 'array' }) .join('') .toLowerCase(), }; pinyinCache.set(name, cached); } return cached; }; export const matchesPerm = (perm: API.PermItem, keyword: string): boolean => { if (!keyword) return true; const k = keyword.toLowerCase(); if (perm.code.toLowerCase().includes(k)) return true; if (perm.name.toLowerCase().includes(k)) return true; const py = getPermPinyin(perm.name); return py.full.includes(k) || py.initials.includes(k); }; // ---- 用户权限 delta 计算 ---- export const calcUserPermDelta = ( checkedIds: number[], roleInheritedIds: number[], ): API.UserPermItem[] => { const checked = new Set(checkedIds); const inherited = new Set(roleInheritedIds); return [ ...checkedIds .filter((id) => !inherited.has(id)) .map((id) => ({ permId: id, effect: 'ALLOW' as const })), ...[...inherited] .filter((id) => !checked.has(id)) .map((id) => ({ permId: id, effect: 'DENY' as const })), ]; }; // ---- pair 查找(Map 预构建,O(1) 查找) ---- export const buildPairMap = (allPerms: API.PermItem[]): Map => { const map = new Map(); for (const p of allPerms) { map.set(p.code, p.id); } return map; }; export const getPairId = (perm: API.PermItem, pairMap: Map): number | undefined => { const parts = perm.code.split(':'); if (parts.length !== 3) return undefined; const [type, model, action] = parts; const pairType = type === 'api' ? 'data' : 'api'; return pairMap.get(`${pairType}:${model}:${action}`); };