diff --git a/.gitignore b/.gitignore index ea8ae16..3219ccc 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ test-results/ .codex-remote-attachments/ tmp-*.png tmp/ +.zcode/ .nezha/ .omo/ .env diff --git a/document/development/2026-06-25/dev-logs/bugs/ai-approval-followup-context.md b/document/development/2026-06-25/dev-logs/bugs/ai-approval-followup-context.md new file mode 100644 index 0000000..1c25883 --- /dev/null +++ b/document/development/2026-06-25/dev-logs/bugs/ai-approval-followup-context.md @@ -0,0 +1,12 @@ +# AI 工作台审核单二轮审核命令丢失候选上下文 + +日期:2026-06-25 +文档路径:document/development/2026-06-25/dev-logs/bugs/ai-approval-followup-context.md + +## 修复记录 +- 16:24:记录 bug 修复:AI 工作台审核单二轮审核命令丢失候选上下文。(bug-log:8a2ae6eb) + - Git 提交检查:fetch 失败:fatal: unable to access 'https://www.caoxiaozhu.com:13002/YG-Soft/X-Financial.git/': LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to www.caoxiaozhu.com:13002;upstream `origin/main`;upstream 新提交:未发现;本地 ahead 提交:8a2ae6eb (HEAD -> main) fix(server): gate_classify 复用 _classify_irrelevant_input 修复 off_topic 误杀;992cf71f refactor(server): Phase 1 图拓扑重构 - LangGraph 成为唯一编排者;54356ba8 refactor(server): scene 注册表骨架 + 统一门控管道设计文档;e9d7c56d feat(server): 会话上下文保留(LLM 历史 + 确定性兜底双保险)。 + - 修改:`workbenchAiCommandIntentModel.js` 新增待审单据候选上下文解析与二轮审批命令提示;`useWorkbenchAiCommandIntents.js` 在 `query_candidates` 前优先复用上一轮待审候选;`workbench-ai-command-intent-model.test.mjs` 覆盖“我有哪些审核单”后继续说“审核通过”的候选承接。 + - 操作:按 TDD 先补失败用例,再实现最小修复;执行 `tools/agent-change-log/update_change_log.py --kind bug` 创建当天 bug 记录,并手动补全真实修复细节。 + - 验证:`node --test web/tests/workbench-ai-command-intent-model.test.mjs` 通过;`node --test web/tests/workbench-ai-command-intent-model.test.mjs web/tests/workbench-intent-frame-model.test.mjs web/tests/ai-document-query-model.test.mjs` 通过,31 项前端相关测试全部通过。 + - 影响:用户在 AI 工作台先查询待审/审核单后,再说“请帮我审核通过”或类似审批命令时,系统会接上刚才候选并要求进入详情确认,不会把二轮命令当成孤立查询或静默失智;仍保留高风险审批动作不直接执行的安全边界。 diff --git a/document/development/2026-06-25/dev-logs/bugs/ai-enterprise-orb-frame.md b/document/development/2026-06-25/dev-logs/bugs/ai-enterprise-orb-frame.md new file mode 100644 index 0000000..0995931 --- /dev/null +++ b/document/development/2026-06-25/dev-logs/bugs/ai-enterprise-orb-frame.md @@ -0,0 +1,12 @@ +# AI模式企业主题光球出现矩形闪动边框 + +日期:2026-06-25 +文档路径:document/development/2026-06-25/dev-logs/bugs/ai-enterprise-orb-frame.md + +## 修复记录 +- 15:02:记录 bug 修复:AI模式企业主题光球出现矩形闪动边框。(bug-log:2ebc2756) + - Git 提交检查:15:01 执行 `git fetch --all --prune` 成功;upstream `origin/main`;upstream 新提交:未发现;本地 ahead 提交:未发现。 + - 修改:`personal-workbench-ai-mode.css`,把企业主题下 `.workbench-ai-orb` 从白底圆角矩形容器改回透明圆形承载,移除边框与阴影;`settings-theme-section.test.mjs` 增加断言锁定 `border: 0`、`border-radius: 50%`、`background: transparent`、`box-shadow: none`。 + - 操作:复现时确认企业主题覆盖块把光球容器设置为 `border-radius: 18px`、白底、阴影,导致 GIF 光球外层出现明显闪动方框;修复后用浏览器读取已加载 CSSOM,确认企业主题规则已变为透明圆形版本。 + - 验证:`node web/tests/settings-theme-section.test.mjs`、`node web/tests/settings-llm-section.test.mjs`、`node web/tests/settings-rendering-section.test.mjs`、`git diff --check`、`npm --prefix web run build` 均通过;本地工作台页面可加载,光球元素存在,页面无 error,浏览器 CSSOM 中企业主题光球规则为 `border: 0px`、`border-radius: 50%`、`background: transparent`、`box-shadow: none`。 + - 影响:企业沉稳主题下 AI 模式欢迎区光球不再显示矩形闪动边框,动感/专业智能主题保持原有光球表现。 diff --git a/document/development/2026-06-25/dev-logs/bugs/application-detail-edit-returned-draft.md b/document/development/2026-06-25/dev-logs/bugs/application-detail-edit-returned-draft.md new file mode 100644 index 0000000..8fb4bd8 --- /dev/null +++ b/document/development/2026-06-25/dev-logs/bugs/application-detail-edit-returned-draft.md @@ -0,0 +1,27 @@ +# 申请详情退回/草稿状态修改申请卡壳 + +日期:2026-06-25 +文档路径:document/development/2026-06-25/dev-logs/bugs/application-detail-edit-returned-draft.md + +## 修复记录 +- 16:40:记录 bug 修复:申请详情退回/草稿状态修改申请卡壳。(bug-log:8a2ae6eb) + - Git 提交检查:fetch 失败:fatal: unable to access 'https://www.caoxiaozhu.com:13002/YG-Soft/X-Financial.git/': LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to www.caoxiaozhu.com:13002;upstream `origin/main`;upstream 新提交:未发现;本地 ahead 提交:8a2ae6eb (HEAD -> main) fix(server): gate_classify 复用 _classify_irrelevant_input 修复 off_topic 误杀;992cf71f refactor(server): Phase 1 图拓扑重构 - LangGraph 成为唯一编排者;54356ba8 refactor(server): scene 注册表骨架 + 统一门控管道设计文档;e9d7c56d feat(server): 会话上下文保留(LLM 历史 + 确定性兜底双保险)。 + - 修改:`travelRequestDetailSetup.js` 和 `TravelRequestDetailView.vue` 将“修改申请”入口从仅退回态放宽为申请单草稿/退回归一后的可编辑态,仍要求当前用户是申请人;打开助手时补齐原申请 `draftPayload`、`applicationEditMode` 和可编辑字段白名单。 + - 修改:`useAppShell.js`、`AppShellRouteView.vue`、`TravelReimbursementCreateView.js`、`useTravelReimbursementCreateViewLifecycle.js` 贯通 `initialDraftPayload`,让申请详情带出的核对表首条消息保留原 `claim_id`,保存草稿/直接提交时走已有 `application_edit_claim_id` 更新链路,不再新建或卡在无上下文状态。 + - 修改:`expenseApplicationPreview.js` 支持 `editableFields`,在修改申请场景只开放事由、时间、地点、出行方式;`aiApplicationPreviewActions.js` 将白名单写入 `application_editable_fields`,便于后续服务端字段级约束。 + - 操作:manual 触发 `tools/agent-change-log/update_change_log.py --kind bug` 生成日志后补充真实修复记录;未修改后端接口逻辑,因为 `user_agent_application.py` 已允许 `draft/returned/supplement` 申请按 `application_edit_claim_id` 更新。 + - 验证:`node --test web/tests/travel-request-detail-risk-advice.test.mjs` 通过;`node --test --test-name-pattern "application edit prefill opens assistant without auto submit" web/tests/app-shell-financial-assistant-entry.test.mjs` 通过;`node --test --test-name-pattern "application edit preview only allows reason time location and transport changes" web/tests/expense-application-fast-preview.test.mjs` 通过;`node web/tests/ai-application-preview-actions.test.mjs` 通过;`git diff --check` 通过;`npm --prefix web run build` 通过。全量跑 `app-shell-financial-assistant-entry.test.mjs` 与 `expense-application-fast-preview.test.mjs` 时仍有既有结构断言漂移,失败点与本次修改无关。 + - 影响:用户在申请详情里看到草稿和退回申请都能继续修改;修改面被限制在事由、时间、地点、出行方式,其他职级、负责人、费用标准和金额仍由原单或规则测算带入。 +- 16:51:补充修复:取消底部“修改申请”按钮,改为申请详情格子内联铅笔编辑。 + - Git 提交检查:fetch 仍失败:fatal: unable to access 'https://www.caoxiaozhu.com:13002/YG-Soft/X-Financial.git/': LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to www.caoxiaozhu.com:13002;upstream `origin/main`;upstream 新提交:未发现;本地 ahead 提交仍为 8a2ae6eb、992cf71f、54356ba8、e9d7c56d。 + - 修改:`TravelRequestDetailView.vue` 移除底部“修改申请”按钮,在申请详情事实格子的值旁显示小铅笔;点击后根据字段类型切换为日期框、下拉框或文本输入,并提供保存/取消按钮。 + - 修改:`travelRequestDetailSetup.js` 新增 `applicationDetailEditor` 状态、`canEditApplicationDetailItem`、`openApplicationDetailEditor`、`saveApplicationDetailEdit` 等内联编辑流程;保存时复用 `runAiApplicationPreviewAction` 的 `save_draft` 路径和 `application_edit_claim_id`,保持更新原申请单。 + - 修改:`travel-request-detail-view.css` 收窄申请详情标签选择器,避免内联编辑内部 `span` 被误当字段名,并补充铅笔、确认、取消、编辑控件样式。 + - 验证:先运行新增目标断言失败,确认旧按钮仍存在;实现后 `node --test --test-name-pattern "draft or returned application detail edits allowed facts inline" web/tests/travel-request-detail-risk-advice.test.mjs` 通过;`node --test web/tests/travel-request-detail-risk-advice.test.mjs` 62 条通过;`node web/tests/ai-application-preview-actions.test.mjs` 通过;`git diff --check` 通过;`npm --prefix web run build` 通过。本地 `http://[::1]:5173/app/documents` 可达但跳转登录页,因无登录态未继续真实详情点击。 + - 影响:草稿/退回申请不再需要先打开 AI 助手才能改,用户可以直接在详情表格中改事由、时间、地点、出行方式;其它字段仍不可编辑,由原单或规则测算带入。 +- 17:02:补充修复:详情页因残留 `handleModifyApplication` 返回项导致 setup 阶段崩溃。 + - Git 提交检查:fetch 仍失败:fatal: unable to access 'https://www.caoxiaozhu.com:13002/YG-Soft/X-Financial.git/': LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to www.caoxiaozhu.com:13002;upstream `origin/main`;upstream 新提交:未发现;本地 ahead 提交仍为 8a2ae6eb、992cf71f、54356ba8、e9d7c56d。 + - 修改:`travelRequestDetailSetup.js` 删除 return 对象里已经不存在的 `handleModifyApplication`,避免详情页初始化时抛 `ReferenceError`。 + - 修改:`travel-request-detail-risk-advice.test.mjs` 为内联编辑回归用例增加 `handleModifyApplication` 不得残留的断言;先运行目标用例确认失败,再删除残留返回项后确认转绿。 + - 验证:`node --test --test-name-pattern "draft or returned application detail edits allowed facts inline" web/tests/travel-request-detail-risk-advice.test.mjs` 先失败后通过;`node --test web/tests/travel-request-detail-risk-advice.test.mjs` 62 条通过;`node web/tests/ai-application-preview-actions.test.mjs` 通过;`git diff --check` 通过;`npm --prefix web run build` 通过。真实本地 `[::1]:5173` 以管理员打开 `AG2YUJ9FB` 详情页无控制台错误;切换申请人 `caoxiaozhu@xf.com` 后同页可见 `申请详情` 和单号,铅笔按钮 5 个,点击后出现 1 个编辑控件,取消后无保存副作用。 + - 影响:申请/报销详情页 setup 不再因为旧按钮处理函数缺失而白屏,内联铅笔编辑入口保留。 diff --git a/document/development/2026-06-25/feature/chat-ui-saas-styling/CONCEPT.md b/document/development/2026-06-25/feature/chat-ui-saas-styling/CONCEPT.md new file mode 100644 index 0000000..d3db13a --- /dev/null +++ b/document/development/2026-06-25/feature/chat-ui-saas-styling/CONCEPT.md @@ -0,0 +1,31 @@ +# AI 对话 UI 样式重构与 SaaS 化设计方案 + +为了让 X-Financial AI 助手的对话界面展现更专业的金融与 SaaS 企业化视觉,我们对前端全局的 Markdown 渲染样式进行了重构。 + +## 设计目标 +- **中性色打底**:对话块背景、边框移除饱和偏色,统一采用 Slate/Neutral 冷灰色调(如 `#f8fafc` 和 `#cbd5e1`)。 +- **降低色彩冗余**:将非必须的高亮蓝色改为中性灰色,各单据卡片仅在状态字样与极淡头部透明底中体现状态点缀,避免彩色杂乱堆积。 +- **界面扁平微阴影**:移除带有斜向彩色发光的阴影与复杂的背景图案,采用 1px 实线描边配合微阴影,契合 Stripe, Jira 等现代 SaaS 产品规范。 + +## 详细参数定义 +- **引用块 (`blockquote` / `.ai-html-callout`)**: + - 边框:`3px solid #cbd5e1` + - 背景:`#f8fafc` + - 文字:`#334155` +- **信息网格 (`.ai-html-focus-grid`)**: + - 边框:`3px solid #cbd5e1` + - 标题颜色:`#475569` (Slate-600) +- **单据卡片 (`.ai-document-card`)**: + - 描边:`1px solid #e2e8f0` + - 投影:`0 1px 2px 0 rgba(15, 23, 42, 0.05)` + - 头部默认背景:`rgba(241, 245, 249, 0.5)` + - 状态点缀色: + - `is-success` (Teal-700): `#0f766e` + - `is-warning` (Amber-700): `#b45309` + - `is-danger` (Red-700): `#b91c1c` + - is-pending (Blue-600): `#2563eb` + +## 消息排版格式规范 +- **限制 Alert 引用块为单条**:在警示/阻塞状态下,只允许包含一条 `>` 引用块用作 Alert 提示。 +- **列表扁平化**:发起前核对结果等普通多维状态信息,一律不使用 `>` 引用块,合并为标准的无序列表展示,保持界面视觉扁平、整洁。 +- **常规表单数据平铺**:时间、单据编号等字段,均采用扁平加粗文本平铺,不再触发 focus-grid 等具有边框线的额外容器。 diff --git a/document/development/2026-06-25/feature/chat-ui-saas-styling/TODO.md b/document/development/2026-06-25/feature/chat-ui-saas-styling/TODO.md new file mode 100644 index 0000000..efb747d --- /dev/null +++ b/document/development/2026-06-25/feature/chat-ui-saas-styling/TODO.md @@ -0,0 +1,9 @@ +# 任务计划 (SaaS 风格视觉优化) + +- [x] 优化全局 `blockquote` 与 `.ai-html-callout` 的色彩饱和度,改用 Slate 灰蓝色系打底。 +- [x] 优化 `.ai-html-focus-grid` 信息网格与竖线的亮蓝色调。 +- [x] 移除单据卡片上的 `ai-document-card-bg.png` 渐变背景图。 +- [x] 扁平化单据卡片的描边与中性阴影。 +- [x] 优化卡片语义状态角标与操作链接的 SaaS 蓝及点缀。 +- [x] 优化原生 Markdown 列表 `li::marker` 与表格外包边框的色彩层级。 +- [x] 重构预审与冲突消息的 Markdown 输出格式,消除不必要的 `>` 引用块,攻克“三条大竖杠”的排版痛点。 diff --git a/document/development/2026-06-25/feature/theme-settings-enterprise-ai-style/CONCEPT.md b/document/development/2026-06-25/feature/theme-settings-enterprise-ai-style/CONCEPT.md new file mode 100644 index 0000000..f261fac --- /dev/null +++ b/document/development/2026-06-25/feature/theme-settings-enterprise-ai-style/CONCEPT.md @@ -0,0 +1,207 @@ +# 主题设置与企业沉稳 AI 模式 概念文档 + +更新时间:2026-06-25 + +文档路径:document/development/2026-06-25/feature/theme-settings-enterprise-ai-style/CONCEPT.md + +## 功能一句话 + +将系统设置中的“界面皮肤”升级为“主题设置”,从单纯色板选择扩展为产品体验风格选择,并让 AI 模式在“企业沉稳”主题下呈现更符合企业级 SaaS 的低噪声、结构化、克制风格。 + +## 背景与问题 + +当前系统设置里的外观入口仍偏向“界面皮肤”语义,主要表达颜色和视觉皮肤选择。这个命名过窄,无法承载用户希望配置的完整体验风格。 + +现有 AI 模式默认更接近动感活泼风格,使用较多渐变、明亮色块和活跃视觉标识。它适合演示和助手化体验,但在企业级财务、审批、风控、报销场景中,容易显得色彩过重,不够沉稳。 + +用户希望在系统设置中明确提供主题类型,至少覆盖: + +1. 动感活泼:保留当前这种更有活力、更有 AI 助手感的主题。 +2. 企业沉稳:符合企业 SaaS 风格,尤其 AI 模式下的对话图标、样式和整体风格需要克制、稳定,减少颜色渲染。 +3. 专业智能:作为第三类默认方案,介于前两者之间,保留少量智能化识别感,但整体更收敛。 + +## 目标与非目标 + +目标: + +- 将“界面皮肤”入口重命名为“主题设置”,让用户理解这里配置的是整体体验风格。 +- 将主题从一组颜色选项收敛成三类可理解的主题类型。 +- 在“企业沉稳”主题下,让 AI 模式呈现企业后台应用的专业感。 +- 保持现有设置保存链路稳定,优先复用当前 appearance 配置和主题变量机制。 +- 为后续进一步扩展租户品牌色、暗色模式、组件密度预留结构边界。 + +非目标: + +- 不重做整个系统设置信息架构。 +- 不一次性重写所有业务页面的视觉风格。 +- 不改变 AI 意图识别、报销流程、审批逻辑和后端业务规则。 +- 不新增复杂的租户级主题发布、审批或版本管理能力。 +- 不引入新的前端主题框架或额外依赖。 + +## 用户与场景 + +管理员在系统设置中进入“主题设置”,选择适合当前组织的产品体验风格。 + +演示、培训、轻量工作台场景可以使用“动感活泼”,保留当前更有活力的 AI 交互表达。 + +企业正式生产环境可以使用“企业沉稳”,让财务、审批、风控和 AI 对话看起来像成熟的企业应用,而不是营销页或玩具化助手。 + +希望保留智能化识别但又不希望过度活泼的组织,可以使用“专业智能”。 + +## 功能能力 + +主题设置页面需要提供三类主题: + +- 动感活泼:当前风格延续,允许渐变、轻动效和更明显的 AI 识别色。 +- 企业沉稳:低饱和色、白灰底、轻描边、少阴影、少渐变,强调信息层级和业务可信度。 +- 专业智能:更克制的智能风格,允许小面积蓝灰、紫灰或品牌色点缀,但避免大面积彩色渲染。 + +页面文案调整: + +- 左侧菜单从“界面皮肤”调整为“主题设置”。 +- 页面标题从“界面皮肤与企业主色”调整为“主题风格与界面体验”。 +- 保存反馈从“界面皮肤已保存”调整为“主题设置已保存”。 +- 说明文案从“皮肤/配色”改为“主题/体验风格”。 + +AI 模式联动: + +- 动感活泼:保留当前 AI 模式视觉语言。 +- 企业沉稳:对 AI 对话区、消息气泡、工具调用状态、思考过程、图标、卡片、提示块做克制化覆写。 +- 专业智能:保留轻量 AI 识别感,但降低渐变、发光、背景装饰和高饱和强调色。 + +## 方案设计 + +配置模型优先沿用当前系统设置外观配置,避免为了命名调整引入后端迁移风险。 + +首期可以继续复用 `appearanceForm.themeSkin` 作为持久化字段,将值从原先色板语义逐步映射为主题语义: + +- `vivid`:动感活泼。 +- `enterprise`:企业沉稳。 +- `intelligent`:专业智能。 + +为了减少现有 CSS 变量和本地存储影响,前端可以在兼容期保留 `themeSkin` 字段,同时在 DOM 上补充更清晰的主题标识: + +```text +document.documentElement.dataset.themeSkin = value +document.documentElement.dataset.themeMode = value +``` + +旧值兼容策略: + +- 旧的 `sky`、`blue`、`emerald` 等明亮主题默认映射到“动感活泼”。 +- 旧的 `navy`、`slate` 等偏稳重主题默认映射到“企业沉稳”。 +- 无法识别的值回退到“企业沉稳”,保证生产环境默认更克制。 + +设置页结构: + +- 保留现有表单保存机制。 +- 将原色板卡片改为三张主题选项卡。 +- 每个主题卡展示名称、适用场景、视觉关键词和小型预览。 +- 当前选中主题需要有明确选中态,但避免大面积彩色边框。 + +企业沉稳 AI 模式样式: + +- 通过 `[data-theme-mode="enterprise"]` 或 `[data-theme-skin="enterprise"]` 覆写 `personal-workbench-ai-mode.css` 中的 AI 模式变量。 +- 背景从多层 radial-gradient 收敛为白灰底或极轻线性渐变。 +- 对话气泡使用白底、浅灰描边和稳定文字层级。 +- AI 图标使用低饱和单色或品牌主色的小面积点缀。 +- 思考过程、工具调用、风险提示等区域使用结构化信息块,减少发光、彩色渐变和装饰性元素。 +- 风险、成功、警告等语义色保留,但只在图标、状态条或小面积标签上表达。 + +专业智能主题样式: + +- 保留少量 AI 识别色,例如主色强调、轻量渐变按钮或小面积状态标识。 +- 背景和卡片仍以企业应用的可读性为主。 +- 避免全屏强背景、过多彩色阴影和过密装饰。 + +## 算法与公式 + +本功能不涉及复杂算法。 + +需要定义稳定的主题值映射函数: + +```text +normalizeThemeMode(rawTheme): + if rawTheme in ["vivid", "sky", "blue", "emerald", "purple"]: + return "vivid" + if rawTheme in ["enterprise", "navy", "slate", "gray"]: + return "enterprise" + if rawTheme in ["intelligent"]: + return "intelligent" + return "enterprise" +``` + +主题应用顺序: + +```text +后端保存值 / 本地缓存值 + -> normalizeThemeMode + -> 写入 appearanceForm.themeSkin + -> 写入 root dataset + -> 应用 CSS 变量 + -> AI 模式按 data-theme-mode 覆写组件样式 +``` + +## 测试方案 + +前端单元和静态测试: + +- 断言系统设置外观入口显示为“主题设置”。 +- 断言页面标题显示为“主题风格与界面体验”。 +- 断言三类主题均可见:动感活泼、企业沉稳、专业智能。 +- 断言企业沉稳主题保存后写入稳定主题值。 +- 断言旧主题值能通过 normalize 逻辑回退到可识别主题。 +- 断言 AI 模式存在企业沉稳主题 CSS 钩子。 + +构建验证: + +- 运行前端构建,确保主题设置改动不破坏现有页面。 +- 运行已有设置相关测试,确保系统设置保存链路不回归。 + +真实页面验收: + +- 打开 `/app/settings?section=appearance`,确认左侧菜单、页面标题、三类主题和保存反馈符合预期。 +- 切换到“企业沉稳”后打开 AI 工作台,确认对话区域、图标、消息、思考过程和提示块明显减少彩色渲染。 +- 切回“动感活泼”,确认现有风格仍可正常展示。 +- 切到“专业智能”,确认介于两者之间,不退化为纯色板换色。 + +## 指标与验收 + +功能验收: + +- “界面皮肤”在设置入口和页面主标题中完成改名。 +- 用户可以选择三类主题,而不是面对一堆颜色皮肤。 +- 选择主题后刷新页面仍保持选中态。 +- 企业沉稳主题下,AI 模式整体视觉明显更接近企业 SaaS。 +- 动感活泼主题不丢失现有活力风格。 +- 专业智能主题具备独立视觉边界。 + +设计验收: + +- 企业沉稳主题下不出现大面积高饱和渐变背景。 +- AI 对话图标和卡片不依赖强发光、强阴影或多彩背景表达层级。 +- 风险、审批、单据、工具调用等业务信息优先使用结构化排版。 +- 主题卡片文字不溢出,不在移动端产生拥挤或重叠。 + +工程验收: + +- 不新增前端依赖。 +- 不引入后端表结构迁移。 +- 旧主题值有明确兼容策略。 +- 相关测试、构建和真实页面验收通过。 + +## 风险与开放问题 + +第三类主题默认命名为“专业智能”。如果后续用户指定更贴合业务的名称,可以只替换展示文案,不影响主题值和实现结构。 + +仅靠全局 CSS 变量可能无法完全消除 AI 模式的活泼感。企业沉稳主题需要对 AI 模式局部样式做有针对性的覆写。 + +旧色板值如果直接隐藏,可能让已有用户困惑。首期需要在兼容层处理旧值,并保证保存一次后落到新的三类主题值。 + +如果后续需要租户品牌色和主题组合,应该把“主题模式”和“品牌主色”拆成两个独立配置,避免再次把体验风格退化成颜色选择。 + +## 本轮文档记录 + +本轮已完成主题设置功能的前端实现:系统设置入口改名为“主题设置”,主题选项收敛为“动感活泼 / 企业沉稳 / 专业智能”三类,并通过主题归一化兼容旧色板值。 + +企业沉稳主题已联动 AI 工作台样式:根节点写入 `data-theme-mode="enterprise"`,AI 模式背景、图标容器、输入框、消息、思考过程和建议动作改为低饱和、轻描边、少渲染的企业 SaaS 风格。 diff --git a/document/development/2026-06-25/feature/theme-settings-enterprise-ai-style/TODO.md b/document/development/2026-06-25/feature/theme-settings-enterprise-ai-style/TODO.md new file mode 100644 index 0000000..cada1ae --- /dev/null +++ b/document/development/2026-06-25/feature/theme-settings-enterprise-ai-style/TODO.md @@ -0,0 +1,69 @@ +# 主题设置与企业沉稳 AI 模式 开发 TODO + +更新时间:2026-06-25 + +文档路径:document/development/2026-06-25/feature/theme-settings-enterprise-ai-style/TODO.md + +## 使用规则 + +- 每个任务都需要关联 `CONCEPT.md` 中的章节,格式为 `[CONCEPT: 章节名]`。 +- 完成实现后再勾选对应任务,不用文档勾选代替代码验证。 +- 涉及真实页面效果的任务,需要在 5173 页面完成验收后再标记完成。 + +## 1. 调研与边界 + +- [x] [CONCEPT: 背景与问题] 确认当前设置外观入口仍使用“界面皮肤”语义,后续需要改为“主题设置”。 +- [x] [CONCEPT: 方案设计] 确认当前主题能力主要依赖 `appearanceForm.themeSkin`、主题选项和根节点 dataset。 +- [x] [CONCEPT: 方案设计] 确认企业沉稳 AI 模式主要需要覆写 `personal-workbench-ai-mode.css` 中的背景、对话、图标和提示块样式。 +- [x] [CONCEPT: 风险与开放问题] 梳理旧色板值到三类主题值的完整映射清单。 +- [x] [CONCEPT: 用户与场景] 确认三类主题在设置页中的展示顺序和说明文案。 + +## 2. 契约与设计 + +- [x] [CONCEPT: 功能能力] 将主题枚举收敛为 `vivid`、`enterprise`、`intelligent`。 +- [x] [CONCEPT: 功能能力] 明确三类主题的中文名称、适用场景和视觉关键词。 +- [x] [CONCEPT: 方案设计] 设计 `normalizeThemeMode` 兼容函数,保证旧值和未知值都有稳定回退。 +- [x] [CONCEPT: 方案设计] 决定是否新增 `themeMode` 前端概念,并保持与 `themeSkin` 字段兼容。 +- [x] [CONCEPT: 指标与验收] 定义企业沉稳 AI 模式的视觉验收标准。 + +## 3. 后端实现 + +- [x] [CONCEPT: 方案设计] 评估后端 settings schema 是否需要补充主题枚举校验。 +- [x] [CONCEPT: 方案设计] 若继续复用 `themeSkin`,确保后端允许新主题值保存。 +- [ ] [CONCEPT: 测试方案] 补充或更新设置持久化测试,覆盖三类主题值。 +- [x] [CONCEPT: 风险与开放问题] 确认不需要数据库结构迁移,并在实现说明中记录。 + +## 4. 算法/规则实现 + +- [x] [CONCEPT: 算法与公式] 实现旧主题值到新主题值的 normalize 逻辑。 +- [x] [CONCEPT: 算法与公式] 为未知值设置默认回退策略,优先回退到“企业沉稳”。 +- [x] [CONCEPT: 算法与公式] 确保本地缓存、后端返回值和根节点 dataset 使用同一套归一化结果。 + +## 5. 前端实现 + +- [x] [CONCEPT: 功能能力] 将设置左侧菜单“界面皮肤”改为“主题设置”。 +- [x] [CONCEPT: 功能能力] 将页面标题改为“主题风格与界面体验”。 +- [x] [CONCEPT: 功能能力] 将保存反馈和说明文案从“皮肤”语义调整为“主题”语义。 +- [x] [CONCEPT: 功能能力] 将原色板式选项调整为三类主题卡片。 +- [x] [CONCEPT: 功能能力] 为“动感活泼”保留当前视觉风格。 +- [x] [CONCEPT: 方案设计] 为“企业沉稳”新增 AI 模式样式覆写。 +- [x] [CONCEPT: 方案设计] 为“专业智能”新增介于活泼和沉稳之间的样式边界。 +- [x] [CONCEPT: 指标与验收] 检查主题卡片、按钮和说明文字在移动端不溢出、不重叠。 +- [x] [CONCEPT: 方案设计] 保证刷新页面后主题选择和 AI 模式样式仍然一致。 + +## 6. 测试与验证 + +- [x] [CONCEPT: 测试方案] 更新设置页相关前端测试,断言“主题设置”和三类主题选项。 +- [x] [CONCEPT: 测试方案] 补充 normalize 逻辑测试,覆盖旧值、未知值和三类新值。 +- [x] [CONCEPT: 测试方案] 补充 AI 模式企业沉稳 CSS 钩子测试或静态断言。 +- [x] [CONCEPT: 测试方案] 运行前端设置相关定向测试。 +- [x] [CONCEPT: 测试方案] 运行 `npm --prefix web run build`。 +- [x] [CONCEPT: 测试方案] 运行 `git diff --check`。 +- [x] [CONCEPT: 测试方案] 在真实 5173 页面验收 `/app/settings?section=appearance`。 +- [ ] [CONCEPT: 测试方案] 在真实 5173 页面验收 AI 工作台三类主题切换效果。 + +## 7. 文档收尾 + +- [x] [CONCEPT: 本轮文档记录] 实现完成后更新本文勾选状态。 +- [x] [CONCEPT: 指标与验收] 在最终交付说明中记录测试、构建和真实页面验收结果。 +- [ ] [CONCEPT: 风险与开放问题] 若第三类主题命名发生变化,同步更新概念文档和测试描述。 diff --git a/document/development/2026-06-26/dev-logs/bugs/multi-task-reimbursement-not-starting.md b/document/development/2026-06-26/dev-logs/bugs/multi-task-reimbursement-not-starting.md new file mode 100644 index 0000000..5501b84 --- /dev/null +++ b/document/development/2026-06-26/dev-logs/bugs/multi-task-reimbursement-not-starting.md @@ -0,0 +1,30 @@ +# 多 task 串行推进时 task2(业务招待费报销)无法启动 + +## 修复记录 + +- 12:14:记录 bug 修复:多 task 串行推进时,task1(出差申请)做完后点击"继续处理费用报销",task2(业务招待费报销)根本无法启动,报销草稿交互不起来,task2 语义(招待费/2000元/昨天)全部丢失。 + - Git 提交检查:`git fetch --all --prune` 因远端 SSL 连接失败未拉到新内容;`HEAD..@{u}` 为空(无 upstream 新提交);`@{u}..HEAD` 本地领先 8 个提交,其中与本 bug 相关的前置提交为 `3a5664c4 feat(web): 多 task 串行推进`、`3e4b1e15 fix(web): 保存草稿/提交成功后也推进到下一个 task`、`43c3ff86 fix(web): steward plan 确认按钮直接拉起申请预览,不丢失 remaining tasks`。 + - 修改: + - `web/src/composables/workbenchAiMode/useWorkbenchAiActionRouter.js`:`travel_reimbursement` 分支不再硬编码 `requiresApplicationBeforeReimbursement=true`,改为从 `steward_current_task.ontology_fields` 解析费用类型并调 `requiresApplicationBeforeReimbursement(expenseType)` 判断;用 `buildAiExpenseDraftPrefillValues` 把 task 语义(金额/时间/事由/地点)预填进报销草稿;透传 `steward_remaining_tasks`。`ai_application_start_inline` 分支也透传 `prefill_values` 和 `steward_remaining_tasks`,让"查不到申请单→发起申请单"后能回到 task2。`buildNextTaskSuggestedAction` payload 补 `steward_remaining_tasks: remainingTasks.slice(1)`,防 3+ task 断链。 + - `web/src/composables/workbenchAiMode/useWorkbenchAiExpenseFlow.js`:`startAiExpenseDraft` 扩展第 4 参 `options`(`prefillValues`/`stewardRemainingTasks`);`resolveAiExpenseApplicationLink` 接收 options,查不到申请单时按费用类型动态生成"确认发起业务招待申请"按钮(不再写死"出差申请"),并透传 `prefill_values`/`steward_remaining_tasks`;新增 `attachStewardRemainingTasks`/`resolveStewardRemainingTasks`/`resolveRequiredApplicationLabel`/`buildExpenseDraftNextTaskAction` helper,把 remaining tasks 上下文挂在 draft 上贯穿报销→关联申请单→pollLinkedDraftJob 全流程;`advanceAiExpenseDraft`、`linkAiExpenseApplication`、`replaceInlineAssistantMessage`、`resumePendingLinkedReimbursementDraftJobs` 均补 remaining tasks 透传。 + - `web/src/composables/workbenchAiMode/useWorkbenchAiApplicationPreviewFlow.js`:`buildApplicationPreviewNextTaskAction` payload 补 `steward_remaining_tasks: remainingTasks.slice(1)`。 + - `web/src/utils/aiExpenseDraftModel.js`:`createAiExpenseDraft` 新增第三参 `prefillValues`,按已填值推进 `stepKey` 到第一个未填字段;新增 `buildAiExpenseDraftPrefillValues` 把 task ontology 映射到草稿字段。 + - `web/src/composables/workbenchAiMode/workbenchAiMessageModel.js`:`createInlineMessage`/`normalizeRuntimeMessage`/`serializeRuntimeMessage` 三处补 `stewardRemainingTasks` 字段读写,避免消息重建/刷新丢失推进上下文。 + - `web/src/utils/aiWorkbenchConversationStore.js`:`normalizeMessage` 持久化时保留 `stewardRemainingTasks`。 + - 操作:未提交(工作区有大量预先存在的未提交改动,未自动提交)。容器 `local-x-financial-linux` 此前未运行,已 `docker start` 恢复。 + - 验证:在容器内(node v22.22.3)跑 `node --test tests/ai-expense-draft-model.test.mjs tests/ai-workbench-conversation-store.test.mjs tests/workbench-ai-action-router.test.mjs`,16 个测试全部通过(含新增的 `buildAiExpenseDraftPrefillValues`、`createAiExpenseDraft` 预填、`stewardRemainingTasks` 持久化、`travel_reimbursement` 分支预填+透传 4 个用例)。其余前端测试失败为基线已存在(git stash 对比确认,与本次改动无关,多为正则匹配源码文本的断言因工作区其他未提交改动而失败)。 + - 影响:用户一次提问含"出差申请 + 招待费报销"等多 task 时,task1 完成后 task2 现在能正常启动:招待费类型、2000元金额、时间、事由会预填到报销草稿;招待费需要前置招待申请单(业务规则保留),查不到时按钮文案按类型动态展示并承接语义,发起申请单后能回到 task2;3+ task 不再断链;刷新会话后推进上下文不丢失。 + +- 12:23:继续修复同一 bug:模型计划已经返回“出差申请 + 业务招待费报销”两个 task 时,AI 工作台入口只消费第一个申请 task,第二个 task 没有自动开始。 + - Git 提交检查:`git fetch --all --prune` 仍因 `LibreSSL SSL_connect: SSL_ERROR_SYSCALL` 失败;`HEAD..@{u}` 为空,未发现可见 upstream 新提交;`@{u}..HEAD` 本地领先 8 个提交:`43c3ff86 fix(web): steward plan 确认按钮直接拉起申请预览,不丢失 remaining tasks`、`3e4b1e15 fix(web): 保存草稿/提交成功后也推进到下一个 task`、`3a5664c4 feat(web): 多 task 串行推进 - task1 完成后自动展示 task2 确认按钮`、`d139a63e refactor(server): 意图识别改 LLM 驱动,规则只做闲聊拦截+resume 兜底`、`8a2ae6eb fix(server): gate_classify 复用 _classify_irrelevant_input 修复 off_topic 误杀`、`992cf71f refactor(server): Phase 1 图拓扑重构 - LangGraph 成为唯一编排者`、`54356ba8 refactor(server): scene 注册表骨架 + 统一门控管道设计文档`、`e9d7c56d feat(server): 会话上下文保留(LLM 历史 + 确定性兜底双保险)`。 + - 修改:`workbenchAiIntentPlannerModel.js` 在归一化模型计划时保留 application task 后面的 `stewardRemainingTasks`,并只在存在剩余 task 时放进可执行申请请求;`usePersonalWorkbenchAiMode.js` 把 remaining tasks 传入申请预览,并在预览生成后通过现有 `steward_continue_next_task` 路由自动启动下一个 task;低置信确认按钮 payload 也继续携带队列;`useWorkbenchAiApplicationPreviewFlow.js` 在普通申请预览完成后调用 `onPreviewReadyForNextTask`;`useWorkbenchAiActionRouter.js` 的 `ai_application_confirm_intent` 分支同样透传 remaining tasks 并注册自动续跑回调。 + - 操作:新增回归测试覆盖“模型返回申请 task + 业务招待报销 task 时,前端可执行请求保留第二个 task”,以及“低置信确认按钮不丢队列并提供自动续跑回调”;保留既有未提交工作区改动,没有回滚或提交其他文件。 + - 验证:先看到新增测试红灯(`plan.stewardRemainingTasks` 为 `undefined`,确认按钮 options 也没有 remaining tasks),修复后 `node --test web/tests/workbench-ai-intent-planner-model.test.mjs web/tests/workbench-ai-action-router.test.mjs` 通过 24/24;`git diff --check` 通过;`docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv x-financial-local-linux timeout 60s /tmp/x-financial-server-venv/bin/pytest -q server/tests/test_steward_planner.py -k 'future_travel_without_apply_word_as_application or uses_llm_for_multi_financial_demands'` 通过 2/2;同命令在 `local-x-financial-linux` 收集阶段因该容器缺 `langgraph` 失败,已改用当前映射 5173 的 `x-financial-local-linux` 验证;`npm --prefix web run build` 通过;真实 `http://localhost:5173/api/v1/steward/plans` 采样确认该用户句子返回 `expense_application` 与 `reimbursement` 两个 task。 + - 影响:用户输入“2月20-23日去上海出差3天,服务国网服务器部署,并且报销昨天的业务招待费2000元”时,前端不再在第一个申请预览处截断队列;申请预览生成后会自动把第二个业务招待费报销 task 交给现有报销流程继续处理,同时刷新/低置信确认路径也不丢 task 队列。 + +- 22:30:继续修复同一 bug:用户点击“保存草稿”后,task1 已经完成,但界面仍只展示“继续处理费用报销”按钮,没有自动开始 task2。 + - Git 提交检查:`git fetch --all --prune` 仍因 `LibreSSL SSL_connect: SSL_ERROR_SYSCALL` 失败;`HEAD..@{u}` 为空,未发现可见 upstream 新提交;`@{u}..HEAD` 本地仍领先 8 个提交:`43c3ff86`、`3e4b1e15`、`3a5664c4`、`d139a63e`、`8a2ae6eb`、`992cf71f`、`54356ba8`、`e9d7c56d`。 + - 修改:`useWorkbenchAiApplicationPreviewFlow.js` 在保存草稿/提交申请成功后,如果当前申请消息还有 `stewardRemainingTasks`,就调用 `onApplicationActionCompleted` 自动续跑下一项;自动续跑时结果消息只保留查看详情动作,不再额外保留“继续处理”按钮,避免重复触发同一个 task。`usePersonalWorkbenchAiMode.js` 将该回调接到 `startModelPlannedNextTask`;`useWorkbenchAiActionRouter.js` 的低置信确认路径也同步传入保存/提交成功回调。 + - 操作:先补红灯断言,要求工作台入口向申请预览流传 `onApplicationActionCompleted`,且申请预览流在保存/提交成功分支调用该回调;然后按同一条 `steward_continue_next_task` 路由复用原有报销启动逻辑。 + - 验证:红灯阶段 `node --test web/tests/workbench-ai-intent-planner-model.test.mjs` 失败在缺少 `onApplicationActionCompleted`;修复后 `node --test web/tests/workbench-ai-intent-planner-model.test.mjs` 17/17 通过,`node --test web/tests/workbench-ai-action-router.test.mjs` 7/7 通过;`git diff --check` 通过;`npm --prefix web run build` 通过。 + - 影响:复合任务里用户保存第一张出差申请草稿后,系统会立即进入第二个业务招待费报销任务,不再要求用户手动点击“继续处理费用报销”;低置信确认后再保存草稿也保持同样行为。 diff --git a/document/development/2026-06-26/work-logs.med b/document/development/2026-06-26/work-logs.med new file mode 100644 index 0000000..c9e42b5 --- /dev/null +++ b/document/development/2026-06-26/work-logs.med @@ -0,0 +1,17 @@ +# 2026-06-26 综合工作日志 + +生成时间:2026-06-26 17:45:36 CST +来源:`feature/` 功能点文档与 `dev-logs/bugs/` bug 记录 + +## 今日功能点 + +- 今日未发现功能点文档。 + +## 今日 Bugs + +- 多 task 串行推进时 task2(业务招待费报销)无法启动:影响:用户输入“2月20-23日去上海出差3天,服务国网服务器部署,并且报销昨天的业务招待费2000元”时,前端不再在第一个申请预览处截断队列;申请预览生成后会自动把第二个业务招待费报销 task 交给现有报销流程继续处理,同时刷新/低置信确认路径也不丢 task 队列。(文件:`multi-task-reimbursement-not-starting.md`) + +## 综合分析 + +- 问题侧记录了 1 个 bug 修复。 +- 后续复盘优先看本文件,再回到对应功能点或 bug 文件追溯证据。 diff --git a/server/rules/finance-rules/交通工具等级标准.xlsx b/server/rules/finance-rules/交通工具等级标准.xlsx index eeaa256..96336f4 100644 Binary files a/server/rules/finance-rules/交通工具等级标准.xlsx and b/server/rules/finance-rules/交通工具等级标准.xlsx differ diff --git a/server/rules/finance-rules/交通费用预估表.xlsx b/server/rules/finance-rules/交通费用预估表.xlsx index 1f68163..36acf72 100644 Binary files a/server/rules/finance-rules/交通费用预估表.xlsx and b/server/rules/finance-rules/交通费用预估表.xlsx differ diff --git a/server/rules/finance-rules/公司通信费报销规则.xlsx b/server/rules/finance-rules/公司通信费报销规则.xlsx index afd075c..13dd126 100644 Binary files a/server/rules/finance-rules/公司通信费报销规则.xlsx and b/server/rules/finance-rules/公司通信费报销规则.xlsx differ diff --git a/server/rules/finance-rules/出差补助标准.xlsx b/server/rules/finance-rules/出差补助标准.xlsx index e3a1667..6f356e8 100644 Binary files a/server/rules/finance-rules/出差补助标准.xlsx and b/server/rules/finance-rules/出差补助标准.xlsx differ diff --git a/server/rules/finance-rules/地区淡旺季映射表.xlsx b/server/rules/finance-rules/地区淡旺季映射表.xlsx index c2f03ee..a1f9de3 100644 Binary files a/server/rules/finance-rules/地区淡旺季映射表.xlsx and b/server/rules/finance-rules/地区淡旺季映射表.xlsx differ diff --git a/server/rules/finance-rules/差旅职级映射表.xlsx b/server/rules/finance-rules/差旅职级映射表.xlsx index 704644d..86d4c88 100644 Binary files a/server/rules/finance-rules/差旅职级映射表.xlsx and b/server/rules/finance-rules/差旅职级映射表.xlsx differ