Files
Public/apps/web/src/access.ts
T
daiyongkang 76f266645d Initial commit: 风影 OA 全栈源码(API/Web/Flutter/IM)
含 Phase 1.1 IM seq 排序、断线重连、多端已读同步与微信式语音转文字 UI。
排除 node_modules、构建产物、安装包与 .env 密钥。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 10:04:03 +00:00

33 lines
1.1 KiB
TypeScript

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}:`));
}