From 04a8912307be3c993fcbc9a63d160a0cbeb8a319 Mon Sep 17 00:00:00 2001 From: 2910410219 <2910410219@qq.com> Date: Sat, 6 Jun 2026 17:23:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../settings/modelConfig/modelModule/index.ts | 2 +- .../modelModule/component/editModule.vue | 264 ++++++++---------- 2 files changed, 119 insertions(+), 147 deletions(-) diff --git a/src/api/settings/modelConfig/modelModule/index.ts b/src/api/settings/modelConfig/modelModule/index.ts index 6a9bfbe..6214799 100644 --- a/src/api/settings/modelConfig/modelModule/index.ts +++ b/src/api/settings/modelConfig/modelModule/index.ts @@ -167,7 +167,7 @@ export interface CreateModelParams { firstFrame?: string; lastFrame?: string; responseMapping?: Record; - responseBody?: Record; + responseBody?: string; extendMapping?: Record; responseTokenField?: string; tokenConfig?: Record; diff --git a/src/views/settings/modelConfig/modelModule/component/editModule.vue b/src/views/settings/modelConfig/modelModule/component/editModule.vue index 4bd8046..8636e99 100644 --- a/src/views/settings/modelConfig/modelModule/component/editModule.vue +++ b/src/views/settings/modelConfig/modelModule/component/editModule.vue @@ -38,7 +38,15 @@ - +
服务商模型配置
@@ -74,7 +82,7 @@ - + @@ -83,10 +91,8 @@ 配置查询/回调
- - - 配置流式参数 - + + @@ -225,58 +231,6 @@ - - - -
-
-
内容路径
- - - -
-
-
-
-
- {{ templateKey }} 附件模板 -
-
-
type
- - - -
body
-
-
-
- - = - - 删除 -
- + 添加 body 字段 -
-
-
-
-
-
- -
-
@@ -430,7 +384,13 @@
- + = @@ -486,19 +446,48 @@ - -
-
- - = - - 删除 + + +
+
+
内容路径
+ + + +
- + 添加字段 -
- +
+
+
+ {{ templateKey }} 附件模板 +
+
+
type
+ + + +
body
+
+
+
+ + = + + 删除 +
+ + 添加 body 字段 +
+
+
+
+
+ + @@ -625,11 +614,10 @@ const typeOptionValue = (id: number | string): number | string => { }; const editModuleFormRef = ref(); -const streamConfigDialogFormRef = ref(); +const extendMappingDialogFormRef = ref(); const emit = defineEmits(['refresh']); const showHeaderDialog = ref(false); const showAsyncQueryConfigDialog = ref(false); -const showStreamConfigDialog = ref(false); const showFormDialog = ref(false); const showRequestMappingDialog = ref(false); const showResponseMappingDialog = ref(false); @@ -662,9 +650,9 @@ const createEmptyStreamConfigForm = (): StreamConfigForm => ({ const streamConfigForm = reactive(createEmptyStreamConfigForm()); const streamConfigRules = { targetContentPath: [{ required: true, message: '请输入内容路径', trigger: 'blur' }], - audioType: [{ required: true, message: '请输入 Audio 附件模板 type', trigger: 'blur' }], - imageType: [{ required: true, message: '请输入 Image 附件模板 type', trigger: 'blur' }], - videoType: [{ required: true, message: '请输入 Video 附件模板 type', trigger: 'blur' }], + // audioType: [{ required: true, message: '请输入 Audio 附件模板 type', trigger: 'blur' }], + // imageType: [{ required: true, message: '请输入 Image 附件模板 type', trigger: 'blur' }], + // videoType: [{ required: true, message: '请输入 Video 附件模板 type', trigger: 'blur' }], }; const streamAttachmentTemplateKeys: Array = ['audio', 'image', 'video']; @@ -765,42 +753,6 @@ const state = reactive({ streamConfig: [ { validator: (_rule: unknown, _value: unknown, callback: (e?: Error) => void) => { - if (Number(state.ruleForm.callMode) !== 2) { - callback(); - return; - } - if (!String(streamConfigForm.targetContentPath || '').trim()) { - callback(new Error('流式执行时,请填写内容路径')); - return; - } - const missingTemplateType = Object.entries(streamConfigForm.attachmentTemplates).some( - ([, template]) => !String(template.type || '').trim() - ); - if (missingTemplateType) { - callback(new Error('流式执行时,请完整填写所有附件模板 type')); - return; - } - const hasEmptyBodyTemplate = Object.entries(streamConfigForm.attachmentTemplates).some(([, template]) => { - const validRows = template.bodyFields.filter( - (item) => String(item.key || '').trim() !== '' && String(item.value || '').trim() !== '' - ); - return validRows.length === 0; - }); - if (hasEmptyBodyTemplate) { - callback(new Error('流式执行时,每个附件模板至少需要一个 body 字段')); - return; - } - const hasInvalidBodyField = Object.entries(streamConfigForm.attachmentTemplates).some(([, template]) => - template.bodyFields.some( - (item) => - (String(item.key || '').trim() === '' && String(item.value || '').trim() !== '') || - (String(item.key || '').trim() !== '' && String(item.value || '').trim() === '') - ) - ); - if (hasInvalidBodyField) { - callback(new Error('附件模板 body 的键和值都必须完整填写')); - return; - } callback(); }, trigger: 'change', @@ -903,9 +855,34 @@ const state = reactive({ extendMapping: [ { validator: (_rule: unknown, _value: unknown, callback: (e?: Error) => void) => { - const emptyKeys = state.extendMappingFields.filter((x) => String(x.key || '').trim() === '' && String(x.value || '').trim() !== ''); - if (emptyKeys.length > 0) { - callback(new Error('附加映射字段名不能为空')); + if (!String(streamConfigForm.targetContentPath || '').trim()) { + callback(new Error('附加映射时,请填写内容路径')); + return; + } + const missingTemplateType = Object.entries(streamConfigForm.attachmentTemplates).some( + ([, template]) => !String(template.type || '').trim() + ); + if (missingTemplateType) { + callback(new Error('附加映射时,请完整填写所有附件模板 type')); + return; + } + const hasEmptyBodyTemplate = Object.entries(streamConfigForm.attachmentTemplates).some(([, template]) => { + const validRows = template.bodyFields.filter((item) => String(item.key || '').trim() !== '' && String(item.value || '').trim() !== ''); + return validRows.length === 0; + }); + if (hasEmptyBodyTemplate) { + callback(new Error('附加映射时,每个附件模板至少需要一个 body 字段')); + return; + } + const hasInvalidBodyField = Object.entries(streamConfigForm.attachmentTemplates).some(([, template]) => + template.bodyFields.some( + (item) => + (String(item.key || '').trim() === '' && String(item.value || '').trim() !== '') || + (String(item.key || '').trim() !== '' && String(item.value || '').trim() === '') + ) + ); + if (hasInvalidBodyField) { + callback(new Error('附件模板 body 的键和值都必须完整填写')); return; } callback(); @@ -1145,10 +1122,10 @@ const removeAsyncQueryStatusValueField = (index: number) => { asyncQueryConfigForm.statusValueFields.splice(index, 1); }; -const validateAndConfirmStreamConfig = async () => { - await streamConfigDialogFormRef.value?.validate?.(); - await editModuleFormRef.value?.validateField?.('streamConfig'); - showStreamConfigDialog.value = false; +const validateAndConfirmExtendMapping = async () => { + await extendMappingDialogFormRef.value?.validate?.(); + await editModuleFormRef.value?.validateField?.('extendMapping'); + showExtendMappingDialog.value = false; }; const objectToFields = (obj: Record) => { @@ -1198,10 +1175,7 @@ const buildStreamAttachmentTemplate = (template: StreamAttachmentTemplateForm) = body: fieldsToUnknownObject(template.bodyFields.filter((item) => String(item.key || '').trim() !== '')), }); -const buildStreamConfig = () => { - if (Number(state.ruleForm.callMode) !== 2) { - return undefined; - } +const buildExtendMappingPayload = () => { return { target_content_path: String(streamConfigForm.targetContentPath || '').trim(), attachment_templates: { @@ -1441,6 +1415,8 @@ const unwrapModelDetailPayload = (data: unknown): Record | null }; const fillFormFromDetailRow = (row: Record) => { + resetStreamConfigForm(); + state.mainBodyIndex = -1; const timeoutSeconds = row.timeoutSeconds != null && row.timeoutSeconds !== '' ? Number(row.timeoutSeconds) @@ -1458,7 +1434,7 @@ const fillFormFromDetailRow = (row: Record) => { } else { ruleFormHeadMsg = ''; } - state.ruleForm = { + Object.assign(state.ruleForm, { id: row.id as string, modelName: String(row.modelName ?? ''), modelType: row.modelType !== undefined && row.modelType !== null ? typeOptionValue(row.modelType as number | string) : null, @@ -1470,7 +1446,7 @@ const fillFormFromDetailRow = (row: Record) => { apiKey: isPrivate === 1 ? String(row.apiKey ?? '') : '', enabled: Number(row.enabled ?? 1), isChatModel: row.isChatModel !== undefined && row.isChatModel !== null ? Number(row.isChatModel) : 0, - callMode: row.callMode !== undefined && row.callMode !== null ? Number(row.callMode) : row.isAsync !== undefined && row.isAsync !== null ? Number(row.isAsync) : 0, + callMode: Number(row.callMode ?? 0), firstFrame: String(row.firstFrame || ''), lastFrame: String(row.lastFrame || ''), requiredFields: Array.isArray(row.requiredFields) ? row.requiredFields.map((item) => String(item || '').trim()).filter(Boolean) : [], @@ -1481,7 +1457,7 @@ const fillFormFromDetailRow = (row: Record) => { extendMapping: '{}', responseTokenField: String(row.responseTokenField || ''), tokenConfig: '{}', - }; + }); state.headers = ensureKeyValueRows(parseHeaders(row.headMsg), () => ({ key: '', value: '' })); state.formFields = parseFormFieldsUnified(row.form); state.requestMappingFields = ensureKeyValueRows(parseRequestMappingFields(row.requestMapping) as RequestMappingField[], () => ({ @@ -1505,7 +1481,7 @@ const fillFormFromDetailRow = (row: Record) => { })); state.extendMappingFields = ensureKeyValueRows(parseFieldsUnified(row.extendMapping), () => ({ key: '', value: '' })); state.tokenConfigFields = ensureKeyValueRows(parseFieldsUnified(row.tokenConfig), () => ({ key: '', value: '' })); - + applyStreamConfig(row.extendMapping); // 根据 responseTokenField 字段设置计费字段标记(单选) const tokenFieldKey = String(row.responseTokenField || '').trim(); if (tokenFieldKey) { @@ -1515,15 +1491,12 @@ const fillFormFromDetailRow = (row: Record) => { } } // 根据 responseBody 字段设置返回主体标记(单选) - if (row.responseBody && typeof row.responseBody === 'object' && !Array.isArray(row.responseBody)) { - const bodyKeys = Object.keys(row.responseBody); - if (bodyKeys.length > 0) { - const bodyKey = bodyKeys[0]; - const bodyFieldIndex = state.responseMappingFields.findIndex((f) => String(f.key || '').trim() === bodyKey); - if (bodyFieldIndex !== -1) { - state.responseMappingFields[bodyFieldIndex].isMainBody = true; - state.mainBodyIndex = bodyFieldIndex; - } + const responseBodyKey = String(row.responseBody || '').trim(); + if (responseBodyKey) { + const bodyFieldIndex = state.responseMappingFields.findIndex((f) => String(f.key || '').trim() === responseBodyKey); + if (bodyFieldIndex !== -1) { + state.responseMappingFields[bodyFieldIndex].isMainBody = true; + state.mainBodyIndex = bodyFieldIndex; } } @@ -1535,7 +1508,10 @@ const fillFormFromDetailRow = (row: Record) => { asyncQueryConfigForm.resultPath = String(qc.result_path || ''); asyncQueryConfigForm.statusPath = String(qc.status_path || ''); asyncQueryConfigForm.intervalSeconds = Number(qc.interval_seconds ?? 2) || 2; - asyncQueryConfigForm.statusValueFields = ensureKeyValueRows(objectToFields((qc.status_values as Record) || {}), () => ({ key: '', value: '' })); + asyncQueryConfigForm.statusValueFields = ensureKeyValueRows(objectToFields((qc.status_values as Record) || {}), () => ({ + key: '', + value: '', + })); } else { asyncQueryConfigForm.url = ''; asyncQueryConfigForm.method = 'POST'; @@ -1545,8 +1521,6 @@ const fillFormFromDetailRow = (row: Record) => { asyncQueryConfigForm.intervalSeconds = 2; asyncQueryConfigForm.statusValueFields = [{ key: '', value: '' }]; } - - applyStreamConfig(row.streamConfig); }; // 打开弹窗(编辑时会请求 /model/getModel 详情) const openDialog = async (type: string, row?: Record) => { @@ -1653,9 +1627,7 @@ const onSubmit = () => { if (Number(state.ruleForm.callMode) === 1) { await editModuleFormRef.value?.validateField?.('asyncQueryConfig'); } - if (Number(state.ruleForm.callMode) === 2) { - await editModuleFormRef.value?.validateField?.('streamConfig'); - } + await editModuleFormRef.value?.validateField?.('extendMapping'); // 验证响应映射(如果有配置) const validResponseFields = state.responseMappingFields.filter((x) => String(x.key || '').trim() !== ''); @@ -1679,9 +1651,9 @@ const onSubmit = () => { state.ruleForm.requiredFields = requiredFields; const responseMapping = fieldsToObject(state.responseMappingFields.filter((f) => String(f.key || '').trim() !== '')); - // 获取被设置为返回主体的字段 {key: value} + // 获取被设置为返回主体的字段 key const responseBodyField = state.responseMappingFields.find((f) => f.isMainBody && String(f.key || '').trim() !== ''); - const responseBody = responseBodyField ? { [responseBodyField.key.trim()]: responseBodyField.value } : {}; + const responseBody = responseBodyField ? responseBodyField.key.trim() : ''; // 获取计费字段(可选) const responseTokenField = @@ -1742,11 +1714,11 @@ const onSubmit = () => { timeoutSeconds: state.ruleForm.timeoutSeconds, retryTimes: state.ruleForm.retryTimes, autoCleanSeconds: state.ruleForm.autoCleanSeconds, - extendMapping: fieldsToUnknownObject(state.extendMappingFields.filter((f) => String(f.key || '').trim() !== '')), + extendMapping: buildExtendMappingPayload(), responseTokenField, tokenConfig: fieldsToUnknownObject(state.tokenConfigFields.filter((f) => String(f.key || '').trim() !== '')), queryConfig: buildQueryConfig(), - streamConfig: buildStreamConfig(), + streamConfig: undefined, }; if (state.dialog.type === 'edit') {