全局中文化

This commit is contained in:
Cheng Zhou
2026-01-12 11:14:04 +08:00
parent 9021c7fe2b
commit 1338fa7e2b
103 changed files with 2443 additions and 1533 deletions
+27 -23
View File
@@ -3,8 +3,10 @@
<!-- 头部欢迎区域 -->
<div class="workbench-header">
<div class="header-content">
<h1 class="welcome-title">我的工作台</h1>
<p class="welcome-subtitle">欢迎回来这是基于您的角色 <strong>{{ roleLabel }}</strong> 聚合的待办事项</p>
<h1 class="welcome-title">{{ TEXT.modules.workbench.title }}</h1>
<p class="welcome-subtitle">
{{ TEXT.modules.workbench.subtitle.replace("{role}", roleLabel) }}
</p>
</div>
<div class="header-actions">
<el-tag effect="dark" class="role-badge">{{ roleLabel }}</el-tag>
@@ -14,7 +16,7 @@
<!-- 提示未选择项目 -->
<el-alert
v-if="!currentStudyId"
title="请先在顶部导航选择一个项目,以开启完整的工作台功能。"
:title="TEXT.modules.workbench.selectProject"
type="warning"
show-icon
:closable="false"
@@ -26,19 +28,19 @@
<div class="stats-row">
<div class="stats-col">
<SectionCard
title="今日待办"
:title="TEXT.modules.workbench.todayTitle"
:items="todayList"
:loading="loading"
empty-text="今天暂时没有需要紧急处理的业务事项"
:empty-text="TEXT.modules.workbench.todayEmpty"
@more="goMore(todayMorePath)"
/>
</div>
<div class="stats-col">
<SectionCard
title="已逾期事项"
:title="TEXT.modules.workbench.overdueTitle"
:items="overdueList"
:loading="loading"
empty-text="太棒了目前没有任何逾期待处理的事项"
:empty-text="TEXT.modules.workbench.overdueEmpty"
@more="goMore(overdueMorePath)"
/>
</div>
@@ -48,19 +50,19 @@
<div class="secondary-row">
<div class="action-col">
<SectionCard
title="需要我处理的事项"
:title="TEXT.modules.workbench.actionTitle"
:items="actionList"
:loading="loading"
empty-text="暂无需要您处理的事项"
:empty-text="TEXT.modules.workbench.actionEmpty"
@more="goMore(actionMorePath)"
/>
</div>
<div class="quick-col">
<div class="quick-entry-card">
<div class="entry-header">
<span class="entry-title">快捷入口</span>
<span class="entry-title">{{ TEXT.modules.workbench.quickEntryTitle }}</span>
<el-button type="primary" link @click="goMore('/project/overview')" class="entry-more">
进入项目 <el-icon class="el-icon--right"><Right /></el-icon>
{{ TEXT.modules.workbench.enterProject }} <el-icon class="el-icon--right"><Right /></el-icon>
</el-button>
</div>
<div class="quick-grid">
@@ -98,6 +100,8 @@ import { useStudyStore } from "../../store/study";
import { fetchAes } from "../../api/aes";
import { listFinanceContracts } from "../../api/financeContracts";
import { Right, Timer, UserFilled, Warning, Money, Collection } from "@element-plus/icons-vue";
import { displayEnum } from "../../utils/display";
import { TEXT } from "../../locales";
interface WorkItem {
title: string;
@@ -121,8 +125,8 @@ const actionList = ref<WorkItem[]>([]);
const currentStudyId = computed(() => study.currentStudy?.id || "");
const todayStr = computed(() => new Date().toISOString().slice(0, 10));
const roleLabel = computed(() => auth.user?.role || "-");
const emptyText = "暂无需要你处理的事项";
const roleLabel = computed(() => displayEnum(TEXT.enums.userRole, auth.user?.role));
const emptyText = TEXT.modules.workbench.quickEmpty;
const showPersonalTodo = computed(() => role.value !== "ADMIN");
const todoStorageKey = computed(() => `workbench_todos_${auth.user?.id || "guest"}`);
@@ -131,17 +135,17 @@ const quickActions = computed(() => {
if (!currentStudyId.value) return [];
if (role.value === "CRA")
return [
{ label: "立项与伦理", path: "/startup/feasibility-ethics", icon: Timer },
{ label: "AE 列表", path: "/subjects", icon: Warning },
{ label: TEXT.modules.workbench.feasibilityEthics, path: "/startup/feasibility-ethics", icon: Timer },
{ label: TEXT.modules.workbench.aeList, path: "/subjects", icon: Warning },
];
if (role.value === "PM")
return [
{ label: "立项与伦理", path: "/startup/feasibility-ethics", icon: Timer },
{ label: "合同费用", path: "/finance/contracts", icon: Money },
{ label: "医学咨询", path: "/knowledge/medical-consult", icon: Collection },
{ label: TEXT.modules.workbench.feasibilityEthics, path: "/startup/feasibility-ethics", icon: Timer },
{ label: TEXT.modules.workbench.contractList, path: "/finance/contracts", icon: Money },
{ label: TEXT.modules.workbench.medicalConsult, path: "/knowledge/medical-consult", icon: Collection },
];
if (role.value === "PV") return [{ label: "AE 列表", path: "/subjects", icon: Warning }];
return [{ label: "立项与伦理", path: "/startup/feasibility-ethics", icon: Timer }];
if (role.value === "PV") return [{ label: TEXT.modules.workbench.aeList, path: "/subjects", icon: Warning }];
return [{ label: TEXT.modules.workbench.feasibilityEthics, path: "/startup/feasibility-ethics", icon: Timer }];
});
const todayMorePath = computed(() => "/subjects");
@@ -157,7 +161,7 @@ const isOverdue = (d?: string | null) => {
};
const toAeItem = (ae: any): WorkItem => ({
title: ae.term || "不良事件",
title: ae.term || TEXT.modules.workbench.aeTitleFallback,
subtitle: study.currentStudy?.name || "",
status: ae.status,
overdue: isOverdue(ae.expected_resolution_date || ae.updated_at),
@@ -165,7 +169,7 @@ const toAeItem = (ae: any): WorkItem => ({
});
const toContractItem = (fi: any): WorkItem => ({
title: fi.contract_no || "合同费用",
title: fi.contract_no || TEXT.modules.workbench.contractTitleFallback,
subtitle: study.currentStudy?.name || "",
status: fi.site_name,
overdue: false,
@@ -186,7 +190,7 @@ const loadData = async () => {
buildSections(aes, finances);
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || "工作台数据加载失败");
ElMessage.error(e?.response?.data?.message || TEXT.modules.workbench.loadFailed);
} finally {
loading.value = false;
}