飞算JavaAI能读懂权限链与状态机吗?SealFlow用印审批实测
一分钱触发一条新审批链,跨部门访问必须被拦截,任何状态变化都要留下时间线——这一次,我没有让 AI 写待办清单,而是给它上了一套真正考验业务理解的题。
一、为什么我没有继续测试普通 CRUD
用 AI 写一个用户表、几组增删改查,再生成一个列表页,现在已经不算难题。真正能拉开体验差距的,是模型能不能把自然语言里的业务约束转成同一套可运行、可验证的系统规则。
这次我设计的项目叫“印章卫士 SealFlow”,它是一套企业合同用印分级审批系统。选择这个题目,是因为它同时包含权限链、金额边界、状态机、部门数据隔离、重复操作防护和审批留痕。任何一个环节理解错了,页面可能照样能打开,但业务链路一定会在后续验收中露馅。
我重点观察的不是“生成了多少文件”,而是下面四件事:
模型能否把一段长需求拆成结构化规则;
同一条规则能否贯穿接口、数据表、后端服务和前端页面;
角色、状态和金额边界能否真正影响流程;
最终项目能否完成构建、测试和浏览器操作,而不是停留在代码片段。
二、这道题到底复杂在哪里
SealFlow 不是单角色系统。项目中设置了研发员工、研发经理、市场员工、市场经理、法务专员、印章管理员和系统管理员 7 个演示账号,对应员工、经理、法务、印章管理员、系统管理员 5 类业务角色。
核心审批规则如下:
-
员工只能查看和操作自己的申请;
-
部门经理只能审批本部门员工的申请,并且禁止自审;
-
合同金额不超过 50,000.00 元,经理审批后直接进入待用印;
-
合同金额超过 50,000.00 元,必须增加法务复核;
-
法务只能处理待法务复核的申请;
-
印章管理员只能处理待用印的申请;
-
系统管理员拥有全局只读台账,但不能代替业务角色审批;
-
草稿、提交、审批、驳回、撤回、完成用印都有明确的前置状态;
-
相同合同编号存在有效申请时,禁止重复提交;
-
申请状态变化和审批记录必须在同一事务中完成。
这里最适合做定量边界验证的是金额分流:
金额只增加 0.01 元,流程就必须多出一个法务节点。如果模型只抓住“合同审批”四个字,很容易把两条路线写成同一条。
完整状态链可以概括为:
DRAFT(草稿)
└─ 提交 → PENDING_MANAGER(待经理审批)
├─ 驳回 → REJECTED(已驳回)
├─ 撤回 → WITHDRAWN(已撤回)
└─ 经理通过
├─ 金额 ≤ 50,000.00 → PENDING_SEAL(待用印)
└─ 金额 > 50,000.00 → PENDING_LEGAL(待法务)
├─ 驳回 → REJECTED
└─ 通过 → PENDING_SEAL
└─ 完成 → COMPLETED
三、测试环境与技术栈
本次在飞算 JavaAI 的“Java Web 工程(新版)”中使用智能路由完成需求分析与工程生成,最终项目采用前后端分离的单体架构,没有引入微服务、Redis、消息队列、工作流引擎或 OCR,尽量让测试聚焦在业务逻辑本身。
四、我给飞算 JavaAI 的不是一句话,而是一份可验收的业务题
我先在编辑区提交完整提示词,明确项目名称、模块结构、技术栈、角色、状态枚举、金额分流、权限范围、错误码、数据库表、测试要求和验收步骤。

提示词最后没有停在“请帮我生成项目”,而是直接给出了验证脚本:用研发员工分别提交 50,000.00 元和 50,000.01 元申请,检查经理审批后的不同去向;再用市场经理尝试审批研发部申请,检查是否返回 403;最后测试重复合同编号和重复审批是否返回 409。

这一步很重要。复杂业务测试不能只给目标,不给边界。提示词里的每个异常案例,后面都应该在接口、服务或测试中找到对应落点。
五、从 51 个关键点到 77 项计划:先看它是否真的“读懂”
需求理解:拆出 51 个关键点
智能引导首先把需求拆成了 51 个关键点。截图中能看到,它识别出了 MyBatis-Plus 持久化、H2 演示数据库、MySQL Profile、7 个演示账号、Swagger 文档、后端测试与构建验证等工程要求,而不是只抽取“合同申请”和“审批”两个名词。

