fix(web): 修复角色测试发现的权限守卫、API 500、权限配置问题
1. CRITICAL: 前端路由权限守卫 — routePermissions 从 3 条扩展到 31 条, 覆盖全部 /health/* 路由;匹配逻辑从宽松模块级前缀改为精确权限码匹配 2. HIGH: health-data API 500 — jsonb_array_elements() 添加 CASE WHEN 类型守卫, 防止 items 字段为非数组 JSON 时崩溃 3. MEDIUM: Doctor 补充 ai.prompt.list、ai.usage.list、follow-up-templates 权限 4. Operator 清理 AI 分析、统计报表菜单关联 5. 更新 5 角色测试计划文档
This commit is contained in:
@@ -96,11 +96,39 @@ function PrivateRoute({ children }: { children: React.ReactNode }) {
|
||||
'/users': ['user.list', 'user.manage'],
|
||||
'/roles': ['role.list', 'role.manage'],
|
||||
'/organizations': ['organization.list', 'organization.manage'],
|
||||
'/workflow': ['workflow.list', 'workflow.read'],
|
||||
'/messages': ['message.list'],
|
||||
'/settings': ['config.settings.list', 'config.settings.manage'],
|
||||
'/plugins/admin': ['plugin.list', 'plugin.manage'],
|
||||
'/health/patients': ['health.patient.list', 'health.patient.manage'],
|
||||
'/health/doctors': ['health.doctor.list', 'health.doctor.manage'],
|
||||
'/health/follow-up-tasks': ['health.follow-up.list', 'health.follow-up.manage'],
|
||||
'/health/consultations': ['health.consultation.list', 'health.consultation.manage'],
|
||||
'/health/action-inbox': ['health.action-inbox.list', 'health.action-inbox.manage'],
|
||||
'/health/follow-up-templates': ['health.follow-up-templates.list', 'health.follow-up-templates.manage'],
|
||||
'/health/diagnoses': ['health.health-data.list', 'health.health-data.manage'],
|
||||
'/health/consents': ['health.consent.list', 'health.consent.manage'],
|
||||
'/health/realtime-monitor': ['health.device-readings.list', 'health.device-readings.manage'],
|
||||
'/health/alert-dashboard': ['health.alerts.list', 'health.alerts.manage'],
|
||||
'/health/devices': ['health.devices.list', 'health.devices.manage'],
|
||||
'/health/ble-gateways': ['health.ble-gateways.list', 'health.ble-gateways.manage'],
|
||||
'/health/critical-value-thresholds': ['health.critical-value-thresholds.list', 'health.critical-value-thresholds.manage'],
|
||||
'/health/articles': ['health.articles.list', 'health.articles.manage'],
|
||||
'/health/points-rules': ['health.points.list', 'health.points.manage'],
|
||||
'/health/points-products': ['health.points.list', 'health.points.manage'],
|
||||
'/health/points-orders': ['health.points.list', 'health.points.manage'],
|
||||
'/health/offline-events': ['health.points.list', 'health.points.manage'],
|
||||
'/health/ai-prompts': ['ai.prompt.list', 'ai.prompt.manage'],
|
||||
'/health/ai-analysis': ['ai.analysis.list', 'ai.analysis.manage'],
|
||||
'/health/ai-usage': ['ai.usage.list'],
|
||||
'/health/oauth-clients': ['health.oauth.list', 'health.oauth.manage'],
|
||||
'/health/statistics': ['health.health-data.list', 'health.dashboard.manage'],
|
||||
'/health/tags': ['health.patient.list', 'health.patient.manage'],
|
||||
};
|
||||
const matchedPrefix = Object.keys(routePermissions).find((prefix) => path.startsWith(prefix));
|
||||
if (matchedPrefix) {
|
||||
const required = routePermissions[matchedPrefix];
|
||||
const hasAccess = permissions.some((p) => required.some((r) => p === r || p.startsWith(r.split('.')[0] + '.')));
|
||||
const hasAccess = required.some((r) => permissions.includes(r));
|
||||
if (!hasAccess) return <Navigate to="/" replace />;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user