11 KiB
采购订单生成与审批检查
本报告记录的是修复前提交
4876d88。随后已按建议修改本地 v2 源码;当前运行规则和升级步骤见 运行与升级说明,验证结果见该文档末尾。
检查日期:2026-09-16。分支:master。远端和本地提交均为 4876d8805d029702be92ec397bc5e9d6c9c25503,最新提交时间为 2026-09-10 16:57 +0800。
目前是可以演示完整流程的初版。普通订单能生成、提交、两级审批并导出 PDF;正式多人使用前,仍需解决身份认证、数据权限、审批职责、金额一致性和事务恢复问题。
本次没有修改业务源码。使用 Flask test client 在 tools/out/ 下复制代码、创建独立数据库进行验证,未向正式服务提交数据。审查脚本为 tools/out/review_probe.py,本次结果在 tools/out/audit_geghi4ic/results.json。这些测试文件被现有 .gitignore 排除。
已验证通过的基础能力
- 采购单 3 行、委外生产订单 30 行,均能完成草稿 → 待主管审核 → 待经理批准 → 已批准。
- 主管和经理未提交盖章确认标记时,接口拒绝通过;普通制单员不能调用通过接口。
- 审批动作会生成记录;已批准订单通过编辑接口修改会被拒绝。
- 草稿 PDF 有水印,已批准 PDF 无水印;采购样本 1 页,委外样本 3 页,有重复明细表头、签署信息和图形印章。
- 英文文件名的标准 XLSX 明细能导入。
这些结果只证明对应样本通过,不能作为所有边界情况、多人并发或正式签章有效性的验收结论。
P0:正式使用前必须解决
1. 固定会话密钥可导致冒充管理员【已复现】
位置:po_app/app.py:40、:52。
会话签名密钥写在源码里。隔离测试使用该密钥签出的管理员会话,在未输入管理员密码的情况下成功访问 /users。仅修改默认密码不能解决这个问题。
修复方向:每个部署使用独立的随机密钥并外置保存,轮换现有密钥、使旧会话失效;上线初始化强制设置密码。
2. 订单权限只过滤了列表,详情和导出仍越权【已复现】
位置:po_app/app.py:326、:435、:473、:1010、:1034。
第二个制单员在列表看不到第一个制单员的订单,但直接访问订单 ID 能查看详情、导出 PDF、复制为自己的订单;导出台账还能得到其他人的订单。导出文件下载入口也仅检查是否登录。
修复方向:明确谁可看哪些订单,统一检查详情、编辑读取、复制、PDF、台账、统计、历史文件的权限。
3. 一个数据库错误会影响其他用户继续操作【已复现;并发风险为代码检查】
位置:po_app/app.py:44、:966、:1071。
所有请求共用一个数据库 Session。新增重名用户触发 IntegrityError 后没有回滚,另一个用户打开订单列表随即触发 PendingRollbackError。此时实际网页请求会报错,需要恢复会话或重启服务。服务还启用了多线程,共用 Session 带来的并发事务风险尚未经过压力测试。
修复方向:每请求独立 Session,结束时关闭,异常时回滚;对唯一性冲突提供明确提示。
P1:直接影响制单与审批正确性
4. 审批职责和环节限制不完整【已复现】
位置:po_app/app.py:89、:265、:360、:382、:403。
- 主管账号可以新建、编辑、提交订单,再审核自己制作的订单。
- 经理可以在主管审核前驳回;主管可以驳回已经进入经理批准环节的订单。
- 管理员可执行全部环节是现有设计;如果公司要求制单、审核、批准分人,应显式限制并规定例外操作。
修复方向:服务端同时校验操作角色、当前环节、制单人和前一审批人;新建及复制权限也需一致。
5. 必填内容和明细数值未有效校验【已复现】
位置:po_app/app.py:132、:297、:339、:488。
提交只判断是否存在明细行。本次以下单据均走到“已批准”:
| 输入 | 实际结果 |
|---|---|
| 供应商为空,数量 -2,单价 10 | 批准金额 -20 元 |
数量为 abc |
静默变成 0,批准金额 0 元 |
| 单价为 0 | 无异常提示,批准金额 0 元 |
修复方向:按业务规则验证供应商、有效明细、数量、价格、日期及必要的结算信息;非法数字不得静默归零。零价是否允许应有明确业务规则。
6. 页面金额、保存金额与 PDF 单价不一致【已复现】
位置:po_app/templates/order_edit.html:158、po_app/app.py:118、po_app/pdf_export.py:288、po_app/models.py:134。
- 两行“数量 1、单价 0.334”:页面每行 0.33,页面合计 0.67;保存后合计 0.66。前端先累加原始乘积,后端先将每行金额保留两位。
- “数量 3、单价 0.3333”:金额为 1.00,但 PDF 把单价显示为 0.33,读者按打印内容只能算出 0.99。订单详情也将单价限制为两位。
- 金额与单价采用浮点数,舍入规则没有形成统一业务定义。
修复方向:统一定点金额、单价精度和舍入规则,前端、后端及导出使用相同口径,并明确展示价格精度。
7. 编辑后直接“提交审核”会提交旧数据【代码确认,未做浏览器点击测试】
位置:po_app/templates/order_edit.html:7、:116;po_app/app.py:339。
保存订单与提交审核是两个独立表单。已有明细的订单在页面修改价格、供应商等内容后,不先点保存而直接点“提交主管审核”,请求只携带提交说明,服务端提交的是数据库中的旧内容。首次填写尚未保存时则被当成明细为空。
修复方向:提供原子性的“保存并提交”,或检测未保存更改并阻止提交;跳转预览和导入时也应处理未保存内容。
8. 中文 Excel 文件名及日期类型处理有缺陷【已复现】
位置:po_app/app.py:498、:527、:536;po_app/templates/order_edit.html:72。
- 相同内容使用
items.xlsx导入成功,改名为采购明细.xlsx导入失败。文件名清理后丢失可识别的扩展名,解析器选择错误。 - XLSX 原生日期单元格被保存为
2026-10-01 00:00:00;编辑页的日期控件要求日期格式,两者不匹配,存在编辑保存时清空交期的风险。已验证数据库值;未用浏览器验证最终清空行为。 - 供应商和物料导入使用相同文件名处理方式,存在同类问题,未逐个进行接口复测。
修复方向:服务器生成独立文件名并保留已验证的扩展名;统一规范日期格式,并为 XLS 日期序号单独处理。
9. 用户维护不完整,停用不能立即终止旧会话【部分已复现,部分代码确认】
位置:po_app/templates/users.html:5、:22;po_app/app.py:52、:966。
说明文档让用户在“用户”页改默认密码,但页面只有新增和列表,没有编辑、改密码、停用入口。后端存在按 ID 修改用户的逻辑,没有设置 active 的逻辑。
隔离测试将主管 active 改为 False 后,其已登录的会话仍能审核通过;请求时只获取用户,没有重新检查 active。
修复方向:补齐用户维护与改密页面,检查账号启用状态,支持强制失效会话,并约束角色和用户名输入。
10. 单号唯一性缺乏数据库和事务保证【约束缺失已复现,实际并发未测】
位置:po_app/app.py:98;po_app/models.py:79。
编号通过读取当天最大号再加一生成,数据库没有唯一约束。隔离测试成功插入两个相同单号。并发或重复请求可能产生重复单号,但本次没有做真实并发压测,不将其表述为已复现的线上并发故障。
修复方向:单号唯一索引、事务内分配或冲突重试,以及新建/复制请求的重复提交保护。
仍需补齐或按业务确认的流程
以下是代码和数据模型中尚未具备的能力,不代表公司已经要求全部实现:
- 撤回、作废、批准后变更重审:现有状态只有草稿、待审核、待批准、已批准、已驳回。尚无提交后主动撤回及正式订单作废/修订流程。
- 审批版本追溯:现有日志记录姓名、动作、时间、意见,但没有修改前后内容、订单版本、审批内容快照和稳定的操作人 ID。驳回修改后,无法从旧审批记录还原当时审核的明细。
- 审批分派和提醒:按角色统一进入待办;没有指定主管/经理、部门、金额阈值、代理人、催办或消息通知。若仅需固定两级流程,可后置复杂审批规则。
- 正式文件归档:批准后 PDF 按当前模板重新生成,没有冻结当时的模板和文件摘要。现有“章”是根据审批状态绘制的图形,
stamped=1是确认标记;没有独立的服务端盖章凭证或文件数字签名。是否需要签章服务须按使用场景确定。 - 多人部署与恢复:源码以开发服务器方式运行,数据库位于运行电脑本地。需要确定统一服务主机、启动方式、备份恢复和升级迁移;每台电脑各运行一个 EXE 会形成各自独立的数据库。README 已提到其他电脑通过主机 IP 访问,这个部署方式应落地验证。
- 采购前置及后续流程:请购、预算、询比价、附件、供应商回签、到货和付款跟踪均不在现有实现中。若目标只到订单生成与内部审批,不必把这些全部纳入首期。
PDF 和测试的其他问题
- 已查看采购正式样本 1 页、委外正式样本 3 页、价格精度样本 1 页的渲染图。大写金额已经包含“元整”或“角/分”,模板右侧仍固定再打印“元整”,例如
壹佰壹拾贰元伍角后又出现元整。位置:po_app/pdf_export.py:314。 - 委外版规格列较窄,短规格也发生多行折行;样本合计与条款/签署分到不同页。基本可读,需按实际单据样本确定版式要求。原始 Excel 套打模板未入库,因此未验证“完全复刻原模板”。
tools/e2e_test.py:75和:78没有传目前必需的盖章标记,也未断言审批后的状态,随后直接打印“审核流程 ok”。该脚本可误报成功;部分工具仍硬编码原开发电脑路径。仓库另有盖章专项脚本,不能据此推定所有测试都失效。- 测试范围不含真实浏览器全流程、EXE 打包运行、局域网部署、压力测试及真实采购数据验收。未将既有测试脚本全部执行,因为部分脚本会操作实际运行数据库和固定外部目录。
建议修复顺序与验收标准
- 身份认证、统一数据权限、按请求管理事务:不能伪造登录或跨制单员读单,单个失败请求不影响其他用户。
- 输入校验、金额精度、保存并提交、Excel 导入、用户维护:页面、数据库和 PDF 金额一致,修改后的内容确实进入审批,中文文件和日期正常。
- 审批角色及环节约束、唯一单号、撤回/作废/版本记录:每次审批能对应明确的人、环节和单据版本。
- 修正 PDF 和自动化检查,在统一部署方式下用真实模板、常见订单和多账号并发完成验收。
完成前两步和核心审批约束后,再开展小范围试用;是否扩展预算、分部门流程和外部签章,单独按业务决定。