Brak opisu

gongtianxiao d8707107cf feat(chat): 会话、问答记录与反馈落地到 DMS 3 dni temu
build 08524fb44a chore: 初始提交——项目基线 4 dni temu
public 08524fb44a chore: 初始提交——项目基线 4 dni temu
src d8707107cf feat(chat): 会话、问答记录与反馈落地到 DMS 3 dni temu
.editorconfig 08524fb44a chore: 初始提交——项目基线 4 dni temu
.env.development d8707107cf feat(chat): 会话、问答记录与反馈落地到 DMS 3 dni temu
.env.production 6b69af8466 fix(policy): 开发环境政策库改用本地 json,修「政策名称」点不开 3 dni temu
.env.qingpu 6b69af8466 fix(policy): 开发环境政策库改用本地 json,修「政策名称」点不开 3 dni temu
.env.test 6b69af8466 fix(policy): 开发环境政策库改用本地 json,修「政策名称」点不开 3 dni temu
.eslintignore 08524fb44a chore: 初始提交——项目基线 4 dni temu
.eslintrc.js 08524fb44a chore: 初始提交——项目基线 4 dni temu
.gitignore 6d6f0e4756 chore: .gitignore 注释说明 docs/ 已并入 harness/docs/ 4 dni temu
.prettierrc.cjs 08524fb44a chore: 初始提交——项目基线 4 dni temu
README.md d8707107cf feat(chat): 会话、问答记录与反馈落地到 DMS 3 dni temu
index.html d8707107cf feat(chat): 会话、问答记录与反馈落地到 DMS 3 dni temu
jest.config.js 08524fb44a chore: 初始提交——项目基线 4 dni temu
package-lock.json 08524fb44a chore: 初始提交——项目基线 4 dni temu
package.json 08524fb44a chore: 初始提交——项目基线 4 dni temu
redirect.html 08524fb44a chore: 初始提交——项目基线 4 dni temu
tsconfig.json 08524fb44a chore: 初始提交——项目基线 4 dni temu
tsconfig.node.json 08524fb44a chore: 初始提交——项目基线 4 dni temu
vite.config.ts d8707107cf feat(chat): 会话、问答记录与反馈落地到 DMS 3 dni temu

README.md

zhaoshang-llm 改动记录

本文件当前只记录按日期的改动。项目概述、技术栈、目录结构、接口说明等内容, 等项目结束时再统一总结。

20260914

  • AI 对话迁移到接口 POST /api/chat(SSE)
    • 新增协议适配层 src/components/api-chat-coordinator.ts,把 SSE 事件翻译成既有渲染组件 可识别的内容标记,渲染层无需感知新协议
    • 请求体严格只发 {thread_id, question}answerresult.response 只展示一次; 未收到 done/error 即断流时按连接中断处理,不自动重试
    • 旧协议实现 src/components/stream-message-coordinator.ts 保留未用
  • 新增环境变量 VITE_CHAT_API,新增 dev 代理 /chat-apihttp://192.168.2.23:8000
  • 政策卡片、政策详情、参考资料、公司补问与候选确认接入新协议
  • 错误码翻译:把 HTTP 与 SSE 错误码转成中文提示(如 thread_busy → 该问题还在处理中)

20260915

  • 修复回答内容顺序:正文 → 政策卡片 → 综合说明 → 参考资料(参考资料移到最下方)
  • 修复换行丢失:块级 markdown 下单个换行会被折叠,导致列表后紧跟的说明行被并进上一条列表项
  • 修复复制功能:复制结果剔除协议标记,不再把 <scope><!-- POLICY_TABLE --><ref_links> 等原始标记一起复制出来
  • 修复卡片顺序与「更多」列表不一致:卡片改为按接口 priority.rank 排序
  • 「更多」面板的列表改为复用卡片数据,不再拉取与卡片无关的公共政策库
  • 部门筛选还原为最初的 15 个固定部门与字面匹配(此前一度改为按接口数据动态生成)
  • 新增惠企政策库来源标识(来自惠企政策库的卡片在右上角打标)
  • 政策详情面板新增「条件核验 / 匹配依据 / 原文引用」三个区块
  • 建立本机开发工作流文件与接口参考目录(按 .gitignore 约定不入库)

20260916

  • 打字机速度加快:每次打出字数 2 → 4(61 → 121 字符/秒),积压加速档位同步上调。 基准取主流 AI 的实测输出速度(Claude 3.5 约 60 字符/秒、DeepSeek-R1 约 75, 主流区间 50~120),取区间上沿——因为本项目后端一次返回整段,打字机是纯额外延迟, 同样速度会比主流慢一整段
  • 「政策事项列表」统一为一个列表、一个入口
    • 卡片区「更多 >>」与详情的「返回政策事项列表」走同一条路径、内容相同
    • 列表数据统一来自 public/merchant-agent/policies_public.v1.json (262 条申报事项 / 38 个政策),本轮匹配到的惠企政策置顶
  • 「政策事项列表」每次进入都重置筛选(部门 / 分类 / 关键词 / 页码), 避免上次的筛选残留导致「条目少」或「筛不出东西」
  • 政策详情面板的「返回政策事项列表」按惠企政策区分:只有惠企政策才显示该入口; 惠企政策判定优先用接口字段 is_policy_library,缺失时回退到按标题在库中匹配 (已做归一化,容忍《》全半角括号等差异)
  • 公司补问改为按 status 字段判定形态(found / not_found / failed / 无 status), 替掉原先靠"候选数是否为 0"和 input_help 文案正则的猜测式判断
    • failed(查询服务失败)此前会落进 not_found 分支,文案被填成"未查询到匹配的公司", 等于把失败说成查无公司,已改为独立分支并说明失败原因
    • status(初次询问是否需要公司信息)此前给"跳过公司查询",改为"不需要公司信息"
  • 补问卡片:输入框移到选项上方并常驻(原来在选项之后、需点击才展开)
  • 补问卡片:修复选项序号错乱——输入框在最上却拿 B、选项在下面却拿 A,现输入框取 A、选项顺延
  • 补问卡片:正文里已展示过的同一段文字不再在卡片内重复
  • 「跳过公司查询」由发送 /skip 改为发送选项文本「跳过公司查询」
  • 问卷提交:修复只取第一题(多题丢失)、多选只取第一项、以及数字开头选项被静默改写成纯数字

