作者:互联网 时间: 2026-08-24 08:09:55
需手动调整Atoms生成的状态字段业务逻辑:先定位@StateField字段及配套状态机/枚举类,补全OrderStatusEnum并绑定code;再重写updateStatus方法校验流转规则;最后在Mapper层增加WHERE条件拦截非法状态写入。
在使用Atoms生成代码后,需手动调整状态字段的业务逻辑以匹配真实场景——比如订单状态不能从“已发货”直接跳转到“待支付”,也不能让“已取消”状态再触发退款操作。
打开Atoms生成的实体类文件(如 Order.java),找到被 @StateField 注解标记的字段,通常形如 private String status;。
确认该字段是否配套生成了状态机配置类(如 OrderStatusMachine.java)或枚举类(如 OrderStatusEnum.java)。【若未生成枚举类,后续所有状态流转校验将失去编译期约束,极易引入非法字符串】
创建 OrderStatusEnum.java,定义明确、不可变的状态值:
public enum OrderStatusEnum {
PENDING_PAYMENT("待支付", "payment_pending"),
PAID("已支付", "payment_success"),
SHIPPED("已发货", "logistics_shipped"),
DELIVERED("已签收", "logistics_delivered"),
CANCELED("已取消", "order_canceled");
private final String desc;
private final String code;
OrderStatusEnum(String desc, String code) { this.desc = desc; this.code = code; }
// 补全 getCode() 和 ofCode() 方法
}
这一步必须完成,否则数据库存入的将是枚举名而非 code 字段值,导致前端展示错乱或条件查询失效。
在 OrderService 中找到 updateStatus() 或类似方法,替换为带校验的实现:
方法一:硬编码状态流转白名单
private static final Map
PENDING_PAYMENT, Set.of(PAID, CANCELED),
PAID, Set.of(SHIPPED, CANCELED),
SHIPPED, Set.of(DELIVERED),
DELIVERED, Set.of(),
CANCELED, Set.of()
);
public void updateStatus(Long orderId, OrderStatusEnum newStatus) {
Order order = orderMapper.selectById(orderId);
OrderStatusEnum current = OrderStatusEnum.ofCode(order.getStatus());
if (!ALLOWED_TRANSITIONS.getOrDefault(current, Set.of()).contains(newStatus)) {
throw new IllegalStateException("状态非法变更:从 " + current + " 到 " + newStatus);
}
order.setStatus(newStatus.getCode());
orderMapper.updateById(order);
}
方法二:抽取为独立状态机服务(推荐用于3个以上状态的复杂流程)
新建 OrderStatusTransitionService 类,内部用 switch 匹配当前状态,返回允许的目标状态列表;调用方只传 current 和 target,由该服务统一判定。这样后续增删状态时,只需改一个类,不散落各处。
修改 OrderMapper.xml,在 <update> 标签内添加 WHERE 条件:
<update id="updateStatus">
UPDATE `order` SET status = #{status}
WHERE id = #{id} AND status IN
<foreach item="allowed" collection="allowedStatuses" open="(" separator="," close=")">
#{allowed}
</foreach>
</update>
对应 Java 接口增加 allowedStatuses 参数,确保只有合法前序状态下才执行更新。这道防线能防止缓存穿透或并发场景下绕过 Service 层校验。