8.6 KiB
8.6 KiB
last_reviewed
| last_reviewed |
|---|
| 2026-06-16 |
src/web/static/js — 前端逻辑模块
概述
财务报销自动化系统的前端入口脚本,按功能拆分为多个模块文件,通过 App 共享状态对象通信。采用原生 JavaScript 编写,通过 HTTP 请求与 Flask 后端通信,使用 SSE 接收处理进度。
文件结构
| 文件 | 职责 |
|---|---|
state.js |
全局状态管理 (App 对象,含处理状态机) |
utils.js |
工具函数 (HTML 转义、会话管理) |
chat.js |
聊天窗口消息管理(含文件消息、处理进度、三点动画、LLM 流式气泡) |
upload.js |
文件上传(含拖拽、config.json 解析) |
config.js |
配置收集与校验(基于状态机的自动触发) |
process.js |
发票处理流程与 SSE 监听(含 file_progress、llm_stream 事件处理) |
agent.js |
Agent 交互(含 supplement 流程、强制提交、用户文字补充、自动提交) |
sync.js |
移动端同步轮询(状态感知模式) |
index.js |
入口初始化 |
加载顺序
state.js → utils.js → chat.js → upload.js → config.js → process.js → sync.js → index.js
模块依赖关系
state.js (无依赖)
│
├── utils.js ────────────────┐
│ │
├── chat.js ─────────────────┐ │
│ │ │
├── upload.js ──────────────┐ │ │
│ │ │ │
├── config.js ─────────────┐ │ │ │
│ │ │ │ │
├── process.js ───────────┐ │ │ │ │
│ │ │ │ │ │
├── sync.js ──────────┐ │ │ │ │ │
│ │ │ │ │ │ │
└── index.js ────────┘ │ │ │ │ │ │
处理状态机
App.processState 控制何时触发自动处理,避免重复执行:
stateDiagram-v2
[*] --> idle
idle --> processing: 配置完整 + 有文件
processing --> done: 处理完成
processing --> awaiting_supplement: Agent 要求补充材料
done --> idle: 有新文件 / forceStart = true
done --> done: 无新文件(保持,不重复)
awaiting_supplement --> idle: 用户补充文件(只上传新文件)
idle --> processing: idle + newFilenames > 0(走 supplement 流程)
idle --> awaiting_files: AI 判断文件不足(未来功能)
awaiting_files --> idle: 用户补充文件
awaiting_files --> processing: 用户说"直接开始" (forceStart = true)
状态字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
processState |
string | 当前处理状态:idle / processing / done / awaiting_files / awaiting_supplement |
lastProcessedFileCount |
number | 上次处理时的文件数,用于检测是否有新文件 |
forceStart |
boolean | 用户强制开始标记(兼容"文件不足也要处理"的场景) |
newFilenames |
array | 待补充上传的文件名列表,用于区分首次处理和补充处理 |
核心流程
1. 文件上传
用户上传文件 → addFileMessage() → 注册到 App.fileMessageMap → promptMissingConfig()
→ processState 为 done 时重置为 idle(支持增量上传后重新处理)
2. 配置收集
promptMissingConfig() → 检查 CONFIG_FIELDS → 有缺失则提示 → 用户输入 → sendUserMessage() → 递归直到完整
3. 自动触发检查 (checkAutoStart)
checkAutoStart() → 状态机判断:
- processing → 跳过
- done + 无新文件 → 跳过(修复重复执行问题)
- done + 有新文件 → 走 supplement 流程(不再走 startProcess)
- idle + newFilenames > 0 → 走 supplement 流程
- idle + 配置完整 + 有文件 → 走 startProcess(首次处理)
- awaiting_files + forceStart → 触发
4. 发票处理(首次)
startProcess() → ensureSession → 上传全部文件 → /api/agent/process → SSE 监听
→ 收到 file_progress(processing) → setFileProcessing()(三点动画)
→ 收到 file_progress(done) → setFileDone()(展示提取摘要)
→ 收到 file_progress(cached) → setFileCached()
→ 收到 file_progress(error) → setFileError()
→ 收到 llm_stream(start) → handleLLMStream() 创建流式气泡
→ 收到 llm_stream(chunk) → handleLLMStream() 逐字追加 AI 输出
→ 收到 llm_stream(end) → handleLLMStream() 关闭流式气泡
→ 收到 done → 设置 processState = 'done' + 记录文件数 → 显示汇总结果
5. 补充文件处理(新增)
当 Agent 返回 awaiting_supplement 状态时,用户补充文件的流程:
用户上传补充文件
→ handleFiles() 检测 processState === 'awaiting_supplement'
→ _uploadNewFiles() 只上传新文件(不再重新上传所有文件)
→ App.newFilenames = [新文件名列表]
→ App.processState = 'idle'
→ syncFiles() 3 秒后触发 checkAutoStart()
→ checkAutoStart() 检测到 idle + newFilenames > 0
→ handleSupplementUpload(filenames)
→ POST /api/agent/supplement/(后端会重新 extract_invoices,旧文件走缓存)
→ 新文件走 LLM 提取,旧文件命中 JSON 缓存直接返回
→ run_agent_round() 重新分析
→ SSE 返回 done → 根据结果进入 awaiting_supplement 或 done 状态
关键区别:补充文件走 /api/agent/supplement/ 而非 /api/agent/process/,后者在已有 agent_session 时会跳过提取阶段。
数据流
配置数据流
config.json → parseConfigFile → App.sessionConfig → startProcess → /api/agent/process
发票数据流(首次处理)
发票文件 → startProcess → /api/upload → /api/agent/process → SSE file_events.log → 文件消息实时更新
发票数据流(补充文件)
新发票文件 → _uploadNewFiles() → /api/upload → /api/agent/supplement
→ extract_invoices()(旧文件走缓存,新文件走 LLM)
→ run_agent_round() → SSE file_events.log → 文件消息实时更新
文件消息状态机
addFileMessage(filename)
→ file_progress(processing) → 三点动画(同一行)
→ file_progress(done/cached/error) → 详情展开 + 状态图标
变更记录
- 2026-06-16:修复补充文件重复上传问题 — 新增
newFilenames状态字段,补充文件时只上传新文件并走/api/agent/supplement/接口。upload.js新增_uploadNewFiles()辅助函数。config.js的checkAutoStart()在done和idle状态下有newFilenames时走 supplement 流程而非startProcess() - 2026-06-16:新增 LLM 流式思考展示 —
chat.js新增handleLLMStream状态机(start/chunk/end/error 四阶段),process.js的 SSE 监听增加llm_stream事件分支,AI 思考过程以聊天气泡逐字展示 - 2026-06-16:引入处理状态机 — 新增
processState/lastProcessedFileCount/forceStart状态字段,修复syncFiles轮询每 3 秒重复触发处理的 bug。checkAutoStart改为基于状态机判断,done 状态下只有检测到新文件才重新触发。为未来 AI 判断文件是否充足预留了awaiting_files状态和forceStart标记 - 2026-06-12:上传区域可折叠 — 新增
toggleUploadPanel()函数,配合 CSSmax-height动画实现面板收起/展开 - 2026-06-12:文件消息框对齐到用户侧 —
addFileMessage的 wrapper 新增user类,上传的文件消息显示在右侧(用户侧),与 agent 消息区分 - 2026-06-12:配置完成增加互动提示 —
promptMissingConfig在配置完整时发送系统消息告知用户即将开始处理发票 - 2026-06-14:新增文件进度实时反馈 — 后端 extractor 在每处理一个文件时产生 SSE 进度事件,前端根据文件名定位 DOM 并更新状态(处理中三点动画、完成摘要展示、缓存/错误状态)
- 2026-06-14:移除发票编辑和财务提交流程 — 删除 table.js、financial.js 及相关 HTML 区域,后续开发不再支持手动编辑发票信息
- 2026-06-12:模块拆分重构 — 将 index.js (625 行) 拆分为 10 个独立模块,引入
App共享状态对象 - 2026-06-12:修复配置收集流程的异步时序问题 — parseConfigFile 改为 Promise,拆分 checkAutoStart 为静默检查/配置提示两个函数