用 EasyAdminBlazor + OpenCode 开发进销存:实际做了什么,花了多久

本文基于 EasyAdminBlazor 2.5.0-beta.1 (预发布版本,公开 NuGet 源当前最新为 2.4.x),使用 .NET 10、Blazor Server 和 OpenCode 开发。进销存代码位于独立分支 feature/inventory,没有并入框架主干。

先给结论:一套面向中小企业的进销存系统第一版,13,229 行有效代码、171 个自动化测试用例,实际开发时间约 6 小时 ,算力成本按官方 API 单价折算约 3.46 美元。


一、项目规模

这次完成的是一套面向中小企业的进销存系统第一版,包含基础资料、采购、销售、库存、审批和报表,不是单纯的 CRUD 演示。

模块 功能
基础资料 商品、分类、单位、客户、供应商、仓库
采购 采购单、采购入库、采购退货
销售 销售单、销售出库、销售退货
库存 库存余额、库存流水、盘点、调拨、库存预警
报表 采购汇总、销售汇总、毛利分析、库存余额、库存流水,支持 Excel 导出
审批 提交、审批、驳回、撤回;审批通过后执行过账
权限 菜单权限、按钮权限

项目统计:

  • 25 张数据表、13 个业务服务、22 个页面
  • 27 个菜单节点、9 类按钮权限码
  • 171 个进销存自动化测试用例,21 个测试文件
  • 59 条业务规则、41 个待澄清问题、16 项手工验收
  • 业务代码 8,310 行,自动化测试代码 4,685 行,宿主代码 234 行
  • 合计 13,229 行有效代码

这里有个值得单独说的比例:宿主代码只有 234 行,业务代码 8,310 行。

宿主代码指的是让这个系统跑起来的启动配置、依赖注入、数据库连接和菜单注册。234 行意味着框架把这部分全包了------我没有为进销存写任何一行"让 Blazor 跑起来"的样板代码,所有新增的 8,310 行全部是业务逻辑。这 35:1 的比例,是判断"框架复用到什么程度"最直观的指标。


二、开发时间与 Token

项目从 2026-10-22 12:36 到 2026-10-23 08:59 ,墙钟跨度为 20 小时 23 分钟 ,实际开发时间约 6 小时。

那 14 小时差在哪

本次使用的是 MiniMax Coding Plan 最低档 Starter:¥29/月,每 5 小时 40 个 prompts 。限额按滑动 5 小时窗口计算,窗口内额度用尽后需等窗口滑动恢复,不额外扣费。

整个开发过程因此被切成约 4 个"能写代码的窗口"------窗口之间是等待,不是产出。配额用尽时正在进行的阶段会被打断,恢复后要重新加载上下文、确认代码库状态,这部分时间算不进"有效开发"里。

6 小时是这个限额下的真实产出速度,不是模型的极限速度。 这个项目全程跑在最低档,没有因为配额不够而升级套餐。

Token 与成本

本次 MiniMax-M3.1-Flash 调用记录:

项目 数量
输入 Token 2,640,195
输出 Token 849,820
缓存读取 Token 170,085,942
按官方 API 单价估算 约 3.46 美元,折合约 23 元人民币

估算口径是官方 M3.1 Flash 单价(输入 0.15/M、输出0.15/M、输出 0.15/M、输出0.60/M、缓存读取 0.015/M),三项加总0.015/M),三项加总 0.015/M),三项加总3.457。缓存读取是未缓存输入的 64 倍,占"输入 + 缓存读取"的 98.5%------绝大部分输入来自项目文件的反复引用。

需要说明:3.46 美元是按 API 单价对本次调用的折算,体现算力消耗量级;实际付的是固定月费,两者不是同一笔账。

此外,coding-plan-search 调用 7 次,部分收尾工作使用了免费 DeepSeek Flash。

费用按 MiniMax 官方 API 单价估算,不代表套餐实际扣费金额。


