优化前后端权限一致性

This commit is contained in:
Cheng Zhou
2026-05-26 14:53:17 +08:00
parent 41bd423be0
commit c909fc9387
15 changed files with 184 additions and 26 deletions
@@ -127,7 +127,7 @@ const route = useRoute();
const router = useRouter();
const study = useStudyStore();
const { can } = usePermission();
const canWrite = computed(() => can("fees.contract.write"));
const canWrite = computed(() => can("fees.contract.update"));
const contractId = route.params.contractId as string;
const loading = ref(false);
+11 -2
View File
@@ -222,6 +222,7 @@ import StateError from "../../components/StateError.vue";
import StateLoading from "../../components/StateLoading.vue";
import FeeAttachmentPanel from "../../components/fees/FeeAttachmentPanel.vue";
import { TEXT } from "../../locales";
import { isApiPermissionAllowed } from "../../utils/apiPermissionValue";
const route = useRoute();
const router = useRouter();
@@ -238,8 +239,6 @@ const siteActiveMap = computed(() => {
});
return map;
});
const isReadOnly = computed(() => isEdit.value && !!form.center_id && siteActiveMap.value[form.center_id] === false);
const formRef = ref();
const form = reactive({
id: "",
@@ -258,6 +257,12 @@ const paymentErrors = ref<Record<string, string>[]>([]);
const contractId = computed(() => route.params.contractId as string | undefined);
const isEdit = computed(() => !!contractId.value);
const projectRole = computed(() => study.currentStudyRole || (study.currentStudy as any)?.role_in_study || "");
const canMutate = computed(() => {
const operationKey = isEdit.value ? "fees_contracts:update" : "fees_contracts:create";
return isApiPermissionAllowed(study.currentPermissions?.[projectRole.value]?.[operationKey]);
});
const isReadOnly = computed(() => !canMutate.value || (isEdit.value && !!form.center_id && siteActiveMap.value[form.center_id] === false));
const attachmentGroups = [
{
@@ -409,6 +414,10 @@ const validatePayments = () => {
const submit = async () => {
if (!study.currentStudy?.id) return;
if (!canMutate.value) {
ElMessage.warning("权限不足");
return;
}
if (isReadOnly.value) {
ElMessage.warning("中心已停用");
return;
+5 -4
View File
@@ -80,7 +80,7 @@
<el-button @click="resetFilters">{{ TEXT.common.actions.reset }}</el-button>
</div>
<div class="filter-spacer"></div>
<el-button type="primary" :disabled="!canWrite" @click="goNew" class="header-action-btn">
<el-button type="primary" :disabled="!canCreate" @click="goNew" class="header-action-btn">
<el-icon class="el-icon--left"><Plus /></el-icon>
{{ TEXT.modules.feeContracts.newTitle }}
</el-button>
@@ -158,7 +158,7 @@
link
type="danger"
size="small"
:disabled="!canWrite || isInactiveSite(scope.row.center_id)"
:disabled="!canDelete || isInactiveSite(scope.row.center_id)"
@click.stop="remove(scope.row)"
>
{{ TEXT.common.actions.delete }}
@@ -192,7 +192,8 @@ import { TEXT } from "../../locales";
const router = useRouter();
const study = useStudyStore();
const { can } = usePermission();
const canWrite = computed(() => can("fees.contract.write"));
const canCreate = computed(() => can("fees.contract.create"));
const canDelete = computed(() => can("fees.contract.delete"));
const loading = ref(false);
const errorMessage = ref("");
@@ -295,7 +296,7 @@ const onRowClick = (row: any) => {
};
const remove = async (row: any) => {
if (!row?.id || !canWrite.value) return;
if (!row?.id || !canDelete.value) return;
if (isInactiveSite(row?.center_id)) {
ElMessage.warning("中心已停用");
return;