优化文档管理与导航体验
1、为文档增加编辑接口和前端编辑抽屉,文档列表与详情页统一按创建、更新、删除权限展示操作。 2、将文档版本上传和分发改为抽屉交互,并在详情页补充版本删除权限检查。 3、增强全局面包屑上下文和详情页标题同步,避免详情页重复或缺失导航信息。 4、按项目权限过滤快捷入口、首页费用指标和 eTMF 新建入口,并补充对应前端测试。
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
:icon="Warning"
|
||||
/>
|
||||
</div>
|
||||
<div class="stats-item">
|
||||
<div v-if="canReadFinanceContracts" class="stats-item">
|
||||
<KpiCard
|
||||
:title="TEXT.modules.projectOverview.kpiFinanceTotal"
|
||||
:value="formatAmount(financeSummary?.total_amount ?? 0)"
|
||||
@@ -116,6 +116,7 @@ import QuickActions from "../components/QuickActions.vue";
|
||||
import { List, Warning, Money } from "@element-plus/icons-vue";
|
||||
import StateEmpty from "../components/StateEmpty.vue";
|
||||
import { getProjectRole, isSystemAdmin } from "../utils/roles";
|
||||
import { isApiPermissionAllowed } from "../utils/apiPermissionValue";
|
||||
import { useRoleTemplateMeta } from "../composables/useRoleTemplateMeta";
|
||||
import { TEXT } from "../locales";
|
||||
import type { NotificationItem } from "../types/notifications";
|
||||
@@ -150,6 +151,12 @@ const projectRole = computed(() => {
|
||||
return getProjectRole(study.currentStudy, study.currentStudyRole);
|
||||
});
|
||||
const roleLabel = computed(() => displayRoleLabel(projectRole.value));
|
||||
const canReadFinanceContracts = computed(() => {
|
||||
if (isSystemAdmin(auth.user)) return true;
|
||||
const role = projectRole.value;
|
||||
if (!role) return false;
|
||||
return isApiPermissionAllowed(study.currentPermissions?.[role]?.["fees_contracts:read"]);
|
||||
});
|
||||
|
||||
const formatAmount = (val: number) => {
|
||||
return new Intl.NumberFormat('zh-CN', { minimumFractionDigits: 2 }).format(val);
|
||||
@@ -160,19 +167,19 @@ const loadData = async () => {
|
||||
if (!studyId) return;
|
||||
|
||||
loading.value.progress = true;
|
||||
loading.value.finance = true;
|
||||
loading.value.finance = canReadFinanceContracts.value;
|
||||
loading.value.overdueAes = true;
|
||||
loading.value.notifications = true;
|
||||
try {
|
||||
const [pRes, fRes, aesRes, nRes] = await Promise.allSettled([
|
||||
fetchProgress(studyId),
|
||||
fetchFinanceSummary(studyId),
|
||||
canReadFinanceContracts.value ? fetchFinanceSummary(studyId) : Promise.resolve(null),
|
||||
fetchOverdueAesCount(studyId),
|
||||
listNotifications(studyId, { limit: 5 }),
|
||||
]);
|
||||
|
||||
if (pRes.status === "fulfilled") progress.value = pRes.value.data;
|
||||
if (fRes.status === "fulfilled") financeSummary.value = fRes.value.data;
|
||||
if (fRes.status === "fulfilled" && fRes.value) financeSummary.value = fRes.value.data;
|
||||
if (aesRes.status === "fulfilled") overdueAes.value = aesRes.value.data?.total ?? 0;
|
||||
if (nRes.status === "fulfilled") notifications.value = nRes.value.data || [];
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user