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

@@ -0,0 +1,25 @@
import type { FormInstance, FormItemProp } from 'element-plus';
import type { Ref } from 'vue';
import { nextTick } from 'vue';
type FormRef = Ref<FormInstance | null | undefined>;
export async function syncProgrammaticFieldValidation(
formRef: FormRef,
fields?: Array<FormItemProp>,
) {
await nextTick();
if (!formRef.value) {
return;
}
if (!fields || fields.length === 0) {
formRef.value.clearValidate();
return;
}
formRef.value.clearValidate(fields);
}

View File

@@ -0,0 +1,59 @@
import { $t } from '#/locales';
interface UploadResponseData {
path?: string;
}
interface UploadResponseBody {
data?: UploadResponseData;
errorCode?: number;
message?: string;
}
function getMessageFromUnknown(error: unknown) {
if (typeof error === 'string' && error) {
return error;
}
if (!error || typeof error !== 'object') {
return '';
}
const raw = error as {
message?: unknown;
response?: unknown;
};
if (typeof raw.message === 'string' && raw.message) {
return raw.message;
}
if (typeof raw.response === 'string' && raw.response) {
try {
const parsed = JSON.parse(raw.response) as UploadResponseBody;
return parsed.message || '';
} catch {
return raw.response;
}
}
return '';
}
export function normalizeUploadError(error: unknown) {
const message = getMessageFromUnknown(error);
return new Error(message || $t('cropper.message.uploadFailed'));
}
export function resolveUploadPath(response: UploadResponseBody) {
if (!response || response.errorCode !== 0) {
throw new Error(response?.message || $t('cropper.message.uploadFailed'));
}
const path = response.data?.path;
if (!path) {
throw new Error($t('cropper.message.notUrl'));
}
return path;
}