feat(ai): 问答助手页入口对齐 web,改为「聊天/写作/图片」(issue 15)

模式标签由「聊天/稿件/创意/策划」改为「聊天/写作/图片」,去掉策划链路;
写作与图片两个入口补上 web 端已有的表单与附件能力。

- 新增 pages/assistant/writing-params.js:web 端 writing-params.ts 的等价移植
  (零依赖纯函数)。写作模式加「文体/字数」面板,入参优先级改为
  「界面显式选择 > 键值入参 > 自然语言推断 > 默认值」——过去没有表单,
  只按「键:值」解析,解析不到就一律回落 doc_type=新闻稿 / Number=800,
  而上游提示词把这两项当主控指令,会直接压掉用户原话里的诉求(issue 13)
- 图片模式加「图片比例 + 参考素材」:附件组装成 user_files(上限 5,
  类型 image/video/audio/document),比例作为文本追加进 user_content
- chat-service 新增 uploadAiFile(file, app);上传必须带 app='creativeAssistant'
  —— Dify 的 /files/upload 按应用鉴权,不传 app 的附件必然报
  Invalid upload file(issue 14)
- 删除 buildOutlinePayload / formatOutlineResult 与 activityOutlineGen import;
  顺带清掉本次改动块内的死代码(未使用的 getCurrentUser、pickDisplayableText)

顺带修掉同源缺陷:pages/creative-assistant 的 uploadAiFile(file) 也没传应用凭证,
该页附件同样是坏的(issue 14 记的 gxmu/creativeAssistant 表单页那个缺陷)。

验证:移植等价性用例 8/8 —— 同一张用例表同时喂给小程序与 web 两端实现逐字段比对
JSON,另加 4 条常量/边界断言(防「两边一起错」);模板↔脚本静态一致性检查
(模板绑定名、this.X() 调用点、已删标识符残留)全绿,判别力经 5 处变异测试证伪;
5 个改动文件 node --check 通过,style 块花括号配平。
本机无 HBuilderX CLI 与 package.json,真机/微信开发者工具未跑。

本文件同时带有此前未提交的 issue 01 跟进改动(resolveFailedCreativeText:
创意失败态采用后端按原因映射的文案,但仍过 isDisplayableAnswer 兜底),
同一文件无法拆分。

Refs: .scratch/ai-assistant/issues/15-uniapp-assistant-modes-align-web.md
This commit is contained in:
2026-10-13 20:17:58 +08:00
parent f4d0e4d4e5
commit 244f0c24d8
5 changed files with 850 additions and 101 deletions
+18 -4
View File
@@ -10,8 +10,24 @@ export function creativeAssistant(data) {
})
}
export function uploadAiFile(file) {
/**
* AI 文件上传(喂给 Dify 开始节点的 file-list 变量)。
*
* @param {object} file `uni.chooseMessageFile` 拿到的临时文件(需有 `path`)
* @param {string} [app] 应用代号(后端按代号选择 Dify 应用凭证)
*
* `app` 不是可选项而是**硬约束**:Dify 的 `/files/upload` 按应用鉴权,
* 文件只能被「上传时所用应用」的工作流引用。不传 `app` 时后端走旧逻辑
* (`type` 为空 → chat 凭证),本页附件必然报 `Invalid upload file`(issue 14 实测)。
*/
export function uploadAiFile(file, app) {
const token = getToken()
const formData = {
tenantId: '10049'
}
if (app) {
formData.app = app
}
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${API_BASE_URL}/ai/file/upload`,
@@ -22,9 +38,7 @@ export function uploadAiFile(file) {
Authorization: token
}
: {},
formData: {
tenantId: '10049'
},
formData,
success: (response) => {
try {
const result = JSON.parse(response.data || '{}')