责任链设计模式进行多级审批
业务场景:在上篇泛型用法中将所有的审批业务都通过泛型方法进行插入待审核记录了,现在便需要对这些待审记录进行审批,由于客户需要多级审批,也就是每个业务的审批人数都不相同
为此引入责任链设计模式
1.首先,创建五级审核人表(最多五级),对各个业务类型,部门分配对应的审核人
2.创建责任链
2.1:通用责任链接口(五级责任链均实现此接口)
1 2 3 4 5 6 7 8 | package com.jeethink.project.business.audit; import com.jeethink.project.business.domain.BusinessAuditlist; import com.jeethink.project.system.domain.SysUser; public interface AuditHandler { void handle(BusinessAuditlist auditlist, SysUser user, String status, String reason); } |
2.2:实现方法,其中有一个字段为auditLink,表示审核环节字段,每次审核成功之后审核环节自增,最终审批完成之后将其设为空(后续审核代码中会呈现)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package com.jeethink.project.business.audit; import com.jeethink.common.utils.DateUtils; import com.jeethink.project.business.domain.BusinessAuditlist; import com.jeethink.project.system.domain.SysUser; /** * 责任链设计模式 */ public class AuditHandler1 implements AuditHandler{ private AuditHandler nextHandler; public void setNextHandler(AuditHandler nextHandler) { this .nextHandler = nextHandler; } @Override public void handle(BusinessAuditlist auditlist, SysUser user, String status, String reason) { if (auditlist.getAuditLink() == 0 ) { auditlist.setAudit1UserId(user.getUserId()); auditlist.setAudit1Time(DateUtils.getNowDate()); auditlist.setAudit1UserName(user.getNickName()); auditlist.setAudit1Status(status); auditlist.setAudit1Reason(reason); } else if (nextHandler != null ) { nextHandler.handle(auditlist, user, status, reason); } else { throw new RuntimeException( "审核失败" ); } } } |
2.3 实现方法2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package com.jeethink.project.business.audit; import com.jeethink.common.utils.DateUtils; import com.jeethink.project.business.domain.BusinessAuditlist; import com.jeethink.project.system.domain.SysUser; public class AuditHandler2 implements AuditHandler { private AuditHandler nextHandler; public void setNextHandler(AuditHandler nextHandler) { this .nextHandler = nextHandler; } @Override public void handle(BusinessAuditlist auditlist, SysUser user, String status, String reason) { if (auditlist.getAuditLink() == 1 ) { auditlist.setAudit2UserId(user.getUserId()); auditlist.setAudit2Time(DateUtils.getNowDate()); auditlist.setAudit2UserName(user.getNickName()); auditlist.setAudit2Status(status); auditlist.setAudit2Reason(reason); } else if (nextHandler != null ) { nextHandler.handle(auditlist, user, status, reason); } else { throw new RuntimeException( "审核失败" ); } } } |
另外3,4,5级审批同上
2.4:组成链路关系类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package com.jeethink.project.business.audit; import com.jeethink.project.business.domain.BusinessAuditlist; import com.jeethink.project.system.domain.SysUser; /** * 组成链路关系 */ public class AuditHandlerChain { private AuditHandler headHandler; public void setHeadHandler(AuditHandler headHandler) { this .headHandler = headHandler; } public void handle(BusinessAuditlist auditlist, SysUser user, String status, String reason) { headHandler.handle(auditlist, user, status, reason); } } |
2.5:审核业务代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | /** * 责任链设计模式 * @param businessAuditlist * @return */ @PreAuthorize ( "@ss.hasPermi('business:auditlist:edit')" ) @Log (title = "待审核业务" , businessType = BusinessType.UPDATE) @PutMapping ( "/audit" ) public AjaxResult audit( @RequestBody BusinessAuditlist businessAuditlist) { BusinessAuditlist temp = businessAuditlistService.selectBusinessAuditlistById(businessAuditlist.getId()); if (temp == null ) { return AjaxResult.error( "查询待审核信息失败" ); } //当前审核人不是指定的审核人 if (!Objects.equals(temp.getNestAudituserid(), getUserId())){ return AjaxResult.error( "非期望审核用户" ); } SysUser sysUser = getLoginUser().getUser(); //查询出此环节的各个审核人 AuditUserInfoParam auditUserInfoParam = new AuditUserInfoParam(); auditUserInfoParam.setBusinessType(temp.getBusinessType()); //todo 部门,单位 BusinessAudituser audituser = audituserService.selectAuditUserByParam(auditUserInfoParam); //创建责任链 AuditHandlerChain handlerChain = new AuditHandlerChain(); AuditHandler1 handler1 = new AuditHandler1(); AuditHandler2 handler2 = new AuditHandler2(); AuditHandler3 handler3 = new AuditHandler3(); AuditHandler4 handler4 = new AuditHandler4(); AuditHandler5 handler5 = new AuditHandler5(); handler1.setNextHandler(handler2); handler2.setNextHandler(handler3); handler3.setNextHandler(handler4); handler4.setNextHandler(handler5); handlerChain.setHeadHandler(handler1); handlerChain.handle(temp, sysUser, businessAuditlist.getAuditStatus(), businessAuditlist.getAuditReason()); //审核成功 if ( "1" .equals(businessAuditlist.getAuditStatus())) { //审核环节自增,指定下一级审核 temp.setAuditLink(temp.getAuditLink() + 1 ); if (temp.getAuditLink() < 5 && audituser != null ) { Long nextAuditUserId = null ; switch (( int ) temp.getAuditLink()) { case 1 : //记录下一级审核人 nextAuditUserId = audituser.getAudit2UserId(); if ( null != nextAuditUserId){ temp.setAudit2Status( "0" ); temp.setAudit2UserId(audituser.getAudit2UserId()); temp.setAudit2UserName(audituser.getAudit2UserName()); } break ; case 2 : nextAuditUserId = audituser.getAudit3UserId(); if ( null != nextAuditUserId) { temp.setAudit3Status( "0" ); temp.setAudit3UserId(audituser.getAudit3UserId()); temp.setAudit3UserName(audituser.getAudit3UserName()); } break ; case 3 : nextAuditUserId = audituser.getAudit4UserId(); if ( null != nextAuditUserId) { temp.setAudit4Status( "0" ); temp.setAudit4UserId(audituser.getAudit4UserId()); temp.setAudit4UserName(audituser.getAudit4UserName()); } break ; case 4 : nextAuditUserId = audituser.getAudit5UserId(); if ( null != nextAuditUserId) { temp.setAudit5Status( "0" ); temp.setAudit5UserId(audituser.getAudit5UserId()); temp.setAudit5UserName(audituser.getAudit5UserName()); } break ; default : return AjaxResult.error( "审核环节出错" ); } //下一级审核人不为空时,责任链往下继续 if (nextAuditUserId != null ) { temp.setNestAudituserid(nextAuditUserId); } else { //下一级审核人为空时,下级审核人为null,正常状态下级审核人会直接为空,直接审核修改这条数据,标识已审核成功 temp.setNestAudituserid( null ); temp.setIsComplete( "1" ); businessAuditlistService.handleAuditList(temp, businessAuditlist.getAuditReason()); } } } if ( "2" .equals(businessAuditlist.getAuditStatus())){ //todo 驳回将原表的状态改为驳回,记录驳回原因 businessAuditlistService.handleUnAuditList(temp,businessAuditlist.getAuditReason()); //并且将当前审核的环节改为最终 temp.setNestAudituserid( null ); temp.setIsComplete( "1" ); } return toAjax(businessAuditlistService.updateBusinessAuditlist(temp)); } |
本质上是每次审核成功查出当前责任链对应的审核用户,而后审核环节自增,指定下一个指定人,当当前审核用户与期望审核人不同是,直接返回错误信息
2.6:审核业务代码
1 | handleAuditList |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /** * 审核功能 * @param temp 待审核对象 * @return */ @Override @Transactional public int handleAuditList(BusinessAuditlist temp,String auditReason) { //todo 根据当前用户审核权限进行不用的审核流程 int i = 0 ; switch (temp.getBusinessType()){ case "AssetsReceive" : i = assetsReceiveService.auditAssetsReceive(temp.getApplyId(),auditReason); break ; case "AssetsTransfer" : i =assetsTransferService.auditAssetsTransfer(temp.getApplyId(),auditReason); break ; case "AssetsLease" : i = assetsLeaseService.auditAssetsLease(temp.getApplyId(),auditReason); break ; case "AssetsMaintenance" : i = assetsMaintenanceService.auditAssetsMaintenance(temp.getApplyId(),auditReason); break ; case "AssetsLend" : i = assetsLendService.auditAssetsLend(temp.getApplyId(),auditReason); break ; case "AssetsBorrow" : i = assetsBorrowService.auditAssetsBorrow(temp.getApplyId(),auditReason); break ; default : break ; } this .updateBusinessAuditlist(temp); return i; } |
再最后更新一下这条审核记录即可,多级审核便完成
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)