三、EasyAdminBlazor 复用了哪些能力

这次开发没有从零搭建后台基础设施,而是直接复用了框架已有能力。

开发需求 复用能力
列表、搜索、分页、表单和校验 AdminTable 等通用组件及实体校验约定
用户、角色、菜单和权限 现有 RBAC 与菜单机制
操作审计 框架操作日志
审批流程 Approval 扩展包
Excel 导出 MiniExcel 与报表组件
业务页面和服务 统一的 .NET、C# 技术栈

商品、客户、供应商、仓库等基础资料相对容易实现。按照框架约定建立实体、页面和权限后,不必为每个模块重新编写列表、表单和权限基础设施。

开发难点主要集中在进销存业务本身,而不是后台页面的重复实现。


四、最费工的业务问题

1. 单据不是简单的增删改查

采购单创建后不能直接增加库存,采购入库过账才增加库存;销售单创建后不能直接扣减库存,销售出库过账才扣减库存。

审批状态与库存过账也需要明确的业务边界。单号生成、单据状态、明细行、来源单据、累计退货数量、冲销和重复提交,都需要明确规则。

如果只让 AI 根据表结构生成 CRUD,页面可能可以操作,但业务流程并不完整。

2. 库存更新需要事务与并发控制

销售出库不能只查询库存后再扣减。两个请求可能同时读到相同的库存量,造成超卖。

本项目使用带库存条件的更新,并检查受影响行数;库存余额、库存流水和单据状态在同一事务中处理。任一步骤失败,都应回滚整笔操作。

3. 退货必须关联来源单据

采购退货需要关联原入库单,销售退货需要关联原出库单,并校验累计可退数量。

如果只允许用户任意填写商品、数量和价格,就可能出现超退或业务记录无法对应的问题。因此,来源单据和可退数量必须在服务端校验,不能只依赖页面限制。

4. 报表必须明确统计口径

订单数量不等于实际入库或出库数量,退货也会影响净额。采购、销售和库存报表需要明确统计的是订单、实际业务发生量,还是扣除退货后的净额。

毛利分析还涉及成本口径。统计规则没有定义清楚,即使 SQL 查询正确,报表结果也可能不符合业务预期。

这四类问题的共同点是:AI 写不出正确答案,只能写出语法正确、看起来合理的答案。区别在于业务规则由谁拍板。


五、AI 编程如何形成验证闭环

本项目不是生成代码后就结束,而是持续执行编译、自动化测试和浏览器冒烟检查。

bash 复制代码
dotnet build EasyAdminBlazor.sln --nologo
dotnet test EasyAdminBlazor.sln

测试包括进销存的 171 个用例,以及框架原有测试。进销存测试使用 SQLite 验证数据库操作、事务和约束;生产环境如果使用 MySQL,还需要在目标数据库上验证相关并发行为。

开发过程中,先整理业务规则 BR-xxx、待确认问题 Q-xx 和测试用例 TR-xxx,再分阶段实现。每完成一个阶段,就重新编译、运行测试并进行页面验收。

那 41 个待澄清问题,是这套流程里最不能省的一步。

它们不是"AI 写错了要修的 bug",而是开工前就知道没有标准答案、必须由人拍板的问题------负库存是否允许、盘点差异怎么算、毛利用加权平均还是移动加权、审批驳回后单据是否可编辑。这类问题如果丢给 AI,它会给出一个"合理"的实现,然后你会在验收时才发现它合理得不对。

把它们提前列成 Q-xx 清单,意味着:AI 负责在规则确定的地方发挥,规则不确定的地方由人先回答。这 41 个问题的处理结果:【待填:例如"38 个在开发中确认口径,3 个转为下版本需求"】。

AI 可以负责大量编码和检查工作,但业务规则仍需要开发者确定,生成的代码也必须经过实际验证。

OpenCode 在其中扮演什么角色

