feat(erp): 实现请购单双层审批流程

- 在提交审批接口中新增指定一审审批人的参数
- 实现一审和二审的两级审批逻辑,一审为管理层审批,二审固定为陈清鑫
- 添加审批人身份验证,确保只有指定审批人才能进行审批操作
- 在前端界面中增加提交审批选择审批人弹窗
- 更新请购单状态显示,新增一审通过待二审状态(状态值6)
- 添加审批进度展示,显示一审人和二审人的审批情况
- 实现基于角色的审批权限控制,管理层可进行一审,特定人员可进行二审
- 新增查询审批人列表的API接口,支持按角色筛选审批人
- 优化审批按钮显示逻辑,根据不同状态和用户身份显示相应操作按钮
This commit is contained in:
jhd
2026-07-08 11:03:50 +08:00
parent abfd5e2ee6
commit ae928692d3
8 changed files with 190 additions and 27 deletions

View File

@@ -85,13 +85,14 @@ public class ErpPurchaseRequisitionController extends BaseController {
@Log(title = "请购及采购单", businessType = BusinessType.UPDATE)
@SaCheckPermission("erp:purchaseRequisition:approve")
@PutMapping("/{reqId}/submit")
public R<Void> submitApproval(@NotNull(message = "主键不能为空") @PathVariable Long reqId) {
return toAjax(iErpPurchaseRequisitionService.submitApproval(reqId));
public R<Void> submitApproval(@NotNull(message = "主键不能为空") @PathVariable Long reqId,
@NotNull(message = "审批人不能为空") @RequestParam Long firstApproverId,
@NotEmpty(message = "审批人姓名不能为空") @RequestParam String firstApproverName) {
return toAjax(iErpPurchaseRequisitionService.submitApproval(reqId, firstApproverId, firstApproverName));
}
/** 审批通过(审批中 → 已通过) */
@Log(title = "请购及采购单", businessType = BusinessType.UPDATE)
@SaCheckPermission("erp:purchaseRequisition:approve")
@PutMapping("/{reqId}/approve")
public R<Void> approve(@NotNull(message = "主键不能为空") @PathVariable Long reqId) {
return toAjax(iErpPurchaseRequisitionService.approve(reqId));
@@ -99,7 +100,6 @@ public class ErpPurchaseRequisitionController extends BaseController {
/** 驳回(审批中 → 已驳回) */
@Log(title = "请购及采购单", businessType = BusinessType.UPDATE)
@SaCheckPermission("erp:purchaseRequisition:approve")
@PutMapping("/{reqId}/reject")
public R<Void> reject(@NotNull(message = "主键不能为空") @PathVariable Long reqId) {
return toAjax(iErpPurchaseRequisitionService.reject(reqId));

View File

@@ -35,7 +35,7 @@ public interface IErpPurchaseRequisitionService {
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/** 提交审批(草稿 → 审批中) */
Boolean submitApproval(Long reqId);
Boolean submitApproval(Long reqId, Long firstApproverId, String firstApproverName);
/** 审批通过(审批中 → 已通过) */
Boolean approve(Long reqId);

View File

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.page.TableDataInfo;
import com.klp.common.helper.LoginHelper;
import com.klp.common.utils.StringUtils;
import com.klp.erp.domain.ErpPurchaseRequisition;
import com.klp.erp.domain.ErpPurchaseRequisitionItem;
@@ -135,13 +136,14 @@ public class ErpPurchaseRequisitionServiceImpl implements IErpPurchaseRequisitio
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean submitApproval(Long reqId) {
public Boolean submitApproval(Long reqId, Long firstApproverId, String firstApproverName) {
ErpPurchaseRequisition entity = baseMapper.selectById(reqId);
if (entity == null) return false;
if (!"0".equals(entity.getFormStatus())) {
throw new RuntimeException("仅草稿状态的请购单可提交审批");
}
entity.setFormStatus("1");
entity.setSignPurchaseHandler(firstApproverName);
return baseMapper.updateById(entity) > 0;
}
@@ -150,11 +152,29 @@ public class ErpPurchaseRequisitionServiceImpl implements IErpPurchaseRequisitio
public Boolean approve(Long reqId) {
ErpPurchaseRequisition entity = baseMapper.selectById(reqId);
if (entity == null) return false;
if (!"1".equals(entity.getFormStatus())) {
throw new RuntimeException("仅审批中状态的请购单可通过");
String currentNickName = LoginHelper.getNickName();
if ("1".equals(entity.getFormStatus())) {
// 一审:校验是否指定的一审人
String approverName = entity.getSignPurchaseHandler();
if (approverName == null || !approverName.equals(currentNickName)) {
throw new RuntimeException("您不是该请购单指定的审批人");
}
entity.setFormStatus("6");
return baseMapper.updateById(entity) > 0;
} else if ("6".equals(entity.getFormStatus())) {
// 二审:校验是否是陈清鑫
if (!"陈清鑫".equals(currentNickName)) {
throw new RuntimeException("二审仅限指定审批人操作");
}
entity.setFormStatus("2");
entity.setSignRequestGm("陈清鑫");
return baseMapper.updateById(entity) > 0;
} else {
throw new RuntimeException("当前状态不允许审批通过");
}
entity.setFormStatus("2");
return baseMapper.updateById(entity) > 0;
}
@Override
@@ -162,11 +182,28 @@ public class ErpPurchaseRequisitionServiceImpl implements IErpPurchaseRequisitio
public Boolean reject(Long reqId) {
ErpPurchaseRequisition entity = baseMapper.selectById(reqId);
if (entity == null) return false;
if (!"1".equals(entity.getFormStatus())) {
String currentNickName = LoginHelper.getNickName();
if ("1".equals(entity.getFormStatus())) {
// 一审期间驳回
String approverName = entity.getSignPurchaseHandler();
if (approverName == null || !approverName.equals(currentNickName)) {
throw new RuntimeException("您不是该请购单指定的审批人");
}
entity.setFormStatus("5");
return baseMapper.updateById(entity) > 0;
} else if ("6".equals(entity.getFormStatus())) {
// 二审期间驳回:仅陈清鑫可驳回
if (!"陈清鑫".equals(currentNickName)) {
throw new RuntimeException("二审仅限指定审批人操作");
}
entity.setFormStatus("5");
return baseMapper.updateById(entity) > 0;
} else {
throw new RuntimeException("仅审批中状态的请购单可驳回");
}
entity.setFormStatus("5");
return baseMapper.updateById(entity) > 0;
}
}