fix: 统一上传响应与表单校验处理

- 上传组件统一解析后端响应并暴露错误事件

- AI 资源、模型提供商和工作流表单补齐程序化字段校验同步

- 修正 MinIO 对外访问域名配置
This commit is contained in:
2026-03-24 18:38:42 +08:00
parent 799174406e
commit da536ea742
9 changed files with 201 additions and 46 deletions

View File

@@ -12,6 +12,7 @@ import { api } from '#/api/request';
import DictSelect from '#/components/dict/DictSelect.vue';
import Upload from '#/components/upload/Upload.vue';
import { $t } from '#/locales';
import { syncProgrammaticFieldValidation } from '#/utils/form-validation';
const emit = defineEmits(['reload']);
// vue
@@ -20,50 +21,50 @@ defineExpose({
openDialog,
});
const saveForm = ref<FormInstance>();
const createDefaultEntity = () => ({
categoryId: '',
deptId: '',
fileSize: '',
options: '',
origin: '',
resourceName: '',
resourceType: '',
resourceUrl: '',
status: 0,
suffix: '',
});
// variables
const dialogVisible = ref(false);
const isAdd = ref(true);
const entity = ref<any>({
deptId: '',
resourceType: '',
resourceName: '',
suffix: '',
resourceUrl: '',
origin: '',
status: '',
options: '',
fileSize: '',
});
const entity = ref<any>(createDefaultEntity());
const btnLoading = ref(false);
const rules = ref({
deptId: [
{ required: true, message: $t('message.required'), trigger: 'blur' },
],
resourceType: [
{ required: true, message: $t('message.required'), trigger: 'blur' },
{ required: true, message: $t('message.required'), trigger: 'change' },
],
resourceName: [
{ required: true, message: $t('message.required'), trigger: 'blur' },
],
suffix: [
{ required: true, message: $t('message.required'), trigger: 'blur' },
{
required: true,
message: $t('message.required'),
trigger: ['blur', 'change'],
},
],
resourceUrl: [
{ required: true, message: $t('message.required'), trigger: 'blur' },
{ required: true, message: $t('message.required'), trigger: 'change' },
],
origin: [
{ required: true, message: $t('message.required'), trigger: 'blur' },
],
status: [
{ required: true, message: $t('message.required'), trigger: 'blur' },
{ required: true, message: $t('message.required'), trigger: 'change' },
],
});
// functions
function openDialog(row: any) {
if (row.id) {
isAdd.value = false;
}
entity.value = row;
isAdd.value = !row?.id;
entity.value = {
...createDefaultEntity(),
...row,
status: row?.status ?? 0,
};
dialogVisible.value = true;
}
function save() {
@@ -92,20 +93,33 @@ function save() {
function closeDialog() {
saveForm.value?.resetFields();
isAdd.value = true;
entity.value = {};
entity.value = createDefaultEntity();
dialogVisible.value = false;
}
function beforeUpload(f: any) {
const fName = f?.name?.split('.')[0];
const fExt = f?.name?.split('.')[1];
const fileName = f?.name || '';
const fileNameParts = fileName.split('.');
const fExt = fileNameParts.length > 1 ? fileNameParts.at(-1) || '' : '';
const fName =
fileNameParts.length > 1 ? fileNameParts.slice(0, -1).join('.') : fileName;
entity.value.resourceType = getResourceType(fExt);
entity.value.resourceName = fName;
entity.value.suffix = fExt;
entity.value.fileSize = f.size;
entity.value.origin = 0;
syncProgrammaticFieldValidation(saveForm, [
'origin',
'resourceName',
'resourceType',
]);
}
function uploadSuccess(res: any) {
entity.value.resourceUrl = res;
syncProgrammaticFieldValidation(saveForm, ['resourceUrl']);
}
function uploadError() {
entity.value.resourceUrl = '';
syncProgrammaticFieldValidation(saveForm, ['resourceUrl']);
}
</script>
@@ -129,7 +143,11 @@ function uploadSuccess(res: any) {
class="easyflow-modal-form easyflow-modal-form--compact"
>
<ElFormItem prop="resourceUrl" :label="$t('aiResource.resourceUrl')">
<Upload @before-upload="beforeUpload" @success="uploadSuccess" />
<Upload
@before-upload="beforeUpload"
@success="uploadSuccess"
@error="uploadError"
/>
</ElFormItem>
<ElFormItem prop="origin" :label="$t('aiResource.origin')">
<DictSelect v-model="entity.origin" dict-code="resourceOriginType" />