From 8ca7a00afb1811183ffe888fb1d15152ed14ef91 Mon Sep 17 00:00:00 2001 From: weicw1996 Date: Tue, 13 Oct 2026 19:57:57 +0800 Subject: [PATCH] =?UTF-8?q?feat(ai):=20=E5=9B=BE=E7=89=87=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E6=8E=A5=E5=85=A5=20file-list=20=E5=8F=82=E8=80=83?= =?UTF-8?q?=E7=B4=A0=E6=9D=90=E4=B8=8A=E4=BC=A0=EF=BC=88issue=2014?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 上游「AI 创意助手」开始节点有 file-list 变量 user_files(最多 5 个,允许 image/video/document/audio),但 web 端图片模式此前完全没有附件入口 —— 发送键左侧 那两个图标按钮没有绑定任何事件,是纯装饰。 - 聊天页图片模式新增「参考素材」区:添加附件(隐藏 input[type=file])、已选列表可 逐个移除、上限 5 个(对齐上游 max_length),按 MIME/扩展名判定 image/video/audio/document,发送时组装 file-list 契约 {transfer_method:"local_file", type, upload_file_id, url:""};上传中禁止发送 - uploadAiFile(file, app?) 支持应用代号;gxmu/creativeAssistant 表单页改传 creativeAssistant —— 该页用同一个接口上传却不指定应用,附件必然报 Invalid upload file(既有缺陷,本次一并修掉) - CreativeAssistantUploadFile.upload_file_id 由 number 改为 string | number: 它实际是 Dify /files/upload 返回的 uuid 字符串,原声明与实现不符 - formatCreativeResult 清洗 video_message / photo_message:剥离 thinking 思维链、 丢弃 {"cover_prompt":…,"width":…} 中间产物 JSON,不再把上游 LLM 的原始输出 当正文展示(截图实测过:气泡里出现整段英文思考过程或裸 JSON) - 删除发送键左侧两个无事件的装饰性图标按钮(.icon-btn 样式仍被消息操作按钮使用,保留) --- src/api/ai/creativeAssistant/index.ts | 10 +- src/api/ai/creativeAssistant/model/index.ts | 8 +- src/views/gxmu/creativeAssistant/index.vue | 4 +- src/views/oa/chatgpt/index.vue | 281 +++++++++++++++++--- 4 files changed, 257 insertions(+), 46 deletions(-) diff --git a/src/api/ai/creativeAssistant/index.ts b/src/api/ai/creativeAssistant/index.ts index 38e19be..d3fe272 100644 --- a/src/api/ai/creativeAssistant/index.ts +++ b/src/api/ai/creativeAssistant/index.ts @@ -10,10 +10,18 @@ import type { /** * AI文件上传 + * + * @param app 应用代号(后端按代号选择 Dify 应用凭证)。 + * Dify 的 /files/upload 是**按应用鉴权**的:文件只能被上传时所用应用的工作流引用, + * 换个应用引用同一个 upload_file_id 会报 `Invalid upload file`。 + * 所以喂给创意助手 file-list 变量的附件,必须用 app='creativeAssistant' 上传。 */ -export async function uploadAiFile(file: File) { +export async function uploadAiFile(file: File, app?: string) { const formData = new FormData(); formData.append('file', file); + if (app) { + formData.append('app', app); + } const res = await request.post>( MODULES_API_URL + '/ai/file/upload', formData diff --git a/src/api/ai/creativeAssistant/model/index.ts b/src/api/ai/creativeAssistant/model/index.ts index f9ffac5..f10b33b 100644 --- a/src/api/ai/creativeAssistant/model/index.ts +++ b/src/api/ai/creativeAssistant/model/index.ts @@ -3,7 +3,13 @@ import type { FileRecord } from '@/api/system/file/model'; export interface CreativeAssistantUploadFile { transfer_method: 'local_file'; type: 'image' | 'document' | 'audio' | 'video'; - upload_file_id?: number; + /** + * Dify /files/upload 返回的文件 id。 + * + * 注意它是 **uuid 字符串**(不是本地 FileRecord 的自增 id);原先声明为 number, + * 与实际不符 —— 而且 Dify 按应用鉴权该 id,必须用同一应用的凭证上传才有效。 + */ + upload_file_id?: string | number; url: string; } diff --git a/src/views/gxmu/creativeAssistant/index.vue b/src/views/gxmu/creativeAssistant/index.vue index 5e5e4cd..a54b443 100644 --- a/src/views/gxmu/creativeAssistant/index.vue +++ b/src/views/gxmu/creativeAssistant/index.vue @@ -480,7 +480,9 @@ mask: true }); try { - const result = await uploadAiFile(rawFile); + // 必须用创意助手自己的应用凭证上传:Dify 的 /files/upload 按应用鉴权, + // 用别的应用的 Key 上传,工作流的 file-list 变量会报 Invalid upload file。 + const result = await uploadAiFile(rawFile, 'creativeAssistant'); uploadedFiles.value = [ ...uploadedFiles.value, { diff --git a/src/views/oa/chatgpt/index.vue b/src/views/oa/chatgpt/index.vue index 535f531..2bfa10f 100644 --- a/src/views/oa/chatgpt/index.vue +++ b/src/views/oa/chatgpt/index.vue @@ -253,6 +253,44 @@ {{ item.label }} +
+ 参考素材 + + + 最多 {{ IMAGE_FILE_LIMIT }} 个,支持图片 / 视频 / 音频 / 文档 + +
    +
  • + {{ item.name }} + +
  • +
+ +