PA6 补齐权限与审计回归

这个提交包含在:
2026-05-12 08:29:18 +08:00
父节点 aec660a8fe
当前提交 a0dc6fc408
共修改 13 个文件,包含 645 行新增和 42 行删除
@@ -2,7 +2,7 @@ import { NavLink } from "react-router-dom";
import { useQuery } from "@tanstack/react-query";
import { fetchSystemNavigation, type NavigationItem } from "../../api/workspace";
import { useAuth } from "../../auth/AuthContext";
import { hasAnyPermission } from "../../auth/permissions";
import { hasAnyPermission, hasBusinessApproverRole, hasFinanceRole } from "../../auth/permissions";
import {
ADMIN_NAV_ORDER,
BACKUP_NAV_ORDER,
@@ -32,7 +32,7 @@ export const NAV_ITEMS: NavItem[] = [
{ to: "/people", label: "人员管理", icon: "group", anyOf: ["system.users", "report.dashboard.view"] },
{ to: "/organization", label: "组织架构", icon: "account_tree", anyOf: ["system.users", "report.dashboard.view"] },
{ to: "/system/workflow-definitions", label: "流程定义", icon: "schema", anyOf: ["system.settings"] },
{ to: "/system/settings", label: "系统设置", icon: "settings", anyOf: ["system.settings", "system.users", "masterdata.view", "masterdata.manage", "notification.channel.manage", "integration.manage"] },
{ to: "/system/settings", label: "系统设置", icon: "settings", anyOf: ["system.settings", "system.users", "masterdata.manage", "notification.channel.manage", "integration.manage"] },
{ to: "/system/feature-flags", label: "功能开关", icon: "toggle_on", anyOf: ["system.settings"] },
{ to: "/audit-logs", label: "审计日志", icon: "manage_search", anyOf: ["system.audit.view"] },
{ to: "/workflow/tasks", label: "审批待办", icon: "fact_check", anyOf: ["expense.approve", "leave.approve", "procurement.approve", "travel.approve"] },
@@ -136,9 +136,12 @@ function renderBackupSection(items: ResolvedNavItem[], onNavigate?: () => void)
);
}
function buildFallbackItems(permissions: string[]) {
function buildFallbackItems(permissions: string[], roleCodes: string[]) {
const financeOnlyPaths = new Set(["/payment-batches", "/ap-operations", "/invoice-pool"]);
const mapItems = (paths: string[]) =>
NAV_ITEMS.filter((item) => paths.includes(item.to))
.filter((item) => item.to !== "/workflow/tasks" || hasBusinessApproverRole(roleCodes, permissions))
.filter((item) => !financeOnlyPaths.has(item.to) || hasFinanceRole(roleCodes, permissions))
.filter((item) => !item.anyOf || hasAnyPermission(permissions, item.anyOf))
.map((item) => ({ key: item.to, href: item.to, label: item.label, icon: item.icon }));
@@ -184,7 +187,7 @@ function normalizeSections(sections: { main: NavigationItem[]; admin: Navigation
}
export function NavLinks({ onNavigate }: { onNavigate?: () => void }) {
const { permissions } = useAuth();
const { me, permissions } = useAuth();
const navigationQuery = useQuery({
queryKey: ["system-navigation"],
queryFn: fetchSystemNavigation,
@@ -193,7 +196,7 @@ export function NavLinks({ onNavigate }: { onNavigate?: () => void }) {
const sections = navigationQuery.data?.sections
? normalizeSections(navigationQuery.data.sections)
: buildFallbackItems(permissions);
: buildFallbackItems(permissions, me?.roleCodes ?? []);
return (
<nav className="space-y-5">