本文基于 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.60/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 编程不仅需要模型,还需要准确的框架文档、项目约定和真实踩坑记录。否则,模型可能生成语法正确、却不符合项目扩展方式的代码。
八、如何复现这套开发流程
- 阅读
doc/如何自建扩展.md,了解IExtensionInitializer、AddEasyAdminBlazorAssembly、MenuProvisioning等扩展契约。 - 先整理业务规则和待确认问题,再设计数据模型,不让 AI 自行猜测负库存、退货和审批规则。
- 从商品、客户、供应商、仓库等基础资料开始,跑通实体、页面、菜单和权限。
- 开发采购入库和销售出库,重点验证过账事务、重复提交、退货关联和并发扣减。
- 每完成一个阶段就运行
dotnet build、dotnet test,并进行浏览器手工验收。 - 将项目特有的框架用法和错误修正记录沉淀为 Skill,后续开发直接复用。
第 6 步值得多说一句:它是唯一一步会随时间变值钱的。前五步是一次性投入,第六步是复利------每修一个坑,后面所有的会话都少踩一次。
九、适用范围与限制
EasyAdminBlazor 适合内部管理系统、定制开发项目和私有化部署。Blazor Server 依赖 SignalR 长连接,弱网或高延迟环境需要关注重连体验;复杂可视化、拖拽和高度定制的前端交互,也可能需要额外的 JavaScript 互操作。
这次案例验证了三件事:
- 框架已有的后台能力可以直接用于真实业务系统,减少重复开发。
- AI 可以承担大量编码工作,但业务规则、事务边界和测试验收仍然重要。
- 把业务规则、测试和项目约定一起提供给 AI,比单纯要求它生成 CRUD 更有效。
这次约 6 小时的实际开发时间是本项目的记录,不代表所有进销存项目都能在相同时间内完成。业务复杂度、框架熟悉程度和验证范围都会影响开发效率。
还要补充一条这次踩过的限制 :本文的 6 小时是在 MiniMax Coding Plan 5 小时滑动窗口限制下取得的。它证明的是"在这种配额条件下能做完",不等于"AI 编程本身只要 6 小时"。换模型、换套餐、换业务复杂度,数字都会变。
相关链接
- 框架主页: easyadmin.wang-zhan.com.cn/
- 开发文档: easyadmin.wang-zhan.com.cn/doc
- 进销存代码:
Inventory/,独立分支feature/inventory - 项目开发规范:
.opencode/skills/easyadminblazor-extension/SKILL.md - MiniMax Coding Plan 订阅: platform.minimaxi.com/subscribe/c...
- M3.1 Flash 官方价格: www.minimax.io/pricing