我的第一感受是:长提示词没有被压缩成一个泛化的后台管理系统。部门隔离、金额边界、状态流转、重复操作和事务一致性都进入了需求清单,这至少说明模型抓住了本题的主要矛盾。
不过,51 只是“覆盖数量”,并不等于 51 条都正确。这个阶段仍然要人工检查:角色权限是否过宽、金额比较是否包含等号、驳回和撤回后能否重新申请,这些词语差一点,最终代码行为就可能完全不同。
接口设计:生成 12 个接口方案
进入接口设计后,系统给出了 12 个接口方案,并把认证、申请、经理审批、法务复核和完成用印拆成不同业务入口。

这里我特别关注两点:一是 Controller 不能直接操作数据库,业务规则要落到 Service;二是非法角色、跨部门、非法状态和重复操作必须分别返回可诊断的 403 或 409,而不能统一吞成 500。接口数量不是越多越好,关键是接口边界要和角色动作对齐。
表结构设计:5 张核心表承接业务语义
数据库阶段生成了 5 张核心表:department、sys_user、seal_info、seal_application 和 approval_record。

这套结构没有把所有信息塞进一张申请表。申请主表负责当前状态,审批记录表保存操作人、角色、动作、原状态、新状态、意见和操作时间。这样的拆分才能还原完整时间线,也为后续审计留下基础。
金额字段使用 decimal(15,2),避免用浮点数比较 50,000.00 元边界;申请表保留 version 字段,为乐观锁或条件更新提供位置。这两个细节,都是普通 CRUD 示例里经常被忽略的工程问题。
代码生成计划:77 项任务覆盖前后端链路
完成接口和表结构后,飞算 JavaAI 生成了 77 项代码计划,包含工程初始化、后端分层、数据初始化、认证、核心表实体与 Mapper、业务服务、接口、测试和前端页面。

从 51 个需求点、12 个接口方案、5 张表到 77 项代码计划,这一过程的价值不只是“看起来步骤很多”,而是让需求、接口、数据和实现之间有可追踪的映射。对于长需求,先暴露理解结果再生成源码,比直接吐出一堆文件更容易发现方向性错误。
六、业务规则有没有真正落进代码
最终生成的系统不只是页面上写了“金额分界”,后端策略类也对 50,000.00 元进行了精确比较:
public static final BigDecimal LEGAL_THRESHOLD = new BigDecimal("50000.00");
public ApplicationStatus nextAfterManagerApproval(BigDecimal amount) {
return amount.compareTo(LEGAL_THRESHOLD) <= 0
? ApplicationStatus.PENDING_SEAL
: ApplicationStatus.PENDING_LEGAL;
}
compareTo(…) <= 0 对应“50,000.00 元及以下直接待用印”,而不是误写成 < 0。配套单元测试也同时覆盖了 50,000.00 和 50,000.01 两个数值。
经理审批前,Service 同时校验部门和申请人身份:
private void requireManagerScope(SealApplication app, CurrentUser actor) {
if (!Objects.equals(app.getDepartmentId(), actor.departmentId())) {
throw forbidden("经理只能审批本部门申请");
}
if (Objects.equals(app.getApplicantId(), actor.id())) {
throw forbidden("审批人与申请人不能是同一人");
}
}
这段代码回答了两个实际问题:经理是不是只能看本部门,以及经理本人能不能给自己的申请放行。权限判断落在后端,而不是只靠前端隐藏按钮。
状态更新和审批记录写入则由同一个事务包裹:
@Transactional
public ApplicationView managerApprove(Long id, String comment, CurrentUser actor) {
requireRole(actor, Role.MANAGER, "只有部门经理可以执行该审批");
SealApplication app = lock(id);
requireManagerScope(app, actor);
policy.requireStatus(app.getStatus(), ApplicationStatus.PENDING_MANAGER, "经理审批");
return transition(
app,
policy.nextAfterManagerApproval(app.getAmount()),
actor,
ApprovalAction.APPROVE,
comment
);
}
这说明模型理解了“审批”不是单独插一条记录,也不是只改一个状态,而是一次完整的业务动作。
七、从登录到分角色处理,我在浏览器走了一遍真实流程
项目启动后,首先进入身份核验页面。界面内置本地演示身份,可以直接选择角色进入对应流程。

研发员工进入系统后,可以看到当前身份可见的申请汇总、最近流转档案,并通过“发起用印”进入申请表单。


