審批流程系統設計與實現:狀態驅動、靈活擴展的企業級解決方案

審批流程系統設計與實現:狀態驅動、靈活擴展的企業級解決方案

本文基于實際企業級審批系統源碼,深入解析如何設計高擴展性、強一致性的審批流程引擎,涵蓋狀態機設計、多租戶隔離、文件服務集成等核心實現。

1. 系統設計概覽

審批系統的核心架構分為三大模塊:

  • 公共模塊:枚舉定義、DTO對象、基礎轉換器
  • 審批模塊:流程引擎核心實現、模板管理
  • 業務模塊:具體業務審批處理器

2. 公共模塊設計精要

2.1 狀態枚舉設計

通過枚舉實現狀態機是審批系統的核心設計模式:

// 業務流程狀態機
public enum ApprovalStatus {PENDING("待提交"),SUBMITTED("已提交"),APPROVED("審批通過"),REJECTED("拒絕"),WITHDRAW("撤回");
}// 流程執行狀態
public enum ProcessStatus {IN_PROGRESS("處理中"),APPROVED("通過"),REJECTED("拒絕"),WITHDRAW("撤回");
}// 審批模式
public enum ApprovalMode {SERIAL,  // 串簽:順序審批PARALLEL // 會簽:并行審批
}

設計亮點

  • 使用@Schema注解實現OpenAPI文檔自動生成
  • 通過description字段支持多語言擴展
  • 嚴格區分流程狀態與業務狀態
2.2 DTO對象設計

數據傳輸對象實現分層解耦:

// 審批流程DTO
public class ApprovalProcessDTO {private Long id;private int currentStep; // 當前步驟private ProcessStatus processStatus;private List<ApprovalStepDTO> approvalStepDTOList; // 步驟樹
}// 審批步驟DTO
public class ApprovalStepDTO {private Integer stepOrder;private StepStatus stepStatus;private ApprovalMode approvalMode; private List<ApproverDTO> approverDTOList; // 審批人列表
}

分層結構

BusinessDTO └── ApprovalProcessDTO└── ApprovalStepDTO└── ApproverDTO

3. 審批流程引擎核心實現

3.1 狀態機流轉邏輯
PENDING:
創建流程
PENDING
SUBMITTED:
提交
SUBMITTED
IN_PROGRESS:
啟動審批
IN_PROGRESS
APPROVED:
最后一步通過
REJECTED:
任意步驟拒絕
APPROVED
REJECTED
WITHDRAW:
用戶撤回
3.2 多模式審批處理

會簽(Parallel)模式處理邏輯

