feat(audit): 增强审核功能并优化查询接口

- 在AuditPageQry和OrderPageQry中新增订单编号、车辆编号和车牌字段
- 重构审核网关实现,添加详细的业务验证逻辑和异常处理
- 实现录入员提交审核、撤回审核以及审核员驳回等功能
- 优化消息通知机制,添加目标用户过滤功能
- 修复数据库表字段映射错误,统一audit_reason和delivery_time字段名
- 添加订单发货时西瓜等级更新的安全检查
- 实现自定义分页查询支持订单编号、车辆编号和车牌的模糊搜索
This commit is contained in:
shenyifei 2026-01-16 11:05:39 +08:00
parent a0bfb12556
commit 198cc6e8d9
7 changed files with 340 additions and 171 deletions

View File

@ -52,14 +52,12 @@ public class AuditGatewayImpl implements AuditGateway {
LambdaQueryWrapper<AuditDO> queryWrapper = Wrappers.lambdaQuery(AuditDO.class); LambdaQueryWrapper<AuditDO> queryWrapper = Wrappers.lambdaQuery(AuditDO.class);
queryWrapper.eq(Objects.nonNull(auditPageQry.getAuditId()), AuditDO::getAuditId, auditPageQry.getAuditId()); queryWrapper.eq(Objects.nonNull(auditPageQry.getAuditId()), AuditDO::getAuditId, auditPageQry.getAuditId());
queryWrapper.eq(Objects.nonNull(auditPageQry.getType()), AuditDO::getType, auditPageQry.getType());
queryWrapper.eq(Objects.nonNull(auditPageQry.getState()), AuditDO::getState, auditPageQry.getState());
queryWrapper.eq(Objects.nonNull(auditPageQry.getSubjectType()), AuditDO::getSubjectType, auditPageQry.getSubjectType()); queryWrapper.eq(Objects.nonNull(auditPageQry.getSubjectType()), AuditDO::getSubjectType, auditPageQry.getSubjectType());
queryWrapper.orderByDesc(AuditDO::getCreatedAt); queryWrapper.orderByDesc(AuditDO::getCreatedAt);
IPage<AuditDO> page = new Page<>(auditPageQry.getPageIndex(), auditPageQry.getPageSize()); IPage<AuditDO> page = new Page<>(auditPageQry.getPageIndex(), auditPageQry.getPageSize());
page = auditMapper.selectPage(page, queryWrapper); page = auditMapper.selectPage(page, queryWrapper, auditPageQry);
Set<Long> orderIdList = page.getRecords().stream().filter(auditDO -> auditDO.getSubjectType().equals(AuditSubjectTypeEnum.PURCHASE_ORDER)).map(AuditDO::getSubjectId).collect(Collectors.toSet()); Set<Long> orderIdList = page.getRecords().stream().filter(auditDO -> auditDO.getSubjectType().equals(AuditSubjectTypeEnum.PURCHASE_ORDER)).map(AuditDO::getSubjectId).collect(Collectors.toSet());
if (CollUtil.isNotEmpty(orderIdList)) { if (CollUtil.isNotEmpty(orderIdList)) {
List<OrderDO> orderDOList = orderMapper.selectByOrderIdList(orderIdList); List<OrderDO> orderDOList = orderMapper.selectByOrderIdList(orderIdList);
@ -103,8 +101,25 @@ public class AuditGatewayImpl implements AuditGateway {
return auditConvert.toAudit(auditDO); return auditConvert.toAudit(auditDO);
} }
/**
* 录入员提交审核
* 1录入员首次提交
* 2审核员驳回后录入员提交
*/
@Override @Override
public Audit submitReview(OrderSubmitReviewCmd orderSubmitReviewCmd) { public Audit submitReview(OrderSubmitReviewCmd orderSubmitReviewCmd) {
// 1. 验证订单是否存在
OrderDO orderDO = orderMapper.selectByOrderId(orderSubmitReviewCmd.getOrderId());
if (Objects.isNull(orderDO)) {
throw new BizException(BizErrorCode.B_BIZ_ORDER_NOT_FOUND);
}
// 2. 验证订单状态是否允许提交审核
if (!orderDO.getState().equals(OrderStateEnum.DRAFT)) {
throw new BizException(BizErrorCode.B_BIZ_ORDER_NOT_DRAFT);
}
// 3. 查询或创建审核记录
LambdaQueryWrapper<AuditDO> auditQueryWrapper = Wrappers.lambdaQuery(AuditDO.class); LambdaQueryWrapper<AuditDO> auditQueryWrapper = Wrappers.lambdaQuery(AuditDO.class);
auditQueryWrapper.eq(AuditDO::getSubjectId, orderSubmitReviewCmd.getOrderId()); auditQueryWrapper.eq(AuditDO::getSubjectId, orderSubmitReviewCmd.getOrderId());
auditQueryWrapper.eq(AuditDO::getSubjectType, AuditSubjectTypeEnum.PURCHASE_ORDER); auditQueryWrapper.eq(AuditDO::getSubjectType, AuditSubjectTypeEnum.PURCHASE_ORDER);
@ -126,167 +141,206 @@ public class AuditGatewayImpl implements AuditGateway {
auditMapper.updateById(auditDO); auditMapper.updateById(auditDO);
} }
// 发送提审消息待审核消息 // 4. 发送提审消息待审核消息
sendAuditNotification(MessageTemplateSceneEnum.WAIT_AUDIT, auditDO, auditDO.getAuditId(), sendAuditNotification(MessageTemplateSceneEnum.WAIT_AUDIT, auditDO, orderSubmitReviewCmd.getCreatedBy(), orderSubmitReviewCmd.getCreatedByName());
orderSubmitReviewCmd.getCreatedBy(), orderSubmitReviewCmd.getCreatedByName());
return auditConvert.toAudit(auditDO); return auditConvert.toAudit(auditDO);
} }
/**
* 录入员撤回审核
*/
@Override @Override
public Audit withdrawReview(OrderWithdrawReviewCmd orderWithdrawReviewCmd) { public Audit withdrawReview(OrderWithdrawReviewCmd orderWithdrawReviewCmd) {
// 更新审核记录状态为草稿撤回审核 // 1. 验证审核记录ID
LambdaQueryWrapper<AuditDO> auditQueryWrapper = Wrappers.lambdaQuery(AuditDO.class); Long auditId = orderWithdrawReviewCmd.getAuditId();
auditQueryWrapper.eq(AuditDO::getSubjectId, orderWithdrawReviewCmd.getOrderId()); if (Objects.isNull(auditId)) {
auditQueryWrapper.eq(AuditDO::getSubjectType, AuditSubjectTypeEnum.PURCHASE_ORDER);
auditQueryWrapper.eq(AuditDO::getState, AuditStateEnum.WAITING_AUDIT);
auditQueryWrapper.eq(AuditDO::getType, AuditTypeEnum.REVIEWER_AUDIT);
auditQueryWrapper.last("limit 1");
AuditDO auditDO = auditMapper.selectOne(auditQueryWrapper);
if (auditDO != null) {
auditDO.setState(AuditStateEnum.AUDIT_CANCEL);
auditDO.setAuditAt(LocalDateTime.now());
auditDO.setAuditBy(orderWithdrawReviewCmd.getCreatedBy());
auditDO.setAuditByName(orderWithdrawReviewCmd.getCreatedByName());
auditMapper.updateById(auditDO);
}
// 撤回审核不发送消息通知
return auditConvert.toAudit(auditDO);
}
@Override
public Audit rejectApprove(OrderRejectApproveCmd orderRejectApproveCmd) {
// 更新审核记录
LambdaQueryWrapper<AuditDO> auditQueryWrapper = Wrappers.lambdaQuery(AuditDO.class);
auditQueryWrapper.eq(AuditDO::getAuditId, orderRejectApproveCmd.getAuditId());
auditQueryWrapper.eq(AuditDO::getSubjectId, orderRejectApproveCmd.getOrderId());
auditQueryWrapper.eq(AuditDO::getSubjectType, AuditSubjectTypeEnum.PURCHASE_ORDER);
auditQueryWrapper.eq(AuditDO::getState, AuditStateEnum.WAITING_AUDIT);
auditQueryWrapper.eq(AuditDO::getType, AuditTypeEnum.REVIEWER_AUDIT);
auditQueryWrapper.last("limit 1");
AuditDO auditDO = auditMapper.selectOne(auditQueryWrapper);
if (auditDO != null) {
auditDO.setState(AuditStateEnum.AUDIT_REJECTED);
auditDO.setAuditReason(orderRejectApproveCmd.getRejectReason());
auditDO.setAuditAt(LocalDateTime.now());
auditDO.setAuditBy(orderRejectApproveCmd.getCreatedBy());
auditDO.setAuditByName(orderRejectApproveCmd.getCreatedByName());
auditMapper.updateById(auditDO);
} else {
// 如果审核记录不存在抛出异常
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND); throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
} }
// 发送审核驳回消息 // 2. 查询审核记录
sendAuditNotification(MessageTemplateSceneEnum.AUDIT_REJECT, auditDO, auditDO.getAuditId(), AuditDO auditDO = auditMapper.selectById(auditId);
orderRejectApproveCmd.getCreatedBy(), orderRejectApproveCmd.getCreatedByName());
return auditConvert.toAudit(auditDO);
}
@Override
public Audit finalApprove(OrderFinalApproveCmd orderFinalApproveCmd) {
// 更新审核记录为审核成功
LambdaQueryWrapper<AuditDO> auditQueryWrapper = Wrappers.lambdaQuery(AuditDO.class);
auditQueryWrapper.eq(AuditDO::getSubjectId, orderFinalApproveCmd.getOrderId());
auditQueryWrapper.eq(AuditDO::getSubjectType, AuditSubjectTypeEnum.PURCHASE_ORDER);
auditQueryWrapper.eq(AuditDO::getState, AuditStateEnum.WAITING_AUDIT);
auditQueryWrapper.eq(AuditDO::getType, AuditTypeEnum.BOSS_AUDIT);
auditQueryWrapper.eq(AuditDO::getAuditId, orderFinalApproveCmd.getAuditId());
auditQueryWrapper.last("limit 1");
AuditDO auditDO = auditMapper.selectOne(auditQueryWrapper);
if (auditDO != null) {
auditDO.setState(AuditStateEnum.AUDIT_SUCCESS);
auditDO.setAuditAt(LocalDateTime.now());
auditDO.setAuditBy(orderFinalApproveCmd.getCreatedBy());
auditDO.setAuditByName(orderFinalApproveCmd.getCreatedByName());
auditMapper.updateById(auditDO);
} else {
// 如果审核记录不存在抛出异常
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 发送审批通过消息
sendAuditNotification(MessageTemplateSceneEnum.APPROVE_PASS, auditDO, auditDO.getAuditId(),
orderFinalApproveCmd.getCreatedBy(), orderFinalApproveCmd.getCreatedByName());
return auditConvert.toAudit(auditDO);
}
@Override
public Audit rejectFinal(OrderRejectFinalCmd orderRejectFinalCmd) {
// 更新审核记录
LambdaQueryWrapper<AuditDO> auditQueryWrapper = Wrappers.lambdaQuery(AuditDO.class);
auditQueryWrapper.eq(AuditDO::getSubjectId, orderRejectFinalCmd.getOrderId());
auditQueryWrapper.eq(AuditDO::getSubjectType, AuditSubjectTypeEnum.PURCHASE_ORDER);
auditQueryWrapper.eq(AuditDO::getState, AuditStateEnum.WAITING_AUDIT);
auditQueryWrapper.eq(AuditDO::getType, AuditTypeEnum.BOSS_AUDIT);
auditQueryWrapper.eq(AuditDO::getAuditId, orderRejectFinalCmd.getAuditId());
auditQueryWrapper.last("limit 1");
AuditDO auditDO = auditMapper.selectOne(auditQueryWrapper);
if (auditDO != null) {
auditDO.setState(AuditStateEnum.AUDIT_REJECTED);
auditDO.setAuditReason(orderRejectFinalCmd.getRejectReason());
auditDO.setAuditAt(LocalDateTime.now());
auditDO.setAuditBy(orderRejectFinalCmd.getCreatedBy());
auditDO.setAuditByName(orderRejectFinalCmd.getCreatedByName());
auditMapper.updateById(auditDO);
} else {
// 如果审核记录不存在抛出异常
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 发送审批驳回消息
sendAuditNotification(MessageTemplateSceneEnum.APPROVE_REJECT, auditDO, auditDO.getAuditId(),
orderRejectFinalCmd.getCreatedBy(), orderRejectFinalCmd.getCreatedByName());
return auditConvert.toAudit(auditDO);
}
@Override
public Audit approve(OrderApproveCmd orderApproveCmd) {
// 更新审核记录状态为审核成功
LambdaQueryWrapper<AuditDO> auditQueryWrapper = Wrappers.lambdaQuery(AuditDO.class);
auditQueryWrapper.eq(AuditDO::getSubjectId, orderApproveCmd.getOrderId());
auditQueryWrapper.eq(AuditDO::getSubjectType, AuditSubjectTypeEnum.PURCHASE_ORDER);
auditQueryWrapper.eq(AuditDO::getState, AuditStateEnum.WAITING_AUDIT);
auditQueryWrapper.eq(AuditDO::getType, AuditTypeEnum.REVIEWER_AUDIT);
AuditDO auditDO = auditMapper.selectOne(auditQueryWrapper);
if (Objects.isNull(auditDO)) { if (Objects.isNull(auditDO)) {
// 如果审核记录不存在抛出异常
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND); throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
} }
if (orderApproveCmd.getDraft()) { // 3. 验证审核记录状态是否为待审核
return auditConvert.toAudit(auditDO); if (!auditDO.getState().equals(AuditStateEnum.WAITING_AUDIT)) {
throw new BizException(BizErrorCode.B_BIZ_ORDER_NOT_WAITING_FOR_WITHDRAW);
} }
auditDO.setState(AuditStateEnum.AUDIT_SUCCESS); // 4. 更新审核记录状态为已取消
auditDO.setState(AuditStateEnum.AUDIT_CANCEL);
auditDO.setAuditAt(LocalDateTime.now()); auditDO.setAuditAt(LocalDateTime.now());
auditDO.setAuditBy(orderApproveCmd.getCreatedBy()); auditDO.setAuditBy(orderWithdrawReviewCmd.getCreatedBy());
auditDO.setAuditByName(orderApproveCmd.getCreatedByName()); auditDO.setAuditByName(orderWithdrawReviewCmd.getCreatedByName());
auditMapper.updateById(auditDO); auditMapper.updateById(auditDO);
// 更新审核记录状态为审核成功 // 撤回审核不发送消息通知
LambdaQueryWrapper<AuditDO> approveQueryWrapper = Wrappers.lambdaQuery(AuditDO.class); return auditConvert.toAudit(auditDO);
approveQueryWrapper.eq(AuditDO::getSubjectId, orderApproveCmd.getOrderId()); }
approveQueryWrapper.eq(AuditDO::getSubjectType, AuditSubjectTypeEnum.PURCHASE_ORDER);
approveQueryWrapper.eq(AuditDO::getType, AuditTypeEnum.BOSS_AUDIT); /**
AuditDO auditDO1 = auditMapper.selectOne(approveQueryWrapper); * 审核员驳回
if (Objects.nonNull(auditDO1)) { */
// 存在老板审批记录就修改状态 @Override
auditDO1.setState(AuditStateEnum.WAITING_AUDIT); public Audit rejectApprove(OrderRejectApproveCmd orderRejectApproveCmd) {
auditMapper.updateById(auditDO1); // 1. 验证审核记录ID
} else { Long auditId = orderRejectApproveCmd.getAuditId();
if (Objects.isNull(auditId)) {
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 2. 查询审核记录
AuditDO auditDO = auditMapper.selectById(auditId);
if (Objects.isNull(auditDO)) {
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 3. 验证审核记录类型是否为审核员审核
if (!auditDO.getType().equals(AuditTypeEnum.REVIEWER_AUDIT)) {
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 4. 验证审核记录状态是否为待审核
if (!auditDO.getState().equals(AuditStateEnum.WAITING_AUDIT)) {
throw new BizException(BizErrorCode.B_BIZ_ORDER_NOT_WAITING_AUDIT);
}
// 5. 更新审核记录为已驳回
auditDO.setState(AuditStateEnum.AUDIT_REJECTED);
auditDO.setAuditReason(orderRejectApproveCmd.getRejectReason());
auditDO.setAuditAt(LocalDateTime.now());
auditDO.setAuditBy(orderRejectApproveCmd.getCreatedBy());
auditDO.setAuditByName(orderRejectApproveCmd.getCreatedByName());
auditMapper.updateById(auditDO);
// 6. 发送审核驳回消息
sendAuditNotification(MessageTemplateSceneEnum.AUDIT_REJECT, auditDO, orderRejectApproveCmd.getCreatedBy(), orderRejectApproveCmd.getCreatedByName());
return auditConvert.toAudit(auditDO);
}
/**
* 老板审批通过
*/
@Override
public Audit finalApprove(OrderFinalApproveCmd orderFinalApproveCmd) {
// 1. 验证审核记录ID
Long auditId = orderFinalApproveCmd.getAuditId();
if (Objects.isNull(auditId)) {
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 2. 查询审核记录
AuditDO auditDO = auditMapper.selectById(auditId);
if (Objects.isNull(auditDO)) {
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 3. 验证审核记录类型是否为老板审核
if (!auditDO.getType().equals(AuditTypeEnum.BOSS_AUDIT)) {
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 4. 验证审核记录状态是否为待审核
if (!auditDO.getState().equals(AuditStateEnum.WAITING_AUDIT)) {
throw new BizException(BizErrorCode.B_BIZ_ORDER_NOT_WAITING_FOR_FINAL_APPROVE);
}
// 5. 更新审核记录为审核成功
auditDO.setState(AuditStateEnum.AUDIT_SUCCESS);
auditDO.setAuditAt(LocalDateTime.now());
auditDO.setAuditBy(orderFinalApproveCmd.getCreatedBy());
auditDO.setAuditByName(orderFinalApproveCmd.getCreatedByName());
auditMapper.updateById(auditDO);
// 6. 发送审批通过消息
sendAuditNotification(MessageTemplateSceneEnum.APPROVE_PASS, auditDO, orderFinalApproveCmd.getCreatedBy(), orderFinalApproveCmd.getCreatedByName());
return auditConvert.toAudit(auditDO);
}
/**
* 老板审批驳回
*/
@Override
public Audit rejectFinal(OrderRejectFinalCmd orderRejectFinalCmd) {
// 1. 验证审核记录ID
Long auditId = orderRejectFinalCmd.getAuditId();
if (Objects.isNull(auditId)) {
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 2. 查询审核记录
AuditDO auditDO = auditMapper.selectById(auditId);
if (Objects.isNull(auditDO)) {
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 3. 验证审核记录类型是否为老板审核
if (!auditDO.getType().equals(AuditTypeEnum.BOSS_AUDIT)) {
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 4. 验证审核记录状态是否为待审核
if (!auditDO.getState().equals(AuditStateEnum.WAITING_AUDIT)) {
throw new BizException(BizErrorCode.B_BIZ_ORDER_NOT_WAITING_FOR_REJECT_FINAL);
}
// 5. 更新审核记录为已驳回
auditDO.setState(AuditStateEnum.AUDIT_REJECTED);
auditDO.setAuditReason(orderRejectFinalCmd.getRejectReason());
auditDO.setAuditAt(LocalDateTime.now());
auditDO.setAuditBy(orderRejectFinalCmd.getCreatedBy());
auditDO.setAuditByName(orderRejectFinalCmd.getCreatedByName());
auditMapper.updateById(auditDO);
// 6. 发送审批驳回消息
sendAuditNotification(MessageTemplateSceneEnum.APPROVE_REJECT, auditDO, orderRejectFinalCmd.getCreatedBy(), orderRejectFinalCmd.getCreatedByName());
return auditConvert.toAudit(auditDO);
}
/**
* 审核员审核通过
* 1录入员提交的审核审核员审核通过
* 2老板驳回审核审核员重新提交审核
*/
@Override
public Audit approve(OrderApproveCmd orderApproveCmd) {
// 1. 验证审核记录ID
Long auditId = orderApproveCmd.getAuditId();
if (Objects.isNull(auditId)) {
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 2. 查询审核记录
AuditDO auditDO = auditMapper.selectById(auditId);
if (Objects.isNull(auditDO)) {
throw new BizException(BizErrorCode.B_BIZ_AUDIT_NOT_FOUND);
}
// 3. 验证审核记录状态是否为待审核
if (!auditDO.getState().equals(AuditStateEnum.WAITING_AUDIT)) {
throw new BizException(BizErrorCode.B_BIZ_ORDER_NOT_WAITING_AUDIT);
}
// 4. 根据审核类型执行不同逻辑
// 录入员的记录审核员审核
if (auditDO.getType().equals(AuditTypeEnum.REVIEWER_AUDIT)) {
if (orderApproveCmd.getDraft()) {
return auditConvert.toAudit(auditDO);
}
auditDO.setState(AuditStateEnum.AUDIT_SUCCESS);
auditDO.setAuditAt(LocalDateTime.now());
auditDO.setAuditBy(orderApproveCmd.getCreatedBy());
auditDO.setAuditByName(orderApproveCmd.getCreatedByName());
auditMapper.updateById(auditDO);
// 自动生成报老板待审核记录 // 自动生成报老板待审核记录
auditDO1 = new AuditDO(); AuditDO auditDO1 = new AuditDO();
auditDO1.setSubjectId(orderApproveCmd.getOrderId()); auditDO1.setSubjectId(orderApproveCmd.getOrderId());
auditDO1.setSubjectType(AuditSubjectTypeEnum.PURCHASE_ORDER); auditDO1.setSubjectType(AuditSubjectTypeEnum.PURCHASE_ORDER);
auditDO1.setType(AuditTypeEnum.BOSS_AUDIT); auditDO1.setType(AuditTypeEnum.BOSS_AUDIT);
@ -294,14 +348,24 @@ public class AuditGatewayImpl implements AuditGateway {
auditDO1.setCreatedBy(orderApproveCmd.getCreatedBy()); auditDO1.setCreatedBy(orderApproveCmd.getCreatedBy());
auditDO1.setCreatedByName(orderApproveCmd.getCreatedByName()); auditDO1.setCreatedByName(orderApproveCmd.getCreatedByName());
auditMapper.insert(auditDO1); auditMapper.insert(auditDO1);
// 发送待审批消息
sendAuditNotification(MessageTemplateSceneEnum.WAIT_APPROVE, auditDO,
orderApproveCmd.getCreatedBy(), orderApproveCmd.getCreatedByName());
return auditConvert.toAudit(auditDO1);
} }
// 发送待审批消息 // 审核员被驳回后的审核
sendAuditNotification(MessageTemplateSceneEnum.WAIT_APPROVE, auditDO, auditDO.getAuditId(), if (auditDO.getType().equals(AuditTypeEnum.BOSS_AUDIT)) {
orderApproveCmd.getCreatedBy(), orderApproveCmd.getCreatedByName()); auditDO.setState(AuditStateEnum.WAITING_AUDIT);
auditMapper.updateById(auditDO);
return auditConvert.toAudit(auditDO1); // 发送待审批消息
sendAuditNotification(MessageTemplateSceneEnum.WAIT_APPROVE, auditDO, orderApproveCmd.getCreatedBy(), orderApproveCmd.getCreatedByName());
return auditConvert.toAudit(auditDO);
}
return null;
} }
/** /**
@ -309,12 +373,11 @@ public class AuditGatewayImpl implements AuditGateway {
* *
* @param sceneEnum 消息场景枚举 * @param sceneEnum 消息场景枚举
* @param auditDO 审核记录 * @param auditDO 审核记录
* @param subjectId 关联主体ID订单ID等
* @param createdBy 操作人ID * @param createdBy 操作人ID
* @param createdByName 操作人名称 * @param createdByName 操作人名称
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
private void sendAuditNotification(MessageTemplateSceneEnum sceneEnum, AuditDO auditDO, Long subjectId, Long createdBy, String createdByName) { private void sendAuditNotification(MessageTemplateSceneEnum sceneEnum, AuditDO auditDO, Long createdBy, String createdByName) {
// 1. 查询启用的消息模板 // 1. 查询启用的消息模板
LambdaQueryWrapper<MessageTemplateDO> templateWrapper = Wrappers.lambdaQuery(MessageTemplateDO.class); LambdaQueryWrapper<MessageTemplateDO> templateWrapper = Wrappers.lambdaQuery(MessageTemplateDO.class);
templateWrapper.eq(MessageTemplateDO::getTemplateCategory, MessageTemplateCategoryEnum.PURCHASE_ORDER_MESSAGE_TEMPLATE); templateWrapper.eq(MessageTemplateDO::getTemplateCategory, MessageTemplateCategoryEnum.PURCHASE_ORDER_MESSAGE_TEMPLATE);
@ -335,7 +398,7 @@ public class AuditGatewayImpl implements AuditGateway {
} }
// 2. 查询订单信息用于变量替换 // 2. 查询订单信息用于变量替换
OrderDO orderDO = orderMapper.selectByOrderId(subjectId); OrderDO orderDO = orderMapper.selectByOrderId(auditDO.getSubjectId());
// 3. 构建变量替换映射 // 3. 构建变量替换映射
Map<String, String> variables = buildTemplateVariables(orderDO, auditDO, createdByName, sceneEnum); Map<String, String> variables = buildTemplateVariables(orderDO, auditDO, createdByName, sceneEnum);
@ -352,7 +415,7 @@ public class AuditGatewayImpl implements AuditGateway {
message.setCreatedBy(createdBy); message.setCreatedBy(createdBy);
message.setCreatedByName(createdByName); message.setCreatedByName(createdByName);
message.setState(MessageStateEnum.SENT); message.setState(MessageStateEnum.SENT);
message.setSubjectId(subjectId); message.setSubjectId(auditDO.getSubjectId());
message.setSubjectType(MessageSubjectTypeEnum.AUDIT); message.setSubjectType(MessageSubjectTypeEnum.AUDIT);
message.setSentAt(LocalDateTime.now()); message.setSentAt(LocalDateTime.now());
messageMapper.insert(message); messageMapper.insert(message);
@ -361,21 +424,28 @@ public class AuditGatewayImpl implements AuditGateway {
UserListQry userListQry = new UserListQry(); UserListQry userListQry = new UserListQry();
userListQry.setRoleIdList(template.getRoleIds()); userListQry.setRoleIdList(template.getRoleIds());
List<UserVO> userVOList = userService.list(userListQry); List<UserVO> userVOList = userService.list(userListQry);
List<Long> userIdList = userVOList.stream().map(UserVO::getUserId).toList();
if (CollUtil.isEmpty(userIdList)) { if (CollUtil.isEmpty(userVOList)) {
return; return;
} }
// 7. 根据消息场景过滤接收人
List<Long> targetUserIdList = filterTargetUsers(sceneEnum, userVOList, orderDO, createdBy);
if (CollUtil.isEmpty(targetUserIdList)) {
return;
}
// 8. 查询对应的 Admin 记录
AdminListQry adminListQry = new AdminListQry(); AdminListQry adminListQry = new AdminListQry();
adminListQry.setUserIdList(userIdList); adminListQry.setUserIdList(targetUserIdList);
List<AdminVO> adminVOList = adminService.list(adminListQry); List<AdminVO> adminVOList = adminService.list(adminListQry);
if (CollUtil.isEmpty(adminVOList)) { if (CollUtil.isEmpty(adminVOList)) {
return; return;
} }
// 7. 批量创建消息接收记录 // 9. 批量创建消息接收记录
List<MessageReceiverDO> receiverList = new ArrayList<>(); List<MessageReceiverDO> receiverList = new ArrayList<>();
for (AdminVO adminVO : adminVOList) { for (AdminVO adminVO : adminVOList) {
MessageReceiverDO receiver = new MessageReceiverDO(); MessageReceiverDO receiver = new MessageReceiverDO();
@ -391,6 +461,37 @@ public class AuditGatewayImpl implements AuditGateway {
} }
} }
/**
* 根据消息场景过滤目标用户
*
* @param sceneEnum 消息场景
* @param userVOList 所有拥有对应角色的用户列表
* @param orderDO 订单信息
* @param currentUserId 当前操作人ID
* @return 目标用户ID列表
*/
private List<Long> filterTargetUsers(MessageTemplateSceneEnum sceneEnum, List<UserVO> userVOList, OrderDO orderDO, Long currentUserId) {
// 驳回场景只发给订单创建人且拥有对应角色的人
if (sceneEnum.equals(MessageTemplateSceneEnum.AUDIT_REJECT) ||
sceneEnum.equals(MessageTemplateSceneEnum.APPROVE_REJECT)) {
if (Objects.isNull(orderDO) || Objects.isNull(orderDO.getCreatedBy())) {
return List.of();
}
final Long orderCreatedBy = orderDO.getCreatedBy();
return userVOList.stream()
.filter(user -> user.getUserId().equals(orderCreatedBy))
.map(UserVO::getUserId)
.toList();
}
// 其他场景发给所有拥有对应角色的用户
return userVOList.stream()
.map(UserVO::getUserId)
.toList();
}
/** /**
* 构建模板变量映射 * 构建模板变量映射
* *

View File

@ -147,12 +147,15 @@ public class OrderShipGatewayImpl implements OrderShipGateway {
OrderShipDO orderShipDO = orderShipMapper.selectOne(queryWrapper); OrderShipDO orderShipDO = orderShipMapper.selectOne(queryWrapper);
// 更新订单明细 List<OrderShipItem> orderShipItemList = orderShipGenerateDocumentCmd.getOrderShipItemList();
for (OrderShipItem orderShipItem : orderShipGenerateDocumentCmd.getOrderShipItemList()) { if (CollUtil.isNotEmpty(orderShipItemList)) {
LambdaUpdateWrapper<OrderShipItemDO> updateWrapper = Wrappers.lambdaUpdate(OrderShipItemDO.class); // 更新订单明细
updateWrapper.eq(OrderShipItemDO::getOrderShipId, orderShipDO.getOrderShipId()); for (OrderShipItem orderShipItem : orderShipItemList) {
updateWrapper.set(OrderShipItemDO::getWatermelonGrade, orderShipItem.getWatermelonGrade()); LambdaUpdateWrapper<OrderShipItemDO> updateWrapper = Wrappers.lambdaUpdate(OrderShipItemDO.class);
orderShipItemMapper.update(null, updateWrapper); updateWrapper.eq(OrderShipItemDO::getOrderShipId, orderShipDO.getOrderShipId());
updateWrapper.set(OrderShipItemDO::getWatermelonGrade, orderShipItem.getWatermelonGrade());
orderShipItemMapper.update(null, updateWrapper);
}
} }
orderShipConvert.toOrderShipDO(orderShipDO, orderShipGenerateDocumentCmd); orderShipConvert.toOrderShipDO(orderShipDO, orderShipGenerateDocumentCmd);

View File

@ -1,13 +1,19 @@
package com.xunhong.erp.turbo.biz.infrastructure.mapper; package com.xunhong.erp.turbo.biz.infrastructure.mapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.xunhong.erp.turbo.api.biz.dto.qry.AuditPageQry;
import com.xunhong.erp.turbo.biz.infrastructure.entity.AuditDO; import com.xunhong.erp.turbo.biz.infrastructure.entity.AuditDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/** /**
* @author shenyifei * @author shenyifei
*/ */
@Mapper @Mapper
public interface AuditMapper extends BaseMapper<AuditDO> { public interface AuditMapper extends BaseMapper<AuditDO> {
IPage<AuditDO> selectPage(IPage<AuditDO> page, @Param(Constants.WRAPPER) LambdaQueryWrapper<AuditDO> queryWrapper, @Param("query") AuditPageQry auditPageQry);
} }

View File

@ -9,10 +9,10 @@
<result property="subjectType" column="subject_type"/> <result property="subjectType" column="subject_type"/>
<result property="state" column="state"/> <result property="state" column="state"/>
<result property="type" column="type"/> <result property="type" column="type"/>
<result property="auditReason" column="reject_reason"/> <result property="auditReason" column="audit_reason"/>
<result property="auditAt" column="audit_at"/> <result property="auditAt" column="audit_at"/>
<result property="auditId" column="reject_by"/> <result property="auditId" column="reject_by"/>
<result property="auditByName" column="reject_by_name"/> <result property="auditByName" column="audit_by_name"/>
<result property="createdBy" column="created_by"/> <result property="createdBy" column="created_by"/>
<result property="createdByName" column="created_by_name"/> <result property="createdByName" column="created_by_name"/>
<result property="createdAt" column="created_at"/> <result property="createdAt" column="created_at"/>
@ -20,5 +20,45 @@
<result property="isDelete" column="is_delete"/> <result property="isDelete" column="is_delete"/>
<result property="version" column="version"/> <result property="version" column="version"/>
</resultMap> </resultMap>
<select id="selectPage"
resultType="com.xunhong.erp.turbo.biz.infrastructure.entity.AuditDO"
resultMap="BaseResultMap">
SELECT
a.*
FROM audit a
<if test="query.orderSn != null">
LEFT JOIN `order` po ON po.order_id = a.subject_id AND
a.subject_type = 1 AND po.is_delete = 0
</if>
<if test="query.vehicleNo != null or query.plate != null">
LEFT JOIN order_vehicle ov ON ov.order_id = a.subject_id AND
a.subject_type = 1 AND ov.is_delete = 0
</if>
<where>
AND a.is_delete = 0
<if test="query.orderSn != null">
AND po.order_sn like CONCAT('%',#{query.orderSn},'%')
</if>
<if test="query.vehicleNo != null">
AND ov.vehicle_no like CONCAT('%',#{query.vehicleNo},'%')
</if>
<if test="query.plate != null">
AND ov.plate like CONCAT('%',#{query.plate},'%')
</if>
<if test="query.state != null">
AND a.state = #{query.state}
</if>
<if test="query.type != null">
AND a.type = #{query.type}
</if>
<if test="ew != null">
<if test="ew.nonEmptyOfWhere">
AND
</if>
${ew.sqlSegment}
</if>
</where>
</select>
</mapper> </mapper>

View File

@ -30,7 +30,7 @@
<result property="dealerName" column="dealer_name"/> <result property="dealerName" column="dealer_name"/>
<result property="origin" column="origin"/> <result property="origin" column="origin"/>
<result property="destination" column="destination"/> <result property="destination" column="destination"/>
<result property="deliveryTime" column="deliveryTime"/> <result property="deliveryTime" column="delivery_time"/>
</association> </association>
</resultMap> </resultMap>
@ -49,6 +49,7 @@
<result property="dealerName" column="dealer_name"/> <result property="dealerName" column="dealer_name"/>
<result property="origin" column="origin"/> <result property="origin" column="origin"/>
<result property="destination" column="destination"/> <result property="destination" column="destination"/>
<result property="deliveryTime" column="delivery_time"/>
</association> </association>
</resultMap> </resultMap>
@ -57,7 +58,7 @@
resultMap="SelectByOrderIdListResultMap"> resultMap="SelectByOrderIdListResultMap">
SELECT SELECT
po.order_id, po.order_sn, po.state, po.audit_state, po.type, po.order_id, po.order_sn, po.state, po.audit_state, po.type,
ov.vehicle_id, ov.vehicle_no, ov.dealer_id, ov.dealer_name, ov.origin, ov.vehicle_id, ov.vehicle_no, ov.dealer_id, ov.dealer_name, ov.origin, ov.delivery_time,
ov.destination ov.destination
FROM `order` po FROM `order` po
LEFT JOIN order_vehicle ov ON po.order_id = ov.order_id AND ov.is_delete LEFT JOIN order_vehicle ov ON po.order_id = ov.order_id AND ov.is_delete
@ -79,7 +80,7 @@
resultMap="BaseResultMap"> resultMap="BaseResultMap">
SELECT SELECT
po.*, po.*,
ov.vehicle_id, ov.vehicle_no, ov.dealer_id, ov.dealer_name, ov.origin, ov.vehicle_id, ov.vehicle_no, ov.dealer_id, ov.dealer_name, ov.origin, ov.delivery_time,
ov.destination ov.destination
FROM `order` po FROM `order` po
LEFT JOIN order_vehicle ov ON po.order_id = ov.order_id AND ov.is_delete LEFT JOIN order_vehicle ov ON po.order_id = ov.order_id AND ov.is_delete
@ -89,6 +90,12 @@
<if test="query.vehicleNo != null"> <if test="query.vehicleNo != null">
AND ov.vehicle_no LIKE CONCAT('%',#{query.vehicleNo},'%') AND ov.vehicle_no LIKE CONCAT('%',#{query.vehicleNo},'%')
</if> </if>
<if test="query.orderSn != null">
AND po.order_sn LIKE CONCAT('%',#{query.orderSn},'%')
</if>
<if test="query.plate != null">
AND ov.plate LIKE CONCAT('%',#{query.plate},'%')
</if>
<if test="query.dealerId != null"> <if test="query.dealerId != null">
AND ov.dealer_id = #{query.dealerId} AND ov.dealer_id = #{query.dealerId}
</if> </if>
@ -120,7 +127,7 @@
resultMap="SelectByOrderIdListResultMap"> resultMap="SelectByOrderIdListResultMap">
SELECT SELECT
po.order_id, po.order_sn, po.state, po.audit_state, po.type, po.order_id, po.order_sn, po.state, po.audit_state, po.type,
ov.vehicle_id, ov.vehicle_no, ov.dealer_id, ov.dealer_name, ov.origin, ov.vehicle_id, ov.vehicle_no, ov.dealer_id, ov.dealer_name, ov.origin, ov.delivery_time,
ov.destination ov.destination
FROM `order` po FROM `order` po
LEFT JOIN order_vehicle ov ON po.order_id = ov.order_id AND ov.is_delete LEFT JOIN order_vehicle ov ON po.order_id = ov.order_id AND ov.is_delete
@ -134,7 +141,7 @@
resultMap="BaseResultMap"> resultMap="BaseResultMap">
SELECT SELECT
po.*, po.*,
ov.vehicle_id, ov.vehicle_no, ov.dealer_id, ov.dealer_name, ov.origin, ov.vehicle_id, ov.vehicle_no, ov.dealer_id, ov.dealer_name, ov.origin, ov.delivery_time,
ov.destination, ov.delivery_time ov.destination, ov.delivery_time
FROM `order` po FROM `order` po
LEFT JOIN order_vehicle ov ON po.order_id = ov.order_id AND ov.is_delete LEFT JOIN order_vehicle ov ON po.order_id = ov.order_id AND ov.is_delete
@ -160,7 +167,7 @@
resultType="com.xunhong.erp.turbo.biz.infrastructure.entity.OrderDO"> resultType="com.xunhong.erp.turbo.biz.infrastructure.entity.OrderDO">
SELECT SELECT
po.*, po.*,
ov.vehicle_id, ov.vehicle_no, ov.dealer_id, ov.dealer_name, ov.origin, ov.vehicle_id, ov.vehicle_no, ov.dealer_id, ov.dealer_name, ov.origin, ov.delivery_time,
ov.destination ov.destination
FROM `order` po FROM `order` po
LEFT JOIN order_vehicle ov ON po.order_id = ov.order_id AND ov.is_delete LEFT JOIN order_vehicle ov ON po.order_id = ov.order_id AND ov.is_delete

View File

@ -27,5 +27,14 @@ public class AuditPageQry extends PageQuery {
@Schema(title = "审核对象类型1_采购单") @Schema(title = "审核对象类型1_采购单")
private AuditSubjectTypeEnum subjectType; private AuditSubjectTypeEnum subjectType;
@Schema(title = "订单编号")
private String orderSn;
@Schema(title = "车辆编号")
private String vehicleNo;
@Schema(title = "车牌")
private String plate;
} }

View File

@ -25,6 +25,9 @@ public class OrderPageQry extends PageQuery {
@Schema(title = "采购订单编号", type = "string") @Schema(title = "采购订单编号", type = "string")
private String orderSn; private String orderSn;
@Schema(title = "车牌号", type = "string")
private String plate;
/** /**
* 采购订单状态: 0_草稿1_审核中2_已完成3_已关闭 * 采购订单状态: 0_草稿1_审核中2_已完成3_已关闭
*/ */