表单左侧会根据当前金额提示审批路线。金额未超过分界线时显示“经理 → 用印”;超过 50,000.00 元后则应增加法务复核。它不是替代后端校验,但能让申请人在提交前理解流程。
研发经理登录后,导航入口切换为“经理审批”,总览数据也按照部门范围变化。

切换到市场经理时,可见档案数量和最近记录随部门变化,验证了同一套页面下的数据隔离,而不是给所有经理返回全量列表。

高金额合同进入法务队列后,法务角色看到“法务复核”入口;经理未通过或状态不正确的申请,不应直接出现在法务待办中。

经理直达用印或法务通过后,申请进入印章管理员队列。印章管理员完成用印时,需要记录实际用印时间和经办说明,之后状态才进入 COMPLETED。

系统管理员最后提供全局只读台账,可查看跨部门状态与时间线,但页面没有业务审批入口。这一点符合“能看全局,不代替业务角色操作”的约束。

八、量化验收结果
为了避免只凭页面观感下结论,我把本次留下的可复核数据汇总如下:
这里没有填写生成总耗时,也没有声称比旧版本快多少,因为本次没有保留可复核的计时数据。对于 AI 编程工具,宁可少写一个漂亮数字,也不要把主观感觉包装成性能结论。
九、真实评价:它已经不只会 CRUD,但还不能跳过人工审查
做得比较好的地方
第一,需求拆解不是简单复述。金额分流、跨部门权限、自审限制、状态前置条件和审批留痕,确实贯穿了需求、接口、表结构、代码和页面。
第二,模型能把业务语义翻译成工程对象。角色被映射为权限,金额边界被映射为 BigDecimal 比较,流程节点被映射为状态枚举,审批轨迹被映射为独立记录表。这比“生成一个审批列表页”更接近真实 Java 项目。
第三,交付物具备基本工程闭环。后端可以执行测试,前端可以构建,H2 可以直接演示,同时保留 MySQL 配置和 Swagger 入口,降低了第一次运行的门槛。
仍然需要人工补强的地方
第一,version 字段存在,不代表并发控制就已经完整。当前业务代码的主要状态更新仍使用普通 updateById;虽然 Mapper 中预留了按当前状态和版本号条件更新的方法,但核心审批路径还需要进一步接入。两个请求同时审批同一申请时,生产级实现应检查受影响行数,并让失败的一方稳定返回 409。
第二,重复合同编号的业务查询能挡住常规重复提交,但强并发下仍可能同时通过“先查询、后写入”。更稳妥的方案是结合数据库约束、条件更新或幂等键,而不是只依赖一次 selectCount。
第三,5 个自动化测试证明了代表性链路能跑通,但还不足以覆盖所有组合。至少还应增加跨部门 403、自审 403、非法状态 409、重复审批 409、驳回或撤回后重新申请,以及事务回滚测试。
第四,本次没有保存飞算 JavaAI 的具体版本号和生成耗时,因此只能评价这一次产物,不能严谨地推导“升级后提升了多少”。后续复测应固定提示词、依赖版本和硬件环境,并记录首次编译成功率、人工修改次数、总生成时间和测试通过率。
十、如果你也想测试 AI 的复杂业务理解,我的建议
不要只写功能名,要把角色、资源范围、前置状态和失败结果写清楚;
一定要设计边界对照,例如本次的 50,000.00 与 50,000.01;
让模型先展示需求、接口、表结构和计划,再开始生成源码;
权限必须在后端验证,前端隐藏按钮只能改善体验,不能充当安全边界;
每次状态变化都要考虑并发、幂等和审计记录;
最终评价要以构建、测试和实际操作为准,而不是以生成代码行数为准。
结论
这次 SealFlow 实测给我的结论是:在输入边界足够清晰的前提下,飞算JavaAI 已经能够把一套包含权限链、金额分流和状态机的需求,组织成可运行的 Java Web 工程。它不只是生成了 CRUD,还理解了“谁能在什么状态下,对哪一类数据执行什么动作”。
但“理解了主要业务”不等于“可以直接上线”。并发审批、数据库级幂等和更完整的异常测试仍需要开发者复核。对我来说,现阶段更合理的定位不是让 AI 替代工程判断,而是让它先完成结构化拆解和第一版工程闭环,再由开发者把关键边界收紧。
如果只让 AI 写 CRUD,很难看出它的真实水平;把权限、状态和边界一起交给它,才更容易知道它究竟是在拼代码,还是开始读懂业务。
#飞算JavaAI #AI编程 #Java #SpringBoot #Vue3 #权限设计 #状态机 #企业审批


