Files
Auto-Finance/src/web/static/js/README.md
T

8.6 KiB
Raw Blame History

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() 函数,配合 CSS max-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 为静默检查/配置提示两个函数