全局中文化
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user