前面说"用 OpenCode 开发",具体是什么形态:

  • AGENTS.md 承载项目约定------把框架用法、目录结构、命名规范写成规则文件,让每次对话都从同一份约定开始,而不是每次重新交代背景
  • 项目级 Skill 按需加载 ------.opencode/skills/easyadminblazor-extension/SKILL.md 记录这个框架特有的扩展契约和踩坑修正。OpenCode 的 skill 机制是渐进式加载:平时只在描述里出现,需要时才把完整内容读进上下文。这对 token 成本影响很大,也正是缓存读取能占到 98.5% 的原因之一------同一份约定被反复命中
  • 踩坑即时回写 ------遇到一个框架特有的坑(漏写 @、事务里用错 IFreeSql),当场追加进 Skill,而不是留到下次再踩一遍

六、一次完整的端到端闭环

自动化测试验证的是单点规则:这条校验通过了吗?这条约束生效了吗?跨单据的链路是否正确、库存和金额能不能对上账,测试跑不出来,得手工走一遍。

下面是 2026-10-23 在 admin 账号下跑的一条完整链路,从采购单一路走到库存余额。

闭环路径

步骤 单据 结果
1 采购单 PO202610230001(SP001×10 / 单价 25 / 250) 审批通过 → 待过账
2 采购入库 PR202610230001(WH01 / 来源 PO...0001) 审批通过即过账 → 已执行 13:36:16 → 库存 +10
3 销售单 SO202610230001(C001 / SP001×4 / 单价 30 / 120) 审批通过 → 待过账(销售单是需求单据,不动库存,设计如此)
4 销售出库 DN202610230001(WH01 / 来源 SO...0001) 审批通过即过账 → 已执行 13:39:35 → 库存 −4
5 库存流水 2 条:出库 −4(前 10 → 后 6,成本 25,金额 100)、入库 +10(前 0 → 后 10,金额 250)
6 库存余额 主仓库 SP001 数量 6 / 成本 25 / 金额 150,最近入库 13:36:16、最近出库 13:39:35

三处对账

校验点 数值 结论
入库流水 +10(前 0 → 后 10),金额 250 10 × 25 = 250 ✓
出库流水 −4(前 10 → 后 6),金额 100 4 × 25 而非 4 × 30 ✓
库存余额 数量 6 / 成本 25 / 金额 150 6 × 25 = 150 ✓,且 10 − 4 = 6 ✓

第三行是这条链路里最关键的一处对账。销售单金额是 120(4 × 30,售价),而库存流水的出库金额是 100(4 × 25,成本),差额 20 就是这 4 件商品的毛利。

如果出库金额写成 120,毛利分析会把售价当成成本,整张毛利报表虚高 20%。 这正是第四节说的"报表必须明确统计口径"------单据的售价和库存的成本本来就是两套价,代码写对了不代表口径写对了。

三个值得单独说的设计

一、审批 ≠ 过账。 采购单审批通过后状态是"待过账",库存纹丝不动;只有采购入库单审批通过才真正过账并增加库存。审批和过账是分离的两个动作。

二、需求单据不动库存。 销售单审批通过后库存完全没变。销售单表达的是"客户要 4 件",不是"4 件已经出库";实物转移发生在销售出库单上。AI 生成的 CRUD 几乎必然会把这个区别抹平------它看到"销售单"就顺手加上一句库存减 4。

三、已执行单据只留下游操作。 销售出库单执行后行内操作变为「冲销 / 编辑 / 删除」,没有"过账"按钮------单据已经过账,不该再有过账入口。

这里有个值得留意的地方:已过账单据仍然保留「编辑」和「删除」入口。编辑一张已过账单据会直接改写已生成的库存流水和余额,成本 25 这个数字可能随之变化。建议后续版本把已过账单据的删除收敛到「冲销」路径上,保留可追溯的冲销记录而非物理删除。这一点会作为待澄清问题跟进。

截图查看


