UX-2(操作级权限控制)

This commit is contained in:
Cheng Zhou
2025-12-17 15:11:02 +08:00
parent dd51f56707
commit 9ca30d12f8
29 changed files with 288 additions and 131 deletions
+61 -5
View File
@@ -1,6 +1,62 @@
// 预留权限工具,可在后续基于 role 与项目内角色实现细粒度控制
export const hasPermission = (requiredRoles: string[], userRole?: string): boolean => {
if (!requiredRoles.length) return true;
if (!userRole) return false;
return requiredRoles.includes(userRole);
import { computed } from "vue";
import { useAuthStore } from "../store/auth";
import { useStudyStore } from "../store/study";
const PERMISSIONS: Record<string, string[]> = {
"task.create": ["ADMIN", "PM"],
"task.edit": ["ADMIN", "PM"],
"milestone.create": ["ADMIN", "PM"],
"subject.create": ["ADMIN", "PM", "CRA"],
"subject.enroll": ["ADMIN", "PM", "CRA"],
"subject.complete": ["ADMIN", "PM", "CRA"],
"subject.drop": ["ADMIN", "PM", "CRA"],
"ae.create": ["ADMIN", "PM", "CRA", "PV"],
"ae.close": ["ADMIN", "PM", "PV", "CRA"],
"issue.create": ["ADMIN", "PM", "PV"],
"issue.close": ["ADMIN", "PM", "PV"],
"finance.create": ["ADMIN", "PM", "CRA"],
"finance.approve": ["ADMIN", "PM"],
"finance.pay": ["ADMIN", "PM"],
"imp.transaction": ["ADMIN", "PM", "IMP"],
"faq.edit": ["ADMIN", "PM"],
};
const REASONS: Record<string, string> = {
"task.create": "仅项目负责人可以创建任务",
"task.edit": "仅项目负责人可以编辑任务",
"milestone.create": "仅项目负责人可以维护里程碑",
"subject.enroll": "仅 PM/CRA 可更新受试者状态",
"subject.complete": "仅 PM/CRA 可更新受试者状态",
"subject.drop": "仅 PM/CRA 可更新受试者状态",
"ae.close": "仅 PM/PV/ADMIN 可关闭 AE",
"finance.approve": "审批需要 PM/ADMIN 权限",
"finance.pay": "支付确认需要 PM/ADMIN 权限",
"imp.transaction": "仅 IMP/PM/ADMIN 可操作台账",
"faq.edit": "仅 PM/ADMIN 可维护 FAQ",
};
export const usePermission = () => {
const auth = useAuthStore();
const study = useStudyStore();
const userRole = computed(() => auth.user?.role || null);
const projectRole = computed(() => study.currentStudyRole || (study.currentStudy as any)?.role_in_study || null);
const can = (action: string): boolean => {
if (userRole.value === "ADMIN") return true;
const allowList = PERMISSIONS[action];
if (!allowList) return false;
if (!projectRole.value) return false;
return allowList.includes(projectRole.value);
};
const reason = (action: string): string => {
if (userRole.value === "ADMIN") return "";
return REASONS[action] || "当前角色无权执行该操作";
};
return {
can,
reason,
};
};