const ADMIN = ['admin', 'owner']; export function canHr(roles: string[]) { return [...ADMIN, 'hr', 'biz_director'].some((r) => roles.includes(r)); } export function canConfirmPay(roles: string[]) { return [...ADMIN, 'hr', 'biz_director'].some((r) => roles.includes(r)); } export function canApproveFin(roles: string[]) { return [...ADMIN, 'finance', 'biz_director'].some((r) => roles.includes(r)); } const ACTIONS = new Set(['view', 'create', 'edit', 'delete', 'approve']); /** 菜单下的具体操作。还没配操作项时,有该菜单就视为能做。 */ export function canDo( permissions: string[], roles: string[], menuCode: string, action: 'view' | 'create' | 'edit' | 'delete' | 'approve', ) { if (ADMIN.some((r) => roles.includes(r))) return true; if (permissions.includes(`${menuCode}:${action}`)) return true; const hasActions = permissions.some((p) => { const tail = p.slice(menuCode.length + 1); return p.startsWith(`${menuCode}:`) && ACTIONS.has(tail); }); if (hasActions) return false; return permissions.includes(menuCode) || permissions.some((p) => p.startsWith(`${menuCode}:`)); }