统一项目角色展示与预设文案

This commit is contained in:
Cheng Zhou
2026-05-26 14:46:01 +08:00
parent 3c168565ce
commit 41bd423be0
25 changed files with 384 additions and 122 deletions
@@ -0,0 +1,74 @@
import { computed, ref } from "vue";
import { fetchPermissionTemplates, type PermissionTemplate } from "@/api/projectPermissions";
const FALLBACK_ROLE_META: Record<string, { label: string; icon: string; desc: string }> = {
ADMIN: { label: "管理员", icon: "🛡️", desc: "系统管理员" },
PM: { label: "PM", icon: "👑", desc: "项目负责人,统筹项目全局,协调进度、资源与关键决策。" },
CRA: { label: "CRA", icon: "📋", desc: "负责各中心临床监查执行,跟进现场质量、数据和问题闭环。" },
PV: { label: "PV", icon: "🔍", desc: "负责药物警戒相关工作,跟踪安全性事件并支持风险评估。" },
MEDICAL_REVIEW: { label: "QA", icon: "🏥", desc: "负责医学审核与稽查,关注质量风险、合规性和医学一致性。" },
IMP: { label: "CTA", icon: "📦", desc: "负责合同、药品及相关项目事务管理,保障执行支持与物资协同。" },
};
const templates = ref<PermissionTemplate[]>([]);
const loading = ref(false);
let pendingLoad: Promise<void> | null = null;
export const useRoleTemplateMeta = () => {
const templateByRole = computed(() => {
const result: Record<string, PermissionTemplate> = {};
for (const template of templates.value) {
if (template.category) result[template.category] = template;
}
return result;
});
const roleLabel = (role?: string | null) => {
if (!role) return "";
return templateByRole.value[role]?.name || FALLBACK_ROLE_META[role]?.label || role;
};
const roleDescription = (role?: string | null) => {
if (!role) return "";
return templateByRole.value[role]?.description || FALLBACK_ROLE_META[role]?.desc || "自定义项目角色";
};
const roleIcon = (role?: string | null) => {
if (!role) return "🔧";
return FALLBACK_ROLE_META[role]?.icon || "🔧";
};
const roleOptionsFor = (roles: string[]) =>
roles.map((role) => ({
value: role,
key: role,
label: roleLabel(role),
icon: roleIcon(role),
desc: roleDescription(role),
}));
const loadRoleTemplates = async () => {
if (pendingLoad) return pendingLoad;
loading.value = true;
pendingLoad = fetchPermissionTemplates()
.then((res) => {
templates.value = res.data;
})
.finally(() => {
loading.value = false;
pendingLoad = null;
});
return pendingLoad;
};
return {
templates,
loading,
templateByRole,
roleLabel,
roleDescription,
roleIcon,
roleOptionsFor,
loadRoleTemplates,
};
};