项目简介
为深圳市淏发工程有限公司定制的 ERP 与财务一体化系统,覆盖项目管理、合同管理、应收应付、费用报销、采购库存、基础数据等 11 个核心模块。5 人核心团队 14 周交付首版,实现了工程公司从"Excel + 微信群对账"到全流程数字化的切换。
架构决策
为什么是单体而非微服务。11 个模块听起来适合拆微服务,但工程公司的业务特点是"模块间数据强耦合"——一个项目立项后,合同、采购、费用、应收应付全链路依赖同一份项目基础数据。微服务拆开后跨服务事务一致性会变得极其复杂。我们选择了模块化单体:FastAPI 下按模块拆分 Blueprint,共享同一个 PostgreSQL Schema,用 Redis 做高频查询缓存。14 周的交付周期不允许在分布式事务上冒险。
为什么选 Ant Design Pro v6。客户团队没有专职前端,期望的是"一眼能看懂、半天能上手"的后台界面。Ant Design Pro 的企业级模板——ProTable、ProForm、ProLayout——让 11 个模块的界面风格完全统一,减少了培训成本。代价是部分定制需求(如合同审批流程图)需要大量覆盖 ProComponents 的默认行为。
核心能力
- 项目管理:立项、预算、进度跟踪、竣工验收全流程
- 合同管理:合同起草、审批流、变更记录、归档
- 应收应付:多币种、多账期、自动提醒与逾期标记
- 费用报销:移动端拍照上传、多级审批、自动生成凭证
- 采购库存:采购申请、入库出库、库存预警
- 基础数据与系统管理:组织架构、角色权限、操作日志
工程挑战与踩坑
坑一:财务模块的金额精度问题。工程行业常涉及"万元"级别的合同金额与"分"级别的材料单价并存。数据库统一用 NUMERIC(18,4) 存储,但 Ant Design Pro 的 Table 组件默认用 JavaScript Number 渲染金额——超过 2^53 的大整数精度丢失,导致 9 位数的合同金额显示为"取整后"数值。解决方案是统一用字符串传输金额、前端用 Intl.NumberFormat 格式化,后端用 Python Decimal 做运算。这个问题在 UAT 阶段才发现,修了 3 天。
坑二:11 个模块的权限矩阵设计过于保守。初版权限系统给每个角色逐模块、逐功能配置,结果客户的管理员在后台"点了半小时没配完一个项目经理的权限"。第二版改为"权限模板 + 例外覆盖"模式——预设项目经理/财务/采购/管理员四套模板,特殊需求走例外审批。权限配置时间从 30 分钟降到 3 分钟。
坑三:报表导出在月末崩了两次。客户在月末集中导出所有项目的财务汇总报表,11 个模块 × 30+ 项目的联表查询导致 PostgreSQL 的 CPU 冲到 95%。最终用 Redis 预缓存 + 异步队列的方案:报表请求进入 Celery 任务队列,生成后通过 WebSocket 通知用户下载,高峰期并发从 40 降到 5。
交付指标
- 5 人核心团队,14 周从需求调研到上线
- 11 个核心模块全覆盖,覆盖工程企业 90%+ 日常业务流程
- 月末报表导出从直接查询(超时 30s+)优化为异步队列(平均 8s 完成)
- 权限配置从逐项勾选 30 分钟降至模板化 3 分钟
- 上线后首月处理 200+ 项目、1500+ 笔财务记录,零数据错误
技术选型
前端:Ant Design Pro v6 · UMI Max · React 19 · TypeScript 5.6 · antd-style · Less · Biome
后端:FastAPI · SQLAlchemy · Alembic · asyncpg · PostgreSQL · Redis · Celery · python-jose / bcrypt