七、开发中遇到的典型问题

问题 处理结果
Razor 中 C# 常量漏写 @ 权限路径取值错误,导致操作被拒绝
日期控件缺少正确的 FormatString 表单提交未按预期生效
事务中使用未绑定工作单元的 IFreeSql SQLite 出现 database is locked 等问题,事务边界不可靠
退货页面允许添加没有来源明细的行 服务端校验拒绝,页面操作与业务规则不一致
用 AdminTable 直接实现聚合报表 查询扩展点不适用,改用独立报表查询与组件
MiniExcel 自动列宽配置不当 大数据导出性能明显下降

这些问题后来整理进项目级 Skill:

.opencode/skills/easyadminblazor-extension/SKILL.md

AI 编程不仅需要模型,还需要准确的框架文档、项目约定和真实踩坑记录。否则,模型可能生成语法正确、却不符合项目扩展方式的代码。


八、如何复现这套开发流程

  1. 阅读 doc/如何自建扩展.md,了解 IExtensionInitializer、AddEasyAdminBlazorAssembly、MenuProvisioning 等扩展契约。
  2. 先整理业务规则和待确认问题,再设计数据模型,不让 AI 自行猜测负库存、退货和审批规则。
  3. 从商品、客户、供应商、仓库等基础资料开始,跑通实体、页面、菜单和权限。
  4. 开发采购入库和销售出库,重点验证过账事务、重复提交、退货关联和并发扣减。
  5. 每完成一个阶段就运行 dotnet build、dotnet test,并进行浏览器手工验收。
  6. 将项目特有的框架用法和错误修正记录沉淀为 Skill,后续开发直接复用。

第 6 步值得多说一句:它是唯一一步会随时间变值钱的。前五步是一次性投入,第六步是复利------每修一个坑,后面所有的会话都少踩一次。


九、适用范围与限制

EasyAdminBlazor 适合内部管理系统、定制开发项目和私有化部署。Blazor Server 依赖 SignalR 长连接,弱网或高延迟环境需要关注重连体验;复杂可视化、拖拽和高度定制的前端交互,也可能需要额外的 JavaScript 互操作。

这次案例验证了三件事:

  • 框架已有的后台能力可以直接用于真实业务系统,减少重复开发。
  • AI 可以承担大量编码工作,但业务规则、事务边界和测试验收仍然重要。
  • 把业务规则、测试和项目约定一起提供给 AI,比单纯要求它生成 CRUD 更有效。

这次约 6 小时的实际开发时间是本项目的记录,不代表所有进销存项目都能在相同时间内完成。业务复杂度、框架熟悉程度和验证范围都会影响开发效率。

还要补充一条这次踩过的限制 :本文的 6 小时是在 MiniMax Coding Plan 5 小时滑动窗口限制下取得的。它证明的是"在这种配额条件下能做完",不等于"AI 编程本身只要 6 小时"。换模型、换套餐、换业务复杂度,数字都会变。


相关链接

相关推荐
ByteRock44 分钟前
同样是 Decimal,为什么 MySQL 和 ClickHouse 会写成两套世界
后端
leo在掘金44 分钟前
一天155万亿Token,DeepInfer省在哪
后端·架构
阿良别做梦1 小时前
LangGraph 学习之路:让工作流返工,也让它及时停下
后端·开源
我的div丢了肿么办1 小时前
go语言抽离路由文件以及对路由进行分组
后端·go
zz在掘金337081 小时前
Django __init__.py 高级应用速记
后端
软件工程师文艺6661 小时前
Teamcenter FMS 文件管理系统深度解析:缓存策略、SSL 部署与性能调优
后端
Gopher_HBo1 小时前
类型系统 —— Type、rtype 与运行时类型元数据
后端
今天早睡1 小时前
并发分支、同步汇总与 State 合并
后端·架构
王川7081 小时前
商协会后台前端的模块聚合实践
前端·后端