PA6 补齐权限与审计回归

这个提交包含在:
2026-05-12 08:29:18 +08:00
父节点 aec660a8fe
当前提交 a0dc6fc408
共修改 13 个文件,包含 645 行新增和 42 行删除
+24
查看文件
@@ -155,6 +155,17 @@ const ROLE_PERMISSIONS: Record<string, readonly string[]> = {
admin: ["*"],
};
export const BUSINESS_APPROVAL_PERMISSIONS = [
"expense.approve",
"leave.approve",
"procurement.approve",
"travel.approve",
] as const;
const BUSINESS_APPROVER_ROLE_CODES = ["manager", "ceo", "finance", "finance_mgr", "hr"] as const;
const FINANCE_ROLE_CODES = ["finance", "finance_mgr"] as const;
const FINANCE_PORTAL_PERMISSIONS = ["payment.batch.manage", "risk.review.manage", "expense.finance.pay"] as const;
function rolePermissions(roleCode: string): readonly string[] {
return ROLE_PERMISSIONS[roleCode] ?? [];
}
@@ -183,6 +194,19 @@ export function hasAnyPermission(permissionCodes: string[], candidates: string[]
return candidates.some((candidate) => hasPermission(permissionCodes, candidate));
}
export function hasBusinessApproverRole(roleCodes: string[] | undefined, permissionCodes: string[]) {
const hasBusinessRole = (roleCodes ?? []).some((roleCode) =>
(BUSINESS_APPROVER_ROLE_CODES as readonly string[]).includes(roleCode),
);
return hasBusinessRole && hasAnyPermission(permissionCodes, [...BUSINESS_APPROVAL_PERMISSIONS]);
}
export function hasFinanceRole(roleCodes: string[] | undefined, permissionCodes: string[]) {
const hasRole = (roleCodes ?? []).some((roleCode) => (FINANCE_ROLE_CODES as readonly string[]).includes(roleCode));
return hasRole && hasAnyPermission(permissionCodes, [...FINANCE_PORTAL_PERMISSIONS]);
}
export function isManagerRole(permissionCodes: string[]) {
if (hasPermission(permissionCodes, "*") || hasPermission(permissionCodes, "system.users")) {
return true;