新闻详情

新闻详情

首页 / 资讯中心 / 详情

业务方案:先记操作流水 → 走审批 → 审批通过后正式生效

发布时间:2026/9/27 4:57:44来源:尧图网络
业务方案:先记操作流水 → 走审批 → 审批通过后正式生效
目录业务概述数据库设计核心 3 张表1. 主业务表比如goods_price 商品价格表2. 操作变更流水表operation_log核心3. 审批任务表approval_task工作流最小实现复杂场景接入 Flowable完整业务流程代码逻辑步骤 1用户提交变更申请事务 1步骤 2审批人处理审批同意 / 驳回分支 A审批【驳回】事务 2分支 B审批【通过】事务 3重点方案变种对比方案 A上面这套【快照流水 审批后更新主表】✅推荐方案 B主表保留多版本主表新增一条版本记录旧版本标记失效方案 C不维护主表业务查询时合并流水不推荐重点问题 边界处理业务概述核心规则用户提交变更先落操作流水记录状态 待审批此时业务实体本身不生效审批流程独立流转审批通过才把变更内容刷入主业务表状态改为生效审批驳回主业务数据不变流水标记驳回。典型场景合同变更、价格调整、权限变更、额度修改、订单改单。 核心目的留痕、可回溯、变更不即时生效审批是生效开关数据库设计核心 3 张表1. 主业务表比如goods_price 商品价格表真实生效的数据在这里审批未通过时本表不更新sqlCREATE TABLE goods_price ( id BIGINT PRIMARY KEY AUTO_INCREMENT, goods_id BIGINT NOT NULL COMMENT 商品ID, price DECIMAL(18,2) NOT NULL COMMENT 生效价格, effective_time DATETIME COMMENT 生效时间, status TINYINT COMMENT 0失效 1生效, create_time DATETIME DEFAULT NOW(), update_time DATETIME DEFAULT NOW() );2. 操作变更流水表operation_log核心用户提交修改先插入这张表保存本次要修改的目标值、变更前后快照、审批状态sqlCREATE TABLE operation_log ( id BIGINT PRIMARY KEY AUTO_INCREMENT, business_type VARCHAR(64) NOT NULL COMMENT 业务类型GOODS_PRICE, business_id BIGINT NOT NULL COMMENT 主业务ID对应goods_price.id, before_content TEXT COMMENT 变更前JSON快照, after_content TEXT COMMENT 申请变更后的JSON快照, apply_user BIGINT NOT NULL COMMENT 申请人, apply_time DATETIME DEFAULT NOW(), approval_status TINYINT NOT NULL COMMENT 0待审批 1审批通过 2审批驳回 3撤销申请, approval_user BIGINT COMMENT 审批人, approval_time DATETIME, approval_comment VARCHAR(512) COMMENT 审批意见, create_time DATETIME DEFAULT NOW(), update_time DATETIME DEFAULT NOW() );3. 审批任务表approval_task工作流最小实现复杂场景接入 Flowable记录每一条流水对应的审批节点、审批人sqlCREATE TABLE approval_task ( id BIGINT PRIMARY KEY AUTO_INCREMENT, operation_log_id BIGINT NOT NULL COMMENT 关联操作流水ID, node_name VARCHAR(64) NOT NULL COMMENT 审批节点, approver BIGINT NOT NULL COMMENT 审批人ID, task_status TINYINT NOT NULL COMMENT 0待处理 1同意 2驳回, task_sort INT COMMENT 审批顺序, create_time DATETIME DEFAULT NOW() );完整业务流程代码逻辑步骤 1用户提交变更申请事务 1查询当前主业务表旧数据序列化为beforeContent用户提交新参数组装afterContent开启事务插入operation_log状态 待审批根据审批规则生成审批任务approval_task✅主业务表【不做任何更新】事务提交返回申请单号流水 ID关键点此时查询主业务数据还是旧值变更只保存在流水里。伪代码javaTransactional(rollbackFor Exception.class) public Long applyChange(GoodsPriceDTO dto) { // 1.查询当前生效数据 GoodsPrice oldData goodsPriceMapper.selectById(dto.getGoodsId()); String beforeContent JSON.toJSONString(oldData); // 2.组装新变更数据快照 GoodsPrice newData BeanUtil.copyProperties(dto, GoodsPrice.class); String afterContent JSON.toJSONString(newData); // 3.写入操作流水待审批 OperationLog log new OperationLog(); log.setBusinessType(GOODS_PRICE); log.setBusinessId(oldData.getId()); log.setBeforeContent(beforeContent); log.setAfterContent(afterContent); log.setApprovalStatus(0); //待审批 log.setApplyUserId(getCurrentUserId()); operationLogMapper.insert(log); // 4.生成审批任务 ListApprovalTask taskList buildApprovalTask(log.getId()); approvalTaskMapper.insertBatch(taskList); return log.getId(); }步骤 2审批人处理审批同意 / 驳回分支 A审批【驳回】事务 2更新operation_log状态 驳回填写审批人、审批意见更新approval_task当前节点状态为驳回后续节点作废主业务表不修改事务提交业务保持旧数据流水永久留痕分支 B审批【通过】事务 3重点如果是多级审批需要判断是否是最后一级审批节点全部节点同意才触发生效javaTransactional(rollbackFor Exception.class) public void approve(Long logId, boolean pass, String comment) { OperationLog log operationLogMapper.selectById(logId); if (!pass) { // 驳回逻辑 log.setApprovalStatus(2); log.setApprovalComment(comment); operationLogMapper.updateById(log); // 更新审批任务状态 approvalTaskMapper.rejectTask(logId); return; } // 判断是否所有审批节点全部通过 boolean allApproved approvalTaskMapper.checkAllApproved(logId); if (!allApproved) { // 不是最后一级只更新当前审批任务不刷主表 approvalTaskMapper.passCurrentTask(logId); return; } // 全部审批完成开始生效把afterContent刷入主业务表 log.setApprovalStatus(1); log.setApprovalTime(LocalDateTime.now()); operationLogMapper.updateById(log); // JSON快照转实体更新主业务表 GoodsPrice target JSON.parseObject(log.getAfterContent(), GoodsPrice.class); goodsPriceMapper.updateById(target); }方案变种对比方案 A上面这套【快照流水 审批后更新主表】✅推荐适用变更字段不多、变更一次性生效查询主表就是最新生效数据。 优点业务查询简单历史变更全部存在流水审计友好。 缺点变更字段多的时候JSON 快照排查麻烦。方案 B主表保留多版本主表新增一条版本记录旧版本标记失效适用需要保留多版本历史例如合同。 逻辑审批通过新增一行主表版本旧版本置为失效不是原地 update。方案 C不维护主表业务查询时合并流水不推荐所有变更都存在流水业务查询主数据时合并所有已通过流水。 缺点查询逻辑复杂性能差适合极简单场景。重点问题 边界处理并发提交多份变更申请同一业务对象可以同时有多条「待审批」流水审批生效时需要考虑顺序。解决方案生效时加乐观锁主表加 version防止后审批的旧变更覆盖新变更。javaupdate goods_price set price?, versionversion1 where id? and versionoldVersion如果更新行数 0抛出异常数据已被其他变更覆盖。申请人撤销申请流水状态改为【撤销】审批任务作废主数据不变。审计追溯before_content和after_content是核心任何时候都可以查到这次修改前后的值。工作流选型审批节点固定、简单直接用上面approval_task表硬编码多级审批、动态审批人、会签或或签接入 Flowable / Camunda流水和工作流实例关联。生效时间控制延时生效业务需求审批通过但指定未来某个时间点才生效。 实现审批通过后主表不立即更新写入定时任务到时间执行更新流水标记 “待定时生效”。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

建设网站需要提前准备的条件一文搞懂 2026/9/27 5:53:25

建设网站需要提前准备的条件一文搞懂

建设网站需要提前准备的条件一文搞懂 模板网站太丑,功能还卡壳,这是很多老板找我们建站时的第一句话。别急着骂供应商,很多时候不是他们不行,是你手里没牌。今天不聊虚的,直接拆解 建设网站需要提前准备的条件…

阅读更多 →
不懂代码怕被黑?一文搞懂谷歌官方建站服务安全坑 2026/9/27 5:53:25

不懂代码怕被黑?一文搞懂谷歌官方建站服务安全坑

不懂代码怕被黑?一文搞懂谷歌官方建站服务安全坑 想做网站却不会写代码,是不是经常心里发虚?尤其是看到新闻里说某某官网被挂马、数据泄露,那种“会不会轮到我家网站”的焦虑感,简直让人睡不着觉。很多设计师或老板以为,只要用了 谷歌官方建站服务…

阅读更多 →
开发了一个GNSS软件接收机,大家觉得怎么样? 2026/9/27 5:53:06

开发了一个GNSS软件接收机,大家觉得怎么样?

一个 GNSS 软件接收机:Qt6 C20,把 GPS / 北斗 / Galileo 十种信号全部打通一个不依赖任何第三方 GNSS 库的离线软件接收机。21,000 行 C20 从捕获、跟踪、导航电文译码一路写到多系统联合定位,配上完整的 Qt6 图形界面和命令行批处理工具。十…

阅读更多 →
RTX 3080 20G 的 CUDA 兼容性 / 新驱动还能不能正常跑本地模型? 2026/9/27 5:52:40

RTX 3080 20G 的 CUDA 兼容性 / 新驱动还能不能正常跑本地模型?

RTX 3080 20G 属于改显存版本,判断它能不能跑本地模型,关键不在显存大小,而在两件事:驱动是否认得出这张卡,以及驱动暴露的 CUDA 支持上限是否不低于框架编译时用的版本。多数情况下,只要 nvidia-smi 能稳定…

阅读更多 →
网络编程:UDP协议 2026/9/27 5:52:15

网络编程:UDP协议

一、是什么 UDP(User Datagram Protocol,用户数据报协议)是一种简单的、无连接的传输层协议,用于在网络中传输数据。 与 TCP 不同,UDP 不提供可靠性、顺序性和流量控制,但它具有低延迟和高效的特点&#xf…

阅读更多 →
做网站都需要买什么问题避坑指南与性能优化实战 2026/9/27 5:52:15

做网站都需要买什么问题避坑指南与性能优化实战

做网站都需要买什么问题避坑指南与性能优化实战 找建站公司最怕什么?怕被忽悠多花冤枉钱,更怕花了钱做出来的网站打开像蜗牛,客户还没看内容就关了页面。很多老板问“做网站都需要买什么问题”,其实核心就是两件事:一是别买没用的服务,二是买对能保性能…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