统一业务页面权限与抽屉编辑
1、将 FAQ 分类和问题维护改为抽屉交互,并按分类、问题、回复的细粒度权限控制入口。 2、将注意事项、可行性和伦理记录接入详情页抽屉编辑,创建时支持先保存主记录再上传附件。 3、将参与者基础信息编辑改为抽屉,详情页按可读权限显示病史、访视、AE 和 PD 标签页。 4、补充业务页面权限一致性测试,覆盖停用中心、无权限入口和面包屑上下文。
This commit is contained in:
@@ -207,7 +207,8 @@
|
||||
v-model="formDialogVisible"
|
||||
direction="rtl"
|
||||
size="580px"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-click-modal="true"
|
||||
:before-close="formDirtyGuard.beforeClose"
|
||||
:show-close="false"
|
||||
class="issue-editor-drawer"
|
||||
>
|
||||
@@ -411,7 +412,7 @@
|
||||
<template #footer>
|
||||
<div class="editor-footer">
|
||||
<el-button @click="formDialogVisible = false">{{ TEXT.common.actions.cancel }}</el-button>
|
||||
<el-button type="primary" :loading="saving" :disabled="!canSaveIssue" @click="submitForm">{{ TEXT.common.actions.save }}</el-button>
|
||||
<el-button v-if="canSaveIssue" type="primary" :loading="saving" @click="submitForm">{{ TEXT.common.actions.save }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
@@ -474,6 +475,7 @@ import type { Site } from "../../types/api";
|
||||
import { isApiPermissionAllowed } from "../../utils/apiPermissionValue";
|
||||
import { displayDateTime } from "../../utils/display";
|
||||
import { getProjectRole, isSystemAdmin } from "../../utils/roles";
|
||||
import { useDrawerDirtyGuard } from "../../utils/drawerDirtyGuard";
|
||||
|
||||
interface MonitoringIssueRow {
|
||||
id: string;
|
||||
@@ -534,7 +536,7 @@ const canUseApiPermission = (operationKey: string) => {
|
||||
if (!role) return false;
|
||||
return isApiPermissionAllowed(study.currentPermissions?.[role]?.[operationKey]);
|
||||
};
|
||||
const canListIssues = computed(() => canUseApiPermission("monitoring_issues:list"));
|
||||
const canListIssues = computed(() => canUseApiPermission("monitoring_issues:read"));
|
||||
const canReadIssue = computed(() => canUseApiPermission("monitoring_issues:read"));
|
||||
const canCreateIssue = computed(() => canUseApiPermission("monitoring_issues:create"));
|
||||
const canUpdateIssue = computed(() => canUseApiPermission("monitoring_issues:update"));
|
||||
@@ -605,6 +607,7 @@ const createForm = reactive({
|
||||
closed_date: "",
|
||||
responsible_name: "",
|
||||
});
|
||||
const formDirtyGuard = useDrawerDirtyGuard(() => createForm);
|
||||
|
||||
const createRules: FormRules = {
|
||||
source: [{ required: true, message: "请选择问题来源", trigger: "change" }],
|
||||
@@ -831,6 +834,7 @@ const openCreateDialog = () => {
|
||||
resetCreateForm();
|
||||
formMode.value = "create";
|
||||
editingIssueId.value = "";
|
||||
formDirtyGuard.syncBaseline();
|
||||
formDialogVisible.value = true;
|
||||
};
|
||||
|
||||
@@ -843,6 +847,7 @@ const openEditDialog = async (row: MonitoringIssueRow) => {
|
||||
formMode.value = "edit";
|
||||
editingIssueId.value = row.id;
|
||||
fillFormFromIssue(issue);
|
||||
formDirtyGuard.syncBaseline();
|
||||
formDialogVisible.value = true;
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e?.response?.data?.detail || TEXT.common.messages.loadFailed);
|
||||
@@ -863,7 +868,11 @@ const openViewDialog = async (row: MonitoringIssueRow) => {
|
||||
|
||||
const submitForm = async () => {
|
||||
const studyId = study.currentStudy?.id;
|
||||
if (!studyId || !canSaveIssue.value) return;
|
||||
if (!studyId) return;
|
||||
if (!canSaveIssue.value) {
|
||||
ElMessage.warning("权限不足");
|
||||
return;
|
||||
}
|
||||
const ok = await createFormRef.value?.validate().catch(() => false);
|
||||
if (!ok) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user