CrmQuoteApprovalServiceImpl.java 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. package org.dromara.crm.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  4. import lombok.RequiredArgsConstructor;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.dromara.common.core.exception.ServiceException;
  7. import org.dromara.crm.domain.CrmQuote;
  8. import org.dromara.crm.domain.CrmQuoteApproval;
  9. import org.dromara.crm.domain.vo.CrmQuoteApprovalVo;
  10. import org.dromara.crm.mapper.CrmQuoteApprovalMapper;
  11. import org.dromara.crm.mapper.CrmQuoteMapper;
  12. import org.dromara.crm.service.ICrmQuoteApprovalService;
  13. import org.springframework.stereotype.Service;
  14. import org.springframework.transaction.annotation.Transactional;
  15. import java.time.LocalDateTime;
  16. import java.util.List;
  17. /**
  18. * 报价单审批Service实现
  19. *
  20. * @author 系统管理员
  21. * @date 2025-01-03
  22. */
  23. @Slf4j
  24. @RequiredArgsConstructor
  25. @Service
  26. public class CrmQuoteApprovalServiceImpl implements ICrmQuoteApprovalService {
  27. private final CrmQuoteApprovalMapper baseMapper;
  28. private final CrmQuoteMapper quoteMapper;
  29. @Override
  30. public List<CrmQuoteApprovalVo> queryListByQuoteId(Long quoteId) {
  31. // 使用关联查询获取用户昵称
  32. return baseMapper.selectVoListWithUserInfo(quoteId);
  33. }
  34. @Override
  35. @Transactional(rollbackFor = Exception.class)
  36. public Boolean approveQuote(Long id, String approvalResult, String approvalOpinion, String remark) {
  37. CrmQuoteApproval entity = baseMapper.selectById(id);
  38. if (entity == null) {
  39. throw new ServiceException("审批记录不存在");
  40. }
  41. if (!"pending".equals(entity.getApprovalResult())) {
  42. throw new ServiceException("该审批已处理");
  43. }
  44. // 更新审批记录
  45. entity.setApprovalResult(approvalResult);
  46. entity.setApprovalOpinion(approvalOpinion);
  47. entity.setApprovalTime(LocalDateTime.now());
  48. entity.setRemark(remark);
  49. baseMapper.updateById(entity);
  50. // 更新报价单状态
  51. CrmQuote quote = quoteMapper.selectById(entity.getQuoteId());
  52. if (quote != null) {
  53. if ("approved".equals(approvalResult)) {
  54. // 检查是否所有审批都通过
  55. LambdaQueryWrapper<CrmQuoteApproval> lqw = Wrappers.lambdaQuery();
  56. lqw.eq(CrmQuoteApproval::getQuoteId, entity.getQuoteId());
  57. lqw.eq(CrmQuoteApproval::getApprovalResult, "pending");
  58. long pendingCount = baseMapper.selectCount(lqw);
  59. if (pendingCount == 0) {
  60. // 所有审批都通过,报价单状态变更为已接受
  61. quote.setStatus("accepted");
  62. quoteMapper.updateById(quote);
  63. }
  64. } else if ("rejected".equals(approvalResult)) {
  65. // 任一审批拒绝,报价单状态变更为已拒绝
  66. quote.setStatus("rejected");
  67. quote.setRejectReason("审批拒绝: " + approvalOpinion);
  68. quoteMapper.updateById(quote);
  69. }
  70. }
  71. return true;
  72. }
  73. @Override
  74. @Transactional(rollbackFor = Exception.class)
  75. public Boolean withdrawApproval(Long quoteId, String remark) {
  76. CrmQuote quote = quoteMapper.selectById(quoteId);
  77. if (quote == null) {
  78. throw new ServiceException("报价单不存在");
  79. }
  80. if (!"submitted".equals(quote.getStatus())) {
  81. throw new ServiceException("只能撤回已提交的报价单");
  82. }
  83. // 删除所有待审批的记录
  84. LambdaQueryWrapper<CrmQuoteApproval> lqw = Wrappers.lambdaQuery();
  85. lqw.eq(CrmQuoteApproval::getQuoteId, quoteId);
  86. lqw.eq(CrmQuoteApproval::getApprovalResult, "pending");
  87. baseMapper.delete(lqw);
  88. // 报价单状态改为草稿
  89. quote.setStatus("draft");
  90. quote.setRemark(remark);
  91. quoteMapper.updateById(quote);
  92. return true;
  93. }
  94. @Override
  95. @Transactional(rollbackFor = Exception.class)
  96. public Boolean createApprovalRecords(Long quoteId, List<Long> approverIds) {
  97. CrmQuote quote = quoteMapper.selectById(quoteId);
  98. if (quote == null) {
  99. throw new ServiceException("报价单不存在");
  100. }
  101. int step = 1;
  102. for (Long approverId : approverIds) {
  103. CrmQuoteApproval approval = new CrmQuoteApproval();
  104. approval.setQuoteId(quoteId);
  105. approval.setQuoteNo(quote.getQuoteNo());
  106. approval.setStep(step++);
  107. approval.setApproverId(approverId);
  108. // 查询审批人昵称
  109. String nickName = baseMapper.selectNickNameByUserId(approverId);
  110. if (nickName != null) {
  111. approval.setApproverName(nickName);
  112. } else {
  113. // 如果查询不到用户,使用默认格式
  114. approval.setApproverName("用户" + approverId);
  115. log.warn("未找到用户昵称, userId: {}", approverId);
  116. }
  117. approval.setApprovalResult("pending");
  118. baseMapper.insert(approval);
  119. }
  120. return true;
  121. }
  122. @Override
  123. public Boolean deletePendingApprovals(Long quoteId) {
  124. LambdaQueryWrapper<CrmQuoteApproval> lqw = Wrappers.lambdaQuery();
  125. lqw.eq(CrmQuoteApproval::getQuoteId, quoteId);
  126. lqw.eq(CrmQuoteApproval::getApprovalResult, "pending");
  127. int count = baseMapper.delete(lqw);
  128. log.info("删除待审批记录: quoteId={}, count={}", quoteId, count);
  129. return count >= 0;
  130. }
  131. @Override
  132. @Transactional(rollbackFor = Exception.class)
  133. public Integer refreshApproverNames(Long quoteId) {
  134. // 构建查询条件
  135. LambdaQueryWrapper<CrmQuoteApproval> lqw = Wrappers.lambdaQuery();
  136. if (quoteId != null) {
  137. lqw.eq(CrmQuoteApproval::getQuoteId, quoteId);
  138. }
  139. // 只更新"审批人xxx"或"用户xxx"格式的记录
  140. lqw.and(wrapper -> wrapper
  141. .likeRight(CrmQuoteApproval::getApproverName, "审批人")
  142. .or()
  143. .likeRight(CrmQuoteApproval::getApproverName, "用户"));
  144. // 查询需要更新的记录
  145. List<CrmQuoteApproval> approvalList = baseMapper.selectList(lqw);
  146. if (approvalList.isEmpty()) {
  147. log.info("没有需要刷新的审批记录");
  148. return 0;
  149. }
  150. int updateCount = 0;
  151. for (CrmQuoteApproval approval : approvalList) {
  152. // 查询用户昵称
  153. String nickName = baseMapper.selectNickNameByUserId(approval.getApproverId());
  154. if (nickName != null && !nickName.equals(approval.getApproverName())) {
  155. approval.setApproverName(nickName);
  156. baseMapper.updateById(approval);
  157. updateCount++;
  158. log.info("刷新审批人姓名成功: id={}, approverId={}, newName={}",
  159. approval.getId(), approval.getApproverId(), nickName);
  160. } else {
  161. log.warn("未找到用户昵称或姓名相同: approvalId={}, approverId={}",
  162. approval.getId(), approval.getApproverId());
  163. }
  164. }
  165. log.info("刷新审批人姓名完成: quoteId={}, 总数={}, 成功={}", quoteId, approvalList.size(), updateCount);
  166. return updateCount;
  167. }
  168. @Override
  169. public Boolean canUserApprove(Long quoteId, Long userId) {
  170. if (quoteId == null || userId == null) {
  171. return false;
  172. }
  173. // 查询该报价单的所有审批记录(按步骤升序)
  174. LambdaQueryWrapper<CrmQuoteApproval> lqw = Wrappers.lambdaQuery();
  175. lqw.eq(CrmQuoteApproval::getQuoteId, quoteId);
  176. lqw.orderByAsc(CrmQuoteApproval::getStep);
  177. List<CrmQuoteApproval> approvalList = baseMapper.selectList(lqw);
  178. if (approvalList.isEmpty()) {
  179. return false;
  180. }
  181. // 查找当前用户的审批记录
  182. CrmQuoteApproval userApproval = null;
  183. for (CrmQuoteApproval approval : approvalList) {
  184. if (userId.equals(approval.getApproverId())) {
  185. userApproval = approval;
  186. break;
  187. }
  188. }
  189. // 如果用户不是审批人
  190. if (userApproval == null) {
  191. return false;
  192. }
  193. // 如果用户的审批记录不是待审批状态
  194. if (!"pending".equals(userApproval.getApprovalResult())) {
  195. return false;
  196. }
  197. // 关键:检查所有前置步骤是否都已完成
  198. for (CrmQuoteApproval approval : approvalList) {
  199. // 如果是用户自己的步骤,跳过
  200. if (approval.getStep().equals(userApproval.getStep())) {
  201. break;
  202. }
  203. // 如果前置步骤不是已通过状态,则不能审批
  204. if (!"approved".equals(approval.getApprovalResult())) {
  205. return false;
  206. }
  207. }
  208. return true;
  209. }
  210. }