fix: harden platform form and response boundaries

This commit is contained in:
2026-07-27 12:19:34 +08:00
parent 34e8b092b3
commit cd58e1f6b6
7 changed files with 294 additions and 67 deletions

View File

@@ -32,7 +32,7 @@
<a-drawer :visible="formVisible" :title="editingIdentity ? `编辑${definition.title}` : `新建${definition.title}`" :width="480" @cancel="formVisible = false" @ok="save">
<a-form :model="form" layout="vertical">
<a-form-item v-for="field in definition.fields" :key="field.key" :label="field.label" :required="field.required">
<a-form-item v-for="field in formFields" :key="field.key" :label="field.label" :required="isResourceFieldRequired(field, formMode)">
<a-switch v-if="field.type === 'boolean'" v-model="form[field.key]" />
<a-input-number v-else-if="field.type === 'number'" v-model="form[field.key]" />
<a-date-picker v-else-if="field.type === 'date'" v-model="form[field.key]" value-format="YYYY-MM-DD" />
@@ -69,7 +69,11 @@
import { Message, Modal } from '@arco-design/web-vue';
import { computed, onMounted, reactive, ref } from 'vue';
import { resourceApi } from '@/api/resource';
import { buildResourcePayload, isMissingField } from '@/api/resource-form';
import {
buildResourcePayload,
isMissingField,
isResourceFieldRequired,
} from '@/api/resource-form';
import type { DetailAction, ResourceUiDefinition } from '@/api/resources';
type Row = Record<string, unknown>;
@@ -91,6 +95,14 @@ const actionForm = reactive<Record<string, any>>({});
const canCreate = computed(() => props.definition.mode !== 'readonly');
const canEdit = computed(() => props.definition.mode === 'writable');
const canArchive = computed(() => props.definition.mode === 'writable');
const formMode = computed<'create' | 'edit'>(() =>
editingIdentity.value ? 'edit' : 'create',
);
const formFields = computed(() =>
props.definition.fields.filter(
(field) => formMode.value === 'create' || field.type !== 'password',
),
);
const displayFields = computed(() =>
props.definition.fields.filter((field) => field.key !== 'status'),
);
@@ -190,15 +202,21 @@ async function submitDetailAction() {
async function save() {
if (
props.definition.fields.some(
(field) => field.required && isMissingField(form[field.key]),
formFields.value.some(
(field) =>
isResourceFieldRequired(field, formMode.value) &&
isMissingField(form[field.key]),
)
) {
Message.warning('请填写必填字段');
return;
}
try {
const payload = buildResourcePayload(props.definition.fields, form);
const payload = buildResourcePayload(
props.definition.fields,
form,
formMode.value,
);
if (editingIdentity.value)
await resourceApi.update(
props.definition.resource,