From 1cdccaf0a06161fcc2a5797e617508c8a7e1f300 Mon Sep 17 00:00:00 2001 From: p-honggang.li <p-honggang.li@pcitc.com> Date: 星期六, 06 九月 2025 03:14:53 +0800 Subject: [PATCH] 修改订单创建,发起工作流调用,采用后端处理,增加事务,修改审核同通过和驳回处理,修改根据用户id获取工作流代办信息,再根据代办ids查询订单信息 --- src/main/java/com/webmanage/service/impl/OrderInfoServiceImpl.java | 414 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 408 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/webmanage/service/impl/OrderInfoServiceImpl.java b/src/main/java/com/webmanage/service/impl/OrderInfoServiceImpl.java index 456e8a3..7655559 100644 --- a/src/main/java/com/webmanage/service/impl/OrderInfoServiceImpl.java +++ b/src/main/java/com/webmanage/service/impl/OrderInfoServiceImpl.java @@ -26,23 +26,35 @@ import com.webmanage.service.OrderInfoService; import com.webmanage.service.OrderNoService; import com.webmanage.service.MinioService; +import com.webmanage.config.WorkflowProperties; import com.webmanage.vo.OrderAttachmentVO; import com.webmanage.vo.OrderDetailItemVO; import com.webmanage.vo.OrderDetailVO; import com.webmanage.vo.OrderEvaluationVO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; +import org.springframework.web.client.RestTemplate; +import org.springframework.http.ResponseEntity; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpEntity; +import org.springframework.http.MediaType; +import org.springframework.http.HttpHeaders; import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.stream.Collectors; +import java.util.Objects; /** * 璁㈠崟淇℃伅Service瀹炵幇绫� @@ -71,6 +83,12 @@ @Resource private ReportResultSubmissionMapper reportResultSubmissionMapper; + + @Autowired + private RestTemplate restTemplate; + + @Autowired + private WorkflowProperties workflowProperties; @Override public PageResult<OrderDetailVO> getBuyerOrderPage(OrderQueryDTO queryDTO) { @@ -167,13 +185,34 @@ // 鍒涘缓鍒嗛〉瀵硅薄 Page<OrderInfo> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()); + // 鍩轰簬workFlowType鏌ヨ娴佺▼瀹炰緥ID闆嗗悎 + List<String> workFlowIds = fetchWorkflowProcessInstanceIds( + queryDTO.getWorkFlowType(), + queryDTO.getUserId(), + queryDTO.getDepartmentId(), + queryDTO.getBusinessType(), + queryDTO.getPageNum(), + queryDTO.getPageSize() + ); + + // 濡傛灉娌℃湁浠讳綍娴佺▼ID锛岀洿鎺ヨ繑鍥炵┖鍒嗛〉 + if (workFlowIds == null || workFlowIds.isEmpty()) { + return new PageResult<OrderDetailVO>( + java.util.Collections.emptyList(), + 0L, + queryDTO.getPageNum().longValue(), + queryDTO.getPageSize().longValue(), + 0L + ); + } + // 鎵ц鍒嗛〉鏌ヨ IPage<OrderInfo> result = baseMapper.selectPendingApprovalOrderPage( page, queryDTO.getOrderStatus(), queryDTO.getProductName(), queryDTO.getProviderName(), queryDTO.getOrderId(), queryDTO.getApplyTimeStart() != null ? queryDTO.getApplyTimeStart().toString() : null, queryDTO.getApplyTimeEnd() != null ? queryDTO.getApplyTimeEnd().toString() : null, - queryDTO.getOrderBy(), queryDTO.getOrderDirection() + queryDTO.getOrderBy(), queryDTO.getOrderDirection(), workFlowIds ); // 灏嗚鍗曚笌璇︽儏鑱旇〃灏佽鍒癡O @@ -227,12 +266,33 @@ Page<OrderInfo> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()); // 鎵ц鍒嗛〉鏌ヨ + // 鍩轰簬workFlowType鏌ヨ娴佺▼瀹炰緥ID闆嗗悎 + List<String> workFlowIds = fetchWorkflowProcessInstanceIds( + queryDTO.getWorkFlowType(), + queryDTO.getUserId(), + queryDTO.getDepartmentId(), + queryDTO.getBusinessType(), + queryDTO.getPageNum(), + queryDTO.getPageSize() + ); + + // 濡傛灉娌℃湁浠讳綍娴佺▼ID锛岀洿鎺ヨ繑鍥炵┖鍒嗛〉 + if (workFlowIds == null || workFlowIds.isEmpty()) { + return new PageResult<OrderInfo>( + java.util.Collections.emptyList(), + 0L, + queryDTO.getPageNum().longValue(), + queryDTO.getPageSize().longValue(), + 0L + ); + } + IPage<OrderInfo> result = baseMapper.selectPendingApprovalOrderPageWithProductConditions( page, queryDTO.getOrderStatus(), queryDTO.getProductName(), queryDTO.getProviderName(), queryDTO.getOrderId(), queryDTO.getApplyTimeStart() != null ? queryDTO.getApplyTimeStart().toString() : null, queryDTO.getApplyTimeEnd() != null ? queryDTO.getApplyTimeEnd().toString() : null, - queryDTO.getOrderBy(), queryDTO.getOrderDirection(), productIds + queryDTO.getOrderBy(), queryDTO.getOrderDirection(), productIds, workFlowIds ); // 鏋勫缓杩斿洖缁撴灉 @@ -432,6 +492,34 @@ } // 鐢熸垚璁㈠崟缂栧彿 String orderId = orderNoService.generateOrderNo(); + + // 鍏堣皟鐢ㄥ伐浣滄祦鎺ュ彛锛岃幏鍙栧伐浣滄祦ID + String workflowId = null; + String taskId = null; + try { + // 妫�鏌ユ槸鍚︽湁浠锋牸绫诲瀷涓�"鍗忚"鐨勬槑缁嗛」 + boolean hasAgreementPrice = createOrderDTO.getItems().stream() + .anyMatch(item -> "鍗忚".equals(item.getPriceType())); + + // 鏍规嵁鏄惁鍖呭惈鍗忚纭畾type鍊� + String type = hasAgreementPrice ? "trade_agreement" : "trade_point"; + + // 璋冪敤鑾峰彇娴佺▼妯℃澘ID鐨勬帴鍙� + // String processTemplateId = getProcessTemplateId(type); + + if (createOrderDTO.getProcessdefId() != null) { + // 璋冪敤鍙戣捣宸ヤ綔娴佺殑鎺ュ彛 + Map<String,Object> resMap = startWorkflowProcess(createOrderDTO.getProcessdefId(), createOrderDTO.getUserId(), type); + workflowId = resMap.get("processinstId").toString(); + taskId = resMap.get("taskId").toString(); + } else { + throw new BusinessException("娴佺▼瀹氫箟Id涓虹┖!"); + } + } catch (Exception e) { + log.error("璋冪敤宸ヤ綔娴佹帴鍙eけ璐ワ紝璁㈠崟ID: {}", orderId, e); + // 宸ヤ綔娴佽皟鐢ㄥけ璐ワ紝鎶涘嚭寮傚父瑙﹀彂浜嬪姟鍥炴粴 + throw new BusinessException("宸ヤ綔娴佽皟鐢ㄥけ璐�: " + e.getMessage()); + } // 璁$畻鎬婚噾棰� BigDecimal totalAmount = BigDecimal.ZERO; @@ -464,6 +552,9 @@ orderInfo.setPaymentType(createOrderDTO.getPaymentType()); orderInfo.setPaymentStatus("鏈敮浠�"); orderInfo.setBuyerRemarks(createOrderDTO.getBuyerRemarks()); + orderInfo.setIsEvaluate("鏈瘎浠�"); + orderInfo.setWorkflowId(workflowId); // 璁剧疆宸ヤ綔娴両D + orderInfo.setTaskId(taskId); orderInfo.setCreatedAt(LocalDateTime.now()); orderInfo.setUpdatedAt(LocalDateTime.now()); @@ -826,6 +917,58 @@ throw new BusinessException("鎻掑叆瀹℃壒璁板綍澶辫触"); } + // 鏇存柊浜ゆ槗淇℃伅澶囨敞锛堝彧鏇存柊remarks锛屼笉鏇存柊璁㈠崟鐘舵�侊級 + // 鍙洿鏂拌鍗曡鎯呭娉紝涓嶆洿鏂拌鍗曠姸鎬� + if(orderApprovalDTO.getOrderDetails() != null) { + for (UpdateOrderDetailDTO.UpdateOrderDetailItemDTO itemDTO : orderApprovalDTO.getOrderDetails()) { + if (itemDTO.getId() == null) { + continue; + } + + OrderDetail orderDetail = orderDetailMapper.selectById(itemDTO.getId()); + if (orderDetail == null) { + log.warn("璁㈠崟璇︽儏涓嶅瓨鍦紝ID: {}", itemDTO.getId()); + continue; + } + + // 鏇存柊澶囨敞 + orderDetail.setRemarks(itemDTO.getRemarks()); + orderDetail.setUpdatedAt(LocalDateTime.now()); + + int detailUpdated = orderDetailMapper.updateById(orderDetail); + if (detailUpdated <= 0) { + log.warn("鏇存柊璁㈠崟璇︽儏澶辫触锛孖D: {}", itemDTO.getId()); + } + } + } + + // 鏇存柊璁㈠崟鐘舵�侊紙閫氳繃 -> 涓嬩竴涓紱椹冲洖 -> 涓婁竴涓級 + String currentStatus = orderInfo.getOrderStatus(); + if (!StringUtils.hasText(currentStatus)) { + throw new BusinessException("璁㈠崟褰撳墠鐘舵�佷负绌�"); + } + boolean isReject = orderApprovalDTO.getApprovalResult().contains("椹冲洖"); + String targetStatus = isReject ? getPreviousOrderStatus(currentStatus) : getNextOrderStatus(currentStatus); + if (targetStatus == null) { + throw new BusinessException((isReject ? "宸叉槸鍒濆鐘舵�侊紝鏃犳硶鍥為��" : "宸叉槸鏈�缁堢姸鎬侊紝鏃犳硶缁х画娴佽浆")); + } + orderInfo.setOrderStatus(targetStatus); + orderInfo.setUpdatedAt(LocalDateTime.now()); + + int updated = this.baseMapper.updateById(orderInfo); + if (updated <= 0) { + throw new BusinessException("鏇存柊璁㈠崟鐘舵�佸け璐�"); + } + + log.info("璁㈠崟鐘舵�佹洿鏂版垚鍔燂紝璁㈠崟ID: {}, 浠� {} 鏇存柊涓� {}", orderInfo.getOrderId(), currentStatus, targetStatus); + // 鏍规嵁瀹℃壒缁撴灉璋冪敤鎻愪氦鎴栭┏鍥炴帴鍙� + String comment = orderApprovalDTO.getApprovalResult().contains("椹冲洖") ? "瀹℃牳椹冲洖" : "瀹℃牳閫氳繃"; + if ("瀹℃牳椹冲洖".equals(comment)) { + rejectWorkflowTask(orderInfo.getTaskId(), String.valueOf(orderApprovalDTO.getApproverId()), comment); + } else { + completeWorkflowTask(orderInfo.getTaskId(), String.valueOf(orderApprovalDTO.getApproverId()), comment); + } + log.info("瀹℃壒璁板綍娣诲姞鎴愬姛锛岃鍗旾D: {}, 瀹℃壒绫诲瀷: {}, 瀹℃壒缁撴灉: {}, 瀹℃壒浜�: {}, 瀹℃壒鎰忚: {}", orderApprovalDTO.getOrderId(), orderApprovalDTO.getApprovalType(), @@ -939,9 +1082,10 @@ private String getNextOrderStatus(String currentStatus) { switch (currentStatus) { case "寰呬笂浼犳枃浠�": - return "寰呮巿鏉�"; + return "寰呭鎵规巿鏉�"; + case "寰呭鎵规巿鏉�": case "寰呮巿鏉�": - return "寰呬氦鏄撶‘璁�"; + return "寰呬氦鏄撶‘璁�"; case "寰呬氦鏄撶‘璁�": return "宸插畬鎴�"; case "宸插畬鎴�": @@ -962,7 +1106,7 @@ switch (currentStatus) { case "寰呬笂浼犳枃浠�": return null; // 鍒濆鐘舵�� - case "寰呮巿鏉�": + case "寰呭鎵规巿鏉�": return "寰呬笂浼犳枃浠�"; case "寰呬氦鏄撶‘璁�": return "寰呮巿鏉�"; @@ -1196,7 +1340,265 @@ wrapper.eq("deleted", 0); // 瀹℃牳涓細鐘舵�佷笉涓� 宸插畬鎴� 鎴� 宸插彇娑� wrapper.notIn("order_status", Arrays.asList("宸插畬鎴�", "宸插彇娑�")); - Integer count = this.baseMapper.selectCount(wrapper); + Long count = this.baseMapper.selectCount(wrapper); return count != null && count > 0; } + + @Override + public boolean updateOrderIsEvaluate(String orderId) { + if (!StringUtils.hasText(orderId)) { + throw new BusinessException("璁㈠崟ID涓嶈兘涓虹┖"); + } + OrderInfo orderInfo = this.getById(orderId); + if (orderInfo == null) { + throw new BusinessException("璁㈠崟涓嶅瓨鍦�"); + } + orderInfo.setIsEvaluate("宸茶瘎浠�"); + return this.updateById(orderInfo); + } + + /** + * 鑾峰彇娴佺▼妯℃澘ID + * @param type 绫诲瀷鍙傛暟 + * @return 娴佺▼妯℃澘ID + */ + private String getProcessTemplateId(String type) { + try { + String url = workflowProperties.getApproval().getBaseUrl() + workflowProperties.getApproval().getTemplateRelationUrl(); + + // 鏋勫缓璇锋眰鍙傛暟 + Map<String, Object> params = new HashMap<>(); + params.put("type", type); + params.put("unitId", workflowProperties.getApproval().getUnitId()); + + // 鍙戦�丳OST璇锋眰 + ResponseEntity<Map<String, Object>> response = restTemplate.exchange( + url, + HttpMethod.POST, + new HttpEntity<>(params), + new ParameterizedTypeReference<Map<String, Object>>() {} + ); + + if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { + Map<String, Object> responseBody = response.getBody(); + return (String) responseBody.get("processTemplateId"); + } else { + log.warn("鑾峰彇娴佺▼妯℃澘ID澶辫触锛屽搷搴旂姸鎬�: {}", response.getStatusCode()); + return null; + } + } catch (Exception e) { + log.error("璋冪敤鑾峰彇娴佺▼妯℃澘ID鎺ュ彛澶辫触", e); + throw new BusinessException("鑾峰彇娴佺▼妯℃澘ID澶辫触: " + e.getMessage()); + } + } + + /** + * 鍚姩宸ヤ綔娴佹祦绋� + * @param processTemplateId 娴佺▼妯℃澘ID + * @param userId 鐢ㄦ埛ID + * @param businessKey 涓氬姟閿紙璁㈠崟ID锛� + * @return 娴佺▼瀹炰緥ID + */ + private Map<String,Object> startWorkflowProcess(String processTemplateId, String userId, String businessKey) { + try { + String url = workflowProperties.getProcess().getBaseUrl() + workflowProperties.getProcess().getStartProcessUrl(); + + // 鏋勫缓璇锋眰鍙傛暟 + Map<String, Object> params = new HashMap<>(); + params.put("processdefId", processTemplateId); + params.put("userid", userId); + params.put("businessKey", businessKey); + + // 鍙戦�丳OST璇锋眰 + ResponseEntity<Map<String, Object>> response = restTemplate.exchange( + url, + HttpMethod.POST, + new HttpEntity<>(params), + new ParameterizedTypeReference<Map<String, Object>>() {} + ); + + if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { + Object code = response.getBody().get("code"); + boolean ok = (code instanceof Number && ((Number) code).intValue() == 200) || "200".equals(String.valueOf(code)); + if (!ok) { + throw new BusinessException("宸ヤ綔娴佸惎鍔ㄤ换鍔″け璐ワ紝杩斿洖鐮�: " + code); + } + Map<String, Object> data = (Map<String, Object>) response.getBody().get("data"); + if (data == null) { + throw new BusinessException("宸ヤ綔娴佸惎鍔ㄤ换鍔″け璐ワ紝杩斿洖鏁版嵁涓虹┖"); + } + return data; + } else { + throw new BusinessException("鍚姩宸ヤ綔娴佸け璐ワ紝鍝嶅簲鐘舵��:"+response.getStatusCode()); + } + } catch (Exception e) { + log.error("璋冪敤鍚姩宸ヤ綔娴佹帴鍙eけ璐�", e); + throw new BusinessException("鍚姩宸ヤ綔娴佸け璐�: " + e.getMessage()); + } + } + + /** + * 鎻愪氦娴佺▼浠诲姟 + * @param taskId 浠诲姟ID锛堜娇鐢ㄨ鍗曠殑workflowId锛� + * @param userId 鐢ㄦ埛ID + * @param comment 瀹℃壒鎰忚锛堝锛氬鏍搁�氳繃锛� + */ + private void completeWorkflowTask(String taskId, String userId, String comment) { + try { + String url = workflowProperties.getProcess().getBaseUrl() + workflowProperties.getProcess().getCompleteUrl(); + Map<String, Object> params = new HashMap<>(); + params.put("taskId", taskId); + params.put("userid", userId); + params.put("commponet", comment); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity<Map<String, Object>> entity = new HttpEntity<>(params, headers); + + ResponseEntity<Map<String, Object>> response = restTemplate.exchange( + url, + HttpMethod.POST, + entity, + new ParameterizedTypeReference<Map<String, Object>>() {} + ); + + if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { + Object code = response.getBody().get("code"); + boolean ok = (code instanceof Number && ((Number) code).intValue() == 200) || "200".equals(String.valueOf(code)); + if (!ok) { + throw new BusinessException("宸ヤ綔娴佸畬鎴愪换鍔″け璐ワ紝杩斿洖鐮�: " + code); + } + Map<?, ?> data = (Map<?, ?>) response.getBody().get("data"); + if (data == null) { + throw new BusinessException("宸ヤ綔娴佸畬鎴愪换鍔″け璐ワ紝杩斿洖鏁版嵁涓虹┖"); + } + log.info("瀹屾垚宸ヤ綔娴佷换鍔℃垚鍔燂紝processinstId: {}", data.get("processinstId")); + } else { + throw new BusinessException("宸ヤ綔娴佸畬鎴愪换鍔℃帴鍙h皟鐢ㄥけ璐ワ紝HTTP鐘舵��: " + response.getStatusCode()); + } + } catch (Exception e) { + log.error("鎻愪氦宸ヤ綔娴佸け璐�", e); + throw new BusinessException("鎻愪氦宸ヤ綔娴佸け璐�: " + e.getMessage()); + } + } + + /** + * 椹冲洖娴佺▼浠诲姟 + */ + private void rejectWorkflowTask(String taskId, String userId, String comment) { + try { + String url = workflowProperties.getProcess().getBaseUrl() + workflowProperties.getProcess().getRejectUrl(); + Map<String, Object> params = new HashMap<>(); + params.put("taskId", taskId); + params.put("userid", userId); + params.put("commponet", comment); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity<Map<String, Object>> entity = new HttpEntity<>(params, headers); + + ResponseEntity<Map<String, Object>> response = restTemplate.exchange( + url, + HttpMethod.POST, + entity, + new ParameterizedTypeReference<Map<String, Object>>() {} + ); + + if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { + Object code = response.getBody().get("code"); + boolean ok = (code instanceof Number && ((Number) code).intValue() == 200) || "200".equals(String.valueOf(code)); + if (!ok) { + throw new BusinessException("宸ヤ綔娴侀┏鍥炰换鍔″け璐ワ紝杩斿洖鐮�: " + code); + } + Map<?, ?> data = (Map<?, ?>) response.getBody().get("data"); + if (data == null) { + throw new BusinessException("宸ヤ綔娴侀┏鍥炰换鍔″け璐ワ紝杩斿洖鏁版嵁涓虹┖"); + } + log.info("椹冲洖宸ヤ綔娴佷换鍔℃垚鍔燂紝processinstId: {}", data.get("processinstId")); + } else { + throw new BusinessException("宸ヤ綔娴侀┏鍥炰换鍔℃帴鍙h皟鐢ㄥけ璐ワ紝HTTP鐘舵��: " + response.getStatusCode()); + } + } catch (Exception e) { + log.error("椹冲洖宸ヤ綔娴佸け璐�", e); + throw new BusinessException("椹冲洖宸ヤ綔娴佸け璐�: " + e.getMessage()); + } + } + + /** + * 鎸夌収workFlowType鏌ヨ娴佺▼瀹炰緥ID闆嗗悎 + * workFlowType: 0=浠e姙锛�1=宸插姙 + */ + private List<String> fetchWorkflowProcessInstanceIds(Integer workFlowType, String userId, String depId,String businessKey,Integer pageIndex, Integer pageSize) { + try { + if (workFlowType == null) { + return java.util.Collections.emptyList(); + } + + String base = workflowProperties.getProcess().getBaseUrl(); + + Map<String, Object> params = new HashMap<>(); + params.put("userid", userId); + params.put("businessKey", businessKey); + params.put("pageIndex", pageIndex != null ? pageIndex : 1); + params.put("pageSize", pageSize != null ? pageSize : 10); + + String url; + if (workFlowType != null && workFlowType == 0) { + // 浠e姙 + url = base + workflowProperties.getProcess().getFindTodoUrl(); + params.put("depid", depId); + } else { + // 宸插姙 + url = base + workflowProperties.getProcess().getFindDoneUrl(); + } + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity<Map<String, Object>> entity = new HttpEntity<>(params, headers); + + ResponseEntity<Map<String, Object>> response = restTemplate.exchange( + url, + HttpMethod.POST, + entity, + new ParameterizedTypeReference<Map<String, Object>>() {} + ); + + if (!response.getStatusCode().is2xxSuccessful() || response.getBody() == null) { + return java.util.Collections.emptyList(); + } + Object dataObj = response.getBody().get("data"); + + if (workFlowType != null && workFlowType == 0) { + if (!(dataObj instanceof java.util.List)) { + return java.util.Collections.emptyList(); + } + java.util.List<?> list = (java.util.List<?>) dataObj; + return list.stream() + .filter(item -> item instanceof Map) + .map(item -> (Map<?, ?>) item) + .map(m -> m.get("processInstanceId")) + .filter(Objects::nonNull) + .map(Object::toString) + .collect(Collectors.toList()); + }else { + if (!(dataObj instanceof Map)) { + return java.util.Collections.emptyList(); + } + Map<?,?> map = (Map<?,?>) dataObj; + Object dataObj1 = ((Map<?, ?>) dataObj).get("list"); + java.util.List<?> list = (java.util.List<?>) dataObj1; + return list.stream() + .filter(item -> item instanceof Map) + .map(item -> (Map<?, ?>) item) + .map(m -> m.get("processInstanceId")) + .filter(Objects::nonNull) + .map(Object::toString) + .collect(Collectors.toList()); + } + + } catch (Exception e) { + log.error("鏌ヨ宸ヤ綔娴佸疄渚婭D澶辫触", e); + return java.util.Collections.emptyList(); + } + } } -- Gitblit v1.8.0