From 7d2ee3cef2e0d68ba6400bc5957640d2771bbf4c Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期三, 16 九月 2026 18:05:40 +0800
Subject: [PATCH] refactor: 单据审核改为审批配置状态机(新增:audit接口/审核人字段/DB变更脚本)

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectRespVO.java                        |   16 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/vo/invoice/CrmInvoiceRespVO.java                     |   16 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/attendance/HrmAttendanceExceptionDO.java                       |   22 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/stocktaking/task/MesWmStockTakingTaskDO.java                |   27 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/CrmCancellationController.java                  |   35 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/vo/MesWmEquipmentReceiptAuditReqVO.java  |   28 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorService.java                         |   37 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemreceipt/MesWmItemReceiptDO.java                         |   19 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceExceptionController.java             |   31 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorRespVO.java              |   13 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptService.java                           |   27 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java                                        |    2 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java                     |  133 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptController.java               |   30 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscissue/MesWmMiscIssueDO.java                             |   19 
 yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java                                 |    5 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdProjectStatusEnum.java                                          |    4 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationServiceImpl.java                       |  162 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java                          |   26 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmResignationApplicationServiceImpl.java                    |  170 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueRespVO.java                    |   13 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/refund/CrmRefundMapper.java                                         |   45 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/vo/HrmAttendanceExceptionRespVO.java              |   13 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmResignationApplicationMapper.java                       |   46 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/cancellation/CrmCancellationService.java                              |   37 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/attendance/HrmAttendanceExceptionMapper.java                        |   47 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceService.java                                        |   39 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmResignationApplicationRespVO.java             |   13 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptRespVO.java                |   13 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/cancellation/CrmCancellationDO.java                            |   18 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/MesWmMiscIssueController.java                   |   26 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java                                    |   28 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmTransferApplicationAuditReqVO.java            |   27 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/refund/CrmRefundService.java                                          |   37 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/finance/ErpFinancePaymentDO.java                               |   26 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractAuditReqVO.java              |   30 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmLeaveApplicationServiceImpl.java                          |  180 -
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmResignationApplicationController.java            |   37 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/miscissue/MesWmMiscIssueMapper.java                              |   43 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java                                      |   31 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmTransferApplicationMapper.java                          |   47 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmRegularizeApplicationMapper.java                        |   46 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationAuditReqVO.java               |   24 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundAuditReqVO.java                           |   24 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmResignationApplicationDO.java                      |   22 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmLeaveApplicationMapper.java                             |   44 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/refund/CrmRefundDO.java                                        |   18 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmResignationApplicationAuditReqVO.java         |   27 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmRegularizeApplicationServiceImpl.java                     |  174 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmServiceImpl.java                     |  158 +
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundRespVO.java                               |   13 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentAuditReqVO.java          |   27 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestAuditReqVO.java        |   25 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestRespVO.java            |   20 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/vo/HrmPerformanceAppraiseRespVO.java     |   14 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/vo/MesWmStockTakingTaskRespVO.java       |   13 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/MesWmEquipmentReceiptServiceImpl.java             |  133 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java                                  |  170 -
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorController.java             |   26 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmRespVO.java              |    8 
 yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java                                     |    8 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/performanceappraise/HrmPerformanceAppraiseDO.java              |   17 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceExceptionService.java                         |   28 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/miscreceipt/MesWmMiscReceiptMapper.java                          |   44 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestService.java                               |   40 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestServiceImpl.java                           |  163 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemreceipt/MesWmItemReceiptMapper.java                          |   43 
 yudao-module-hrm-api/src/main/java/cn/iocoder/yudao/module/hrm/enums/ErrorCodeConstants.java                                             |   33 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/vo/HrmAttendanceExceptionAuditReqVO.java          |   27 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationService.java                           |   44 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/vo/HrmPerformanceAppraiseAuditReqVO.java |   14 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmTransferApplicationDO.java                         |   22 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptAuditReqVO.java            |   28 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmRegularizeApplicationDO.java                       |   22 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdTechConfirmStatusEnum.java                                      |   46 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmTransferApplicationRespVO.java                |   13 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java                             |  136 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueServiceImpl.java                           |  133 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/performanceappraise/HrmPerformanceAppraiseMapper.java               |   48 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/HrmPerformanceAppraiseService.java                |   31 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java                                                 |   14 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnvendor/MesWmReturnVendorDO.java                       |   19 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/HrmPerformanceAppraiseController.java    |   27 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pd/techconfirm/ProductTechConfirmMapper.java                        |   46 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptRespVO.java                |   13 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java                  |   15 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmTransferApplicationController.java               |   33 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueAuditReqVO.java                |   28 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmLeaveApplicationRespVO.java                   |   13 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmRegularizeApplicationService.java                         |   39 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskStatusEnum.java                                  |    2 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptService.java                           |   36 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskService.java                  |   54 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationRespVO.java                   |   13 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundSaveReqVO.java                            |   13 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmResignationApplicationService.java                        |   44 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/equipmentreceipt/MesWmEquipmentReceiptDO.java               |   19 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptServiceImpl.java                       |  132 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/MesWmMiscReceiptController.java               |   26 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentRespVO.java              |   17 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseRequestMapper.java                              |   32 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmLeaveApplicationController.java                  |   33 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/cancellation/CrmCancellationMapper.java                             |   45 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmRegularizeApplicationAuditReqVO.java          |   27 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/vo/invoice/CrmInvoiceAuditReqVO.java                 |   30 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/ProductTechConfirmController.java             |   40 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java                       |  139 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java                                                 |   21 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/MesWmEquipmentReceiptController.java     |   26 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/CrmRefundController.java                              |   35 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/MesWmStockTakingTaskController.java      |   25 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectAuditReqVO.java                    |   30 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnvendor/MesWmReturnVendorMapper.java                        |   44 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseRequestDO.java                             |   26 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/invoice/CrmInvoiceMapper.java                                       |   45 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmSaveReqVO.java           |   46 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pd/project/MesPdProjectMapper.java                                  |   46 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinancePaymentController.java                     |   31 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java                                    |  101 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/HrmPerformanceAppraiseServiceImpl.java            |  192 -
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/stocktaking/task/MesWmStockTakingTaskMapper.java                 |   73 
 yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java                               |   35 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmLeaveApplicationService.java                              |   44 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscreceipt/MesWmMiscReceiptDO.java                         |   19 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskServiceImpl.java              |  164 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/equipmentreceipt/MesWmEquipmentReceiptMapper.java                |   44 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/invoice/CrmInvoiceDO.java                                      |   19 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectServiceImpl.java                               |  130 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/MesPdProjectController.java                       |   28 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmLeaveApplicationDO.java                            |   22 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java                                     |   44 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmLeaveApplicationAuditReqVO.java               |   27 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceExceptionServiceImpl.java                     |  110 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmService.java                         |   88 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmRegularizeApplicationController.java             |   34 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorAuditReqVO.java          |   28 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/techconfirm/ProductTechConfirmDO.java                       |   18 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/vo/MesWmEquipmentReceiptRespVO.java      |   13 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueService.java                               |   36 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationSaveReqVO.java                |   13 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseRequestController.java                   |   29 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/vo/MesWmStockTakingTaskAuditReqVO.java   |   30 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java                                      |    2 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentService.java                                 |   39 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/MesWmEquipmentReceiptService.java                 |   36 
 /dev/null                                                                                                                                |   46 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectService.java                                   |   31 
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmRegularizeApplicationRespVO.java              |   13 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmAuditReqVO.java          |   30 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptAuditReqVO.java            |   30 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/finance/ErpFinancePaymentMapper.java                                |   31 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/project/MesPdProjectDO.java                                 |   19 
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/CrmInvoiceController.java                            |   22 
 153 files changed, 4,259 insertions(+), 2,249 deletions(-)

diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/CrmCancellationController.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/CrmCancellationController.java
index dcab261..2ae6612 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/CrmCancellationController.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/CrmCancellationController.java
@@ -21,12 +21,11 @@
 
 import java.io.IOException;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 @Tag(name = "绠$悊鍚庡彴 - CRM 閿�鎴风敵璇�")
 @RestController
@@ -52,28 +51,28 @@
         return success(true);
     }
 
-    @PutMapping("/audit")
-    @Operation(summary = "瀹℃壒閿�鎴风敵璇凤紙閫氳繃/椹冲洖锛�")
-    @PreAuthorize("@ss.hasPermission('crm:cancellation:update')")
-    public CommonResult<Boolean> auditCancellation(@Valid @RequestBody CrmCancellationAuditReqVO auditReqVO) {
-        cancellationService.auditCancellation(auditReqVO);
-        return success(true);
-    }
-
     @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦閿�鎴风敵璇峰鎵�")
+    @Operation(summary = "鎻愪氦閿�鎴风敵璇峰鎵癸紙鑽夌/瀹℃牳涓嶉�氳繃鈫掑鎵逛腑锛夛紝瀹℃壒浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
+    @Parameter(name = "id", description = "缂栧彿", required = true)
     @PreAuthorize("@ss.hasPermission('crm:cancellation:update')")
-    public CommonResult<Boolean> submitCancellation(@RequestParam("id") Long id,
-                                                    @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        cancellationService.submitCancellation(id, processDefinitionKey, getLoginUserId());
+    public CommonResult<Boolean> submitCancellation(@RequestParam("id") Long id) {
+        cancellationService.submitCancellation(id);
         return success(true);
     }
 
-    @GetMapping("/approve-process-list")
-    @Operation(summary = "鑾峰緱閿�鎴风敵璇峰鎵规祦绋嬪畾涔夊垪琛�")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳閿�鎴风敵璇凤紙瀹℃壒涓啋瀹℃牳閫氳繃/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('crm:cancellation:audit')")
+    public CommonResult<Boolean> auditCancellation(@Valid @RequestBody CrmCancellationAuditReqVO auditReqVO) {
+        cancellationService.auditCancellation(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱閿�鎴风敵璇风殑瀹℃壒浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
     @PreAuthorize("@ss.hasPermission('crm:cancellation:query')")
-    public CommonResult<List<Map<String, Object>>> getCancellationApproveProcessDefinitionList() {
-        return success(cancellationService.getCancellationApproveProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(cancellationService.getCancellationApproverUserIds());
     }
 
     @DeleteMapping("/delete")
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationAuditReqVO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationAuditReqVO.java
index 48844f9..7d9d848 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationAuditReqVO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationAuditReqVO.java
@@ -4,19 +4,27 @@
 import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 
-@Schema(description = "绠$悊鍚庡彴 - CRM 閿�鎴风敵璇峰鎵� Request VO")
+/**
+ * CRM 閿�鎴风敵璇峰鏍� Request VO
+ *
+ * 瀹℃牳閫氳繃 / 涓嶉�氳繃鍏辩敤鏈� VO锛岀敱 pass 鍖哄垎锛�
+ * 閫氳繃鏃跺鏍告剰瑙侀�夊~锛屼笉閫氳繃鏃跺鏍告剰瑙侊紙涓嶉�氳繃鍘熷洜锛夊繀濉紝鐢� Service 鏍¢獙銆�
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - CRM 閿�鎴风敵璇峰鏍� Request VO")
 @Data
 public class CrmCancellationAuditReqVO {
 
-    @Schema(description = "閿�鎴风敵璇风紪鍙�", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "閿�鎴风敵璇风紪鍙�", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotNull(message = "閿�鎴风敵璇风紪鍙蜂笉鑳戒负绌�")
     private Long id;
 
-    @Schema(description = "瀹℃壒缁撴灉锛�20=閫氳繃 / 30=椹冲洖", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "瀹℃壒缁撴灉涓嶈兘涓虹┖")
-    private Integer auditStatus;
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
 
-    @Schema(description = "瀹℃壒鎰忚")
-    private String remark;
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃堕�夊~ / 瀹℃牳涓嶉�氳繃鏃跺繀濉紝鍗充笉閫氳繃鍘熷洜锛�", example = "璇峰厛缁撴竻娆犺垂")
+    private String reviewRemark;
 
-}
\ No newline at end of file
+}
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationRespVO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationRespVO.java
index 8696a9c..7fb64cd 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationRespVO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationRespVO.java
@@ -81,8 +81,17 @@
     @DictFormat(CRM_AUDIT_STATUS)
     private Integer auditStatus;
 
-    @Schema(description = "娴佺▼瀹炰緥ID")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�")
+    private String reviewRemark;
 
     @Schema(description = "澶囨敞")
     @ExcelProperty("澶囨敞")
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationSaveReqVO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationSaveReqVO.java
index ff24197..3fe3100 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationSaveReqVO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/cancellation/vo/CrmCancellationSaveReqVO.java
@@ -62,8 +62,17 @@
     @Schema(description = "瀹℃壒鐘舵�侊紙0鑽夌/10寰呭鎵�/20閫氳繃/30椹冲洖锛�", example = "0")
     private Integer auditStatus;
 
-    @Schema(description = "娴佺▼瀹炰緥ID")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�")
+    private String reviewRemark;
 
     @Schema(description = "澶囨敞")
     private String remark;
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
index 411a69a..9e2719c 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
@@ -10,6 +10,7 @@
 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractAuditReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractPageReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO;
 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractSaveReqVO;
@@ -48,6 +49,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.stream.Stream;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
@@ -189,19 +191,27 @@
     }
 
     @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦鍚堝悓瀹℃壒")
+    @Operation(summary = "鎻愪氦鍚堝悓瀹℃壒锛堟湭鎻愪氦/瀹℃牳涓嶉�氳繃鈫掑鎵逛腑锛夛紝瀹℃壒浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
+    @Parameter(name = "id", description = "鍚堝悓缂栧彿", required = true)
     @PreAuthorize("@ss.hasPermission('crm:contract:update')")
-    public CommonResult<Boolean> submitContract(@RequestParam("id") Long id,
-                                                  @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        contractService.submitContract(id, processDefinitionKey, getLoginUserId());
+    public CommonResult<Boolean> submitContract(@RequestParam("id") Long id) {
+        contractService.submitContract(id);
         return success(true);
     }
 
-    @GetMapping("/approve-process-list")
-    @Operation(summary = "鑾峰彇鍚堝悓瀹℃壒娴佺▼鍒楄〃")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳鍚堝悓锛堝鎵逛腑鈫掑鏍搁�氳繃/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('crm:contract:audit')")
+    public CommonResult<Boolean> auditContract(@Valid @RequestBody CrmContractAuditReqVO auditReqVO) {
+        contractService.auditContract(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱鍚堝悓鐨勫鎵逛汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳")
     @PreAuthorize("@ss.hasPermission('crm:contract:query')")
-    public CommonResult<List<Map<String, Object>>> getContractApproveProcessList() {
-        return success(contractService.getContractApproveProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(contractService.getContractApproverUserIds());
     }
 
     private List<CrmContractRespVO> buildContractDetailList(List<CrmContractDO> contractList) {
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractAuditReqVO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractAuditReqVO.java
new file mode 100644
index 0000000..0d6e283
--- /dev/null
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractAuditReqVO.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * CRM 鍚堝悓瀹℃牳 Request VO
+ *
+ * 瀹℃牳閫氳繃 / 涓嶉�氳繃鍏辩敤鏈� VO锛岀敱 pass 鍖哄垎锛�
+ * 閫氳繃鏃跺鏍告剰瑙侀�夊~锛屼笉閫氳繃鏃跺鏍告剰瑙侊紙涓嶉�氳繃鍘熷洜锛夊繀濉紝鐢� Service 鏍¢獙銆�
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - CRM 鍚堝悓瀹℃牳 Request VO")
+@Data
+public class CrmContractAuditReqVO {
+
+    @Schema(description = "鍚堝悓缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "鍚堝悓缂栧彿涓嶈兘涓虹┖")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃堕�夊~ / 瀹℃牳涓嶉�氳繃鏃跺繀濉紝鍗充笉閫氳繃鍘熷洜锛�", example = "閲戦闇�涓庡鎴峰啀娆℃牳瀵�")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java
index fa8793e..95c8e8a 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java
@@ -52,9 +52,6 @@
     @ExcelProperty(value = "鎵�灞為儴闂�", index = 16)
     private String ownerUserDeptName;
 
-    @Schema(description = "宸ヤ綔娴佺紪鍙�", example = "1043")
-    private String processInstanceId;
-
     @Schema(description = "瀹℃壒鐘舵��", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
     private Integer auditStatus;
 
@@ -62,6 +59,18 @@
     @ExcelProperty(value = "鍚堝悓鐘舵��", index = 20)
     private String auditStatusName;
 
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "1024")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "寮犱笁")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堜笉閫氳繃鏃跺嵆涓嶉�氳繃鍘熷洜锛�", example = "閲戦闇�涓庡鎴峰啀娆℃牳瀵�")
+    private String reviewRemark;
+
     @Schema(description = "涓嬪崟鏃ユ湡", requiredMode = Schema.RequiredMode.REQUIRED)
     @ExcelProperty(value = "涓嬪崟鏃堕棿", index = 6)
     private LocalDateTime orderDate;
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/CrmInvoiceController.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/CrmInvoiceController.java
index 8397ad9..4d6da14 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/CrmInvoiceController.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/CrmInvoiceController.java
@@ -10,6 +10,7 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO;
+import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceAuditReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoicePageReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceRespVO;
 import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceSaveReqVO;
@@ -43,6 +44,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.stream.Stream;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
@@ -187,13 +189,29 @@
     }
 
     @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦寮�绁ㄥ鎵�")
+    @Operation(summary = "鎻愪氦寮�绁ㄥ鎵癸紙鑽夌/瀹℃牳涓嶉�氳繃鈫掑鎵逛腑锛夛紝瀹℃壒浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
+    @Parameter(name = "id", description = "缂栧彿", required = true)
     @PreAuthorize("@ss.hasPermission('crm:invoice:update')")
     public CommonResult<Boolean> submitInvoice(@RequestParam("id") Long id) {
-        invoiceService.submitInvoice(id, getLoginUserId());
+        invoiceService.submitInvoice(id);
         return success(true);
     }
 
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳寮�绁紙瀹℃壒涓啋瀹℃牳閫氳繃/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('crm:invoice:audit')")
+    public CommonResult<Boolean> auditInvoice(@Valid @RequestBody CrmInvoiceAuditReqVO auditReqVO) {
+        invoiceService.auditInvoice(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱寮�绁ㄧ殑瀹℃壒浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
+    @PreAuthorize("@ss.hasPermission('crm:invoice:query')")
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(invoiceService.getInvoiceApproverUserIds());
+    }
+
     @GetMapping("/audit-count")
     @Operation(summary = "鑾峰緱寰呭鏍稿紑绁ㄦ暟閲�")
     @PreAuthorize("@ss.hasPermission('crm:invoice:query')")
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/vo/invoice/CrmInvoiceAuditReqVO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/vo/invoice/CrmInvoiceAuditReqVO.java
new file mode 100644
index 0000000..3c14f1a
--- /dev/null
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/vo/invoice/CrmInvoiceAuditReqVO.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * CRM 寮�绁ㄥ鏍� Request VO
+ *
+ * 瀹℃牳閫氳繃 / 涓嶉�氳繃鍏辩敤鏈� VO锛岀敱 pass 鍖哄垎锛�
+ * 閫氳繃鏃跺鏍告剰瑙侀�夊~锛屼笉閫氳繃鏃跺鏍告剰瑙侊紙涓嶉�氳繃鍘熷洜锛夊繀濉紝鐢� Service 鏍¢獙銆�
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - CRM 寮�绁ㄥ鏍� Request VO")
+@Data
+public class CrmInvoiceAuditReqVO {
+
+    @Schema(description = "寮�绁ㄧ紪鍙�", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "寮�绁ㄧ紪鍙蜂笉鑳戒负绌�")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃堕�夊~ / 瀹℃牳涓嶉�氳繃鏃跺繀濉紝鍗充笉閫氳繃鍘熷洜锛�", example = "鍙戠エ鎶ご鏈夎")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/vo/invoice/CrmInvoiceRespVO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/vo/invoice/CrmInvoiceRespVO.java
index 57f86c5..e54e8ef 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/vo/invoice/CrmInvoiceRespVO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/invoice/vo/invoice/CrmInvoiceRespVO.java
@@ -69,15 +69,23 @@
     @ExcelProperty("璐熻矗浜洪儴闂�")
     private String ownerUserDeptName;
 
-    @Schema(description = "宸ヤ綔娴佺紪鍙�", example = "1043")
-    @ExcelProperty("宸ヤ綔娴佺紪鍙�")
-    private String processInstanceId;
-
     @Schema(description = "瀹℃壒鐘舵��", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
     @ExcelProperty(value = "瀹℃壒鐘舵��", converter = DictConvert.class)
     @DictFormat(DictTypeConstants.CRM_AUDIT_STATUS)
     private Integer auditStatus;
 
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�")
+    private String reviewRemark;
+
     @Schema(description = "澶囨敞", example = "澶囨敞")
     @ExcelProperty("澶囨敞")
     private String remark;
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/CrmRefundController.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/CrmRefundController.java
index 256bcda..e183ca7 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/CrmRefundController.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/CrmRefundController.java
@@ -21,12 +21,11 @@
 
 import java.io.IOException;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 @Tag(name = "绠$悊鍚庡彴 - CRM 閫�璐瑰崟")
 @RestController
@@ -52,28 +51,28 @@
         return success(true);
     }
 
-    @PutMapping("/audit")
-    @Operation(summary = "瀹℃壒閫�璐瑰崟锛堥�氳繃/椹冲洖锛�")
-    @PreAuthorize("@ss.hasPermission('crm:refund:update')")
-    public CommonResult<Boolean> auditRefund(@Valid @RequestBody CrmRefundAuditReqVO auditReqVO) {
-        refundService.auditRefund(auditReqVO);
-        return success(true);
-    }
-
     @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦閫�璐瑰崟瀹℃壒")
+    @Operation(summary = "鎻愪氦閫�璐瑰崟瀹℃壒锛堣崏绋�/瀹℃牳涓嶉�氳繃鈫掑鎵逛腑锛夛紝瀹℃壒浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
+    @Parameter(name = "id", description = "缂栧彿", required = true)
     @PreAuthorize("@ss.hasPermission('crm:refund:update')")
-    public CommonResult<Boolean> submitRefund(@RequestParam("id") Long id,
-                                              @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        refundService.submitRefund(id, processDefinitionKey, getLoginUserId());
+    public CommonResult<Boolean> submitRefund(@RequestParam("id") Long id) {
+        refundService.submitRefund(id);
         return success(true);
     }
 
-    @GetMapping("/approve-process-list")
-    @Operation(summary = "鑾峰緱閫�璐瑰崟瀹℃壒娴佺▼瀹氫箟鍒楄〃")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳閫�璐瑰崟锛堝鎵逛腑鈫掑鏍搁�氳繃/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('crm:refund:audit')")
+    public CommonResult<Boolean> auditRefund(@Valid @RequestBody CrmRefundAuditReqVO auditReqVO) {
+        refundService.auditRefund(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱閫�璐瑰崟鐨勫鎵逛汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳")
     @PreAuthorize("@ss.hasPermission('crm:refund:query')")
-    public CommonResult<List<Map<String, Object>>> getRefundApproveProcessDefinitionList() {
-        return success(refundService.getRefundApproveProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(refundService.getRefundApproverUserIds());
     }
 
     @DeleteMapping("/delete")
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundAuditReqVO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundAuditReqVO.java
index 684448c..9732347 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundAuditReqVO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundAuditReqVO.java
@@ -4,19 +4,27 @@
 import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 
-@Schema(description = "绠$悊鍚庡彴 - CRM 閫�璐瑰崟瀹℃壒 Request VO")
+/**
+ * CRM 閫�璐瑰崟瀹℃牳 Request VO
+ *
+ * 瀹℃牳閫氳繃 / 涓嶉�氳繃鍏辩敤鏈� VO锛岀敱 pass 鍖哄垎锛�
+ * 閫氳繃鏃跺鏍告剰瑙侀�夊~锛屼笉閫氳繃鏃跺鏍告剰瑙侊紙涓嶉�氳繃鍘熷洜锛夊繀濉紝鐢� Service 鏍¢獙銆�
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - CRM 閫�璐瑰崟瀹℃牳 Request VO")
 @Data
 public class CrmRefundAuditReqVO {
 
-    @Schema(description = "閫�璐瑰崟缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "閫�璐瑰崟缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     @NotNull(message = "閫�璐瑰崟缂栧彿涓嶈兘涓虹┖")
     private Long id;
 
-    @Schema(description = "瀹℃壒缁撴灉锛�20=閫氳繃 / 30=椹冲洖", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "瀹℃壒缁撴灉涓嶈兘涓虹┖")
-    private Integer auditStatus;
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
 
-    @Schema(description = "瀹℃壒鎰忚")
-    private String remark;
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃堕�夊~ / 瀹℃牳涓嶉�氳繃鏃跺繀濉紝鍗充笉閫氳繃鍘熷洜锛�", example = "閲戦闇�涓庡鎴峰啀娆℃牳瀵�")
+    private String reviewRemark;
 
-}
\ No newline at end of file
+}
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundRespVO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundRespVO.java
index 1069c2a..594d99e 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundRespVO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundRespVO.java
@@ -72,8 +72,17 @@
     @DictFormat(CRM_AUDIT_STATUS)
     private Integer auditStatus;
 
-    @Schema(description = "娴佺▼瀹炰緥ID")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�")
+    private String reviewRemark;
 
     @Schema(description = "澶囨敞")
     @ExcelProperty("澶囨敞")
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundSaveReqVO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundSaveReqVO.java
index 41855e8..2dc3326 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundSaveReqVO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/refund/vo/CrmRefundSaveReqVO.java
@@ -56,8 +56,17 @@
     @Schema(description = "瀹℃壒鐘舵�侊紙0鑽夌/10寰呭鎵�/20閫氳繃/30椹冲洖锛�", example = "0")
     private Integer auditStatus;
 
-    @Schema(description = "娴佺▼瀹炰緥ID")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�")
+    private String reviewRemark;
 
     @Schema(description = "澶囨敞")
     private String remark;
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/cancellation/CrmCancellationDO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/cancellation/CrmCancellationDO.java
index 00b01ac..2d2826b 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/cancellation/CrmCancellationDO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/cancellation/CrmCancellationDO.java
@@ -45,10 +45,24 @@
     private String applyUserName;
     private LocalDateTime applyTime;
     /**
-     * 瀹℃壒鐘舵�侊細0鑽夌/10寰呭鎵�/20閫氳繃/30椹冲洖
+     * 瀹℃壒鐘舵��
+     *
+     * 鏋氫妇 {@link cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum}
      */
     private Integer auditStatus;
-    private String processInstanceId;
+    /**
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� cancellation_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
+     */
+    private Long reviewerId;
+    /** 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛� */
+    private String reviewerName;
+    /** 瀹℃牳鏃堕棿 */
+    private LocalDateTime reviewTime;
+    /** 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛� */
+    private String reviewRemark;
     private String remark;
 
 }
\ No newline at end of file
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java
index e86a1d3..bd1c08a 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java
@@ -67,17 +67,33 @@
     private Long ownerUserId;
 
     /**
-     * 宸ヤ綔娴佺紪鍙�
-     *
-     * 鍏宠仈 ProcessInstance 鐨� id 灞炴��
-     */
-    private String processInstanceId;
-    /**
      * 瀹℃壒鐘舵��
+     *
+     * 鐢变笟鍔℃祦绋嬮┍鍔紝涓嶆帴鍙楀墠绔洿鎺ヨ祴鍊硷細鍒涘缓鏃跺浐瀹氫负鏈彁浜わ紝鎻愪氦瀹℃壒鍚庣疆涓哄鎵逛腑锛�
+     * 瀹℃牳閫氳繃 / 涓嶉�氳繃鐢� {@link cn.iocoder.yudao.module.crm.service.contract.CrmContractService#auditContract} 鎺ㄨ繘銆�
      *
      * 鏋氫妇 {@link CrmAuditStatusEnum}
      */
     private Integer auditStatus;
+    /**
+     * 瀹℃牳浜虹敤鎴风紪鍙凤紙鎻愪氦瀹℃壒鏃剁敱鎻愪氦浜轰粠绯荤粺鐢ㄦ埛涓�夋嫨锛�
+     *
+     * 鍙湁璇ョ敤鎴疯兘鍦ㄥ垪琛ㄩ〉鐪嬪埌銆屽鏍搞�嶆寜閽苟鎵ц瀹℃牳鎿嶄綔銆�
+     * 鍏宠仈 AdminUserDO 鐨� id 瀛楁
+     */
+    private Long reviewerId;
+    /**
+     * 瀹℃牳浜哄鍚嶏紙鎻愪氦瀹℃壒鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鏃跺啀鏌ョ敤鎴凤級
+     */
+    private String reviewerName;
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private LocalDateTime reviewTime;
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
 
     /**
      * 涓嬪崟鏃ユ湡
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/invoice/CrmInvoiceDO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/invoice/CrmInvoiceDO.java
index 664300d..29cedc2 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/invoice/CrmInvoiceDO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/invoice/CrmInvoiceDO.java
@@ -82,16 +82,23 @@
     private String remark;
 
     /**
-     * 宸ヤ綔娴佺紪鍙�
-     *
-     * 鍏宠仈 ProcessInstance 鐨� id 灞炴��
-     */
-    private String processInstanceId;
-    /**
      * 瀹℃壒鐘舵��
      *
      * 鏋氫妇 {@link CrmAuditStatusEnum}
      */
     private Integer auditStatus;
+    /**
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� crm_invoice_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
+     */
+    private Long reviewerId;
+    /** 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛� */
+    private String reviewerName;
+    /** 瀹℃牳鏃堕棿 */
+    private LocalDateTime reviewTime;
+    /** 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛� */
+    private String reviewRemark;
 
 }
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/refund/CrmRefundDO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/refund/CrmRefundDO.java
index 741ab0f..2c49726 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/refund/CrmRefundDO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/refund/CrmRefundDO.java
@@ -42,10 +42,24 @@
     private String applyUserName;
     private LocalDateTime applyTime;
     /**
-     * 瀹℃壒鐘舵�侊細0鑽夌/10寰呭鎵�/20閫氳繃/30椹冲洖
+     * 瀹℃壒鐘舵��
+     *
+     * 鏋氫妇 {@link cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum}
      */
     private Integer auditStatus;
-    private String processInstanceId;
+    /**
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� refund_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
+     */
+    private Long reviewerId;
+    /** 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛� */
+    private String reviewerName;
+    /** 瀹℃牳鏃堕棿 */
+    private LocalDateTime reviewTime;
+    /** 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛� */
+    private String reviewRemark;
     private String remark;
 
 }
\ No newline at end of file
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/cancellation/CrmCancellationMapper.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/cancellation/CrmCancellationMapper.java
index b5fa2f7..1b7b536 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/cancellation/CrmCancellationMapper.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/cancellation/CrmCancellationMapper.java
@@ -5,8 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.crm.controller.admin.cancellation.vo.CrmCancellationPageReqVO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.cancellation.CrmCancellationDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.time.LocalDateTime;
 import java.util.List;
 
 @Mapper
@@ -16,6 +18,49 @@
         return selectPage(reqVO, buildQuery(reqVO));
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 涔嬫墍浠ョ敤 UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鐨勫瓧娈垫洿鏂扮瓥鐣ヤ細蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜恒�佸鏍告椂闂淬�佸鏍告剰瑙佺湡姝f竻绌恒��
+     *
+     * @param id     閿�鎴风敵璇风紪鍙�
+     * @param status 鐩爣鐘舵�侊紙瀹℃壒涓級
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<CrmCancellationDO>()
+                .eq(CrmCancellationDO::getId, id)
+                .set(CrmCancellationDO::getAuditStatus, status)
+                .set(CrmCancellationDO::getReviewerId, null)
+                .set(CrmCancellationDO::getReviewerName, null)
+                .set(CrmCancellationDO::getReviewTime, null)
+                .set(CrmCancellationDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * reviewRemark 鍏佽涓� null锛堝鏍搁�氳繃鏃舵剰瑙佸彲閫夛級锛屾晠鍚屾牱浣跨敤 UpdateWrapper 鐩村啓銆�
+     *
+     * @param id           閿�鎴风敵璇风紪鍙�
+     * @param status       鐩爣鐘舵�侊紙瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditCancellation(Long id, Integer status, Long reviewerId,
+                                  String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<CrmCancellationDO>()
+                .eq(CrmCancellationDO::getId, id)
+                .set(CrmCancellationDO::getAuditStatus, status)
+                .set(CrmCancellationDO::getReviewerId, reviewerId)
+                .set(CrmCancellationDO::getReviewerName, reviewerName)
+                .set(CrmCancellationDO::getReviewTime, LocalDateTime.now())
+                .set(CrmCancellationDO::getReviewRemark, reviewRemark));
+    }
+
     default List<CrmCancellationDO> selectList(CrmCancellationPageReqVO reqVO) {
         return selectList(buildQuery(reqVO));
     }
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java
index 8b635f1..2c4bdfe 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java
@@ -13,6 +13,7 @@
 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
 import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
 import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
 import java.math.BigDecimal;
@@ -31,6 +32,49 @@
         return selectOne(CrmContractDO::getNo, no);
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 涔嬫墍浠ョ敤 UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鐨勫瓧娈垫洿鏂扮瓥鐣ヤ細蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜恒�佸鏍告椂闂淬�佸鏍告剰瑙佺湡姝f竻绌恒��
+     *
+     * @param id     鍚堝悓缂栧彿
+     * @param status 鐩爣鐘舵�侊紙瀹℃壒涓級
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<CrmContractDO>()
+                .eq(CrmContractDO::getId, id)
+                .set(CrmContractDO::getAuditStatus, status)
+                .set(CrmContractDO::getReviewerId, null)
+                .set(CrmContractDO::getReviewerName, null)
+                .set(CrmContractDO::getReviewTime, null)
+                .set(CrmContractDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * reviewRemark 鍏佽涓� null锛堝鏍搁�氳繃鏃舵剰瑙佸彲閫夛級锛屾晠鍚屾牱浣跨敤 UpdateWrapper 鐩村啓銆�
+     *
+     * @param id           鍚堝悓缂栧彿
+     * @param status       鐩爣鐘舵�侊紙瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditContract(Long id, Integer status, Long reviewerId,
+                              String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<CrmContractDO>()
+                .eq(CrmContractDO::getId, id)
+                .set(CrmContractDO::getAuditStatus, status)
+                .set(CrmContractDO::getReviewerId, reviewerId)
+                .set(CrmContractDO::getReviewerName, reviewerName)
+                .set(CrmContractDO::getReviewTime, LocalDateTime.now())
+                .set(CrmContractDO::getReviewRemark, reviewRemark));
+    }
+
     default PageResult<CrmContractDO> selectPageByCustomerId(CrmContractPageReqVO pageReqVO) {
         return selectPage(pageReqVO, new LambdaQueryWrapperX<CrmContractDO>()
                 .eq(CrmContractDO::getCustomerId, pageReqVO.getCustomerId())
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/invoice/CrmInvoiceMapper.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/invoice/CrmInvoiceMapper.java
index 9dcbca0..0f9cdee 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/invoice/CrmInvoiceMapper.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/invoice/CrmInvoiceMapper.java
@@ -12,9 +12,11 @@
 import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
 import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -34,6 +36,49 @@
         return selectOne(CrmInvoiceDO::getNo, no);
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 涔嬫墍浠ョ敤 UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鐨勫瓧娈垫洿鏂扮瓥鐣ヤ細蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜恒�佸鏍告椂闂淬�佸鏍告剰瑙佺湡姝f竻绌恒��
+     *
+     * @param id     寮�绁ㄧ紪鍙�
+     * @param status 鐩爣鐘舵�侊紙瀹℃壒涓級
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<CrmInvoiceDO>()
+                .eq(CrmInvoiceDO::getId, id)
+                .set(CrmInvoiceDO::getAuditStatus, status)
+                .set(CrmInvoiceDO::getReviewerId, null)
+                .set(CrmInvoiceDO::getReviewerName, null)
+                .set(CrmInvoiceDO::getReviewTime, null)
+                .set(CrmInvoiceDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * reviewRemark 鍏佽涓� null锛堝鏍搁�氳繃鏃舵剰瑙佸彲閫夛級锛屾晠鍚屾牱浣跨敤 UpdateWrapper 鐩村啓銆�
+     *
+     * @param id           寮�绁ㄧ紪鍙�
+     * @param status       鐩爣鐘舵�侊紙瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditInvoice(Long id, Integer status, Long reviewerId,
+                             String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<CrmInvoiceDO>()
+                .eq(CrmInvoiceDO::getId, id)
+                .set(CrmInvoiceDO::getAuditStatus, status)
+                .set(CrmInvoiceDO::getReviewerId, reviewerId)
+                .set(CrmInvoiceDO::getReviewerName, reviewerName)
+                .set(CrmInvoiceDO::getReviewTime, LocalDateTime.now())
+                .set(CrmInvoiceDO::getReviewRemark, reviewRemark));
+    }
+
     default PageResult<CrmInvoiceDO> selectPageByCustomerId(CrmInvoicePageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<CrmInvoiceDO>()
                 .eq(CrmInvoiceDO::getCustomerId, reqVO.getCustomerId()) // 蹇呴』浼犻��
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/refund/CrmRefundMapper.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/refund/CrmRefundMapper.java
index d824d52..4ff9c7f 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/refund/CrmRefundMapper.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/refund/CrmRefundMapper.java
@@ -5,8 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.crm.controller.admin.refund.vo.CrmRefundPageReqVO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.refund.CrmRefundDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.time.LocalDateTime;
 import java.util.List;
 
 @Mapper
@@ -16,6 +18,49 @@
         return selectPage(reqVO, buildQuery(reqVO));
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 涔嬫墍浠ョ敤 UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鐨勫瓧娈垫洿鏂扮瓥鐣ヤ細蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜恒�佸鏍告椂闂淬�佸鏍告剰瑙佺湡姝f竻绌恒��
+     *
+     * @param id     閫�璐瑰崟缂栧彿
+     * @param status 鐩爣鐘舵�侊紙瀹℃壒涓級
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<CrmRefundDO>()
+                .eq(CrmRefundDO::getId, id)
+                .set(CrmRefundDO::getAuditStatus, status)
+                .set(CrmRefundDO::getReviewerId, null)
+                .set(CrmRefundDO::getReviewerName, null)
+                .set(CrmRefundDO::getReviewTime, null)
+                .set(CrmRefundDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * reviewRemark 鍏佽涓� null锛堝鏍搁�氳繃鏃舵剰瑙佸彲閫夛級锛屾晠鍚屾牱浣跨敤 UpdateWrapper 鐩村啓銆�
+     *
+     * @param id           閫�璐瑰崟缂栧彿
+     * @param status       鐩爣鐘舵�侊紙瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditRefund(Long id, Integer status, Long reviewerId,
+                            String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<CrmRefundDO>()
+                .eq(CrmRefundDO::getId, id)
+                .set(CrmRefundDO::getAuditStatus, status)
+                .set(CrmRefundDO::getReviewerId, reviewerId)
+                .set(CrmRefundDO::getReviewerName, reviewerName)
+                .set(CrmRefundDO::getReviewTime, LocalDateTime.now())
+                .set(CrmRefundDO::getReviewRemark, reviewRemark));
+    }
+
     default List<CrmRefundDO> selectList(CrmRefundPageReqVO reqVO) {
         return selectList(buildQuery(reqVO));
     }
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/cancellation/CrmCancellationService.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/cancellation/CrmCancellationService.java
index 59de8ea..b4bbf71 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/cancellation/CrmCancellationService.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/cancellation/CrmCancellationService.java
@@ -1,14 +1,13 @@
 package cn.iocoder.yudao.module.crm.service.cancellation;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.crm.controller.admin.cancellation.vo.CrmCancellationAuditReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.cancellation.vo.CrmCancellationPageReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.cancellation.vo.CrmCancellationRespVO;
 import cn.iocoder.yudao.module.crm.controller.admin.cancellation.vo.CrmCancellationSaveReqVO;
 import jakarta.validation.Valid;
 
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 public interface CrmCancellationService {
 
@@ -24,12 +23,34 @@
 
     List<CrmCancellationRespVO> getCancellationList(CrmCancellationPageReqVO reqVO);
 
-    void auditCancellation(@Valid CrmCancellationAuditReqVO auditReqVO);
+    /**
+     * 鎻愪氦閿�鎴风敵璇峰鎵癸紙鑽夌 / 瀹℃牳涓嶉�氳繃 鈫� 瀹℃壒涓級
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� cancellation_approve锛夛紝
+     * 鎻愪氦鏃舵棤闇�鎸囧畾锛涙湭鍚敤瀹℃壒鎴栨湭閰嶇疆鏈夋晥瀹℃壒浜烘椂鎶涘嚭涓氬姟寮傚父銆�
+     *
+     * @param id 閿�鎴风敵璇风紪鍙�
+     */
+    void submitCancellation(Long id);
 
-    void submitCancellation(Long id, String processDefinitionKey, Long userId);
+    /**
+     * 鑾峰緱閿�鎴风敵璇峰鎵圭殑瀹℃壒浜虹紪鍙烽泦鍚�
+     *
+     * 渚涘墠绔垽鏂綋鍓嶇櫥褰曠敤鎴锋槸鍚﹀簲灞曠ず銆屽鏍搞�嶆寜閽紱鏈厤缃椂杩斿洖绌洪泦鍚堛��
+     *
+     * @return 瀹℃壒浜虹敤鎴风紪鍙烽泦鍚�
+     */
+    Set<Long> getCancellationApproverUserIds();
 
-    void updateCancellationAuditStatus(Long id, Integer bpmResult);
+    /**
+     * 瀹℃牳閿�鎴风敵璇凤紙瀹℃壒涓� 鈫� 瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     *
+     * 浠呬笟鍔$紪鐮� cancellation_approve 閰嶇疆鐨勫鎵逛汉鍙搷浣滐紙澶氫汉鏃舵垨绛撅級锛涘鏍镐笉閫氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜銆�
+     *
+     * @param id           閿�鎴风敵璇风紪鍙�
+     * @param pass         鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛堜笉閫氳繃鏃跺嵆涓嶉�氳繃鍘熷洜锛屽繀濉級
+     */
+    void auditCancellation(Long id, Boolean pass, String reviewRemark);
 
-    List<Map<String, Object>> getCancellationApproveProcessDefinitionList();
-
-}
\ No newline at end of file
+}
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/cancellation/listener/CrmCancellationStatusListener.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/cancellation/listener/CrmCancellationStatusListener.java
deleted file mode 100644
index 8f14fc7..0000000
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/cancellation/listener/CrmCancellationStatusListener.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package cn.iocoder.yudao.module.crm.service.cancellation.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.crm.dal.dataobject.cancellation.CrmCancellationDO;
-import cn.iocoder.yudao.module.crm.dal.mysql.cancellation.CrmCancellationMapper;
-import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
-import cn.iocoder.yudao.module.crm.service.cancellation.CrmCancellationService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-/**
- * 閿�鎴峰鎵圭殑缁撴灉鐩戝惉鍣ㄥ疄鐜扮被
- *
- * 閫氳繃 businessKey锛堥攢鎴风敵璇稩D锛夊尮閰嶏紝鑰屼笉鏄浐瀹氱殑娴佺▼瀹氫箟 Key锛�
- * 杩欐牱鍙互鏀寔鍒嗙被涓嬩换鎰� Key 鐨勬祦绋嬫ā鍨嬨��
- */
-@Component
-@Slf4j
-public class CrmCancellationStatusListener implements ApplicationListener<BpmProcessInstanceStatusEvent> {
-
-    @Resource
-    private CrmCancellationService cancellationService;
-    @Resource
-    private CrmCancellationMapper cancellationMapper;
-
-    @Override
-    public void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
-        // 閫氳繃 businessKey 鏌ヨ閿�鎴风敵璇�
-        Long cancellationId;
-        try {
-            cancellationId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            return; // businessKey 涓嶆槸鏁板瓧锛屽拷鐣�
-        }
-
-        CrmCancellationDO cancellation = cancellationMapper.selectById(cancellationId);
-        if (cancellation == null) {
-            return; // 涓嶆槸閿�鎴风敵璇凤紝蹇界暐
-        }
-
-        // 鍙湁瀹℃壒涓姸鎬佺殑閿�鎴风敵璇锋墠澶勭悊
-        if (!CrmAuditStatusEnum.PROCESS.getStatus().equals(cancellation.getAuditStatus())) {
-            log.warn("[onApplicationEvent] 閿�鎴风敵璇�({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵��: {}", cancellationId, cancellation.getAuditStatus());
-            return;
-        }
-
-        log.info("[onApplicationEvent] 閿�鎴风敵璇�({}) 瀹℃壒鐘舵�佹洿鏂�: {}", cancellationId, event.getStatus());
-        // 鏇存柊瀹℃壒鐘舵��
-        cancellationService.updateCancellationAuditStatus(cancellationId, event.getStatus());
-    }
-
-}
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java
index 80693c2..f13e9c1 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java
@@ -14,6 +14,7 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 
@@ -65,28 +66,34 @@
     void updateContractFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent);
 
     /**
-     * 鍙戣捣鍚堝悓瀹℃壒娴佺▼
+     * 鎻愪氦鍚堝悓瀹℃壒锛堟湭鎻愪氦 / 瀹℃牳涓嶉�氳繃 鈫� 瀹℃壒涓級
      *
-     * @param id                    鍚堝悓缂栧彿
-     * @param processDefinitionKey  娴佺▼瀹氫箟 Key
-     * @param userId                鐢ㄦ埛缂栧彿
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� contract_approve锛夛紝
+     * 鎻愪氦鏃舵棤闇�鎸囧畾锛涙湭鍚敤瀹℃壒鎴栨湭閰嶇疆鏈夋晥瀹℃壒浜烘椂鎶涘嚭涓氬姟寮傚父銆�
+     *
+     * @param id 鍚堝悓缂栧彿
      */
-    void submitContract(Long id, String processDefinitionKey, Long userId);
+    void submitContract(Long id);
 
     /**
-     * 鑾峰彇鍚堝悓瀹℃壒娴佺▼鍒楄〃
+     * 鑾峰緱鍚堝悓瀹℃壒鐨勫鎵逛汉缂栧彿闆嗗悎
      *
-     * @return 娴佺▼瀹氫箟鍒楄〃
+     * 渚涘墠绔垽鏂綋鍓嶇櫥褰曠敤鎴锋槸鍚﹀簲灞曠ず銆屽鏍搞�嶆寜閽紱鏈厤缃椂杩斿洖绌洪泦鍚堛��
+     *
+     * @return 瀹℃壒浜虹敤鎴风紪鍙烽泦鍚�
      */
-    List<Map<String, Object>> getContractApproveProcessDefinitionList();
+    Set<Long> getContractApproverUserIds();
 
     /**
-     * 鏇存柊鍚堝悓娴佺▼瀹℃壒缁撴灉
+     * 瀹℃牳鍚堝悓锛堝鎵逛腑 鈫� 瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
      *
-     * @param id        鍚堝悓缂栧彿
-     * @param bpmResult BPM 瀹℃壒缁撴灉
+     * 浠呬笟鍔$紪鐮� contract_approve 閰嶇疆鐨勫鎵逛汉鍙搷浣滐紙澶氫汉鏃舵垨绛撅級锛涘鏍镐笉閫氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜銆�
+     *
+     * @param id           鍚堝悓缂栧彿
+     * @param pass         鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛堜笉閫氳繃鏃跺嵆涓嶉�氳繃鍘熷洜锛屽繀濉級
      */
-    void updateContractAuditStatus(Long id, Integer bpmResult);
+    void auditContract(Long id, Boolean pass, String reviewRemark);
 
     /**
      * 鑾峰緱鍚堝悓
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
index 88705a1..f9edb8a 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -4,15 +4,11 @@
 import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractPageReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractSaveReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractTransferReqVO;
@@ -42,7 +38,9 @@
 import cn.iocoder.yudao.module.erp.api.sale.dto.ErpSaleOrderRespDTO;
 import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
 import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import com.mzt.logapi.context.LogRecordContext;
 import com.mzt.logapi.service.impl.DiffParseFunction;
 import com.mzt.logapi.starter.annotation.LogRecord;
@@ -63,13 +61,11 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.flowable.engine.repository.ProcessDefinition;
-
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
-import static cn.iocoder.yudao.module.crm.util.CrmAuditStatusUtils.convertBpmResultToAuditStatus;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 /**
  * CRM 鍚堝悓 Service 瀹炵幇绫�
@@ -82,14 +78,11 @@
 public class CrmContractServiceImpl implements CrmContractService {
 
     /**
-     * BPM 鍚堝悓瀹℃壒娴佺▼鏍囪瘑
+     * CRM 鍚堝悓瀹℃壒鐨勪笟鍔$被鍨嬬紪鐮�
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鎵逛汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
      */
-    public static final String BPM_PROCESS_DEFINITION_KEY = "crm-contract-audit";
-
-    /**
-     * BPM 鍚堝悓瀹℃壒鍒嗙被缂栫爜
-     */
-    private static final String CONTRACT_APPROVE_CATEGORY_CODE = "contract_approve";
+    private static final String CONTRACT_APPROVE_BIZ_TYPE = "contract_approve";
 
     @Resource
     private CrmContractMapper contractMapper;
@@ -117,11 +110,7 @@
     @Resource
     private AdminUserApi adminUserApi;
     @Resource
-    private BpmProcessInstanceApi bpmProcessInstanceApi;
-    @Resource
-    private BpmCategoryService bpmCategoryService;
-    @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private ApprovalConfigApi approvalConfigApi;
     @Resource
     private ErpSaleOrderApi saleOrderApi;
     @Resource
@@ -300,6 +289,20 @@
         return contract;
     }
 
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
+        }
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}",
@@ -338,114 +341,53 @@
     @Transactional(rollbackFor = Exception.class)
     @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_SUBMIT_SUB_TYPE, bizNo = "{{#id}}",
             success = CRM_CONTRACT_SUBMIT_SUCCESS)
-    public void submitContract(Long id, String processDefinitionKey, Long userId) {
-        // 1. 鏍¢獙鍚堝悓鏄惁鍦ㄥ鎵�
+    public void submitContract(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鍙彁浜ょ姸鎬侊紙鏈彁浜� / 瀹℃牳涓嶉�氳繃锛�
         CrmContractDO contract = validateContractExists(id);
-        if (ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())) {
-            throw exception(CONTRACT_SUBMIT_FAIL_NOT_DRAFT);
+        if (ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())
+                && ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.REJECT.getStatus())) {
+            throw exception(CONTRACT_SUBMIT_FAIL_NOT_EDITABLE);
         }
 
-        // 2. 鏍¢獙鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-        validateContractApproveCategoryAndProcessDefinition();
+        // 2. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鎵逛汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(CONTRACT_APPROVE_BIZ_TYPE);
 
-        // 3. 鏍¢獙浼犲叆鐨勬祦绋嬪畾涔� Key 鏄惁灞炰簬璇ュ垎绫讳笖澶勪簬婵�娲荤姸鎬�
-        ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey);
-        if (processDefinition == null) {
-            throw exception(CONTRACT_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
+        // 3. 鐘舵�佺疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋滐紝閬垮厤娈嬬暀銆屽鏍镐笉閫氳繃銆嶇殑鍘熷洜
+        contractMapper.submitAndResetAuditInfo(id, CrmAuditStatusEnum.PROCESS.getStatus());
 
-        // 4. 鍒涘缓鍚堝悓瀹℃壒娴佺▼瀹炰緥
-        String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
-                .setProcessDefinitionKey(processDefinitionKey).setBusinessKey(String.valueOf(id)));
-
-        // 5. 鏇存柊鍚堝悓宸ヤ綔娴佺紪鍙�
-        contractMapper.updateById(new CrmContractDO().setId(id).setProcessInstanceId(processInstanceId)
-                .setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus()));
-
-        // 6. 璁板綍鏃ュ織
+        // 4. 璁板綍鏃ュ織
         LogRecordContext.putVariable("contractName", contract.getName());
     }
 
-    /**
-     * 鏍¢獙 BPM 鍚堝悓瀹℃壒鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-     */
-    private void validateContractApproveCategoryAndProcessDefinition() {
-        // 1. 鏍¢獙鍒嗙被鏄惁瀛樺湪
-        List<String> codes = Collections.singletonList(CONTRACT_APPROVE_CATEGORY_CODE);
-        Map<String, ?> categoryMap = bpmCategoryService.getCategoryMap(codes);
-        if (!categoryMap.containsKey(CONTRACT_APPROVE_CATEGORY_CODE)) {
-            throw exception(CONTRACT_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-
-        // 2. 鏍¢獙鍒嗙被涓嬫槸鍚︽湁鍙敤鐨勬祦绋嬪畾涔�
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(CONTRACT_APPROVE_CATEGORY_CODE);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            throw exception(CONTRACT_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-
-        // 3. 鏍¢獙鏄惁鏈夋縺娲荤姸鎬佺殑娴佺▼瀹氫箟
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-        boolean hasActiveDefinition = processDefinitions.stream()
-                .anyMatch(pd -> !pd.isSuspended());
-        if (!hasActiveDefinition) {
-            throw exception(CONTRACT_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
+    @Override
+    public Set<Long> getContractApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(CONTRACT_APPROVE_BIZ_TYPE);
     }
 
     @Override
-    public List<Map<String, Object>> getContractApproveProcessDefinitionList() {
-        // 1. 鏍¢獙鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-        validateContractApproveCategoryAndProcessDefinition();
-
-        // 2. 鑾峰彇鍒嗙被涓嬬殑娴佺▼瀹氫箟淇℃伅
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(CONTRACT_APPROVE_CATEGORY_CODE);
-
-        // 3. 鑾峰彇娴佺▼瀹氫箟璇︽儏
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-
-        // 4. 杩囨护锛氬彧淇濈暀婵�娲荤姸鎬侊紝涓旂浉鍚� key 鍙繚鐣欐渶鏂扮増鏈�
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (ProcessDefinition pd : processDefinitions) {
-            if (pd.isSuspended()) {
-                continue;
-            }
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-
-        // 5. 杩斿洖娴佺▼瀹氫箟鍒楄〃
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            item.put("version", pd.getVersion());
-            result.add(item);
-        }
-        return result;
-    }
-
-    @Override
-    public void updateContractAuditStatus(Long id, Integer bpmResult) {
-        // 1.1 鏍¢獙鍚堝悓鏄惁瀛樺湪
+    @Transactional(rollbackFor = Exception.class)
+    public void auditContract(Long id, Boolean pass, String reviewRemark) {
+        // 1. 鏍¢獙瀛樺湪
         CrmContractDO contract = validateContractExists(id);
-        // 1.2 鍙湁瀹℃壒涓紝鍙互鏇存柊瀹℃壒缁撴灉
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
         if (ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) {
-            log.error("[updateContractAuditStatus][contract({}) 涓嶅浜庡鎵逛腑锛屾棤娉曟洿鏂板鎵圭粨鏋�({})]",
-                    contract.getId(), bpmResult);
-            throw exception(CONTRACT_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS);
+            throw exception(CONTRACT_AUDIT_FAIL_NOT_PROCESS);
         }
-
-        // 2. 鏇存柊鍚堝悓瀹℃壒缁撴灉
-        Integer auditStatus = convertBpmResultToAuditStatus(bpmResult);
-        contractMapper.updateById(new CrmContractDO().setId(id).setAuditStatus(auditStatus));
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鎵逛汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(CONTRACT_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝鐘舵�佺疆涓哄鏍镐笉閫氳繃锛岄��鍥炴彁浜や汉淇敼鍚庡彲閲嶆柊鎻愪氦
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(CONTRACT_AUDIT_REJECT_REASON_REQUIRED);
+            }
+            contractMapper.auditContract(id, CrmAuditStatusEnum.REJECT.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
+            return;
+        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄鏍搁�氳繃
+        contractMapper.auditContract(id, CrmAuditStatusEnum.APPROVE.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
     }
 
     // ======================= 鏌ヨ鐩稿叧 =======================
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/listener/CrmContractStatusListener.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/listener/CrmContractStatusListener.java
deleted file mode 100644
index 3d425ad..0000000
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/contract/listener/CrmContractStatusListener.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package cn.iocoder.yudao.module.crm.service.contract.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
-import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
-import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
-import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-/**
- * 鍚堝悓瀹℃壒鐨勭粨鏋滅洃鍚櫒瀹炵幇绫�
- *
- * 閫氳繃 businessKey锛堝悎鍚孖D锛夊尮閰嶏紝鑰屼笉鏄浐瀹氱殑娴佺▼瀹氫箟 Key锛�
- * 杩欐牱鍙互鏀寔鍒嗙被涓嬩换鎰� Key 鐨勬祦绋嬫ā鍨嬨��
- *
- * @author HUIHUI
- */
-@Component
-@Slf4j
-public class CrmContractStatusListener implements ApplicationListener<BpmProcessInstanceStatusEvent> {
-
-    @Resource
-    private CrmContractService contractService;
-    @Resource
-    private CrmContractMapper contractMapper;
-
-    @Override
-    public void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
-        // 閫氳繃 businessKey 鏌ヨ鍚堝悓
-        Long contractId;
-        try {
-            contractId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            return; // businessKey 涓嶆槸鏁板瓧锛屽拷鐣�
-        }
-
-        CrmContractDO contract = contractMapper.selectById(contractId);
-        if (contract == null) {
-            return; // 涓嶆槸鍚堝悓锛屽拷鐣�
-        }
-
-        // 鍙湁瀹℃壒涓姸鎬佺殑鍚堝悓鎵嶅鐞�
-        if (!CrmAuditStatusEnum.PROCESS.getStatus().equals(contract.getAuditStatus())) {
-            log.warn("[onApplicationEvent] 鍚堝悓({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵��: {}", contractId, contract.getAuditStatus());
-            return;
-        }
-
-        log.info("[onApplicationEvent] 鍚堝悓({}) 瀹℃壒鐘舵�佹洿鏂�: {}", contractId, event.getStatus());
-        // 鏇存柊瀹℃壒鐘舵��
-        contractService.updateContractAuditStatus(contractId, event.getStatus());
-    }
-
-}
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceService.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceService.java
index 0390851..6fb86fd 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceService.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceService.java
@@ -10,6 +10,7 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 
@@ -36,14 +37,6 @@
     void updateInvoice(@Valid CrmInvoiceSaveReqVO updateReqVO);
 
     /**
-     * 鏇存柊寮�绁ㄦ祦绋嬪鎵圭粨鏋�
-     *
-     * @param id        寮�绁ㄧ紪鍙�
-     * @param bpmResult BPM 瀹℃壒缁撴灉
-     */
-    void updateInvoiceAuditStatus(Long id, Integer bpmResult);
-
-    /**
      * 鍒犻櫎寮�绁�
      *
      * @param id 缂栧彿
@@ -51,12 +44,34 @@
     void deleteInvoice(Long id);
 
     /**
-     * 鍙戣捣寮�绁ㄥ鎵规祦绋�
+     * 鎻愪氦寮�绁ㄥ鎵癸紙鑽夌 / 瀹℃牳涓嶉�氳繃 鈫� 瀹℃壒涓級
      *
-     * @param id     寮�绁ㄧ紪鍙�
-     * @param userId 鐢ㄦ埛缂栧彿
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� crm_invoice_approve锛夛紝
+     * 鎻愪氦鏃舵棤闇�鎸囧畾锛涙湭鍚敤瀹℃壒鎴栨湭閰嶇疆鏈夋晥瀹℃壒浜烘椂鎶涘嚭涓氬姟寮傚父銆�
+     *
+     * @param id 寮�绁ㄧ紪鍙�
      */
-    void submitInvoice(Long id, Long userId);
+    void submitInvoice(Long id);
+
+    /**
+     * 鑾峰緱寮�绁ㄥ鎵圭殑瀹℃壒浜虹紪鍙烽泦鍚�
+     *
+     * 渚涘墠绔垽鏂綋鍓嶇櫥褰曠敤鎴锋槸鍚﹀簲灞曠ず銆屽鏍搞�嶆寜閽紱鏈厤缃椂杩斿洖绌洪泦鍚堛��
+     *
+     * @return 瀹℃壒浜虹敤鎴风紪鍙烽泦鍚�
+     */
+    Set<Long> getInvoiceApproverUserIds();
+
+    /**
+     * 瀹℃牳寮�绁紙瀹℃壒涓� 鈫� 瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     *
+     * 浠呬笟鍔$紪鐮� crm_invoice_approve 閰嶇疆鐨勫鎵逛汉鍙搷浣滐紙澶氫汉鏃舵垨绛撅級锛涘鏍镐笉閫氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜銆�
+     *
+     * @param id           寮�绁ㄧ紪鍙�
+     * @param pass         鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛堜笉閫氳繃鏃跺嵆涓嶉�氳繃鍘熷洜锛屽繀濉級
+     */
+    void auditInvoice(Long id, Boolean pass, String reviewRemark);
 
     /**
      * 鑾峰緱寮�绁�
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java
index 4d0fd42..326a256 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java
@@ -5,12 +5,11 @@
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
 import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoicePageReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceSaveReqVO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
@@ -24,8 +23,10 @@
 import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
 import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import com.mzt.logapi.context.LogRecordContext;
 import com.mzt.logapi.service.impl.DiffParseFunction;
 import com.mzt.logapi.starter.annotation.LogRecord;
@@ -39,11 +40,12 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
-import static cn.iocoder.yudao.module.crm.util.CrmAuditStatusUtils.convertBpmResultToAuditStatus;
 
 /**
  * CRM 寮�绁� Service 瀹炵幇绫�
@@ -56,9 +58,11 @@
 public class CrmInvoiceServiceImpl implements CrmInvoiceService {
 
     /**
-     * BPM 寮�绁ㄥ鎵规祦绋嬫爣璇�
+     * CRM 寮�绁ㄥ鎵圭殑涓氬姟绫诲瀷缂栫爜
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鎵逛汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
      */
-    public static final String BPM_PROCESS_DEFINITION_KEY = "crm-invoice-audit";
+    private static final String INVOICE_APPROVE_BIZ_TYPE = "crm_invoice_approve";
 
     /**
      * 鍙戠エ闄勪欢鐨勪笟鍔¤褰曠被鍨嬶紝瀵瑰簲 {@link cn.iocoder.yudao.module.system.enums.storage.StorageRecordTypeEnum#CRM_INVOICE}
@@ -79,7 +83,7 @@
     @Resource
     private AdminUserApi adminUserApi;
     @Resource
-    private BpmProcessInstanceApi bpmProcessInstanceApi;
+    private ApprovalConfigApi approvalConfigApi;
     @Resource
     private StorageAttachmentApi storageAttachmentApi;
 
@@ -182,22 +186,6 @@
     }
 
     @Override
-    public void updateInvoiceAuditStatus(Long id, Integer bpmResult) {
-        // 1.1 鏍¢獙瀛樺湪
-        CrmInvoiceDO invoice = validateInvoiceExists(id);
-        // 1.2 鍙湁瀹℃壒涓紝鍙互鏇存柊瀹℃壒缁撴灉
-        if (ObjUtil.notEqual(invoice.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) {
-            log.error("[updateInvoiceAuditStatus][invoice({}) 涓嶅浜庡鎵逛腑锛屾棤娉曟洿鏂板鎵圭粨鏋�({})]",
-                    invoice.getId(), bpmResult);
-            throw exception(INVOICE_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS);
-        }
-
-        // 2. 鏇存柊寮�绁ㄥ鎵圭姸鎬�
-        Integer auditStatus = convertBpmResultToAuditStatus(bpmResult);
-        invoiceMapper.updateById(new CrmInvoiceDO().setId(id).setAuditStatus(auditStatus));
-    }
-
-    @Override
     @Transactional(rollbackFor = Exception.class)
     @LogRecord(type = CRM_INVOICE_TYPE, subType = CRM_INVOICE_DELETE_SUB_TYPE, bizNo = "{{#id}}",
             success = CRM_INVOICE_DELETE_SUCCESS)
@@ -225,29 +213,74 @@
     @Transactional(rollbackFor = Exception.class)
     @LogRecord(type = CRM_INVOICE_TYPE, subType = CRM_INVOICE_SUBMIT_SUB_TYPE, bizNo = "{{#id}}",
             success = CRM_INVOICE_SUBMIT_SUCCESS)
-    public void submitInvoice(Long id, Long userId) {
-        // 1. 鏍¢獙寮�绁ㄦ槸鍚﹀湪瀹℃壒
+    public void submitInvoice(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鍙彁浜ょ姸鎬侊紙鏈彁浜� / 瀹℃牳涓嶉�氳繃锛�
         CrmInvoiceDO invoice = validateInvoiceExists(id);
-        if (ObjUtil.notEqual(invoice.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())) {
-            throw exception(INVOICE_SUBMIT_FAIL_NOT_DRAFT);
+        if (ObjUtil.notEqual(invoice.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())
+                && ObjUtil.notEqual(invoice.getAuditStatus(), CrmAuditStatusEnum.REJECT.getStatus())) {
+            throw exception(INVOICE_SUBMIT_FAIL_NOT_EDITABLE);
         }
 
-        // 1.1 閲嶆柊鏍¢獙鍙紑绁ㄩ噾棰濓紝闃叉绱寮�绁ㄨ秴杩囧悎鍚岄噾棰濓紙鑽夌鏈熷悗鍙兘鏈夊叾浠栧崟杩涘叆瀹℃壒涓級
+        // 2. 閲嶆柊鏍¢獙鍙紑绁ㄩ噾棰濓紝闃叉绱寮�绁ㄨ秴杩囧悎鍚岄噾棰濓紙鑽夌鏈熷悗鍙兘鏈夊叾浠栧崟杩涘叆瀹℃壒涓級
         validateInvoicePriceExceedsLimit(new CrmInvoiceSaveReqVO()
                 .setId(invoice.getId()).setContractId(invoice.getContractId()).setPrice(invoice.getPrice()));
 
-        // 2. 鍒涘缓寮�绁ㄥ鎵规祦绋嬪疄渚�
-        String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
-                .setProcessDefinitionKey(BPM_PROCESS_DEFINITION_KEY).setBusinessKey(String.valueOf(id)));
+        // 3. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鎵逛汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(INVOICE_APPROVE_BIZ_TYPE);
 
-        // 3. 鏇存柊寮�绁ㄥ伐浣滄祦缂栧彿
-        invoiceMapper.updateById(new CrmInvoiceDO().setId(id).setProcessInstanceId(processInstanceId)
-                .setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus()));
+        // 4. 鐘舵�佺疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋滐紝閬垮厤娈嬬暀銆屽鏍镐笉閫氳繃銆嶇殑鍘熷洜
+        invoiceMapper.submitAndResetAuditInfo(id, CrmAuditStatusEnum.PROCESS.getStatus());
 
-        // 4. 璁板綍鏃ュ織
+        // 5. 璁板綍鏃ュ織
         LogRecordContext.putVariable("invoiceNo", invoice.getNo());
     }
 
+    @Override
+    public Set<Long> getInvoiceApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(INVOICE_APPROVE_BIZ_TYPE);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void auditInvoice(Long id, Boolean pass, String reviewRemark) {
+        // 1. 鏍¢獙瀛樺湪
+        CrmInvoiceDO invoice = validateInvoiceExists(id);
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
+        if (ObjUtil.notEqual(invoice.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) {
+            throw exception(INVOICE_AUDIT_FAIL_NOT_PROCESS);
+        }
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鎵逛汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(INVOICE_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝鐘舵�佺疆涓哄鏍镐笉閫氳繃锛岄��鍥炴彁浜や汉淇敼鍚庡彲閲嶆柊鎻愪氦
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(INVOICE_AUDIT_REJECT_REASON_REQUIRED);
+            }
+            invoiceMapper.auditInvoice(id, CrmAuditStatusEnum.REJECT.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
+            return;
+        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄鏍搁�氳繃
+        //    锛堝紑绁ㄦ棤棰濆鍚庣疆涓氬姟閫昏緫锛屽鎵归�氳繃鍚庡嵆鍙敤浜庡垱寤哄洖娆� / 鍏宠仈寮�绁ㄩ�夋嫨锛�
+        invoiceMapper.auditInvoice(id, CrmAuditStatusEnum.APPROVE.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
+        }
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
+    }
+
     private CrmInvoiceDO validateInvoiceExists(Long id) {
         CrmInvoiceDO invoice = invoiceMapper.selectById(id);
         if (invoice == null) {
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/listener/CrmInvoiceStatusListener.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/listener/CrmInvoiceStatusListener.java
deleted file mode 100644
index 17bcab3..0000000
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/listener/CrmInvoiceStatusListener.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package cn.iocoder.yudao.module.crm.service.invoice.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener;
-import cn.iocoder.yudao.module.crm.service.invoice.CrmInvoiceService;
-import cn.iocoder.yudao.module.crm.service.invoice.CrmInvoiceServiceImpl;
-import jakarta.annotation.Resource;
-import org.springframework.stereotype.Component;
-
-/**
- * 寮�绁ㄥ鎵圭殑缁撴灉鐨勭洃鍚櫒瀹炵幇绫�
- *
- * @author 瓒呯骇绠$悊鍛�
- */
-@Component
-public class CrmInvoiceStatusListener extends BpmProcessInstanceStatusEventListener {
-
-    @Resource
-    private CrmInvoiceService invoiceService;
-
-    @Override
-    public String getProcessDefinitionKey() {
-        return CrmInvoiceServiceImpl.BPM_PROCESS_DEFINITION_KEY;
-    }
-
-    @Override
-    public void onEvent(BpmProcessInstanceStatusEvent event) {
-        invoiceService.updateInvoiceAuditStatus(Long.parseLong(event.getBusinessKey()), event.getStatus());
-    }
-
-}
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/refund/CrmRefundService.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/refund/CrmRefundService.java
index 1b9125c..4c4ff14 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/refund/CrmRefundService.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/refund/CrmRefundService.java
@@ -1,14 +1,13 @@
 package cn.iocoder.yudao.module.crm.service.refund;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.crm.controller.admin.refund.vo.CrmRefundAuditReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.refund.vo.CrmRefundPageReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.refund.vo.CrmRefundRespVO;
 import cn.iocoder.yudao.module.crm.controller.admin.refund.vo.CrmRefundSaveReqVO;
 import jakarta.validation.Valid;
 
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 public interface CrmRefundService {
 
@@ -24,12 +23,34 @@
 
     List<CrmRefundRespVO> getRefundList(CrmRefundPageReqVO reqVO);
 
-    void auditRefund(@Valid CrmRefundAuditReqVO auditReqVO);
+    /**
+     * 鎻愪氦閫�璐瑰崟瀹℃壒锛堣崏绋� / 瀹℃牳涓嶉�氳繃 鈫� 瀹℃壒涓級
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� refund_approve锛夛紝
+     * 鎻愪氦鏃舵棤闇�鎸囧畾锛涙湭鍚敤瀹℃壒鎴栨湭閰嶇疆鏈夋晥瀹℃壒浜烘椂鎶涘嚭涓氬姟寮傚父銆�
+     *
+     * @param id 閫�璐瑰崟缂栧彿
+     */
+    void submitRefund(Long id);
 
-    void submitRefund(Long id, String processDefinitionKey, Long userId);
+    /**
+     * 鑾峰緱閫�璐瑰崟瀹℃壒鐨勫鎵逛汉缂栧彿闆嗗悎
+     *
+     * 渚涘墠绔垽鏂綋鍓嶇櫥褰曠敤鎴锋槸鍚﹀簲灞曠ず銆屽鏍搞�嶆寜閽紱鏈厤缃椂杩斿洖绌洪泦鍚堛��
+     *
+     * @return 瀹℃壒浜虹敤鎴风紪鍙烽泦鍚�
+     */
+    Set<Long> getRefundApproverUserIds();
 
-    void updateRefundAuditStatus(Long id, Integer bpmResult);
+    /**
+     * 瀹℃牳閫�璐瑰崟锛堝鎵逛腑 鈫� 瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     *
+     * 浠呬笟鍔$紪鐮� refund_approve 閰嶇疆鐨勫鎵逛汉鍙搷浣滐紙澶氫汉鏃舵垨绛撅級锛涘鏍镐笉閫氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜銆�
+     *
+     * @param id           閫�璐瑰崟缂栧彿
+     * @param pass         鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛堜笉閫氳繃鏃跺嵆涓嶉�氳繃鍘熷洜锛屽繀濉級
+     */
+    void auditRefund(Long id, Boolean pass, String reviewRemark);
 
-    List<Map<String, Object>> getRefundApproveProcessDefinitionList();
-
-}
\ No newline at end of file
+}
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/refund/listener/CrmRefundStatusListener.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/refund/listener/CrmRefundStatusListener.java
deleted file mode 100644
index a7ed588..0000000
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/refund/listener/CrmRefundStatusListener.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package cn.iocoder.yudao.module.crm.service.refund.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.crm.dal.dataobject.refund.CrmRefundDO;
-import cn.iocoder.yudao.module.crm.dal.mysql.refund.CrmRefundMapper;
-import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
-import cn.iocoder.yudao.module.crm.service.refund.CrmRefundService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-/**
- * 閫�璐瑰鎵圭殑缁撴灉鐩戝惉鍣ㄥ疄鐜扮被
- *
- * 閫氳繃 businessKey锛堥��璐瑰崟ID锛夊尮閰嶏紝鑰屼笉鏄浐瀹氱殑娴佺▼瀹氫箟 Key锛�
- * 杩欐牱鍙互鏀寔鍒嗙被涓嬩换鎰� Key 鐨勬祦绋嬫ā鍨嬨��
- */
-@Component
-@Slf4j
-public class CrmRefundStatusListener implements ApplicationListener<BpmProcessInstanceStatusEvent> {
-
-    @Resource
-    private CrmRefundService refundService;
-    @Resource
-    private CrmRefundMapper refundMapper;
-
-    @Override
-    public void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
-        // 閫氳繃 businessKey 鏌ヨ閫�璐瑰崟
-        Long refundId;
-        try {
-            refundId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            return; // businessKey 涓嶆槸鏁板瓧锛屽拷鐣�
-        }
-
-        CrmRefundDO refund = refundMapper.selectById(refundId);
-        if (refund == null) {
-            return; // 涓嶆槸閫�璐瑰崟锛屽拷鐣�
-        }
-
-        // 鍙湁瀹℃壒涓姸鎬佺殑閫�璐瑰崟鎵嶅鐞�
-        if (!CrmAuditStatusEnum.PROCESS.getStatus().equals(refund.getAuditStatus())) {
-            log.warn("[onApplicationEvent] 閫�璐瑰崟({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵��: {}", refundId, refund.getAuditStatus());
-            return;
-        }
-
-        log.info("[onApplicationEvent] 閫�璐瑰崟({}) 瀹℃壒鐘舵�佹洿鏂�: {}", refundId, event.getStatus());
-        // 鏇存柊瀹℃壒鐘舵��
-        refundService.updateRefundAuditStatus(refundId, event.getStatus());
-    }
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinancePaymentController.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinancePaymentController.java
index e24d92f..93b2c09 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinancePaymentController.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinancePaymentController.java
@@ -9,6 +9,7 @@
 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentAuditReqVO;
 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentPageReqVO;
 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentRespVO;
 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentSaveReqVO;
@@ -38,12 +39,12 @@
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.stream.Stream;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 @Tag(name = "绠$悊鍚庡彴 - ERP 浠樻鍗�")
 @RestController
@@ -80,21 +81,29 @@
         return success(true);
     }
 
-    @PostMapping("/submit")
-    @Operation(summary = "鎻愪氦浠樻鍗曞鎵�")
+    @PutMapping("/submit")
+    @Operation(summary = "鎻愪氦浠樻鍗曞鎵癸紙鏈鏍� 鈫� 瀹℃壒涓級锛屽鎵逛汉鐢卞鎵归厤缃粺涓�鎸囧畾")
+    @Parameter(name = "id", description = "缂栧彿", required = true)
     @PreAuthorize("@ss.hasPermission('erp:finance-payment:update')")
-    public CommonResult<Boolean> submitFinancePayment(@RequestParam("id") Long id,
-                                                      @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        Long userId = getLoginUserId();
-        financePaymentService.submitFinancePayment(id, processDefinitionKey, userId);
+    public CommonResult<Boolean> submitFinancePayment(@RequestParam("id") Long id) {
+        financePaymentService.submitFinancePayment(id);
         return success(true);
     }
 
-    @GetMapping("/approve-process-list")
-    @Operation(summary = "鑾峰彇浠樻鍗曞鎵规祦绋嬪垪琛�")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳浠樻鍗曪紙瀹℃壒涓� 鈫� 瀹℃牳閫氳繃/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('erp:finance-payment:audit')")
+    public CommonResult<Boolean> auditFinancePayment(@Valid @RequestBody ErpFinancePaymentAuditReqVO auditReqVO) {
+        financePaymentService.auditFinancePayment(auditReqVO.getId(), auditReqVO.getPass(),
+                auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱浠樻鍗曠殑瀹℃壒浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
     @PreAuthorize("@ss.hasPermission('erp:finance-payment:query')")
-    public CommonResult<List<Map<String, Object>>> getApproveProcessList() {
-        return success(financePaymentService.getFinancePaymentApproveProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(financePaymentService.getFinancePaymentApproverUserIds());
     }
 
     @DeleteMapping("/delete")
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentAuditReqVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentAuditReqVO.java
new file mode 100644
index 0000000..5fcf7d0
--- /dev/null
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentAuditReqVO.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * ERP 浠樻鍗曞鏍� Request VO
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - ERP 浠樻鍗曞鏍� Request VO")
+@Data
+public class ErpFinancePaymentAuditReqVO {
+
+    @Schema(description = "浠樻鍗曠紪鍙�", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "浠樻鍗曠紪鍙蜂笉鑳戒负绌�")
+    private Long id;
+
+    @Schema(description = "鏄惁瀹℃牳閫氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "瀹℃牳缁撴灉涓嶈兘涓虹┖")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃朵负鍙�夛紱瀹℃牳涓嶉�氳繃鏃朵负蹇呭~鐨勫師鍥狅級", example = "鍚屾剰浠樻")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentRespVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentRespVO.java
index 05d7d76..271db4a 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentRespVO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/vo/payment/ErpFinancePaymentRespVO.java
@@ -26,9 +26,24 @@
     @Schema(description = "浠樻鐘舵��", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     private Integer status;
 
-    @Schema(description = "宸ヤ綔娴佺紪鍙�", example = "3cc7f8e6")
+    @Schema(description = "宸ヤ綔娴佺紪鍙凤紙宸插簾寮冿紝杞婚噺绾у鎵逛笉鍐嶄娇鐢級", example = "3cc7f8e6")
+    @Deprecated
     private String processInstanceId;
 
+    // ========== 瀹℃壒淇℃伅锛堣交閲忕骇鐘舵�佹満瀹℃壒锛� ==========
+
+    @Schema(description = "瀹℃牳浜虹紪鍙�", example = "1")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜烘樀绉�", example = "瓒呯骇绠$悊鍛�")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍镐笉閫氳繃鏃朵负椹冲洖鍘熷洜锛�", example = "鍚屾剰浠樻")
+    private String reviewRemark;
+
     @Schema(description = "浠樻鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime paymentTime;
 
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseRequestController.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseRequestController.java
index ed0bed4..01e2453 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseRequestController.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseRequestController.java
@@ -8,6 +8,7 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestAuditReqVO;
 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestPageReqVO;
 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestRespVO;
 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestSaveReqVO;
@@ -38,12 +39,12 @@
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 @Tag(name = "绠$悊鍚庡彴 - ERP 閲囪喘鐢宠")
 @RestController
@@ -134,20 +135,28 @@
     }
 
     @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦閲囪喘鐢宠瀹℃壒")
+    @Operation(summary = "鎻愪氦閲囪喘鐢宠瀹℃壒锛堟湭鎻愪氦/瀹℃牳涓嶉�氳繃 鈫� 瀹℃壒涓級锛屽鎵逛汉鐢卞鎵归厤缃粺涓�鎸囧畾")
+    @Parameter(name = "id", description = "缂栧彿", required = true)
     @PreAuthorize("@ss.hasPermission('erp:purchase-request:submit')")
-    public CommonResult<Boolean> submitPurchaseRequest(@RequestParam("id") Long id,
-                                                       @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        Long userId = getLoginUserId();
-        purchaseRequestService.submitPurchaseRequest(id, processDefinitionKey, userId);
+    public CommonResult<Boolean> submitPurchaseRequest(@RequestParam("id") Long id) {
+        purchaseRequestService.submitPurchaseRequest(id);
         return success(true);
     }
 
-    @GetMapping("/approve-process-list")
-    @Operation(summary = "鑾峰彇閲囪喘鐢宠瀹℃壒娴佺▼鍒楄〃")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳閲囪喘鐢宠锛堝鎵逛腑 鈫� 瀹℃牳閫氳繃/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('erp:purchase-request:audit')")
+    public CommonResult<Boolean> auditPurchaseRequest(@Valid @RequestBody ErpPurchaseRequestAuditReqVO auditReqVO) {
+        purchaseRequestService.auditPurchaseRequest(auditReqVO.getId(), auditReqVO.getPass(),
+                auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱閲囪喘鐢宠鐨勫鎵逛汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳")
     @PreAuthorize("@ss.hasPermission('erp:purchase-request:query')")
-    public CommonResult<List<Map<String, Object>>> getApproveProcessList() {
-        return success(purchaseRequestService.getPurchaseRequestApproveProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(purchaseRequestService.getPurchaseRequestApproverUserIds());
     }
 
     @PostMapping("/generate-order")
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestAuditReqVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestAuditReqVO.java
new file mode 100644
index 0000000..a325efa
--- /dev/null
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestAuditReqVO.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * ERP 閲囪喘鐢宠瀹℃牳 Request VO
+ */
+@Schema(description = "绠$悊鍚庡彴 - ERP 閲囪喘鐢宠瀹℃牳 Request VO")
+@Data
+public class ErpPurchaseRequestAuditReqVO {
+
+    @Schema(description = "閲囪喘鐢宠缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "閲囪喘鐢宠缂栧彿涓嶈兘涓虹┖")
+    private Long id;
+
+    @Schema(description = "鏄惁瀹℃牳閫氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "瀹℃牳缁撴灉涓嶈兘涓虹┖")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃朵负鍙�夛紱瀹℃牳涓嶉�氳繃鏃朵负蹇呭~鐨勫師鍥狅級", example = "鍚屾剰閲囪喘")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestRespVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestRespVO.java
index 74ff12b..6e1e183 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestRespVO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestRespVO.java
@@ -29,9 +29,27 @@
     @ExcelProperty(value = "鐘舵��", converter = cn.iocoder.yudao.module.erp.convert.ErpPurchaseRequestStatusConvert.class)
     private Integer status;
 
-    @Schema(description = "娴佺▼瀹炰緥缂栧彿", example = "1024")
+    @Schema(description = "娴佺▼瀹炰緥缂栧彿锛堝凡搴熷純锛岃交閲忕骇瀹℃壒涓嶅啀浣跨敤锛�", example = "1024")
+    @Deprecated
     private String processInstanceId;
 
+    // ========== 瀹℃壒淇℃伅锛堣交閲忕骇鐘舵�佹満瀹℃壒锛� ==========
+
+    @Schema(description = "瀹℃牳浜虹紪鍙�", example = "1")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜烘樀绉�", example = "瓒呯骇绠$悊鍛�")
+    @ExcelProperty("瀹℃牳浜�")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    @ExcelProperty("瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍镐笉閫氳繃鏃朵负椹冲洖鍘熷洜锛�", example = "鍚屾剰閲囪喘")
+    @ExcelProperty("瀹℃牳鎰忚")
+    private String reviewRemark;
+
     @Schema(description = "鐢宠浜虹紪鍙�", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     @ExcelProperty("鐢宠浜虹紪鍙�")
     private Long requestUserId;
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/finance/ErpFinancePaymentDO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/finance/ErpFinancePaymentDO.java
index dfdaeda..c981a1f 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/finance/ErpFinancePaymentDO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/finance/ErpFinancePaymentDO.java
@@ -44,9 +44,33 @@
     /**
      * 宸ヤ綔娴佺紪鍙�
      *
-     * 鍏宠仈 BPM 娴佺▼瀹炰緥鐨� id
+     * 宸插簾寮冿細浠樻鍗曟敼涓鸿交閲忕骇鐘舵�佹満瀹℃壒鍚庝笉鍐嶅啓鍏ワ紝浠呬繚鐣欏巻鍙叉暟鎹��
      */
+    @Deprecated
     private String processInstanceId;
+
+    /**
+     * 瀹℃牳浜虹紪鍙凤紙绯荤粺鐢ㄦ埛锛�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� erp_finance_payment_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
+     */
+    private Long reviewerId;
+
+    /**
+     * 瀹℃牳浜烘樀绉帮紙鍐椾綑灞曠ず鐢級
+     */
+    private String reviewerName;
+
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private LocalDateTime reviewTime;
+
+    /**
+     * 瀹℃牳鎰忚锛堝鏍镐笉閫氳繃鏃跺繀濉紝浣滀负椹冲洖鍘熷洜锛�
+     */
+    private String reviewRemark;
     /**
      * 浠樻鏃堕棿
      */
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseRequestDO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseRequestDO.java
index de4cde0..b24aca3 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseRequestDO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseRequestDO.java
@@ -111,10 +111,36 @@
 
     /**
      * BPM 娴佺▼瀹炰緥缂栧彿
+     *
+     * 宸插簾寮冿細閲囪喘鐢宠鏀逛负杞婚噺绾х姸鎬佹満瀹℃壒鍚庝笉鍐嶅啓鍏ワ紝浠呬繚鐣欏巻鍙叉暟鎹��
      */
+    @Deprecated
     private String processInstanceId;
 
     /**
+     * 瀹℃牳浜虹紪鍙凤紙绯荤粺鐢ㄦ埛锛�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� purchase_request_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
+     */
+    private Long reviewerId;
+
+    /**
+     * 瀹℃牳浜烘樀绉帮紙鍐椾綑灞曠ず鐢級
+     */
+    private String reviewerName;
+
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private LocalDateTime reviewTime;
+
+    /**
+     * 瀹℃牳鎰忚锛堝鏍镐笉閫氳繃鏃跺繀濉紝浣滀负椹冲洖鍘熷洜锛�
+     */
+    private String reviewRemark;
+
+    /**
      * 鐢熸垚鐨勯噰璐鍗曠紪鍙�
      */
     private Long orderId;
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/finance/ErpFinancePaymentMapper.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/finance/ErpFinancePaymentMapper.java
index b08d529..5f9f603 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/finance/ErpFinancePaymentMapper.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/finance/ErpFinancePaymentMapper.java
@@ -14,6 +14,7 @@
 import org.apache.ibatis.annotations.Mapper;
 
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -84,4 +85,34 @@
         return convertMap(result, obj -> (Long) obj.get("invoice_id"), obj -> (BigDecimal) obj.get("total_payment_price"));
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜�/瀹℃牳鏃堕棿/瀹℃牳鎰忚娓呯┖銆�
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<ErpFinancePaymentDO>()
+                .eq(ErpFinancePaymentDO::getId, id)
+                .set(ErpFinancePaymentDO::getStatus, status)
+                .set(ErpFinancePaymentDO::getReviewerId, null)
+                .set(ErpFinancePaymentDO::getReviewerName, null)
+                .set(ErpFinancePaymentDO::getReviewTime, null)
+                .set(ErpFinancePaymentDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛堥�氳繃 / 涓嶉�氳繃锛夛細鍐欏叆瀹℃牳缁撴灉銆佸鏍镐汉涓庡鏍告剰瑙�
+     */
+    default int auditFinancePayment(Long id, Integer status, Long reviewerId,
+                                    String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<ErpFinancePaymentDO>()
+                .eq(ErpFinancePaymentDO::getId, id)
+                .set(ErpFinancePaymentDO::getStatus, status)
+                .set(ErpFinancePaymentDO::getReviewerId, reviewerId)
+                .set(ErpFinancePaymentDO::getReviewerName, reviewerName)
+                .set(ErpFinancePaymentDO::getReviewTime, LocalDateTime.now())
+                .set(ErpFinancePaymentDO::getReviewRemark, reviewRemark));
+    }
+
 }
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseRequestMapper.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseRequestMapper.java
index 0c989a6..d68ef85 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseRequestMapper.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseRequestMapper.java
@@ -5,8 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestPageReqVO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
 
@@ -42,4 +44,34 @@
                 .orderByDesc(ErpPurchaseRequestDO::getId));
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜�/瀹℃牳鏃堕棿/瀹℃牳鎰忚娓呯┖銆�
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<ErpPurchaseRequestDO>()
+                .eq(ErpPurchaseRequestDO::getId, id)
+                .set(ErpPurchaseRequestDO::getStatus, status)
+                .set(ErpPurchaseRequestDO::getReviewerId, null)
+                .set(ErpPurchaseRequestDO::getReviewerName, null)
+                .set(ErpPurchaseRequestDO::getReviewTime, null)
+                .set(ErpPurchaseRequestDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛堥�氳繃 / 涓嶉�氳繃锛夛細鍐欏叆瀹℃牳缁撴灉銆佸鏍镐汉涓庡鏍告剰瑙�
+     */
+    default int auditPurchaseRequest(Long id, Integer status, Long reviewerId,
+                                     String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<ErpPurchaseRequestDO>()
+                .eq(ErpPurchaseRequestDO::getId, id)
+                .set(ErpPurchaseRequestDO::getStatus, status)
+                .set(ErpPurchaseRequestDO::getReviewerId, reviewerId)
+                .set(ErpPurchaseRequestDO::getReviewerName, reviewerName)
+                .set(ErpPurchaseRequestDO::getReviewTime, LocalDateTime.now())
+                .set(ErpPurchaseRequestDO::getReviewRemark, reviewRemark));
+    }
+
 }
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
index 20399ad..1339ebc 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
@@ -51,14 +51,14 @@
     ErrorCode PURCHASE_REQUEST_NOT_EXISTS = new ErrorCode(1_030_104_000, "閲囪喘鐢宠鍗曚笉瀛樺湪");
     ErrorCode PURCHASE_REQUEST_DELETE_FAIL_NOT_DRAFT = new ErrorCode(1_030_104_001, "閲囪喘鐢宠鍗�({})涓嶆槸鑽夌鐘舵�侊紝鏃犳硶鍒犻櫎");
     ErrorCode PURCHASE_REQUEST_UPDATE_FAIL_NOT_DRAFT = new ErrorCode(1_030_104_002, "閲囪喘鐢宠鍗�({})涓嶆槸鑽夌鐘舵�侊紝鏃犳硶淇敼");
-    ErrorCode PURCHASE_REQUEST_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_030_104_003, "鎻愪氦澶辫触锛屽彧鏈夎崏绋跨姸鎬佺殑鐢宠鍗曟墠鑳芥彁浜�");
     ErrorCode PURCHASE_REQUEST_NO_EXISTS = new ErrorCode(1_030_104_004, "鐢熸垚鐢宠鍗曞彿澶辫触锛岃閲嶆柊鎻愪氦");
-    ErrorCode PURCHASE_REQUEST_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_030_104_005, "鏇存柊瀹℃壒鐘舵�佸け璐ワ紝鍙湁瀹℃壒涓殑鐢宠鍗曟墠鑳芥洿鏂�");
     ErrorCode PURCHASE_REQUEST_NOT_APPROVE = new ErrorCode(1_030_104_006, "閲囪喘鐢宠鍗曟湭瀹℃牳閫氳繃锛屾棤娉曟搷浣�");
     ErrorCode PURCHASE_REQUEST_ORDER_EXISTS = new ErrorCode(1_030_104_007, "閲囪喘鐢宠鍗曞凡鐢熸垚閲囪喘璁㈠崟锛岃鍕块噸澶嶆搷浣�");
-    ErrorCode PURCHASE_REQUEST_BPM_CATEGORY_NOT_EXISTS = new ErrorCode(1_030_104_008, "閲囪喘鐢宠瀹℃壒鍒嗙被涓嶅瓨鍦紝璇峰厛鍦˙PM妯″潡鍒涘缓閲囪喘鐢宠瀹℃壒娴佺▼鍒嗙被");
-    ErrorCode PURCHASE_REQUEST_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_104_009, "閲囪喘鐢宠瀹℃壒鍒嗙被涓嬫病鏈夊彲鐢ㄧ殑娴佺▼妯″瀷锛岃鍏堝垱寤哄苟鍙戝竷娴佺▼");
     ErrorCode PURCHASE_REQUEST_ITEM_PRICE_EMPTY = new ErrorCode(1_030_104_021, "閲囪喘鐢宠鏄庣粏({})閲戦淇℃伅涓嶅畬鏁达紝鏃犳硶鐢熸垚閲囪喘璁㈠崟");
+    ErrorCode PURCHASE_REQUEST_SUBMIT_FAIL_NOT_ALLOWED = new ErrorCode(1_030_104_022, "鎻愪氦澶辫触锛屽彧鏈夎崏绋挎垨瀹℃牳涓嶉�氳繃鐘舵�佺殑閲囪喘鐢宠鎵嶈兘鎻愪氦");
+    ErrorCode PURCHASE_REQUEST_AUDIT_FAIL_NOT_PROCESS = new ErrorCode(1_030_104_023, "瀹℃牳澶辫触锛屽彧鏈夊鎵逛腑鐘舵�佺殑閲囪喘鐢宠鎵嶈兘瀹℃牳");
+    ErrorCode PURCHASE_REQUEST_AUDIT_REJECT_REASON_REQUIRED = new ErrorCode(1_030_104_024, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
+    ErrorCode PURCHASE_REQUEST_ITEM_EMPTY = new ErrorCode(1_030_104_025, "閲囪喘鐢宠鍗曟病鏈夌敵璇锋槑缁嗭紝鏃犳硶鎻愪氦瀹℃壒");
 
     // ========== ERP 閲囪喘璁″垝锛�1-030-104-010锛� ==========
     ErrorCode PURCHASE_PLAN_NOT_EXISTS = new ErrorCode(1_030_104_010, "閲囪喘璁″垝涓嶅瓨鍦�");
@@ -216,11 +216,11 @@
     ErrorCode FINANCE_PAYMENT_CREATE_FAIL_INVOICE_NOT_ATTACHMENT = new ErrorCode(1_030_601_008, "鍒涘缓浠樻鍗曞け璐ワ紝鍘熷洜锛氬叧鑱旂殑鏉ョエ鏈笂浼犲彂绁ㄩ檮浠�");
     ErrorCode FINANCE_PAYMENT_CREATE_FAIL_INVOICE_SUPPLIER_MISMATCH = new ErrorCode(1_030_601_009, "鍒涘缓浠樻鍗曞け璐ワ紝鍘熷洜锛氬叧鑱旂殑鏉ョエ涓庢墍閫変緵搴斿晢涓嶅尮閰�");
     ErrorCode FINANCE_PAYMENT_CREATE_FAIL_INVOICE_PRICE_EXCEEDS = new ErrorCode(1_030_601_010, "鍒涘缓浠樻鍗曞け璐ワ紝鍘熷洜锛氫粯娆鹃噾棰濊秴鍑鸿鏉ョエ鍓╀綑鍙粯閲戦锛岀洰鍓嶅彲浠橈細{} 鍏�");
-    ErrorCode FINANCE_PAYMENT_SUBMIT_FAIL_STATUS = new ErrorCode(1_030_601_011, "鎻愪氦瀹℃壒澶辫触锛屽彧鏈夋湭瀹℃牳鐘舵�佺殑浠樻鍗曟墠鑳芥彁浜�");
-    ErrorCode FINANCE_PAYMENT_BPM_CATEGORY_NOT_EXISTS = new ErrorCode(1_030_601_012, "浠樻鍗曞鎵瑰垎绫讳笉瀛樺湪锛岃鍏堝湪BPM妯″潡鍒涘缓閲囪喘瀹℃牳娴佺▼鍒嗙被");
-    ErrorCode FINANCE_PAYMENT_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_601_013, "浠樻鍗曞鎵瑰垎绫讳笅娌℃湁鍙敤鐨勬祦绋嬫ā鍨嬶紝璇峰厛鍒涘缓骞跺彂甯冩祦绋�");
     ErrorCode FINANCE_PAYMENT_UPDATE_FAIL_APPROVING = new ErrorCode(1_030_601_014, "浠樻鍗�({})瀹℃壒涓紝鏃犳硶淇敼");
     ErrorCode FINANCE_PAYMENT_DELETE_FAIL_APPROVING = new ErrorCode(1_030_601_015, "浠樻鍗�({})瀹℃壒涓紝鏃犳硶鍒犻櫎");
+    ErrorCode FINANCE_PAYMENT_SUBMIT_FAIL_NOT_ALLOWED = new ErrorCode(1_030_601_016, "鎻愪氦澶辫触锛屽彧鏈夋湭瀹℃牳鐘舵�佺殑浠樻鍗曟墠鑳芥彁浜�");
+    ErrorCode FINANCE_PAYMENT_AUDIT_FAIL_NOT_PROCESS = new ErrorCode(1_030_601_017, "瀹℃牳澶辫触锛屽彧鏈夊鎵逛腑鐘舵�佺殑浠樻鍗曟墠鑳藉鏍�");
+    ErrorCode FINANCE_PAYMENT_AUDIT_REJECT_REASON_REQUIRED = new ErrorCode(1_030_601_018, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
 
     // ========== ERP 鏀舵鍗� 1-030-602-000 ==========
     ErrorCode FINANCE_RECEIPT_NOT_EXISTS = new ErrorCode(1_030_602_000, "鏀舵鍗曚笉瀛樺湪");
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentService.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentService.java
index a58be47..55b411f 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentService.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentService.java
@@ -11,6 +11,7 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * ERP 浠樻鍗� Service 鎺ュ彛
@@ -37,26 +38,30 @@
     /**
      * 鎻愪氦浠樻鍗曞鎵�
      *
-     * @param id 缂栧彿
-     * @param processDefinitionKey 娴佺▼瀹氫箟鐨勭紪鍙�
-     * @param userId 鐢ㄦ埛缂栧彿
-     */
-    void submitFinancePayment(Long id, String processDefinitionKey, Long userId);
-
-    /**
-     * 鑾峰緱浠樻鍗曞鎵规祦绋嬪畾涔夊垪琛�
-     *
-     * @return 娴佺▼瀹氫箟鍒楄〃
-     */
-    List<Map<String, Object>> getFinancePaymentApproveProcessDefinitionList();
-
-    /**
-     * 鏇存柊浠樻鍗曠殑瀹℃壒鐘舵�侊紙鐢� BPM 娴佺▼瀹炰緥鐨勫洖璋冭Е鍙戯級
+     * 浠呫�愭湭瀹℃牳銆戯紙鍚鏍镐笉閫氳繃閫�鍥烇級鐘舵�佸彲鎻愪氦锛涘鎵逛汉鐢便�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶇粺涓�鎸囧畾锛�
+     * 鎻愪氦鍚庤繘鍏ャ�愬鎵逛腑銆戯紝骞舵竻绌轰笂涓�杞鏍哥粨鏋溿��
      *
      * @param id 缂栧彿
-     * @param bpmResult BPM 瀹℃壒缁撴灉
      */
-    void updateFinancePaymentAuditStatus(Long id, Integer bpmResult);
+    void submitFinancePayment(Long id);
+
+    /**
+     * 鑾峰彇浠樻鍗曠殑瀹℃壒浜虹紪鍙烽泦鍚堬紙鎴栫锛氫换涓�浜哄鏍稿嵆鍙級
+     *
+     * @return 瀹℃壒浜虹敤鎴风紪鍙�
+     */
+    Set<Long> getFinancePaymentApproverUserIds();
+
+    /**
+     * 瀹℃牳浠樻鍗曪紙閫氳繃 / 涓嶉�氳繃锛�
+     *
+     * 浠呴厤缃唴鐨勫鎵逛汉鍙墽琛岋紱瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欏師鍥狅紝閫�鍥炲悗鍙慨鏀瑰苟閲嶆柊鎻愪氦銆�
+     *
+     * @param id 缂栧彿
+     * @param pass 鏄惁瀹℃牳閫氳繃
+     * @param reviewRemark 瀹℃牳鎰忚
+     */
+    void auditFinancePayment(Long id, Boolean pass, String reviewRemark);
 
     /**
      * 鍒犻櫎浠樻鍗�
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java
index 5fdd106..397afd9 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java
@@ -2,15 +2,9 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentPageReqVO;
 import cn.iocoder.yudao.module.erp.controller.admin.finance.vo.payment.ErpFinancePaymentSaveReqVO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO;
@@ -23,11 +17,12 @@
 import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceService;
 import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceServiceImpl;
 import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
 import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
@@ -37,6 +32,7 @@
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
 
 /**
@@ -50,9 +46,9 @@
 public class ErpFinancePaymentServiceImpl implements ErpFinancePaymentService {
 
     /**
-     * BPM 浠樻鍗曞鎵瑰垎绫荤紪鐮�
+     * 閫氱敤瀹℃壒閰嶇疆鐨勪笟鍔$被鍨嬬紪鐮侊紙瀵瑰簲 system_approval_config.biz_type锛�
      */
-    private static final String BPM_PROCESS_DEFINITION_CATEGORY_CODE = "erp_finance_payment_approve";
+    private static final String FINANCE_PAYMENT_APPROVE_BIZ_TYPE = "erp_finance_payment_approve";
 
     @Resource
     private ErpFinancePaymentMapper financePaymentMapper;
@@ -76,11 +72,7 @@
     private StorageAttachmentApi storageAttachmentApi;
 
     @Resource
-    private BpmProcessInstanceApi processInstanceApi;
-    @Resource
-    private BpmCategoryService bpmCategoryService;
-    @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private ApprovalConfigApi approvalConfigApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -176,105 +168,61 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitFinancePayment(Long id, String processDefinitionKey, Long userId) {
-        // 1. 鏍¢獙瀛樺湪 + 鏈鏍哥姸鎬�
+    public void submitFinancePayment(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鍙彁浜ょ姸鎬侊紙鏈鏍革細鍚鏍镐笉閫氳繃閫�鍥炲悗閲嶆柊鎻愪氦锛�
         ErpFinancePaymentDO payment = validateFinancePaymentExists(id);
         if (!ErpAuditStatus.PROCESS.getStatus().equals(payment.getStatus())) {
-            throw exception(FINANCE_PAYMENT_SUBMIT_FAIL_STATUS);
+            throw exception(FINANCE_PAYMENT_SUBMIT_FAIL_NOT_ALLOWED);
         }
-
-        // 2. 鍒涘缓 BPM 娴佺▼瀹炰緥
-        String processInstanceId = processInstanceApi.createProcessInstance(userId,
-                new BpmProcessInstanceCreateReqDTO()
-                        .setProcessDefinitionKey(processDefinitionKey)
-                        .setBusinessKey(String.valueOf(id)));
-
-        // 3. 鏇存柊浠樻鍗曠姸鎬佷负瀹℃壒涓�
-        financePaymentMapper.updateById(new ErpFinancePaymentDO()
-                .setId(id)
-                .setStatus(ErpAuditStatus.APPROVING.getStatus())
-                .setProcessInstanceId(processInstanceId));
+        // 2. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鎵逛汉
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(FINANCE_PAYMENT_APPROVE_BIZ_TYPE);
+        // 3. 鐘舵�佺疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+        financePaymentMapper.submitAndResetAuditInfo(id, ErpAuditStatus.APPROVING.getStatus());
     }
 
     @Override
-    public List<Map<String, Object>> getFinancePaymentApproveProcessDefinitionList() {
-        // 1. 鏍¢獙鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-        validateFinancePaymentApproveCategoryAndProcessDefinition();
-
-        // 2. 鑾峰彇鍒嗙被涓嬬殑娴佺▼瀹氫箟淇℃伅
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(BPM_PROCESS_DEFINITION_CATEGORY_CODE);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            return Collections.emptyList();
-        }
-
-        // 3. 閬嶅巻鑾峰彇娴佺▼瀹氫箟璇︽儏锛岃繃婊ゆ縺娲荤姸鎬侊紝淇濈暀鏈�鏂扮増鏈�
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (BpmProcessDefinitionInfoDO info : definitionInfoList) {
-            ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId());
-            if (pd == null || pd.isSuspended()) {
-                continue;
-            }
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-
-        // 4. 杩斿洖娴佺▼瀹氫箟鍒楄〃
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            result.add(item);
-        }
-        return result;
+    public Set<Long> getFinancePaymentApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(FINANCE_PAYMENT_APPROVE_BIZ_TYPE);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void updateFinancePaymentAuditStatus(Long id, Integer bpmResult) {
+    public void auditFinancePayment(Long id, Boolean pass, String reviewRemark) {
         // 1. 鏍¢獙瀛樺湪
         ErpFinancePaymentDO payment = validateFinancePaymentExists(id);
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
         if (!ErpAuditStatus.APPROVING.getStatus().equals(payment.getStatus())) {
-            log.warn("[updateFinancePaymentAuditStatus] 浠樻鍗�({}) 涓嶅浜庡鎵逛腑鐘舵��", id);
+            throw exception(FINANCE_PAYMENT_AUDIT_FAIL_NOT_PROCESS);
+        }
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鎵逛汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(FINANCE_PAYMENT_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝閫�鍥炶储鍔′汉鍛樹慨鏀瑰悗鍙噸鏂版彁浜�
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(FINANCE_PAYMENT_AUDIT_REJECT_REASON_REQUIRED);
+            }
+            financePaymentMapper.auditFinancePayment(id, ErpAuditStatus.PROCESS.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
             return;
         }
-
-        // 2. 鏍规嵁瀹℃壒缁撴灉鏇存柊鐘舵��
-        Integer newStatus = convertBpmResultToAuditStatus(bpmResult);
-        if (newStatus != null) {
-            financePaymentMapper.updateById(new ErpFinancePaymentDO()
-                    .setId(id).setStatus(newStatus));
-        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄凡瀹℃牳
+        financePaymentMapper.auditFinancePayment(id, ErpAuditStatus.APPROVE.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
     }
 
     /**
-     * 鏍¢獙浠樻鍗曞鎵瑰垎绫诲拰娴佺▼瀹氫箟鏄惁瀛樺湪
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
      */
-    private void validateFinancePaymentApproveCategoryAndProcessDefinition() {
-        // 1. 鏍¢獙鍒嗙被鏄惁瀛樺湪
-        List<BpmCategoryDO> categories = bpmCategoryService.getCategoryListByCode(
-                Collections.singletonList(BPM_PROCESS_DEFINITION_CATEGORY_CODE));
-        if (CollUtil.isEmpty(categories)) {
-            throw exception(FINANCE_PAYMENT_BPM_CATEGORY_NOT_EXISTS);
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
         }
-    }
-
-    /**
-     * 杞崲 BPM 瀹℃壒缁撴灉涓哄鏍哥姸鎬�
-     */
-    private Integer convertBpmResultToAuditStatus(Integer bpmResult) {
-        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
-            return ErpAuditStatus.APPROVE.getStatus();
-        } else if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
-            return ErpAuditStatus.PROCESS.getStatus();
-        } else if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
-            return ErpAuditStatus.CANCEL.getStatus();
-        }
-        return null;
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
     private List<ErpFinancePaymentItemDO> validateFinancePaymentItems(
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/listener/ErpFinancePaymentStatusListener.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/listener/ErpFinancePaymentStatusListener.java
deleted file mode 100644
index 9a168e3..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/listener/ErpFinancePaymentStatusListener.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package cn.iocoder.yudao.module.erp.service.finance.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener;
-import cn.iocoder.yudao.module.erp.service.finance.ErpFinancePaymentService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-/**
- * 浠樻鍗曞鎵圭姸鎬佺洃鍚櫒
- *
- * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝鏇存柊浠樻鍗曠殑瀹℃壒鐘舵��
- *
- * @author 瓒呯骇绠$悊鍛�
- */
-@Component
-@Slf4j
-public class ErpFinancePaymentStatusListener extends BpmProcessInstanceStatusEventListener {
-
-    /**
-     * BPM 浠樻鍗曞鎵规祦绋嬪畾涔� key
-     */
-    private static final String BPM_PROCESS_DEFINITION_KEY = "erp-finance-payment-audit";
-
-    @Resource
-    private ErpFinancePaymentService financePaymentService;
-
-    @Override
-    protected String getProcessDefinitionKey() {
-        return BPM_PROCESS_DEFINITION_KEY;
-    }
-
-    @Override
-    protected void onEvent(BpmProcessInstanceStatusEvent event) {
-        Long paymentId;
-        try {
-            paymentId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勪粯娆惧崟缂栧彿", event.getBusinessKey());
-            return;
-        }
-        log.info("[onEvent] 鏀跺埌BPM瀹℃壒浜嬩欢锛宲aymentId={}, status={}", paymentId, event.getStatus());
-        financePaymentService.updateFinancePaymentAuditStatus(paymentId, event.getStatus());
-    }
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestService.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestService.java
index a761923..9919861 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestService.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestService.java
@@ -9,7 +9,7 @@
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 /**
  * ERP 閲囪喘鐢宠 Service 鎺ュ彛
@@ -73,26 +73,30 @@
     /**
      * 鎻愪氦閲囪喘鐢宠瀹℃壒
      *
-     * @param id 缂栧彿
-     * @param processDefinitionKey 娴佺▼瀹氫箟 Key
-     * @param userId 鐢ㄦ埛缂栧彿
-     */
-    void submitPurchaseRequest(Long id, String processDefinitionKey, Long userId);
-
-    /**
-     * 鑾峰彇閲囪喘鐢宠瀹℃壒娴佺▼鍒楄〃
-     *
-     * @return 娴佺▼瀹氫箟鍒楄〃
-     */
-    List<Map<String, Object>> getPurchaseRequestApproveProcessDefinitionList();
-
-    /**
-     * 鏇存柊閲囪喘鐢宠瀹℃壒缁撴灉锛圔PM 鍥炶皟锛�
+     * 浠呫�愭湭鎻愪氦銆戞垨銆愬鏍镐笉閫氳繃銆戠姸鎬佸彲鎻愪氦锛涘鎵逛汉鐢便�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶇粺涓�鎸囧畾锛�
+     * 鎻愪氦鍚庤繘鍏ャ�愬鎵逛腑銆戯紝骞舵竻绌轰笂涓�杞鏍哥粨鏋溿��
      *
      * @param id 缂栧彿
-     * @param bpmResult BPM 瀹℃壒缁撴灉
      */
-    void updatePurchaseRequestAuditStatus(Long id, Integer bpmResult);
+    void submitPurchaseRequest(Long id);
+
+    /**
+     * 鑾峰彇閲囪喘鐢宠鐨勫鎵逛汉缂栧彿闆嗗悎锛堟垨绛撅細浠讳竴浜哄鏍稿嵆鍙級
+     *
+     * @return 瀹℃壒浜虹敤鎴风紪鍙�
+     */
+    Set<Long> getPurchaseRequestApproverUserIds();
+
+    /**
+     * 瀹℃牳閲囪喘鐢宠锛堥�氳繃 / 涓嶉�氳繃锛�
+     *
+     * 浠呴厤缃唴鐨勫鎵逛汉鍙墽琛岋紱瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欏師鍥狅紝閫�鍥炲悗鍙慨鏀瑰苟閲嶆柊鎻愪氦銆�
+     *
+     * @param id 缂栧彿
+     * @param pass 鏄惁瀹℃牳閫氳繃
+     * @param reviewRemark 瀹℃牳鎰忚
+     */
+    void auditPurchaseRequest(Long id, Boolean pass, String reviewRemark);
 
     /**
      * 鐢熸垚閲囪喘璁㈠崟
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestServiceImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestServiceImpl.java
index 6c3c7a7..b8eb017 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestServiceImpl.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestServiceImpl.java
@@ -1,16 +1,10 @@
 package cn.iocoder.yudao.module.erp.service.purchase;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestPageReqVO;
 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestSaveReqVO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
@@ -24,13 +18,13 @@
 import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
 import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
 import cn.iocoder.yudao.module.erp.enums.ErpPurchaseRequestStatusEnum;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
@@ -40,6 +34,7 @@
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
 
 /**
@@ -51,9 +46,9 @@
 public class ErpPurchaseRequestServiceImpl implements ErpPurchaseRequestService {
 
     /**
-     * BPM 閲囪喘鐢宠瀹℃壒鍒嗙被缂栫爜
+     * 閫氱敤瀹℃壒閰嶇疆鐨勪笟鍔$被鍨嬬紪鐮侊紙瀵瑰簲 system_approval_config.biz_type锛�
      */
-    private static final String PURCHASE_REQUEST_APPROVE_CATEGORY_CODE = "purchase_request_approve";
+    private static final String PURCHASE_REQUEST_APPROVE_BIZ_TYPE = "purchase_request_approve";
 
     @Resource
     private ErpPurchaseRequestMapper purchaseRequestMapper;
@@ -72,11 +67,7 @@
     private ErpSupplierService supplierService;
 
     @Resource
-    private BpmProcessInstanceApi processInstanceApi;
-    @Resource
-    private BpmCategoryService bpmCategoryService;
-    @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private ApprovalConfigApi approvalConfigApi;
 
     @Resource
     private AdminUserApi adminUserApi;
@@ -245,90 +236,77 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitPurchaseRequest(Long id, String processDefinitionKey, Long userId) {
-        // 1. 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
-        ErpPurchaseRequestDO purchaseRequest = validatePurchaseRequestCanModify(id);
-
+    public void submitPurchaseRequest(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鍙彁浜ょ姸鎬侊紙鏈彁浜� / 瀹℃牳涓嶉�氳繃锛�
+        ErpPurchaseRequestDO purchaseRequest = validatePurchaseRequestExists(id);
+        if (!ErpPurchaseRequestStatusEnum.DRAFT.getStatus().equals(purchaseRequest.getStatus())
+                && !ErpPurchaseRequestStatusEnum.REJECT.getStatus().equals(purchaseRequest.getStatus())) {
+            throw exception(PURCHASE_REQUEST_SUBMIT_FAIL_NOT_ALLOWED);
+        }
         // 2. 鏍¢獙鏄惁鏈夋槑缁�
         List<ErpPurchaseRequestItemDO> items = purchaseRequestItemMapper.selectListByRequestId(id);
         if (CollUtil.isEmpty(items)) {
-            throw exception(PURCHASE_REQUEST_NOT_EXISTS); // TODO: 娣诲姞鏄庣粏涓虹┖鐨勯敊璇爜
+            throw exception(PURCHASE_REQUEST_ITEM_EMPTY);
         }
-
-        // 3. 鍒涘缓 BPM 娴佺▼瀹炰緥
-        String processInstanceId = processInstanceApi.createProcessInstance(userId,
-                new BpmProcessInstanceCreateReqDTO()
-                        .setProcessDefinitionKey(processDefinitionKey)
-                        .setBusinessKey(String.valueOf(id)));
-
-        // 4. 鏇存柊閲囪喘鐢宠鐘舵�佷负瀹℃壒涓�
-        purchaseRequestMapper.updateById(new ErpPurchaseRequestDO()
-                .setId(id)
-                .setStatus(ErpPurchaseRequestStatusEnum.PROCESS.getStatus())
-                .setProcessInstanceId(processInstanceId));
+        // 3. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鎵逛汉
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(PURCHASE_REQUEST_APPROVE_BIZ_TYPE);
+        // 4. 鐘舵�佺疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+        purchaseRequestMapper.submitAndResetAuditInfo(id, ErpPurchaseRequestStatusEnum.PROCESS.getStatus());
     }
 
     @Override
-    public List<Map<String, Object>> getPurchaseRequestApproveProcessDefinitionList() {
-        // 1. 鏍¢獙鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-        validatePurchaseRequestApproveCategoryAndProcessDefinition();
-
-        // 2. 鑾峰彇鍒嗙被涓嬬殑娴佺▼瀹氫箟淇℃伅
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(PURCHASE_REQUEST_APPROVE_CATEGORY_CODE);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            return Collections.emptyList();
-        }
-
-        // 3. 閬嶅巻鑾峰彇娴佺▼瀹氫箟璇︽儏锛岃繃婊ゆ縺娲荤姸鎬侊紝淇濈暀鏈�鏂扮増鏈�
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (BpmProcessDefinitionInfoDO info : definitionInfoList) {
-            ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId());
-            if (pd == null || pd.isSuspended()) {
-                continue;
-            }
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-
-        // 4. 杩斿洖娴佺▼瀹氫箟鍒楄〃
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            result.add(item);
-        }
-        return result;
+    public Set<Long> getPurchaseRequestApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(PURCHASE_REQUEST_APPROVE_BIZ_TYPE);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void updatePurchaseRequestAuditStatus(Long id, Integer bpmResult) {
+    public void auditPurchaseRequest(Long id, Boolean pass, String reviewRemark) {
         // 1. 鏍¢獙瀛樺湪
         ErpPurchaseRequestDO purchaseRequest = validatePurchaseRequestExists(id);
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
         if (!ErpPurchaseRequestStatusEnum.PROCESS.getStatus().equals(purchaseRequest.getStatus())) {
-            log.warn("[updatePurchaseRequestAuditStatus] 閲囪喘鐢宠({}) 涓嶅浜庡鎵逛腑鐘舵��", id);
+            throw exception(PURCHASE_REQUEST_AUDIT_FAIL_NOT_PROCESS);
+        }
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鎵逛汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(PURCHASE_REQUEST_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝閫�鍥炵敵璇蜂汉淇敼鍚庡彲閲嶆柊鎻愪氦
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(PURCHASE_REQUEST_AUDIT_REJECT_REASON_REQUIRED);
+            }
+            purchaseRequestMapper.auditPurchaseRequest(id, ErpPurchaseRequestStatusEnum.REJECT.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
             return;
         }
-
-        // 2. 鏍规嵁瀹℃壒缁撴灉鏇存柊鐘舵��
-        Integer newStatus = convertBpmResultToStatus(bpmResult);
-        if (newStatus != null) {
-            purchaseRequestMapper.updateById(new ErpPurchaseRequestDO()
-                    .setId(id).setStatus(newStatus));
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙�
+        purchaseRequestMapper.auditPurchaseRequest(id, ErpPurchaseRequestStatusEnum.APPROVE.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
+        // 6. 瀹℃牳閫氳繃涓旀湁渚涘簲鍟嗐�佹湭鐢熸垚璁㈠崟鏃讹紝鑷姩鐢熸垚閲囪喘璁㈠崟
+        if (purchaseRequest.getSupplierId() != null && purchaseRequest.getOrderId() == null) {
+            try {
+                Long orderId = doGeneratePurchaseOrder(purchaseRequest);
+                log.info("[auditPurchaseRequest] 閲囪喘鐢宠({}) 鑷姩鐢熸垚閲囪喘璁㈠崟({})", id, orderId);
+            } catch (Exception e) {
+                // 涓嶆姏鍑哄紓甯革紝閬垮厤褰卞搷瀹℃牳缁撴灉钀藉簱锛涚敓鎴愬け璐ュ彲鐢辩敤鎴锋墜鍔ㄨЕ鍙�
+                log.error("[auditPurchaseRequest] 閲囪喘鐢宠({}) 鑷姩鐢熸垚閲囪喘璁㈠崟澶辫触", id, e);
+            }
         }
+    }
 
-        // 3. 瀹℃壒閫氳繃涓旀湁渚涘簲鍟嗭紝鑷姩鐢熸垚閲囪喘璁㈠崟
-        if (ErpPurchaseRequestStatusEnum.APPROVE.getStatus().equals(newStatus)
-                && purchaseRequest.getSupplierId() != null
-                && purchaseRequest.getOrderId() == null) {
-            Long orderId = doGeneratePurchaseOrder(purchaseRequest);
-            log.info("[updatePurchaseRequestAuditStatus] 閲囪喘鐢宠({}) 鑷姩鐢熸垚閲囪喘璁㈠崟({})", id, orderId);
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
         }
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
     @Override
@@ -421,31 +399,6 @@
                 .setOrderNo(orderNo));
 
         return purchaseOrder.getId();
-    }
-
-    /**
-     * 鏍¢獙閲囪喘鐢宠瀹℃壒鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-     */
-    private void validatePurchaseRequestApproveCategoryAndProcessDefinition() {
-        List<BpmCategoryDO> categories = bpmCategoryService.getCategoryListByCode(
-                Collections.singletonList(PURCHASE_REQUEST_APPROVE_CATEGORY_CODE));
-        if (CollUtil.isEmpty(categories)) {
-            throw exception(PURCHASE_REQUEST_BPM_CATEGORY_NOT_EXISTS);
-        }
-    }
-
-    /**
-     * 杞崲 BPM 瀹℃壒缁撴灉涓虹姸鎬�
-     */
-    private Integer convertBpmResultToStatus(Integer bpmResult) {
-        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
-            return ErpPurchaseRequestStatusEnum.APPROVE.getStatus();
-        } else if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
-            return ErpPurchaseRequestStatusEnum.REJECT.getStatus();
-        } else if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
-            return ErpPurchaseRequestStatusEnum.CANCEL.getStatus();
-        }
-        return null;
     }
 
     private ErpPurchaseRequestDO validatePurchaseRequestExists(Long id) {
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/listener/ErpPurchaseRequestStatusListener.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/listener/ErpPurchaseRequestStatusListener.java
deleted file mode 100644
index caf124d..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/listener/ErpPurchaseRequestStatusListener.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package cn.iocoder.yudao.module.erp.service.purchase.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseRequestService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-/**
- * 閲囪喘鐢宠瀹℃壒鐘舵�佺洃鍚櫒
- *
- * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝鏇存柊閲囪喘鐢宠鐨勫鎵圭姸鎬�
- */
-@Component
-@Slf4j
-public class ErpPurchaseRequestStatusListener extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener {
-
-    /**
-     * 閲囪喘鐢宠瀹℃壒娴佺▼瀹氫箟 Key
-     */
-    private static final String PROCESS_DEFINITION_KEY = "purchase_request_approve";
-
-    @Resource
-    private ErpPurchaseRequestService purchaseRequestService;
-
-    @Override
-    protected String getProcessDefinitionKey() {
-        return PROCESS_DEFINITION_KEY;
-    }
-
-    @Override
-    protected void onEvent(BpmProcessInstanceStatusEvent event) {
-        Long requestId;
-        try {
-            requestId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勯噰璐敵璇风紪鍙�", event.getBusinessKey());
-            return;
-        }
-
-        log.info("[onEvent] 鏀跺埌BPM瀹℃壒浜嬩欢锛宺equestId={}, status={}", requestId, event.getStatus());
-
-        try {
-            purchaseRequestService.updatePurchaseRequestAuditStatus(requestId, event.getStatus());
-            log.info("[onEvent] 閲囪喘鐢宠({}) 瀹℃壒鐘舵�佹洿鏂板畬鎴�", requestId);
-        } catch (Exception e) {
-            log.error("[onEvent] 鏇存柊閲囪喘鐢宠瀹℃壒鐘舵�佸け璐ワ紝requestId={}", requestId, e);
-        }
-    }
-
-}
diff --git a/yudao-module-hrm-api/src/main/java/cn/iocoder/yudao/module/hrm/enums/ErrorCodeConstants.java b/yudao-module-hrm-api/src/main/java/cn/iocoder/yudao/module/hrm/enums/ErrorCodeConstants.java
index 241652b..7649438 100644
--- a/yudao-module-hrm-api/src/main/java/cn/iocoder/yudao/module/hrm/enums/ErrorCodeConstants.java
+++ b/yudao-module-hrm-api/src/main/java/cn/iocoder/yudao/module/hrm/enums/ErrorCodeConstants.java
@@ -32,30 +32,32 @@
     // ========== 璇峰亣鐢宠 1-030-001-000 ==========
     ErrorCode LEAVE_APPLICATION_NOT_EXISTS = new ErrorCode(1_030_001_000, "璇峰亣鐢宠涓嶅瓨鍦�");
     ErrorCode LEAVE_APPLICATION_UPDATE_FAIL_NOT_DRAFT = new ErrorCode(1_030_001_001, "璇峰亣鐢宠鏇存柊澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
-    ErrorCode LEAVE_APPLICATION_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_030_001_002, "璇峰亣鐢宠鎻愪氦澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
+    ErrorCode LEAVE_APPLICATION_SUBMIT_FAIL_NOT_EDITABLE = new ErrorCode(1_030_001_002, "鍙湁鑽夌鎴栧鏍镐笉閫氳繃鐘舵�佺殑璇峰亣鐢宠鎵嶈兘鎻愪氦瀹℃壒");
     ErrorCode LEAVE_APPLICATION_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_030_001_003, "鏇存柊璇峰亣鐢宠瀹℃壒鐘舵�佸け璐ワ紝鍘熷洜锛氫笉鏄鎵逛腑鐘舵��");
     ErrorCode LEAVE_APPLICATION_NO_EXISTS = new ErrorCode(1_030_001_004, "鐢熸垚璇峰亣鐢宠鍗曞彿閲嶅锛岃閲嶈瘯");
     ErrorCode LEAVE_APPLICATION_DURATION_EXCEED = new ErrorCode(1_030_001_005, "璇峰亣鏃堕暱瓒呭嚭骞村亣浣欓");
-    ErrorCode LEAVE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_001_006, "璇峰亣瀹℃壒娴佺▼涓嶅瓨鍦�");
+    ErrorCode LEAVE_APPLICATION_AUDIT_FAIL_NOT_PROCESS = new ErrorCode(1_030_001_006, "鍙湁瀹℃壒涓姸鎬佺殑璇峰亣鐢宠鎵嶈兘瀹℃牳");
+    ErrorCode LEAVE_APPLICATION_AUDIT_REJECT_REASON_REQUIRED = new ErrorCode(1_030_001_007, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
 
     // ========== 璋冨矖鐢宠 1-030-002-000 ==========
     ErrorCode TRANSFER_APPLICATION_NOT_EXISTS = new ErrorCode(1_030_002_000, "璋冨矖鐢宠涓嶅瓨鍦�");
     ErrorCode TRANSFER_APPLICATION_UPDATE_FAIL_NOT_DRAFT = new ErrorCode(1_030_002_001, "璋冨矖鐢宠鏇存柊澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
-    ErrorCode TRANSFER_APPLICATION_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_030_002_002, "璋冨矖鐢宠鎻愪氦澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
-    ErrorCode TRANSFER_APPLICATION_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_030_002_003, "鏇存柊璋冨矖鐢宠瀹℃壒鐘舵�佸け璐ワ紝鍘熷洜锛氫笉鏄鎵逛腑鐘舵��");
+    ErrorCode TRANSFER_APPLICATION_SUBMIT_FAIL_NOT_EDITABLE = new ErrorCode(1_030_002_002, "鍙湁鑽夌鎴栧鏍镐笉閫氳繃鐘舵�佺殑璋冨矖鐢宠鎵嶈兘鎻愪氦瀹℃壒");
     ErrorCode TRANSFER_APPLICATION_NO_EXISTS = new ErrorCode(1_030_002_004, "鐢熸垚璋冨矖鐢宠鍗曞彿閲嶅锛岃閲嶈瘯");
     ErrorCode TRANSFER_APPLICATION_SAME_DEPT = new ErrorCode(1_030_002_005, "璋冨矖澶辫触锛屽師鍥狅細鐩爣閮ㄩ棬涓庡師閮ㄩ棬鐩稿悓");
     ErrorCode TRANSFER_APPLICATION_SAME_POST = new ErrorCode(1_030_002_006, "璋冨矖澶辫触锛屽師鍥狅細鐩爣宀椾綅涓庡師宀椾綅鐩稿悓");
-    ErrorCode TRANSFER_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_002_007, "璋冨矖瀹℃壒娴佺▼涓嶅瓨鍦�");
+    ErrorCode TRANSFER_APPLICATION_AUDIT_FAIL_NOT_PROCESS = new ErrorCode(1_030_002_008, "鍙湁瀹℃壒涓姸鎬佺殑璋冨矖鐢宠鎵嶈兘瀹℃牳");
+    ErrorCode TRANSFER_APPLICATION_AUDIT_REJECT_REASON_REQUIRED = new ErrorCode(1_030_002_009, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
 
     // ========== 绂昏亴鐢宠 1-030-003-000 ==========
     ErrorCode RESIGNATION_APPLICATION_NOT_EXISTS = new ErrorCode(1_030_003_000, "绂昏亴鐢宠涓嶅瓨鍦�");
     ErrorCode RESIGNATION_APPLICATION_UPDATE_FAIL_NOT_DRAFT = new ErrorCode(1_030_003_001, "绂昏亴鐢宠鏇存柊澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
-    ErrorCode RESIGNATION_APPLICATION_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_030_003_002, "绂昏亴鐢宠鎻愪氦澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
+    ErrorCode RESIGNATION_APPLICATION_SUBMIT_FAIL_NOT_EDITABLE = new ErrorCode(1_030_003_002, "鍙湁鑽夌鎴栧鏍镐笉閫氳繃鐘舵�佺殑绂昏亴鐢宠鎵嶈兘鎻愪氦瀹℃壒");
     ErrorCode RESIGNATION_APPLICATION_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_030_003_003, "鏇存柊绂昏亴鐢宠瀹℃壒鐘舵�佸け璐ワ紝鍘熷洜锛氫笉鏄鎵逛腑鐘舵��");
     ErrorCode RESIGNATION_APPLICATION_NO_EXISTS = new ErrorCode(1_030_003_004, "鐢熸垚绂昏亴鐢宠鍗曞彿閲嶅锛岃閲嶈瘯");
     ErrorCode RESIGNATION_APPLICATION_EXISTS = new ErrorCode(1_030_003_005, "璇ュ憳宸ュ凡瀛樺湪绂昏亴鐢宠锛岃鍕块噸澶嶆彁浜�");
-    ErrorCode RESIGNATION_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_003_006, "绂昏亴瀹℃壒娴佺▼涓嶅瓨鍦�");
+    ErrorCode RESIGNATION_APPLICATION_AUDIT_FAIL_NOT_PROCESS = new ErrorCode(1_030_003_006, "鍙湁瀹℃壒涓姸鎬佺殑绂昏亴鐢宠鎵嶈兘瀹℃牳");
+    ErrorCode RESIGNATION_APPLICATION_AUDIT_REJECT_REASON_REQUIRED = new ErrorCode(1_030_003_007, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
 
     // ========== 鐢ㄦ埛鏁版嵁浜ゆ帴 1-030-007-000 ==========
     ErrorCode USER_HANDOVER_NOT_EXISTS = new ErrorCode(1_030_007_000, "鐢ㄦ埛浜ゆ帴璁板綍涓嶅瓨鍦�");
@@ -68,7 +70,7 @@
     ErrorCode ATTENDANCE_RECORD_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_030_004_001, "瀵煎叆鑰冨嫟鏁版嵁涓嶈兘涓虹┖");
     ErrorCode ATTENDANCE_RECORD_EXISTS = new ErrorCode(1_030_004_002, "璇ュ憳宸ュ綋鏃ヨ�冨嫟璁板綍宸插瓨鍦�");
     ErrorCode ATTENDANCE_EXCEPTION_NOT_EXISTS = new ErrorCode(1_030_004_003, "鑰冨嫟寮傚父鐢宠涓嶅瓨鍦�");
-    ErrorCode ATTENDANCE_EXCEPTION_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_030_004_004, "鑰冨嫟寮傚父鐢宠鎻愪氦澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
+    ErrorCode ATTENDANCE_EXCEPTION_SUBMIT_FAIL_NOT_EDITABLE = new ErrorCode(1_030_004_004, "鍙湁鑽夌鎴栧鏍镐笉閫氳繃鐘舵�佺殑鑰冨嫟寮傚父鐢宠鎵嶈兘鎻愪氦瀹℃壒");
     ErrorCode ATTENDANCE_EXCEPTION_UPDATE_FAIL_NOT_DRAFT = new ErrorCode(1_030_004_017, "鑰冨嫟寮傚父鐢宠鏇存柊澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
     ErrorCode ATTENDANCE_EXCEPTION_DELETE_FAIL_NOT_DRAFT = new ErrorCode(1_030_004_018, "鑰冨嫟寮傚父鐢宠鍒犻櫎澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
     ErrorCode ATTENDANCE_RULE_NOT_EXISTS = new ErrorCode(1_030_004_005, "鑰冨嫟瑙勫垯涓嶅瓨鍦�");
@@ -80,17 +82,17 @@
     ErrorCode ATTENDANCE_CLOCK_FAIL_HOLIDAY = new ErrorCode(1_030_004_011, "鎵撳崱澶辫触锛屽綋鏃ヤ负浼戞伅鏃�");
     ErrorCode ATTENDANCE_CLOCK_FAIL_NOT_WORKDAY = new ErrorCode(1_030_004_012, "鎵撳崱澶辫触锛屽綋鏃ヤ笉鏄伐浣滄棩");
     ErrorCode ATTENDANCE_SUMMARY_NOT_EXISTS = new ErrorCode(1_030_004_013, "鑰冨嫟姹囨�昏褰曚笉瀛樺湪");
-    ErrorCode ATTENDANCE_EXCEPTION_UPDATE_AUDIT_STATUS_FAIL = new ErrorCode(1_030_004_014, "鏇存柊鑰冨嫟寮傚父瀹℃壒鐘舵�佸け璐ワ紝鍘熷洜锛氫笉鏄鎵逛腑鐘舵��");
-    ErrorCode ATTENDANCE_EXCEPTION_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_004_015, "鑰冨嫟寮傚父瀹℃壒娴佺▼涓嶅瓨鍦�");
     ErrorCode ATTENDANCE_CLOCK_ALREADY_CLOCKED = new ErrorCode(1_030_004_016, "宸叉墦杩囧崱锛岃鍕块噸澶嶆墦鍗�");
+    ErrorCode ATTENDANCE_EXCEPTION_AUDIT_FAIL_NOT_PROCESS = new ErrorCode(1_030_004_019, "鍙湁瀹℃壒涓姸鎬佺殑鑰冨嫟寮傚父鐢宠鎵嶈兘瀹℃牳");
+    ErrorCode ATTENDANCE_EXCEPTION_AUDIT_REJECT_REASON_REQUIRED = new ErrorCode(1_030_004_020, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
 
     // ========== 缁╂晥鑰冩牳 1-030-008-000 ==========
     ErrorCode PERFORMANCE_APPRAISE_NOT_EXISTS = new ErrorCode(1_030_008_000, "缁╂晥鑰冩牳鏂规涓嶅瓨鍦�");
     ErrorCode PERFORMANCE_APPRAISE_ITEM_NOT_EXISTS = new ErrorCode(1_030_008_001, "鑰冩牳鎸囨爣涓嶅瓨鍦�");
     ErrorCode PERFORMANCE_APPRAISE_UPDATE_FAIL_NOT_DRAFT = new ErrorCode(1_030_008_002, "缁╂晥鑰冩牳鏂规鏇存柊澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
-    ErrorCode PERFORMANCE_APPRAISE_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_030_008_003, "缁╂晥鑰冩牳鏂规鎻愪氦澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
-    ErrorCode PERFORMANCE_APPRAISE_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_030_008_004, "鏇存柊缁╂晥鑰冩牳瀹℃壒鐘舵�佸け璐ワ紝鍘熷洜锛氫笉鏄鎵逛腑鐘舵��");
-    ErrorCode PERFORMANCE_APPRAISE_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_008_005, "缁╂晥鑰冩牳瀹℃壒娴佺▼涓嶅瓨鍦ㄦ垨鏈縺娲伙紝璇锋鏌� BPM 閰嶇疆");
+    ErrorCode PERFORMANCE_APPRAISE_SUBMIT_FAIL_NOT_EDITABLE = new ErrorCode(1_030_008_003, "鍙湁鑽夌鎴栧鏍镐笉閫氳繃鐘舵�佺殑缁╂晥鑰冩牳鏂规鎵嶈兘鎻愪氦瀹℃壒");
+    ErrorCode PERFORMANCE_APPRAISE_AUDIT_FAIL_NOT_PROCESS = new ErrorCode(1_030_008_004, "鍙湁瀹℃壒涓姸鎬佺殑缁╂晥鑰冩牳鏂规鎵嶈兘瀹℃牳");
+    ErrorCode PERFORMANCE_APPRAISE_AUDIT_REJECT_REASON_REQUIRED = new ErrorCode(1_030_008_005, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
     ErrorCode PERFORMANCE_APPRAISE_ITEM_EMPTY = new ErrorCode(1_030_008_006, "鑰冩牳鎸囨爣涓嶈兘涓虹┖");
     ErrorCode PERFORMANCE_APPRAISE_RESULT_NOT_EXISTS = new ErrorCode(1_030_008_007, "鑰冩牳缁撴灉涓嶅瓨鍦�");
     ErrorCode PERFORMANCE_APPRAISE_RESULT_ITEM_NOT_EXISTS = new ErrorCode(1_030_008_008, "鑰冩牳鎸囨爣璇勫垎涓嶅瓨鍦�");
@@ -127,11 +129,12 @@
     // ========== 杞鐢宠 1-030-006-000 ==========
     ErrorCode REGULARIZE_APPLICATION_NOT_EXISTS = new ErrorCode(1_030_006_000, "杞鐢宠涓嶅瓨鍦�");
     ErrorCode REGULARIZE_APPLICATION_UPDATE_FAIL_NOT_DRAFT = new ErrorCode(1_030_006_001, "杞鐢宠鏇存柊澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
-    ErrorCode REGULARIZE_APPLICATION_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_030_006_002, "杞鐢宠鎻愪氦澶辫触锛屽師鍥狅細涓嶆槸鑽夌鐘舵��");
+    ErrorCode REGULARIZE_APPLICATION_SUBMIT_FAIL_NOT_EDITABLE = new ErrorCode(1_030_006_002, "鍙湁鑽夌鎴栧鏍镐笉閫氳繃鐘舵�佺殑杞鐢宠鎵嶈兘鎻愪氦瀹℃壒");
     ErrorCode REGULARIZE_APPLICATION_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_030_006_003, "鏇存柊杞鐢宠瀹℃壒鐘舵�佸け璐ワ紝鍘熷洜锛氫笉鏄鎵逛腑鐘舵��");
     ErrorCode REGULARIZE_APPLICATION_NO_EXISTS = new ErrorCode(1_030_006_004, "鐢熸垚杞鐢宠鍗曞彿閲嶅锛岃閲嶈瘯");
     ErrorCode REGULARIZE_APPLICATION_EXISTS = new ErrorCode(1_030_006_005, "璇ュ憳宸ュ凡瀛樺湪杞鐢宠锛岃鍕块噸澶嶆彁浜�");
-    ErrorCode REGULARIZE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_006_006, "杞瀹℃壒娴佺▼涓嶅瓨鍦�");
+    ErrorCode REGULARIZE_APPLICATION_AUDIT_FAIL_NOT_PROCESS = new ErrorCode(1_030_006_006, "鍙湁瀹℃壒涓姸鎬佺殑杞鐢宠鎵嶈兘瀹℃牳");
+    ErrorCode REGULARIZE_APPLICATION_AUDIT_REJECT_REASON_REQUIRED = new ErrorCode(1_030_006_007, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
 
     // ========== 鍩硅绠$悊 1-030-009-000 ==========
     ErrorCode TRAINING_NOT_EXISTS = new ErrorCode(1_030_009_000, "鍩硅娲诲姩涓嶅瓨鍦�");
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmLeaveApplicationController.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmLeaveApplicationController.java
index 179547e..cd2eff1 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmLeaveApplicationController.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmLeaveApplicationController.java
@@ -5,7 +5,7 @@
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmLeaveApplicationAuditReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmLeaveApplicationPageReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmLeaveApplicationRespVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmLeaveApplicationSaveReqVO;
@@ -22,7 +22,7 @@
 
 import java.io.IOException;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -75,23 +75,28 @@
         return success(leaveApplicationService.getLeaveApplicationPage(pageReqVO));
     }
 
-    @PostMapping("/submit")
-    @Operation(summary = "鎻愪氦璇峰亣鐢宠瀹℃壒")
+    @PutMapping("/submit")
+    @Operation(summary = "鎻愪氦瀹℃壒锛堣崏绋�/瀹℃牳涓嶉�氳繃鈫掑鎵逛腑锛夛紝瀹℃壒浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
     @Parameter(name = "id", description = "鐢宠ID", required = true)
-    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟Key", required = true)
-    @PreAuthorize("@ss.hasPermission('hrm:leave:submit')")
-    public CommonResult<Boolean> submitLeaveApplication(@RequestParam("id") Long id,
-                                                         @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        Long userId = SecurityFrameworkUtils.getLoginUserId();
-        leaveApplicationService.submitLeaveApplication(id, processDefinitionKey, userId);
+    @PreAuthorize("@ss.hasPermission('hrm:leave:update')")
+    public CommonResult<Boolean> submitLeaveApplication(@RequestParam("id") Long id) {
+        leaveApplicationService.submitLeaveApplication(id);
         return success(true);
     }
 
-    @GetMapping("/approve-process-definition-list")
-    @Operation(summary = "鑾峰彇鍙敤鐨勫鎵规祦绋嬪畾涔夊垪琛�")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳锛堝鎵逛腑鈫掑鏍搁�氳繃/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('hrm:leave:audit')")
+    public CommonResult<Boolean> auditLeaveApplication(@Valid @RequestBody HrmLeaveApplicationAuditReqVO auditReqVO) {
+        leaveApplicationService.auditLeaveApplication(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱瀹℃壒浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
     @PreAuthorize("@ss.hasPermission('hrm:leave:query')")
-    public CommonResult<List<Map<String, Object>>> getApproveProcessDefinitionList() {
-        return success(leaveApplicationService.getApproveProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(leaveApplicationService.getLeaveApplicationApproverUserIds());
     }
 
     @GetMapping("/export-excel")
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmRegularizeApplicationController.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmRegularizeApplicationController.java
index ff7840e..09e732f 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmRegularizeApplicationController.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmRegularizeApplicationController.java
@@ -2,7 +2,7 @@
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationAuditReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationPageReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationRespVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationSaveReqVO;
@@ -16,8 +16,7 @@
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
@@ -69,23 +68,28 @@
         return success(regularizeApplicationService.getRegularizeApplicationPage(pageReqVO));
     }
 
-    @PostMapping("/submit")
-    @Operation(summary = "鎻愪氦杞鐢宠瀹℃壒")
+    @PutMapping("/submit")
+    @Operation(summary = "鎻愪氦瀹℃壒锛堣崏绋�/瀹℃牳涓嶉�氳繃鈫掑鎵逛腑锛夛紝瀹℃壒浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
     @Parameter(name = "id", description = "鐢宠ID", required = true)
-    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟Key", required = true)
-    @PreAuthorize("@ss.hasPermission('hrm:regularize:submit')")
-    public CommonResult<Boolean> submitRegularizeApplication(@RequestParam("id") Long id,
-                                                             @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        Long userId = SecurityFrameworkUtils.getLoginUserId();
-        regularizeApplicationService.submitRegularizeApplication(id, processDefinitionKey, userId);
+    @PreAuthorize("@ss.hasPermission('hrm:regularize:update')")
+    public CommonResult<Boolean> submitRegularizeApplication(@RequestParam("id") Long id) {
+        regularizeApplicationService.submitRegularizeApplication(id);
         return success(true);
     }
 
-    @GetMapping("/approve-process-definition-list")
-    @Operation(summary = "鑾峰彇鍙敤鐨勫鎵规祦绋嬪畾涔夊垪琛�")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳锛堝鎵逛腑鈫掑鏍搁�氳繃/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('hrm:regularize:audit')")
+    public CommonResult<Boolean> auditRegularizeApplication(@Valid @RequestBody HrmRegularizeApplicationAuditReqVO auditReqVO) {
+        regularizeApplicationService.auditRegularizeApplication(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱瀹℃壒浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
     @PreAuthorize("@ss.hasPermission('hrm:regularize:query')")
-    public CommonResult<List<Map<String, Object>>> getApproveProcessDefinitionList() {
-        return success(regularizeApplicationService.getApproveProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(regularizeApplicationService.getRegularizeApplicationApproverUserIds());
     }
 
 }
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmResignationApplicationController.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmResignationApplicationController.java
index 7bd6ef8..1a25d25 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmResignationApplicationController.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmResignationApplicationController.java
@@ -5,14 +5,12 @@
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationApplicationAuditReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationApplicationPageReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationApplicationRespVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationApplicationSaveReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationHandoverReqVO;
 import cn.iocoder.yudao.module.hrm.service.approval.HrmResignationApplicationService;
-import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
-import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -25,7 +23,7 @@
 
 import java.io.IOException;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -38,8 +36,6 @@
 
     @Resource
     private HrmResignationApplicationService resignationApplicationService;
-    @Resource
-    private AdminUserApi adminUserApi;
 
     @PostMapping("/create")
     @Operation(summary = "鍒涘缓绂昏亴鐢宠")
@@ -80,23 +76,28 @@
         return success(resignationApplicationService.getResignationApplicationPage(pageReqVO));
     }
 
-    @PostMapping("/submit")
-    @Operation(summary = "鎻愪氦绂昏亴鐢宠瀹℃壒")
+    @PutMapping("/submit")
+    @Operation(summary = "鎻愪氦瀹℃壒锛堣崏绋�/瀹℃牳涓嶉�氳繃鈫掑鎵逛腑锛夛紝瀹℃壒浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
     @Parameter(name = "id", description = "鐢宠ID", required = true)
-    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟Key", required = true)
-    @PreAuthorize("@ss.hasPermission('hrm:resignation:submit')")
-    public CommonResult<Boolean> submitResignationApplication(@RequestParam("id") Long id,
-                                                              @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        Long userId = SecurityFrameworkUtils.getLoginUserId();
-        resignationApplicationService.submitResignationApplication(id, processDefinitionKey, userId);
+    @PreAuthorize("@ss.hasPermission('hrm:resignation:update')")
+    public CommonResult<Boolean> submitResignationApplication(@RequestParam("id") Long id) {
+        resignationApplicationService.submitResignationApplication(id);
         return success(true);
     }
 
-    @GetMapping("/approve-process-definition-list")
-    @Operation(summary = "鑾峰彇鍙敤鐨勫鎵规祦绋嬪畾涔夊垪琛�")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳锛堝鎵逛腑鈫掑鏍搁�氳繃/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('hrm:resignation:audit')")
+    public CommonResult<Boolean> auditResignationApplication(@Valid @RequestBody HrmResignationApplicationAuditReqVO auditReqVO) {
+        resignationApplicationService.auditResignationApplication(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱瀹℃壒浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
     @PreAuthorize("@ss.hasPermission('hrm:resignation:query')")
-    public CommonResult<List<Map<String, Object>>> getApproveProcessDefinitionList() {
-        return success(resignationApplicationService.getApproveProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(resignationApplicationService.getResignationApplicationApproverUserIds());
     }
 
     @PutMapping("/handover")
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmTransferApplicationController.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmTransferApplicationController.java
index 83cd690..6a5013f 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmTransferApplicationController.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmTransferApplicationController.java
@@ -5,7 +5,7 @@
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationAuditReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationPageReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationRespVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationSaveReqVO;
@@ -24,7 +24,7 @@
 
 import java.io.IOException;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -79,23 +79,28 @@
         return success(transferApplicationService.getTransferApplicationPage(pageReqVO));
     }
 
-    @PostMapping("/submit")
-    @Operation(summary = "鎻愪氦璋冨矖鐢宠瀹℃壒")
+    @PutMapping("/submit")
+    @Operation(summary = "鎻愪氦瀹℃壒锛堣崏绋�/瀹℃牳涓嶉�氳繃鈫掑鎵逛腑锛夛紝瀹℃壒浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
     @Parameter(name = "id", description = "鐢宠ID", required = true)
-    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟Key", required = true)
-    @PreAuthorize("@ss.hasPermission('hrm:transfer:submit')")
-    public CommonResult<Boolean> submitTransferApplication(@RequestParam("id") Long id,
-                                                           @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        Long userId = SecurityFrameworkUtils.getLoginUserId();
-        transferApplicationService.submitTransferApplication(id, processDefinitionKey, userId);
+    @PreAuthorize("@ss.hasPermission('hrm:transfer:update')")
+    public CommonResult<Boolean> submitTransferApplication(@RequestParam("id") Long id) {
+        transferApplicationService.submitTransferApplication(id);
         return success(true);
     }
 
-    @GetMapping("/approve-process-definition-list")
-    @Operation(summary = "鑾峰彇鍙敤鐨勫鎵规祦绋嬪畾涔夊垪琛�")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳锛堝鎵逛腑鈫掑鏍搁�氳繃/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('hrm:transfer:audit')")
+    public CommonResult<Boolean> auditTransferApplication(@Valid @RequestBody HrmTransferApplicationAuditReqVO auditReqVO) {
+        transferApplicationService.auditTransferApplication(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱瀹℃壒浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
     @PreAuthorize("@ss.hasPermission('hrm:transfer:query')")
-    public CommonResult<List<Map<String, Object>>> getApproveProcessDefinitionList() {
-        return success(transferApplicationService.getApproveProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(transferApplicationService.getTransferApplicationApproverUserIds());
     }
 
     @GetMapping("/export-excel")
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmLeaveApplicationAuditReqVO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmLeaveApplicationAuditReqVO.java
new file mode 100644
index 0000000..b5cf4cb
--- /dev/null
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmLeaveApplicationAuditReqVO.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.hrm.controller.admin.approval.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 绠$悊鍚庡彴 - 璇峰亣鐢宠瀹℃牳 Request VO
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - 璇峰亣鐢宠瀹℃牳 Request VO")
+@Data
+public class HrmLeaveApplicationAuditReqVO {
+
+    @Schema(description = "鐢宠ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "鐢宠ID涓嶈兘涓虹┖")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堥�氳繃鏃堕�夊~ / 涓嶉�氳繃鏃跺繀濉級", example = "璇峰亣浜嬬敱闇�琛ュ厖璇存槑")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmLeaveApplicationRespVO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmLeaveApplicationRespVO.java
index 23fd6dc..ed7c3a7 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmLeaveApplicationRespVO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmLeaveApplicationRespVO.java
@@ -54,8 +54,17 @@
     @Schema(description = "瀹℃壒鐘舵�佸悕绉�", example = "鑽夌")
     private String statusName;
 
-    @Schema(description = "BPM 娴佺▼瀹炰緥ID", example = "xxx")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "1")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "寮犱笁")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿", example = "2024-01-01 10:00:00")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�", example = "鍚屾剰")
+    private String reviewRemark;
 
     @Schema(description = "瀹℃壒瀹屾垚鏃堕棿", example = "2024-01-01 10:00:00")
     private LocalDateTime approveTime;
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmRegularizeApplicationAuditReqVO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmRegularizeApplicationAuditReqVO.java
new file mode 100644
index 0000000..7234b74
--- /dev/null
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmRegularizeApplicationAuditReqVO.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.hrm.controller.admin.approval.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 绠$悊鍚庡彴 - 杞鐢宠瀹℃牳 Request VO
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - 杞鐢宠瀹℃牳 Request VO")
+@Data
+public class HrmRegularizeApplicationAuditReqVO {
+
+    @Schema(description = "鐢宠ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "鐢宠ID涓嶈兘涓虹┖")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堥�氳繃鏃堕�夊~ / 涓嶉�氳繃鏃跺繀濉級", example = "杞鑰冩牳闇�琛ュ厖鏉愭枡")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmRegularizeApplicationRespVO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmRegularizeApplicationRespVO.java
index 85ba6c9..65975bf 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmRegularizeApplicationRespVO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmRegularizeApplicationRespVO.java
@@ -52,8 +52,17 @@
     @Schema(description = "瀹℃壒鐘舵�佸悕绉�", example = "鑽夌")
     private String statusName;
 
-    @Schema(description = "BPM 娴佺▼瀹炰緥ID", example = "xxx")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "1")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "寮犱笁")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿", example = "2024-01-01 10:00:00")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�", example = "鍚屾剰")
+    private String reviewRemark;
 
     @Schema(description = "瀹℃壒瀹屾垚鏃堕棿", example = "2024-01-01 10:00:00")
     private LocalDateTime approveTime;
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmResignationApplicationAuditReqVO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmResignationApplicationAuditReqVO.java
new file mode 100644
index 0000000..4a89abc
--- /dev/null
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmResignationApplicationAuditReqVO.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.hrm.controller.admin.approval.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 绠$悊鍚庡彴 - 绂昏亴鐢宠瀹℃牳 Request VO
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - 绂昏亴鐢宠瀹℃牳 Request VO")
+@Data
+public class HrmResignationApplicationAuditReqVO {
+
+    @Schema(description = "鐢宠ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "鐢宠ID涓嶈兘涓虹┖")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堥�氳繃鏃堕�夊~ / 涓嶉�氳繃鏃跺繀濉級", example = "闇�鍏堝畬鎴愬伐浣滀氦鎺�")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmResignationApplicationRespVO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmResignationApplicationRespVO.java
index 3c7aaa6..27f5778 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmResignationApplicationRespVO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmResignationApplicationRespVO.java
@@ -66,8 +66,17 @@
     @Schema(description = "瀹℃壒鐘舵�佸悕绉�", example = "鑽夌")
     private String statusName;
 
-    @Schema(description = "BPM 娴佺▼瀹炰緥ID", example = "xxx")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "1")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "寮犱笁")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿", example = "2024-01-01 10:00:00")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�", example = "鍚屾剰")
+    private String reviewRemark;
 
     @Schema(description = "瀹℃壒瀹屾垚鏃堕棿", example = "2024-01-01 10:00:00")
     private LocalDateTime approveTime;
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmTransferApplicationAuditReqVO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmTransferApplicationAuditReqVO.java
new file mode 100644
index 0000000..ab8a4fc
--- /dev/null
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmTransferApplicationAuditReqVO.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.hrm.controller.admin.approval.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 绠$悊鍚庡彴 - 璋冨矖鐢宠瀹℃牳 Request VO
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - 璋冨矖鐢宠瀹℃牳 Request VO")
+@Data
+public class HrmTransferApplicationAuditReqVO {
+
+    @Schema(description = "鐢宠ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "鐢宠ID涓嶈兘涓虹┖")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堥�氳繃鏃堕�夊~ / 涓嶉�氳繃鏃跺繀濉級", example = "鐩爣宀椾綅闇�鍐嶆纭")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmTransferApplicationRespVO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmTransferApplicationRespVO.java
index bb3e292..beb66f5 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmTransferApplicationRespVO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/vo/HrmTransferApplicationRespVO.java
@@ -66,8 +66,17 @@
     @Schema(description = "瀹℃壒鐘舵�佸悕绉�", example = "鑽夌")
     private String statusName;
 
-    @Schema(description = "BPM 娴佺▼瀹炰緥ID", example = "xxx")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "1")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "鏉庡洓")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿", example = "2024-01-01 10:00:00")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�", example = "鍚屾剰璋冨矖")
+    private String reviewRemark;
 
     @Schema(description = "瀹℃壒瀹屾垚鏃堕棿", example = "2024-01-01 10:00:00")
     private LocalDateTime approveTime;
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceExceptionController.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceExceptionController.java
index 3ca789b..adb6bc7 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceExceptionController.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceExceptionController.java
@@ -4,6 +4,7 @@
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceExceptionAuditReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceExceptionPageReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceExceptionRespVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceExceptionSaveReqVO;
@@ -143,16 +144,28 @@
         }
     }
 
-    @PostMapping("/submit")
-    @Operation(summary = "鎻愪氦鑰冨嫟寮傚父鐢宠")
-    @PreAuthorize("@ss.hasPermission('hrm:attendance:submit')")
-    public CommonResult<Boolean> submitAttendanceException(
-            @RequestParam("id") Long id,
-            @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        // 鑾峰彇褰撳墠鐧诲綍鐢ㄦ埛ID
-        Long userId = cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId();
-        attendanceExceptionService.submitAttendanceException(id, processDefinitionKey, userId);
+    @PutMapping("/submit")
+    @Operation(summary = "鎻愪氦瀹℃壒锛堣崏绋�/瀹℃牳涓嶉�氳繃鈫掑鎵逛腑锛夛紝瀹℃壒浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
+    @Parameter(name = "id", description = "鐢宠ID", required = true)
+    @PreAuthorize("@ss.hasPermission('hrm:attendance-exception:submit')")
+    public CommonResult<Boolean> submitAttendanceException(@RequestParam("id") Long id) {
+        attendanceExceptionService.submitAttendanceException(id);
         return success(true);
     }
 
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳锛堝鎵逛腑鈫掑鏍搁�氳繃/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('hrm:attendance-exception:audit')")
+    public CommonResult<Boolean> auditAttendanceException(@Valid @RequestBody HrmAttendanceExceptionAuditReqVO auditReqVO) {
+        attendanceExceptionService.auditAttendanceException(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱瀹℃壒浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
+    @PreAuthorize("@ss.hasPermission('hrm:attendance:query')")
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(attendanceExceptionService.getAttendanceExceptionApproverUserIds());
+    }
+
 }
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/vo/HrmAttendanceExceptionAuditReqVO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/vo/HrmAttendanceExceptionAuditReqVO.java
new file mode 100644
index 0000000..c1b2031
--- /dev/null
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/vo/HrmAttendanceExceptionAuditReqVO.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 绠$悊鍚庡彴 - 鑰冨嫟寮傚父鐢宠瀹℃牳 Request VO
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - 鑰冨嫟寮傚父鐢宠瀹℃牳 Request VO")
+@Data
+public class HrmAttendanceExceptionAuditReqVO {
+
+    @Schema(description = "鐢宠ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "鐢宠ID涓嶈兘涓虹┖")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堥�氳繃鏃堕�夊~ / 涓嶉�氳繃鏃跺繀濉級", example = "琛ュ崱鏃堕棿闇�涓庨棬绂佽褰曚竴鑷�")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/vo/HrmAttendanceExceptionRespVO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/vo/HrmAttendanceExceptionRespVO.java
index 6d41a13..2de7760 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/vo/HrmAttendanceExceptionRespVO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/vo/HrmAttendanceExceptionRespVO.java
@@ -61,8 +61,17 @@
     @DictFormat("hrm_audit_status")
     private Integer status;
 
-    @Schema(description = "BPM娴佺▼瀹炰緥ID")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "1")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "鏉庡洓")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿", example = "2024-01-01 10:00:00")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�", example = "鍚屾剰琛ュ崱")
+    private String reviewRemark;
 
     @Schema(description = "瀹℃壒瀹屾垚鏃堕棿")
     @ExcelProperty("瀹℃壒瀹屾垚鏃堕棿")
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/HrmPerformanceAppraiseController.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/HrmPerformanceAppraiseController.java
index 31b1107..6357ac1 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/HrmPerformanceAppraiseController.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/HrmPerformanceAppraiseController.java
@@ -21,16 +21,13 @@
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 @Tag(name = "绠$悊鍚庡彴 - HRM 缁╂晥鑰冩牳鏂规")
 @RestController
@@ -112,30 +109,28 @@
 
     // ========== 瀹℃壒 ==========
 
-    @PostMapping("/submit")
-    @Operation(summary = "鎻愪氦缁╂晥鑰冩牳鏂规瀹℃壒")
+    @PutMapping("/submit")
+    @Operation(summary = "鎻愪氦瀹℃壒锛堣崏绋�/瀹℃牳涓嶉�氳繃鈫掑鎵逛腑锛夛紝瀹℃壒浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
     @Parameter(name = "id", description = "鏂规缂栧彿", required = true)
-    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟Key", required = true)
-    @PreAuthorize("@ss.hasPermission('hrm:performance-appraise:submit')")
-    public CommonResult<Boolean> submitAppraise(@RequestParam("id") Long id,
-                                                @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        appraiseService.submitAppraise(id, processDefinitionKey, getLoginUserId());
+    @PreAuthorize("@ss.hasPermission('hrm:performance-appraise:update')")
+    public CommonResult<Boolean> submitAppraise(@RequestParam("id") Long id) {
+        appraiseService.submitAppraise(id);
         return success(true);
     }
 
     @PutMapping("/audit")
-    @Operation(summary = "瀹℃壒缁╂晥鑰冩牳鏂规锛堥�氳繃/椹冲洖锛�")
+    @Operation(summary = "瀹℃牳锛堝鎵逛腑鈫掑鏍搁�氳繃/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
     @PreAuthorize("@ss.hasPermission('hrm:performance-appraise:audit')")
     public CommonResult<Boolean> auditAppraise(@Valid @RequestBody HrmPerformanceAppraiseAuditReqVO auditReqVO) {
-        appraiseService.auditAppraise(auditReqVO);
+        appraiseService.auditAppraise(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
         return success(true);
     }
 
-    @GetMapping("/approve-process-list")
-    @Operation(summary = "鑾峰緱缁╂晥鑰冩牳鏂规瀹℃壒娴佺▼瀹氫箟鍒楄〃")
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱瀹℃壒浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
     @PreAuthorize("@ss.hasPermission('hrm:performance-appraise:query')")
-    public CommonResult<List<Map<String, Object>>> getAppraiseApproveProcessDefinitionList() {
-        return success(appraiseService.getAppraiseApproveProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(appraiseService.getAppraiseApproverUserIds());
     }
 
     // ========== 璇勫垎/缁撴灉 ==========
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/vo/HrmPerformanceAppraiseAuditReqVO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/vo/HrmPerformanceAppraiseAuditReqVO.java
index 2828995..c7eb4b8 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/vo/HrmPerformanceAppraiseAuditReqVO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/vo/HrmPerformanceAppraiseAuditReqVO.java
@@ -5,9 +5,9 @@
 import lombok.Data;
 
 /**
- * HRM 缁╂晥鑰冩牳鏂规 瀹℃壒 Request VO
+ * HRM 缁╂晥鑰冩牳鏂规 瀹℃牳 Request VO
  */
-@Schema(description = "HRM 缁╂晥鑰冩牳鏂规 - 瀹℃壒 Request VO")
+@Schema(description = "HRM 缁╂晥鑰冩牳鏂规 - 瀹℃牳 Request VO")
 @Data
 public class HrmPerformanceAppraiseAuditReqVO {
 
@@ -15,11 +15,11 @@
     @NotNull(message = "鏂规缂栧彿涓嶈兘涓虹┖")
     private Long id;
 
-    @Schema(description = "瀹℃壒缁撴灉锛�20 閫氳繃 / 30 椹冲洖锛�", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
-    @NotNull(message = "瀹℃壒缁撴灉涓嶈兘涓虹┖")
-    private Integer auditStatus;
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
 
-    @Schema(description = "瀹℃壒澶囨敞", example = "鍚屾剰鍙戝竷")
-    private String remark;
+    @Schema(description = "瀹℃牳鎰忚锛堥�氳繃鏃堕�夊~ / 涓嶉�氳繃鏃跺繀濉級", example = "鑰冩牳鎸囨爣闇�琛ュ厖璇存槑")
+    private String reviewRemark;
 
 }
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/vo/HrmPerformanceAppraiseRespVO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/vo/HrmPerformanceAppraiseRespVO.java
index 2e73509..1c2c452 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/vo/HrmPerformanceAppraiseRespVO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/performanceappraise/vo/HrmPerformanceAppraiseRespVO.java
@@ -55,17 +55,17 @@
     @Schema(description = "瀹℃壒鐘舵�佸悕绉�", example = "鑽夌")
     private String auditStatusName;
 
-    @Schema(description = "瀹℃壒娴佺▼瀹炰緥缂栧彿")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "1")
+    private Long reviewerId;
 
-    @Schema(description = "瀹℃牳浜�", example = "1")
-    private Long auditUserId;
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "鏉庡洓")
+    private String reviewerName;
 
     @Schema(description = "瀹℃牳鏃堕棿")
-    private LocalDateTime auditTime;
+    private LocalDateTime reviewTime;
 
-    @Schema(description = "瀹℃牳澶囨敞")
-    private String auditRemark;
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�")
+    private String reviewRemark;
 
     @Schema(description = "澶囨敞")
     @ExcelProperty("澶囨敞")
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmLeaveApplicationDO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmLeaveApplicationDO.java
index c7d6ef9..6844589 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmLeaveApplicationDO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmLeaveApplicationDO.java
@@ -85,9 +85,27 @@
     private Integer status;
 
     /**
-     * BPM 娴佺▼瀹炰緥ID
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� hrm_leave_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
      */
-    private String processInstanceId;
+    private Long reviewerId;
+
+    /**
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
+     */
+    private String reviewerName;
+
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private LocalDateTime reviewTime;
+
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
 
     /**
      * 瀹℃壒瀹屾垚鏃堕棿
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmRegularizeApplicationDO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmRegularizeApplicationDO.java
index 1739e06..f6b9544 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmRegularizeApplicationDO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmRegularizeApplicationDO.java
@@ -80,9 +80,27 @@
     private Integer status;
 
     /**
-     * BPM 娴佺▼瀹炰緥ID
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� hrm_regularize_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
      */
-    private String processInstanceId;
+    private Long reviewerId;
+
+    /**
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
+     */
+    private String reviewerName;
+
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private java.time.LocalDateTime reviewTime;
+
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
 
     /**
      * 瀹℃壒瀹屾垚鏃堕棿
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmResignationApplicationDO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmResignationApplicationDO.java
index e2bc15f..31ae086 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmResignationApplicationDO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmResignationApplicationDO.java
@@ -98,9 +98,27 @@
     private Integer status;
 
     /**
-     * BPM 娴佺▼瀹炰緥ID
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� hrm_resignation_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
      */
-    private String processInstanceId;
+    private Long reviewerId;
+
+    /**
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
+     */
+    private String reviewerName;
+
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private java.time.LocalDateTime reviewTime;
+
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
 
     /**
      * 瀹℃壒瀹屾垚鏃堕棿
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmTransferApplicationDO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmTransferApplicationDO.java
index 0f5b1c4..0db7dec 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmTransferApplicationDO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/approval/HrmTransferApplicationDO.java
@@ -95,9 +95,27 @@
     private Integer status;
 
     /**
-     * BPM 娴佺▼瀹炰緥ID
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� hrm_transfer_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
      */
-    private String processInstanceId;
+    private Long reviewerId;
+
+    /**
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
+     */
+    private String reviewerName;
+
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private java.time.LocalDateTime reviewTime;
+
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
 
     /**
      * 瀹℃壒瀹屾垚鏃堕棿
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/attendance/HrmAttendanceExceptionDO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/attendance/HrmAttendanceExceptionDO.java
index bb9ae48..d3798c5 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/attendance/HrmAttendanceExceptionDO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/attendance/HrmAttendanceExceptionDO.java
@@ -73,9 +73,27 @@
     private Integer status;
 
     /**
-     * BPM娴佺▼瀹炰緥ID
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� hrm_attendance_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
      */
-    private String processInstanceId;
+    private Long reviewerId;
+
+    /**
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
+     */
+    private String reviewerName;
+
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private LocalDateTime reviewTime;
+
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
 
     /**
      * 瀹℃壒瀹屾垚鏃堕棿
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/performanceappraise/HrmPerformanceAppraiseDO.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/performanceappraise/HrmPerformanceAppraiseDO.java
index 63d6d87..546c82c 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/performanceappraise/HrmPerformanceAppraiseDO.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/dataobject/performanceappraise/HrmPerformanceAppraiseDO.java
@@ -68,24 +68,27 @@
     private Integer auditStatus;
 
     /**
-     * 瀹℃壒娴佺▼瀹炰緥缂栧彿
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� performance_appraise_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
      */
-    private String processInstanceId;
+    private Long reviewerId;
 
     /**
-     * 瀹℃牳浜�
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
      */
-    private Long auditUserId;
+    private String reviewerName;
 
     /**
      * 瀹℃牳鏃堕棿
      */
-    private LocalDateTime auditTime;
+    private LocalDateTime reviewTime;
 
     /**
-     * 瀹℃牳澶囨敞
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
      */
-    private String auditRemark;
+    private String reviewRemark;
 
     /**
      * 澶囨敞
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmLeaveApplicationMapper.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmLeaveApplicationMapper.java
index 6d98f1a..63520f4 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmLeaveApplicationMapper.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmLeaveApplicationMapper.java
@@ -3,6 +3,7 @@
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmLeaveApplicationPageReqVO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmLeaveApplicationDO;
 import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
@@ -34,8 +35,47 @@
         return selectOne(HrmLeaveApplicationDO::getNo, no);
     }
 
-    default HrmLeaveApplicationDO selectByProcessInstanceId(String processInstanceId) {
-        return selectOne(HrmLeaveApplicationDO::getProcessInstanceId, processInstanceId);
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� LambdaUpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜�/瀹℃牳鏃堕棿/瀹℃牳鎰忚娓呯┖銆�
+     *
+     * @param id     鐢宠ID
+     * @param status 鐩爣鐘舵��
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<HrmLeaveApplicationDO>()
+                .eq(HrmLeaveApplicationDO::getId, id)
+                .set(HrmLeaveApplicationDO::getStatus, status)
+                .set(HrmLeaveApplicationDO::getReviewerId, null)
+                .set(HrmLeaveApplicationDO::getReviewerName, null)
+                .set(HrmLeaveApplicationDO::getReviewTime, null)
+                .set(HrmLeaveApplicationDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * reviewRemark 鍏佽涓� null锛堝鏍搁�氳繃鏃舵剰瑙佸彲閫夛級锛屾晠鍚屾牱浣跨敤 UpdateWrapper 鐩村啓銆�
+     *
+     * @param id           鐢宠ID
+     * @param status       鐩爣鐘舵�侊紙瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditLeaveApplication(Long id, Integer status, Long reviewerId,
+                                      String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<HrmLeaveApplicationDO>()
+                .eq(HrmLeaveApplicationDO::getId, id)
+                .set(HrmLeaveApplicationDO::getStatus, status)
+                .set(HrmLeaveApplicationDO::getReviewerId, reviewerId)
+                .set(HrmLeaveApplicationDO::getReviewerName, reviewerName)
+                .set(HrmLeaveApplicationDO::getReviewTime, LocalDateTime.now())
+                .set(HrmLeaveApplicationDO::getReviewRemark, reviewRemark));
     }
 
     /**
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmRegularizeApplicationMapper.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmRegularizeApplicationMapper.java
index cfd79d4..08f6f4c 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmRegularizeApplicationMapper.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmRegularizeApplicationMapper.java
@@ -5,7 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationPageReqVO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmRegularizeApplicationDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
+
+import java.time.LocalDateTime;
 
 /**
  * 杞鐢宠 Mapper
@@ -30,8 +33,47 @@
         return selectOne(HrmRegularizeApplicationDO::getNo, no);
     }
 
-    default HrmRegularizeApplicationDO selectByProcessInstanceId(String processInstanceId) {
-        return selectOne(HrmRegularizeApplicationDO::getProcessInstanceId, processInstanceId);
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� LambdaUpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜�/瀹℃牳鏃堕棿/瀹℃牳鎰忚娓呯┖銆�
+     *
+     * @param id     鐢宠ID
+     * @param status 鐩爣鐘舵��
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<HrmRegularizeApplicationDO>()
+                .eq(HrmRegularizeApplicationDO::getId, id)
+                .set(HrmRegularizeApplicationDO::getStatus, status)
+                .set(HrmRegularizeApplicationDO::getReviewerId, null)
+                .set(HrmRegularizeApplicationDO::getReviewerName, null)
+                .set(HrmRegularizeApplicationDO::getReviewTime, null)
+                .set(HrmRegularizeApplicationDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * reviewRemark 鍏佽涓� null锛堝鏍搁�氳繃鏃舵剰瑙佸彲閫夛級锛屾晠鍚屾牱浣跨敤 UpdateWrapper 鐩村啓銆�
+     *
+     * @param id           鐢宠ID
+     * @param status       鐩爣鐘舵�侊紙瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditRegularizeApplication(Long id, Integer status, Long reviewerId,
+                                           String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<HrmRegularizeApplicationDO>()
+                .eq(HrmRegularizeApplicationDO::getId, id)
+                .set(HrmRegularizeApplicationDO::getStatus, status)
+                .set(HrmRegularizeApplicationDO::getReviewerId, reviewerId)
+                .set(HrmRegularizeApplicationDO::getReviewerName, reviewerName)
+                .set(HrmRegularizeApplicationDO::getReviewTime, LocalDateTime.now())
+                .set(HrmRegularizeApplicationDO::getReviewRemark, reviewRemark));
     }
 
     default HrmRegularizeApplicationDO selectByUserIdAndStatusNot(Long userId, Integer status) {
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmResignationApplicationMapper.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmResignationApplicationMapper.java
index 10032dc..80a6ce0 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmResignationApplicationMapper.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmResignationApplicationMapper.java
@@ -5,7 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationApplicationPageReqVO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmResignationApplicationDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
+
+import java.time.LocalDateTime;
 
 /**
  * 绂昏亴鐢宠 Mapper
@@ -30,8 +33,47 @@
         return selectOne(HrmResignationApplicationDO::getNo, no);
     }
 
-    default HrmResignationApplicationDO selectByProcessInstanceId(String processInstanceId) {
-        return selectOne(HrmResignationApplicationDO::getProcessInstanceId, processInstanceId);
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� LambdaUpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜�/瀹℃牳鏃堕棿/瀹℃牳鎰忚娓呯┖銆�
+     *
+     * @param id     鐢宠ID
+     * @param status 鐩爣鐘舵��
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<HrmResignationApplicationDO>()
+                .eq(HrmResignationApplicationDO::getId, id)
+                .set(HrmResignationApplicationDO::getStatus, status)
+                .set(HrmResignationApplicationDO::getReviewerId, null)
+                .set(HrmResignationApplicationDO::getReviewerName, null)
+                .set(HrmResignationApplicationDO::getReviewTime, null)
+                .set(HrmResignationApplicationDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * reviewRemark 鍏佽涓� null锛堝鏍搁�氳繃鏃舵剰瑙佸彲閫夛級锛屾晠鍚屾牱浣跨敤 UpdateWrapper 鐩村啓銆�
+     *
+     * @param id           鐢宠ID
+     * @param status       鐩爣鐘舵�侊紙瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditResignationApplication(Long id, Integer status, Long reviewerId,
+                                            String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<HrmResignationApplicationDO>()
+                .eq(HrmResignationApplicationDO::getId, id)
+                .set(HrmResignationApplicationDO::getStatus, status)
+                .set(HrmResignationApplicationDO::getReviewerId, reviewerId)
+                .set(HrmResignationApplicationDO::getReviewerName, reviewerName)
+                .set(HrmResignationApplicationDO::getReviewTime, LocalDateTime.now())
+                .set(HrmResignationApplicationDO::getReviewRemark, reviewRemark));
     }
 
     default HrmResignationApplicationDO selectByUserIdAndStatusNot(Long userId, Integer status) {
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmTransferApplicationMapper.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmTransferApplicationMapper.java
index b698cfd..97c1a20 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmTransferApplicationMapper.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/approval/HrmTransferApplicationMapper.java
@@ -5,7 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationPageReqVO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmTransferApplicationDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
+
+import java.time.LocalDateTime;
 
 /**
  * 璋冨矖鐢宠 Mapper
@@ -31,8 +34,48 @@
         return selectOne(HrmTransferApplicationDO::getNo, no);
     }
 
-    default HrmTransferApplicationDO selectByProcessInstanceId(String processInstanceId) {
-        return selectOne(HrmTransferApplicationDO::getProcessInstanceId, processInstanceId);
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� LambdaUpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜�/瀹℃牳鏃堕棿/瀹℃牳鎰忚娓呯┖銆�
+     *
+     * @param id     鐢宠ID
+     * @param status 鐩爣鐘舵��
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<HrmTransferApplicationDO>()
+                .eq(HrmTransferApplicationDO::getId, id)
+                .set(HrmTransferApplicationDO::getStatus, status)
+                .set(HrmTransferApplicationDO::getReviewerId, null)
+                .set(HrmTransferApplicationDO::getReviewerName, null)
+                .set(HrmTransferApplicationDO::getReviewTime, null)
+                .set(HrmTransferApplicationDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * reviewRemark 鍏佽涓� null锛堝鏍搁�氳繃鏃舵剰瑙佸彲閫夛級锛屾晠鍚屾牱浣跨敤 UpdateWrapper 鐩村啓銆�
+     *
+     * @param id           鐢宠ID
+     * @param status       鐩爣鐘舵�侊紙瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditTransferApplication(Long id, Integer status, Long reviewerId,
+                                         String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<HrmTransferApplicationDO>()
+                .eq(HrmTransferApplicationDO::getId, id)
+                .set(HrmTransferApplicationDO::getStatus, status)
+                .set(HrmTransferApplicationDO::getReviewerId, reviewerId)
+                .set(HrmTransferApplicationDO::getReviewerName, reviewerName)
+                .set(HrmTransferApplicationDO::getReviewTime, LocalDateTime.now())
+                .set(HrmTransferApplicationDO::getReviewRemark, reviewRemark)
+                .set(HrmTransferApplicationDO::getApproveTime, LocalDateTime.now()));
     }
 
 }
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/attendance/HrmAttendanceExceptionMapper.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/attendance/HrmAttendanceExceptionMapper.java
index 7cc071c..fc1afba 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/attendance/HrmAttendanceExceptionMapper.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/attendance/HrmAttendanceExceptionMapper.java
@@ -5,7 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceExceptionPageReqVO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceExceptionDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
+
+import java.time.LocalDateTime;
 
 /**
  * 鑰冨嫟寮傚父鐢宠 Mapper
@@ -29,8 +32,48 @@
         return selectOne(HrmAttendanceExceptionDO::getNo, no);
     }
 
-    default HrmAttendanceExceptionDO selectByProcessInstanceId(String processInstanceId) {
-        return selectOne(HrmAttendanceExceptionDO::getProcessInstanceId, processInstanceId);
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� LambdaUpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜�/瀹℃牳鏃堕棿/瀹℃牳鎰忚娓呯┖銆�
+     *
+     * @param id     鐢宠ID
+     * @param status 鐩爣鐘舵��
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<HrmAttendanceExceptionDO>()
+                .eq(HrmAttendanceExceptionDO::getId, id)
+                .set(HrmAttendanceExceptionDO::getStatus, status)
+                .set(HrmAttendanceExceptionDO::getReviewerId, null)
+                .set(HrmAttendanceExceptionDO::getReviewerName, null)
+                .set(HrmAttendanceExceptionDO::getReviewTime, null)
+                .set(HrmAttendanceExceptionDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * reviewRemark 鍏佽涓� null锛堝鏍搁�氳繃鏃舵剰瑙佸彲閫夛級锛屾晠鍚屾牱浣跨敤 UpdateWrapper 鐩村啓銆�
+     *
+     * @param id           鐢宠ID
+     * @param status       鐩爣鐘舵�侊紙瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditAttendanceException(Long id, Integer status, Long reviewerId,
+                                         String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<HrmAttendanceExceptionDO>()
+                .eq(HrmAttendanceExceptionDO::getId, id)
+                .set(HrmAttendanceExceptionDO::getStatus, status)
+                .set(HrmAttendanceExceptionDO::getReviewerId, reviewerId)
+                .set(HrmAttendanceExceptionDO::getReviewerName, reviewerName)
+                .set(HrmAttendanceExceptionDO::getReviewTime, LocalDateTime.now())
+                .set(HrmAttendanceExceptionDO::getReviewRemark, reviewRemark)
+                .set(HrmAttendanceExceptionDO::getApproveTime, LocalDateTime.now()));
     }
 
 }
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/performanceappraise/HrmPerformanceAppraiseMapper.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/performanceappraise/HrmPerformanceAppraiseMapper.java
index 8662626..cbb287c 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/performanceappraise/HrmPerformanceAppraiseMapper.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/performanceappraise/HrmPerformanceAppraiseMapper.java
@@ -5,7 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.hrm.controller.admin.performanceappraise.vo.HrmPerformanceAppraisePageReqVO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.performanceappraise.HrmPerformanceAppraiseDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
+
+import java.time.LocalDateTime;
 
 /**
  * HRM 缁╂晥鑰冩牳鏂规 Mapper
@@ -21,6 +24,51 @@
                 .orderByDesc(HrmPerformanceAppraiseDO::getId));
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� LambdaUpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜�/瀹℃牳鏃堕棿/瀹℃牳鎰忚娓呯┖銆�
+     *
+     * @param id          鏂规缂栧彿
+     * @param auditStatus 鐩爣瀹℃壒鐘舵��
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer auditStatus) {
+        return update(null, new LambdaUpdateWrapper<HrmPerformanceAppraiseDO>()
+                .eq(HrmPerformanceAppraiseDO::getId, id)
+                .set(HrmPerformanceAppraiseDO::getAuditStatus, auditStatus)
+                .set(HrmPerformanceAppraiseDO::getReviewerId, null)
+                .set(HrmPerformanceAppraiseDO::getReviewerName, null)
+                .set(HrmPerformanceAppraiseDO::getReviewTime, null)
+                .set(HrmPerformanceAppraiseDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * reviewRemark 鍏佽涓� null锛堝鏍搁�氳繃鏃舵剰瑙佸彲閫夛級锛屾晠鍚屾牱浣跨敤 UpdateWrapper 鐩村啓銆�
+     *
+     * @param id           鏂规缂栧彿
+     * @param auditStatus  鐩爣瀹℃壒鐘舵�侊紙瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     * @param status       鏂规鐘舵�侊紙瀹℃牳閫氳繃鏃剁疆涓哄凡鍙戝竷锛屽惁鍒欎繚鎸佷笉鍙橈級
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditAppraise(Long id, Integer auditStatus, Integer status, Long reviewerId,
+                              String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<HrmPerformanceAppraiseDO>()
+                .eq(HrmPerformanceAppraiseDO::getId, id)
+                .set(HrmPerformanceAppraiseDO::getAuditStatus, auditStatus)
+                .set(HrmPerformanceAppraiseDO::getStatus, status)
+                .set(HrmPerformanceAppraiseDO::getReviewerId, reviewerId)
+                .set(HrmPerformanceAppraiseDO::getReviewerName, reviewerName)
+                .set(HrmPerformanceAppraiseDO::getReviewTime, LocalDateTime.now())
+                .set(HrmPerformanceAppraiseDO::getReviewRemark, reviewRemark));
+    }
+
     default HrmPerformanceAppraiseDO selectMonthlyCompletedByPeriod(String period) {
         return selectOne(new LambdaQueryWrapperX<HrmPerformanceAppraiseDO>()
                 .eq(HrmPerformanceAppraiseDO::getPeriodType, 1)
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmLeaveApplicationService.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmLeaveApplicationService.java
index 39f5047..b24f67c 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmLeaveApplicationService.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmLeaveApplicationService.java
@@ -7,8 +7,7 @@
 import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmLeaveApplicationDO;
 import jakarta.validation.Valid;
 
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 /**
  * 璇峰亣鐢宠 Service 鎺ュ彛
@@ -16,16 +15,6 @@
  * @author 瓒呯骇绠$悊鍛�
  */
 public interface HrmLeaveApplicationService {
-
-    /**
-     * BPM 璇峰亣瀹℃壒娴佺▼鏍囪瘑
-     */
-    String BPM_PROCESS_DEFINITION_KEY = "hrm_leave";
-
-    /**
-     * BPM 璇峰亣瀹℃壒鍒嗙被缂栫爜
-     */
-    String APPROVE_CATEGORY_CODE = "hrm_leave_approve";
 
     /**
      * 鍒涘缓璇峰亣鐢宠
@@ -74,35 +63,28 @@
     PageResult<HrmLeaveApplicationRespVO> getLeaveApplicationPage(HrmLeaveApplicationPageReqVO pageReqVO);
 
     /**
-     * 鎻愪氦璇峰亣鐢宠瀹℃壒
+     * 鎻愪氦璇峰亣鐢宠瀹℃壒锛堣崏绋� / 瀹℃牳涓嶉�氳繃 鈫� 瀹℃壒涓級
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴鎸囧畾锛屾彁浜ゆ椂鏃犻渶閫夋嫨銆�
      *
      * @param id 鐢宠ID
-     * @param processDefinitionKey 娴佺▼瀹氫箟Key
-     * @param userId 鎻愪氦浜篒D
      */
-    void submitLeaveApplication(Long id, String processDefinitionKey, Long userId);
+    void submitLeaveApplication(Long id);
 
     /**
-     * 鑾峰彇鍙敤鐨勫鎵规祦绋嬪畾涔夊垪琛�
+     * 鑾峰緱璇峰亣鐢宠鐨勫鎵逛汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳
      *
-     * @return 娴佺▼瀹氫箟鍒楄〃
+     * @return 瀹℃壒浜虹敤鎴风紪鍙烽泦鍚�
      */
-    List<Map<String, Object>> getApproveProcessDefinitionList();
+    Set<Long> getLeaveApplicationApproverUserIds();
 
     /**
-     * 鏇存柊璇峰亣鐢宠瀹℃壒鐘舵�侊紙BPM 鍥炶皟锛�
+     * 瀹℃牳璇峰亣鐢宠锛堝鎵逛腑 鈫� 瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
      *
-     * @param id 鐢宠ID
-     * @param status 瀹℃壒鐘舵��
+     * @param id           鐢宠ID
+     * @param pass         鏄惁閫氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛堜笉閫氳繃鏃跺繀濉級
      */
-    void updateLeaveApplicationAuditStatus(Long id, Integer status);
-
-    /**
-     * 鏍规嵁娴佺▼瀹炰緥ID鑾峰彇璇峰亣鐢宠
-     *
-     * @param processInstanceId 娴佺▼瀹炰緥ID
-     * @return 璇峰亣鐢宠
-     */
-    HrmLeaveApplicationDO getLeaveApplicationByProcessInstanceId(String processInstanceId);
+    void auditLeaveApplication(Long id, Boolean pass, String reviewRemark);
 
 }
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmLeaveApplicationServiceImpl.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmLeaveApplicationServiceImpl.java
index 0ee5726..47ffce1 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmLeaveApplicationServiceImpl.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmLeaveApplicationServiceImpl.java
@@ -1,15 +1,9 @@
 package cn.iocoder.yudao.module.hrm.service.approval;
 
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmLeaveApplicationPageReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmLeaveApplicationRespVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmLeaveApplicationSaveReqVO;
@@ -18,6 +12,7 @@
 import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO;
 import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
 import cn.iocoder.yudao.module.hrm.enums.HrmLeaveTypeEnum;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
 import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
@@ -25,14 +20,11 @@
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -40,7 +32,7 @@
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*;
 
 /**
@@ -53,6 +45,13 @@
 @Slf4j
 public class HrmLeaveApplicationServiceImpl implements HrmLeaveApplicationService {
 
+    /**
+     * 璇峰亣鐢宠瀹℃壒鐨勪笟鍔$被鍨嬬紪鐮�
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鎵逛汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
+     */
+    private static final String LEAVE_APPROVE_BIZ_TYPE = "hrm_leave_approve";
+
     @Resource
     private HrmLeaveApplicationMapper leaveApplicationMapper;
     @Resource
@@ -62,13 +61,9 @@
     @Resource
     private AdminUserApi adminUserApi;
     @Resource
-    private BpmProcessInstanceApi bpmProcessInstanceApi;
-    @Resource
-    private BpmCategoryService bpmCategoryService;
-    @Resource
     private StorageAttachmentApi storageAttachmentApi;
     @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private ApprovalConfigApi approvalConfigApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -215,121 +210,64 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitLeaveApplication(Long id, String processDefinitionKey, Long userId) {
-        // 1. 鏍¢獙璇峰亣鐢宠鏄惁瀛樺湪
+    public void submitLeaveApplication(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鍙彁浜ょ姸鎬侊紙鑽夌 / 瀹℃牳涓嶉�氳繃锛�
         HrmLeaveApplicationDO application = validateLeaveApplicationExists(id);
-        if (ObjUtil.notEqual(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())) {
-            throw exception(LEAVE_APPLICATION_SUBMIT_FAIL_NOT_DRAFT);
+        if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())
+                && !Objects.equals(application.getStatus(), HrmAuditStatusEnum.REJECT.getStatus())) {
+            throw exception(LEAVE_APPLICATION_SUBMIT_FAIL_NOT_EDITABLE);
         }
 
-        // 2. 鏍¢獙鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-        validateApproveCategoryAndProcessDefinition();
+        // 2. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鎵逛汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(LEAVE_APPROVE_BIZ_TYPE);
 
-        // 3. 鏍¢獙浼犲叆鐨勬祦绋嬪畾涔� Key 鏄惁灞炰簬璇ュ垎绫讳笖澶勪簬婵�娲荤姸鎬�
-        ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey);
-        if (processDefinition == null) {
-            throw exception(LEAVE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
+        // 3. 鐘舵�佺疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋滐紝閬垮厤娈嬬暀銆屽鏍镐笉閫氳繃銆嶇殑鍘熷洜
+        leaveApplicationMapper.submitAndResetAuditInfo(id, HrmAuditStatusEnum.PROCESS.getStatus());
+    }
+
+    @Override
+    public Set<Long> getLeaveApplicationApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(LEAVE_APPROVE_BIZ_TYPE);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void auditLeaveApplication(Long id, Boolean pass, String reviewRemark) {
+        // 1. 鏍¢獙瀛樺湪
+        HrmLeaveApplicationDO application = validateLeaveApplicationExists(id);
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
+        if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.PROCESS.getStatus())) {
+            throw exception(LEAVE_APPLICATION_AUDIT_FAIL_NOT_PROCESS);
         }
-
-        // 4. 鍒涘缓瀹℃壒娴佺▼瀹炰緥
-        String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
-                .setProcessDefinitionKey(processDefinitionKey).setBusinessKey(String.valueOf(id)));
-
-        // 5. 鏇存柊璇峰亣鐢宠宸ヤ綔娴佺紪鍙�
-        leaveApplicationMapper.updateById(HrmLeaveApplicationDO.builder()
-                .id(id)
-                .processInstanceId(processInstanceId)
-                .status(HrmAuditStatusEnum.PROCESS.getStatus())
-                .build());
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鎵逛汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(LEAVE_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝鐘舵�佺疆涓哄鏍镐笉閫氳繃锛岄��鍥炴彁浜や汉淇敼鍚庡彲閲嶆柊鎻愪氦
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(LEAVE_APPLICATION_AUDIT_REJECT_REASON_REQUIRED);
+            }
+            leaveApplicationMapper.auditLeaveApplication(id, HrmAuditStatusEnum.REJECT.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
+            return;
+        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄鏍搁�氳繃
+        leaveApplicationMapper.auditLeaveApplication(id, HrmAuditStatusEnum.APPROVE.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
     }
 
     /**
-     * 鏍¢獙 BPM 璇峰亣瀹℃壒鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
      */
-    private void validateApproveCategoryAndProcessDefinition() {
-        // 1. 鏍¢獙鍒嗙被鏄惁瀛樺湪
-        List<String> codes = Collections.singletonList(APPROVE_CATEGORY_CODE);
-        Map<String, ?> categoryMap = bpmCategoryService.getCategoryMap(codes);
-        if (!categoryMap.containsKey(APPROVE_CATEGORY_CODE)) {
-            throw exception(LEAVE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
         }
-
-        // 2. 鏍¢獙鍒嗙被涓嬫槸鍚︽湁鍙敤鐨勬祦绋嬪畾涔�
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            throw exception(LEAVE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-
-        // 3. 鏍¢獙鏄惁鏈夋縺娲荤姸鎬佺殑娴佺▼瀹氫箟
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-        boolean hasActiveDefinition = processDefinitions.stream()
-                .anyMatch(pd -> !pd.isSuspended());
-        if (!hasActiveDefinition) {
-            throw exception(LEAVE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-    }
-
-    @Override
-    public List<Map<String, Object>> getApproveProcessDefinitionList() {
-        // 1. 鏍¢獙鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-        validateApproveCategoryAndProcessDefinition();
-
-        // 2. 鑾峰彇鍒嗙被涓嬬殑娴佺▼瀹氫箟淇℃伅
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE);
-
-        // 3. 鑾峰彇娴佺▼瀹氫箟璇︽儏
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-
-        // 4. 杩囨护锛氬彧淇濈暀婵�娲荤姸鎬侊紝涓旂浉鍚� key 鍙繚鐣欐渶鏂扮増鏈�
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (ProcessDefinition pd : processDefinitions) {
-            if (pd.isSuspended()) {
-                continue;
-            }
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-
-        // 5. 杩斿洖娴佺▼瀹氫箟鍒楄〃
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            item.put("version", pd.getVersion());
-            result.add(item);
-        }
-        return result;
-    }
-
-    @Override
-    public void updateLeaveApplicationAuditStatus(Long id, Integer status) {
-        // 鏍¢獙瀛樺湪
-        HrmLeaveApplicationDO application = validateLeaveApplicationExists(id);
-        // 鏍¢獙鐘舵�佷负瀹℃壒涓�
-        if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.PROCESS.getStatus())) {
-            log.error("[updateLeaveApplicationAuditStatus][application({}) 涓嶅浜庡鎵逛腑锛屾棤娉曟洿鏂板鎵圭粨鏋�({})]",
-                    id, status);
-            throw exception(LEAVE_APPLICATION_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS);
-        }
-        // 鏇存柊鐘舵��
-        leaveApplicationMapper.updateById(HrmLeaveApplicationDO.builder()
-                .id(id)
-                .status(status)
-                .approveTime(java.time.LocalDateTime.now())
-                .build());
-    }
-
-    @Override
-    public HrmLeaveApplicationDO getLeaveApplicationByProcessInstanceId(String processInstanceId) {
-        return leaveApplicationMapper.selectByProcessInstanceId(processInstanceId);
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
 }
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmRegularizeApplicationService.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmRegularizeApplicationService.java
index 5106664..7a43961 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmRegularizeApplicationService.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmRegularizeApplicationService.java
@@ -6,8 +6,7 @@
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationSaveReqVO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmRegularizeApplicationDO;
 
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 /**
  * 杞鐢宠 Service 鎺ュ彛
@@ -15,11 +14,6 @@
  * @author 瓒呯骇绠$悊鍛�
  */
 public interface HrmRegularizeApplicationService {
-
-    /**
-     * 瀹℃壒鍒嗙被缂栫爜锛氳浆姝e鎵�
-     */
-    String APPROVE_CATEGORY_CODE = "hrm_regularize_approve";
 
     /**
      * 鍒涘缓杞鐢宠
@@ -68,35 +62,30 @@
     PageResult<HrmRegularizeApplicationRespVO> getRegularizeApplicationPage(HrmRegularizeApplicationPageReqVO pageReqVO);
 
     /**
-     * 鎻愪氦杞鐢宠瀹℃壒
+     * 鎻愪氦杞鐢宠瀹℃壒锛堣崏绋� / 瀹℃牳涓嶉�氳繃 鈫� 瀹℃壒涓級
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴鎸囧畾锛屾彁浜ゆ椂鏃犻渶閫夋嫨銆�
      *
      * @param id 鐢宠ID
-     * @param processDefinitionKey 娴佺▼瀹氫箟Key
-     * @param userId 鍙戣捣浜篒D
      */
-    void submitRegularizeApplication(Long id, String processDefinitionKey, Long userId);
+    void submitRegularizeApplication(Long id);
 
     /**
-     * 鏇存柊杞鐢宠瀹℃壒鐘舵��
+     * 鑾峰緱杞鐢宠鐨勫鎵逛汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳
      *
-     * @param id 鐢宠ID
-     * @param status 瀹℃壒鐘舵��
+     * @return 瀹℃壒浜虹敤鎴风紪鍙烽泦鍚�
      */
-    void updateRegularizeApplicationAuditStatus(Long id, Integer status);
+    Set<Long> getRegularizeApplicationApproverUserIds();
 
     /**
-     * 鏍规嵁娴佺▼瀹炰緥ID鑾峰彇杞鐢宠
+     * 瀹℃牳杞鐢宠锛堝鎵逛腑 鈫� 瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
      *
-     * @param processInstanceId 娴佺▼瀹炰緥ID
-     * @return 鐢宠淇℃伅
-     */
-    HrmRegularizeApplicationDO getRegularizeApplicationByProcessInstanceId(String processInstanceId);
-
-    /**
-     * 鑾峰彇杞瀹℃壒娴佺▼瀹氫箟鍒楄〃
+     * 瀹℃牳閫氳繃鏃跺洖鍐欏憳宸ヤ富妗o紙鐘舵��=鍦ㄨ亴锛岀敤宸ユ�ц川=姝e紡锛岃浆姝f棩鏈燂級銆�
      *
-     * @return 娴佺▼瀹氫箟鍒楄〃
+     * @param id           鐢宠ID
+     * @param pass         鏄惁閫氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛堜笉閫氳繃鏃跺繀濉級
      */
-    List<Map<String, Object>> getApproveProcessDefinitionList();
+    void auditRegularizeApplication(Long id, Boolean pass, String reviewRemark);
 
 }
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmRegularizeApplicationServiceImpl.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmRegularizeApplicationServiceImpl.java
index 660134a..2a90f0e 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmRegularizeApplicationServiceImpl.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmRegularizeApplicationServiceImpl.java
@@ -1,23 +1,20 @@
 package cn.iocoder.yudao.module.hrm.service.approval;
 
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationPageReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationRespVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmRegularizeApplicationSaveReqVO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmRegularizeApplicationDO;
+import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO;
 import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmRegularizeApplicationMapper;
+import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper;
 import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO;
 import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
 import cn.iocoder.yudao.module.hrm.enums.HrmEmploymentTypeEnum;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.PostApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
@@ -26,23 +23,20 @@
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
-import java.util.ArrayList;
+import java.time.LocalDate;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*;
 
 /**
@@ -55,6 +49,23 @@
 @Slf4j
 public class HrmRegularizeApplicationServiceImpl implements HrmRegularizeApplicationService {
 
+    /**
+     * 杞鐢宠瀹℃壒鐨勪笟鍔$被鍨嬬紪鐮�
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鎵逛汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
+     */
+    private static final String REGULARIZE_APPROVE_BIZ_TYPE = "hrm_regularize_approve";
+
+    /**
+     * 鍛樺伐鐘舵�侊細鍦ㄨ亴
+     */
+    private static final Integer EMPLOYEE_STATUS_ACTIVE = 1;
+
+    /**
+     * 鐢ㄥ伐鎬ц川锛氭寮�
+     */
+    private static final Integer EMPLOYMENT_TYPE_FORMAL = 1;
+
     @Resource
     private HrmRegularizeApplicationMapper regularizeApplicationMapper;
     @Resource
@@ -66,11 +77,9 @@
     @Resource
     private AdminUserApi adminUserApi;
     @Resource
-    private BpmProcessInstanceApi bpmProcessInstanceApi;
+    private ApprovalConfigApi approvalConfigApi;
     @Resource
-    private BpmCategoryService bpmCategoryService;
-    @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private HrmEmployeeMapper employeeMapper;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -220,88 +229,87 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitRegularizeApplication(Long id, String processDefinitionKey, Long userId) {
+    public void submitRegularizeApplication(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鍙彁浜ょ姸鎬侊紙鑽夌 / 瀹℃牳涓嶉�氳繃锛�
         HrmRegularizeApplicationDO application = validateRegularizeApplicationExists(id);
-        if (ObjUtil.notEqual(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())) {
-            throw exception(REGULARIZE_APPLICATION_SUBMIT_FAIL_NOT_DRAFT);
+        if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())
+                && !Objects.equals(application.getStatus(), HrmAuditStatusEnum.REJECT.getStatus())) {
+            throw exception(REGULARIZE_APPLICATION_SUBMIT_FAIL_NOT_EDITABLE);
         }
-        validateApproveCategoryAndProcessDefinition();
-        ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey);
-        if (processDefinition == null) {
-            throw exception(REGULARIZE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-        String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
-                .setProcessDefinitionKey(processDefinitionKey).setBusinessKey(String.valueOf(id)));
-        regularizeApplicationMapper.updateById(HrmRegularizeApplicationDO.builder()
-                .id(id)
-                .processInstanceId(processInstanceId)
-                .status(HrmAuditStatusEnum.PROCESS.getStatus())
-                .build());
-    }
 
-    private void validateApproveCategoryAndProcessDefinition() {
-        List<String> codes = Collections.singletonList(APPROVE_CATEGORY_CODE);
-        Map<String, ?> categoryMap = bpmCategoryService.getCategoryMap(codes);
-        if (!categoryMap.containsKey(APPROVE_CATEGORY_CODE)) {
-            throw exception(REGULARIZE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            throw exception(REGULARIZE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-        boolean hasActiveDefinition = processDefinitions.stream().anyMatch(pd -> !pd.isSuspended());
-        if (!hasActiveDefinition) {
-            throw exception(REGULARIZE_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
+        // 2. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鎵逛汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(REGULARIZE_APPROVE_BIZ_TYPE);
+
+        // 3. 鐘舵�佺疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋滐紝閬垮厤娈嬬暀銆屽鏍镐笉閫氳繃銆嶇殑鍘熷洜
+        regularizeApplicationMapper.submitAndResetAuditInfo(id, HrmAuditStatusEnum.PROCESS.getStatus());
     }
 
     @Override
-    public List<Map<String, Object>> getApproveProcessDefinitionList() {
-        validateApproveCategoryAndProcessDefinition();
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE);
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (ProcessDefinition pd : processDefinitions) {
-            if (pd.isSuspended()) continue;
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            item.put("version", pd.getVersion());
-            result.add(item);
-        }
-        return result;
+    public Set<Long> getRegularizeApplicationApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(REGULARIZE_APPROVE_BIZ_TYPE);
     }
 
     @Override
-    public void updateRegularizeApplicationAuditStatus(Long id, Integer status) {
+    @Transactional(rollbackFor = Exception.class)
+    public void auditRegularizeApplication(Long id, Boolean pass, String reviewRemark) {
+        // 1. 鏍¢獙瀛樺湪
         HrmRegularizeApplicationDO application = validateRegularizeApplicationExists(id);
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
         if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.PROCESS.getStatus())) {
-            log.error("[updateRegularizeApplicationAuditStatus][application({}) 涓嶅浜庡鎵逛腑锛屾棤娉曟洿鏂板鎵圭粨鏋�({})]", id, status);
-            throw exception(REGULARIZE_APPLICATION_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS);
+            throw exception(REGULARIZE_APPLICATION_AUDIT_FAIL_NOT_PROCESS);
         }
-        regularizeApplicationMapper.updateById(HrmRegularizeApplicationDO.builder()
-                .id(id)
-                .status(status)
-                .approveTime(java.time.LocalDateTime.now())
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鎵逛汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(REGULARIZE_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝鐘舵�佺疆涓哄鏍镐笉閫氳繃锛岄��鍥炴彁浜や汉淇敼鍚庡彲閲嶆柊鎻愪氦
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(REGULARIZE_APPLICATION_AUDIT_REJECT_REASON_REQUIRED);
+            }
+            regularizeApplicationMapper.auditRegularizeApplication(id, HrmAuditStatusEnum.REJECT.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
+            return;
+        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄鏍搁�氳繃
+        regularizeApplicationMapper.auditRegularizeApplication(id, HrmAuditStatusEnum.APPROVE.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
+
+        // 6. 瀹℃牳閫氳繃鍚庣疆涓氬姟閫昏緫锛氬洖鍐欏憳宸ヤ富妗o紙鐘舵��=鍦ㄨ亴锛岀敤宸ユ�ц川=姝e紡锛岃浆姝f棩鏈� = 鎷熻浆姝f棩鏈熸垨褰撳ぉ锛�
+        writeBackEmployee(application);
+    }
+
+    /**
+     * 瀹℃牳閫氳繃鍚庡洖鍐欏憳宸ヤ富妗�
+     *
+     * @param application 杞鐢宠
+     */
+    private void writeBackEmployee(HrmRegularizeApplicationDO application) {
+        HrmEmployeeDO employee = employeeMapper.selectByUserId(application.getUserId());
+        if (employee == null) {
+            log.warn("[writeBackEmployee] 杞鐢宠({}) 鐢ㄦ埛({}) 鏈壘鍒板憳宸ユ。妗堬紝璺宠繃鍥炲啓", application.getId(), application.getUserId());
+            return;
+        }
+        LocalDate regularDate = application.getExpectedDate() != null ? application.getExpectedDate() : LocalDate.now();
+        employeeMapper.updateById(HrmEmployeeDO.builder()
+                .id(employee.getId())
+                .employeeStatus(EMPLOYEE_STATUS_ACTIVE)
+                .employmentType(EMPLOYMENT_TYPE_FORMAL)
+                .regularDate(regularDate)
                 .build());
     }
 
-    @Override
-    public HrmRegularizeApplicationDO getRegularizeApplicationByProcessInstanceId(String processInstanceId) {
-        return regularizeApplicationMapper.selectByProcessInstanceId(processInstanceId);
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
+        }
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
 }
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmResignationApplicationService.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmResignationApplicationService.java
index 4ea0a0e..f8fa936 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmResignationApplicationService.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmResignationApplicationService.java
@@ -8,8 +8,7 @@
 import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmResignationApplicationDO;
 import jakarta.validation.Valid;
 
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 /**
  * 绂昏亴鐢宠 Service 鎺ュ彛
@@ -17,16 +16,6 @@
  * @author 瓒呯骇绠$悊鍛�
  */
 public interface HrmResignationApplicationService {
-
-    /**
-     * BPM 绂昏亴瀹℃壒娴佺▼鏍囪瘑
-     */
-    String BPM_PROCESS_DEFINITION_KEY = "hrm_resignation";
-
-    /**
-     * BPM 绂昏亴瀹℃壒鍒嗙被缂栫爜
-     */
-    String APPROVE_CATEGORY_CODE = "hrm_resignation_approve";
 
     /**
      * 鍒涘缓绂昏亴鐢宠
@@ -75,36 +64,31 @@
     PageResult<HrmResignationApplicationRespVO> getResignationApplicationPage(HrmResignationApplicationPageReqVO pageReqVO);
 
     /**
-     * 鎻愪氦绂昏亴鐢宠瀹℃壒
+     * 鎻愪氦绂昏亴鐢宠瀹℃壒锛堣崏绋� / 瀹℃牳涓嶉�氳繃 鈫� 瀹℃壒涓級
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴鎸囧畾锛屾彁浜ゆ椂鏃犻渶閫夋嫨銆�
      *
      * @param id 鐢宠ID
-     * @param processDefinitionKey 娴佺▼瀹氫箟Key
-     * @param userId 鎻愪氦浜篒D
      */
-    void submitResignationApplication(Long id, String processDefinitionKey, Long userId);
+    void submitResignationApplication(Long id);
 
     /**
-     * 鑾峰彇鍙敤鐨勫鎵规祦绋嬪畾涔夊垪琛�
+     * 鑾峰緱绂昏亴鐢宠鐨勫鎵逛汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳
      *
-     * @return 娴佺▼瀹氫箟鍒楄〃
+     * @return 瀹℃壒浜虹敤鎴风紪鍙烽泦鍚�
      */
-    List<Map<String, Object>> getApproveProcessDefinitionList();
+    Set<Long> getResignationApplicationApproverUserIds();
 
     /**
-     * 鏇存柊绂昏亴鐢宠瀹℃壒鐘舵�侊紙BPM 鍥炶皟锛�
+     * 瀹℃牳绂昏亴鐢宠锛堝鎵逛腑 鈫� 瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
      *
-     * @param id 鐢宠ID
-     * @param status 瀹℃壒鐘舵��
-     */
-    void updateResignationApplicationAuditStatus(Long id, Integer status);
-
-    /**
-     * 鏍规嵁娴佺▼瀹炰緥ID鑾峰彇绂昏亴鐢宠
+     * 瀹℃牳閫氳繃鏃跺洖鍐欏憳宸ヤ富妗o紙鐘舵��=绂昏亴锛岀鑱屾棩鏈燂級銆�
      *
-     * @param processInstanceId 娴佺▼瀹炰緥ID
-     * @return 绂昏亴鐢宠
+     * @param id           鐢宠ID
+     * @param pass         鏄惁閫氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛堜笉閫氳繃鏃跺繀濉級
      */
-    HrmResignationApplicationDO getResignationApplicationByProcessInstanceId(String processInstanceId);
+    void auditResignationApplication(Long id, Boolean pass, String reviewRemark);
 
     /**
      * 鏇存柊绂昏亴鐢宠浜ゆ帴鐘舵��
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmResignationApplicationServiceImpl.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmResignationApplicationServiceImpl.java
index 8d97391..f10205b 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmResignationApplicationServiceImpl.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmResignationApplicationServiceImpl.java
@@ -1,24 +1,21 @@
 package cn.iocoder.yudao.module.hrm.service.approval;
 
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationApplicationPageReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationApplicationRespVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationApplicationSaveReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmResignationHandoverReqVO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmResignationApplicationDO;
+import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO;
 import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmResignationApplicationMapper;
+import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper;
 import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO;
 import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
 import cn.iocoder.yudao.module.hrm.enums.HrmResignationTypeEnum;
 import cn.iocoder.yudao.module.hrm.service.handover.HrmUserHandoverService;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
 import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
@@ -26,14 +23,12 @@
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
-import java.util.ArrayList;
+import java.time.LocalDate;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -44,7 +39,7 @@
 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*;
 
 /**
@@ -61,6 +56,18 @@
     private static final Integer HANDOVER_STATUS_IN_PROGRESS = 10;
     private static final Integer HANDOVER_STATUS_COMPLETED = 20;
 
+    /**
+     * 绂昏亴鐢宠瀹℃壒鐨勪笟鍔$被鍨嬬紪鐮�
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鎵逛汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
+     */
+    private static final String RESIGNATION_APPROVE_BIZ_TYPE = "hrm_resignation_approve";
+
+    /**
+     * 鍛樺伐鐘舵�侊細绂昏亴
+     */
+    private static final Integer EMPLOYEE_STATUS_RESIGNED = 3;
+
     @Resource
     private HrmResignationApplicationMapper resignationApplicationMapper;
     @Resource
@@ -70,13 +77,11 @@
     @Resource
     private AdminUserApi adminUserApi;
     @Resource
-    private BpmProcessInstanceApi bpmProcessInstanceApi;
-    @Resource
-    private BpmCategoryService bpmCategoryService;
-    @Resource
     private StorageAttachmentApi storageAttachmentApi;
     @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private ApprovalConfigApi approvalConfigApi;
+    @Resource
+    private HrmEmployeeMapper employeeMapper;
     @Resource
     private HrmUserHandoverService handoverService;
 
@@ -243,88 +248,87 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitResignationApplication(Long id, String processDefinitionKey, Long userId) {
+    public void submitResignationApplication(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鍙彁浜ょ姸鎬侊紙鑽夌 / 瀹℃牳涓嶉�氳繃锛�
         HrmResignationApplicationDO application = validateResignationApplicationExists(id);
-        if (ObjUtil.notEqual(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())) {
-            throw exception(RESIGNATION_APPLICATION_SUBMIT_FAIL_NOT_DRAFT);
+        if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())
+                && !Objects.equals(application.getStatus(), HrmAuditStatusEnum.REJECT.getStatus())) {
+            throw exception(RESIGNATION_APPLICATION_SUBMIT_FAIL_NOT_EDITABLE);
         }
-        validateApproveCategoryAndProcessDefinition();
-        ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey);
-        if (processDefinition == null) {
-            throw exception(RESIGNATION_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-        String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
-                .setProcessDefinitionKey(processDefinitionKey).setBusinessKey(String.valueOf(id)));
-        resignationApplicationMapper.updateById(HrmResignationApplicationDO.builder()
-                .id(id)
-                .processInstanceId(processInstanceId)
-                .status(HrmAuditStatusEnum.PROCESS.getStatus())
-                .build());
-    }
 
-    private void validateApproveCategoryAndProcessDefinition() {
-        List<String> codes = Collections.singletonList(APPROVE_CATEGORY_CODE);
-        Map<String, ?> categoryMap = bpmCategoryService.getCategoryMap(codes);
-        if (!categoryMap.containsKey(APPROVE_CATEGORY_CODE)) {
-            throw exception(RESIGNATION_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            throw exception(RESIGNATION_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-        boolean hasActiveDefinition = processDefinitions.stream().anyMatch(pd -> !pd.isSuspended());
-        if (!hasActiveDefinition) {
-            throw exception(RESIGNATION_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
+        // 2. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鎵逛汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(RESIGNATION_APPROVE_BIZ_TYPE);
+
+        // 3. 鐘舵�佺疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋滐紝閬垮厤娈嬬暀銆屽鏍镐笉閫氳繃銆嶇殑鍘熷洜
+        resignationApplicationMapper.submitAndResetAuditInfo(id, HrmAuditStatusEnum.PROCESS.getStatus());
     }
 
     @Override
-    public List<Map<String, Object>> getApproveProcessDefinitionList() {
-        validateApproveCategoryAndProcessDefinition();
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE);
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (ProcessDefinition pd : processDefinitions) {
-            if (pd.isSuspended()) continue;
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            item.put("version", pd.getVersion());
-            result.add(item);
-        }
-        return result;
+    public Set<Long> getResignationApplicationApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(RESIGNATION_APPROVE_BIZ_TYPE);
     }
 
     @Override
-    public void updateResignationApplicationAuditStatus(Long id, Integer status) {
+    @Transactional(rollbackFor = Exception.class)
+    public void auditResignationApplication(Long id, Boolean pass, String reviewRemark) {
+        // 1. 鏍¢獙瀛樺湪
         HrmResignationApplicationDO application = validateResignationApplicationExists(id);
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
         if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.PROCESS.getStatus())) {
-            log.error("[updateResignationApplicationAuditStatus][application({}) 涓嶅浜庡鎵逛腑锛屾棤娉曟洿鏂板鎵圭粨鏋�({})]", id, status);
-            throw exception(RESIGNATION_APPLICATION_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS);
+            throw exception(RESIGNATION_APPLICATION_AUDIT_FAIL_NOT_PROCESS);
         }
-        resignationApplicationMapper.updateById(HrmResignationApplicationDO.builder()
-                .id(id)
-                .status(status)
-                .approveTime(java.time.LocalDateTime.now())
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鎵逛汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(RESIGNATION_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝鐘舵�佺疆涓哄鏍镐笉閫氳繃锛岄��鍥炴彁浜や汉淇敼鍚庡彲閲嶆柊鎻愪氦
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(RESIGNATION_APPLICATION_AUDIT_REJECT_REASON_REQUIRED);
+            }
+            resignationApplicationMapper.auditResignationApplication(id, HrmAuditStatusEnum.REJECT.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
+            return;
+        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄鏍搁�氳繃
+        resignationApplicationMapper.auditResignationApplication(id, HrmAuditStatusEnum.APPROVE.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
+
+        // 6. 瀹℃牳閫氳繃鍚庣疆涓氬姟閫昏緫锛氬洖鍐欏憳宸ヤ富妗o紙鐘舵��=绂昏亴锛岀鑱屾棩鏈� = 瀹為檯绂昏亴鏃ユ湡鎴栭璁$鑱屾棩鏈燂級
+        writeBackEmployee(application);
+    }
+
+    /**
+     * 瀹℃牳閫氳繃鍚庡洖鍐欏憳宸ヤ富妗�
+     *
+     * @param application 绂昏亴鐢宠
+     */
+    private void writeBackEmployee(HrmResignationApplicationDO application) {
+        HrmEmployeeDO employee = employeeMapper.selectByUserId(application.getUserId());
+        if (employee == null) {
+            log.warn("[writeBackEmployee] 绂昏亴鐢宠({}) 鐢ㄦ埛({}) 鏈壘鍒板憳宸ユ。妗堬紝璺宠繃鍥炲啓", application.getId(), application.getUserId());
+            return;
+        }
+        LocalDate leaveDate = application.getActualDate() != null
+                ? application.getActualDate() : application.getExpectedDate();
+        employeeMapper.updateById(HrmEmployeeDO.builder()
+                .id(employee.getId())
+                .employeeStatus(EMPLOYEE_STATUS_RESIGNED)
+                .leaveDate(leaveDate)
                 .build());
     }
 
-    @Override
-    public HrmResignationApplicationDO getResignationApplicationByProcessInstanceId(String processInstanceId) {
-        return resignationApplicationMapper.selectByProcessInstanceId(processInstanceId);
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
+        }
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
     @Override
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationService.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationService.java
index 3a2283b..2d227b6 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationService.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationService.java
@@ -7,8 +7,7 @@
 import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmTransferApplicationDO;
 import jakarta.validation.Valid;
 
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 /**
  * 璋冨矖鐢宠 Service 鎺ュ彛
@@ -16,16 +15,6 @@
  * @author 瓒呯骇绠$悊鍛�
  */
 public interface HrmTransferApplicationService {
-
-    /**
-     * BPM 璋冨矖瀹℃壒娴佺▼鏍囪瘑
-     */
-    String BPM_PROCESS_DEFINITION_KEY = "hrm_transfer";
-
-    /**
-     * BPM 璋冨矖瀹℃壒鍒嗙被缂栫爜
-     */
-    String APPROVE_CATEGORY_CODE = "hrm_transfer_approve";
 
     /**
      * 鍒涘缓璋冨矖鐢宠
@@ -74,35 +63,30 @@
     PageResult<HrmTransferApplicationRespVO> getTransferApplicationPage(HrmTransferApplicationPageReqVO pageReqVO);
 
     /**
-     * 鎻愪氦璋冨矖鐢宠瀹℃壒
+     * 鎻愪氦璋冨矖鐢宠瀹℃壒锛堣崏绋� / 瀹℃牳涓嶉�氳繃 鈫� 瀹℃壒涓級
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴鎸囧畾锛屾彁浜ゆ椂鏃犻渶閫夋嫨銆�
      *
      * @param id 鐢宠ID
-     * @param processDefinitionKey 娴佺▼瀹氫箟Key
-     * @param userId 鎻愪氦浜篒D
      */
-    void submitTransferApplication(Long id, String processDefinitionKey, Long userId);
+    void submitTransferApplication(Long id);
 
     /**
-     * 鑾峰彇鍙敤鐨勫鎵规祦绋嬪畾涔夊垪琛�
+     * 鑾峰緱璋冨矖鐢宠鐨勫鎵逛汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳
      *
-     * @return 娴佺▼瀹氫箟鍒楄〃
+     * @return 瀹℃壒浜虹敤鎴风紪鍙烽泦鍚�
      */
-    List<Map<String, Object>> getApproveProcessDefinitionList();
+    Set<Long> getTransferApplicationApproverUserIds();
 
     /**
-     * 鏇存柊璋冨矖鐢宠瀹℃壒鐘舵�侊紙BPM 鍥炶皟锛�
+     * 瀹℃牳璋冨矖鐢宠锛堝鎵逛腑 鈫� 瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
      *
-     * @param id 鐢宠ID
-     * @param status 瀹℃壒鐘舵��
-     */
-    void updateTransferApplicationAuditStatus(Long id, Integer status);
-
-    /**
-     * 鏍规嵁娴佺▼瀹炰緥ID鑾峰彇璋冨矖鐢宠
+     * 瀹℃牳閫氳繃鏃跺洖鍐欏憳宸ヤ富妗o紙閮ㄩ棬 = 鐩爣閮ㄩ棬锛屽矖浣� = 鐩爣宀椾綅锛夈��
      *
-     * @param processInstanceId 娴佺▼瀹炰緥ID
-     * @return 璋冨矖鐢宠
+     * @param id           鐢宠ID
+     * @param pass         鏄惁閫氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛堜笉閫氳繃鏃跺繀濉級
      */
-    HrmTransferApplicationDO getTransferApplicationByProcessInstanceId(String processInstanceId);
+    void auditTransferApplication(Long id, Boolean pass, String reviewRemark);
 
 }
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationServiceImpl.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationServiceImpl.java
index 7505b7b..0535199 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationServiceImpl.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationServiceImpl.java
@@ -1,22 +1,19 @@
 package cn.iocoder.yudao.module.hrm.service.approval;
 
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationPageReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationRespVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationSaveReqVO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmTransferApplicationDO;
+import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO;
 import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmTransferApplicationMapper;
+import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper;
 import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO;
 import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
 import cn.iocoder.yudao.module.hrm.enums.HrmTransferTypeEnum;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.PostApi;
 import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
@@ -26,14 +23,11 @@
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -44,7 +38,7 @@
 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*;
 
 /**
@@ -57,6 +51,13 @@
 @Slf4j
 public class HrmTransferApplicationServiceImpl implements HrmTransferApplicationService {
 
+    /**
+     * 璋冨矖鐢宠瀹℃壒鐨勪笟鍔$被鍨嬬紪鐮�
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鎵逛汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
+     */
+    private static final String TRANSFER_APPROVE_BIZ_TYPE = "hrm_transfer_approve";
+
     @Resource
     private HrmTransferApplicationMapper transferApplicationMapper;
     @Resource
@@ -68,13 +69,11 @@
     @Resource
     private AdminUserApi adminUserApi;
     @Resource
-    private BpmProcessInstanceApi bpmProcessInstanceApi;
-    @Resource
-    private BpmCategoryService bpmCategoryService;
-    @Resource
     private StorageAttachmentApi storageAttachmentApi;
     @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private ApprovalConfigApi approvalConfigApi;
+    @Resource
+    private HrmEmployeeMapper employeeMapper;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -254,88 +253,85 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitTransferApplication(Long id, String processDefinitionKey, Long userId) {
+    public void submitTransferApplication(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鍙彁浜ょ姸鎬侊紙鑽夌 / 瀹℃牳涓嶉�氳繃锛�
         HrmTransferApplicationDO application = validateTransferApplicationExists(id);
-        if (ObjUtil.notEqual(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())) {
-            throw exception(TRANSFER_APPLICATION_SUBMIT_FAIL_NOT_DRAFT);
+        if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.DRAFT.getStatus())
+                && !Objects.equals(application.getStatus(), HrmAuditStatusEnum.REJECT.getStatus())) {
+            throw exception(TRANSFER_APPLICATION_SUBMIT_FAIL_NOT_EDITABLE);
         }
-        validateApproveCategoryAndProcessDefinition();
-        ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey);
-        if (processDefinition == null) {
-            throw exception(TRANSFER_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-        String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
-                .setProcessDefinitionKey(processDefinitionKey).setBusinessKey(String.valueOf(id)));
-        transferApplicationMapper.updateById(HrmTransferApplicationDO.builder()
-                .id(id)
-                .processInstanceId(processInstanceId)
-                .status(HrmAuditStatusEnum.PROCESS.getStatus())
-                .build());
-    }
 
-    private void validateApproveCategoryAndProcessDefinition() {
-        List<String> codes = Collections.singletonList(APPROVE_CATEGORY_CODE);
-        Map<String, ?> categoryMap = bpmCategoryService.getCategoryMap(codes);
-        if (!categoryMap.containsKey(APPROVE_CATEGORY_CODE)) {
-            throw exception(TRANSFER_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            throw exception(TRANSFER_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-        boolean hasActiveDefinition = processDefinitions.stream().anyMatch(pd -> !pd.isSuspended());
-        if (!hasActiveDefinition) {
-            throw exception(TRANSFER_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
+        // 2. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鎵逛汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(TRANSFER_APPROVE_BIZ_TYPE);
+
+        // 3. 鐘舵�佺疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋滐紝閬垮厤娈嬬暀銆屽鏍镐笉閫氳繃銆嶇殑鍘熷洜
+        transferApplicationMapper.submitAndResetAuditInfo(id, HrmAuditStatusEnum.PROCESS.getStatus());
     }
 
     @Override
-    public List<Map<String, Object>> getApproveProcessDefinitionList() {
-        validateApproveCategoryAndProcessDefinition();
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE);
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (ProcessDefinition pd : processDefinitions) {
-            if (pd.isSuspended()) continue;
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            item.put("version", pd.getVersion());
-            result.add(item);
-        }
-        return result;
+    public Set<Long> getTransferApplicationApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(TRANSFER_APPROVE_BIZ_TYPE);
     }
 
     @Override
-    public void updateTransferApplicationAuditStatus(Long id, Integer status) {
+    @Transactional(rollbackFor = Exception.class)
+    public void auditTransferApplication(Long id, Boolean pass, String reviewRemark) {
+        // 1. 鏍¢獙瀛樺湪
         HrmTransferApplicationDO application = validateTransferApplicationExists(id);
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
         if (!Objects.equals(application.getStatus(), HrmAuditStatusEnum.PROCESS.getStatus())) {
-            log.error("[updateTransferApplicationAuditStatus][application({}) 涓嶅浜庡鎵逛腑锛屾棤娉曟洿鏂板鎵圭粨鏋�({})]", id, status);
-            throw exception(TRANSFER_APPLICATION_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS);
+            throw exception(TRANSFER_APPLICATION_AUDIT_FAIL_NOT_PROCESS);
         }
-        transferApplicationMapper.updateById(HrmTransferApplicationDO.builder()
-                .id(id)
-                .status(status)
-                .approveTime(java.time.LocalDateTime.now())
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鎵逛汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(TRANSFER_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝鐘舵�佺疆涓哄鏍镐笉閫氳繃锛岄��鍥炴彁浜や汉淇敼鍚庡彲閲嶆柊鎻愪氦
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(TRANSFER_APPLICATION_AUDIT_REJECT_REASON_REQUIRED);
+            }
+            transferApplicationMapper.auditTransferApplication(id, HrmAuditStatusEnum.REJECT.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
+            return;
+        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄鏍搁�氳繃
+        transferApplicationMapper.auditTransferApplication(id, HrmAuditStatusEnum.APPROVE.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
+
+        // 6. 瀹℃牳閫氳繃鍚庣疆涓氬姟閫昏緫锛氬洖鍐欏憳宸ヤ富妗o紙閮ㄩ棬 = 鐩爣閮ㄩ棬锛屽矖浣� = 鐩爣宀椾綅锛�
+        writeBackEmployee(application);
+    }
+
+    /**
+     * 瀹℃牳閫氳繃鍚庡洖鍐欏憳宸ヤ富妗�
+     *
+     * @param application 璋冨矖鐢宠
+     */
+    private void writeBackEmployee(HrmTransferApplicationDO application) {
+        HrmEmployeeDO employee = employeeMapper.selectByUserId(application.getUserId());
+        if (employee == null) {
+            log.warn("[writeBackEmployee] 璋冨矖鐢宠({}) 鐢ㄦ埛({}) 鏈壘鍒板憳宸ユ。妗堬紝璺宠繃鍥炲啓", application.getId(), application.getUserId());
+            return;
+        }
+        employeeMapper.updateById(HrmEmployeeDO.builder()
+                .id(employee.getId())
+                .deptId(application.getTargetDeptId())
+                .postId(application.getTargetPostId())
                 .build());
     }
 
-    @Override
-    public HrmTransferApplicationDO getTransferApplicationByProcessInstanceId(String processInstanceId) {
-        return transferApplicationMapper.selectByProcessInstanceId(processInstanceId);
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
+        }
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
 }
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/listener/HrmLeaveApplicationStatusListener.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/listener/HrmLeaveApplicationStatusListener.java
deleted file mode 100644
index 3a4f422..0000000
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/listener/HrmLeaveApplicationStatusListener.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package cn.iocoder.yudao.module.hrm.service.approval.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmLeaveApplicationDO;
-import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmLeaveApplicationMapper;
-import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
-import cn.iocoder.yudao.module.hrm.service.approval.HrmLeaveApplicationService;
-import cn.iocoder.yudao.module.hrm.util.HrmAuditStatusUtils;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-/**
- * 璇峰亣鐢宠瀹℃壒鐨勭粨鏋滅洃鍚櫒瀹炵幇绫�
- *
- * @author 瓒呯骇绠$悊鍛�
- */
-@Component
-@Slf4j
-public class HrmLeaveApplicationStatusListener implements ApplicationListener<BpmProcessInstanceStatusEvent> {
-
-    @Resource
-    private HrmLeaveApplicationService leaveApplicationService;
-    @Resource
-    private HrmLeaveApplicationMapper leaveApplicationMapper;
-
-    @Override
-    public void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
-        // 閫氳繃 businessKey 鏌ヨ璇峰亣鐢宠
-        Long applicationId;
-        try {
-            applicationId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            return;
-        }
-
-        HrmLeaveApplicationDO application = leaveApplicationMapper.selectById(applicationId);
-        if (application == null) {
-            return;
-        }
-
-        // 鍙湁瀹℃壒涓姸鎬佺殑璇峰亣鐢宠鎵嶅鐞�
-        if (!HrmAuditStatusEnum.PROCESS.getStatus().equals(application.getStatus())) {
-            log.warn("[onApplicationEvent] 璇峰亣鐢宠({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵��: {}", applicationId, application.getStatus());
-            return;
-        }
-
-        log.info("[onApplicationEvent] 璇峰亣鐢宠({}) 瀹℃壒鐘舵�佹洿鏂�: {}", applicationId, event.getStatus());
-        // 鏇存柊瀹℃壒鐘舵��
-        Integer auditStatus = HrmAuditStatusUtils.convertBpmResultToAuditStatus(event.getStatus());
-        leaveApplicationService.updateLeaveApplicationAuditStatus(applicationId, auditStatus);
-    }
-
-}
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/listener/HrmRegularizeApplicationStatusListener.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/listener/HrmRegularizeApplicationStatusListener.java
deleted file mode 100644
index ff27e25..0000000
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/listener/HrmRegularizeApplicationStatusListener.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package cn.iocoder.yudao.module.hrm.service.approval.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmRegularizeApplicationDO;
-import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO;
-import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmRegularizeApplicationMapper;
-import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper;
-import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
-import cn.iocoder.yudao.module.hrm.service.approval.HrmRegularizeApplicationService;
-import cn.iocoder.yudao.module.hrm.util.HrmAuditStatusUtils;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-import java.time.LocalDate;
-
-/**
- * 杞鐢宠瀹℃壒鐨勭粨鏋滅洃鍚櫒瀹炵幇绫�
- *
- * @author 瓒呯骇绠$悊鍛�
- */
-@Component
-@Slf4j
-public class HrmRegularizeApplicationStatusListener implements ApplicationListener<BpmProcessInstanceStatusEvent> {
-
-    /**
-     * 鍛樺伐鐘舵�侊細鍦ㄨ亴
-     */
-    private static final Integer EMPLOYEE_STATUS_ACTIVE = 1;
-
-    /**
-     * 鐢ㄥ伐鎬ц川锛氭寮�
-     */
-    private static final Integer EMPLOYMENT_TYPE_FORMAL = 1;
-
-    @Resource
-    private HrmRegularizeApplicationService regularizeApplicationService;
-    @Resource
-    private HrmRegularizeApplicationMapper regularizeApplicationMapper;
-    @Resource
-    private HrmEmployeeMapper employeeMapper;
-
-    @Override
-    public void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
-        // 閫氳繃 businessKey 鏌ヨ杞鐢宠
-        Long applicationId;
-        try {
-            applicationId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            return;
-        }
-
-        HrmRegularizeApplicationDO application = regularizeApplicationMapper.selectById(applicationId);
-        if (application == null) {
-            return;
-        }
-
-        // 鍙湁瀹℃壒涓姸鎬佺殑杞鐢宠鎵嶅鐞�
-        if (!HrmAuditStatusEnum.PROCESS.getStatus().equals(application.getStatus())) {
-            log.warn("[onApplicationEvent] 杞鐢宠({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵��: {}", applicationId, application.getStatus());
-            return;
-        }
-
-        log.info("[onApplicationEvent] 杞鐢宠({}) 瀹℃壒鐘舵�佹洿鏂�: {}", applicationId, event.getStatus());
-        // 鏇存柊瀹℃壒鐘舵��
-        Integer auditStatus = HrmAuditStatusUtils.convertBpmResultToAuditStatus(event.getStatus());
-        regularizeApplicationService.updateRegularizeApplicationAuditStatus(applicationId, auditStatus);
-        // 瀹℃壒閫氳繃锛氬洖鍐欏憳宸ヤ富妗o紙鐘舵��=鍦ㄨ亴锛岀敤宸ユ�ц川=姝e紡锛岃浆姝f棩鏈� = 鎷熻浆姝f棩鏈熸垨褰撳ぉ锛�
-        if (HrmAuditStatusEnum.APPROVE.getStatus().equals(auditStatus)) {
-            writeBackEmployee(application);
-        }
-    }
-
-    private void writeBackEmployee(HrmRegularizeApplicationDO application) {
-        HrmEmployeeDO employee = employeeMapper.selectByUserId(application.getUserId());
-        if (employee == null) {
-            log.warn("[writeBackEmployee] 杞鐢宠({}) 鐢ㄦ埛({}) 鏈壘鍒板憳宸ユ。妗堬紝璺宠繃鍥炲啓", application.getId(), application.getUserId());
-            return;
-        }
-        LocalDate regularDate = application.getExpectedDate() != null ? application.getExpectedDate() : LocalDate.now();
-        employeeMapper.updateById(HrmEmployeeDO.builder()
-                .id(employee.getId())
-                .employeeStatus(EMPLOYEE_STATUS_ACTIVE)
-                .employmentType(EMPLOYMENT_TYPE_FORMAL)
-                .regularDate(regularDate)
-                .build());
-    }
-
-}
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/listener/HrmResignationApplicationStatusListener.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/listener/HrmResignationApplicationStatusListener.java
deleted file mode 100644
index 0ab04dd..0000000
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/listener/HrmResignationApplicationStatusListener.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package cn.iocoder.yudao.module.hrm.service.approval.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmResignationApplicationDO;
-import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO;
-import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmResignationApplicationMapper;
-import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper;
-import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
-import cn.iocoder.yudao.module.hrm.service.approval.HrmResignationApplicationService;
-import cn.iocoder.yudao.module.hrm.util.HrmAuditStatusUtils;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-/**
- * 绂昏亴鐢宠瀹℃壒鐨勭粨鏋滅洃鍚櫒瀹炵幇绫�
- *
- * @author 瓒呯骇绠$悊鍛�
- */
-@Component
-@Slf4j
-public class HrmResignationApplicationStatusListener implements ApplicationListener<BpmProcessInstanceStatusEvent> {
-
-    /**
-     * 鍛樺伐鐘舵�侊細绂昏亴
-     */
-    private static final Integer EMPLOYEE_STATUS_RESIGNED = 3;
-
-    @Resource
-    private HrmResignationApplicationService resignationApplicationService;
-    @Resource
-    private HrmResignationApplicationMapper resignationApplicationMapper;
-    @Resource
-    private HrmEmployeeMapper employeeMapper;
-
-    @Override
-    public void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
-        // 閫氳繃 businessKey 鏌ヨ绂昏亴鐢宠
-        Long applicationId;
-        try {
-            applicationId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            return;
-        }
-
-        HrmResignationApplicationDO application = resignationApplicationMapper.selectById(applicationId);
-        if (application == null) {
-            return;
-        }
-
-        // 鍙湁瀹℃壒涓姸鎬佺殑绂昏亴鐢宠鎵嶅鐞�
-        if (!HrmAuditStatusEnum.PROCESS.getStatus().equals(application.getStatus())) {
-            log.warn("[onApplicationEvent] 绂昏亴鐢宠({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵��: {}", applicationId, application.getStatus());
-            return;
-        }
-
-        log.info("[onApplicationEvent] 绂昏亴鐢宠({}) 瀹℃壒鐘舵�佹洿鏂�: {}", applicationId, event.getStatus());
-        // 鏇存柊瀹℃壒鐘舵��
-        Integer auditStatus = HrmAuditStatusUtils.convertBpmResultToAuditStatus(event.getStatus());
-        resignationApplicationService.updateResignationApplicationAuditStatus(applicationId, auditStatus);
-        // 瀹℃壒閫氳繃锛氬洖鍐欏憳宸ヤ富妗o紙鐘舵��=绂昏亴锛岀鑱屾棩鏈� = 瀹為檯绂昏亴鏃ユ湡鎴栭璁$鑱屾棩鏈燂級
-        if (HrmAuditStatusEnum.APPROVE.getStatus().equals(auditStatus)) {
-            writeBackEmployee(application);
-        }
-    }
-
-    private void writeBackEmployee(HrmResignationApplicationDO application) {
-        HrmEmployeeDO employee = employeeMapper.selectByUserId(application.getUserId());
-        if (employee == null) {
-            log.warn("[writeBackEmployee] 绂昏亴鐢宠({}) 鐢ㄦ埛({}) 鏈壘鍒板憳宸ユ。妗堬紝璺宠繃鍥炲啓", application.getId(), application.getUserId());
-            return;
-        }
-        java.time.LocalDate leaveDate = application.getActualDate() != null
-                ? application.getActualDate() : application.getExpectedDate();
-        employeeMapper.updateById(HrmEmployeeDO.builder()
-                .id(employee.getId())
-                .employeeStatus(EMPLOYEE_STATUS_RESIGNED)
-                .leaveDate(leaveDate)
-                .build());
-    }
-
-}
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/listener/HrmTransferApplicationStatusListener.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/listener/HrmTransferApplicationStatusListener.java
deleted file mode 100644
index 8c3871f..0000000
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/listener/HrmTransferApplicationStatusListener.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package cn.iocoder.yudao.module.hrm.service.approval.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.hrm.dal.dataobject.approval.HrmTransferApplicationDO;
-import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO;
-import cn.iocoder.yudao.module.hrm.dal.mysql.approval.HrmTransferApplicationMapper;
-import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper;
-import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
-import cn.iocoder.yudao.module.hrm.service.approval.HrmTransferApplicationService;
-import cn.iocoder.yudao.module.hrm.util.HrmAuditStatusUtils;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-/**
- * 璋冨矖鐢宠瀹℃壒鐨勭粨鏋滅洃鍚櫒瀹炵幇绫�
- *
- * @author 瓒呯骇绠$悊鍛�
- */
-@Component
-@Slf4j
-public class HrmTransferApplicationStatusListener implements ApplicationListener<BpmProcessInstanceStatusEvent> {
-
-    @Resource
-    private HrmTransferApplicationService transferApplicationService;
-    @Resource
-    private HrmTransferApplicationMapper transferApplicationMapper;
-    @Resource
-    private HrmEmployeeMapper employeeMapper;
-
-    @Override
-    public void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
-        // 閫氳繃 businessKey 鏌ヨ璋冨矖鐢宠
-        Long applicationId;
-        try {
-            applicationId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            return;
-        }
-
-        HrmTransferApplicationDO application = transferApplicationMapper.selectById(applicationId);
-        if (application == null) {
-            return;
-        }
-
-        // 鍙湁瀹℃壒涓姸鎬佺殑璋冨矖鐢宠鎵嶅鐞�
-        if (!HrmAuditStatusEnum.PROCESS.getStatus().equals(application.getStatus())) {
-            log.warn("[onApplicationEvent] 璋冨矖鐢宠({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵��: {}", applicationId, application.getStatus());
-            return;
-        }
-
-        log.info("[onApplicationEvent] 璋冨矖鐢宠({}) 瀹℃壒鐘舵�佹洿鏂�: {}", applicationId, event.getStatus());
-        // 鏇存柊瀹℃壒鐘舵��
-        Integer auditStatus = HrmAuditStatusUtils.convertBpmResultToAuditStatus(event.getStatus());
-        transferApplicationService.updateTransferApplicationAuditStatus(applicationId, auditStatus);
-        // 瀹℃壒閫氳繃锛氬洖鍐欏憳宸ヤ富妗o紙閮ㄩ棬 = 鐩爣閮ㄩ棬锛屽矖浣� = 鐩爣宀椾綅锛�
-        if (HrmAuditStatusEnum.APPROVE.getStatus().equals(auditStatus)) {
-            writeBackEmployee(application);
-        }
-    }
-
-    private void writeBackEmployee(HrmTransferApplicationDO application) {
-        HrmEmployeeDO employee = employeeMapper.selectByUserId(application.getUserId());
-        if (employee == null) {
-            log.warn("[writeBackEmployee] 璋冨矖鐢宠({}) 鐢ㄦ埛({}) 鏈壘鍒板憳宸ユ。妗堬紝璺宠繃鍥炲啓", application.getId(), application.getUserId());
-            return;
-        }
-        employeeMapper.updateById(HrmEmployeeDO.builder()
-                .id(employee.getId())
-                .deptId(application.getTargetDeptId())
-                .postId(application.getTargetPostId())
-                .build());
-    }
-
-}
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceExceptionService.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceExceptionService.java
index dff67a3..917cfb3 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceExceptionService.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceExceptionService.java
@@ -6,6 +6,8 @@
 import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceExceptionDO;
 import jakarta.validation.Valid;
 
+import java.util.Set;
+
 /**
  * 鑰冨嫟寮傚父鐢宠 Service 鎺ュ彛
  *
@@ -39,20 +41,30 @@
     HrmAttendanceExceptionDO getAttendanceException(Long id);
 
     /**
-     * 鎻愪氦鑰冨嫟寮傚父鐢宠
+     * 鎻愪氦鑰冨嫟寮傚父鐢宠瀹℃壒锛堣崏绋� / 瀹℃牳涓嶉�氳繃 鈫� 瀹℃壒涓級
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴鎸囧畾锛屾彁浜ゆ椂鏃犻渶閫夋嫨銆�
      *
      * @param id 鐢宠ID
-     * @param processDefinitionKey 娴佺▼瀹氫箟Key
-     * @param userId 鎻愪氦浜篒D
      */
-    void submitAttendanceException(Long id, String processDefinitionKey, Long userId);
+    void submitAttendanceException(Long id);
 
     /**
-     * 鏇存柊鑰冨嫟寮傚父鐢宠瀹℃壒鐘舵��
+     * 鑾峰緱鑰冨嫟寮傚父鐢宠鐨勫鎵逛汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳
      *
-     * @param id 鐢宠ID
-     * @param auditStatus 瀹℃壒鐘舵��
+     * @return 瀹℃壒浜虹敤鎴风紪鍙烽泦鍚�
      */
-    void updateAttendanceExceptionAuditStatus(Long id, Integer auditStatus);
+    Set<Long> getAttendanceExceptionApproverUserIds();
+
+    /**
+     * 瀹℃牳鑰冨嫟寮傚父鐢宠锛堝鎵逛腑 鈫� 瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     *
+     * 瀹℃牳閫氳繃鏃舵墽琛屽悗缃笟鍔¢�昏緫锛氳ˉ鍗″洖濉笂涓嬬彮鏃堕棿 / 鍔犵彮鍥炲啓鍔犵彮鏃堕暱銆�
+     *
+     * @param id           鐢宠ID
+     * @param pass         鏄惁閫氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛堜笉閫氳繃鏃跺繀濉級
+     */
+    void auditAttendanceException(Long id, Boolean pass, String reviewRemark);
 
 }
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceExceptionServiceImpl.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceExceptionServiceImpl.java
index 54eb8ab..e4579e9 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceExceptionServiceImpl.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceExceptionServiceImpl.java
@@ -1,16 +1,18 @@
 package cn.iocoder.yudao.module.hrm.service.attendance;
 
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceExceptionPageReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceExceptionSaveReqVO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceExceptionDO;
 import cn.iocoder.yudao.module.hrm.dal.mysql.attendance.HrmAttendanceExceptionMapper;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
 import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO;
+import cn.iocoder.yudao.module.hrm.enums.HrmAttendanceExceptionTypeEnum;
 import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO;
 import cn.iocoder.yudao.module.hrm.service.employee.HrmEmployeeService;
@@ -20,9 +22,10 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
-import java.time.LocalDateTime;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*;
 
 /**
@@ -35,18 +38,27 @@
 @Slf4j
 public class HrmAttendanceExceptionServiceImpl implements HrmAttendanceExceptionService {
 
+    /**
+     * 鑰冨嫟寮傚父鐢宠瀹℃壒鐨勪笟鍔$被鍨嬬紪鐮�
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鎵逛汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
+     */
+    private static final String ATTENDANCE_APPROVE_BIZ_TYPE = "hrm_attendance_approve";
+
     @Resource
     private HrmAttendanceExceptionMapper attendanceExceptionMapper;
     @Resource
     private HrmNoRedisDAO noRedisDAO;
     @Resource
-    private BpmProcessInstanceApi bpmProcessInstanceApi;
-    @Resource
     private StorageAttachmentApi storageAttachmentApi;
     @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private ApprovalConfigApi approvalConfigApi;
+    @Resource
+    private AdminUserApi adminUserApi;
     @Resource
     private HrmEmployeeService employeeService;
+    @Resource
+    private HrmAttendanceRecordService attendanceRecordService;
 
     @Override
     public Long createAttendanceException(HrmAttendanceExceptionSaveReqVO createReqVO) {
@@ -110,47 +122,73 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitAttendanceException(Long id, String processDefinitionKey, Long userId) {
-        // 1. 鏍¢獙寮傚父鐢宠瀛樺湪涓斾负鑽夌鐘舵��
+    public void submitAttendanceException(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鍙彁浜ょ姸鎬侊紙鑽夌 / 瀹℃牳涓嶉�氳繃锛�
         HrmAttendanceExceptionDO exception = validateAttendanceExceptionExists(id);
-        if (!HrmAuditStatusEnum.DRAFT.getStatus().equals(exception.getStatus())) {
-            throw exception(ATTENDANCE_EXCEPTION_SUBMIT_FAIL_NOT_DRAFT);
+        if (!HrmAuditStatusEnum.DRAFT.getStatus().equals(exception.getStatus())
+                && !HrmAuditStatusEnum.REJECT.getStatus().equals(exception.getStatus())) {
+            throw exception(ATTENDANCE_EXCEPTION_SUBMIT_FAIL_NOT_EDITABLE);
         }
 
-        // 2. 鏍¢獙娴佺▼瀹氫箟瀛樺湪涓斾负婵�娲荤姸鎬�
-        if (processDefinitionKey != null) {
-            bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey);
-        }
+        // 2. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鎵逛汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(ATTENDANCE_APPROVE_BIZ_TYPE);
 
-        // 3. 鍒涘缓瀹℃壒娴佺▼瀹炰緥
-        String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId,
-                new BpmProcessInstanceCreateReqDTO()
-                        .setProcessDefinitionKey(processDefinitionKey)
-                        .setBusinessKey(String.valueOf(id)));
+        // 3. 鐘舵�佺疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋滐紝閬垮厤娈嬬暀銆屽鏍镐笉閫氳繃銆嶇殑鍘熷洜
+        attendanceExceptionMapper.submitAndResetAuditInfo(id, HrmAuditStatusEnum.PROCESS.getStatus());
+    }
 
-        // 4. 鏇存柊寮傚父鐢宠鐘舵��
-        attendanceExceptionMapper.updateById(HrmAttendanceExceptionDO.builder()
-                .id(id)
-                .processInstanceId(processInstanceId)
-                .status(HrmAuditStatusEnum.PROCESS.getStatus())
-                .build());
+    @Override
+    public Set<Long> getAttendanceExceptionApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(ATTENDANCE_APPROVE_BIZ_TYPE);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void updateAttendanceExceptionAuditStatus(Long id, Integer auditStatus) {
-        // 1. 鏍¢獙寮傚父鐢宠瀛樺湪
+    public void auditAttendanceException(Long id, Boolean pass, String reviewRemark) {
+        // 1. 鏍¢獙瀛樺湪
         HrmAttendanceExceptionDO exception = validateAttendanceExceptionExists(id);
-        // 2. 鏍¢獙褰撳墠鐘舵�佷负瀹℃壒涓�
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
         if (!HrmAuditStatusEnum.PROCESS.getStatus().equals(exception.getStatus())) {
-            throw exception(ATTENDANCE_EXCEPTION_UPDATE_AUDIT_STATUS_FAIL);
+            throw exception(ATTENDANCE_EXCEPTION_AUDIT_FAIL_NOT_PROCESS);
         }
-        // 3. 鏇存柊鐘舵��
-        attendanceExceptionMapper.updateById(HrmAttendanceExceptionDO.builder()
-                .id(id)
-                .status(auditStatus)
-                .approveTime(LocalDateTime.now())
-                .build());
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鎵逛汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(ATTENDANCE_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝鐘舵�佺疆涓哄鏍镐笉閫氳繃锛岄��鍥炴彁浜や汉淇敼鍚庡彲閲嶆柊鎻愪氦
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(ATTENDANCE_EXCEPTION_AUDIT_REJECT_REASON_REQUIRED);
+            }
+            attendanceExceptionMapper.auditAttendanceException(id, HrmAuditStatusEnum.REJECT.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
+            return;
+        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄鏍搁�氳繃
+        attendanceExceptionMapper.auditAttendanceException(id, HrmAuditStatusEnum.APPROVE.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
+
+        // 6. 瀹℃牳閫氳繃鍚庣疆涓氬姟閫昏緫锛氳ˉ鍗″洖濉笂涓嬬彮鏃堕棿 / 鍔犵彮鍥炲啓鍔犵彮鏃堕暱
+        if (HrmAttendanceExceptionTypeEnum.SUPPLEMENT.getType().equals(exception.getType())) {
+            log.info("[auditAttendanceException] 琛ュ崱鐢宠({}) 瀹℃壒閫氳繃锛屽紑濮嬫洿鏂拌�冨嫟璁板綍", id);
+            attendanceRecordService.supplementClockIn(exception);
+        } else if (HrmAttendanceExceptionTypeEnum.OVERTIME.getType().equals(exception.getType())) {
+            log.info("[auditAttendanceException] 鍔犵彮鐢宠({}) 瀹℃壒閫氳繃锛屽紑濮嬪洖鍐欏姞鐝椂闀�", id);
+            attendanceRecordService.recordOvertime(exception);
+        }
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
+        }
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
 }
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/listener/HrmAttendanceExceptionStatusListener.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/listener/HrmAttendanceExceptionStatusListener.java
deleted file mode 100644
index 33a7b52..0000000
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/listener/HrmAttendanceExceptionStatusListener.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package cn.iocoder.yudao.module.hrm.service.attendance.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceExceptionDO;
-import cn.iocoder.yudao.module.hrm.dal.mysql.attendance.HrmAttendanceExceptionMapper;
-import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
-import cn.iocoder.yudao.module.hrm.enums.HrmAttendanceExceptionTypeEnum;
-import cn.iocoder.yudao.module.hrm.service.attendance.HrmAttendanceExceptionService;
-import cn.iocoder.yudao.module.hrm.service.attendance.HrmAttendanceRecordService;
-import cn.iocoder.yudao.module.hrm.util.HrmAuditStatusUtils;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-/**
- * 鑰冨嫟寮傚父鐢宠瀹℃壒鐨勭粨鏋滅洃鍚櫒瀹炵幇绫�
- *
- * @author 瓒呯骇绠$悊鍛�
- */
-@Component
-@Slf4j
-public class HrmAttendanceExceptionStatusListener implements ApplicationListener<BpmProcessInstanceStatusEvent> {
-
-    @Resource
-    private HrmAttendanceExceptionService attendanceExceptionService;
-    @Resource
-    private HrmAttendanceExceptionMapper attendanceExceptionMapper;
-    @Resource
-    private HrmAttendanceRecordService attendanceRecordService;
-
-    @Override
-    public void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
-        // 閫氳繃 businessKey 鏌ヨ鑰冨嫟寮傚父鐢宠
-        Long exceptionId;
-        try {
-            exceptionId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            return;
-        }
-
-        HrmAttendanceExceptionDO exception = attendanceExceptionMapper.selectById(exceptionId);
-        if (exception == null) {
-            return;
-        }
-
-        // 鍙湁瀹℃壒涓姸鎬佺殑鑰冨嫟寮傚父鐢宠鎵嶅鐞�
-        if (!HrmAuditStatusEnum.PROCESS.getStatus().equals(exception.getStatus())) {
-            log.warn("[onApplicationEvent] 鑰冨嫟寮傚父鐢宠({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵��: {}", exceptionId, exception.getStatus());
-            return;
-        }
-
-        log.info("[onApplicationEvent] 鑰冨嫟寮傚父鐢宠({}) 瀹℃壒鐘舵�佹洿鏂�: {}", exceptionId, event.getStatus());
-        // 杞崲瀹℃壒鐘舵��
-        Integer auditStatus = HrmAuditStatusUtils.convertBpmResultToAuditStatus(event.getStatus());
-        // 鏇存柊瀹℃壒鐘舵��
-        attendanceExceptionService.updateAttendanceExceptionAuditStatus(exceptionId, auditStatus);
-
-        // 琛ュ崱/鍔犵彮瀹℃壒閫氳繃鍚庯紝鏇存柊鑰冨嫟璁板綍锛堣ˉ鍗″洖濉笂涓嬬彮鏃堕棿锛屽姞鐝洖鍐欏姞鐝椂闀匡級
-        if (HrmAuditStatusEnum.APPROVE.getStatus().equals(auditStatus)) {
-            if (HrmAttendanceExceptionTypeEnum.SUPPLEMENT.getType().equals(exception.getType())) {
-                log.info("[onApplicationEvent] 琛ュ崱鐢宠({}) 瀹℃壒閫氳繃锛屽紑濮嬫洿鏂拌�冨嫟璁板綍", exceptionId);
-                attendanceRecordService.supplementClockIn(exception);
-            } else if (HrmAttendanceExceptionTypeEnum.OVERTIME.getType().equals(exception.getType())) {
-                log.info("[onApplicationEvent] 鍔犵彮鐢宠({}) 瀹℃壒閫氳繃锛屽紑濮嬪洖鍐欏姞鐝椂闀�", exceptionId);
-                attendanceRecordService.recordOvertime(exception);
-            }
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/HrmPerformanceAppraiseService.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/HrmPerformanceAppraiseService.java
index 8367ecb..28a9aad 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/HrmPerformanceAppraiseService.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/HrmPerformanceAppraiseService.java
@@ -9,7 +9,7 @@
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 /**
  * HRM 缁╂晥鑰冩牳鏂规 Service 鎺ュ彛
@@ -37,24 +37,31 @@
     void saveAppraiseItems(HrmPerformanceAppraiseItemSaveReqVO saveReqVO);
 
     /**
-     * 鎻愪氦缁╂晥鑰冩牳鏂规瀹℃壒
+     * 鎻愪氦缁╂晥鑰冩牳鏂规瀹℃壒锛堣崏绋� / 瀹℃牳涓嶉�氳繃 鈫� 瀹℃壒涓級
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴鎸囧畾锛屾彁浜ゆ椂鏃犻渶閫夋嫨銆�
+     *
+     * @param id 鏂规缂栧彿
      */
-    void submitAppraise(Long id, String processDefinitionKey, Long userId);
+    void submitAppraise(Long id);
 
     /**
-     * 瀹℃壒缁╂晥鑰冩牳鏂规锛堥�氳繃/椹冲洖锛宮anual锛�
+     * 鑾峰緱缁╂晥鑰冩牳鏂规鐨勫鎵逛汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳
+     *
+     * @return 瀹℃壒浜虹敤鎴风紪鍙烽泦鍚�
      */
-    void auditAppraise(HrmPerformanceAppraiseAuditReqVO auditReqVO);
+    Set<Long> getAppraiseApproverUserIds();
 
     /**
-     * 鏇存柊缁╂晥鑰冩牳鏂规瀹℃壒鐘舵�侊紙BPM 鐩戝惉鍥炶皟锛�
+     * 瀹℃牳缁╂晥鑰冩牳鏂规锛堝鎵逛腑 鈫� 瀹℃牳閫氳繃 / 瀹℃牳涓嶉�氳繃锛�
+     *
+     * 瀹℃牳閫氳繃鏃舵柟妗堢姸鎬佹祦杞负銆屽凡鍙戝竷銆嶃��
+     *
+     * @param id           鏂规缂栧彿
+     * @param pass         鏄惁閫氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛堜笉閫氳繃鏃跺繀濉級
      */
-    void updateAppraiseAuditStatus(Long id, Integer bpmResult);
-
-    /**
-     * 鑾峰緱缁╂晥鑰冩牳鏂规瀹℃壒娴佺▼瀹氫箟鍒楄〃
-     */
-    List<Map<String, Object>> getAppraiseApproveProcessDefinitionList();
+    void auditAppraise(Long id, Boolean pass, String reviewRemark);
 
     /**
      * 淇濆瓨鍛樺伐鑰冩牳缁撴灉锛堟寜鍛樺伐閫愭寚鏍囨墦鍒嗭紝鑷姩璁$畻缁煎悎寰楀垎涓庢。绾э級
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/HrmPerformanceAppraiseServiceImpl.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/HrmPerformanceAppraiseServiceImpl.java
index 69451fc..d5a5a5d 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/HrmPerformanceAppraiseServiceImpl.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/HrmPerformanceAppraiseServiceImpl.java
@@ -7,11 +7,6 @@
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.hrm.controller.admin.performanceappraise.vo.*;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.performanceappraise.*;
@@ -19,16 +14,17 @@
 import cn.iocoder.yudao.module.hrm.dal.mysql.performanceappraise.*;
 import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
 import cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.time.LocalDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -36,7 +32,6 @@
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-import static cn.iocoder.yudao.module.hrm.util.HrmAuditStatusUtils.convertBpmResultToAuditStatus;
 
 /**
  * HRM 缁╂晥鑰冩牳鏂规 Service 瀹炵幇绫�
@@ -82,9 +77,11 @@
     private static final Integer EMPLOYEE_STATUS_ACTIVE = 1;
 
     /**
-     * BPM 缁╂晥鑰冩牳瀹℃壒鍒嗙被缂栫爜
+     * 缁╂晥鑰冩牳鏂规瀹℃壒鐨勪笟鍔$被鍨嬬紪鐮�
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鎵逛汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
      */
-    private static final String APPRAISE_APPROVE_CATEGORY_CODE = "performance_appraise_approve";
+    private static final String APPRAISE_APPROVE_BIZ_TYPE = "performance_appraise_approve";
 
     @Resource
     private HrmPerformanceAppraiseMapper appraiseMapper;
@@ -97,11 +94,9 @@
     @Resource
     private HrmEmployeeMapper employeeMapper;
     @Resource
-    private BpmProcessInstanceApi bpmProcessInstanceApi;
+    private ApprovalConfigApi approvalConfigApi;
     @Resource
-    private BpmCategoryService bpmCategoryService;
-    @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private AdminUserApi adminUserApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -121,8 +116,7 @@
         HrmPerformanceAppraiseDO oldAppraise = validateAppraiseCanModify(updateReqVO.getId());
         HrmPerformanceAppraiseDO updateObj = BeanUtils.toBean(updateReqVO, HrmPerformanceAppraiseDO.class, req -> req
                 .setStatus(oldAppraise.getStatus())
-                .setAuditStatus(oldAppraise.getAuditStatus())
-                .setProcessInstanceId(oldAppraise.getProcessInstanceId()));
+                .setAuditStatus(oldAppraise.getAuditStatus()));
         updateObj.setScopeTeamIds(CollUtil.isEmpty(updateReqVO.getScopeTeamIds())
                 ? null : JSONUtil.toJsonStr(updateReqVO.getScopeTeamIds()));
         appraiseMapper.updateById(updateObj);
@@ -185,122 +179,72 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitAppraise(Long id, String processDefinitionKey, Long userId) {
-        // 1. 鏍¢獙鏂规鏄惁鍦ㄨ崏绋跨姸鎬�
+    public void submitAppraise(Long id) {
+        // 1. 鏍¢獙鏂规瀛樺湪 + 鍙彁浜ょ姸鎬侊紙鑽夌 / 瀹℃牳涓嶉�氳繃锛�
         HrmPerformanceAppraiseDO appraise = appraiseMapper.selectById(id);
         if (appraise == null) {
             throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_NOT_EXISTS);
         }
-        if (ObjUtil.notEqual(appraise.getAuditStatus(), HrmAuditStatusEnum.DRAFT.getStatus())) {
-            throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_SUBMIT_FAIL_NOT_DRAFT);
+        if (ObjUtil.notEqual(appraise.getAuditStatus(), HrmAuditStatusEnum.DRAFT.getStatus())
+                && ObjUtil.notEqual(appraise.getAuditStatus(), HrmAuditStatusEnum.REJECT.getStatus())) {
+            throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_SUBMIT_FAIL_NOT_EDITABLE);
         }
         if (CollUtil.isEmpty(itemMapper.selectListByAppraiseId(id))) {
             throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_ITEM_EMPTY);
         }
 
-        // 2. 鏍¢獙瀹℃壒鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦紝涓斾紶鍏ョ殑娴佺▼瀹氫箟澶勪簬婵�娲荤姸鎬�
-        validateAppraiseApproveCategoryAndProcessDefinition();
-        ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey);
-        if (processDefinition == null) {
-            throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
+        // 2. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鎵逛汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(APPRAISE_APPROVE_BIZ_TYPE);
 
-        // 3. 鍒涘缓瀹℃壒娴佺▼瀹炰緥
-        String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId,
-                new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(processDefinitionKey)
-                        .setBusinessKey(String.valueOf(id)));
+        // 3. 瀹℃壒鐘舵�佺疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋滐紝閬垮厤娈嬬暀銆屽鏍镐笉閫氳繃銆嶇殑鍘熷洜
+        appraiseMapper.submitAndResetAuditInfo(id, HrmAuditStatusEnum.PROCESS.getStatus());
+    }
 
-        // 4. 鏇存柊鏂规娴佺▼缂栧彿涓庡鎵圭姸鎬�
-        appraiseMapper.updateById(new HrmPerformanceAppraiseDO().setId(id).setProcessInstanceId(processInstanceId)
-                .setAuditStatus(HrmAuditStatusEnum.PROCESS.getStatus()));
+    @Override
+    public Set<Long> getAppraiseApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(APPRAISE_APPROVE_BIZ_TYPE);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void auditAppraise(HrmPerformanceAppraiseAuditReqVO auditReqVO) {
-        HrmPerformanceAppraiseDO appraise = validateAppraiseExists(auditReqVO.getId());
+    public void auditAppraise(Long id, Boolean pass, String reviewRemark) {
+        // 1. 鏍¢獙瀛樺湪
+        HrmPerformanceAppraiseDO appraise = validateAppraiseExists(id);
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
         if (ObjUtil.notEqual(appraise.getAuditStatus(), HrmAuditStatusEnum.PROCESS.getStatus())) {
-            throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS);
+            throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_AUDIT_FAIL_NOT_PROCESS);
         }
-        Integer auditStatus = auditReqVO.getAuditStatus();
-        if (!Objects.equals(auditStatus, HrmAuditStatusEnum.APPROVE.getStatus())
-                && !Objects.equals(auditStatus, HrmAuditStatusEnum.REJECT.getStatus())) {
-            throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS);
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鎵逛汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(APPRAISE_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝瀹℃壒鐘舵�佺疆涓哄鏍镐笉閫氳繃锛岄��鍥炴彁浜や汉淇敼鍚庡彲閲嶆柊鎻愪氦
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_AUDIT_REJECT_REASON_REQUIRED);
+            }
+            // 鏂规鐘舵�佷繚鎸佷笉鍙�
+            appraiseMapper.auditAppraise(id, HrmAuditStatusEnum.REJECT.getStatus(), appraise.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
+            return;
         }
-        HrmPerformanceAppraiseDO update = new HrmPerformanceAppraiseDO()
-                .setId(appraise.getId())
-                .setAuditStatus(auditStatus)
-                .setAuditUserId(getLoginUserId())
-                .setAuditTime(LocalDateTime.now());
-        if (auditReqVO.getRemark() != null) {
-            update.setAuditRemark(auditReqVO.getRemark());
-        }
-        // 瀹℃壒閫氳繃 -> 鏂规鍙戝竷
-        if (Objects.equals(auditStatus, HrmAuditStatusEnum.APPROVE.getStatus())) {
-            update.setStatus(STATUS_PUBLISHED);
-        }
-        appraiseMapper.updateById(update);
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝瀹℃壒鐘舵�佺疆涓哄鏍搁�氳繃
+        // 6. 瀹℃牳閫氳繃鍚庣疆涓氬姟閫昏緫锛氭柟妗堢姸鎬佹祦杞负銆屽凡鍙戝竷銆�
+        appraiseMapper.auditAppraise(id, HrmAuditStatusEnum.APPROVE.getStatus(), STATUS_PUBLISHED,
+                userId, getUserNickname(userId), reviewRemark);
     }
 
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void updateAppraiseAuditStatus(Long id, Integer bpmResult) {
-        // 1.1 鏍¢獙鏂规鏄惁瀛樺湪
-        HrmPerformanceAppraiseDO appraise = appraiseMapper.selectById(id);
-        if (appraise == null) {
-            throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_NOT_EXISTS);
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
         }
-        // 1.2 鍙湁瀹℃壒涓紝鍙互鏇存柊瀹℃壒缁撴灉
-        if (ObjUtil.notEqual(appraise.getAuditStatus(), HrmAuditStatusEnum.PROCESS.getStatus())) {
-            log.error("[updateAppraiseAuditStatus][appraise({}) 涓嶅浜庡鎵逛腑锛屾棤娉曟洿鏂板鎵圭粨鏋�({})]", appraise.getId(), bpmResult);
-            throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS);
-        }
-
-        // 2. 鏇存柊鏂规瀹℃壒缁撴灉
-        Integer auditStatus = convertBpmResultToAuditStatus(bpmResult);
-        HrmPerformanceAppraiseDO update = new HrmPerformanceAppraiseDO().setId(id).setAuditStatus(auditStatus);
-        if (Objects.equals(auditStatus, HrmAuditStatusEnum.APPROVE.getStatus())) {
-            update.setStatus(STATUS_PUBLISHED);
-        }
-        appraiseMapper.updateById(update);
-    }
-
-    @Override
-    public List<Map<String, Object>> getAppraiseApproveProcessDefinitionList() {
-        // 1. 鏍¢獙瀹℃壒鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-        validateAppraiseApproveCategoryAndProcessDefinition();
-
-        // 2. 鑾峰彇鍒嗙被涓嬬殑娴佺▼瀹氫箟淇℃伅
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(APPRAISE_APPROVE_CATEGORY_CODE);
-
-        // 3. 鑾峰彇娴佺▼瀹氫箟璇︽儏
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-
-        // 4. 杩囨护锛氬彧淇濈暀婵�娲荤姸鎬侊紝涓旂浉鍚� key 鍙繚鐣欐渶鏂扮増鏈�
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (ProcessDefinition pd : processDefinitions) {
-            if (pd.isSuspended()) {
-                continue;
-            }
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-
-        // 5. 杩斿洖娴佺▼瀹氫箟鍒楄〃
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            item.put("version", pd.getVersion());
-            result.add(item);
-        }
-        return result;
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
     @Override
@@ -482,32 +426,6 @@
             throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_UPDATE_FAIL_NOT_DRAFT);
         }
         return appraise;
-    }
-
-    /**
-     * 鏍¢獙 BPM 缁╂晥鑰冩牳瀹℃壒鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-     */
-    private void validateAppraiseApproveCategoryAndProcessDefinition() {
-        // 1. 鏍¢獙鍒嗙被鏄惁瀛樺湪
-        Map<String, ?> categoryMap = bpmCategoryService.getCategoryMap(Collections.singletonList(APPRAISE_APPROVE_CATEGORY_CODE));
-        if (!categoryMap.containsKey(APPRAISE_APPROVE_CATEGORY_CODE)) {
-            throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-
-        // 2. 鏍¢獙鍒嗙被涓嬫槸鍚︽湁鍙敤鐨勬祦绋嬪畾涔�
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(APPRAISE_APPROVE_CATEGORY_CODE);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-
-        // 3. 鏍¢獙鏄惁鏈夋縺娲荤姸鎬佺殑娴佺▼瀹氫箟
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-        boolean hasActiveDefinition = processDefinitions.stream().anyMatch(pd -> !pd.isSuspended());
-        if (!hasActiveDefinition) {
-            throw exception(ErrorCodeConstants.PERFORMANCE_APPRAISE_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
     }
 
 }
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/listener/HrmPerformanceAppraiseStatusListener.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/listener/HrmPerformanceAppraiseStatusListener.java
deleted file mode 100644
index 12bc056..0000000
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/performanceappraise/listener/HrmPerformanceAppraiseStatusListener.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package cn.iocoder.yudao.module.hrm.service.performanceappraise.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.hrm.dal.dataobject.performanceappraise.HrmPerformanceAppraiseDO;
-import cn.iocoder.yudao.module.hrm.dal.mysql.performanceappraise.HrmPerformanceAppraiseMapper;
-import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
-import cn.iocoder.yudao.module.hrm.service.performanceappraise.HrmPerformanceAppraiseService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-/**
- * 缁╂晥鑰冩牳鏂规瀹℃壒鐨勭粨鏋滅洃鍚櫒瀹炵幇绫�
- *
- * 閫氳繃 businessKey锛堟柟妗圛D锛夊尮閰嶏紝鑰屼笉鏄浐瀹氱殑娴佺▼瀹氫箟 Key锛�
- * 杩欐牱鍙互鏀寔鍒嗙被涓嬩换鎰� Key 鐨勬祦绋嬫ā鍨嬨��
- */
-@Component
-@Slf4j
-public class HrmPerformanceAppraiseStatusListener implements ApplicationListener<BpmProcessInstanceStatusEvent> {
-
-    @Resource
-    private HrmPerformanceAppraiseService appraiseService;
-    @Resource
-    private HrmPerformanceAppraiseMapper appraiseMapper;
-
-    @Override
-    public void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
-        // 閫氳繃 businessKey 鏌ヨ鑰冩牳鏂规
-        Long appraiseId;
-        try {
-            appraiseId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            return; // businessKey 涓嶆槸鏁板瓧锛屽拷鐣�
-        }
-
-        HrmPerformanceAppraiseDO appraise = appraiseMapper.selectById(appraiseId);
-        if (appraise == null) {
-            return; // 涓嶆槸缁╂晥鑰冩牳鏂规锛屽拷鐣�
-        }
-
-        // 鍙湁瀹℃壒涓姸鎬佺殑鏂规鎵嶅鐞�
-        if (!HrmAuditStatusEnum.PROCESS.getStatus().equals(appraise.getAuditStatus())) {
-            log.warn("[onApplicationEvent] 鑰冩牳鏂规({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵��: {}", appraiseId, appraise.getAuditStatus());
-            return;
-        }
-
-        log.info("[onApplicationEvent] 鑰冩牳鏂规({}) 瀹℃壒鐘舵�佹洿鏂�: {}", appraiseId, event.getStatus());
-        // 鏇存柊瀹℃壒鐘舵��
-        appraiseService.updateAppraiseAuditStatus(appraiseId, event.getStatus());
-    }
-
-}
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/util/HrmAuditStatusUtils.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/util/HrmAuditStatusUtils.java
deleted file mode 100644
index f48945f..0000000
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/util/HrmAuditStatusUtils.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package cn.iocoder.yudao.module.hrm.util;
-
-import cn.hutool.core.lang.Assert;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
-import cn.iocoder.yudao.module.hrm.enums.HrmAuditStatusEnum;
-
-/**
- * HRM 娴佺▼宸ュ叿绫�
- *
- * @author 瓒呯骇绠$悊鍛�
- */
-public class HrmAuditStatusUtils {
-
-    /**
-     * BPM 瀹℃壒缁撴灉杞崲
-     *
-     * @param bpmResult BPM 瀹℃壒缁撴灉
-     */
-    public static Integer convertBpmResultToAuditStatus(Integer bpmResult) {
-        Integer auditStatus = BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult) ? HrmAuditStatusEnum.APPROVE.getStatus()
-                : BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult) ? HrmAuditStatusEnum.REJECT.getStatus()
-                : BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult) ? HrmAuditStatusEnum.CANCEL.getStatus() : null;
-        Assert.notNull(auditStatus, "BPM 瀹℃壒缁撴灉({}) 杞崲澶辫触", bpmResult);
-        return auditStatus;
-    }
-
-}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/MesPdProjectController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/MesPdProjectController.java
index 45c7cb9..1ad30d1 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/MesPdProjectController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/MesPdProjectController.java
@@ -8,6 +8,7 @@
 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectAuditReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectSaveReqVO;
@@ -29,6 +30,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.stream.Stream;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
@@ -125,21 +127,27 @@
     }
 
     @PutMapping("/submit-approval")
-    @Operation(summary = "鎻愪氦璁捐椤圭洰瀹℃壒锛堝緟瀹℃牳鈫掑鎵逛腑锛�")
+    @Operation(summary = "鎻愪氦璁捐椤圭洰瀹℃壒锛堝緟瀹℃牳鈫掑鎵逛腑锛夛紝瀹℃牳浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
     @Parameter(name = "id", description = "缂栧彿", required = true)
-    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟 Key", required = true)
     @PreAuthorize("@ss.hasPermission('mes:pd-project:update')")
-    public CommonResult<Boolean> submitProjectApproval(@RequestParam("id") Long id,
-                                                       @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        projectService.submitProjectApproval(id, processDefinitionKey);
+    public CommonResult<Boolean> submitProjectApproval(@RequestParam("id") Long id) {
+        projectService.submitProjectApproval(id);
         return success(true);
     }
 
-    @GetMapping("/approve-process-list")
-    @Operation(summary = "鑾峰緱璁捐椤圭洰瀹℃壒娴佺▼鍒楄〃")
-    @PreAuthorize("@ss.hasPermission('mes:pd-project:update')")
-    public CommonResult<List<Map<String, Object>>> getProjectApproveProcessDefinitionList() {
-        return success(projectService.getProjectApproveProcessDefinitionList());
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳璁捐椤圭洰锛堝鎵逛腑鈫掑緟褰掓。/寰呭鏍革級锛屼粎瀹℃壒浜烘湰浜哄彲鎿嶄綔")
+    @PreAuthorize("@ss.hasPermission('mes:pd-project:audit')")
+    public CommonResult<Boolean> auditProject(@Valid @RequestBody MesPdProjectAuditReqVO auditReqVO) {
+        projectService.auditProject(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱璁捐椤圭洰鐨勫鏍镐汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳")
+    @PreAuthorize("@ss.hasPermission('mes:pd-project:query')")
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(projectService.getProjectApproverUserIds());
     }
 
     @PutMapping("/archive")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectAuditReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectAuditReqVO.java
new file mode 100644
index 0000000..ae4ae34
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectAuditReqVO.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 璁捐椤圭洰瀹℃牳 Request VO
+ *
+ * 瀹℃牳閫氳繃 / 涓嶉�氳繃鍏辩敤鏈� VO锛岀敱 pass 鍖哄垎锛�
+ * 閫氳繃鏃跺鏍告剰瑙侀�夊~锛屼笉閫氳繃鏃跺鏍告剰瑙侊紙涓嶉�氳繃鍘熷洜锛夊繀濉紝鐢� Service 鏍¢獙銆�
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - MES 璁捐椤圭洰瀹℃牳 Request VO")
+@Data
+public class MesPdProjectAuditReqVO {
+
+    @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "璁捐椤圭洰缂栧彿涓嶈兘涓虹┖")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃堕�夊~ / 瀹℃牳涓嶉�氳繃鏃跺繀濉紝鍗充笉閫氳繃鍘熷洜锛�", example = "璧勬枡闇�琛ュ厖瀹屾暣")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectRespVO.java
index 28a581f..8cd5b61 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectRespVO.java
@@ -66,8 +66,20 @@
     @ExcelProperty("澶囨敞")
     private String remark;
 
-    @Schema(description = "BPM 娴佺▼瀹炰緥缂栧彿")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "2")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "鏉庡伐")
+    @ExcelProperty("瀹℃牳浜�")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    @ExcelProperty("瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�", example = "璧勬枡闇�琛ュ厖瀹屾暣")
+    @ExcelProperty("瀹℃牳鎰忚")
+    private String reviewRemark;
 
     @Schema(description = "鍒涘缓鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
     @ExcelProperty("鍒涘缓鏃堕棿")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/ProductTechConfirmController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/ProductTechConfirmController.java
index 05cdfc2..a1490b0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/ProductTechConfirmController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/ProductTechConfirmController.java
@@ -6,6 +6,7 @@
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo.ProductTechConfirmAuditReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo.ProductTechConfirmPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo.ProductTechConfirmRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo.ProductTechConfirmSaveReqVO;
@@ -22,8 +23,8 @@
 import org.springframework.web.bind.annotation.*;
 
 import java.io.IOException;
-import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -53,7 +54,7 @@
     }
 
     @DeleteMapping("/delete")
-    @Operation(summary = "鍒犻櫎浜у搧鎶�鏈‘璁ゅ嚱")
+    @Operation(summary = "鍒犻櫎浜у搧鎶�鏈‘璁ゅ嚱锛堜粎鑽夌 / 瀹℃牳涓嶉�氳繃鐘舵�佸彲鍒犻櫎锛�")
     @Parameter(name = "id", description = "缂栧彿", required = true)
     @PreAuthorize("@ss.hasPermission('mes:pd-tech-confirm:delete')")
     public CommonResult<Boolean> deleteTechConfirm(@RequestParam("id") Long id) {
@@ -61,6 +62,41 @@
         return success(true);
     }
 
+    @PutMapping("/submit-approval")
+    @Operation(summary = "鎻愪氦鎶�鏈‘璁ゅ嚱瀹℃牳锛堣崏绋�/瀹℃牳涓嶉�氳繃鈫掑緟瀹℃牳锛夛紝瀹℃牳浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
+    @Parameter(name = "id", description = "缂栧彿", required = true)
+    @PreAuthorize("@ss.hasPermission('mes:pd-tech-confirm:update')")
+    public CommonResult<Boolean> submitTechConfirmAudit(@RequestParam("id") Long id) {
+        techConfirmService.submitTechConfirmAudit(id);
+        return success(true);
+    }
+
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳鎶�鏈‘璁ゅ嚱锛堝緟瀹℃牳鈫掑凡瀹℃牳/瀹℃牳涓嶉�氳繃锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('mes:pd-tech-confirm:audit')")
+    public CommonResult<Boolean> auditTechConfirm(@Valid @RequestBody ProductTechConfirmAuditReqVO auditReqVO) {
+        techConfirmService.auditTechConfirm(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱鎶�鏈‘璁ゅ嚱鐨勫鏍镐汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳")
+    @PreAuthorize("@ss.hasPermission('mes:pd-tech-confirm:query')")
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(techConfirmService.getTechConfirmApproverUserIds());
+    }
+
+    @PutMapping("/customer-confirm")
+    @Operation(summary = "瀹㈡埛纭锛堝凡瀹℃牳鈫掑鎴峰凡纭锛�")
+    @Parameter(name = "id", description = "缂栧彿", required = true)
+    @Parameter(name = "customerConfirmUser", description = "瀹㈡埛纭浜哄鍚�", required = true)
+    @PreAuthorize("@ss.hasPermission('mes:pd-tech-confirm:update')")
+    public CommonResult<Boolean> confirmTechConfirmByCustomer(@RequestParam("id") Long id,
+                                                              @RequestParam("customerConfirmUser") String customerConfirmUser) {
+        techConfirmService.confirmTechConfirmByCustomer(id, customerConfirmUser);
+        return success(true);
+    }
+
     @GetMapping("/get")
     @Operation(summary = "鑾峰緱浜у搧鎶�鏈‘璁ゅ嚱")
     @Parameter(name = "id", description = "缂栧彿", required = true, example = "1024")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmAuditReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmAuditReqVO.java
new file mode 100644
index 0000000..a569c84
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmAuditReqVO.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 浜у搧鎶�鏈‘璁ゅ嚱瀹℃牳 Request VO
+ *
+ * 瀹℃牳閫氳繃 / 涓嶉�氳繃鍏辩敤鏈� VO锛岀敱 pass 鍖哄垎锛�
+ * 閫氳繃鏃跺鏍告剰瑙侀�夊~锛屼笉閫氳繃鏃跺鏍告剰瑙侊紙涓嶉�氳繃鍘熷洜锛夊繀濉紝鐢� Service 鏍¢獙銆�
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - 浜у搧鎶�鏈‘璁ゅ嚱瀹℃牳 Request VO")
+@Data
+public class ProductTechConfirmAuditReqVO {
+
+    @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "鎶�鏈‘璁ゅ嚱缂栧彿涓嶈兘涓虹┖")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃堕�夊~ / 瀹℃牳涓嶉�氳繃鏃跺繀濉紝鍗充笉閫氳繃鍘熷洜锛�", example = "鍙傛暟闇�涓庡鎴峰啀娆℃牳瀵�")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmRespVO.java
index 12281cd..3c1c376 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmRespVO.java
@@ -57,7 +57,7 @@
     @ExcelProperty("缂栧埗鏃堕棿")
     private LocalDateTime draftTime;
 
-    @Schema(description = "瀹℃牳浜篒D", example = "2")
+    @Schema(description = "瀹℃牳浜篒D锛堟彁浜ゅ鏍告椂鐢辩紪鍒朵汉鎸囧畾锛�", example = "2")
     private Long reviewerId;
 
     @Schema(description = "瀹℃牳浜哄鍚�", example = "鏉庡伐")
@@ -68,6 +68,10 @@
     @ExcelProperty("瀹℃牳鏃堕棿")
     private LocalDateTime reviewTime;
 
+    @Schema(description = "瀹℃牳鎰忚锛堝鎵归�氳繃鏃剁殑鎰忚 / 椹冲洖鏃剁殑鍘熷洜锛�", example = "鍙傛暟闇�涓庡鎴峰啀娆℃牳瀵�")
+    @ExcelProperty("瀹℃牳鎰忚")
+    private String reviewRemark;
+
     @Schema(description = "瀹㈡埛纭浜�", example = "鐜嬬粡鐞�")
     @ExcelProperty("瀹㈡埛纭浜�")
     private String customerConfirmUser;
@@ -76,7 +80,7 @@
     @ExcelProperty("瀹㈡埛纭鏃堕棿")
     private LocalDateTime customerConfirmTime;
 
-    @Schema(description = "鐘舵�侊紙0=鑽夌锛�1=寰呭鏍革紝2=宸插鏍革紝3=瀹㈡埛宸茬‘璁わ級", example = "0")
+    @Schema(description = "鐘舵�侊紙0=鑽夌锛�1=寰呭鏍革紝2=宸插鏍革紝3=瀹㈡埛宸茬‘璁わ紝4=瀹℃牳涓嶉�氳繃锛�", example = "0")
     @ExcelProperty(value = "鐘舵��", converter = DictConvert.class)
     @DictFormat(DictTypeConstants.PRODUCT_TECH_CONFIRM_STATUS)
     private Integer status;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmSaveReqVO.java
index 2891aaa..7c58938 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmSaveReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/techconfirm/vo/ProductTechConfirmSaveReqVO.java
@@ -3,13 +3,26 @@
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
-import java.time.LocalDateTime;
-
+/**
+ * 浜у搧鎶�鏈‘璁ゅ嚱鏂板/淇敼 Request VO
+ *
+ * 娉ㄦ剰锛氭湰 VO 鍙壙杞界敤鎴峰彲濉啓鐨勪笟鍔″瓧娈点��
+ * 鐘舵�併�佺紪鍒朵汉/缂栧埗鏃堕棿銆佸鏍镐汉/瀹℃牳鏃堕棿銆佸鎴风‘璁や汉/瀹㈡埛纭鏃堕棿鍧囩敱涓氬姟娴佺▼椹卞姩锛�
+ * 涓嶆帴鍙楀墠绔紶鍙傦紝鍥犳涓嶅湪鏈� VO 涓畾涔夛細
+ * <ul>
+ *     <li>鐘舵�侊細鍒涘缓鏃跺浐瀹氫负鑽夌锛岀敱鎻愪氦瀹℃壒銆丅PM 瀹℃壒鍥炶皟銆佸鎴风‘璁ら�愭鎺ㄨ繘</li>
+ *     <li>缂栧埗浜�/缂栧埗鏃堕棿锛氬垱寤烘椂鍙栧綋鍓嶇櫥褰曠敤鎴蜂笌褰撳墠鏃堕棿</li>
+ *     <li>瀹℃牳浜�/瀹℃牳鏃堕棿锛欱PM 瀹℃壒缁撴潫鏃跺彇瀹℃壒浜哄啓鍏�</li>
+ *     <li>瀹㈡埛纭浜�/瀹㈡埛纭鏃堕棿锛氬鎴风‘璁ゆ椂鍙栧綋鍓嶇櫥褰曠敤鎴蜂笌褰撳墠鏃堕棿</li>
+ * </ul>
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
 @Schema(description = "绠$悊鍚庡彴 - 浜у搧鎶�鏈‘璁ゅ嚱鏂板/淇敼 Request VO")
 @Data
 public class ProductTechConfirmSaveReqVO {
 
-    @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1024")
+    @Schema(description = "缂栧彿锛堟柊澧炴椂涓虹┖锛屼慨鏀规椂蹇呭~锛�", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "1024")
     private Long id;
 
     @Schema(description = "纭鍑界紪鍙�", requiredMode = Schema.RequiredMode.REQUIRED, example = "TC20260801001")
@@ -32,33 +45,6 @@
 
     @Schema(description = "妯℃澘绫诲瀷锛堝ゥ鍦板埄/鏃ユ湰/閫氱敤锛�", example = "general")
     private String templateType;
-
-    @Schema(description = "缂栧埗浜篒D", example = "1")
-    private Long drafterId;
-
-    @Schema(description = "缂栧埗浜哄鍚�", example = "鑳′笢")
-    private String drafterName;
-
-    @Schema(description = "缂栧埗鏃堕棿")
-    private LocalDateTime draftTime;
-
-    @Schema(description = "瀹℃牳浜篒D", example = "2")
-    private Long reviewerId;
-
-    @Schema(description = "瀹℃牳浜哄鍚�", example = "鏉庡伐")
-    private String reviewerName;
-
-    @Schema(description = "瀹℃牳鏃堕棿")
-    private LocalDateTime reviewTime;
-
-    @Schema(description = "瀹㈡埛纭浜�", example = "鐜嬬粡鐞�")
-    private String customerConfirmUser;
-
-    @Schema(description = "瀹㈡埛纭鏃堕棿")
-    private LocalDateTime customerConfirmTime;
-
-    @Schema(description = "鐘舵�侊紙0=鑽夌锛�1=寰呭鏍革紝2=宸插鏍革紝3=瀹㈡埛宸茬‘璁わ級", example = "0")
-    private Integer status;
 
     @Schema(description = "澶囨敞", example = "娴嬭瘯澶囨敞")
     private String remark;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/MesWmEquipmentReceiptController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/MesWmEquipmentReceiptController.java
index d9cab39..a8addf4 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/MesWmEquipmentReceiptController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/MesWmEquipmentReceiptController.java
@@ -15,8 +15,7 @@
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
@@ -68,19 +67,26 @@
     }
 
     @PutMapping("/submit-approval")
-    @Operation(summary = "鎻愪氦璁惧鍏ュ簱鍗曞鎵�")
+    @Operation(summary = "鎻愪氦璁惧鍏ュ簱鍗曞鎵癸紙鑽夌鈫掑鎵逛腑锛夛紝瀹℃牳浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
     @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:submit')")
-    public CommonResult<Boolean> submitApproval(@RequestParam("id") Long id,
-                                                  @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        equipmentReceiptService.submitEquipmentReceiptApproval(id, processDefinitionKey);
+    public CommonResult<Boolean> submitApproval(@RequestParam("id") Long id) {
+        equipmentReceiptService.submitEquipmentReceiptApproval(id);
         return success(true);
     }
 
-    @GetMapping("/approval-process-list")
-    @Operation(summary = "鑾峰緱璁惧鍏ュ簱瀹℃壒娴佺▼瀹氫箟鍒楄〃")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳璁惧鍏ュ簱鍗曪紙瀹℃壒涓啋宸插鎵�/鑽夌锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:audit')")
+    public CommonResult<Boolean> audit(@Valid @RequestBody MesWmEquipmentReceiptAuditReqVO auditReqVO) {
+        equipmentReceiptService.auditEquipmentReceipt(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱璁惧鍏ュ簱鍗曠殑瀹℃牳浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
     @PreAuthorize("@ss.hasPermission('mes:wm:equipment-receipt:query')")
-    public CommonResult<List<Map<String, Object>>> approvalProcessList() {
-        return success(equipmentReceiptService.getEquipmentReceiptApprovalProcessDefinitionList());
+    public CommonResult<Set<Long>> approverIds() {
+        return success(equipmentReceiptService.getEquipmentReceiptApproverUserIds());
     }
 
     @PutMapping("/finish")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/vo/MesWmEquipmentReceiptAuditReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/vo/MesWmEquipmentReceiptAuditReqVO.java
new file mode 100644
index 0000000..a64ec4b
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/vo/MesWmEquipmentReceiptAuditReqVO.java
@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 璁惧鍏ュ簱鍗曞鏍� Request VO
+ *
+ * 瀹℃牳閫氳繃 / 涓嶉�氳繃鍏辩敤鏈� VO锛岀敱 pass 鍖哄垎锛�
+ * 閫氳繃鏃跺鏍告剰瑙侀�夊~锛屼笉閫氳繃鏃跺鏍告剰瑙侊紙涓嶉�氳繃鍘熷洜锛夊繀濉紝鐢� Service 鏍¢獙銆�
+ */
+@Schema(description = "绠$悊鍚庡彴 - MES 璁惧鍏ュ簱鍗曞鏍� Request VO")
+@Data
+public class MesWmEquipmentReceiptAuditReqVO {
+
+    @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "璁惧鍏ュ簱鍗曠紪鍙蜂笉鑳戒负绌�")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃堕�夊~ / 瀹℃牳涓嶉�氳繃鏃跺繀濉紝鍗充笉閫氳繃鍘熷洜锛�", example = "鏁伴噺闇�鍐嶆鏍稿")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/vo/MesWmEquipmentReceiptRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/vo/MesWmEquipmentReceiptRespVO.java
index 9fbbf11..1e8c855 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/vo/MesWmEquipmentReceiptRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/equipmentreceipt/vo/MesWmEquipmentReceiptRespVO.java
@@ -29,8 +29,17 @@
     @Schema(description = "鐘舵��", example = "0")
     private Integer status;
 
-    @Schema(description = "BPM 娴佺▼瀹炰緥缂栧彿")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "2")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "鏉庡伐")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�", example = "鏁伴噺闇�鍐嶆鏍稿")
+    private String reviewRemark;
 
     @Schema(description = "澶囨敞", example = "澶囨敞淇℃伅")
     private String remark;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptController.java
index 08be571..0ccdb11 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptController.java
@@ -8,6 +8,7 @@
 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptAuditReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptSaveReqVO;
@@ -33,6 +34,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -111,12 +113,27 @@
     }
 
     @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦閲囪喘鍏ュ簱鍗�")
+    @Operation(summary = "鎻愪氦閲囪喘鍏ュ簱鍗曞鎵癸紙鑽夌鈫掑緟涓婃灦锛夛紝瀹℃牳浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
     @Parameter(name = "id", description = "缂栧彿", required = true)
     @PreAuthorize("@ss.hasPermission('mes:wm-item-receipt:update')")
     public CommonResult<Boolean> submitItemReceipt(@RequestParam("id") Long id) {
         itemReceiptService.submitItemReceipt(id);
         return success(true);
+    }
+
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳閲囪喘鍏ュ簱鍗曪紙寰呬笂鏋垛啋寰呮墽琛屽叆搴�/鑽夌锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('mes:wm-item-receipt:audit')")
+    public CommonResult<Boolean> auditItemReceipt(@Valid @RequestBody MesWmItemReceiptAuditReqVO auditReqVO) {
+        itemReceiptService.auditItemReceipt(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱閲囪喘鍏ュ簱鍗曠殑瀹℃牳浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
+    @PreAuthorize("@ss.hasPermission('mes:wm-item-receipt:query')")
+    public CommonResult<Set<Long>> approverIds() {
+        return success(itemReceiptService.getItemReceiptApproverUserIds());
     }
 
     @PutMapping("/stock")
@@ -152,17 +169,6 @@
     @PreAuthorize("@ss.hasPermission('mes:wm-item-receipt:create')")
     public CommonResult<Long> generateFromArrivalNotice(@RequestParam("arrivalNoticeId") Long arrivalNoticeId) {
         return success(itemReceiptService.generateItemReceiptFromArrivalNotice(arrivalNoticeId));
-    }
-
-    @PutMapping("/submit-approval")
-    @Operation(summary = "鎻愪氦閲囪喘鍏ュ簱鍗曞鎵�")
-    @Parameter(name = "id", description = "鍏ュ簱鍗曠紪鍙�", required = true)
-    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟 Key", required = true)
-    @PreAuthorize("@ss.hasPermission('mes:wm-item-receipt:update')")
-    public CommonResult<Boolean> submitApproval(@RequestParam("id") Long id,
-                                                 @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        itemReceiptService.submitItemReceiptApproval(id, processDefinitionKey);
-        return success(true);
     }
 
     // ==================== 鎷兼帴 VO ====================
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptAuditReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptAuditReqVO.java
new file mode 100644
index 0000000..7b7f0b5
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptAuditReqVO.java
@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 閲囪喘鍏ュ簱鍗曞鏍� Request VO
+ *
+ * 瀹℃牳閫氳繃 / 涓嶉�氳繃鍏辩敤鏈� VO锛岀敱 pass 鍖哄垎锛�
+ * 閫氳繃鏃跺鏍告剰瑙侀�夊~锛屼笉閫氳繃鏃跺鏍告剰瑙侊紙涓嶉�氳繃鍘熷洜锛夊繀濉紝鐢� Service 鏍¢獙銆�
+ */
+@Schema(description = "绠$悊鍚庡彴 - MES 閲囪喘鍏ュ簱鍗曞鏍� Request VO")
+@Data
+public class MesWmItemReceiptAuditReqVO {
+
+    @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "閲囪喘鍏ュ簱鍗曠紪鍙蜂笉鑳戒负绌�")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃堕�夊~ / 瀹℃牳涓嶉�氳繃鏃跺繀濉紝鍗充笉閫氳繃鍘熷洜锛�", example = "鏁伴噺闇�鍐嶆鏍稿")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptRespVO.java
index f5437af..a1d393f 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/MesWmItemReceiptRespVO.java
@@ -57,8 +57,17 @@
     @ExcelProperty("鐘舵��")
     private Integer status;
 
-    @Schema(description = "BPM 娴佺▼瀹炰緥缂栧彿", example = "xxx")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "2")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "鏉庡伐")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�", example = "鏁伴噺闇�鍐嶆鏍稿")
+    private String reviewRemark;
 
     @Schema(description = "澶囨敞", example = "澶囨敞")
     @ExcelProperty("澶囨敞")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/MesWmMiscIssueController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/MesWmMiscIssueController.java
index a5b1ed9..3c8e1b0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/MesWmMiscIssueController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/MesWmMiscIssueController.java
@@ -7,6 +7,7 @@
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.miscissue.vo.MesWmMiscIssueAuditReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.miscissue.vo.MesWmMiscIssuePageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.miscissue.vo.MesWmMiscIssueRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.miscissue.vo.MesWmMiscIssueSaveReqVO;
@@ -25,6 +26,7 @@
 import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -96,21 +98,27 @@
     }
 
     @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦鏉傞」鍑哄簱鍗曞鎵�")
+    @Operation(summary = "鎻愪氦鏉傞」鍑哄簱鍗曞鎵癸紙鑽夌鈫掑鎵逛腑锛夛紝瀹℃牳浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
     @Parameter(name = "id", description = "缂栧彿", required = true)
-    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟 Key", required = true)
     @PreAuthorize("@ss.hasPermission('mes:wm-misc-issue:update')")
-    public CommonResult<Boolean> submitMiscIssue(@RequestParam("id") Long id,
-                                                  @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        miscIssueService.submitMiscIssueApproval(id, processDefinitionKey);
+    public CommonResult<Boolean> submitMiscIssue(@RequestParam("id") Long id) {
+        miscIssueService.submitMiscIssueApproval(id);
         return success(true);
     }
 
-    @GetMapping("/approval-process-list")
-    @Operation(summary = "鑾峰緱鏉傞」鍑哄簱瀹℃壒娴佺▼瀹氫箟鍒楄〃")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳鏉傞」鍑哄簱鍗曪紙瀹℃壒涓啋寰呮墽琛屽嚭搴�/鑽夌锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('mes:wm-misc-issue:audit')")
+    public CommonResult<Boolean> auditMiscIssue(@Valid @RequestBody MesWmMiscIssueAuditReqVO auditReqVO) {
+        miscIssueService.auditMiscIssue(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱鏉傞」鍑哄簱鍗曠殑瀹℃牳浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
     @PreAuthorize("@ss.hasPermission('mes:wm-misc-issue:query')")
-    public CommonResult<List<java.util.Map<String, Object>>> getApprovalProcessList() {
-        return success(miscIssueService.getMiscIssueApprovalProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(miscIssueService.getMiscIssueApproverUserIds());
     }
 
     @PutMapping("/finish")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueAuditReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueAuditReqVO.java
new file mode 100644
index 0000000..a38176f
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueAuditReqVO.java
@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.mes.controller.admin.wm.miscissue.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 鏉傞」鍑哄簱鍗曞鏍� Request VO
+ *
+ * 瀹℃牳閫氳繃 / 涓嶉�氳繃鍏辩敤鏈� VO锛岀敱 pass 鍖哄垎锛�
+ * 閫氳繃鏃跺鏍告剰瑙侀�夊~锛屼笉閫氳繃鏃跺鏍告剰瑙侊紙涓嶉�氳繃鍘熷洜锛夊繀濉紝鐢� Service 鏍¢獙銆�
+ */
+@Schema(description = "绠$悊鍚庡彴 - 鏉傞」鍑哄簱鍗曞鏍� Request VO")
+@Data
+public class MesWmMiscIssueAuditReqVO {
+
+    @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "鏉傞」鍑哄簱鍗曠紪鍙蜂笉鑳戒负绌�")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃堕�夊~ / 瀹℃牳涓嶉�氳繃鏃跺繀濉紝鍗充笉閫氳繃鍘熷洜锛�", example = "鍑哄簱鏁伴噺闇�鍐嶆鏍稿")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueRespVO.java
index 9eeea53..565868d 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueRespVO.java
@@ -35,8 +35,17 @@
     @Schema(description = "鐘舵��", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
     private Integer status;
 
-    @Schema(description = "BPM 娴佺▼瀹炰緥缂栧彿", example = "xxx")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "1")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "寮犱笁")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堥�氳繃鏃剁殑鎰忚 / 涓嶉�氳繃鏃剁殑鍘熷洜锛�", example = "鍑哄簱鏁伴噺闇�鍐嶆鏍稿")
+    private String reviewRemark;
 
     @Schema(description = "澶囨敞", example = "澶囨敞")
     private String remark;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/MesWmMiscReceiptController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/MesWmMiscReceiptController.java
index 88ea25b..40c8f34 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/MesWmMiscReceiptController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/MesWmMiscReceiptController.java
@@ -5,6 +5,7 @@
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.miscreceipt.vo.MesWmMiscReceiptAuditReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.miscreceipt.vo.MesWmMiscReceiptPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.miscreceipt.vo.MesWmMiscReceiptRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.miscreceipt.vo.MesWmMiscReceiptSaveReqVO;
@@ -22,6 +23,7 @@
 
 import java.io.IOException;
 import java.util.List;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -77,21 +79,27 @@
     }
 
     @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦鏉傞」鍏ュ簱鍗曞鎵�")
+    @Operation(summary = "鎻愪氦鏉傞」鍏ュ簱鍗曞鎵癸紙鑽夌鈫掑鎵逛腑锛夛紝瀹℃牳浜虹敱瀹℃壒閰嶇疆缁熶竴鎸囧畾")
     @Parameter(name = "id", description = "缂栧彿", required = true)
-    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟 Key", required = true)
     @PreAuthorize("@ss.hasPermission('mes:wm:misc-receipt:submit')")
-    public CommonResult<Boolean> submitMiscReceipt(@RequestParam("id") Long id,
-                                                    @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        miscReceiptService.submitMiscReceiptApproval(id, processDefinitionKey);
+    public CommonResult<Boolean> submitMiscReceipt(@RequestParam("id") Long id) {
+        miscReceiptService.submitMiscReceiptApproval(id);
         return success(true);
     }
 
-    @GetMapping("/approval-process-list")
-    @Operation(summary = "鑾峰緱鏉傞」鍏ュ簱瀹℃壒娴佺▼瀹氫箟鍒楄〃")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳鏉傞」鍏ュ簱鍗曪紙瀹℃壒涓啋宸插鎵�/鑽夌锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('mes:wm:misc-receipt:audit')")
+    public CommonResult<Boolean> auditMiscReceipt(@Valid @RequestBody MesWmMiscReceiptAuditReqVO auditReqVO) {
+        miscReceiptService.auditMiscReceipt(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱鏉傞」鍏ュ簱鍗曠殑瀹℃牳浜虹紪鍙烽泦鍚堬紝渚涘墠绔垽鏂槸鍚﹀睍绀哄鏍告寜閽�")
     @PreAuthorize("@ss.hasPermission('mes:wm:misc-receipt:query')")
-    public CommonResult<List<java.util.Map<String, Object>>> getApprovalProcessList() {
-        return success(miscReceiptService.getMiscReceiptApprovalProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(miscReceiptService.getMiscReceiptApproverUserIds());
     }
 
     @PutMapping("/finish")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptAuditReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptAuditReqVO.java
new file mode 100644
index 0000000..76aa5dd
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptAuditReqVO.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.mes.controller.admin.wm.miscreceipt.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 鏉傞」鍏ュ簱鍗曞鏍� Request VO
+ *
+ * 瀹℃牳閫氳繃 / 涓嶉�氳繃鍏辩敤鏈� VO锛岀敱 pass 鍖哄垎锛�
+ * 閫氳繃鏃跺鏍告剰瑙侀�夊~锛屼笉閫氳繃鏃跺鏍告剰瑙侊紙涓嶉�氳繃鍘熷洜锛夊繀濉紝鐢� Service 鏍¢獙銆�
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - 鏉傞」鍏ュ簱鍗曞鏍� Request VO")
+@Data
+public class MesWmMiscReceiptAuditReqVO {
+
+    @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "鏉傞」鍏ュ簱鍗曠紪鍙蜂笉鑳戒负绌�")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃堕�夊~ / 瀹℃牳涓嶉�氳繃鏃跺繀濉紝鍗充笉閫氳繃鍘熷洜锛�", example = "鍏ュ簱鏁伴噺闇�鍐嶆鏍稿")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptRespVO.java
index 2fa6c34..4991cd9 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptRespVO.java
@@ -35,8 +35,17 @@
     @Schema(description = "鐘舵��", example = "0")
     private Integer status;
 
-    @Schema(description = "BPM 娴佺▼瀹炰緥缂栧彿", example = "xxx")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "1")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "寮犱笁")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堥�氳繃鏃剁殑鎰忚 / 涓嶉�氳繃鏃剁殑鍘熷洜锛�", example = "鍏ュ簱鏁伴噺闇�鍐嶆鏍稿")
+    private String reviewRemark;
 
     @Schema(description = "澶囨敞", example = "澶囨敞")
     private String remark;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorController.java
index 3642e16..dbbce88 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorController.java
@@ -8,6 +8,7 @@
 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorAuditReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorSaveReqVO;
@@ -29,6 +30,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -103,21 +105,27 @@
     }
 
     @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦渚涘簲鍟嗛��璐у崟瀹℃壒")
+    @Operation(summary = "鎻愪氦渚涘簲鍟嗛��璐у崟瀹℃壒锛堣崏绋库啋寰呮嫞璐э級锛屽鏍镐汉鐢卞鎵归厤缃粺涓�鎸囧畾")
     @Parameter(name = "id", description = "缂栧彿", required = true)
-    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟 Key", required = true)
     @PreAuthorize("@ss.hasPermission('mes:wm-return-vendor:update')")
-    public CommonResult<Boolean> submitReturnVendor(@RequestParam("id") Long id,
-                                                     @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        returnVendorService.submitReturnVendorApproval(id, processDefinitionKey);
+    public CommonResult<Boolean> submitReturnVendor(@RequestParam("id") Long id) {
+        returnVendorService.submitReturnVendorApproval(id);
         return success(true);
     }
 
-    @GetMapping("/approval-process-list")
-    @Operation(summary = "鑾峰緱渚涘簲鍟嗛��璐у鎵规祦绋嬪畾涔夊垪琛�")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳渚涘簲鍟嗛��璐у崟锛堝緟鎷h揣鈫掑緟鎵ц閫�璐�/鑽夌锛夛紝浠呭鎵逛汉鏈汉鍙搷浣�")
+    @PreAuthorize("@ss.hasPermission('mes:wm-return-vendor:audit')")
+    public CommonResult<Boolean> auditReturnVendor(@Valid @RequestBody MesWmReturnVendorAuditReqVO auditReqVO) {
+        returnVendorService.auditReturnVendor(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱渚涘簲鍟嗛��璐у崟鐨勫鏍镐汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳")
     @PreAuthorize("@ss.hasPermission('mes:wm-return-vendor:query')")
-    public CommonResult<List<java.util.Map<String, Object>>> getApprovalProcessList() {
-        return success(returnVendorService.getReturnVendorApprovalProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(returnVendorService.getReturnVendorApproverUserIds());
     }
 
     @PutMapping("/stock")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorAuditReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorAuditReqVO.java
new file mode 100644
index 0000000..7d36770
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorAuditReqVO.java
@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 渚涘簲鍟嗛��璐у崟瀹℃牳 Request VO
+ *
+ * 瀹℃牳閫氳繃 / 涓嶉�氳繃鍏辩敤鏈� VO锛岀敱 pass 鍖哄垎锛�
+ * 閫氳繃鏃跺鏍告剰瑙侀�夊~锛屼笉閫氳繃鏃跺鏍告剰瑙侊紙涓嶉�氳繃鍘熷洜锛夊繀濉紝鐢� Service 鏍¢獙銆�
+ */
+@Schema(description = "绠$悊鍚庡彴 - 渚涘簲鍟嗛��璐у崟瀹℃牳 Request VO")
+@Data
+public class MesWmReturnVendorAuditReqVO {
+
+    @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "渚涘簲鍟嗛��璐у崟缂栧彿涓嶈兘涓虹┖")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃堕�夊~ / 瀹℃牳涓嶉�氳繃鏃跺繀濉紝鍗充笉閫氳繃鍘熷洜锛�", example = "閫�璐ф暟閲忛渶鍐嶆鏍稿")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorRespVO.java
index 5af5624..f18f995 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorRespVO.java
@@ -48,8 +48,17 @@
     @Schema(description = "鐘舵��", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
     private Integer status;
 
-    @Schema(description = "BPM 娴佺▼瀹炰緥缂栧彿", example = "xxx")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "1")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "寮犱笁")
+    private String reviewerName;
+
+    @Schema(description = "瀹℃牳鏃堕棿")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堥�氳繃鏃剁殑鎰忚 / 涓嶉�氳繃鏃剁殑鍘熷洜锛�", example = "閫�璐ф暟閲忛渶鍐嶆鏍稿")
+    private String reviewRemark;
 
     @Schema(description = "澶囨敞", example = "澶囨敞")
     private String remark;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/MesWmStockTakingTaskController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/MesWmStockTakingTaskController.java
index 12f3008..90b1051 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/MesWmStockTakingTaskController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/MesWmStockTakingTaskController.java
@@ -29,6 +29,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -114,21 +115,27 @@
     }
 
     @PutMapping("/submit-approval")
-    @Operation(summary = "鎻愪氦鐩樼偣缁撴灉瀹℃壒")
+    @Operation(summary = "鎻愪氦鐩樼偣缁撴灉瀹℃壒锛堢洏鐐逛腑鈫掔洏鐐逛腑路缁撴灉瀹℃壒涓級锛屽鏍镐汉鐢卞鎵归厤缃粺涓�鎸囧畾")
     @Parameter(name = "id", description = "缂栧彿", required = true)
-    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟 Key", required = true)
     @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:update')")
-    public CommonResult<Boolean> submitStockTakingTaskResultApproval(@RequestParam("id") Long id,
-                                                                     @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        stockTakingTaskService.submitStockTakingResultApproval(id, processDefinitionKey);
+    public CommonResult<Boolean> submitStockTakingTaskResultApproval(@RequestParam("id") Long id) {
+        stockTakingTaskService.submitStockTakingResultApproval(id);
         return success(true);
     }
 
-    @GetMapping("/approval-process-list")
-    @Operation(summary = "鑾峰緱鐩樼偣缁撴灉瀹℃壒娴佺▼瀹氫箟鍒楄〃")
+    @PutMapping("/audit")
+    @Operation(summary = "瀹℃牳鐩樼偣缁撴灉锛堢粨鏋滃鎵逛腑鈫掑凡瀹屾垚/鐩樼偣涓級锛屼粎瀹℃壒浜烘湰浜哄彲鎿嶄綔")
+    @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:audit')")
+    public CommonResult<Boolean> auditStockTakingTaskResult(@Valid @RequestBody MesWmStockTakingTaskAuditReqVO auditReqVO) {
+        stockTakingTaskService.auditStockTakingResult(auditReqVO.getId(), auditReqVO.getPass(), auditReqVO.getReviewRemark());
+        return success(true);
+    }
+
+    @GetMapping("/approver-ids")
+    @Operation(summary = "鑾峰緱鐩樼偣缁撴灉瀹℃壒鐨勫鏍镐汉缂栧彿闆嗗悎锛屼緵鍓嶇鍒ゆ柇鏄惁灞曠ず瀹℃牳鎸夐挳")
     @PreAuthorize("@ss.hasPermission('mes:wm-stock-taking-task:query')")
-    public CommonResult<List<Map<String, Object>>> getStockTakingTaskResultApprovalProcessDefinitionList() {
-        return success(stockTakingTaskService.getStockTakingTaskResultApprovalProcessDefinitionList());
+    public CommonResult<Set<Long>> getApproverUserIds() {
+        return success(stockTakingTaskService.getStockTakingTaskApproverUserIds());
     }
 
     @PutMapping("/cancel")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/vo/MesWmStockTakingTaskAuditReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/vo/MesWmStockTakingTaskAuditReqVO.java
new file mode 100644
index 0000000..8f103db
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/vo/MesWmStockTakingTaskAuditReqVO.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * 鐩樼偣缁撴灉瀹℃牳 Request VO
+ *
+ * 瀹℃牳閫氳繃 / 涓嶉�氳繃鍏辩敤鏈� VO锛岀敱 pass 鍖哄垎锛�
+ * 閫氳繃鏃跺鏍告剰瑙侀�夊~锛屼笉閫氳繃鏃跺鏍告剰瑙侊紙涓嶉�氳繃鍘熷洜锛夊繀濉紝鐢� Service 鏍¢獙銆�
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Schema(description = "绠$悊鍚庡彴 - 鐩樼偣缁撴灉瀹℃牳 Request VO")
+@Data
+public class MesWmStockTakingTaskAuditReqVO {
+
+    @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "鐩樼偣浠诲姟缂栧彿涓嶈兘涓虹┖")
+    private Long id;
+
+    @Schema(description = "鏄惁閫氳繃锛歵rue=瀹℃牳閫氳繃 / false=瀹℃牳涓嶉�氳繃", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @NotNull(message = "璇烽�夋嫨瀹℃牳缁撴灉")
+    private Boolean pass;
+
+    @Schema(description = "瀹℃牳鎰忚锛堝鏍搁�氳繃鏃堕�夊~ / 瀹℃牳涓嶉�氳繃鏃跺繀濉紝鍗充笉閫氳繃鍘熷洜锛�", example = "鐩樹簭宸紓闇�闄勮鏄�")
+    private String reviewRemark;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/vo/MesWmStockTakingTaskRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/vo/MesWmStockTakingTaskRespVO.java
index ab9c6a0..73d093c 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/vo/MesWmStockTakingTaskRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/stocktaking/task/vo/MesWmStockTakingTaskRespVO.java
@@ -70,8 +70,17 @@
     @ExcelProperty("鐘舵��")
     private Integer status;
 
-    @Schema(description = "BPM 娴佺▼瀹炰緥缂栧彿锛岄潪绌鸿〃绀虹洏鐐圭粨鏋滃凡鎻愪氦瀹℃壒", example = "xxx")
-    private String processInstanceId;
+    @Schema(description = "瀹℃牳浜虹敤鎴风紪鍙�", example = "1")
+    private Long reviewerId;
+
+    @Schema(description = "瀹℃牳浜哄鍚�", example = "寮犱笁")
+    private String reviewerName;
+
+    @Schema(description = "缁撴灉瀹℃壒鎻愪氦鏃堕棿 / 瀹℃牳鏃堕棿", example = "2026-09-16 10:00:00")
+    private LocalDateTime reviewTime;
+
+    @Schema(description = "瀹℃牳鎰忚锛堥�氳繃鏃剁殑鎰忚 / 涓嶉�氳繃鏃剁殑鍘熷洜锛�", example = "鐩樹簭宸紓闇�闄勮鏄�")
+    private String reviewRemark;
 
     @Schema(description = "澶囨敞", example = "澶囨敞")
     @ExcelProperty("澶囨敞")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/project/MesPdProjectDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/project/MesPdProjectDO.java
index bbfd926..c65ea3d 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/project/MesPdProjectDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/project/MesPdProjectDO.java
@@ -58,13 +58,24 @@
      */
     private Integer status;
     /**
-     * BPM 娴佺▼瀹炰緥缂栧彿
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� mes_pd_project_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
      */
-    private String processInstanceId;
+    private Long reviewerId;
     /**
-     * BPM 娴佺▼瀹氫箟 Key
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
      */
-    private String processDefinitionKey;
+    private String reviewerName;
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private LocalDateTime reviewTime;
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
     /**
      * 涓昏璁″笀
      *
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/techconfirm/ProductTechConfirmDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/techconfirm/ProductTechConfirmDO.java
index f9c7570..9263c62 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/techconfirm/ProductTechConfirmDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/techconfirm/ProductTechConfirmDO.java
@@ -73,16 +73,23 @@
     private LocalDateTime draftTime;
     /**
      * 瀹℃牳浜篒D
+     *
+     * 瀹℃牳浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� pd_tech_confirm_approve锛夛紝
+     * 鎻愪氦瀹℃牳鏃朵笉鎸囧畾锛涙澶勮褰曠殑鏄疄闄呮墽琛屽鏍哥殑鐢ㄦ埛锛屽鏍搁�氳繃鍚庝笉鍐嶅彉鍔ㄣ��
      */
     private Long reviewerId;
     /**
-     * 瀹℃牳浜哄鍚�
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鏃跺啀鏌ョ敤鎴凤級
      */
     private String reviewerName;
     /**
      * 瀹℃牳鏃堕棿
      */
     private LocalDateTime reviewTime;
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
     /**
      * 瀹㈡埛纭浜�
      */
@@ -92,9 +99,16 @@
      */
     private LocalDateTime customerConfirmTime;
     /**
-     * 鐘舵�侊紙0=鑽夌锛�1=寰呭鏍革紝2=宸插鏍革紝3=瀹㈡埛宸茬‘璁わ級
+     * 鐘舵�侊紙0=鑽夌锛�1=寰呭鏍革紝2=宸插鏍革紝3=瀹㈡埛宸茬‘璁わ紝4=瀹℃牳涓嶉�氳繃锛�
+     *
+     * 鍙敱涓氬姟娴佺▼椹卞姩锛屼笉鎺ュ彈鍓嶇鐩存帴璧嬪�硷細
+     * 鍒涘缓鏃跺浐瀹氫负鑽夌锛屾彁浜ゅ鏍稿悗缃负寰呭鏍革紝瀹℃牳閫氳繃/涓嶉�氳繃鐢�
+     * {@link cn.iocoder.yudao.module.mes.service.pd.techconfirm.ProductTechConfirmService#auditTechConfirm} 鎺ㄨ繘锛�
+     * 瀹㈡埛纭鐢�
+     * {@link cn.iocoder.yudao.module.mes.service.pd.techconfirm.ProductTechConfirmService#confirmTechConfirmByCustomer} 鎺ㄨ繘銆�
      *
      * 瀛楀吀 {@link DictTypeConstants#PRODUCT_TECH_CONFIRM_STATUS}
+     * 鏋氫妇 {@link cn.iocoder.yudao.module.mes.enums.pd.MesPdTechConfirmStatusEnum}
      */
     private Integer status;
     /**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/equipmentreceipt/MesWmEquipmentReceiptDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/equipmentreceipt/MesWmEquipmentReceiptDO.java
index 7e11549..c12efdd 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/equipmentreceipt/MesWmEquipmentReceiptDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/equipmentreceipt/MesWmEquipmentReceiptDO.java
@@ -49,9 +49,24 @@
      */
     private Integer status;
     /**
-     * BPM 娴佺▼瀹炰緥缂栧彿
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� equipment_receipt_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
      */
-    private String processInstanceId;
+    private Long reviewerId;
+    /**
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
+     */
+    private String reviewerName;
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private LocalDateTime reviewTime;
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
     /**
      * 澶囨敞
      */
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemreceipt/MesWmItemReceiptDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemreceipt/MesWmItemReceiptDO.java
index f641a4d..56c8444 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemreceipt/MesWmItemReceiptDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemreceipt/MesWmItemReceiptDO.java
@@ -81,13 +81,24 @@
      */
     private Integer status;
     /**
-     * BPM 娴佺▼瀹炰緥缂栧彿
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃壒浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� item_receipt_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
      */
-    private String processInstanceId;
+    private Long reviewerId;
     /**
-     * BPM 娴佺▼瀹氫箟 Key
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
      */
-    private String processDefinitionKey;
+    private String reviewerName;
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private LocalDateTime reviewTime;
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
     /**
      * 澶囨敞
      */
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscissue/MesWmMiscIssueDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscissue/MesWmMiscIssueDO.java
index 126e77a..04d53b3 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscissue/MesWmMiscIssueDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscissue/MesWmMiscIssueDO.java
@@ -68,9 +68,24 @@
      */
     private Integer status;
     /**
-     * BPM 娴佺▼瀹炰緥缂栧彿
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃牳浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� misc_issue_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
      */
-    private String processInstanceId;
+    private Long reviewerId;
+    /**
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
+     */
+    private String reviewerName;
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private LocalDateTime reviewTime;
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
     /**
      * 澶囨敞
      */
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscreceipt/MesWmMiscReceiptDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscreceipt/MesWmMiscReceiptDO.java
index 9502fdd..4858fcd 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscreceipt/MesWmMiscReceiptDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscreceipt/MesWmMiscReceiptDO.java
@@ -68,9 +68,24 @@
      */
     private Integer status;
     /**
-     * BPM 娴佺▼瀹炰緥缂栧彿
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃牳浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� misc_receipt_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
      */
-    private String processInstanceId;
+    private Long reviewerId;
+    /**
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
+     */
+    private String reviewerName;
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private LocalDateTime reviewTime;
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
     /**
      * 澶囨敞
      */
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnvendor/MesWmReturnVendorDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnvendor/MesWmReturnVendorDO.java
index c96cdfb..d5c935a 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnvendor/MesWmReturnVendorDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnvendor/MesWmReturnVendorDO.java
@@ -70,9 +70,24 @@
      */
     private Integer status;
     /**
-     * BPM 娴佺▼瀹炰緥缂栧彿
+     * 瀹℃牳浜虹敤鎴风紪鍙�
+     *
+     * 瀹℃牳浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� return_vendor_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆�
      */
-    private String processInstanceId;
+    private Long reviewerId;
+    /**
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
+     */
+    private String reviewerName;
+    /**
+     * 瀹℃牳鏃堕棿
+     */
+    private LocalDateTime reviewTime;
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
     /**
      * 澶囨敞
      */
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/stocktaking/task/MesWmStockTakingTaskDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/stocktaking/task/MesWmStockTakingTaskDO.java
index 6279c2e..1f1f83b 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/stocktaking/task/MesWmStockTakingTaskDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/stocktaking/task/MesWmStockTakingTaskDO.java
@@ -93,11 +93,32 @@
     private Integer status;
 
     /**
-     * BPM 娴佺▼瀹炰緥缂栧彿
+     * 瀹℃牳浜虹敤鎴风紪鍙�
      *
-     * 闈炵┖琛ㄧず鐩樼偣缁撴灉宸叉彁浜� BPM 瀹℃壒锛屾鍦ㄧ瓑寰呭鎵圭粨鏋�
+     * 瀹℃牳浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� stock_taking_result_approve锛夛紝
+     * 鎻愪氦鏃朵笉鎸囧畾锛涙澶勮褰曞疄闄呮墽琛屽鏍哥殑鐢ㄦ埛銆傚鏍镐笉閫氳繃鍚庝繚鐣欙紝琛ㄧず缁撴灉瀹℃壒宸茶澶勭悊杩囥��
      */
-    private String processInstanceId;
+    private Long reviewerId;
+    /**
+     * 瀹℃牳浜哄鍚嶏紙瀹℃牳鏃跺啑浣欒褰曪紝閬垮厤鍒楄〃灞曠ず鍐嶆煡鐢ㄦ埛锛�
+     */
+    private String reviewerName;
+    /**
+     * 缁撴灉瀹℃壒鎻愪氦鏃堕棿 / 瀹℃牳鏃堕棿
+     *
+     * 鏈换鍔$殑鐘舵�� 2锛堢洏鐐逛腑锛夊悓鏃舵壙杞姐�岀洏鐐逛腑銆嶄笌銆岀洏鐐圭粨鏋滃鎵逛腑銆嶄袱涓樁娈碉紝
+     * 鏁呯敤鏈瓧娈靛尯鍒嗛樁娈碉細
+     * <ul>
+     *     <li>鎻愪氦缁撴灉瀹℃壒鏃跺啓鍏ユ彁浜ゆ椂闂达紝瀹℃牳浜轰笌瀹℃牳鎰忚涓虹┖ 鈥斺�� 缁撴灉瀹℃壒宸叉彁浜ゃ�佺瓑寰呭鏍革紱</li>
+     *     <li>瀹℃牳鏃舵洿鏂颁负瀹為檯瀹℃牳鏃堕棿 鈥斺�� 涓� reviewerId 涓�鍚岄潪绌猴紝琛ㄧず鏈疆缁撴灉瀹℃壒宸插鐞嗗畬姣曪紱</li>
+     *     <li>涓よ�呯殕绌鸿〃绀烘湰杞粨鏋滃鎵瑰皻鏈彁浜わ紝鍙户缁綍鍏ュ疄鐩樻暟閲忋��</li>
+     * </ul>
+     */
+    private LocalDateTime reviewTime;
+    /**
+     * 瀹℃牳鎰忚锛堝鏍搁�氳繃鏃剁殑鎰忚 / 瀹℃牳涓嶉�氳繃鏃剁殑鍘熷洜锛�
+     */
+    private String reviewRemark;
 
     /**
      * 澶囨敞
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pd/project/MesPdProjectMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pd/project/MesPdProjectMapper.java
index 1da3d0b..f6c5299 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pd/project/MesPdProjectMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pd/project/MesPdProjectMapper.java
@@ -5,7 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectPageReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pd.project.MesPdProjectDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
+
+import java.time.LocalDateTime;
 
 @Mapper
 public interface MesPdProjectMapper extends BaseMapperX<MesPdProjectDO> {
@@ -25,4 +28,47 @@
         return selectOne(MesPdProjectDO::getTaskCode, taskCode);
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜� / 瀹℃牳鏃堕棿 / 瀹℃牳鎰忚娓呯┖銆�
+     *
+     * @param id     缂栧彿
+     * @param status 鐩爣鐘舵�侊紙瀹℃壒涓級
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<MesPdProjectDO>()
+                .eq(MesPdProjectDO::getId, id)
+                .set(MesPdProjectDO::getStatus, status)
+                .set(MesPdProjectDO::getReviewerId, null)
+                .set(MesPdProjectDO::getReviewerName, null)
+                .set(MesPdProjectDO::getReviewTime, null)
+                .set(MesPdProjectDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * reviewRemark 鍏佽涓� null锛堝鏍搁�氳繃鏃舵剰瑙佸彲閫夛級锛屾晠鍚屾牱浣跨敤 UpdateWrapper 鐩村啓銆�
+     *
+     * @param id           缂栧彿
+     * @param status       鐩爣鐘舵�侊紙寰呭綊妗� / 寰呭鏍革級
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditProject(Long id, Integer status, Long reviewerId,
+                             String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<MesPdProjectDO>()
+                .eq(MesPdProjectDO::getId, id)
+                .set(MesPdProjectDO::getStatus, status)
+                .set(MesPdProjectDO::getReviewerId, reviewerId)
+                .set(MesPdProjectDO::getReviewerName, reviewerName)
+                .set(MesPdProjectDO::getReviewTime, LocalDateTime.now())
+                .set(MesPdProjectDO::getReviewRemark, reviewRemark));
+    }
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pd/techconfirm/ProductTechConfirmMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pd/techconfirm/ProductTechConfirmMapper.java
index befbb93..d4529cd 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pd/techconfirm/ProductTechConfirmMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pd/techconfirm/ProductTechConfirmMapper.java
@@ -5,7 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo.ProductTechConfirmPageReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pd.techconfirm.ProductTechConfirmDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
+
+import java.time.LocalDateTime;
 
 @Mapper
 public interface ProductTechConfirmMapper extends BaseMapperX<ProductTechConfirmDO> {
@@ -20,4 +23,47 @@
                 .orderByDesc(ProductTechConfirmDO::getId));
     }
 
+    /**
+     * 鎻愪氦瀹℃牳锛氱疆涓哄緟瀹℃牳锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 涔嬫墍浠ョ敤 UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鐨勫瓧娈垫洿鏂扮瓥鐣ヤ細蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜恒�佸鏍告椂闂淬�佸鏍告剰瑙佺湡姝f竻绌恒��
+     *
+     * @param id     缂栧彿
+     * @param status 鐩爣鐘舵�侊紙寰呭鏍革級
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<ProductTechConfirmDO>()
+                .eq(ProductTechConfirmDO::getId, id)
+                .set(ProductTechConfirmDO::getStatus, status)
+                .set(ProductTechConfirmDO::getReviewerId, null)
+                .set(ProductTechConfirmDO::getReviewerName, null)
+                .set(ProductTechConfirmDO::getReviewTime, null)
+                .set(ProductTechConfirmDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * reviewRemark 鍏佽涓� null锛堝鏍搁�氳繃鏃舵剰瑙佸彲閫夛級锛屾晠鍚屾牱浣跨敤 UpdateWrapper 鐩村啓銆�
+     *
+     * @param id           缂栧彿
+     * @param status       鐩爣鐘舵�侊紙宸插鏍� / 瀹℃牳涓嶉�氳繃锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditTechConfirm(Long id, Integer status, Long reviewerId,
+                                 String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<ProductTechConfirmDO>()
+                .eq(ProductTechConfirmDO::getId, id)
+                .set(ProductTechConfirmDO::getStatus, status)
+                .set(ProductTechConfirmDO::getReviewerId, reviewerId)
+                .set(ProductTechConfirmDO::getReviewerName, reviewerName)
+                .set(ProductTechConfirmDO::getReviewTime, LocalDateTime.now())
+                .set(ProductTechConfirmDO::getReviewRemark, reviewRemark));
+    }
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/equipmentreceipt/MesWmEquipmentReceiptMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/equipmentreceipt/MesWmEquipmentReceiptMapper.java
index 9424c6c..d86b157 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/equipmentreceipt/MesWmEquipmentReceiptMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/equipmentreceipt/MesWmEquipmentReceiptMapper.java
@@ -5,7 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.MesWmEquipmentReceiptPageReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt.MesWmEquipmentReceiptDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
+
+import java.time.LocalDateTime;
 
 /**
  * MES 璁惧鍏ュ簱鍗� Mapper
@@ -27,4 +30,45 @@
         return selectOne(MesWmEquipmentReceiptDO::getCode, code);
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜� / 瀹℃牳鏃堕棿 / 瀹℃牳鎰忚娓呯┖銆�
+     *
+     * @param id     缂栧彿
+     * @param status 鐩爣鐘舵�侊紙瀹℃壒涓級
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<MesWmEquipmentReceiptDO>()
+                .eq(MesWmEquipmentReceiptDO::getId, id)
+                .set(MesWmEquipmentReceiptDO::getStatus, status)
+                .set(MesWmEquipmentReceiptDO::getReviewerId, null)
+                .set(MesWmEquipmentReceiptDO::getReviewerName, null)
+                .set(MesWmEquipmentReceiptDO::getReviewTime, null)
+                .set(MesWmEquipmentReceiptDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * @param id           缂栧彿
+     * @param status       鐩爣鐘舵�侊紙宸插鎵� / 鑽夌锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditEquipmentReceipt(Long id, Integer status, Long reviewerId,
+                                      String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<MesWmEquipmentReceiptDO>()
+                .eq(MesWmEquipmentReceiptDO::getId, id)
+                .set(MesWmEquipmentReceiptDO::getStatus, status)
+                .set(MesWmEquipmentReceiptDO::getReviewerId, reviewerId)
+                .set(MesWmEquipmentReceiptDO::getReviewerName, reviewerName)
+                .set(MesWmEquipmentReceiptDO::getReviewTime, LocalDateTime.now())
+                .set(MesWmEquipmentReceiptDO::getReviewRemark, reviewRemark));
+    }
+
 }
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemreceipt/MesWmItemReceiptMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemreceipt/MesWmItemReceiptMapper.java
index 65336ff..6e6352f 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemreceipt/MesWmItemReceiptMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/itemreceipt/MesWmItemReceiptMapper.java
@@ -5,8 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptPageReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.time.LocalDateTime;
 import java.util.List;
 
 /**
@@ -40,4 +42,45 @@
         return selectOne(MesWmItemReceiptDO::getNoticeId, noticeId);
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄緟涓婃灦锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜� / 瀹℃牳鏃堕棿 / 瀹℃牳鎰忚娓呯┖銆�
+     *
+     * @param id     缂栧彿
+     * @param status 鐩爣鐘舵�侊紙寰呬笂鏋讹級
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<MesWmItemReceiptDO>()
+                .eq(MesWmItemReceiptDO::getId, id)
+                .set(MesWmItemReceiptDO::getStatus, status)
+                .set(MesWmItemReceiptDO::getReviewerId, null)
+                .set(MesWmItemReceiptDO::getReviewerName, null)
+                .set(MesWmItemReceiptDO::getReviewTime, null)
+                .set(MesWmItemReceiptDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * @param id           缂栧彿
+     * @param status       鐩爣鐘舵�侊紙寰呮墽琛屽叆搴� / 鑽夌锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditItemReceipt(Long id, Integer status, Long reviewerId,
+                                 String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<MesWmItemReceiptDO>()
+                .eq(MesWmItemReceiptDO::getId, id)
+                .set(MesWmItemReceiptDO::getStatus, status)
+                .set(MesWmItemReceiptDO::getReviewerId, reviewerId)
+                .set(MesWmItemReceiptDO::getReviewerName, reviewerName)
+                .set(MesWmItemReceiptDO::getReviewTime, LocalDateTime.now())
+                .set(MesWmItemReceiptDO::getReviewRemark, reviewRemark));
+    }
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/miscissue/MesWmMiscIssueMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/miscissue/MesWmMiscIssueMapper.java
index f5b4440..f88fa5a 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/miscissue/MesWmMiscIssueMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/miscissue/MesWmMiscIssueMapper.java
@@ -5,8 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.miscissue.vo.MesWmMiscIssuePageReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.miscissue.MesWmMiscIssueDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.time.LocalDateTime;
 import java.util.List;
 
 /**
@@ -35,4 +37,45 @@
         return selectList(MesWmMiscIssueDO::getStatus, status);
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜� / 瀹℃牳鏃堕棿 / 瀹℃牳鎰忚娓呯┖銆�
+     *
+     * @param id     缂栧彿
+     * @param status 鐩爣鐘舵�侊紙瀹℃壒涓級
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<MesWmMiscIssueDO>()
+                .eq(MesWmMiscIssueDO::getId, id)
+                .set(MesWmMiscIssueDO::getStatus, status)
+                .set(MesWmMiscIssueDO::getReviewerId, null)
+                .set(MesWmMiscIssueDO::getReviewerName, null)
+                .set(MesWmMiscIssueDO::getReviewTime, null)
+                .set(MesWmMiscIssueDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * @param id           缂栧彿
+     * @param status       鐩爣鐘舵�侊紙寰呮墽琛屽嚭搴� / 鑽夌锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditMiscIssue(Long id, Integer status, Long reviewerId,
+                              String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<MesWmMiscIssueDO>()
+                .eq(MesWmMiscIssueDO::getId, id)
+                .set(MesWmMiscIssueDO::getStatus, status)
+                .set(MesWmMiscIssueDO::getReviewerId, reviewerId)
+                .set(MesWmMiscIssueDO::getReviewerName, reviewerName)
+                .set(MesWmMiscIssueDO::getReviewTime, LocalDateTime.now())
+                .set(MesWmMiscIssueDO::getReviewRemark, reviewRemark));
+    }
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/miscreceipt/MesWmMiscReceiptMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/miscreceipt/MesWmMiscReceiptMapper.java
index 4a6f6e6..519da5c 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/miscreceipt/MesWmMiscReceiptMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/miscreceipt/MesWmMiscReceiptMapper.java
@@ -5,7 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.miscreceipt.vo.MesWmMiscReceiptPageReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.miscreceipt.MesWmMiscReceiptDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
+
+import java.time.LocalDateTime;
 
 /**
  * MES 鏉傞」鍏ュ簱鍗� Mapper
@@ -31,4 +34,45 @@
         return selectOne(MesWmMiscReceiptDO::getCode, code);
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜� / 瀹℃牳鏃堕棿 / 瀹℃牳鎰忚娓呯┖銆�
+     *
+     * @param id     缂栧彿
+     * @param status 鐩爣鐘舵�侊紙瀹℃壒涓級
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<MesWmMiscReceiptDO>()
+                .eq(MesWmMiscReceiptDO::getId, id)
+                .set(MesWmMiscReceiptDO::getStatus, status)
+                .set(MesWmMiscReceiptDO::getReviewerId, null)
+                .set(MesWmMiscReceiptDO::getReviewerName, null)
+                .set(MesWmMiscReceiptDO::getReviewTime, null)
+                .set(MesWmMiscReceiptDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * @param id           缂栧彿
+     * @param status       鐩爣鐘舵�侊紙宸插鎵� / 鑽夌锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditMiscReceipt(Long id, Integer status, Long reviewerId,
+                                 String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<MesWmMiscReceiptDO>()
+                .eq(MesWmMiscReceiptDO::getId, id)
+                .set(MesWmMiscReceiptDO::getStatus, status)
+                .set(MesWmMiscReceiptDO::getReviewerId, reviewerId)
+                .set(MesWmMiscReceiptDO::getReviewerName, reviewerName)
+                .set(MesWmMiscReceiptDO::getReviewTime, LocalDateTime.now())
+                .set(MesWmMiscReceiptDO::getReviewRemark, reviewRemark));
+    }
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnvendor/MesWmReturnVendorMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnvendor/MesWmReturnVendorMapper.java
index dfb626f..25b80b4 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnvendor/MesWmReturnVendorMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnvendor/MesWmReturnVendorMapper.java
@@ -5,7 +5,10 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.returnvendor.vo.MesWmReturnVendorPageReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDO;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
+
+import java.time.LocalDateTime;
 
 /**
  * MES 渚涘簲鍟嗛��璐у崟 Mapper
@@ -30,4 +33,45 @@
         return selectOne(MesWmReturnVendorDO::getCode, code);
     }
 
+    /**
+     * 鎻愪氦瀹℃壒锛氱疆涓哄緟鎷h揣锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+     *
+     * 鐢� UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜� / 瀹℃牳鏃堕棿 / 瀹℃牳鎰忚娓呯┖銆�
+     *
+     * @param id     缂栧彿
+     * @param status 鐩爣鐘舵�侊紙寰呮嫞璐э級
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<MesWmReturnVendorDO>()
+                .eq(MesWmReturnVendorDO::getId, id)
+                .set(MesWmReturnVendorDO::getStatus, status)
+                .set(MesWmReturnVendorDO::getReviewerId, null)
+                .set(MesWmReturnVendorDO::getReviewerName, null)
+                .set(MesWmReturnVendorDO::getReviewTime, null)
+                .set(MesWmReturnVendorDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * @param id           缂栧彿
+     * @param status       鐩爣鐘舵�侊紙寰呮墽琛岄��璐� / 鑽夌锛�
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditReturnVendor(Long id, Integer status, Long reviewerId,
+                                 String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<MesWmReturnVendorDO>()
+                .eq(MesWmReturnVendorDO::getId, id)
+                .set(MesWmReturnVendorDO::getStatus, status)
+                .set(MesWmReturnVendorDO::getReviewerId, reviewerId)
+                .set(MesWmReturnVendorDO::getReviewerName, reviewerName)
+                .set(MesWmReturnVendorDO::getReviewTime, LocalDateTime.now())
+                .set(MesWmReturnVendorDO::getReviewRemark, reviewRemark));
+    }
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/stocktaking/task/MesWmStockTakingTaskMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/stocktaking/task/MesWmStockTakingTaskMapper.java
index 09ff64a..5103c32 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/stocktaking/task/MesWmStockTakingTaskMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/stocktaking/task/MesWmStockTakingTaskMapper.java
@@ -8,6 +8,8 @@
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.time.LocalDateTime;
+
 /**
  * MES 鐩樼偣浠诲姟 Mapper
  *
@@ -21,16 +23,79 @@
     }
 
     /**
-     * 娓呯┖ BPM 娴佺▼瀹炰緥缂栧彿
+     * 寮�濮嬬洏鐐癸細缃负鐩樼偣涓紝骞舵竻绌轰笂涓�杞鏍哥粨鏋�
      *
-     * 鐢ㄤ簬鐩樼偣缁撴灉瀹℃壒琚┏鍥�/鍙栨秷鍚庣疆绌猴紝浠诲姟鍥炲埌鍙噸鏂版彁浜ょ粨鏋滃鎵圭殑鐘舵��
+     * 鐢� UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐蹇界暐 null锛�
+     * 鐩存帴 updateById 鏃犳硶鎶婂鏍镐汉 / 瀹℃牳鏃堕棿 / 瀹℃牳鎰忚鐪熸娓呯┖銆�
+     *
+     * @param id     鐩樼偣浠诲姟缂栧彿
+     * @param status 鐩爣鐘舵�侊紙鐩樼偣涓級
+     * @return 褰卞搷琛屾暟
+     */
+    default int submitAndResetAuditInfo(Long id, Integer status) {
+        return update(null, new LambdaUpdateWrapper<MesWmStockTakingTaskDO>()
+                .eq(MesWmStockTakingTaskDO::getId, id)
+                .set(MesWmStockTakingTaskDO::getStatus, status)
+                .set(MesWmStockTakingTaskDO::getReviewerId, null)
+                .set(MesWmStockTakingTaskDO::getReviewerName, null)
+                .set(MesWmStockTakingTaskDO::getReviewTime, null)
+                .set(MesWmStockTakingTaskDO::getReviewRemark, null));
+    }
+
+    /**
+     * 鎻愪氦缁撴灉瀹℃壒锛氬啓鍏ユ彁浜ゆ椂闂村苟娓呯┖涓婁竴杞殑瀹℃牳浜轰笌瀹℃牳鎰忚
+     *
+     * 浠诲姟鐘舵�佷繚鎸併�岀洏鐐逛腑銆嶄笉鍙橈紙璇ョ姸鎬佸悓鏃舵壙杞界洏鐐逛腑涓庣粨鏋滃鎵逛腑涓や釜闃舵锛夛紝
+     * 浠� reviewTime 闈炵┖涓� reviewerId 涓虹┖琛ㄧず銆岀粨鏋滃鎵瑰凡鎻愪氦銆佺瓑寰呭鏍搞�嶃��
+     * 涓嶄慨鏀� status 瀛楁锛屾晠鐢� UpdateWrapper 绮剧‘鍐欏叆銆�
+     *
+     * @param id 鐩樼偣浠诲姟缂栧彿
+     * @return 褰卞搷琛屾暟
+     */
+    default int markResultApprovalSubmitted(Long id) {
+        return update(null, new LambdaUpdateWrapper<MesWmStockTakingTaskDO>()
+                .eq(MesWmStockTakingTaskDO::getId, id)
+                .set(MesWmStockTakingTaskDO::getReviewTime, LocalDateTime.now())
+                .set(MesWmStockTakingTaskDO::getReviewerId, null)
+                .set(MesWmStockTakingTaskDO::getReviewerName, null)
+                .set(MesWmStockTakingTaskDO::getReviewRemark, null));
+    }
+
+    /**
+     * 瀹℃牳缁撴灉锛氬啓鍏ュ鏍哥粨鏋溿�佸鏍镐汉涓庡鏍告剰瑙�
+     *
+     * @param id           鐩樼偣浠诲姟缂栧彿
+     * @param status       鐩爣鐘舵�侊紙宸插畬鎴� / 鐩樼偣涓級
+     * @param reviewerId   瀹℃牳浜虹紪鍙�
+     * @param reviewerName 瀹℃牳浜哄鍚�
+     * @param reviewRemark 瀹℃牳鎰忚
+     * @return 褰卞搷琛屾暟
+     */
+    default int auditStockTakingTask(Long id, Integer status, Long reviewerId,
+                                     String reviewerName, String reviewRemark) {
+        return update(null, new LambdaUpdateWrapper<MesWmStockTakingTaskDO>()
+                .eq(MesWmStockTakingTaskDO::getId, id)
+                .set(MesWmStockTakingTaskDO::getStatus, status)
+                .set(MesWmStockTakingTaskDO::getReviewerId, reviewerId)
+                .set(MesWmStockTakingTaskDO::getReviewerName, reviewerName)
+                .set(MesWmStockTakingTaskDO::getReviewTime, LocalDateTime.now())
+                .set(MesWmStockTakingTaskDO::getReviewRemark, reviewRemark));
+    }
+
+    /**
+     * 娓呯┖瀹℃牳鏍囪
+     *
+     * 鐢ㄤ簬浠诲姟鍙栨秷鍚庢竻闄ょ粨鏋滃鎵圭棔杩�
      *
      * @param id 鐩樼偣浠诲姟缂栧彿
      */
-    default void clearProcessInstanceId(Long id) {
+    default void clearAuditInfo(Long id) {
         update(null, new LambdaUpdateWrapper<MesWmStockTakingTaskDO>()
                 .eq(MesWmStockTakingTaskDO::getId, id)
-                .set(MesWmStockTakingTaskDO::getProcessInstanceId, null));
+                .set(MesWmStockTakingTaskDO::getReviewerId, null)
+                .set(MesWmStockTakingTaskDO::getReviewerName, null)
+                .set(MesWmStockTakingTaskDO::getReviewTime, null)
+                .set(MesWmStockTakingTaskDO::getReviewRemark, null));
     }
 
     default PageResult<MesWmStockTakingTaskDO> selectPage(MesWmStockTakingTaskPageReqVO reqVO) {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
index c0f0a6b..95286cd 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -523,6 +523,8 @@
     ErrorCode WM_ITEM_RECEIPT_STATUS_ERROR = new ErrorCode(1_040_705_005, "鍏ュ簱鍗曠姸鎬佷笉姝g‘");
     ErrorCode WM_ITEM_RECEIPT_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_705_006, "宸插畬鎴愭垨宸插彇娑堢殑鍏ュ簱鍗曚笉鍏佽鍙栨秷");
     ErrorCode WM_ITEM_RECEIPT_ALREADY_EXISTS = new ErrorCode(1_040_705_007, "璇ュ埌璐ч�氱煡鍗曞凡鐢熸垚鍏ュ簱鍗曪紝涓嶈兘閲嶅鐢熸垚");
+    ErrorCode WM_ITEM_RECEIPT_NOT_APPROVING = new ErrorCode(1_040_705_008, "鍙湁寰呬笂鏋剁姸鎬佺殑閲囪喘鍏ュ簱鍗曟墠鑳藉鏍�");
+    ErrorCode WM_ITEM_RECEIPT_REJECT_REASON_REQUIRED = new ErrorCode(1_040_705_009, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
     ErrorCode WM_PURCHASE_ORDER_NOT_EXISTS = new ErrorCode(1_040_705_008, "閲囪喘璁㈠崟涓嶅瓨鍦�");
     ErrorCode WM_PURCHASE_ORDER_NO_ITEM = new ErrorCode(1_040_705_008, "閲囪喘璁㈠崟鏃犳槑缁嗘暟鎹�");
     ErrorCode WM_ITEM_RECEIPT_LINE_NOT_EXISTS = new ErrorCode(1_040_705_100, "閲囪喘鍏ュ簱鍗曡涓嶅瓨鍦�");
@@ -625,6 +627,8 @@
     ErrorCode WM_RETURN_VENDOR_CODE_DUPLICATE = new ErrorCode(1_040_711_005, "渚涘簲鍟嗛��璐у崟缂栧彿宸插瓨鍦�");
     ErrorCode WM_RETURN_VENDOR_NO_DETAIL = new ErrorCode(1_040_711_006, "渚涘簲鍟嗛��璐у崟娌℃湁鎷h揣鏄庣粏锛屾棤娉曟墽琛岄��璐�");
     ErrorCode WM_RETURN_VENDOR_DETAIL_ITEM_MISMATCH = new ErrorCode(1_040_711_007, "鎷h揣鏄庣粏鐨勭墿鏂欎笌閫�璐у崟琛岀殑鐗╂枡涓嶄竴鑷�");
+    ErrorCode WM_RETURN_VENDOR_NOT_APPROVING = new ErrorCode(1_040_711_008, "鍙湁寰呮嫞璐х姸鎬佺殑渚涘簲鍟嗛��璐у崟鎵嶈兘瀹℃牳");
+    ErrorCode WM_RETURN_VENDOR_REJECT_REASON_REQUIRED = new ErrorCode(1_040_711_009, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
     ErrorCode WM_RETURN_VENDOR_LINE_NOT_EXISTS = new ErrorCode(1_040_711_100, "渚涘簲鍟嗛��璐у崟琛屼笉瀛樺湪");
     ErrorCode WM_RETURN_VENDOR_DETAIL_NOT_EXISTS = new ErrorCode(1_040_711_200, "渚涘簲鍟嗛��璐у崟鏄庣粏涓嶅瓨鍦�");
     ErrorCode WM_RETURN_VENDOR_DETAIL_QUANTITY_INVALID = new ErrorCode(1_040_711_201, "閫�璐ф槑缁嗘暟閲忓繀椤诲ぇ浜� 0");
@@ -691,6 +695,8 @@
     ErrorCode WM_STOCK_TAKING_TASK_NOT_FINISHED = new ErrorCode(1_040_714_121, "鍙湁宸插畬鎴愮姸鎬佺殑鐩樼偣浠诲姟鎵嶈兘澶勭悊宸紓");
     ErrorCode WM_STOCK_TAKING_TASK_NO_RESULT = new ErrorCode(1_040_714_122, "鐩樼偣浠诲姟鑷冲皯闇�瑕佷竴鏉$洏鐐圭粨鏋滄墠鍏佽鎻愪氦缁撴灉瀹℃壒");
     ErrorCode WM_STOCK_TAKING_TASK_ALREADY_SUBMIT_APPROVAL = new ErrorCode(1_040_714_123, "鐩樼偣缁撴灉瀹℃壒宸叉彁浜わ紝璇峰嬁閲嶅鎻愪氦");
+    ErrorCode WM_STOCK_TAKING_TASK_RESULT_NOT_SUBMITTED = new ErrorCode(1_040_714_124, "鍙湁宸叉彁浜ょ粨鏋滃鎵圭殑鐩樼偣浠诲姟鎵嶈兘瀹℃牳");
+    ErrorCode WM_STOCK_TAKING_TASK_REJECT_REASON_REQUIRED = new ErrorCode(1_040_714_125, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
 
     // ========== MES 浠撳簱绠$悊-閿�鍞嚭搴撳崟锛�1-040-714-000锛� ==========
     ErrorCode WM_PRODUCT_SALES_NOT_EXISTS = new ErrorCode(1_040_714_000, "閿�鍞嚭搴撳崟涓嶅瓨鍦�");
@@ -732,6 +738,8 @@
     ErrorCode WM_MISC_ISSUE_NO_LINE = new ErrorCode(1_040_715_003, "鏉傞」鍑哄簱鍗曡嚦灏戦渶瑕佷竴鏉¤鏁版嵁");
     ErrorCode WM_MISC_ISSUE_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_715_004, "鏉傞」鍑哄簱鍗曞凡瀹屾垚鎴栧凡鍙栨秷锛屾棤娉曞彇娑�");
     ErrorCode WM_MISC_ISSUE_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_715_005, "鏉傞」鍑哄簱鍗曡鏁伴噺涓庢槑缁嗘暟閲忎笉涓�鑷�");
+    ErrorCode WM_MISC_ISSUE_NOT_APPROVING = new ErrorCode(1_040_715_006, "鍙湁瀹℃壒涓姸鎬佺殑鏉傞」鍑哄簱鍗曟墠鑳藉鏍�");
+    ErrorCode WM_MISC_ISSUE_REJECT_REASON_REQUIRED = new ErrorCode(1_040_715_007, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
     ErrorCode WM_MISC_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_715_100, "鏉傞」鍑哄簱鍗曡涓嶅瓨鍦�");
     ErrorCode WM_MISC_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_715_200, "鏉傞」鍑哄簱鍗曟槑缁嗕笉瀛樺湪");
 
@@ -742,6 +750,8 @@
     ErrorCode WM_MISC_RECEIPT_STATUS_NOT_APPROVED = new ErrorCode(1_040_716_003, "鍙湁宸插鎵圭姸鎬佹墠鍏佽鎵ц鍏ュ簱");
     ErrorCode WM_MISC_RECEIPT_NO_LINE = new ErrorCode(1_040_716_004, "鑷冲皯闇�瑕佷竴鏉¤椤圭洰");
     ErrorCode WM_MISC_RECEIPT_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_716_005, "宸插畬鎴愭垨宸插彇娑堢殑鍏ュ簱鍗曚笉鍏佽鍙栨秷");
+    ErrorCode WM_MISC_RECEIPT_NOT_APPROVING = new ErrorCode(1_040_716_006, "鍙湁瀹℃壒涓姸鎬佺殑鏉傞」鍏ュ簱鍗曟墠鑳藉鏍�");
+    ErrorCode WM_MISC_RECEIPT_REJECT_REASON_REQUIRED = new ErrorCode(1_040_716_007, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
     ErrorCode WM_MISC_RECEIPT_LINE_NOT_EXISTS = new ErrorCode(1_040_716_100, "鏉傞」鍏ュ簱鍗曡涓嶅瓨鍦�");
     ErrorCode WM_MISC_RECEIPT_WAREHOUSE_REQUIRED = new ErrorCode(1_040_716_101, "浠撳簱涓嶈兘涓虹┖");
     ErrorCode WM_MISC_RECEIPT_QUANTITY_INVALID = new ErrorCode(1_040_716_102, "鍏ュ簱鏁伴噺蹇呴』澶т簬 0");
@@ -794,6 +804,8 @@
     ErrorCode WM_EQUIP_RECEIPT_LINE_NOT_EXISTS = new ErrorCode(1_040_733_100, "璁惧鍏ュ簱鍗曡涓嶅瓨鍦�");
     ErrorCode WM_EQUIP_RECEIPT_MACHINERY_NOT_VALID = new ErrorCode(1_040_733_101, "鎵�閫夎澶囨湭鍏宠仈鐗╂枡锛屾棤娉曞叆搴�");
     ErrorCode WM_EQUIP_RECEIPT_QUANTITY_INVALID = new ErrorCode(1_040_733_102, "鍏ュ簱鏁伴噺蹇呴』澶т簬 0");
+    ErrorCode WM_EQUIP_RECEIPT_NOT_APPROVING = new ErrorCode(1_040_733_006, "鍙湁瀹℃壒涓姸鎬佺殑璁惧鍏ュ簱鍗曟墠鑳藉鏍�");
+    ErrorCode WM_EQUIP_RECEIPT_REJECT_REASON_REQUIRED = new ErrorCode(1_040_733_007, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
 
     // ========== MES 浠撳簱绠$悊-瑁呯鍗曪紙1-040-740-000锛� ==========
     ErrorCode WM_PACKAGE_NOT_EXISTS = new ErrorCode(1_040_740_000, "瑁呯鍗曚笉瀛樺湪");
@@ -817,8 +829,8 @@
     ErrorCode PD_PROJECT_NOT_AUDIT_FOR_ARCHIVE = new ErrorCode(1_040_800_006, "鍙湁寰呭綊妗g姸鎬佺殑璁捐椤圭洰鎵嶈兘褰掓。");
     ErrorCode PD_PROJECT_AUDIT_NOT_FINISHED = new ErrorCode(1_040_800_007, "璇ラ」鐩笅瀛樺湪鏈鏍哥殑璧勬枡锛岃鍏堝畬鎴愭墍鏈夎祫鏂欏鏍�");
     ErrorCode PD_PROJECT_NOT_UPLOAD_FOR_APPROVAL = new ErrorCode(1_040_800_008, "鍙湁寰呭鏍哥姸鎬佺殑璁捐椤圭洰鎵嶈兘鎻愪氦瀹℃壒");
-    ErrorCode PD_PROJECT_NOT_APPROVING = new ErrorCode(1_040_800_009, "璁捐椤圭洰涓嶅浜庡鎵逛腑鐘舵��");
-    ErrorCode PD_PROJECT_BPM_CATEGORY_NOT_EXISTS = new ErrorCode(1_040_800_010, "璁捐椤圭洰瀹℃壒鍒嗙被涓嶅瓨鍦紝璇峰厛閰嶇疆 BPM 瀹℃壒娴佺▼");
+    ErrorCode PD_PROJECT_NOT_APPROVING = new ErrorCode(1_040_800_009, "鍙湁瀹℃壒涓姸鎬佺殑璁捐椤圭洰鎵嶈兘瀹℃牳");
+    ErrorCode PD_PROJECT_AUDIT_REJECT_REASON_REQUIRED = new ErrorCode(1_040_800_010, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
 
     // ========== MES 浜у搧璁捐-璧勬枡瀛愯〃锛�1-040-801-000锛� ==========
     ErrorCode PD_DOCUMENT_NOT_EXISTS = new ErrorCode(1_040_801_000, "璁捐璧勬枡涓嶅瓨鍦�");
@@ -849,6 +861,11 @@
     // ========== MES 浜у搧璁捐-鎶�鏈‘璁ゅ嚱锛�1-040-808-000锛� ==========
     ErrorCode PD_TECH_CONFIRM_NOT_EXISTS = new ErrorCode(1_040_808_000, "鎶�鏈‘璁ゅ嚱涓嶅瓨鍦�");
     ErrorCode PD_TECH_CONFIRM_NO_DUPLICATE = new ErrorCode(1_040_808_001, "纭鍑界紪鍙峰凡瀛樺湪");
+    ErrorCode PD_TECH_CONFIRM_NOT_EDITABLE = new ErrorCode(1_040_808_002, "鍙湁鑽夌鎴栧鏍镐笉閫氳繃鐘舵�佺殑鎶�鏈‘璁ゅ嚱鎵嶈兘淇敼鎴栧垹闄�");
+    ErrorCode PD_TECH_CONFIRM_NOT_EDITABLE_FOR_SUBMIT = new ErrorCode(1_040_808_003, "鍙湁鑽夌鎴栧鏍镐笉閫氳繃鐘舵�佺殑鎶�鏈‘璁ゅ嚱鎵嶈兘鎻愪氦瀹℃牳");
+    ErrorCode PD_TECH_CONFIRM_NOT_PENDING_AUDIT = new ErrorCode(1_040_808_004, "鍙湁寰呭鏍哥姸鎬佺殑鎶�鏈‘璁ゅ嚱鎵嶈兘瀹℃牳");
+    ErrorCode PD_TECH_CONFIRM_REJECT_REASON_REQUIRED = new ErrorCode(1_040_808_007, "瀹℃牳涓嶉�氳繃鏃跺繀椤诲~鍐欎笉閫氳繃鍘熷洜");
+    ErrorCode PD_TECH_CONFIRM_NOT_AUDITED_FOR_CUSTOMER_CONFIRM = new ErrorCode(1_040_808_008, "鍙湁宸插鏍哥姸鎬佺殑鎶�鏈‘璁ゅ嚱鎵嶈兘杩涜瀹㈡埛纭");
 
     // ========== MES 浜у搧璁捐-浜у搧妗f涓庡熀纭�鏁版嵁锛�1-040-809-000锛� ==========
     ErrorCode PD_PRODUCT_NOT_EXISTS = new ErrorCode(1_040_809_000, "浜у搧妗f涓嶅瓨鍦�");
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdProjectStatusEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdProjectStatusEnum.java
index 8aa13ec..923b49b 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdProjectStatusEnum.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdProjectStatusEnum.java
@@ -39,7 +39,7 @@
     /**
      * 寰呭綊妗�
      *
-     * 瀵瑰簲 MesPdProjectService#updateProjectAuditStatus 鏂规硶锛圔PM 瀹℃壒閫氳繃鍚庯級
+     * 瀵瑰簲 MesPdProjectService#auditProject 鏂规硶锛堝鏍搁�氳繃鍚庯級
      */
     AUDIT(MesPdStatusConstants.AUDIT, "寰呭綊妗�"),
     /**
@@ -51,7 +51,7 @@
     /**
      * 瀹℃壒涓�
      *
-     * 瀵瑰簲 MesPdProjectService#submitProjectApproval 鏂规硶
+     * 瀵瑰簲 MesPdProjectService#submitProjectApproval 鏂规硶锛涘鏍搁�氳繃鍚庣疆涓哄緟褰掓。锛屼笉閫氳繃閫�鍥炲緟瀹℃牳
      */
     APPROVING(MesPdStatusConstants.APPROVING, "瀹℃壒涓�");
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdTechConfirmStatusEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdTechConfirmStatusEnum.java
new file mode 100644
index 0000000..b1ed567
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdTechConfirmStatusEnum.java
@@ -0,0 +1,46 @@
+package cn.iocoder.yudao.module.mes.enums.pd;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Arrays;
+
+/**
+ * 浜у搧璁捐-鎶�鏈‘璁ゅ嚱鐘舵��
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@RequiredArgsConstructor
+@Getter
+public enum MesPdTechConfirmStatusEnum implements ArrayValuable<Integer> {
+
+    DRAFT(0, "鑽夌"),
+    PENDING_AUDIT(1, "寰呭鏍�"),
+    AUDITED(2, "宸插鏍�"),
+    CUSTOMER_CONFIRMED(3, "瀹㈡埛宸茬‘璁�"),
+    REJECTED(4, "瀹℃牳涓嶉�氳繃");
+
+    private final Integer status;
+    private final String name;
+
+    public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesPdTechConfirmStatusEnum::getStatus).toArray(Integer[]::new);
+
+    public static String getNameByStatus(Integer status) {
+        if (status == null) {
+            return null;
+        }
+        for (MesPdTechConfirmStatusEnum e : values()) {
+            if (e.getStatus().equals(status)) {
+                return e.getName();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Integer[] array() {
+        return ARRAYS;
+    }
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java
index 8a11385..ce8b368 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java
@@ -33,7 +33,7 @@
     /**
      * 寰呮墽琛屽嚭搴�
      *
-     * 瀵瑰簲 MesWmMiscIssueService#updateMiscIssueAuditStatus 鏂规硶
+     * 瀵瑰簲 MesWmMiscIssueService#auditMiscIssue 鏂规硶
      */
     APPROVED(MesOrderStatusConstants.APPROVED, "寰呮墽琛屽嚭搴�"),
     /**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java
index e09fbbb..5763b58 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java
@@ -31,7 +31,7 @@
     /**
      * 宸插鎵�
      *
-     * 瀵瑰簲 MesWmMiscReceiptService#updateMiscReceiptAuditStatus 鏂规硶
+     * 瀵瑰簲 MesWmMiscReceiptService#auditMiscReceipt 鏂规硶
      */
     APPROVED(MesOrderStatusConstants.APPROVED, "宸插鎵�"),
     /**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskStatusEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskStatusEnum.java
index 9e8c990..49a4c3e 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskStatusEnum.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmStockTakingTaskStatusEnum.java
@@ -32,7 +32,7 @@
     /**
      * 宸插畬鎴�
      *
-     * 鐩樼偣缁撴灉瀹℃壒閫氳繃鍚庯紝鐢辩粨鏋滃鎵瑰洖璋冪疆涓哄凡瀹屾垚骞惰嚜鍔ㄦ牳閿�宸紓
+     * 鐩樼偣缁撴灉瀹℃牳閫氳繃鍚庯紝鐢辩粨鏋滃鏍哥疆涓哄凡瀹屾垚骞惰嚜鍔ㄦ牳閿�宸紓
      */
     FINISHED(MesOrderStatusConstants.FINISHED, "宸插畬鎴�"),
     /**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectService.java
index 54deaeb..2dcbdf1 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectService.java
@@ -9,6 +9,7 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * MES 璁捐椤圭洰 Service 鎺ュ彛
@@ -82,28 +83,34 @@
 
     /**
      * 鎻愪氦璁捐椤圭洰瀹℃壒锛堝緟瀹℃牳鈫掑鎵逛腑锛�
-     * <p>
-     * 鍒涘缓 BPM 娴佺▼瀹炰緥锛屽鎵归�氳繃鍚庣敱鐩戝惉鍣ㄥ洖璋冩洿鏂颁负寰呭綊妗�
      *
-     * @param id                  缂栧彿
-     * @param processDefinitionKey 娴佺▼瀹氫箟 Key
+     * 瀹℃牳浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� mes_pd_project_approve锛夛紝
+     * 鎻愪氦鏃舵棤闇�鎸囧畾锛涙湭鍚敤瀹℃壒鎴栨湭閰嶇疆鏈夋晥瀹℃牳浜烘椂鎶涘嚭涓氬姟寮傚父銆�
+     *
+     * @param id 缂栧彿
      */
-    void submitProjectApproval(Long id, String processDefinitionKey);
+    void submitProjectApproval(Long id);
 
     /**
-     * 鑾峰緱璁捐椤圭洰瀹℃壒娴佺▼鍒楄〃
+     * 鑾峰緱璁捐椤圭洰瀹℃壒鐨勫鏍镐汉缂栧彿闆嗗悎
      *
-     * @return 娴佺▼鍒楄〃锛坕d/name/version/key锛�
+     * 渚涘墠绔垽鏂綋鍓嶇櫥褰曠敤鎴锋槸鍚﹀簲灞曠ず銆屽鏍搞�嶆寜閽紱鏈厤缃椂杩斿洖绌洪泦鍚堛��
+     *
+     * @return 瀹℃牳浜虹敤鎴风紪鍙烽泦鍚�
      */
-    List<Map<String, Object>> getProjectApproveProcessDefinitionList();
+    Set<Long> getProjectApproverUserIds();
 
     /**
-     * 鏇存柊璁捐椤圭洰瀹℃壒鐘舵�侊紙BPM 鐩戝惉鍣ㄥ洖璋冿級
+     * 瀹℃牳璁捐椤圭洰锛堝鎵逛腑鈫掑緟褰掓。 / 寰呭鏍革級
      *
-     * @param id       缂栧彿
-     * @param bpmResult BPM 瀹℃壒缁撴灉
+     * 浠呬笟鍔$紪鐮� mes_pd_project_approve 閰嶇疆鐨勫鏍镐汉鍙搷浣滐紙澶氫汉鏃舵垨绛撅級锛屼笖浠呭湪瀹℃壒涓姸鎬佷笅鍏佽銆�
+     * 瀹℃牳閫氳繃缃负寰呭綊妗o紱瀹℃牳涓嶉�氳繃蹇呴』濉啓鍘熷洜锛岄��鍥炲緟瀹℃牳鐘舵�佸彲淇敼鍚庨噸鏂版彁浜ゃ��
+     *
+     * @param id           缂栧彿
+     * @param pass         鏄惁閫氳繃锛宼rue=閫氳繃 / false=涓嶉�氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛屽鏍镐笉閫氳繃鏃跺繀濉�
      */
-    void updateProjectAuditStatus(Long id, Integer bpmResult);
+    void auditProject(Long id, Boolean pass, String reviewRemark);
 
     /**
      * 褰掓。璁捐椤圭洰锛堝緟褰掓。鈫掑凡褰掓。锛�
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectServiceImpl.java
index 6648c60..3869a63 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectServiceImpl.java
@@ -1,14 +1,7 @@
 package cn.iocoder.yudao.module.mes.service.pd.project;
 
-import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pd.document.MesPdDocumentDO;
@@ -22,22 +15,22 @@
 import cn.iocoder.yudao.module.mes.enums.pd.MesPdProjectStatusEnum;
 import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
 import cn.iocoder.yudao.module.mes.service.pd.document.MesPdDocumentService;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import java.time.LocalDateTime;
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
@@ -55,9 +48,11 @@
 public class MesPdProjectServiceImpl implements MesPdProjectService {
 
     /**
-     * BPM 浜у搧椤圭洰瀹℃壒鍒嗙被缂栫爜
+     * 璁捐椤圭洰瀹℃壒鐨勪笟鍔$被鍨嬬紪鐮�
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鏍镐汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
      */
-    private static final String BPM_PROCESS_DEFINITION_CATEGORY_CODE = "mes_pd_project_approve";
+    private static final String PROJECT_APPROVE_BIZ_TYPE = "mes_pd_project_approve";
 
     @Resource
     private MesPdProjectMapper projectMapper;
@@ -77,13 +72,10 @@
     private MesMdAutoCodeRecordService autoCodeRecordService;
 
     @Resource
-    private BpmProcessInstanceApi processInstanceApi;
+    private AdminUserApi adminUserApi;
 
     @Resource
-    private BpmCategoryService bpmCategoryService;
-
-    @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private ApprovalConfigApi approvalConfigApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -210,7 +202,7 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitProjectApproval(Long id, String processDefinitionKey) {
+    public void submitProjectApproval(Long id) {
         // 1. 鏍¢獙瀛樺湪 + 寰呭鏍哥姸鎬�
         MesPdProjectDO project = validateProjectExists(id);
         if (!MesPdProjectStatusEnum.UPLOAD.getStatus().equals(project.getStatus())) {
@@ -222,89 +214,55 @@
         if (documentAuditMapper.existsPendingAuditByDocumentIds(documentIds)) {
             throw exception(PD_PROJECT_AUDIT_NOT_FINISHED);
         }
-        // 3. 鍒涘缓 BPM 娴佺▼瀹炰緥
-        String processInstanceId = processInstanceApi.createProcessInstance(getLoginUserId(),
-                new BpmProcessInstanceCreateReqDTO()
-                        .setProcessDefinitionKey(processDefinitionKey)
-                        .setBusinessKey(String.valueOf(id)));
-        // 4. 鏇存柊椤圭洰鐘舵�佷负瀹℃壒涓�
-        projectMapper.updateById(MesPdProjectDO.builder()
-                .id(id)
-                .status(MesPdProjectStatusEnum.APPROVING.getStatus())
-                .processInstanceId(processInstanceId)
-                .processDefinitionKey(processDefinitionKey)
-                .build());
+        // 3. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鏍镐汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(PROJECT_APPROVE_BIZ_TYPE);
+        // 4. 鐘舵�佺疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+        projectMapper.submitAndResetAuditInfo(id, MesPdProjectStatusEnum.APPROVING.getStatus());
     }
 
     @Override
-    public List<Map<String, Object>> getProjectApproveProcessDefinitionList() {
-        // 1. 鏍¢獙鍒嗙被鏄惁瀛樺湪
-        List<BpmCategoryDO> categories = bpmCategoryService.getCategoryListByCode(
-                Collections.singletonList(BPM_PROCESS_DEFINITION_CATEGORY_CODE));
-        if (CollUtil.isEmpty(categories)) {
-            throw exception(PD_PROJECT_BPM_CATEGORY_NOT_EXISTS);
-        }
-        // 2. 鑾峰彇鍒嗙被涓嬬殑娴佺▼瀹氫箟淇℃伅
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(BPM_PROCESS_DEFINITION_CATEGORY_CODE);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            return Collections.emptyList();
-        }
-        // 3. 杩囨护婵�娲荤姸鎬侊紝淇濈暀鏈�鏂扮増鏈�
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (BpmProcessDefinitionInfoDO info : definitionInfoList) {
-            ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId());
-            if (pd == null || pd.isSuspended()) {
-                continue;
-            }
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-        // 4. 杩斿洖娴佺▼瀹氫箟鍒楄〃
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            result.add(item);
-        }
-        return result;
+    public Set<Long> getProjectApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(PROJECT_APPROVE_BIZ_TYPE);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void updateProjectAuditStatus(Long id, Integer bpmResult) {
+    public void auditProject(Long id, Boolean pass, String reviewRemark) {
         // 1. 鏍¢獙瀛樺湪
         MesPdProjectDO project = validateProjectExists(id);
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
         if (!MesPdProjectStatusEnum.APPROVING.getStatus().equals(project.getStatus())) {
-            log.warn("[updateProjectAuditStatus] 璁捐椤圭洰({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵�侊細{}", id, project.getStatus());
+            throw exception(PD_PROJECT_NOT_APPROVING);
+        }
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鏍镐汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(PROJECT_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝閫�鍥炲緟瀹℃牳鐘舵�侊紝鍙慨鏀瑰悗閲嶆柊鎻愪氦
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(PD_PROJECT_AUDIT_REJECT_REASON_REQUIRED);
+            }
+            projectMapper.auditProject(id, MesPdProjectStatusEnum.UPLOAD.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
             return;
         }
-        // 2. 鏍规嵁瀹℃壒缁撴灉鏇存柊鐘舵��
-        Integer newStatus = convertBpmResultToProjectStatus(bpmResult);
-        if (newStatus != null) {
-            projectMapper.updateById(MesPdProjectDO.builder()
-                    .id(id)
-                    .status(newStatus)
-                    .build());
-        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄緟褰掓。
+        projectMapper.auditProject(id, MesPdProjectStatusEnum.AUDIT.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
     }
 
     /**
-     * 杞崲 BPM 瀹℃壒缁撴灉涓鸿璁¢」鐩姸鎬�
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
      */
-    private Integer convertBpmResultToProjectStatus(Integer bpmResult) {
-        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
-            return MesPdProjectStatusEnum.AUDIT.getStatus();
-        } else if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
-            return MesPdProjectStatusEnum.UPLOAD.getStatus();
-        } else if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
-            return MesPdProjectStatusEnum.UPLOAD.getStatus();
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
         }
-        return null;
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
     @Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/listener/MesPdProjectStatusListener.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/listener/MesPdProjectStatusListener.java
deleted file mode 100644
index 31402d1..0000000
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/listener/MesPdProjectStatusListener.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package cn.iocoder.yudao.module.mes.service.pd.project.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener;
-import cn.iocoder.yudao.module.mes.service.pd.project.MesPdProjectService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-/**
- * 璁捐椤圭洰瀹℃壒鐘舵�佺洃鍚櫒
- *
- * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝鏇存柊璁捐椤圭洰鐨勫鎵圭姸鎬�
- *
- * @author 瓒呯骇绠$悊鍛�
- */
-@Component
-@Slf4j
-public class MesPdProjectStatusListener extends BpmProcessInstanceStatusEventListener {
-
-    /**
-     * BPM 璁捐椤圭洰瀹℃壒娴佺▼瀹氫箟 key
-     */
-    private static final String BPM_PROCESS_DEFINITION_KEY = "mes-pd-project-audit";
-
-    @Resource
-    private MesPdProjectService projectService;
-
-    @Override
-    protected String getProcessDefinitionKey() {
-        return BPM_PROCESS_DEFINITION_KEY;
-    }
-
-    @Override
-    protected void onEvent(BpmProcessInstanceStatusEvent event) {
-        Long projectId;
-        try {
-            projectId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勮璁¢」鐩紪鍙�", event.getBusinessKey());
-            return;
-        }
-        log.info("[onEvent] 鏀跺埌BPM瀹℃壒浜嬩欢锛宲rojectId={}, status={}", projectId, event.getStatus());
-        projectService.updateProjectAuditStatus(projectId, event.getStatus());
-    }
-
-}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmService.java
index 8192ac3..8293229 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmService.java
@@ -5,21 +5,109 @@
 import cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo.ProductTechConfirmSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pd.techconfirm.ProductTechConfirmDO;
 
+import java.util.Set;
+
 /**
  * MES 浜у搧鎶�鏈‘璁ゅ嚱 Service 鎺ュ彛
+ *
+ * 鐘舵�佹祦杞畬鍏ㄧ敱涓氬姟娴佺▼椹卞姩锛屼笉鎺ュ彈鍓嶇鐩存帴鎸囧畾鐘舵�侊細
+ * <pre>
+ *   0 鑽夌 --鎻愪氦瀹℃牳--> 1 寰呭鏍� --瀹℃牳閫氳繃--> 2 宸插鏍� --瀹㈡埛纭--> 3 瀹㈡埛宸茬‘璁�
+ *      ^                    |
+ *      |                    +--瀹℃牳涓嶉�氳繃--> 4 瀹℃牳涓嶉�氳繃
+ *      |                                        |
+ *      +----------------------------------------+  瀹℃牳涓嶉�氳繃鍙慨鏀瑰悗閲嶆柊鎻愪氦
+ * </pre>
+ * 鍙湁鑽夌涓庡鏍镐笉閫氳繃鐘舵�佸厑璁镐慨鏀逛笟鍔″瓧娈碉紝寰呭鏍� / 宸插鏍� / 瀹㈡埛宸茬‘璁や负閿佸畾鎴栫粓鎬併��
  *
  * @author 瓒呯骇绠$悊鍛�
  */
 public interface ProductTechConfirmService {
 
+    /**
+     * 鍒涘缓鎶�鏈‘璁ゅ嚱
+     *
+     * 鐘舵�佸浐瀹氫负鑽夌锛岀紪鍒朵汉 / 缂栧埗鏃堕棿鍙栧綋鍓嶇櫥褰曠敤鎴蜂笌褰撳墠鏃堕棿銆�
+     *
+     * @param createReqVO 鍒涘缓淇℃伅
+     * @return 缂栧彿
+     */
     Long createTechConfirm(ProductTechConfirmSaveReqVO createReqVO);
 
+    /**
+     * 淇敼鎶�鏈‘璁ゅ嚱
+     *
+     * 浠呰崏绋夸笌瀹℃牳涓嶉�氳繃鐘舵�佸厑璁镐慨鏀癸紝鍏朵綑鐘舵�佷竴寰嬫嫆缁濄��
+     *
+     * @param updateReqVO 淇敼淇℃伅
+     */
     void updateTechConfirm(ProductTechConfirmSaveReqVO updateReqVO);
 
+    /**
+     * 鍒犻櫎鎶�鏈‘璁ゅ嚱
+     *
+     * 浠呰崏绋夸笌瀹℃牳涓嶉�氳繃鐘舵�佸厑璁稿垹闄ゃ��
+     *
+     * @param id 缂栧彿
+     */
     void deleteTechConfirm(Long id);
 
+    /**
+     * 鑾峰緱鎶�鏈‘璁ゅ嚱
+     *
+     * @param id 缂栧彿
+     * @return 鎶�鏈‘璁ゅ嚱
+     */
     ProductTechConfirmDO getTechConfirm(Long id);
 
+    /**
+     * 鑾峰緱鎶�鏈‘璁ゅ嚱鍒嗛〉
+     *
+     * @param pageReqVO 鍒嗛〉鏌ヨ
+     * @return 鎶�鏈‘璁ゅ嚱鍒嗛〉
+     */
     PageResult<ProductTechConfirmDO> getTechConfirmPage(ProductTechConfirmPageReqVO pageReqVO);
 
+    /**
+     * 鎻愪氦瀹℃牳锛堣崏绋� / 瀹℃牳涓嶉�氳繃 鈫� 寰呭鏍革級
+     *
+     * 瀹℃牳浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� pd_tech_confirm_approve锛夛紝
+     * 鎻愪氦鏃舵棤闇�鎸囧畾锛涙湭鍚敤瀹℃壒鎴栨湭閰嶇疆鏈夋晥瀹℃牳浜烘椂鎶涘嚭涓氬姟寮傚父銆�
+     *
+     * @param id 缂栧彿
+     */
+    void submitTechConfirmAudit(Long id);
+
+    /**
+     * 鑾峰緱鎶�鏈‘璁ゅ嚱瀹℃牳鐨勫鏍镐汉缂栧彿闆嗗悎
+     *
+     * 渚涘墠绔垽鏂綋鍓嶇櫥褰曠敤鎴锋槸鍚﹀簲灞曠ず銆屽鏍搞�嶆寜閽紱鏈厤缃椂杩斿洖绌洪泦鍚堛��
+     *
+     * @return 瀹℃牳浜虹敤鎴风紪鍙烽泦鍚�
+     */
+    Set<Long> getTechConfirmApproverUserIds();
+
+    /**
+     * 瀹℃牳鎶�鏈‘璁ゅ嚱锛堝緟瀹℃牳 鈫� 宸插鏍� / 瀹℃牳涓嶉�氳繃锛�
+     *
+     * 浠呬笟鍔$紪鐮� pd_tech_confirm_approve 閰嶇疆鐨勫鏍镐汉鍙搷浣滐紙澶氫汉鏃舵垨绛撅級锛屼笖浠呭湪寰呭鏍哥姸鎬佷笅鍏佽銆�
+     * 瀹℃牳閫氳繃璁板綍瀹℃牳浜轰笌瀹℃牳鏃堕棿锛涘鏍镐笉閫氳繃蹇呴』濉啓涓嶉�氳繃鍘熷洜锛�
+     * 浣垮崟鎹��鍥炲彲淇敼鐘舵�侊紝鐢辩紪鍒朵汉淇敼鍚庨噸鏂版彁浜ゃ��
+     *
+     * @param id           缂栧彿
+     * @param pass         鏄惁閫氳繃锛宼rue=閫氳繃 / false=涓嶉�氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛屽鏍镐笉閫氳繃鏃跺繀濉�
+     */
+    void auditTechConfirm(Long id, Boolean pass, String reviewRemark);
+
+    /**
+     * 瀹㈡埛纭锛堝凡瀹℃牳 鈫� 瀹㈡埛宸茬‘璁わ級
+     *
+     * 鐢变笟鍔″憳浠e鎴锋墽琛岋紝璁板綍瀹㈡埛纭浜轰笌瀹㈡埛纭鏃堕棿銆�
+     *
+     * @param id                  缂栧彿
+     * @param customerConfirmUser 瀹㈡埛纭浜哄鍚�
+     */
+    void confirmTechConfirmByCustomer(Long id, String customerConfirmUser);
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmServiceImpl.java
index 155c10e..07a031f 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/techconfirm/ProductTechConfirmServiceImpl.java
@@ -1,56 +1,108 @@
 package cn.iocoder.yudao.module.mes.service.pd.techconfirm;
 
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo.ProductTechConfirmPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pd.techconfirm.vo.ProductTechConfirmSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pd.techconfirm.ProductTechConfirmDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.pd.techconfirm.ProductTechConfirmMapper;
+import cn.iocoder.yudao.module.mes.enums.pd.MesPdTechConfirmStatusEnum;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
+import java.time.LocalDateTime;
+import java.util.Set;
+
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PD_TECH_CONFIRM_NOT_EXISTS;
-import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PD_TECH_CONFIRM_NO_DUPLICATE;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
+import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
 
 /**
  * MES 浜у搧鎶�鏈‘璁ゅ嚱 Service 瀹炵幇绫�
+ *
+ * 鐘舵�佸畬鍏ㄧ敱涓氬姟娴佺▼椹卞姩锛屽墠绔笉鍙備笌鐘舵�佽祴鍊笺�傚悇鐘舵�佺殑鍐欏叆鍏ュ彛涓ユ牸鍖哄垎锛�
+ * <ul>
+ *     <li>鑽夌锛歿@link #createTechConfirm} 鍒涘缓鏃跺啓鍏ワ紱{@link #auditTechConfirm} 瀹㈡埛纭琚┏鍥炴椂鍥為��</li>
+ *     <li>寰呭鏍革細{@link #submitTechConfirmAudit} 鎻愪氦瀹℃牳鍚庡啓鍏ワ紝鍚屾椂璁板綍缂栧埗浜烘寚瀹氱殑瀹℃牳浜�</li>
+ *     <li>宸插鏍革細{@link #auditTechConfirm} 瀹℃牳閫氳繃鏃跺啓鍏ワ紝鍚屾椂璁板綍瀹℃牳鏃堕棿涓庡鏍告剰瑙�</li>
+ *     <li>瀹℃牳涓嶉�氳繃锛歿@link #auditTechConfirm} 瀹℃牳涓嶉�氳繃鏃跺啓鍏ワ紝淇濈暀涓嶉�氳繃鍘熷洜渚涚紪鍒朵汉淇敼鍚庨噸鏂版彁浜�</li>
+ *     <li>瀹㈡埛宸茬‘璁わ細{@link #confirmTechConfirmByCustomer} 瀹㈡埛纭鍚庡啓鍏�</li>
+ * </ul>
  *
  * @author 瓒呯骇绠$悊鍛�
  */
 @Service
 @Validated
+@Slf4j
 public class ProductTechConfirmServiceImpl implements ProductTechConfirmService {
+
+    /**
+     * 鎶�鏈‘璁ゅ嚱瀹℃壒鐨勪笟鍔$被鍨嬬紪鐮�
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鏍镐汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
+     */
+    private static final String TECH_CONFIRM_APPROVE_BIZ_TYPE = "pd_tech_confirm_approve";
 
     @Resource
     private ProductTechConfirmMapper techConfirmMapper;
 
+    @Resource
+    private AdminUserApi adminUserApi;
+
+    @Resource
+    private ApprovalConfigApi approvalConfigApi;
+
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Long createTechConfirm(ProductTechConfirmSaveReqVO createReqVO) {
         // 鏍¢獙纭鍑界紪鍙峰敮涓�
         validateConfirmNoUnique(createReqVO.getConfirmNo(), null);
-        // 鎻掑叆
+        // 鎻掑叆锛氱姸鎬佸浐瀹氫负鑽夌锛岀紪鍒朵汉 / 缂栧埗鏃堕棿鍙栧綋鍓嶇櫥褰曠敤鎴蜂笌褰撳墠鏃堕棿
+        Long userId = getLoginUserId();
         ProductTechConfirmDO techConfirm = BeanUtils.toBean(createReqVO, ProductTechConfirmDO.class);
+        techConfirm.setStatus(MesPdTechConfirmStatusEnum.DRAFT.getStatus());
+        techConfirm.setDrafterId(userId);
+        techConfirm.setDrafterName(getUserNickname(userId));
+        techConfirm.setDraftTime(LocalDateTime.now());
+        // 瀹℃牳浜虹敱鎻愪氦瀹℃牳鏃舵寚瀹氾紝鍒涘缓鏃舵竻绌猴紝閬垮厤鍓嶇浼犲弬甯﹀叆
+        techConfirm.setReviewerId(null);
+        techConfirm.setReviewerName(null);
+        techConfirm.setReviewTime(null);
+        techConfirm.setReviewRemark(null);
+        techConfirm.setCustomerConfirmUser(null);
+        techConfirm.setCustomerConfirmTime(null);
         techConfirmMapper.insert(techConfirm);
         return techConfirm.getId();
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updateTechConfirm(ProductTechConfirmSaveReqVO updateReqVO) {
         // 鏍¢獙瀛樺湪
-        validateTechConfirmExists(updateReqVO.getId());
+        ProductTechConfirmDO techConfirm = validateTechConfirmExists(updateReqVO.getId());
+        // 鏍¢獙鐘舵�佷负鑽夌鎴栧鏍镐笉閫氳繃
+        validateTechConfirmEditable(techConfirm);
         // 鏍¢獙纭鍑界紪鍙峰敮涓�锛堟帓闄よ嚜韬級
         validateConfirmNoUnique(updateReqVO.getConfirmNo(), updateReqVO.getId());
-        // 鏇存柊
+        // 鏇存柊锛氱姸鎬併�佺紪鍒朵汉銆佸鏍镐汉銆佸鎴风‘璁や汉绛夋祦绋嬪瓧娈典竴寰嬩笉鎺ユ敹鍓嶇浼犲弬锛屾澶勫彧钀戒笟鍔″瓧娈�
         ProductTechConfirmDO updateObj = BeanUtils.toBean(updateReqVO, ProductTechConfirmDO.class);
         techConfirmMapper.updateById(updateObj);
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void deleteTechConfirm(Long id) {
         // 鏍¢獙瀛樺湪
-        validateTechConfirmExists(id);
+        ProductTechConfirmDO techConfirm = validateTechConfirmExists(id);
+        // 鏍¢獙鐘舵�佷负鑽夌鎴栧鏍镐笉閫氳繃
+        validateTechConfirmEditable(techConfirm);
         // 鍒犻櫎
         techConfirmMapper.deleteById(id);
     }
@@ -63,6 +115,85 @@
     @Override
     public PageResult<ProductTechConfirmDO> getTechConfirmPage(ProductTechConfirmPageReqVO pageReqVO) {
         return techConfirmMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void submitTechConfirmAudit(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鍙彁浜ょ姸鎬侊紙鑽夌 / 瀹℃牳涓嶉�氳繃锛�
+        ProductTechConfirmDO techConfirm = validateTechConfirmExists(id);
+        if (!MesPdTechConfirmStatusEnum.DRAFT.getStatus().equals(techConfirm.getStatus())
+                && !MesPdTechConfirmStatusEnum.REJECTED.getStatus().equals(techConfirm.getStatus())) {
+            throw exception(PD_TECH_CONFIRM_NOT_EDITABLE_FOR_SUBMIT);
+        }
+        // 2. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鏍镐汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(TECH_CONFIRM_APPROVE_BIZ_TYPE);
+        // 3. 鏇存柊鐘舵�佷负寰呭鏍革紝骞舵竻绌轰笂涓�杞鏍哥粨鏋�
+        //    鐢� UpdateWrapper 鑰岄潪 updateById锛歁yBatis-Plus 榛樿鏇存柊绛栫暐浼氬拷鐣� null锛�
+        //    鐩存帴 updateById 鏃犳硶鎶婂鏍镐笉閫氳繃鍚庢畫鐣欑殑瀹℃牳浜� / 瀹℃牳鏃堕棿 / 瀹℃牳鎰忚鐪熸娓呯┖銆�
+        techConfirmMapper.submitAndResetAuditInfo(id, MesPdTechConfirmStatusEnum.PENDING_AUDIT.getStatus());
+    }
+
+    @Override
+    public Set<Long> getTechConfirmApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(TECH_CONFIRM_APPROVE_BIZ_TYPE);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void auditTechConfirm(Long id, Boolean pass, String reviewRemark) {
+        // 1. 鏍¢獙瀛樺湪
+        ProductTechConfirmDO techConfirm = validateTechConfirmExists(id);
+        // 2. 鏍¢獙澶勪簬寰呭鏍哥姸鎬�
+        if (!MesPdTechConfirmStatusEnum.PENDING_AUDIT.getStatus().equals(techConfirm.getStatus())) {
+            throw exception(PD_TECH_CONFIRM_NOT_PENDING_AUDIT);
+        }
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鏍镐汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(TECH_CONFIRM_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝鐘舵�佺疆涓哄鏍镐笉閫氳繃锛岄��鍥炵紪鍒朵汉淇敼鍚庡彲閲嶆柊鎻愪氦
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(PD_TECH_CONFIRM_REJECT_REASON_REQUIRED);
+            }
+            techConfirmMapper.auditTechConfirm(id, MesPdTechConfirmStatusEnum.REJECTED.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
+            return;
+        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄凡瀹℃牳
+        techConfirmMapper.auditTechConfirm(id, MesPdTechConfirmStatusEnum.AUDITED.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void confirmTechConfirmByCustomer(Long id, String customerConfirmUser) {
+        // 1. 鏍¢獙瀛樺湪 + 宸插鏍哥姸鎬�
+        ProductTechConfirmDO techConfirm = validateTechConfirmExists(id);
+        if (!MesPdTechConfirmStatusEnum.AUDITED.getStatus().equals(techConfirm.getStatus())) {
+            throw exception(PD_TECH_CONFIRM_NOT_AUDITED_FOR_CUSTOMER_CONFIRM);
+        }
+        // 2. 鏇存柊鐘舵�佷负瀹㈡埛宸茬‘璁わ紝骞惰褰曞鎴风‘璁や汉涓庣‘璁ゆ椂闂�
+        techConfirmMapper.updateById(ProductTechConfirmDO.builder()
+                .id(id)
+                .status(MesPdTechConfirmStatusEnum.CUSTOMER_CONFIRMED.getStatus())
+                .customerConfirmUser(customerConfirmUser)
+                .customerConfirmTime(LocalDateTime.now())
+                .build());
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
+        }
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
     private void validateConfirmNoUnique(String confirmNo, Long excludeId) {
@@ -84,4 +215,19 @@
         return techConfirm;
     }
 
+    /**
+     * 鏍¢獙鎶�鏈‘璁ゅ嚱澶勪簬鍙慨鏀圭姸鎬�
+     *
+     * 鍙湁鑽夌涓庡鏍镐笉閫氳繃鍏佽淇敼涓庡垹闄わ紱寰呭鏍� / 宸插鏍� / 瀹㈡埛宸茬‘璁や负閿佸畾鎴栫粓鎬併��
+     * 瀹℃牳涓嶉�氳繃鐨勫崟鎹渶閫�鍥炵粰缂栧埗浜轰慨鏀瑰悗閲嶆柊鎻愪氦锛屽洜姝ゅ悓鏍锋斁寮�銆�
+     *
+     * @param techConfirm 鎶�鏈‘璁ゅ嚱
+     */
+    private void validateTechConfirmEditable(ProductTechConfirmDO techConfirm) {
+        if (!MesPdTechConfirmStatusEnum.DRAFT.getStatus().equals(techConfirm.getStatus())
+                && !MesPdTechConfirmStatusEnum.REJECTED.getStatus().equals(techConfirm.getStatus())) {
+            throw exception(PD_TECH_CONFIRM_NOT_EDITABLE);
+        }
+    }
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/MesWmEquipmentReceiptService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/MesWmEquipmentReceiptService.java
index 1c8a618..ee49b25 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/MesWmEquipmentReceiptService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/MesWmEquipmentReceiptService.java
@@ -6,12 +6,9 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt.MesWmEquipmentReceiptDO;
 import jakarta.validation.Valid;
 
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 public interface MesWmEquipmentReceiptService {
-
-    String APPROVE_CATEGORY_CODE = "equipment_receipt_approve";
 
     Long createEquipmentReceipt(@Valid MesWmEquipmentReceiptSaveReqVO createReqVO);
 
@@ -23,11 +20,36 @@
 
     PageResult<MesWmEquipmentReceiptDO> getEquipmentReceiptPage(MesWmEquipmentReceiptPageReqVO pageReqVO);
 
-    void submitEquipmentReceiptApproval(Long id, String processDefinitionKey);
+    /**
+     * 鎻愪氦璁惧鍏ュ簱鍗曞鎵癸紙鑽夌 鈫� 瀹℃壒涓級
+     *
+     * 瀹℃牳浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� equipment_receipt_approve锛夛紝
+     * 鎻愪氦鏃舵棤闇�鎸囧畾锛涙湭鍚敤瀹℃壒鎴栨湭閰嶇疆鏈夋晥瀹℃牳浜烘椂鎶涘嚭涓氬姟寮傚父銆�
+     *
+     * @param id 缂栧彿
+     */
+    void submitEquipmentReceiptApproval(Long id);
 
-    void updateEquipmentReceiptAuditStatus(Long id, Integer bpmResult);
+    /**
+     * 鑾峰緱璁惧鍏ュ簱鍗曞鎵圭殑瀹℃牳浜虹紪鍙烽泦鍚�
+     *
+     * 渚涘墠绔垽鏂綋鍓嶇櫥褰曠敤鎴锋槸鍚﹀簲灞曠ず銆屽鏍搞�嶆寜閽紱鏈厤缃椂杩斿洖绌洪泦鍚堛��
+     *
+     * @return 瀹℃牳浜虹敤鎴风紪鍙烽泦鍚�
+     */
+    Set<Long> getEquipmentReceiptApproverUserIds();
 
-    List<Map<String, Object>> getEquipmentReceiptApprovalProcessDefinitionList();
+    /**
+     * 瀹℃牳璁惧鍏ュ簱鍗曪紙瀹℃壒涓� 鈫� 宸插鎵� / 鑽夌锛�
+     *
+     * 浠呬笟鍔$紪鐮� equipment_receipt_approve 閰嶇疆鐨勫鏍镐汉鍙搷浣滐紙澶氫汉鏃舵垨绛撅級锛屼笖浠呭湪瀹℃壒涓姸鎬佷笅鍏佽銆�
+     * 瀹℃牳閫氳繃缃负宸插鎵癸紙鍙墽琛屽叆搴擄級锛涘鏍镐笉閫氳繃蹇呴』濉啓鍘熷洜锛岄��鍥炶崏绋垮彲淇敼鍚庨噸鏂版彁浜ゃ��
+     *
+     * @param id           缂栧彿
+     * @param pass         鏄惁閫氳繃锛宼rue=閫氳繃 / false=涓嶉�氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛屽鏍镐笉閫氳繃鏃跺繀濉�
+     */
+    void auditEquipmentReceipt(Long id, Boolean pass, String reviewRemark);
 
     void finishEquipmentReceipt(Long id);
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/MesWmEquipmentReceiptServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/MesWmEquipmentReceiptServiceImpl.java
index 4b6c700..3ffe92d 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/MesWmEquipmentReceiptServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/MesWmEquipmentReceiptServiceImpl.java
@@ -2,13 +2,9 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.MesWmEquipmentReceiptPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.equipmentreceipt.vo.MesWmEquipmentReceiptSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.equipmentreceipt.MesWmEquipmentReceiptDO;
@@ -25,21 +21,23 @@
 import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
 import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
 import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.context.annotation.Lazy;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import java.math.BigDecimal;
-import java.util.*;
+import java.util.List;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
 
 /**
@@ -49,6 +47,13 @@
 @Validated
 @Slf4j
 public class MesWmEquipmentReceiptServiceImpl implements MesWmEquipmentReceiptService {
+
+    /**
+     * 璁惧鍏ュ簱鍗曞鎵圭殑涓氬姟绫诲瀷缂栫爜
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鏍镐汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
+     */
+    private static final String EQUIPMENT_RECEIPT_APPROVE_BIZ_TYPE = "equipment_receipt_approve";
 
     @Resource
     private MesWmEquipmentReceiptMapper equipmentReceiptMapper;
@@ -64,9 +69,9 @@
     @Resource
     private MesWmWarehouseAreaService wmAreaService;
     @Resource
-    private BpmProcessInstanceApi processInstanceApi;
+    private AdminUserApi adminUserApi;
     @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private ApprovalConfigApi approvalConfigApi;
 
     @Override
     public Long createEquipmentReceipt(MesWmEquipmentReceiptSaveReqVO createReqVO) {
@@ -114,95 +119,63 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitEquipmentReceiptApproval(Long id, String processDefinitionKey) {
-        // 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
+    public void submitEquipmentReceiptApproval(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
         validateEquipmentReceiptExistsAndPrepare(id);
-        // 鏍¢獙鑷冲皯鏈変竴鏉¤
+        // 2. 鏍¢獙鑷冲皯鏈変竴鏉¤
         List<MesWmEquipmentReceiptLineDO> lines = equipmentReceiptLineService.getEquipmentReceiptLineListByReceiptId(id);
         if (CollUtil.isEmpty(lines)) {
             throw exception(WM_EQUIP_RECEIPT_NO_LINE);
         }
-        // 鍒涘缓 BPM 娴佺▼瀹炰緥
-        String processInstanceId = processInstanceApi.createProcessInstance(getCurrentUserId(),
-                new BpmProcessInstanceCreateReqDTO()
-                        .setProcessDefinitionKey(processDefinitionKey)
-                        .setBusinessKey(String.valueOf(id)));
-        // 鎻愪氦瀹℃壒锛堣崏绋� 鈫� 瀹℃壒涓級
-        equipmentReceiptMapper.updateById(new MesWmEquipmentReceiptDO()
-                .setId(id)
-                .setStatus(MesWmEquipmentReceiptStatusEnum.APPROVING.getStatus())
-                .setProcessInstanceId(processInstanceId));
+        // 3. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鏍镐汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(EQUIPMENT_RECEIPT_APPROVE_BIZ_TYPE);
+        // 4. 鐘舵�佺疆涓哄鎵逛腑锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+        equipmentReceiptMapper.submitAndResetAuditInfo(id, MesWmEquipmentReceiptStatusEnum.APPROVING.getStatus());
     }
 
     @Override
-    public List<Map<String, Object>> getEquipmentReceiptApprovalProcessDefinitionList() {
-        return getProcessDefinitionListByCategory(APPROVE_CATEGORY_CODE);
+    public Set<Long> getEquipmentReceiptApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(EQUIPMENT_RECEIPT_APPROVE_BIZ_TYPE);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void updateEquipmentReceiptAuditStatus(Long id, Integer bpmResult) {
+    public void auditEquipmentReceipt(Long id, Boolean pass, String reviewRemark) {
         // 1. 鏍¢獙瀛樺湪
         MesWmEquipmentReceiptDO receipt = validateEquipmentReceiptExists(id);
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
         if (!MesWmEquipmentReceiptStatusEnum.APPROVING.getStatus().equals(receipt.getStatus())) {
-            log.warn("[updateEquipmentReceiptAuditStatus] 璁惧鍏ュ簱鍗�({}) 涓嶅浜庡鎵逛腑鐘舵��", id);
+            throw exception(WM_EQUIP_RECEIPT_NOT_APPROVING);
+        }
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鏍镐汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(EQUIPMENT_RECEIPT_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝閫�鍥炶崏绋垮彲淇敼鍚庨噸鏂版彁浜�
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(WM_EQUIP_RECEIPT_REJECT_REASON_REQUIRED);
+            }
+            equipmentReceiptMapper.auditEquipmentReceipt(id, MesWmEquipmentReceiptStatusEnum.PREPARE.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
             return;
         }
-        // 2. 鏍规嵁瀹℃壒缁撴灉鏇存柊鐘舵��
-        Integer newStatus = convertBpmResultToStatus(bpmResult);
-        if (newStatus != null) {
-            equipmentReceiptMapper.updateById(new MesWmEquipmentReceiptDO().setId(id).setStatus(newStatus));
-        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄凡瀹℃壒锛堝彲鎵ц鍏ュ簱锛�
+        equipmentReceiptMapper.auditEquipmentReceipt(id, MesWmEquipmentReceiptStatusEnum.APPROVED.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
     }
 
-    private Integer convertBpmResultToStatus(Integer bpmResult) {
-        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
-            return MesWmEquipmentReceiptStatusEnum.APPROVED.getStatus();
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
         }
-        if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
-            return MesWmEquipmentReceiptStatusEnum.PREPARE.getStatus();
-        }
-        if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
-            return MesWmEquipmentReceiptStatusEnum.CANCELED.getStatus();
-        }
-        return null;
-    }
-
-    private List<Map<String, Object>> getProcessDefinitionListByCategory(String categoryCode) {
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(categoryCode);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            return Collections.emptyList();
-        }
-        // 杩囨护婵�娲荤姸鎬侊紝淇濈暀鏈�鏂扮増鏈�
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (BpmProcessDefinitionInfoDO info : definitionInfoList) {
-            ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId());
-            if (pd == null || pd.isSuspended()) {
-                continue;
-            }
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            result.add(item);
-        }
-        return result;
-    }
-
-    private Long getCurrentUserId() {
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof Long) {
-            return (Long) authentication.getPrincipal();
-        }
-        return 1L; // 榛樿鐢ㄦ埛
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
     @Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/listener/MesWmEquipmentReceiptStatusListener.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/listener/MesWmEquipmentReceiptStatusListener.java
deleted file mode 100644
index 1112504..0000000
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/equipmentreceipt/listener/MesWmEquipmentReceiptStatusListener.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package cn.iocoder.yudao.module.mes.service.wm.equipmentreceipt.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.mes.service.wm.equipmentreceipt.MesWmEquipmentReceiptService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-/**
- * 璁惧鍏ュ簱鍗� BPM 瀹℃壒鐘舵�佺洃鍚櫒
- */
-@Component
-@Slf4j
-public class MesWmEquipmentReceiptStatusListener
-        extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener {
-
-    @Resource
-    private MesWmEquipmentReceiptService equipmentReceiptService;
-
-    @Override
-    protected String getProcessDefinitionKey() {
-        return MesWmEquipmentReceiptService.APPROVE_CATEGORY_CODE;
-    }
-
-    @Override
-    protected void onEvent(BpmProcessInstanceStatusEvent event) {
-        Long id;
-        try {
-            id = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勮澶囧叆搴撳崟缂栧彿", event.getBusinessKey());
-            return;
-        }
-        log.info("[onEvent] 鏀跺埌BPM瀹℃壒浜嬩欢锛宔quipmentReceiptId={}, status={}", id, event.getStatus());
-        try {
-            equipmentReceiptService.updateEquipmentReceiptAuditStatus(id, event.getStatus());
-            log.info("[onEvent] 璁惧鍏ュ簱鍗�({}) 瀹℃壒鐘舵�佹洿鏂板畬鎴�", id);
-        } catch (Exception e) {
-            log.error("[onEvent] 鏇存柊璁惧鍏ュ簱鍗曞鎵圭姸鎬佸け璐ワ紝equipmentReceiptId={}", id, e);
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptService.java
index 487d2b6..038c8d0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptService.java
@@ -8,6 +8,7 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 
@@ -55,7 +56,10 @@
     PageResult<MesWmItemReceiptDO> getItemReceiptPage(MesWmItemReceiptPageReqVO pageReqVO);
 
     /**
-     * 鎻愪氦閲囪喘鍏ュ簱鍗曪紙鑽夌 鈫� 寰呬笂鏋讹級
+     * 鎻愪氦閲囪喘鍏ュ簱鍗曞鎵癸紙鑽夌 鈫� 寰呬笂鏋讹級
+     *
+     * 瀹℃牳浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� item_receipt_approve锛夛紝
+     * 鎻愪氦鏃舵棤闇�鎸囧畾锛涙湭鍚敤瀹℃壒鎴栨湭閰嶇疆鏈夋晥瀹℃牳浜烘椂鎶涘嚭涓氬姟寮傚父銆�
      *
      * @param id 缂栧彿
      */
@@ -133,19 +137,24 @@
     Long generateItemReceiptFromArrivalNotice(Long arrivalNoticeId);
 
     /**
-     * 鎻愪氦閲囪喘鍏ュ簱鍗曞鎵�
+     * 鑾峰緱閲囪喘鍏ュ簱鍗曞鎵圭殑瀹℃牳浜虹紪鍙烽泦鍚�
      *
-     * @param id 鍏ュ簱鍗曠紪鍙�
-     * @param processDefinitionKey 娴佺▼瀹氫箟 Key
+     * 渚涘墠绔垽鏂綋鍓嶇櫥褰曠敤鎴锋槸鍚﹀簲灞曠ず銆屽鏍搞�嶆寜閽紱鏈厤缃椂杩斿洖绌洪泦鍚堛��
+     *
+     * @return 瀹℃牳浜虹敤鎴风紪鍙烽泦鍚�
      */
-    void submitItemReceiptApproval(Long id, String processDefinitionKey);
+    Set<Long> getItemReceiptApproverUserIds();
 
     /**
-     * 鏇存柊閲囪喘鍏ュ簱鍗曞鎵圭姸鎬侊紙鐢� BPM Listener 鍥炶皟锛�
+     * 瀹℃牳閲囪喘鍏ュ簱鍗曪紙寰呬笂鏋� 鈫� 寰呮墽琛屽叆搴� / 鑽夌锛�
      *
-     * @param id 鍏ュ簱鍗曠紪鍙�
-     * @param bpmResult BPM 瀹℃壒缁撴灉
+     * 浠呬笟鍔$紪鐮� item_receipt_approve 閰嶇疆鐨勫鏍镐汉鍙搷浣滐紙澶氫汉鏃舵垨绛撅級锛屼笖浠呭湪寰呬笂鏋剁姸鎬佷笅鍏佽銆�
+     * 瀹℃牳閫氳繃缃负寰呮墽琛屽叆搴擄紱瀹℃牳涓嶉�氳繃蹇呴』濉啓鍘熷洜锛岄��鍥炶崏绋垮彲淇敼鍚庨噸鏂版彁浜ゃ��
+     *
+     * @param id           鍏ュ簱鍗曠紪鍙�
+     * @param pass         鏄惁閫氳繃锛宼rue=閫氳繃 / false=涓嶉�氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛屽鏍镐笉閫氳繃鏃跺繀濉�
      */
-    void updateItemReceiptAuditStatus(Long id, Integer bpmResult);
+    void auditItemReceipt(Long id, Boolean pass, String reviewRemark);
 
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java
index f15ad92..baadd8c 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java
@@ -16,21 +16,20 @@
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemReceiptStatusEnum;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
 import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcService;
 import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeService;
 import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeLineService;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
 import cn.iocoder.yudao.module.erp.api.purchase.PurchaseOrderApi;
 import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi;
 import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
 import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import cn.hutool.core.util.StrUtil;
 import jakarta.annotation.Resource;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
@@ -42,9 +41,11 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
 
 /**
@@ -54,6 +55,13 @@
 @Validated
 @Slf4j
 public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
+
+    /**
+     * 閲囪喘鍏ュ簱鍗曞鎵圭殑涓氬姟绫诲瀷缂栫爜
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鏍镐汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
+     */
+    private static final String ITEM_RECEIPT_APPROVE_BIZ_TYPE = "item_receipt_approve";
 
     @Resource
     private MesWmItemReceiptMapper itemReceiptMapper;
@@ -78,7 +86,10 @@
     private MesWmArrivalNoticeLineService arrivalNoticeLineService;
 
     @Resource
-    private BpmProcessInstanceApi processInstanceApi;
+    private AdminUserApi adminUserApi;
+
+    @Resource
+    private ApprovalConfigApi approvalConfigApi;
 
     @Resource
     private PurchaseOrderApi purchaseOrderApi;
@@ -165,9 +176,56 @@
         // 鏍¢獙鐗╂枡鎵规绠$悊锛氬鏋滅墿鏂欏紑鍚壒娆$鐞嗭紝鍒欐槑缁嗙殑鎵规鍙蜂笉鑳戒负绌�
         validateBatchManagement(lines);
 
-        // 鎻愪氦锛堣崏绋� 鈫� 寰呬笂鏋讹級
-        itemReceiptMapper.updateById(new MesWmItemReceiptDO()
-                .setId(id).setStatus(MesWmItemReceiptStatusEnum.APPROVING.getStatus()));
+        // 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鏍镐汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(ITEM_RECEIPT_APPROVE_BIZ_TYPE);
+
+        // 鎻愪氦锛堣崏绋� 鈫� 寰呬笂鏋讹級锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+        itemReceiptMapper.submitAndResetAuditInfo(id, MesWmItemReceiptStatusEnum.APPROVING.getStatus());
+    }
+
+    @Override
+    public Set<Long> getItemReceiptApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(ITEM_RECEIPT_APPROVE_BIZ_TYPE);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void auditItemReceipt(Long id, Boolean pass, String reviewRemark) {
+        // 1. 鏍¢獙瀛樺湪
+        MesWmItemReceiptDO receipt = validateItemReceiptExists(id);
+        // 2. 鏍¢獙澶勪簬寰呬笂鏋剁姸鎬�
+        if (!MesWmItemReceiptStatusEnum.APPROVING.getStatus().equals(receipt.getStatus())) {
+            throw exception(WM_ITEM_RECEIPT_NOT_APPROVING);
+        }
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鏍镐汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(ITEM_RECEIPT_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝閫�鍥炶崏绋垮彲淇敼鍚庨噸鏂版彁浜�
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(WM_ITEM_RECEIPT_REJECT_REASON_REQUIRED);
+            }
+            itemReceiptMapper.auditItemReceipt(id, MesWmItemReceiptStatusEnum.PREPARE.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
+            return;
+        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄緟鎵ц鍏ュ簱
+        itemReceiptMapper.auditItemReceipt(id, MesWmItemReceiptStatusEnum.APPROVED.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
+        }
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
     /**
@@ -443,69 +501,6 @@
         }
 
         return receipt.getId();
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void submitItemReceiptApproval(Long id, String processDefinitionKey) {
-        // 1. 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
-        validateItemReceiptExistsAndDraft(id);
-
-        // 2. 鍒涘缓 BPM 娴佺▼瀹炰緥
-        Long userId = getCurrentUserId();
-        String processInstanceId = processInstanceApi.createProcessInstance(userId,
-                new BpmProcessInstanceCreateReqDTO()
-                        .setProcessDefinitionKey(processDefinitionKey)
-                        .setBusinessKey(String.valueOf(id)));
-
-        // 3. 鏇存柊鍏ュ簱鍗曠姸鎬佷负瀹℃壒涓�
-        itemReceiptMapper.updateById(new MesWmItemReceiptDO()
-                .setId(id)
-                .setStatus(MesWmItemReceiptStatusEnum.APPROVING.getStatus())
-                .setProcessInstanceId(processInstanceId));
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void updateItemReceiptAuditStatus(Long id, Integer bpmResult) {
-        // 1. 鏍¢獙瀛樺湪
-        MesWmItemReceiptDO receipt = validateItemReceiptExists(id);
-        if (!MesWmItemReceiptStatusEnum.APPROVING.getStatus().equals(receipt.getStatus())) {
-            log.warn("[updateItemReceiptAuditStatus] 鍏ュ簱鍗�({}) 涓嶅浜庡鎵逛腑鐘舵��", id);
-            return;
-        }
-
-        // 2. 鏍规嵁瀹℃壒缁撴灉鏇存柊鐘舵��
-        Integer newStatus = convertBpmResultToReceiptStatus(bpmResult);
-        if (newStatus != null) {
-            itemReceiptMapper.updateById(new MesWmItemReceiptDO()
-                    .setId(id).setStatus(newStatus));
-        }
-    }
-
-    /**
-     * 杞崲 BPM 瀹℃壒缁撴灉涓哄叆搴撳崟鐘舵��
-     */
-    private Integer convertBpmResultToReceiptStatus(Integer bpmResult) {
-        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
-            return MesWmItemReceiptStatusEnum.APPROVED.getStatus();
-        } else if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
-            return MesWmItemReceiptStatusEnum.PREPARE.getStatus();
-        } else if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
-            return MesWmItemReceiptStatusEnum.CANCELED.getStatus();
-        }
-        return null;
-    }
-
-    /**
-     * 鑾峰彇褰撳墠鐢ㄦ埛 ID
-     */
-    private Long getCurrentUserId() {
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof Long) {
-            return (Long) authentication.getPrincipal();
-        }
-        return 1L; // 榛樿鐢ㄦ埛
     }
 
     /**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/listener/MesWmItemReceiptStatusListener.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/listener/MesWmItemReceiptStatusListener.java
deleted file mode 100644
index c88b0b9..0000000
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/listener/MesWmItemReceiptStatusListener.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package cn.iocoder.yudao.module.mes.service.wm.itemreceipt.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDO;
-import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptMapper;
-import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemReceiptStatusEnum;
-import cn.iocoder.yudao.module.mes.service.wm.itemreceipt.MesWmItemReceiptService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.event.EventListener;
-import org.springframework.stereotype.Component;
-
-/**
- * 閲囪喘鍏ュ簱鍗� BPM 瀹℃壒鐘舵�佺洃鍚櫒
- *
- * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝鏇存柊閲囪喘鍏ュ簱鍗曠殑瀹℃壒鐘舵��
- */
-@Component
-@Slf4j
-public class MesWmItemReceiptStatusListener {
-
-    /**
-     * BPM 鍒嗙被缂栫爜锛氶噰璐叆搴撳鎵�
-     */
-    public static final String ITEM_RECEIPT_APPROVE_CATEGORY_CODE = "item_receipt_approve";
-
-    @Resource
-    private MesWmItemReceiptService itemReceiptService;
-
-    @Resource
-    private MesWmItemReceiptMapper itemReceiptMapper;
-
-    @EventListener
-    public void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
-        // 1. 瑙f瀽涓氬姟涓婚敭
-        Long receiptId;
-        try {
-            receiptId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            log.warn("[onApplicationEvent] 涓氬姟涓婚敭({}) 涓嶆槸鏈夋晥鐨勫叆搴撳崟缂栧彿", event.getBusinessKey());
-            return;
-        }
-
-        // 2. 鏍¢獙鍏ュ簱鍗曞瓨鍦�
-        MesWmItemReceiptDO receipt = itemReceiptMapper.selectById(receiptId);
-        if (receipt == null) {
-            log.warn("[onApplicationEvent] 鍏ュ簱鍗�({}) 涓嶅瓨鍦�", receiptId);
-            return;
-        }
-
-        // 3. 鏍¢獙鍏ュ簱鍗曠姸鎬佷负瀹℃壒涓�
-        if (!MesWmItemReceiptStatusEnum.APPROVING.getStatus().equals(receipt.getStatus())) {
-            log.warn("[onApplicationEvent] 鍏ュ簱鍗�({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵�侊細{}", receiptId, receipt.getStatus());
-            return;
-        }
-
-        // 4. 鏇存柊鍏ュ簱鍗曞鎵圭姸鎬�
-        itemReceiptService.updateItemReceiptAuditStatus(receiptId, event.getStatus());
-        log.info("[onApplicationEvent] 鍏ュ簱鍗�({}) 瀹℃壒鐘舵�佹洿鏂板畬鎴愶紝BPM 鐘舵�侊細{}", receiptId, event.getStatus());
-    }
-
-}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueService.java
index 81da3b0..fc5dd40 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueService.java
@@ -6,18 +6,12 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.miscissue.MesWmMiscIssueDO;
 import jakarta.validation.Valid;
 
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 /**
  * MES 鏉傞」鍑哄簱鍗� Service 鎺ュ彛
  */
 public interface MesWmMiscIssueService {
-
-    /**
-     * 鏉傞」鍑哄簱 BPM 瀹℃壒鍒嗙被缂栫爜
-     */
-    String APPROVE_CATEGORY_CODE = "misc_issue_approve";
 
     /**
      * 鍒涘缓鏉傞」鍑哄簱鍗�
@@ -58,27 +52,35 @@
     PageResult<MesWmMiscIssueDO> getMiscIssuePage(MesWmMiscIssuePageReqVO pageReqVO);
 
     /**
-     * 鎻愪氦鏉傞」鍑哄簱鍗曞鎵癸紙鑽夌 鈫� 瀹℃壒涓級锛屽垱寤� BPM 娴佺▼瀹炰緥
+     * 鎻愪氦鏉傞」鍑哄簱鍗曞鎵癸紙鑽夌 鈫� 瀹℃壒涓級
+     *
+     * 瀹℃牳浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� misc_issue_approve锛夛紝
+     * 鎻愪氦鏃舵棤闇�鎸囧畾锛涙湭鍚敤瀹℃壒鎴栨湭閰嶇疆鏈夋晥瀹℃牳浜烘椂鎶涘嚭涓氬姟寮傚父銆�
      *
      * @param id 缂栧彿
-     * @param processDefinitionKey 娴佺▼瀹氫箟 Key
      */
-    void submitMiscIssueApproval(Long id, String processDefinitionKey);
+    void submitMiscIssueApproval(Long id);
 
     /**
-     * 鏇存柊鏉傞」鍑哄簱鍗曞鎵圭姸鎬侊紙瀹℃壒涓� 鈫� 寰呮墽琛屽嚭搴�/鑽夌/宸插彇娑堬級
+     * 鑾峰緱鏉傞」鍑哄簱鍗曞鎵圭殑瀹℃牳浜虹紪鍙烽泦鍚�
      *
-     * @param id 缂栧彿
-     * @param bpmResult BPM 瀹℃壒缁撴灉
+     * 渚涘墠绔垽鏂綋鍓嶇櫥褰曠敤鎴锋槸鍚﹀簲灞曠ず銆屽鏍搞�嶆寜閽紱鏈厤缃椂杩斿洖绌洪泦鍚堛��
+     *
+     * @return 瀹℃牳浜虹敤鎴风紪鍙烽泦鍚�
      */
-    void updateMiscIssueAuditStatus(Long id, Integer bpmResult);
+    Set<Long> getMiscIssueApproverUserIds();
 
     /**
-     * 鑾峰彇鏉傞」鍑哄簱瀹℃壒鍙敤鐨� BPM 娴佺▼瀹氫箟鍒楄〃
+     * 瀹℃牳鏉傞」鍑哄簱鍗曪紙瀹℃壒涓� 鈫� 寰呮墽琛屽嚭搴� / 鑽夌锛�
      *
-     * @return 娴佺▼瀹氫箟鍒楄〃锛坕d/key/name锛�
+     * 浠呬笟鍔$紪鐮� misc_issue_approve 閰嶇疆鐨勫鏍镐汉鍙搷浣滐紙澶氫汉鏃舵垨绛撅級锛屼笖浠呭湪瀹℃壒涓姸鎬佷笅鍏佽銆�
+     * 瀹℃牳閫氳繃缃负寰呮墽琛屽嚭搴擄紙鍙墽琛屽嚭搴擄級锛涘鏍镐笉閫氳繃蹇呴』濉啓鍘熷洜锛岄��鍥炶崏绋垮彲淇敼鍚庨噸鏂版彁浜ゃ��
+     *
+     * @param id           缂栧彿
+     * @param pass         鏄惁閫氳繃锛宼rue=閫氳繃 / false=涓嶉�氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛屽鏍镐笉閫氳繃鏃跺繀濉�
      */
-    List<Map<String, Object>> getMiscIssueApprovalProcessDefinitionList();
+    void auditMiscIssue(Long id, Boolean pass, String reviewRemark);
 
     /**
      * 鎵ц鍑哄簱锛堝緟鎵ц鍑哄簱 鈫� 宸插畬鎴愶級锛屾墸鍑忓簱瀛�
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueServiceImpl.java
index c179604..1abd1f0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueServiceImpl.java
@@ -2,6 +2,7 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
@@ -15,24 +16,21 @@
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
-import java.util.*;
+import java.util.List;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
 
 /**
@@ -43,6 +41,13 @@
 @Slf4j
 public class MesWmMiscIssueServiceImpl implements MesWmMiscIssueService {
 
+    /**
+     * 鏉傞」鍑哄簱鍗曞鎵圭殑涓氬姟绫诲瀷缂栫爜
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鏍镐汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
+     */
+    private static final String MISC_ISSUE_APPROVE_BIZ_TYPE = "misc_issue_approve";
+
     @Resource
     private MesWmMiscIssueMapper miscIssueMapper;
 
@@ -51,9 +56,9 @@
     @Resource
     private MesWmTransactionService wmTransactionService;
     @Resource
-    private BpmProcessInstanceApi processInstanceApi;
+    private AdminUserApi adminUserApi;
     @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private ApprovalConfigApi approvalConfigApi;
 
     @Override
     public Long createMiscIssue(MesWmMiscIssueSaveReqVO createReqVO) {
@@ -103,95 +108,63 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitMiscIssueApproval(Long id, String processDefinitionKey) {
-        // 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
+    public void submitMiscIssueApproval(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
         validateMiscIssueExistsAndDraft(id);
-        // 鏍¢獙鑷冲皯鏈変竴鏉¤
+        // 2. 鏍¢獙鑷冲皯鏈変竴鏉¤
         List<MesWmMiscIssueLineDO> lines = miscIssueLineService.getMiscIssueLineListByIssueId(id);
         if (CollUtil.isEmpty(lines)) {
             throw exception(WM_MISC_ISSUE_NO_LINE);
         }
-        // 鍒涘缓 BPM 娴佺▼瀹炰緥
-        String processInstanceId = processInstanceApi.createProcessInstance(getCurrentUserId(),
-                new BpmProcessInstanceCreateReqDTO()
-                        .setProcessDefinitionKey(processDefinitionKey)
-                        .setBusinessKey(String.valueOf(id)));
-        // 鎻愪氦瀹℃壒锛堣崏绋� 鈫� 瀹℃壒涓級
-        miscIssueMapper.updateById(new MesWmMiscIssueDO()
-                .setId(id)
-                .setStatus(MesWmMiscIssueStatusEnum.APPROVING.getStatus())
-                .setProcessInstanceId(processInstanceId));
+        // 3. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鏍镐汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(MISC_ISSUE_APPROVE_BIZ_TYPE);
+        // 4. 鎻愪氦瀹℃壒锛堣崏绋� 鈫� 瀹℃壒涓級锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+        miscIssueMapper.submitAndResetAuditInfo(id, MesWmMiscIssueStatusEnum.APPROVING.getStatus());
     }
 
     @Override
-    public List<Map<String, Object>> getMiscIssueApprovalProcessDefinitionList() {
-        return getProcessDefinitionListByCategory(APPROVE_CATEGORY_CODE);
+    public Set<Long> getMiscIssueApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(MISC_ISSUE_APPROVE_BIZ_TYPE);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void updateMiscIssueAuditStatus(Long id, Integer bpmResult) {
+    public void auditMiscIssue(Long id, Boolean pass, String reviewRemark) {
         // 1. 鏍¢獙瀛樺湪
         MesWmMiscIssueDO issue = validateMiscIssueExists(id);
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
         if (!MesWmMiscIssueStatusEnum.APPROVING.getStatus().equals(issue.getStatus())) {
-            log.warn("[updateMiscIssueAuditStatus] 鏉傞」鍑哄簱鍗�({}) 涓嶅浜庡鎵逛腑鐘舵��", id);
+            throw exception(WM_MISC_ISSUE_NOT_APPROVING);
+        }
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鏍镐汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(MISC_ISSUE_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝閫�鍥炶崏绋垮彲淇敼鍚庨噸鏂版彁浜�
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(WM_MISC_ISSUE_REJECT_REASON_REQUIRED);
+            }
+            miscIssueMapper.auditMiscIssue(id, MesWmMiscIssueStatusEnum.PREPARE.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
             return;
         }
-        // 2. 鏍规嵁瀹℃壒缁撴灉鏇存柊鐘舵��
-        Integer newStatus = convertBpmResultToStatus(bpmResult);
-        if (newStatus != null) {
-            miscIssueMapper.updateById(new MesWmMiscIssueDO().setId(id).setStatus(newStatus));
-        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄緟鎵ц鍑哄簱
+        miscIssueMapper.auditMiscIssue(id, MesWmMiscIssueStatusEnum.APPROVED.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
     }
 
-    private Integer convertBpmResultToStatus(Integer bpmResult) {
-        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
-            return MesWmMiscIssueStatusEnum.APPROVED.getStatus();
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
         }
-        if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
-            return MesWmMiscIssueStatusEnum.PREPARE.getStatus();
-        }
-        if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
-            return MesWmMiscIssueStatusEnum.CANCELED.getStatus();
-        }
-        return null;
-    }
-
-    private List<Map<String, Object>> getProcessDefinitionListByCategory(String categoryCode) {
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(categoryCode);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            return Collections.emptyList();
-        }
-        // 杩囨护婵�娲荤姸鎬侊紝淇濈暀鏈�鏂扮増鏈�
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (BpmProcessDefinitionInfoDO info : definitionInfoList) {
-            ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId());
-            if (pd == null || pd.isSuspended()) {
-                continue;
-            }
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            result.add(item);
-        }
-        return result;
-    }
-
-    private Long getCurrentUserId() {
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof Long) {
-            return (Long) authentication.getPrincipal();
-        }
-        return 1L; // 榛樿鐢ㄦ埛
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
     @Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/listener/MesWmMiscIssueStatusListener.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/listener/MesWmMiscIssueStatusListener.java
deleted file mode 100644
index 95186d1..0000000
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/listener/MesWmMiscIssueStatusListener.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package cn.iocoder.yudao.module.mes.service.wm.miscissue.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.mes.service.wm.miscissue.MesWmMiscIssueService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-/**
- * 鏉傞」鍑哄簱鍗� BPM 瀹℃壒鐘舵�佺洃鍚櫒
- *
- * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝鏇存柊鏉傞」鍑哄簱鍗曠殑瀹℃壒鐘舵��
- */
-@Component
-@Slf4j
-public class MesWmMiscIssueStatusListener
-        extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener {
-
-    @Resource
-    private MesWmMiscIssueService miscIssueService;
-
-    @Override
-    protected String getProcessDefinitionKey() {
-        return MesWmMiscIssueService.APPROVE_CATEGORY_CODE;
-    }
-
-    @Override
-    protected void onEvent(BpmProcessInstanceStatusEvent event) {
-        Long id;
-        try {
-            id = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勬潅椤瑰嚭搴撳崟缂栧彿", event.getBusinessKey());
-            return;
-        }
-        log.info("[onEvent] 鏀跺埌BPM瀹℃壒浜嬩欢锛宮iscIssueId={}, status={}", id, event.getStatus());
-        try {
-            miscIssueService.updateMiscIssueAuditStatus(id, event.getStatus());
-            log.info("[onEvent] 鏉傞」鍑哄簱鍗�({}) 瀹℃壒鐘舵�佹洿鏂板畬鎴�", id);
-        } catch (Exception e) {
-            log.error("[onEvent] 鏇存柊鏉傞」鍑哄簱鍗曞鎵圭姸鎬佸け璐ワ紝miscIssueId={}", id, e);
-        }
-    }
-
-}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptService.java
index 242c749..2b1e8fa 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptService.java
@@ -6,8 +6,7 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.miscreceipt.MesWmMiscReceiptDO;
 import jakarta.validation.Valid;
 
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 /**
  * MES 鏉傞」鍏ュ簱鍗� Service 鎺ュ彛
@@ -15,11 +14,6 @@
  * @author 瓒呯骇绠$悊鍛�
  */
 public interface MesWmMiscReceiptService {
-
-    /**
-     * 鏉傞」鍏ュ簱 BPM 瀹℃壒鍒嗙被缂栫爜
-     */
-    String APPROVE_CATEGORY_CODE = "misc_receipt_approve";
 
     /**
      * 鍒涘缓鏉傞」鍏ュ簱鍗�
@@ -60,27 +54,35 @@
     PageResult<MesWmMiscReceiptDO> getMiscReceiptPage(MesWmMiscReceiptPageReqVO pageReqVO);
 
     /**
-     * 鎻愪氦鏉傞」鍏ュ簱鍗曞鎵癸紙鑽夌 鈫� 瀹℃壒涓級锛屽垱寤� BPM 娴佺▼瀹炰緥
+     * 鎻愪氦鏉傞」鍏ュ簱鍗曞鎵癸紙鑽夌 鈫� 瀹℃壒涓級
+     *
+     * 瀹℃牳浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� misc_receipt_approve锛夛紝
+     * 鎻愪氦鏃舵棤闇�鎸囧畾锛涙湭鍚敤瀹℃壒鎴栨湭閰嶇疆鏈夋晥瀹℃牳浜烘椂鎶涘嚭涓氬姟寮傚父銆�
      *
      * @param id 缂栧彿
-     * @param processDefinitionKey 娴佺▼瀹氫箟 Key
      */
-    void submitMiscReceiptApproval(Long id, String processDefinitionKey);
+    void submitMiscReceiptApproval(Long id);
 
     /**
-     * 鏇存柊鏉傞」鍏ュ簱鍗曞鎵圭姸鎬侊紙瀹℃壒涓� 鈫� 宸插鎵�/鑽夌/宸插彇娑堬級
+     * 鑾峰緱鏉傞」鍏ュ簱鍗曞鎵圭殑瀹℃牳浜虹紪鍙烽泦鍚�
      *
-     * @param id 缂栧彿
-     * @param bpmResult BPM 瀹℃壒缁撴灉
+     * 渚涘墠绔垽鏂綋鍓嶇櫥褰曠敤鎴锋槸鍚﹀簲灞曠ず銆屽鏍搞�嶆寜閽紱鏈厤缃椂杩斿洖绌洪泦鍚堛��
+     *
+     * @return 瀹℃牳浜虹敤鎴风紪鍙烽泦鍚�
      */
-    void updateMiscReceiptAuditStatus(Long id, Integer bpmResult);
+    Set<Long> getMiscReceiptApproverUserIds();
 
     /**
-     * 鑾峰彇鏉傞」鍏ュ簱瀹℃壒鍙敤鐨� BPM 娴佺▼瀹氫箟鍒楄〃
+     * 瀹℃牳鏉傞」鍏ュ簱鍗曪紙瀹℃壒涓� 鈫� 宸插鎵� / 鑽夌锛�
      *
-     * @return 娴佺▼瀹氫箟鍒楄〃锛坕d/key/name锛�
+     * 浠呬笟鍔$紪鐮� misc_receipt_approve 閰嶇疆鐨勫鏍镐汉鍙搷浣滐紙澶氫汉鏃舵垨绛撅級锛屼笖浠呭湪瀹℃壒涓姸鎬佷笅鍏佽銆�
+     * 瀹℃牳閫氳繃缃负宸插鎵癸紙鍙墽琛屽叆搴擄級锛涘鏍镐笉閫氳繃蹇呴』濉啓鍘熷洜锛岄��鍥炶崏绋垮彲淇敼鍚庨噸鏂版彁浜ゃ��
+     *
+     * @param id           缂栧彿
+     * @param pass         鏄惁閫氳繃锛宼rue=閫氳繃 / false=涓嶉�氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛屽鏍镐笉閫氳繃鏃跺繀濉�
      */
-    List<Map<String, Object>> getMiscReceiptApprovalProcessDefinitionList();
+    void auditMiscReceipt(Long id, Boolean pass, String reviewRemark);
 
     /**
      * 鎵ц鍏ュ簱锛堝凡瀹℃壒 鈫� 宸插畬鎴愶級锛屾洿鏂板簱瀛樺彴璐�
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptServiceImpl.java
index 2e7ed10..fa03d13 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptServiceImpl.java
@@ -2,6 +2,7 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.miscreceipt.vo.MesWmMiscReceiptPageReqVO;
@@ -14,26 +15,22 @@
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.context.annotation.Lazy;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
-import java.util.*;
 import java.util.List;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
 
 /**
@@ -44,6 +41,13 @@
 @Slf4j
 public class MesWmMiscReceiptServiceImpl implements MesWmMiscReceiptService {
 
+    /**
+     * 鏉傞」鍏ュ簱鍗曞鎵圭殑涓氬姟绫诲瀷缂栫爜
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鏍镐汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
+     */
+    private static final String MISC_RECEIPT_APPROVE_BIZ_TYPE = "misc_receipt_approve";
+
     @Resource
     private MesWmMiscReceiptMapper miscReceiptMapper;
 
@@ -53,9 +57,9 @@
     @Resource
     private MesWmTransactionService wmTransactionService;
     @Resource
-    private BpmProcessInstanceApi processInstanceApi;
+    private AdminUserApi adminUserApi;
     @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private ApprovalConfigApi approvalConfigApi;
 
     @Override
     public Long createMiscReceipt(MesWmMiscReceiptSaveReqVO createReqVO) {
@@ -105,95 +109,63 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitMiscReceiptApproval(Long id, String processDefinitionKey) {
-        // 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
+    public void submitMiscReceiptApproval(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
         validateMiscReceiptExistsAndPrepare(id);
-        // 鏍¢獙鑷冲皯鏈変竴鏉¤
+        // 2. 鏍¢獙鑷冲皯鏈変竴鏉¤
         List<MesWmMiscReceiptLineDO> lines = miscReceiptLineService.getMiscReceiptLineListByReceiptId(id);
         if (CollUtil.isEmpty(lines)) {
             throw exception(WM_MISC_RECEIPT_NO_LINE);
         }
-        // 鍒涘缓 BPM 娴佺▼瀹炰緥
-        String processInstanceId = processInstanceApi.createProcessInstance(getCurrentUserId(),
-                new BpmProcessInstanceCreateReqDTO()
-                        .setProcessDefinitionKey(processDefinitionKey)
-                        .setBusinessKey(String.valueOf(id)));
-        // 鎻愪氦瀹℃壒锛堣崏绋� 鈫� 瀹℃壒涓級
-        miscReceiptMapper.updateById(new MesWmMiscReceiptDO()
-                .setId(id)
-                .setStatus(MesWmMiscReceiptStatusEnum.APPROVING.getStatus())
-                .setProcessInstanceId(processInstanceId));
+        // 3. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鏍镐汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(MISC_RECEIPT_APPROVE_BIZ_TYPE);
+        // 4. 鎻愪氦瀹℃壒锛堣崏绋� 鈫� 瀹℃壒涓級锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+        miscReceiptMapper.submitAndResetAuditInfo(id, MesWmMiscReceiptStatusEnum.APPROVING.getStatus());
     }
 
     @Override
-    public List<Map<String, Object>> getMiscReceiptApprovalProcessDefinitionList() {
-        return getProcessDefinitionListByCategory(APPROVE_CATEGORY_CODE);
+    public Set<Long> getMiscReceiptApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(MISC_RECEIPT_APPROVE_BIZ_TYPE);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void updateMiscReceiptAuditStatus(Long id, Integer bpmResult) {
+    public void auditMiscReceipt(Long id, Boolean pass, String reviewRemark) {
         // 1. 鏍¢獙瀛樺湪
         MesWmMiscReceiptDO receipt = validateMiscReceiptExists(id);
+        // 2. 鏍¢獙澶勪簬瀹℃壒涓姸鎬�
         if (!MesWmMiscReceiptStatusEnum.APPROVING.getStatus().equals(receipt.getStatus())) {
-            log.warn("[updateMiscReceiptAuditStatus] 鏉傞」鍏ュ簱鍗�({}) 涓嶅浜庡鎵逛腑鐘舵��", id);
+            throw exception(WM_MISC_RECEIPT_NOT_APPROVING);
+        }
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鏍镐汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(MISC_RECEIPT_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝閫�鍥炶崏绋垮彲淇敼鍚庨噸鏂版彁浜�
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(WM_MISC_RECEIPT_REJECT_REASON_REQUIRED);
+            }
+            miscReceiptMapper.auditMiscReceipt(id, MesWmMiscReceiptStatusEnum.PREPARE.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
             return;
         }
-        // 2. 鏍规嵁瀹℃壒缁撴灉鏇存柊鐘舵��
-        Integer newStatus = convertBpmResultToStatus(bpmResult);
-        if (newStatus != null) {
-            miscReceiptMapper.updateById(new MesWmMiscReceiptDO().setId(id).setStatus(newStatus));
-        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄凡瀹℃壒锛堝彲鎵ц鍏ュ簱锛�
+        miscReceiptMapper.auditMiscReceipt(id, MesWmMiscReceiptStatusEnum.APPROVED.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
     }
 
-    private Integer convertBpmResultToStatus(Integer bpmResult) {
-        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
-            return MesWmMiscReceiptStatusEnum.APPROVED.getStatus();
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
         }
-        if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
-            return MesWmMiscReceiptStatusEnum.PREPARE.getStatus();
-        }
-        if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
-            return MesWmMiscReceiptStatusEnum.CANCELED.getStatus();
-        }
-        return null;
-    }
-
-    private List<Map<String, Object>> getProcessDefinitionListByCategory(String categoryCode) {
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(categoryCode);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            return Collections.emptyList();
-        }
-        // 杩囨护婵�娲荤姸鎬侊紝淇濈暀鏈�鏂扮増鏈�
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (BpmProcessDefinitionInfoDO info : definitionInfoList) {
-            ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId());
-            if (pd == null || pd.isSuspended()) {
-                continue;
-            }
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            result.add(item);
-        }
-        return result;
-    }
-
-    private Long getCurrentUserId() {
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof Long) {
-            return (Long) authentication.getPrincipal();
-        }
-        return 1L; // 榛樿鐢ㄦ埛
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
     @Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/listener/MesWmMiscReceiptStatusListener.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/listener/MesWmMiscReceiptStatusListener.java
deleted file mode 100644
index 17ab0b8..0000000
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/listener/MesWmMiscReceiptStatusListener.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package cn.iocoder.yudao.module.mes.service.wm.miscreceipt.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.mes.service.wm.miscreceipt.MesWmMiscReceiptService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-/**
- * 鏉傞」鍏ュ簱鍗� BPM 瀹℃壒鐘舵�佺洃鍚櫒
- *
- * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝鏇存柊鏉傞」鍏ュ簱鍗曠殑瀹℃壒鐘舵��
- */
-@Component
-@Slf4j
-public class MesWmMiscReceiptStatusListener
-        extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener {
-
-    @Resource
-    private MesWmMiscReceiptService miscReceiptService;
-
-    @Override
-    protected String getProcessDefinitionKey() {
-        return MesWmMiscReceiptService.APPROVE_CATEGORY_CODE;
-    }
-
-    @Override
-    protected void onEvent(BpmProcessInstanceStatusEvent event) {
-        Long id;
-        try {
-            id = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勬潅椤瑰叆搴撳崟缂栧彿", event.getBusinessKey());
-            return;
-        }
-        log.info("[onEvent] 鏀跺埌BPM瀹℃壒浜嬩欢锛宮iscReceiptId={}, status={}", id, event.getStatus());
-        try {
-            miscReceiptService.updateMiscReceiptAuditStatus(id, event.getStatus());
-            log.info("[onEvent] 鏉傞」鍏ュ簱鍗�({}) 瀹℃壒鐘舵�佹洿鏂板畬鎴�", id);
-        } catch (Exception e) {
-            log.error("[onEvent] 鏇存柊鏉傞」鍏ュ簱鍗曞鎵圭姸鎬佸け璐ワ紝miscReceiptId={}", id, e);
-        }
-    }
-
-}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorService.java
index 872d206..eac5b4a 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorService.java
@@ -6,18 +6,12 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDO;
 import jakarta.validation.Valid;
 
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 /**
  * MES 渚涘簲鍟嗛��璐у崟 Service 鎺ュ彛
  */
 public interface MesWmReturnVendorService {
-
-    /**
-     * 渚涘簲鍟嗛��璐� BPM 瀹℃壒鍒嗙被缂栫爜
-     */
-    String APPROVE_CATEGORY_CODE = "return_vendor_approve";
 
     /**
      * 鍒涘缓渚涘簲鍟嗛��璐у崟
@@ -66,27 +60,36 @@
     MesWmReturnVendorDO validateReturnVendorExists(Long id);
 
     /**
-     * 鎻愪氦渚涘簲鍟嗛��璐у崟瀹℃壒锛堣崏绋� -> 瀹℃壒涓級锛屽垱寤� BPM 娴佺▼瀹炰緥
+     * 鎻愪氦渚涘簲鍟嗛��璐у崟瀹℃壒锛堣崏绋� 鈫� 寰呮嫞璐э級
+     *
+     * 瀹℃牳浜虹敱銆岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆锛堜笟鍔$紪鐮� return_vendor_approve锛夛紝
+     * 鎻愪氦鏃舵棤闇�鎸囧畾锛涙湭鍚敤瀹℃壒鎴栨湭閰嶇疆鏈夋晥瀹℃牳浜烘椂鎶涘嚭涓氬姟寮傚父銆�
      *
      * @param id 缂栧彿
-     * @param processDefinitionKey 娴佺▼瀹氫箟 Key
      */
-    void submitReturnVendorApproval(Long id, String processDefinitionKey);
+    void submitReturnVendorApproval(Long id);
 
     /**
-     * 鏇存柊渚涘簲鍟嗛��璐у崟瀹℃壒鐘舵�侊紙瀹℃壒涓� -> 寰呮墽琛岄��璐�/鑽夌/宸插彇娑堬級
+     * 鑾峰緱渚涘簲鍟嗛��璐у崟瀹℃壒鐨勫鏍镐汉缂栧彿闆嗗悎
      *
-     * @param id 缂栧彿
-     * @param bpmResult BPM 瀹℃壒缁撴灉
+     * 渚涘墠绔垽鏂綋鍓嶇櫥褰曠敤鎴锋槸鍚﹀簲灞曠ず銆屽鏍搞�嶆寜閽紱鏈厤缃椂杩斿洖绌洪泦鍚堛��
+     *
+     * @return 瀹℃牳浜虹敤鎴风紪鍙烽泦鍚�
      */
-    void updateReturnVendorAuditStatus(Long id, Integer bpmResult);
+    Set<Long> getReturnVendorApproverUserIds();
 
     /**
-     * 鑾峰彇渚涘簲鍟嗛��璐у鎵瑰彲鐢ㄧ殑 BPM 娴佺▼瀹氫箟鍒楄〃
+     * 瀹℃牳渚涘簲鍟嗛��璐у崟锛堝緟鎷h揣 鈫� 寰呮墽琛岄��璐� / 鑽夌锛�
      *
-     * @return 娴佺▼瀹氫箟鍒楄〃锛坕d/key/name锛�
+     * 浠呬笟鍔$紪鐮� return_vendor_approve 閰嶇疆鐨勫鏍镐汉鍙搷浣滐紙澶氫汉鏃舵垨绛撅級锛屼笖浠呭湪寰呮嫞璐х姸鎬佷笅鍏佽銆�
+     * 瀹℃牳閫氳繃缃负寰呮墽琛岄��璐э紙鍙畬鎴愰��璐у苟鎵e噺搴撳瓨锛夛紱瀹℃牳涓嶉�氳繃蹇呴』濉啓鍘熷洜锛�
+     * 閫�鍥炶崏绋垮彲淇敼鍚庨噸鏂版彁浜ゃ��
+     *
+     * @param id           缂栧彿
+     * @param pass         鏄惁閫氳繃锛宼rue=閫氳繃 / false=涓嶉�氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛屽鏍镐笉閫氳繃鏃跺繀濉�
      */
-    List<Map<String, Object>> getReturnVendorApprovalProcessDefinitionList();
+    void auditReturnVendor(Long id, Boolean pass, String reviewRemark);
 
     /**
      * 鎵ц鎷h揣锛堝緟鎷h揣 -> 寰呮墽琛岄��璐э級
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java
index f5a6f07..271d5d1 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java
@@ -2,6 +2,7 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@@ -18,25 +19,22 @@
 import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import java.math.BigDecimal;
-import java.util.*;
+import java.util.List;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
 
 /**
@@ -46,6 +44,13 @@
 @Validated
 @Slf4j
 public class MesWmReturnVendorServiceImpl implements MesWmReturnVendorService {
+
+    /**
+     * 渚涘簲鍟嗛��璐у崟瀹℃壒鐨勪笟鍔$被鍨嬬紪鐮�
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鏍镐汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
+     */
+    private static final String RETURN_VENDOR_APPROVE_BIZ_TYPE = "return_vendor_approve";
 
     @Resource
     private MesWmReturnVendorMapper returnVendorMapper;
@@ -59,9 +64,9 @@
     @Resource
     private MesWmTransactionService wmTransactionService;
     @Resource
-    private BpmProcessInstanceApi processInstanceApi;
+    private AdminUserApi adminUserApi;
     @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private ApprovalConfigApi approvalConfigApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -113,95 +118,63 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitReturnVendorApproval(Long id, String processDefinitionKey) {
-        // 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
+    public void submitReturnVendorApproval(Long id) {
+        // 1. 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
         validateReturnVendorExistsAndPrepare(id);
-        // 鏍¢獙鑷冲皯鏈変竴鏉¤
+        // 2. 鏍¢獙鑷冲皯鏈変竴鏉¤
         List<MesWmReturnVendorLineDO> lines = returnVendorLineService.getReturnVendorLineListByReturnId(id);
         if (CollUtil.isEmpty(lines)) {
             throw exception(WM_RETURN_VENDOR_NO_LINE);
         }
-        // 鍒涘缓 BPM 娴佺▼瀹炰緥
-        String processInstanceId = processInstanceApi.createProcessInstance(getCurrentUserId(),
-                new BpmProcessInstanceCreateReqDTO()
-                        .setProcessDefinitionKey(processDefinitionKey)
-                        .setBusinessKey(String.valueOf(id)));
-        // 鎻愪氦瀹℃壒锛堣崏绋� 鈫� 瀹℃壒涓級
-        returnVendorMapper.updateById(new MesWmReturnVendorDO()
-                .setId(id)
-                .setStatus(MesWmReturnVendorStatusEnum.APPROVING.getStatus())
-                .setProcessInstanceId(processInstanceId));
+        // 3. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鏍镐汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(RETURN_VENDOR_APPROVE_BIZ_TYPE);
+        // 4. 鎻愪氦瀹℃壒锛堣崏绋� 鈫� 寰呮嫞璐э級锛屽苟娓呯┖涓婁竴杞鏍哥粨鏋�
+        returnVendorMapper.submitAndResetAuditInfo(id, MesWmReturnVendorStatusEnum.APPROVING.getStatus());
     }
 
     @Override
-    public List<Map<String, Object>> getReturnVendorApprovalProcessDefinitionList() {
-        return getProcessDefinitionListByCategory(APPROVE_CATEGORY_CODE);
+    public Set<Long> getReturnVendorApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(RETURN_VENDOR_APPROVE_BIZ_TYPE);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void updateReturnVendorAuditStatus(Long id, Integer bpmResult) {
+    public void auditReturnVendor(Long id, Boolean pass, String reviewRemark) {
         // 1. 鏍¢獙瀛樺湪
         MesWmReturnVendorDO returnVendor = validateReturnVendorExists(id);
+        // 2. 鏍¢獙澶勪簬寰呮嫞璐х姸鎬�
         if (!MesWmReturnVendorStatusEnum.APPROVING.getStatus().equals(returnVendor.getStatus())) {
-            log.warn("[updateReturnVendorAuditStatus] 渚涘簲鍟嗛��璐у崟({}) 涓嶅浜庡鎵逛腑鐘舵��", id);
+            throw exception(WM_RETURN_VENDOR_NOT_APPROVING);
+        }
+        // 3. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鏍镐汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(RETURN_VENDOR_APPROVE_BIZ_TYPE, userId);
+        // 4. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝閫�鍥炶崏绋垮彲淇敼鍚庨噸鏂版彁浜�
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(WM_RETURN_VENDOR_REJECT_REASON_REQUIRED);
+            }
+            returnVendorMapper.auditReturnVendor(id, MesWmReturnVendorStatusEnum.PREPARE.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
             return;
         }
-        // 2. 鏍规嵁瀹℃壒缁撴灉鏇存柊鐘舵��
-        Integer newStatus = convertBpmResultToStatus(bpmResult);
-        if (newStatus != null) {
-            returnVendorMapper.updateById(new MesWmReturnVendorDO().setId(id).setStatus(newStatus));
-        }
+        // 5. 瀹℃牳閫氳繃锛氳褰曞鏍镐汉涓庡鏍告剰瑙侊紝鐘舵�佺疆涓哄緟鎵ц閫�璐э紙鍙畬鎴愰��璐у苟鎵e噺搴撳瓨锛�
+        returnVendorMapper.auditReturnVendor(id, MesWmReturnVendorStatusEnum.APPROVED.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
     }
 
-    private Integer convertBpmResultToStatus(Integer bpmResult) {
-        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
-            return MesWmReturnVendorStatusEnum.APPROVED.getStatus();
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
         }
-        if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
-            return MesWmReturnVendorStatusEnum.PREPARE.getStatus();
-        }
-        if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
-            return MesWmReturnVendorStatusEnum.CANCELED.getStatus();
-        }
-        return null;
-    }
-
-    private List<Map<String, Object>> getProcessDefinitionListByCategory(String categoryCode) {
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(categoryCode);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            return Collections.emptyList();
-        }
-        // 杩囨护婵�娲荤姸鎬侊紝淇濈暀鏈�鏂扮増鏈�
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (BpmProcessDefinitionInfoDO info : definitionInfoList) {
-            ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId());
-            if (pd == null || pd.isSuspended()) {
-                continue;
-            }
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            result.add(item);
-        }
-        return result;
-    }
-
-    private Long getCurrentUserId() {
-        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        if (authentication != null && authentication.getPrincipal() instanceof Long) {
-            return (Long) authentication.getPrincipal();
-        }
-        return 1L; // 榛樿鐢ㄦ埛
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
     @Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/listener/MesWmReturnVendorStatusListener.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/listener/MesWmReturnVendorStatusListener.java
deleted file mode 100644
index 886f882..0000000
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/listener/MesWmReturnVendorStatusListener.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package cn.iocoder.yudao.module.mes.service.wm.returnvendor.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.mes.service.wm.returnvendor.MesWmReturnVendorService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-/**
- * 渚涘簲鍟嗛��璐у崟 BPM 瀹℃壒鐘舵�佺洃鍚櫒
- *
- * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝鏇存柊渚涘簲鍟嗛��璐у崟鐨勫鎵圭姸鎬�
- */
-@Component
-@Slf4j
-public class MesWmReturnVendorStatusListener
-        extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener {
-
-    @Resource
-    private MesWmReturnVendorService returnVendorService;
-
-    @Override
-    protected String getProcessDefinitionKey() {
-        return MesWmReturnVendorService.APPROVE_CATEGORY_CODE;
-    }
-
-    @Override
-    protected void onEvent(BpmProcessInstanceStatusEvent event) {
-        Long id;
-        try {
-            id = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勪緵搴斿晢閫�璐у崟缂栧彿", event.getBusinessKey());
-            return;
-        }
-        log.info("[onEvent] 鏀跺埌BPM瀹℃壒浜嬩欢锛宺eturnVendorId={}, status={}", id, event.getStatus());
-        try {
-            returnVendorService.updateReturnVendorAuditStatus(id, event.getStatus());
-            log.info("[onEvent] 渚涘簲鍟嗛��璐у崟({}) 瀹℃壒鐘舵�佹洿鏂板畬鎴�", id);
-        } catch (Exception e) {
-            log.error("[onEvent] 鏇存柊渚涘簲鍟嗛��璐у崟瀹℃壒鐘舵�佸け璐ワ紝returnVendorId={}", id, e);
-        }
-    }
-
-}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskService.java
index a83c2a6..082c64e 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskService.java
@@ -6,8 +6,7 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.stocktaking.task.MesWmStockTakingTaskDO;
 import jakarta.validation.Valid;
 
-import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 /**
  * MES 鐩樼偣浠诲姟 Service 鎺ュ彛
@@ -15,11 +14,6 @@
  * @author 瓒呯骇绠$悊鍛�
  */
 public interface MesWmStockTakingTaskService {
-
-    /**
-     * 鐩樼偣缁撴灉瀹℃壒 BPM 鍒嗙被缂栫爜
-     */
-    String APPROVE_CATEGORY_CODE = "stock_taking_result_approve";
 
     /**
      * 鍒涘缓鐩樼偣浠诲姟
@@ -54,37 +48,41 @@
     void submitStockTakingTask(Long id);
 
     /**
-     * 鎻愪氦鐩樼偣缁撴灉瀹℃壒锛堢洏鐐逛腑 鈫� 鐩樼偣涓� + 鍒涘缓 BPM 娴佺▼瀹炰緥锛�
+     * 鎻愪氦鐩樼偣缁撴灉瀹℃壒锛堢洏鐐逛腑 鈫� 鐩樼偣涓风粨鏋滃鎵逛腑锛�
      *
-     * <p>褰曞叆/瀵煎叆瀹屾垚鍚庢彁浜ょ粨鏋滃鎵癸細鏍¢獙鐩樼偣涓瓨鍦ㄤ笖鑷冲皯涓�鏉$洏鐐圭粨鏋溿�佷笖缁撴灉瀹℃壒鏈彁浜よ繃锛�
-     * 鍒涘缓 BPM 娴佺▼瀹炰緥骞跺洖鍐� {@code processInstanceId}銆傚鎵归�氳繃鍚庢墠鎵ц宸紓鏍搁攢骞剁疆涓哄凡瀹屾垚銆�
+     * <p>褰曞叆/瀵煎叆瀹屾垚鍚庢彁浜ょ粨鏋滃鎵癸細鏍¢獙鐩樼偣涓瓨鍦ㄤ笖鑷冲皯涓�鏉$洏鐐圭粨鏋溿�佷笖鏈疆缁撴灉瀹℃壒鏈彁浜よ繃锛�
+     * 璁板綍鎻愪氦鏃堕棿鍚庣瓑寰呭鏍搞�傚鏍镐汉鐢便�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶆寜涓氬姟绫诲瀷缁熶竴閰嶇疆
+     * 锛堜笟鍔$紪鐮� stock_taking_result_approve锛夛紝鎻愪氦鏃舵棤闇�鎸囧畾锛�
+     * 鏈惎鐢ㄥ鎵规垨鏈厤缃湁鏁堝鏍镐汉鏃舵姏鍑轰笟鍔″紓甯搞�傚鎵归�氳繃鍚庢墠鎵ц宸紓鏍搁攢骞剁疆涓哄凡瀹屾垚銆�
      *
-     * @param id                  鐩樼偣浠诲姟缂栧彿
-     * @param processDefinitionKey BPM 娴佺▼瀹氫箟 Key
+     * @param id 鐩樼偣浠诲姟缂栧彿
      */
-    void submitStockTakingResultApproval(Long id, String processDefinitionKey);
+    void submitStockTakingResultApproval(Long id);
 
     /**
-     * 鏇存柊鐩樼偣浠诲姟缁撴灉瀹℃壒鐘舵�侊紙BPM 瀹℃壒鍥炶皟锛�
+     * 鑾峰緱鐩樼偣缁撴灉瀹℃壒鐨勫鏍镐汉缂栧彿闆嗗悎
      *
-     * <p>浠呯洏鐐逛腑鐘舵�佸鐞嗭細
+     * 渚涘墠绔垽鏂綋鍓嶇櫥褰曠敤鎴锋槸鍚﹀簲灞曠ず銆屽鏍搞�嶆寜閽紱鏈厤缃椂杩斿洖绌洪泦鍚堛��
+     *
+     * @return 瀹℃牳浜虹敤鎴风紪鍙烽泦鍚�
+     */
+    Set<Long> getStockTakingTaskApproverUserIds();
+
+    /**
+     * 瀹℃牳鐩樼偣缁撴灉锛堢洏鐐逛腑路缁撴灉瀹℃壒涓� 鈫� 宸插畬鎴� / 鐩樼偣涓級
+     *
+     * <p>浠呬笟鍔$紪鐮� stock_taking_result_approve 閰嶇疆鐨勫鏍镐汉鍙搷浣滐紙澶氫汉鏃舵垨绛撅級锛�
+     * 涓斾粎鍦ㄧ粨鏋滃鎵瑰凡鎻愪氦銆佸皻鏈鏍告椂鍏佽锛�
      * <ul>
-     *     <li>瀹℃壒閫氳繃锛氳В鍐诲簱瀛橈紝鍚屼簨鍔¤嚜鍔ㄦ牳閿�鐩樼泩/鐩樹簭骞剁疆涓哄凡瀹屾垚锛�</li>
-     *     <li>瀹℃壒椹冲洖锛氭竻绌烘祦绋嬪疄渚嬬紪鍙凤紝浠诲姟淇濇寔鐩樼偣涓紝鍙慨鏀瑰疄鐩樺悗閲嶆柊鎻愪氦锛�</li>
-     *     <li>瀹℃壒鍙栨秷锛氳В鍐诲簱瀛樺苟缃负宸插彇娑堛��</li>
+     *     <li>瀹℃牳閫氳繃锛氳В鍐诲簱瀛橈紝鍚屼簨鍔¤嚜鍔ㄦ牳閿�鐩樼泩/鐩樹簭骞剁疆涓哄凡瀹屾垚锛�</li>
+     *     <li>瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝浠诲姟淇濇寔鐩樼偣涓紝鍙慨鏀瑰疄鐩樺悗閲嶆柊鎻愪氦缁撴灉瀹℃壒銆�</li>
      * </ul>
      *
-     * @param id        鐩樼偣浠诲姟缂栧彿
-     * @param bpmResult BPM 瀹℃壒缁撴灉锛堥�氳繃/椹冲洖/鍙栨秷锛�
+     * @param id           鐩樼偣浠诲姟缂栧彿
+     * @param pass         鏄惁閫氳繃锛宼rue=閫氳繃 / false=涓嶉�氳繃
+     * @param reviewRemark 瀹℃牳鎰忚锛屽鏍镐笉閫氳繃鏃跺繀濉�
      */
-    void updateStockTakingTaskResultAuditStatus(Long id, Integer bpmResult);
-
-    /**
-     * 鑾峰彇鐩樼偣缁撴灉瀹℃壒鍙敤鐨� BPM 娴佺▼瀹氫箟鍒楄〃
-     *
-     * @return 娴佺▼瀹氫箟鍒楄〃锛坕d/key/name锛�
-     */
-    List<Map<String, Object>> getStockTakingTaskResultApprovalProcessDefinitionList();
+    void auditStockTakingResult(Long id, Boolean pass, String reviewRemark);
 
     /**
      * 鍙栨秷鐩樼偣浠诲姟
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskServiceImpl.java
index c419242..09ae4b4 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/MesWmStockTakingTaskServiceImpl.java
@@ -2,6 +2,7 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.stocktaking.task.vo.MesWmStockTakingTaskPageReqVO;
@@ -20,15 +21,11 @@
 import cn.iocoder.yudao.module.mes.service.wm.stocktaking.plan.MesWmStockTakingPlanService;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
-import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
+import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -38,11 +35,14 @@
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
 
 /**
@@ -55,13 +55,15 @@
 @Slf4j
 public class MesWmStockTakingTaskServiceImpl implements MesWmStockTakingTaskService {
 
-    @Resource
-    private MesWmStockTakingTaskMapper stockTakingTaskMapper;
+    /**
+     * 鐩樼偣缁撴灉瀹℃壒鐨勪笟鍔$被鍨嬬紪鐮�
+     *
+     * 涓� system_approval_config.biz_type 瀵瑰簲锛屽鏍镐汉鍦ㄣ�岀郴缁熺鐞� - 瀹℃壒閰嶇疆銆嶄腑缁存姢銆�
+     */
+    private static final String STOCK_TAKING_RESULT_APPROVE_BIZ_TYPE = "stock_taking_result_approve";
 
     @Resource
-    private BpmProcessInstanceApi processInstanceApi;
-    @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
+    private MesWmStockTakingTaskMapper stockTakingTaskMapper;
 
     @Resource
     private MesWmMaterialStockService materialStockService;
@@ -82,6 +84,9 @@
 
     @Resource
     private AdminUserApi adminUserApi;
+
+    @Resource
+    private ApprovalConfigApi approvalConfigApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -186,9 +191,8 @@
             throw exception(WM_STOCK_TAKING_TASK_NO_LINE);
         }
 
-        // 2. 鏇存柊浠诲姟鐘舵�佷负瀹℃壒涓�
-        stockTakingTaskMapper.updateById(new MesWmStockTakingTaskDO().setId(id)
-                .setStatus(MesWmStockTakingTaskStatusEnum.APPROVING.getStatus()));
+        // 2. 鏇存柊浠诲姟鐘舵�佷负鐩樼偣涓紝骞舵竻绌哄鏍告爣璁�
+        stockTakingTaskMapper.submitAndResetAuditInfo(id, MesWmStockTakingTaskStatusEnum.APPROVING.getStatus());
 
         // 3. 鏍规嵁鍐荤粨鏍囪瘑锛屽鐗╄祫杩涜鍐荤粨
         if (Boolean.TRUE.equals(task.getFrozen())) {
@@ -198,11 +202,11 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitStockTakingResultApproval(Long id, String processDefinitionKey) {
+    public void submitStockTakingResultApproval(Long id) {
         // 1.1 鏍¢獙浠诲姟瀛樺湪涓斿浜庣洏鐐逛腑鐘舵��
         MesWmStockTakingTaskDO task = validateStockTakingTaskExistsAndApproving(id);
-        // 1.2 鏍¢獙缁撴灉瀹℃壒鏈彁浜よ繃锛堥伩鍏嶉噸澶嶆彁浜わ級
-        if (task.getProcessInstanceId() != null) {
+        // 1.2 鏍¢獙鏈疆缁撴灉瀹℃壒鏈彁浜よ繃锛堥伩鍏嶉噸澶嶆彁浜わ級
+        if (isResultApprovalPending(task)) {
             throw exception(WM_STOCK_TAKING_TASK_ALREADY_SUBMIT_APPROVAL);
         }
         // 1.3 鏍¢獙鑷冲皯鏈変竴鏉$洏鐐圭粨鏋�
@@ -210,94 +214,80 @@
         if (CollUtil.isEmpty(results)) {
             throw exception(WM_STOCK_TAKING_TASK_NO_RESULT);
         }
+        // 1.4 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鏍镐汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
+        approvalConfigApi.validateApprovalEnabledAndGetApprovers(STOCK_TAKING_RESULT_APPROVE_BIZ_TYPE);
 
-        // 2. 鍒涘缓 BPM 娴佺▼瀹炰緥
-        String processInstanceId = processInstanceApi.createProcessInstance(getCurrentUserId(),
-                new BpmProcessInstanceCreateReqDTO()
-                        .setProcessDefinitionKey(processDefinitionKey)
-                        .setBusinessKey(String.valueOf(id)));
-
-        // 3. 鍥炲啓娴佺▼瀹炰緥缂栧彿锛堜换鍔′繚鎸佺洏鐐逛腑锛岀瓑寰呭鎵癸級
-        stockTakingTaskMapper.updateById(new MesWmStockTakingTaskDO()
-                .setId(id).setProcessInstanceId(processInstanceId));
+        // 2. 璁板綍鎻愪氦鏃堕棿骞舵竻绌轰笂涓�杞鏍哥粨鏋滐紙浠诲姟淇濇寔鐩樼偣涓紝绛夊緟瀹℃牳锛�
+        stockTakingTaskMapper.markResultApprovalSubmitted(id);
     }
 
     @Override
-    public List<Map<String, Object>> getStockTakingTaskResultApprovalProcessDefinitionList() {
-        return getProcessDefinitionListByCategory(APPROVE_CATEGORY_CODE);
+    public Set<Long> getStockTakingTaskApproverUserIds() {
+        return approvalConfigApi.getApproverUserIds(STOCK_TAKING_RESULT_APPROVE_BIZ_TYPE);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void updateStockTakingTaskResultAuditStatus(Long id, Integer bpmResult) {
+    public void auditStockTakingResult(Long id, Boolean pass, String reviewRemark) {
         // 1. 鏍¢獙浠诲姟瀛樺湪
         MesWmStockTakingTaskDO task = validateStockTakingTaskExists(id);
+        // 2. 鏍¢獙澶勪簬鐩樼偣涓紙鍚粨鏋滃鎵逛腑锛夌姸鎬�
         if (!MesWmStockTakingTaskStatusEnum.APPROVING.getStatus().equals(task.getStatus())) {
-            log.warn("[updateStockTakingTaskResultAuditStatus] 鐩樼偣浠诲姟({}) 涓嶅浜庣洏鐐逛腑鐘舵�侊紝蹇界暐瀹℃壒浜嬩欢", id);
-            return;
+            throw exception(WM_STOCK_TAKING_TASK_NOT_APPROVING);
         }
-        // 2. 瀹℃壒閫氳繃锛氬厛缃负宸插畬鎴愶紝鍐嶈В鍐诲苟鍚屼簨鍔¤嚜鍔ㄦ牳閿�宸紓
-        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
-            // 2.1 鍏堢疆涓哄凡瀹屾垚锛氫换鍔$姸鎬佸彉鏇村悗锛屽悗缁噸澶嶇殑瀹℃壒浜嬩欢璇诲彇鍒� FINISHED 鍗宠蹇界暐锛岄伩鍏嶉噸澶嶆牳閿�
-            stockTakingTaskMapper.updateById(new MesWmStockTakingTaskDO().setId(id)
-                    .setStatus(MesWmStockTakingTaskStatusEnum.FINISHED.getStatus()));
-            // 2.2 瑙e喕搴撳瓨锛氶』鍦ㄥ樊寮傛牳閿�鍓嶈В鍐伙紝鍚﹀垯鏍搁攢浜嬪姟浼氳搴撳瓨鍐荤粨鏍¢獙鎷︽埅
-            if (Boolean.TRUE.equals(task.getFrozen())) {
-                updateMaterialStockFrozen(stockTakingTaskLineService.getStockTakingTaskLineListByTaskId(id), false);
+        // 3. 鏍¢獙鏈疆缁撴灉瀹℃壒宸叉彁浜や笖灏氭湭瀹℃牳
+        if (!isResultApprovalPending(task)) {
+            throw exception(WM_STOCK_TAKING_TASK_RESULT_NOT_SUBMITTED);
+        }
+        // 4. 鏍¢獙褰撳墠鐧诲綍鐢ㄦ埛鏄涓氬姟绫诲瀷鐨勫鏍镐汉锛堟垨绛撅細浠讳竴浜哄潎鍙鏍革級
+        Long userId = getLoginUserId();
+        approvalConfigApi.validateApprover(STOCK_TAKING_RESULT_APPROVE_BIZ_TYPE, userId);
+        // 5. 瀹℃牳涓嶉�氳繃锛氬繀椤诲~鍐欏師鍥狅紝浠诲姟淇濇寔鐩樼偣涓紝鍙慨鏀瑰疄鐩樺悗閲嶆柊鎻愪氦缁撴灉瀹℃壒
+        if (!Boolean.TRUE.equals(pass)) {
+            if (StrUtil.isBlank(reviewRemark)) {
+                throw exception(WM_STOCK_TAKING_TASK_REJECT_REASON_REQUIRED);
             }
-            // 2.3 鑷姩鏍搁攢鐩樼偣宸紓锛氱洏鐩堝叆搴� / 鐩樹簭鍑哄簱锛屽悓浜嬪姟鍐呮洿鏂板簱瀛樺彴璐︼紱浠讳竴姝ュけ璐ユ暣浣撳洖婊氾紝浠诲姟鍥為��涓虹洏鐐逛腑
-            doProcessStockTakingDifference(task);
+            stockTakingTaskMapper.auditStockTakingTask(id, MesWmStockTakingTaskStatusEnum.APPROVING.getStatus(),
+                    userId, getUserNickname(userId), reviewRemark);
             return;
         }
-        // 3. 瀹℃壒椹冲洖锛氭竻绌烘祦绋嬪疄渚嬬紪鍙凤紝浠诲姟淇濇寔鐩樼偣涓紝鍙慨鏀瑰疄鐩樺悗閲嶆柊鎻愪氦缁撴灉瀹℃壒
-        if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
-            stockTakingTaskMapper.clearProcessInstanceId(id);
-            return;
+        // 6. 瀹℃牳閫氳繃锛氬厛缃负宸插畬鎴愬苟璁板綍瀹℃牳浜轰笌瀹℃牳鎰忚
+        stockTakingTaskMapper.auditStockTakingTask(id, MesWmStockTakingTaskStatusEnum.FINISHED.getStatus(),
+                userId, getUserNickname(userId), reviewRemark);
+        // 7. 瑙e喕搴撳瓨锛氶』鍦ㄥ樊寮傛牳閿�鍓嶈В鍐伙紝鍚﹀垯鏍搁攢浜嬪姟浼氳搴撳瓨鍐荤粨鏍¢獙鎷︽埅
+        if (Boolean.TRUE.equals(task.getFrozen())) {
+            updateMaterialStockFrozen(stockTakingTaskLineService.getStockTakingTaskLineListByTaskId(id), false);
         }
-        // 4. 瀹℃壒鍙栨秷锛氳В鍐诲簱瀛樺苟缃负宸插彇娑�
-        if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
-            if (Boolean.TRUE.equals(task.getFrozen())) {
-                updateMaterialStockFrozen(stockTakingTaskLineService.getStockTakingTaskLineListByTaskId(id), false);
-            }
-            stockTakingTaskMapper.clearProcessInstanceId(id);
-            stockTakingTaskMapper.updateById(new MesWmStockTakingTaskDO().setId(id)
-                    .setStatus(MesWmStockTakingTaskStatusEnum.CANCELED.getStatus()));
-        }
+        // 8. 鑷姩鏍搁攢鐩樼偣宸紓锛氱洏鐩堝叆搴� / 鐩樹簭鍑哄簱锛屽悓浜嬪姟鍐呮洿鏂板簱瀛樺彴璐︼紱浠讳竴姝ュけ璐ユ暣浣撳洖婊氾紝浠诲姟鍥為��涓虹洏鐐逛腑
+        doProcessStockTakingDifference(task);
     }
 
     /**
-     * 鑾峰彇鍒嗙被涓嬬殑鍙敤 BPM 娴佺▼瀹氫箟锛堣繃婊ゆ寕璧锋祦绋嬶紝鍚� Key 淇濈暀鏈�鏂扮増鏈級
+     * 鍒ゆ柇鏈疆鐩樼偣缁撴灉瀹℃壒鏄惁宸叉彁浜や笖灏氭湭瀹℃牳
      *
-     * @param categoryCode 娴佺▼鍒嗙被缂栫爜
-     * @return 娴佺▼瀹氫箟鍒楄〃锛坕d/key/name锛�
+     * 浠诲姟鐘舵�� 2锛堢洏鐐逛腑锛夊悓鏃舵壙杞姐�岀洏鐐逛腑銆嶄笌銆岀洏鐐圭粨鏋滃鎵逛腑銆嶄袱涓樁娈碉紝
+     * 浠� reviewTime 闈炵┖涓� reviewerId 涓虹┖浣滀负銆屽凡鎻愪氦銆佺瓑寰呭鏍搞�嶇殑鍒ゅ畾鏉′欢锛�
+     * 瀹℃牳涓嶉�氳繃鍚� reviewerId 闈炵┖锛屼换鍔″洖鍒板彲閲嶆柊鎻愪氦缁撴灉瀹℃壒鐨勭姸鎬併��
+     *
+     * @param task 鐩樼偣浠诲姟
+     * @return 鏄惁澶勪簬缁撴灉瀹℃壒涓�
      */
-    private List<Map<String, Object>> getProcessDefinitionListByCategory(String categoryCode) {
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(categoryCode);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            return Collections.emptyList();
+    private boolean isResultApprovalPending(MesWmStockTakingTaskDO task) {
+        return task.getReviewerId() == null && task.getReviewTime() != null;
+    }
+
+    /**
+     * 鑾峰彇鐢ㄦ埛鏄电О
+     *
+     * @param userId 鐢ㄦ埛缂栧彿
+     * @return 鏄电О锛岀敤鎴蜂笉瀛樺湪鏃惰繑鍥� null
+     */
+    private String getUserNickname(Long userId) {
+        if (userId == null) {
+            return null;
         }
-        // 杩囨护婵�娲荤姸鎬侊紝淇濈暀鏈�鏂扮増鏈�
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (BpmProcessDefinitionInfoDO info : definitionInfoList) {
-            ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId());
-            if (pd == null || pd.isSuspended()) {
-                continue;
-            }
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-        List<Map<String, Object>> result = new ArrayList<>();
-        for (ProcessDefinition pd : latestVersionMap.values()) {
-            Map<String, Object> item = new HashMap<>();
-            item.put("id", pd.getId());
-            item.put("key", pd.getKey());
-            item.put("name", pd.getName());
-            result.add(item);
-        }
-        return result;
+        AdminUserRespDTO user = adminUserApi.getUser(userId);
+        return user == null ? null : user.getNickname();
     }
 
     private Long getCurrentUserId() {
@@ -318,8 +308,8 @@
         }
         task.setStatus(MesWmStockTakingTaskStatusEnum.CANCELED.getStatus());
         stockTakingTaskMapper.updateById(task);
-        // 鍙栨秷鍚庢竻绌烘祦绋嬪疄渚嬬紪鍙凤紝閬垮厤娈嬬暀瀹℃壒鏍囪褰卞搷鍚庣画閲嶆柊寮�濮嬬洏鐐�
-        stockTakingTaskMapper.clearProcessInstanceId(id);
+        // 鍙栨秷鍚庢竻绌哄鏍告爣璁帮紝閬垮厤娈嬬暀瀹℃壒鏍囪褰卞搷鍚庣画閲嶆柊寮�濮嬬洏鐐�
+        stockTakingTaskMapper.clearAuditInfo(id);
         if (Boolean.TRUE.equals(task.getFrozen())) {
             updateMaterialStockFrozen(stockTakingTaskLineService.getStockTakingTaskLineListByTaskId(id), false);
         }
@@ -384,7 +374,7 @@
     /**
      * 鑷姩鏍搁攢鐩樼偣宸紓锛氭寜鐩樼偣缁撴灉閫愯鐢熸垚 IN/OUT 搴撳瓨浜嬪姟鏇存柊搴撳瓨鍙拌处
      *
-     * <p>浠呯敱 {@link #updateStockTakingTaskResultAuditStatus} 鐨勫鎵归�氳繃鍒嗘敮鍦ㄥ悓浜嬪姟鍐呰皟鐢紱
+     * <p>浠呯敱 {@link #auditStockTakingResult} 鐨勫鏍搁�氳繃鍒嗘敮鍦ㄥ悓浜嬪姟鍐呰皟鐢紱
      * 澶辫触鏁翠綋鍥炴粴锛屼换鍔″洖閫�涓虹洏鐐逛腑鐘舵�侊紝閬垮厤閲嶅璋冩暣銆�
      *
      * @param task 宸茬疆涓哄凡瀹屾垚銆佸凡瑙e喕鐨勭洏鐐逛换鍔�
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/listener/MesWmStockTakingTaskResultStatusListener.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/listener/MesWmStockTakingTaskResultStatusListener.java
deleted file mode 100644
index 0ec8424..0000000
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/stocktaking/task/listener/MesWmStockTakingTaskResultStatusListener.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package cn.iocoder.yudao.module.mes.service.wm.stocktaking.task.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.mes.service.wm.stocktaking.task.MesWmStockTakingTaskService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-/**
- * MES 鐩樼偣缁撴灉瀹℃壒 BPM 鐘舵�佺洃鍚櫒
- *
- * 鐩戝惉鐩樼偣缁撴灉瀹℃壒娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹細瀹℃壒閫氳繃鍚庤В鍐诲簱瀛樺苟鑷姩鏍搁攢鐩樼偣宸紓缃负宸插畬鎴愶紱
- * 椹冲洖鍚庝换鍔′繚鎸佺洏鐐逛腑鍙慨鏀瑰疄鐩橀噸鏂版彁浜わ紱鍙栨秷鍒欒В鍐诲苟缃负宸插彇娑�
- */
-@Component
-@Slf4j
-public class MesWmStockTakingTaskResultStatusListener
-        extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener {
-
-    @Resource
-    private MesWmStockTakingTaskService stockTakingTaskService;
-
-    @Override
-    protected String getProcessDefinitionKey() {
-        return MesWmStockTakingTaskService.APPROVE_CATEGORY_CODE;
-    }
-
-    @Override
-    protected void onEvent(BpmProcessInstanceStatusEvent event) {
-        Long id;
-        try {
-            id = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勭洏鐐逛换鍔$紪鍙�", event.getBusinessKey());
-            return;
-        }
-        log.info("[onEvent] 鏀跺埌鐩樼偣缁撴灉瀹℃壒浜嬩欢锛宻tockTakingTaskId={}, status={}", id, event.getStatus());
-        try {
-            stockTakingTaskService.updateStockTakingTaskResultAuditStatus(id, event.getStatus());
-            log.info("[onEvent] 鐩樼偣浠诲姟({}) 缁撴灉瀹℃壒鐘舵�佹洿鏂板畬鎴�", id);
-        } catch (Exception e) {
-            log.error("[onEvent] 鏇存柊鐩樼偣浠诲姟缁撴灉瀹℃壒鐘舵�佸け璐ワ紝stockTakingTaskId={}", id, e);
-        }
-    }
-
-}
diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java
index 81e6c02..de53ca5 100644
--- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java
+++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java
@@ -11,9 +11,12 @@
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.*;
 import cn.iocoder.yudao.module.system.convert.user.UserConvert;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
 import cn.iocoder.yudao.module.system.enums.common.SexEnum;
 import cn.iocoder.yudao.module.system.service.dept.DeptService;
+import cn.iocoder.yudao.module.system.service.permission.PermissionService;
+import cn.iocoder.yudao.module.system.service.permission.RoleService;
 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -33,6 +36,8 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -49,6 +54,10 @@
     private AdminUserService userService;
     @Resource
     private DeptService deptService;
+    @Resource
+    private RoleService roleService;
+    @Resource
+    private PermissionService permissionService;
 
     @PostMapping("/create")
     @Operation(summary = "鏂板鐢ㄦ埛")
@@ -148,6 +157,32 @@
         return success(UserConvert.INSTANCE.convertSimpleList(list, deptMap));
     }
 
+    @GetMapping("/list-by-role-code")
+    @Operation(summary = "鑾峰緱鎸囧畾瑙掕壊缂栫爜鐨勭敤鎴风簿绠�淇℃伅鍒楄〃", description = "鍙寘鍚寮�鍚殑鐢ㄦ埛锛屼富瑕佺敤浜庡墠绔殑涓嬫媺閫夐」")
+    @Parameter(name = "code", description = "瑙掕壊缂栫爜", required = true, example = "production_submit_work")
+    public CommonResult<List<UserSimpleRespVO>> getUserListByRoleCode(@RequestParam("code") String code) {
+        // 1. 鏌ヨ瑙掕壊
+        RoleDO role = roleService.getRoleByCode(code);
+        if (role == null) {
+            return success(Collections.emptyList());
+        }
+        // 2. 鏌ヨ鎷ユ湁璇ヨ鑹茬殑鐢ㄦ埛缂栧彿
+        Set<Long> userIds = permissionService.getUserRoleIdListByRoleId(Collections.singletonList(role.getId()));
+        if (CollUtil.isEmpty(userIds)) {
+            return success(Collections.emptyList());
+        }
+        // 3. 鏌ヨ鐢ㄦ埛锛屽彧淇濈暀寮�鍚姸鎬�
+        List<AdminUserDO> list = userService.getUserList(userIds).stream()
+                .filter(user -> CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus()))
+                .collect(Collectors.toList());
+        if (CollUtil.isEmpty(list)) {
+            return success(Collections.emptyList());
+        }
+        // 4. 鎷兼帴閮ㄩ棬鏁版嵁
+        Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertList(list, AdminUserDO::getDeptId));
+        return success(UserConvert.INSTANCE.convertSimpleList(list, deptMap));
+    }
+
     @GetMapping("/get")
     @Operation(summary = "鑾峰緱鐢ㄦ埛璇︽儏")
     @Parameter(name = "id", description = "缂栧彿", required = true, example = "1024")
diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java
index 7d4b133..e048a8f 100644
--- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java
+++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java
@@ -73,6 +73,14 @@
     RoleDO getRoleFromCache(Long id);
 
     /**
+     * 鏍规嵁瑙掕壊缂栫爜鑾峰緱瑙掕壊
+     *
+     * @param code 瑙掕壊缂栫爜
+     * @return 瑙掕壊
+     */
+    RoleDO getRoleByCode(String code);
+
+    /**
      * 鑾峰緱瑙掕壊鍒楄〃
      *
      * @param ids 瑙掕壊缂栧彿鏁扮粍
diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java
index c1559e2..a0c9913 100644
--- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java
+++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java
@@ -196,6 +196,11 @@
         return roleMapper.selectById(id);
     }
 
+    @Override
+    public RoleDO getRoleByCode(String code) {
+        return roleMapper.selectByCode(code);
+    }
+
 
     @Override
     public List<RoleDO> getRoleListByStatus(Collection<Integer> statuses) {

--
Gitblit v1.9.3