立项配置页初步优化

This commit is contained in:
Cheng Zhou
2026-02-24 16:53:22 +08:00
parent 0693f09b1d
commit 8f3f717e48
124 changed files with 12519 additions and 2954 deletions
+75 -13
View File
@@ -17,6 +17,7 @@ import AdminSites from "../views/admin/Sites.vue";
import ProjectDetail from "../views/admin/ProjectDetail.vue";
import ProfileSettings from "../views/ProfileSettings.vue";
import ProjectOverview from "../views/ia/ProjectOverview.vue";
import ProjectMilestones from "../views/ia/ProjectMilestones.vue";
import FinanceContracts from "../views/ia/FinanceContracts.vue";
import FinanceSpecial from "../views/ia/FinanceSpecial.vue";
import FeeContracts from "../views/fees/ContractFees.vue";
@@ -26,14 +27,19 @@ import FeeSpecials from "../views/fees/SpecialExpenses.vue";
import FeeSpecialForm from "../views/fees/SpecialExpenseForm.vue";
import FeeSpecialDetail from "../views/fees/SpecialExpenseDetail.vue";
import DrugShipments from "../views/ia/DrugShipments.vue";
import MaterialEquipment from "../views/ia/MaterialEquipment.vue";
import MaterialOthers from "../views/ia/MaterialOthers.vue";
import FileVersionManagement from "../views/ia/FileVersionManagement.vue";
import DocumentList from "../views/documents/DocumentList.vue";
import DocumentDetail from "../views/documents/DocumentDetail.vue";
import StartupFeasibilityEthics from "../views/ia/StartupFeasibilityEthics.vue";
import StartupMeetingAuth from "../views/ia/StartupMeetingAuth.vue";
import SubjectManagement from "../views/ia/SubjectManagement.vue";
import MonitoringPlaceholder from "../views/ia/MonitoringPlaceholder.vue";
import AuditPlaceholder from "../views/ia/AuditPlaceholder.vue";
import RiskIssueSae from "../views/ia/RiskIssueSae.vue";
import RiskIssuePd from "../views/ia/RiskIssuePd.vue";
import RiskIssueMonitoringVisits from "../views/ia/RiskIssueMonitoringVisits.vue";
import MonitoringAuditPlaceholder from "../views/ia/MonitoringAuditPlaceholder.vue";
import EtmfPlaceholder from "../views/ia/EtmfPlaceholder.vue";
import KnowledgeMedicalConsult from "../views/ia/KnowledgeMedicalConsult.vue";
import KnowledgeNotes from "../views/ia/KnowledgeNotes.vue";
import KnowledgeSupportFiles from "../views/ia/KnowledgeSupportFiles.vue";
@@ -100,6 +106,12 @@ const routes: RouteRecordRaw[] = [
component: ProjectOverview,
meta: { title: TEXT.menu.projectOverview, requiresStudy: true },
},
{
path: "project/milestones",
name: "ProjectMilestones",
component: ProjectMilestones,
meta: { title: TEXT.menu.projectMilestones, requiresStudy: true },
},
{
path: "finance/contracts",
name: "FinanceContracts",
@@ -202,6 +214,18 @@ const routes: RouteRecordRaw[] = [
component: DrugShipments,
meta: { title: TEXT.menu.drugShipments, requiresStudy: true },
},
{
path: "materials/equipment",
name: "MaterialEquipment",
component: MaterialEquipment,
meta: { title: TEXT.menu.materialEquipment, requiresStudy: true },
},
{
path: "materials/others",
name: "MaterialOthers",
component: MaterialOthers,
meta: { title: TEXT.menu.materialOthers, requiresStudy: true },
},
{
path: "drug/shipments/new",
name: "DrugShipmentNew",
@@ -346,17 +370,47 @@ const routes: RouteRecordRaw[] = [
component: SubjectForm,
meta: { title: TEXT.common.actions.edit + TEXT.menu.subjects, requiresStudy: true },
},
{
path: "risk-issues",
redirect: "/risk-issues/sae",
},
{
path: "risk-issues/sae",
name: "RiskIssueSae",
component: RiskIssueSae,
meta: { title: TEXT.menu.riskIssueSae, requiresStudy: true },
},
{
path: "risk-issues/pd",
name: "RiskIssuePd",
component: RiskIssuePd,
meta: { title: TEXT.menu.riskIssuePd, requiresStudy: true },
},
{
path: "risk-issues/monitoring-visits",
name: "RiskIssueMonitoringVisits",
component: RiskIssueMonitoringVisits,
meta: { title: TEXT.menu.riskIssueMonitoringVisits, requiresStudy: true },
},
{
path: "monitoring-audit",
name: "MonitoringAuditPlaceholder",
component: MonitoringAuditPlaceholder,
meta: { title: TEXT.menu.monitoringAudit, requiresStudy: true },
},
{
path: "monitoring",
name: "MonitoringPlaceholder",
component: MonitoringPlaceholder,
meta: { title: TEXT.menu.monitoring, requiresStudy: true },
redirect: "/monitoring-audit",
},
{
path: "audit",
name: "AuditPlaceholder",
component: AuditPlaceholder,
meta: { title: TEXT.menu.audit, requiresStudy: true },
redirect: "/monitoring-audit",
},
{
path: "etmf",
name: "EtmfPlaceholder",
component: EtmfPlaceholder,
meta: { title: TEXT.menu.etmf, requiresStudy: true },
},
{
path: "knowledge/medical-consult",
@@ -431,6 +485,12 @@ const routes: RouteRecordRaw[] = [
component: AdminProjects,
meta: { title: TEXT.menu.projectManagement, requiresAdmin: true },
},
{
path: "projects/:projectId",
name: "AdminProjectDetail",
component: ProjectDetail,
meta: { title: TEXT.modules.adminProjects.detailTitle, requiresAdmin: true },
},
{
path: "projects/:projectId/members",
name: "AdminProjectMembers",
@@ -453,9 +513,7 @@ const routes: RouteRecordRaw[] = [
},
{
path: "/projects/:projectId",
name: "ProjectDetail",
component: ProjectDetail,
meta: { title: TEXT.modules.adminProjects.detailTitle, requiresAdmin: true },
redirect: (to) => `/admin/projects/${to.params.projectId}`,
},
];
@@ -468,14 +526,18 @@ router.beforeEach(async (to, _from, next) => {
const auth = useAuthStore();
const studyStore = useStudyStore();
const getToken = () => auth.token;
let token = getToken();
if (!auth.user && getToken()) {
try {
await auth.fetchMe();
} catch {
// 由统一的认证处理流程处理 401/403
// 有 token 但无法获取用户,强制回登录,避免进入“无用户上下文”页面
auth.logout();
next({ path: "/login" });
return;
}
}
const token = getToken();
token = getToken();
const isAdmin = auth.user?.role === "ADMIN";
if (token && !studyStore.currentStudy) {
if (isAdmin) {