立项配置页初步优化
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user