本页只通过本仓库的 import-http.js 调用后端真实接口:先确认预览,再入队并轮询任务状态。入队返回 202 只表示任务已受理,解析结束前一律显示“进行中”,不显示“已完成”。
会话状态:尚未确认(页面加载后会先恢复已有会话,未确认前不会发出任何写请求)。
第零步:上传源文件(POST /api/v1/imports/files 已接线)
尚未选择文件。选择后点击“上传文件”才会发出上传请求;上传成功会把返回的 file_id 填入下面的批次引用。
尚未选择文件:请选择 CSV 文件后再确认预览。
只支持 .csv(扩展名不区分大小写)。Excel(.xlsx/.xls)暂不支持,待解析实现后开放:选中 Excel 时会明确提示并且不会把文件当作 CSV 发出。请求体严格为 {original_name, content_base64}(JSON);需要会话 Cookie、X-CSRF-Token 与合法 Origin。服务端已有相同内容时返回 200 复用既有 file_id;空文件、超过 262144 字节或内容非法返回 422。上传成功后会点击“开始导入”进入既有建批与轮询流程。
批次引用(照实填写,agency 由会话决定)
请求体只包含 case_id、file_id、mapping_rule_id、mapping_rule_version 四项;客户端不传 agency_id(会话决定代理范围),传了会被后端按 422 拒绝。
请求摘要(非加密指纹):批次引用未填写完整,暂不生成。
第一步:确认并开始导入
尚未创建批次。
尚未入队。
状态用文字表达
状态一律以文字显示,不依赖颜色:尚未选择文件 / 待确认预览 / 进行中(含任务标识)/ 已完成 / 失败(含状态与错误码)/ 未知状态(立即停止轮询)/ 超时(未确认成功)。
请求互斥:同一时间只允许一个进行中的导入;请求进行中时“开始导入”“重新选择”与文件选择均不可用。
已知缺口与联调状态(未验收项不得宣称可用)
一、批次创建已接线:POST /api/v1/imports(201 → batch_id + state),随后 POST /api/v1/imports/{batch_id}/jobs 入队并轮询状态。case_id 与 file_id 必须引用后端已存在的预算案件与源文件;file_id 由本页「第零步」上传源文件取得(POST /api/v1/imports/files 已接线),无需外部登记流程。
二、CSRF 令牌交接:已由 imports-session.js 完成交接(页面加载时先恢复已有会话,成功后页面即取得令牌并交给写请求)。若会话恢复失败或未取得令牌,本页按失败显示并在本地阻止写请求,不会伪装成功。
三、端到端联调:成功路径已在真实浏览器(Chrome 153.0.8010.36,headless)+ 真实后端进程 + 临时 PostgreSQL + 全部虚构数据上跑通端到端联调(登录 200 → 会话徽标确认 → 进入本页 → 会话/CSRF 交接成功 → 本地 CSV 预览未发请求 → POST /api/v1/imports 201 → POST /api/v1/imports/{batch_id}/jobs 202 → 轮询 GET /api/v1/import-jobs/{job_id} 200(done,attempts=1)→ GET /api/v1/imports/{batch_id}/result 200(row_count=1))。仍未验收:视觉/布局渲染、失败与重试分支、打包启动链、真实表格解析。
导入结果(GET /api/v1/imports/{batch_id}/result)
尚未读取导入结果:批次导入任务结束后,本页会读取该批次的结果。
上传内容回显(只读,GET /api/v1/imports/{batch_id}/echo)
本区为只读回显:不做任何计算、不写回、不发起任何写请求(仅一次只读 GET,且仅在点击按钮或显式调用时发出)。金额一律按后端原文展示;a_path_values 为 null 时显示「暂无 A 路径填写」,不以 0、空字符串或空表代替;未解析 sheet 归入「代理上传项」仅回显,不解析业务含义;echo_state 非 ok 时如实提示,不假装成功。
echo_state:尚未读取
列组声明(agency_column_groups)
代理上报 12 行(按 line_label / column_group 分组,展示 original_text 原文)
预算核对行(budget_check_rows)
A 路径值(a_path_values)
代理上传项(未解析 sheet,仅回显)
金额按后端返回的字符串原样显示,不做数字转换、不补零;所有动态值只用 textContent 写入。
整本工作簿上传(H1)
上传整本 .xlsx(POST /api/v1/imports/workbooks,请求体 {original_name, content_base64, fiscal_year, n_months})。顺序:会话 401 → Origin/CSRF 403 → 上传缝 503 → 上传前全量校验(任一硬失败 ⇒ 422:整份被拒绝、未落库;软提示只提示、不阻断)。未解析 sheet 仅存档回显,本页不解析其业务含义;本页不做任何金额换算。
校验结果(拒绝原因逐条)
通过项
软提示(不阻断)
软提示来自后端 outcome.soft(如 DUPLICATE_FILE / TOTAL_MISMATCH):只提示、**不阻断**上传,与上方硬失败拒绝原因分开展示;不做任何业务解释与金额换算。