实践开发:老系统新增字段我是如何用枚举优雅兼容历史数据的

背景:

最近在给一个 CRM 系统做升级,新增了一个字段:发票方向(invoiceDirection)。

一开始系统里的发票没区分红冲还是正常,只有一个字段:发票金额。

后来有红冲场景了,我那就简单的说一下红冲:

红冲 = 用一张「负数发票」来冲销一张已经开的正数发票,红冲是财务概念,这里不展开,知道它会导致金额为负就够了。

  • 正常开票

  • 红冲发票(简单理解为:用负数金额冲销原发票)

方案设计:

我最开始的方案(两行代码解决)

我当时的方案非常简单:

  • 金额 > 0:绿色

  • 金额 < 0:红色

前端区分一下展示就行了,两行代码就解决了。

老数据 0 影响,后端 0 改表

说实话,这个方案:简单、直接、完全够用。

if (column.property === 'invoiceMoney') {

const money = Number(row.invoiceMoney || 0)

return money > 0 ? 'xr-money green' : money === 0 ? 'xr-money gray' : 'xr-money red'

}

我到现在也觉得:在这个场景下,其实是 OK 的可能是我经验不足吧。

老大的原话大概意思是:

"颜色只是展示,必须加个字段必须明确区分是不是红冲。加字段。"这不是增加复杂度吗......

但没办法,谁让人家是老大呢 而且你还真不好反驳。

遇到的问题:

字段已经确定要加了,那真正的问题变成:

  • 这是一个 新增字段

  • 历史数据已经存在

  • 不可能全表 update

  • 也不能随便给默认值

如果处理不好,比不加还麻烦

最终方案:我用到了枚举了+兜底处理来处理就数据

  1. 用枚举定义业务边界:

  2. 读数据:不信任数据库,必须兜底

  3. 写数据:通过金额统一推导方向

这样做的好处:用枚举把"发票方向"的业务含义和判断规则集中管理,同时通过兜底逻辑兼容历史数据,避免魔法值扩散,让老系统升级更安全、更可维护。

最后我们在查询的时候做个兜底处理,因为老数据新的字段都是null 就根据发票金额做个兜底是正常开票还是红冲。

private void fillInvoiceDirectionIfAbsent(Map<String, Object> row) {

// 新字段已有值,直接使用

if (row.get("invoiceDirection") != null) {

return;

}

BigDecimal money = Convert.toBigDecimal(row.get("invoiceMoney"), BigDecimal.ZERO);

int direction = InvoiceDirectionEnum.fromMoney(money);

row.put("invoiceDirection", direction);

}

实现的结果:

结语:

这个字段本身,是不是一定非加不可?说实话,我现在依然觉得:不一定。用金额正负 + 前端颜色,

在当时的业务复杂度下,完全可以跑得通。但现实开发里经常是这样:

  • 需求不一定最优

  • 但你得让系统稳住

  • 让历史数据不受影响

  • 让后面接手的人少踩坑

所以最终选择了:

  • 用枚举把业务含义说清楚

  • 用兜底逻辑兼容老数据。

相关推荐
软件技术NINI1 分钟前
基于SpringBoot和Vue的新能源汽车销售推荐系统
java·vue.js·spring boot·后端·汽车·毕业设计·毕设
Flynn Liang31 分钟前
LangChain4j 生产级工程骨架:12 个模块 + Docker 一键启动
java·spring boot·langchain·rag·langchain4j
噢,我明白了2 小时前
JAVA中的一些基础应用知识点
java·开发语言
SL_staff2 小时前
私有化低代码不是妥协,而是企业级数字化的自主可控主航道
java
装不满的克莱因瓶2 小时前
【SpringAI Alibaba】ReactAgent结构化输出OutputType与OutputSchema实战
java·人工智能·ai·springai·springaialibaba
秋天的怀念_David3 小时前
算法一千零一夜 · 第二十八夜 注册
java·程序人生·算法
Java码农也是农3 小时前
Spring 事务详解:@Transactional 如何生效、何时回滚、传播行为怎么选
java·spring boot·spring·事务
学长毕设4 小时前
基于SpringBoot的游乐园管理系统-附源码
java·spring boot·后端
SimonKing4 小时前
震惊:怎么回事,opencode一轮对话耗尽免费额度
java·后端·程序员
装不满的克莱因瓶4 小时前
【SpringAI Alibaba】ReactAgent响应SSE实时流式传输案例实战
java·人工智能·ai·sse·springai