|
|
@@ -286,5 +286,87 @@ console.log('\n【6】不支持的格式:toast 提示 + **不放进输入框**
|
|
|
globalThis.fetch = restoreFetch;
|
|
|
}
|
|
|
|
|
|
+console.log('\n【7】消息附件:`url`(能显示)与 `fileUrl`(发给后端)不能混 —— 回归:气泡里的图不显示');
|
|
|
+{
|
|
|
+ // 用户 2026-09-23 报「提交之后看不到图片了」:
|
|
|
+ // 换 DMS 后 `fileUrl` 从 OSS 绝对地址变成了 `/static/photo/…` 这种**相对路径**,
|
|
|
+ // 而 `consumeSuccessfulFileTransmission` 当时仍然只填 `url: file.fileUrl` ——
|
|
|
+ // 于是气泡里的 `<img src="/static/photo/…">` 经 dev server 拿到的是 index.html(200 但非图片),
|
|
|
+ // 图**解不出来**。实测:相对路径 → text/html;`/dms-api` + 相对路径 → image/png。
|
|
|
+ const stubFetchOk = () =>
|
|
|
+ new Response(JSON.stringify({ code: 200, content: '/static/photo/1889-c_question-x.png' }), { status: 200 });
|
|
|
+ const restoreFetch = globalThis.fetch;
|
|
|
+ globalThis.fetch = async () => stubFetchOk();
|
|
|
+
|
|
|
+ const RELATIVE = '/static/photo/1889-c_question-x.png';
|
|
|
+ const DISPLAY = '/dms-api' + RELATIVE;
|
|
|
+
|
|
|
+ // 7.1 配好 DMS 前缀(开发环境的取值,见 .env.development 的 VITE_DMS_API)
|
|
|
+ globalThis.VITE_DMS_API = '/dms-api';
|
|
|
+ {
|
|
|
+ const { uploadedFiles, handleFiles, consumeSuccessfulFileTransmission } = useBusinessAssistantUpload({
|
|
|
+ notify: () => {},
|
|
|
+ });
|
|
|
+ handleFiles([new File(['x'], 'ok.png', { type: 'image/png' })], true);
|
|
|
+ await new Promise((r) => setTimeout(r, 30));
|
|
|
+ check('图片上传成功(DMS 前缀配好时)', uploadedFiles.value[0]?.status === 'success',
|
|
|
+ JSON.stringify(uploadedFiles.value.map((f) => f.status)));
|
|
|
+
|
|
|
+ const transmission = consumeSuccessfulFileTransmission(0);
|
|
|
+ const attachment = (transmission.attachments || [])[0] || {};
|
|
|
+ check('attachment.fileUrl = 相对路径(发给后端用)', attachment.fileUrl === RELATIVE, String(attachment.fileUrl));
|
|
|
+ check('**attachment.url = 可显示地址(拼了代理前缀)**', attachment.url === DISPLAY, String(attachment.url));
|
|
|
+ check('**两个字段不相等**(曾经的 bug 就是 url 直接用了相对路径)',
|
|
|
+ attachment.url !== attachment.fileUrl, `${attachment.url} vs ${attachment.fileUrl}`);
|
|
|
+
|
|
|
+ // 后端拿到的必须仍是相对路径 —— 换 DMS 后这是请求体契约
|
|
|
+ const payload = toChatAttachmentUrls(transmission);
|
|
|
+ check('请求体 pictures 里是相对路径(不是展示地址)',
|
|
|
+ payload.pictures.length === 1 && payload.pictures[0] === RELATIVE, JSON.stringify(payload));
|
|
|
+ check('展示地址**没有**混进请求体', !JSON.stringify(payload).includes('/dms-api'), JSON.stringify(payload));
|
|
|
+ check('非图片附件不占 pictures', payload.files.length === 0, JSON.stringify(payload));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7.2 非图片文件:气泡里是个「文件条」(只显示名字/大小),不需要展示地址
|
|
|
+ {
|
|
|
+ const { uploadedFiles, handleFiles, consumeSuccessfulFileTransmission } = useBusinessAssistantUpload({
|
|
|
+ notify: () => {},
|
|
|
+ });
|
|
|
+ globalThis.fetch = async () =>
|
|
|
+ new Response(JSON.stringify({ code: 200, content: '/static/file/1889-c_question-y.xlsx' }), { status: 200 });
|
|
|
+ handleFiles([new File(['x'], 'ok.xlsx')], false);
|
|
|
+ await new Promise((r) => setTimeout(r, 30));
|
|
|
+ const transmission = consumeSuccessfulFileTransmission(0);
|
|
|
+ const attachment = (transmission.attachments || [])[0] || {};
|
|
|
+ check('文件附件的 fileUrl 是相对路径', attachment.fileUrl === '/static/file/1889-c_question-y.xlsx',
|
|
|
+ String(attachment.fileUrl));
|
|
|
+ check('文件附件没有可显示地址(气泡走文件条,不需要)', attachment.url === undefined, String(attachment.url));
|
|
|
+ check('文件附件仍进请求体 files', toChatAttachmentUrls(transmission).files.length === 1,
|
|
|
+ JSON.stringify(toChatAttachmentUrls(transmission)));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7.3 没配 DMS 前缀时(生产环境当前就是没配,见 .env.production)——
|
|
|
+ // 宁可**不给展示地址**,也不能塞一个取不到的地址让气泡显示成坏图
|
|
|
+ {
|
|
|
+ globalThis.VITE_DMS_API = '';
|
|
|
+ const { uploadedFiles, handleFiles, consumeSuccessfulFileTransmission } = useBusinessAssistantUpload({
|
|
|
+ notify: () => {},
|
|
|
+ });
|
|
|
+ globalThis.fetch = async () => stubFetchOk();
|
|
|
+ handleFiles([new File(['x'], 'ok.png', { type: 'image/png' })], true);
|
|
|
+ await new Promise((r) => setTimeout(r, 30));
|
|
|
+ // 上传本身会失败(未配置 DMS 接口地址)→ 附件不会进消息,这是「拦在源头」
|
|
|
+ check('未配 DMS 前缀时上传直接失败(不会产生一个坏地址的附件)',
|
|
|
+ uploadedFiles.value.length === 0 || uploadedFiles.value[0]?.status === 'error',
|
|
|
+ JSON.stringify(uploadedFiles.value.map((f) => f.status)));
|
|
|
+ const transmission = consumeSuccessfulFileTransmission(0);
|
|
|
+ check('失败的上传不会混进消息附件', (transmission.attachments || []).length === 0,
|
|
|
+ JSON.stringify(transmission.attachments));
|
|
|
+ }
|
|
|
+
|
|
|
+ globalThis.VITE_DMS_API = '';
|
|
|
+ globalThis.fetch = restoreFetch;
|
|
|
+}
|
|
|
+
|
|
|
console.log(`\n===== 通过 ${pass} 项,失败 ${fail} 项 =====`);
|
|
|
process.exit(fail ? 1 : 0);
|