| | |
| | | import com.vincent.rsf.openApi.entity.constant.RcsConstant; |
| | | import com.vincent.rsf.openApi.entity.dto.SyncLocsDto; |
| | | import com.vincent.rsf.openApi.entity.params.ExMsgCallbackParams; |
| | | import com.vincent.rsf.openApi.entity.params.LocSiteParams; |
| | | import com.vincent.rsf.openApi.entity.params.RcsPubTaskParams; |
| | | import com.vincent.rsf.openApi.entity.params.SyncRcsLocsParam; |
| | | import com.vincent.rsf.openApi.entity.params.TaskReportParams; |
| | | import com.vincent.rsf.openApi.mapper.LocMapper; |
| | | import com.vincent.rsf.openApi.service.WmsRcsService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | |
| | | @Autowired |
| | | private PlatformProperties rcsApi; |
| | | |
| | | @Autowired |
| | | private PlatformProperties.WmsApi wmsApi; |
| | | |
| | | @Autowired |
| | | private RestTemplate restTemplate; |
| | | |
| | | |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R pubTasks(RcsPubTaskParams params) { |
| | | public CommonResponse pubTasks(RcsPubTaskParams params) { |
| | | /**RCS基础配置链接*/ |
| | | String rcsUrl = rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.pubTask; |
| | | log.info("任务下发,请求地址: {}, 请求参数: {}", rcsUrl , JSONObject.toJSONString(params)); |
| | | log.info("========== 开始下发任务到RCS =========="); |
| | | log.info("RCS请求地址:{}", rcsUrl); |
| | | if (params != null) { |
| | | log.info("批次编号:{}", params.getBatchNo()); |
| | | if (params.getTasks() != null) { |
| | | log.info("任务数量:{}", params.getTasks().size()); |
| | | } |
| | | } |
| | | log.info("请求参数:{}", JSONObject.toJSONString(params)); |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.add("Content-Type", "application/json"); |
| | | headers.add("api-version", "v2.0"); |
| | | HttpEntity httpEntity = new HttpEntity(params, headers); |
| | | long startTime = System.currentTimeMillis(); |
| | | ResponseEntity<String> exchange = restTemplate.exchange(rcsUrl, HttpMethod.POST, httpEntity, String.class); |
| | | log.info("任务下发后,响应结果: {}", exchange); |
| | | long endTime = System.currentTimeMillis(); |
| | | log.info("RCS响应耗时:{}ms", (endTime - startTime)); |
| | | log.info("RCS响应状态码:{}", exchange.getStatusCode()); |
| | | log.info("RCS响应头:{}", exchange.getHeaders()); |
| | | log.info("RCS响应体:{}", exchange.getBody()); |
| | | if (Objects.isNull(exchange.getBody())) { |
| | | throw new CoolException("任务下发失败!!"); |
| | | log.error("========== RCS任务下发失败 =========="); |
| | | log.error("RCS响应体为空,无法解析响应结果"); |
| | | log.error("请求地址:{}", rcsUrl); |
| | | log.error("请求参数:{}", JSONObject.toJSONString(params)); |
| | | throw new CoolException("任务下发失败,RCS响应体为空!!"); |
| | | } else { |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | objectMapper.coercionConfigDefaults() |
| | | .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty); |
| | | try { |
| | | CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class); |
| | | log.info("RCS响应解析结果 - code:{},msg:{},data:{}", |
| | | result.getCode(), result.getMsg(), result.getData()); |
| | | if (result.getCode() == 200) { |
| | | return R.ok(); |
| | | log.info("========== RCS任务下发成功 =========="); |
| | | return result; |
| | | } else { |
| | | throw new CoolException("任务下发失败!!"); |
| | | log.error("========== RCS任务下发失败 =========="); |
| | | log.error("RCS返回错误 - code:{},msg:{},data:{}", |
| | | result.getCode(), result.getMsg(), result.getData()); |
| | | return result; |
| | | } |
| | | } catch (JsonProcessingException e) { |
| | | throw new CoolException(e.getMessage()); |
| | | log.error("========== RCS任务下发异常 =========="); |
| | | log.error("解析RCS响应失败,响应体:{}", exchange.getBody(), e); |
| | | throw new CoolException("解析RCS响应失败:" + e.getMessage()); |
| | | } catch (Exception e) { |
| | | log.error("========== RCS任务下发异常 =========="); |
| | | log.error("任务下发过程中发生异常", e); |
| | | throw e; |
| | | } |
| | | } |
| | | } |
| | |
| | | * @version 1.0 |
| | | */ |
| | | @Override |
| | | public R cancelTasks(Map<String, Object> params) { |
| | | return R.ok(); |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public CommonResponse cancelTasks(Map<String, Object> params) { |
| | | /**RCS基础配置链接*/ |
| | | String rcsUrl = rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.cancelTask; |
| | | log.info("========== 开始取消RCS任务(open-rcs接口) =========="); |
| | | log.info("RCS取消任务请求地址:{}", rcsUrl); |
| | | log.info("RCS取消任务请求参数:{}", JSONObject.toJSONString(params)); |
| | | |
| | | // 打印详细的请求参数信息 |
| | | if (params != null) { |
| | | Object batchNo = params.get("batchNo"); |
| | | Object tasks = params.get("tasks"); |
| | | if (batchNo != null) { |
| | | log.info("批次编号:{}", batchNo); |
| | | } |
| | | if (tasks != null) { |
| | | if (tasks instanceof List) { |
| | | log.info("任务数量:{}", ((List<?>) tasks).size()); |
| | | log.info("任务编号列表:{}", tasks); |
| | | } else { |
| | | log.info("任务参数:{}", tasks); |
| | | } |
| | | } |
| | | } |
| | | |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.add("Content-Type", "application/json"); |
| | | headers.add("api-version", "v2.0"); |
| | | HttpEntity httpEntity = new HttpEntity(params, headers); |
| | | |
| | | long startTime = System.currentTimeMillis(); |
| | | ResponseEntity<String> exchange = restTemplate.exchange(rcsUrl, HttpMethod.POST, httpEntity, String.class); |
| | | long endTime = System.currentTimeMillis(); |
| | | |
| | | log.info("RCS取消任务响应耗时:{}ms", (endTime - startTime)); |
| | | log.info("RCS取消任务响应状态码:{}", exchange.getStatusCode()); |
| | | log.info("RCS取消任务响应头:{}", exchange.getHeaders()); |
| | | log.info("RCS取消任务响应体:{}", exchange.getBody()); |
| | | if (Objects.isNull(exchange.getBody())) { |
| | | throw new CoolException("取消任务失败!!"); |
| | | } else { |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | objectMapper.coercionConfigDefaults() |
| | | .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty); |
| | | try { |
| | | CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class); |
| | | if (result.getCode() == 200) { |
| | | log.info("========== RCS任务取消成功(open-rcs接口) =========="); |
| | | log.info("成功取消的任务编号:{}", params.get("tasks")); |
| | | return result; |
| | | } else { |
| | | log.error("========== RCS任务取消失败(open-rcs接口) =========="); |
| | | log.error("RCS返回错误码:{},错误信息:{}", result.getCode(), result.getMsg()); |
| | | throw new CoolException("取消任务失败!!" + (result.getMsg() != null ? ":" + result.getMsg() : "")); |
| | | } |
| | | } catch (JsonProcessingException e) { |
| | | log.error("RCS取消任务响应解析失败:{}", e.getMessage(), e); |
| | | throw new CoolException("RCS取消任务响应解析失败:" + e.getMessage()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | * @version 1.0 |
| | | */ |
| | | @Override |
| | | public R callBackEvent(ExMsgCallbackParams params) { |
| | | public CommonResponse callBackEvent(ExMsgCallbackParams params) { |
| | | // 参数校验 |
| | | if (Objects.isNull(params)) { |
| | | log.error("RCS回调事件参数为空!"); |
| | | throw new CoolException("参数不能为空!!"); |
| | | } |
| | | |
| | | // 详细记录接收到的参数 |
| | | log.info("RCS回调事件接收参数 - seqNum: {}, eventType: {}, robotCode: {}, zpallet: {}", |
| | | params.getSeqNum(), params.getEventType(), params.getRobotCode(), params.getZpallet()); |
| | | |
| | | // 检查关键字段是否为空 |
| | | if (Objects.isNull(params.getSeqNum()) || params.getSeqNum().isEmpty()) { |
| | | log.warn("RCS回调事件参数seqNum为空!完整参数:{}", JSONObject.toJSONString(params)); |
| | | } |
| | | if (Objects.isNull(params.getEventType()) || params.getEventType().isEmpty()) { |
| | | log.warn("RCS回调事件参数eventType为空!完整参数:{}", JSONObject.toJSONString(params)); |
| | | } |
| | | |
| | | String callUrl = wmsApi.getHost() + ":" + wmsApi.getPort() + WmsConstant.callBack; |
| | | /**WMS基础配置链接*/ |
| | | log.info("任务执行状态上报,请求地址: {}, 请求参数: {}", callUrl , JSONObject.toJSONString(params)); |
| | |
| | | ResponseEntity<String> exchange = restTemplate.exchange(callUrl, HttpMethod.POST, httpEntity, String.class); |
| | | log.info("任务执行状态上报,响应结果: {}", exchange); |
| | | if (Objects.isNull(exchange.getBody())) { |
| | | return R.error(); |
| | | return new CommonResponse(); |
| | | } else { |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | objectMapper.coercionConfigDefaults() |
| | |
| | | try { |
| | | CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class); |
| | | if (result.getCode() == 200) { |
| | | return R.ok(); |
| | | return result; |
| | | } else { |
| | | return R.error(result.getMsg()); |
| | | return result; |
| | | // throw new CoolException("任务执行状态上报失败!!"); |
| | | } |
| | | } catch (JsonProcessingException e) { |
| | |
| | | return syncRcsLocs(params); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @author Ryan |
| | | * @date 2025/11/10 |
| | | * @description: 修改库位或站点状态 |
| | | * @version 1.0 |
| | | */ |
| | | @Override |
| | | public R modifyLocOrSite(LocSiteParams params) { |
| | | /**RCS基础配置链接*/ |
| | | String rcsUrl = rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.modifystatus; |
| | | log.info("库位或站点状态修改,请求地址: {}, 请求参数: {}", rcsUrl , JSONObject.toJSONString(params)); |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.add("Content-Type", "application/json"); |
| | | headers.add("api-version", "v2.0"); |
| | | HttpEntity httpEntity = new HttpEntity(params, headers); |
| | | ResponseEntity<String> exchange = restTemplate.exchange(rcsUrl, HttpMethod.POST, httpEntity, String.class); |
| | | log.info("库位或站点状态修改,响应结果: {}", exchange); |
| | | if (Objects.isNull(exchange.getBody())) { |
| | | throw new CoolException("状态修改失败!!"); |
| | | } else { |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | objectMapper.coercionConfigDefaults() |
| | | .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty); |
| | | try { |
| | | CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class); |
| | | if (result.getCode() == 200) { |
| | | return R.ok(); |
| | | } else { |
| | | throw new CoolException("状态修改失败!!"); |
| | | } |
| | | } catch (JsonProcessingException e) { |
| | | throw new CoolException(e.getMessage()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @author Ryan |
| | | * @date 2025/8/28 |
| | |
| | | public List<SyncLocsDto> syncRcsLocs(SyncRcsLocsParam params) { |
| | | /**RCS基础配置链接*/ |
| | | String rcsUrl = rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.syncLocs; |
| | | log.info("任务下发,请求地址: {}, 请求参数: {}", rcsUrl , JSONObject.toJSONString(params)); |
| | | log.info("任务下发,请求地址2: {}, 请求参数: {}", rcsUrl , JSONObject.toJSONString(params)); |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.add("Content-Type", "application/json"); |
| | | headers.add("api-version", "v2.0"); |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @author Ryan |
| | | * @date 2026/2/3 |
| | | * @description: 任务执行通知上报(RCS回调接口) |
| | | * @version 1.0 |
| | | */ |
| | | @Override |
| | | public CommonResponse reportTask(TaskReportParams params) { |
| | | log.info("任务执行通知上报,请求参数: {}", JSONObject.toJSONString(params)); |
| | | |
| | | // 参数校验 |
| | | if (Objects.isNull(params)) { |
| | | throw new CoolException("参数不能为空!!"); |
| | | } |
| | | if (Objects.isNull(params.getBatchNo()) || params.getBatchNo().isEmpty()) { |
| | | throw new CoolException("任务批次不能为空!!"); |
| | | } |
| | | if (Objects.isNull(params.getTaskNo()) || params.getTaskNo().isEmpty()) { |
| | | throw new CoolException("任务编号不能为空!!"); |
| | | } |
| | | if (Objects.isNull(params.getTimestamp()) || params.getTimestamp().isEmpty()) { |
| | | throw new CoolException("时间戳不能为空!!"); |
| | | } |
| | | |
| | | // 将TaskReportParams转换为ExMsgParams格式(taskNo -> seqNum) |
| | | // 根据RCS新接口规范,taskNo对应旧接口的seqNum |
| | | JSONObject exMsgParams = new JSONObject(); |
| | | exMsgParams.put("seqNum", params.getTaskNo()); // taskNo映射到seqNum |
| | | // eventType设置为END,表示任务完成(根据业务需求可能需要调整) |
| | | exMsgParams.put("eventType", "END"); |
| | | exMsgParams.put("robotCode", null); |
| | | exMsgParams.put("zpallet", null); |
| | | |
| | | // 将任务上报回调转发到WMS系统 |
| | | String callUrl = wmsApi.getHost() + ":" + wmsApi.getPort() + WmsConstant.callBack; |
| | | log.info("任务执行通知上报,请求地址: {}, 转换后参数: {}", callUrl, exMsgParams.toJSONString()); |
| | | HttpHeaders headers = new HttpHeaders(); |
| | | headers.add("Content-Type", "application/json"); |
| | | headers.add("api-version", "v2.0"); |
| | | HttpEntity httpEntity = new HttpEntity(exMsgParams, headers); |
| | | ResponseEntity<String> exchange = restTemplate.exchange(callUrl, HttpMethod.POST, httpEntity, String.class); |
| | | log.info("任务执行通知上报,响应结果: {}", exchange); |
| | | |
| | | if (Objects.isNull(exchange.getBody())) { |
| | | // 如果回调失败,返回成功响应(避免RCS重复回调) |
| | | CommonResponse response = new CommonResponse(); |
| | | response.setCode(200); |
| | | response.setMsg("接收成功"); |
| | | log.warn("任务执行通知上报回调失败,但返回成功响应,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); |
| | | return response; |
| | | } else { |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | objectMapper.coercionConfigDefaults() |
| | | .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty); |
| | | try { |
| | | CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class); |
| | | if (result.getCode() == 200) { |
| | | log.info("任务执行通知上报成功,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); |
| | | return result; |
| | | } else { |
| | | log.warn("任务执行通知上报回调返回非200状态,任务编号:{},批次:{},响应:{}", params.getTaskNo(), params.getBatchNo(), exchange.getBody()); |
| | | return result; |
| | | } |
| | | } catch (JsonProcessingException e) { |
| | | log.error("任务执行通知上报回调响应解析失败,任务编号:{},批次:{},错误:{}", params.getTaskNo(), params.getBatchNo(), e.getMessage()); |
| | | // 解析失败时返回成功响应,避免RCS重复回调 |
| | | CommonResponse response = new CommonResponse(); |
| | | response.setCode(200); |
| | | response.setMsg("接收成功"); |
| | | return response; |
| | | } |
| | | } |
| | | } |
| | | } |