// ApprovalProcessService.java
private void checkStepCompletion(ApprovalStep step, ApprovalProcess process, ApprovalStatus currentStatus) {if (step.getApprovalMode() == ApprovalMode.PARALLEL) {// 會簽模式:任一拒絕即整體拒絕boolean anyRejected = approverList.stream().anyMatch(a -> a.getStatus() == ApproverStatus.REJECTED);if (anyRejected) {rejectProcess(process); // 觸發流程拒絕} // 所有審批人通過才進入下一步else if (allApproved(approverList)) {moveToNextStep(process);}}
}

串簽(Serial)模式處理邏輯

private void moveToNextApproverOrStep(ApprovalStep step, ApprovalProcess process) {if (step.getApprovalMode() == ApprovalMode.SERIAL) {// 查找下一個待處理審批人Optional<ApprovalStepApprover> nextApprover = approverRepository.findFirstByStepIdAndStatusOrderById(step.getId(), ApproverStatus.PENDING);if (nextApprover.isPresent()) return; // 不移動步驟}moveToNextStep(process); // 移動到下一步
}

4. 文件服務深度集成

4.1 文件關聯設計
@Entity
public class ApprovalStepApprover {@Idprivate Long id;// 通過approverId關聯文件private String approverId; 
}@Entity
public class BaseFile {private String approverId; // 關聯審批人private String objectName; // MinIO存儲標識
}
4.2 文件操作服務
@Service
public class MinioService {// 生成唯一存儲路徑private String generateObjectName(String suffix) {return "approval/" + UUID.randomUUID() + "." + suffix;}// 上傳并關聯審批人public void uploadFile(String objectName, MultipartFile file) {minioClient.putObject(PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(file.getInputStream(), file.getSize(), -1).build());}// 生成臨時訪問鏈接public String getPresignedUrl(String objectName) {return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(objectName).expiry(3600) // 1小時有效.build());}
}

5. 擴展性設計

5.1 業務處理器注冊機制
@Service
public class ApprovalProcessService {private final Map<BusinessType, Consumer<FinishApprovalDTO>> approvalHandlers;@PostConstructvoid initHandlers() {// 注冊原油業務處理器EnumSet.of(BusinessType.CRUDE_OIL_PURCHASE_CONFIRM_ORDER,BusinessType.CRUDE_OIL_PURCHASE_PLAN).forEach(type -> approvalHandlers.put(type, crudeOilMngClient::finishApproval));// 注冊原材料業務處理器approvalHandlers.put(BusinessType.RAW_MATERIAL_PROCUREMENT_PLAN, rawMaterialMngClient::finishApproval);}private void finishApproval(FinishApprovalDTO dto) {approvalHandlers.get(dto.getBusinessType()).accept(dto);}
}
5.2 新增業務接入步驟
  1. BusinessType枚舉中添加新業務類型
  2. 實現ApprovalHandler接口
@Component
public class NewBusinessHandler implements ApprovalHandler {@Overridepublic BusinessType getSupportedType() {return BusinessType.NEW_BUSINESS;}@Overridepublic void handleApproval(Long businessId, ApprovalStatus status) {// 實現業務狀態更新邏輯}
}
  1. FinishApprovalService中自動注冊處理器

6. 性能優化實踐

6.1 審批流程保存優化
// 批量保存優化:減少DB交互
private List<ApprovalStepDTO> saveSteps(Long processId, List<ApprovalStepDTO> stepDTOs) {// 批量保存步驟List<ApprovalStep> steps = stepRepository.saveAll(stepDTOs.stream().map(dto -> {ApprovalStep step = new ApprovalStep();step.setProcessId(processId);return step;}).collect(Collectors.toList()));// 批量保存審批人List<ApprovalStepApprover> approvers = new ArrayList<>();steps.forEach(step -> {stepDTOs.get(step.getStepOrder()-1).getApproverDTOList().forEach(approverDTO -> {ApprovalStepApprover a = new ApprovalStepApprover();a.setStepId(step.getId());approvers.add(a);});});approverRepository.saveAll(approvers);return convertToDTOs(steps);
}
6.2 文件清理任務
@Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2點執行
public void clearOrphanFiles() {List<BaseFile> orphans = baseFileRepository.findOrphanFiles();List<String> objectNames = orphans.stream().map(BaseFile::getObjectName).collect(Collectors.toList());minioService.removeFiles(objectNames); // 批量刪除baseFileRepository.deleteAll(orphans);
}

7. 關鍵設計決策總結

設計選擇優勢應用場景
枚舉狀態機編譯時檢查、杜絕無效狀態流程狀態管理
DTO分層結構解耦持久層與展示層API接口設計
審批模式策略靈活支持不同審批場景會簽/串簽流程
處理器注冊機制開閉原則支持擴展新增業務審批
文件元數據分離獨立管理存儲資源附件管理

最佳實踐建議

  1. 狀態驅動開發:所有業務邏輯圍繞狀態流轉實現
  2. 防腐層設計:通過DTO隔離領域模型與接口模型
  3. 冪等性保證:審批操作需支持重復提交
  4. 事件溯源:關鍵狀態變更記錄審計日志
  5. 資源隔離:按業務類型隔離審批流程實例

完整實現源碼將托管至unknown:TODO

通過本文展示的審批系統設計,開發者可快速構建支持復雜業務流程的企業級審批引擎,其模塊化設計和擴展機制能滿足各類業務場景的審批需求。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/93001.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/93001.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/93001.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

汽車免拆診斷案例 | 2010款奧迪A4L車行駛中發動機偶爾自動熄火

故障現象 一輛2010款奧迪A4L車&#xff0c;搭載CDZ發動機 &#xff0c;累計行駛里程約為18.2萬km。該車行駛中發動機偶爾自動熄火&#xff0c;有時熄火后能夠立即重新起動著機&#xff0c;有時需要等待一會兒才能重新起動著機&#xff0c;故障頻率較低。因該故障在其他維修廠陸…

Liam ERD:自動生成美觀的交互式實體關系圖

Liam ERD 是一個可以快速生成美觀且具有交互性的數據庫實體關系圖&#xff08;ERD&#xff09;的工具&#xff0c;可以幫助用戶實現復雜數據庫結構的可視化。 Liam ERD 是一個免費開源的項目&#xff0c;代碼托管在 GitHub&#xff1a; https://github.com/liam-hq/liam 功能…

網絡協議序列化工具Protobuf

目錄前言一、下載注意二、解壓安裝三、Protobuf的使用1、創建.proto文件2、利用protoc編譯.proto文件前言 Protocol Buffers是Google的?種語??關、平臺?關、可擴展的序列化結構數據的?法&#xff0c;它可?于&#xff08;數據&#xff09;通信協議、數據存儲等。 Protoco…

從表單校驗到API網關:全鏈路輸入安全防護指南

從表單校驗到 API 網關:全鏈路輸入安全防護指南 在軟件系統的安全防御體系中,輸入安全是第一道防線,而這道防線的堅固程度直接決定了系統抵御外部攻擊的能力。從用戶在瀏覽器中填寫表單的那一刻起,到數據經過 API 網關流轉至后端服務,每一個環節都可能成為輸入攻擊的突破…

Flask vs Django:微框架與一站式對決

Flask 簡介 1、簡介 Flask誕生于2010年&#xff0c;是Armin ronacher用Python語言基于Werkzeug工具箱編寫的輕量級Web開發框架&#xff0c;又稱之為微框架。 "微"的含義&#xff1a;Flask旨在保持核心簡潔&#xff0c;本身相當于內核&#xff0c;其他功能需通過擴展…

真實業務場景:mysql慢查詢優化(從17秒的查詢優化到700毫秒)

慢查詢業務場景:原先在我們系統中要統計一些人員的單位 部門信息的數據情況&#xff0c;比如總的男女人數&#xff0c;每個單位下的男女人數等等&#xff0c;然后原來的sql是這樣寫的 根據一個單位的id 然后對一張表做出多個子查詢進行查詢&#xff0c;這時候統計記錄 由于加載…

遠程影音訪問:通過 cpolar 內網穿透服務使用 LibreTV

文章目錄前言【視頻教程】1.關于LibreTV2.docker部署LibreTV3.簡單使用LibreTV4.安裝cpolar內網穿透5.配置ward公網地址6.配置固定公網地址總結LibreTV 與 cpolar 的協同應用&#xff0c;為用戶打造了一條通往高清觀影自由的便捷之路。通過這一方案&#xff0c;用戶不僅擺脫了商…

Apache ECharts 6 核心技術解密 – Vue3企業級可視化實戰指南

簡介 ECharts 是百度開源的一個使用 JavaScript 實現的開源可視化庫&#xff0c;它能夠生動、可交互地展示數據。在 Vue3 項目中集成 ECharts 可以讓你的項目更加直觀和動態地呈現數據信息。 核心優勢 特性SVG渲染器Canvas渲染器縮放保真度★★★★★★★☆☆☆動態交互性能…

考公VS考研,拼哪個性價比高?

即將到來下半年&#xff0c;將迎來考公和考研是兩個非常重要的考試&#xff0c;也是許多年輕人為之奮斗的目標。無論是獲得一份穩定的“鐵飯碗”&#xff0c;還是提升學歷學位獲得更高的競爭力&#xff0c;都是值得努力的方向。那么&#xff0c;考公vs考研&#xff0c;到底哪個…

python2操作neo4j

環境依賴 jdk、neo4j圖數據庫 操作一條數據完整demo import os,json,sys,io from py2neo import Graph,Nodetry:sys.stdout io.TextIOWrapper(sys.stdout.buffer, encodingutf-8)sys.stderr io.TextIOWrapper(sys.stderr.buffer, encodingutf-8) except Exception:passcla…

AI 編程實踐:用 Trae 快速開發 HTML 貪吃蛇游戲

1. 背景與目標 貪吃蛇是最適合入門的 2D 網頁小游戲之一&#xff1a;規則簡單、反饋清晰、可擴展空間大&#xff08;穿墻模式、道具、多食物、排行榜……&#xff09;。 demo地址&#xff1a;https://game.haiyong.site/snake-game.html 本項目的目標是&#xff1a; 純前端、…

FreeRTOS-C語言指針筆記

文章目錄一級指針指針基本概念指針使用示例代碼說明二、二級指針二級指針重點解析一級指針 C語言中的指針是一個非常重要的概念&#xff0c;它存儲了變量的內存地址。指針的使用可以使程序更加高效&#xff0c;尤其在處理數組、字符串和動態內存分配時。 指針基本概念 指針變…

界面布局智能建議生成:從功能需求到專業UI的AI加速之路

內容簡介: 傳統界面設計讓產品經理陷入"不懂設計、等設計師"的困境&#xff0c;效率低下還容易被挑刺。本文深度解析DeepSeek驅動的界面布局智能生成技術&#xff0c;通過DESIGN框架提示詞模板&#xff0c;讓產品經理在30分鐘內生成3種專業級界面方案&#xff0c;實現…

【BLE系列-第三篇】數據鏈路層(LL):廣播/連接/掃描流程詳解

目錄 引言 一、廣播及連接建立 1.1 廣播類型 1.2 掃描/連接請求與響應 1.2.1 廣播流程說明 1.2.1.1 廣播流程示例圖 1.2.1.2 廣播信息設置 1.2.1.3 信道廣播 1.2.1.4 信道切換 1.2.1.5 廣播間隔 1.2.1.6 接收窗口與理論最小傳輸時間 1.2.2 掃描/連接流程說明 1.2.…

JMeter 測試 WebSocket 接口的詳細教程

1. 安裝 WebSocket 插件 方法一&#xff1a;通過 Plugins Manager 下載并安裝 JMeter Plugins Manager在 JMeter 中&#xff1a;Options → Plugins Manager搜索 WebSocket 并安裝 方法二&#xff1a;手動安裝 下載 jmeter-websocket-samplers 插件將 jar 文件放到 JMeter/…

飛算JavaAI智慧教育場景實踐:從個性化學習到教學管理的全鏈路技術革新

目錄一、智慧教育核心場景的技術突破1.1 個性化學習路徑推薦系統1.1.1 學習者能力建模與評估1.2 智能教學管理系統1.2.1 自動化作業批改與學情分析1.3 教育資源智能管理系統1.3.1 教育資源智能標簽與推薦二、智慧教育系統效能升級實踐2.1 教育數據中臺構建2.1.1 教育數據整合與…

Java面試場景題大全精簡版

1.分布式系統下如何實現服務限流核心算法&#xff1a;固定窗口&#xff1a;將時間劃分為固定窗口&#xff08;如 1 秒&#xff09;&#xff0c;統計窗口內請求數&#xff0c;超過閾值則限流。實現簡單但存在臨界值突發流量問題。滑動窗口&#xff1a;將固定窗口拆分為多個小窗口…

紅帽 AI 推理服務 (vLLM) - 入門篇

《教程匯總》 RedHat AI Inference Server 和 vLLM vLLM (Virtual Large Language Model) 是一款專為大語言模型推理加速而設計的框架。它是由加州大學伯克利分校 (UC Berkeley) 的研究團隊于 2023 年開源的項目&#xff0c;目前 UC Berkeley 和 RedHat 分別是 vLLM 開源社區…

Sql server 命令行和控制臺使用二三事

近來遇到了幾件關于sql server的事情。 第一&#xff1a;低版本sqlserver備份竟然無法還原到高版本 奇怪&#xff01;從來未碰到過。過程如下&#xff1a; 1.在低版本上中備份好了數據庫 2.通過共享將文件拷貝到新服務器上 3.打開控制臺&#xff0c;還原數據庫&#xff0c;結果…

vue excel轉json功能 xlsx

需求&#xff1a; 完成excel表格內容轉json&#xff0c;excel表格內可能存在多個表格&#xff0c;要求全部解析出來。完成表格內合服功能&#xff0c;即&#xff1a;提取表格內老服務器與新服務器數據&#xff0c;多臺老服務器對應合并到一臺新服務器上 3.最終輸出結果為:[{‘1…