fix: 统一上传响应与表单校验处理
- 上传组件统一解析后端响应并暴露错误事件 - AI 资源、模型提供商和工作流表单补齐程序化字段校验同步 - 修正 MinIO 对外访问域名配置
This commit is contained in:
@@ -9,6 +9,7 @@ import {ElForm, ElFormItem, ElIcon, ElInput, ElMessage, ElOption, ElSelect,} fro
|
||||
import {api} from '#/api/request';
|
||||
import UploadAvatar from '#/components/upload/UploadAvatar.vue';
|
||||
import {$t} from '#/locales';
|
||||
import {syncProgrammaticFieldValidation} from '#/utils/form-validation';
|
||||
import ModelProviderBadge from '#/views/ai/model/ModelProviderBadge.vue';
|
||||
import {getProviderPresetByValue, providerPresets,} from '#/views/ai/model/modelUtils/defaultIcon';
|
||||
|
||||
@@ -132,6 +133,14 @@ const applyPreset = (value: string) => {
|
||||
formData.chatPath = preset.options.chatPath || '';
|
||||
formData.embedPath = preset.options.embedPath || '';
|
||||
formData.rerankPath = preset.options.rerankPath || '';
|
||||
syncProgrammaticFieldValidation(formDataRef, [
|
||||
'providerType',
|
||||
'providerName',
|
||||
'endpoint',
|
||||
'chatPath',
|
||||
'embedPath',
|
||||
'rerankPath',
|
||||
]);
|
||||
};
|
||||
|
||||
const save = async () => {
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -12,6 +12,7 @@ import DictSelect from '#/components/dict/DictSelect.vue';
|
||||
// import Cropper from '#/components/upload/Cropper.vue';
|
||||
import UploadAvatar from '#/components/upload/UploadAvatar.vue';
|
||||
import { $t } from '#/locales';
|
||||
import { syncProgrammaticFieldValidation } from '#/utils/form-validation';
|
||||
|
||||
const emit = defineEmits(['reload']);
|
||||
// vue
|
||||
@@ -66,18 +67,18 @@ function openDialog(row: any, importMode = false) {
|
||||
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
|
||||
jsonFile.value = file;
|
||||
uploadFileList.value = [file];
|
||||
saveForm.value?.clearValidate('jsonFile');
|
||||
syncProgrammaticFieldValidation(saveForm, ['jsonFile']);
|
||||
return false;
|
||||
};
|
||||
const handleChange: UploadProps['onChange'] = (file, fileList) => {
|
||||
jsonFile.value = file.raw;
|
||||
uploadFileList.value = fileList.slice(-1);
|
||||
saveForm.value?.clearValidate('jsonFile');
|
||||
syncProgrammaticFieldValidation(saveForm, ['jsonFile']);
|
||||
};
|
||||
const handleRemove: UploadProps['onRemove'] = () => {
|
||||
jsonFile.value = null;
|
||||
uploadFileList.value = [];
|
||||
saveForm.value?.clearValidate('jsonFile');
|
||||
syncProgrammaticFieldValidation(saveForm, ['jsonFile']);
|
||||
};
|
||||
function save() {
|
||||
saveForm.value?.validate((valid) => {
|
||||
|
||||
Reference in New Issue
Block a user