20260917

  • 修复切会话时误报「请求已取消」:
    • 根因是两处「内容是否为空」的判空口径不一致——归一化用 content.trim()<scope> 进度块算作有内容),渲染层用 stripScopeBlocks() (进度块不算内容)。同一段内容,一处认为「有」、一处认为「没有」
    • 新协议的正文要等 done 才写入,处理期间内容只有进度块,把这个缝隙 从偶发放大成「一切会话就出现」:归一化认为有内容 → 不替换文案,却把状态翻成 Finish;渲染层认为没内容 → 显示「请求已取消」,而请求其实还在跑
    • 修法:抽出唯一的判空口径 hasVisibleMessageContent()utils/interrupted-message.ts), 归一化与渲染层都改用它
    • 新增回归脚本 harness/tools/verify-empty-content-agreement.mjs, 断言的不变量就是「两处必须一致」,30 项断言
  • 删除政策详情面板的「原文引用」板块(条件核验、匹配依据保留)
  • 思考中卡片的阶段文案一律不换行:
    • 原因:ScopeContent 按卡片宽度切样式 —— 没撑满容器时标题 nowrap + 省略号, 撑满时切成 pre-wrap。而阶段文案长度不一(新协议的文案比原来的"正在思考中..."长得多), 切换时表现为「突然换行」且卡片高度跳动
    • 改法:拆开原本同时管标题与正文的规则 —— 正文保持可换行, 标题恒定 nowrap + 省略号
  • 政策详情面板的「政策名称」支持点击跳转:由库条目的 data.市级政策id 拼出 https://zwdt.sh.gov.cn/qykj/shell_oc_policy_zq/policy/policy-detail?id=<id>
    • 背景:库里 apply_link 字段 262 条全为空资源申请备注 里的 URL 是按申报事项 零散对应、且混有内网地址(25 条指向 http://10.235.238.34:7202/imanage/login), 不能作为来源。市级政策id 有 261/262 条,可靠
    • 没有 id 时不给链接(不猜),宁可没有也不指向打不开的地址
  • 查明「政策名称」显示为纯文本的真因,并调整政策库数据源(开发环境改用本地 json):
    • 政策库其实有两个来源,字段并不一致:
    • 本地 public/merchant-agent/policies_public.v1.json:262 条,data.市级政策id261
    • 远端 VITE_DOWNLOAD_URL:327 条,该字段一条都没有(它有的 policy_id 是 40 位、 与条目 id 相同,与 24 位的 市级政策id 是两套 id 体系
    • index.html 原本是远端优先(远端带 CORS 头,浏览器里确实会赢), 于是取不到 id → 拼不出详情地址 → 「政策名称」是纯文本。 此前怀疑的「HMR 状态陈旧」「走了兜底路径」均排除
    • 新增环境变量 VITE_POLICY_LOCAL_FIRST仅开发环境打开(本地优先、远端兜底), 生产仍远端优先——生产该问题属后端数据缺失,需远端那份补上 data.市级政策id, 前端无法修
    • 新增 harness/tools/check-policy-sources.mjs:对比两个来源的条数与字段覆盖率, 并在「远端也带上 id 了」时提醒可以移除该开关
    • 代价:开发环境用的这份比远端少 65 条申报事项(262 vs 327)
  • 会话、问答记录与反馈落地到 DMS 数据管理服务(栏目 1887 助手会话 / 1889 助手问答记录)
    • 提交问题时写入会话(按 c_session_id upsert:没有就新增、有就更新)与问答记录(先写问题); 回答完成补写回答;停止/断流也补写已生成的内容,避免中断的问答只有问题没有回答
    • 会话列表、历史记录改为从 DMS 读取;会话改名、删除同步到 DMS
    • 点赞/点踩/取消写入 DMS 的问答记录(按 c_record_id 定位那一行)
    • 未登录的访客也写入,以 访客_<访客id> 归属(访客 id 复用埋点的那个)
    • 会话标识用前端的 session.id(它恒等于聊天协议的 thread_id);问答记录标识用 AI 消息 id(同时是反馈组件用的 record.id,因此从 DMS 读回的历史消息点赞仍能命中原始行)
    • token 只存在于 vite 代理侧.env.development.local,按约定不入库), 浏览器产物里没有 token;DMS 不可用时静默降级,聊天与本地历史不受影响
    • 实测踩坑:DMS 的「删除」不是 delContentById(各种传法都返回参数错误), 而是 POST /content/updateAudit 把状态改成 4(销毁);addContent 会返回记录 uuid