rsf-open-api/src/main/java/com/vincent/rsf/openApi/controller/WmsRcsController.java
@@ -5,6 +5,7 @@ import com.vincent.rsf.openApi.entity.dto.CommonResponse; import com.vincent.rsf.openApi.entity.params.ExMsgCallbackParams; import com.vincent.rsf.openApi.entity.params.LocSiteParams; import com.vincent.rsf.openApi.entity.params.LocationAllocateParams; import com.vincent.rsf.openApi.entity.params.RcsPubTaskParams; import com.vincent.rsf.openApi.entity.params.SyncRcsLocsParam; import com.vincent.rsf.openApi.entity.params.TaskReportParams; @@ -116,4 +117,29 @@ return wmsRcsService.reportTask(params); } /** * @author Ryan * @date 2026/2/6 * @description: 申请入库任务 * @version 1.0 */ @ApiOperation("申请入库任务") @PostMapping("/api/open/location/allocate") public R allocateLocation(@RequestBody LocationAllocateParams params) { log.info("申请入库任务,请求参数:{}", params); if (Objects.isNull(params)) { return R.error("参数不能为空!!"); } if (Objects.isNull(params.getBarcode()) || params.getBarcode().isEmpty()) { return R.error("料箱码不能为空!!"); } if (Objects.isNull(params.getStaNo()) || params.getStaNo().isEmpty()) { return R.error("入库站点不能为空!!"); } if (Objects.isNull(params.getType())) { params.setType(18); } return wmsRcsService.allocateLocation(params); } } rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/dto/LocationAllocateResponse.java
New file @@ -0,0 +1,19 @@ package com.vincent.rsf.openApi.entity.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; import java.io.Serializable; @Data @Accessors(chain = true) @ApiModel(value = "LocationAllocateResponse", description = "申请入库任务返回结果") public class LocationAllocateResponse implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty("库位号") private String locNo; } rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/params/LocationAllocateParams.java
New file @@ -0,0 +1,25 @@ package com.vincent.rsf.openApi.entity.params; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; import java.io.Serializable; @Data @Accessors(chain = true) @ApiModel(value = "LocationAllocateParams", description = "申请入库任务参数") public class LocationAllocateParams implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "料箱码", required = true) private String barcode; @ApiModelProperty(value = "入库站点", required = true) private String staNo; @ApiModelProperty(value = "入库类型", required = true) private Integer type; } rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/WmsRcsService.java
@@ -8,6 +8,7 @@ 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.LocationAllocateParams; import com.vincent.rsf.openApi.entity.params.RcsPubTaskParams; import com.vincent.rsf.openApi.entity.params.SyncRcsLocsParam; import com.vincent.rsf.openApi.entity.params.TaskReportParams; @@ -28,4 +29,6 @@ R modifyLocOrSite(LocSiteParams params); CommonResponse reportTask(TaskReportParams params); R allocateLocation(LocationAllocateParams params); } rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/WmsRcsServiceImpl.java
@@ -15,8 +15,10 @@ import com.vincent.rsf.openApi.entity.dto.CommonResponse; import com.vincent.rsf.openApi.entity.constant.RcsConstant; import com.vincent.rsf.openApi.entity.dto.SyncLocsDto; import com.vincent.rsf.openApi.entity.dto.LocationAllocateResponse; import com.vincent.rsf.openApi.entity.params.ExMsgCallbackParams; import com.vincent.rsf.openApi.entity.params.LocSiteParams; import com.vincent.rsf.openApi.entity.params.LocationAllocateParams; import com.vincent.rsf.openApi.entity.params.RcsPubTaskParams; import com.vincent.rsf.openApi.entity.params.SyncRcsLocsParam; import com.vincent.rsf.openApi.entity.params.TaskReportParams; @@ -335,7 +337,7 @@ */ @Override public CommonResponse reportTask(TaskReportParams params) { log.info("任务执行通知上报,请求参数: {}", JSONObject.toJSONString(params)); log.info("RCS回调,请求参数: {}", JSONObject.toJSONString(params)); // 参数校验 if (Objects.isNull(params)) { @@ -362,21 +364,22 @@ // 将任务上报回调转发到WMS系统 String callUrl = wmsApi.getHost() + ":" + wmsApi.getPort() + WmsConstant.callBack; log.info("任务执行通知上报,请求地址: {}, 转换后参数: {}", callUrl, exMsgParams.toJSONString()); log.info("RCS回调-WMS-SERVER任务上报-,请求地址: {}, 转换后参数: {}", 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); log.info("RCS回调-WMS-SERVER任务上报-,响应结果: {}", exchange); if (Objects.isNull(exchange.getBody())) { // 如果回调失败,返回成功响应(避免RCS重复回调) CommonResponse response = new CommonResponse(); response.setCode(200); response.setMsg("接收成功"); log.warn("任务执行通知上报回调失败,但返回成功响应,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); return response; // 回调失败,抛出异常 log.error("========== RCS回调-WMS-SERVER任务上报-失败 =========="); log.error("RCS回调-WMS-SERVER任务上报-响应体为空,无法解析响应结果"); log.error("RCS回调-WMS-SERVER任务上报-请求地址:{}", callUrl); log.error("RCS回调-WMS-SERVER任务上报-请求参数:{}", exMsgParams.toJSONString()); log.error("RCS回调-WMS-SERVER任务上报-失败的任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); throw new CoolException("RCS回调-WMS-SERVER任务上报-失败,WMS响应体为空!任务编号:" + params.getTaskNo() + ",批次:" + params.getBatchNo()); } else { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.coercionConfigDefaults() @@ -384,14 +387,14 @@ try { CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class); if (result.getCode() == 200) { log.info("任务执行通知上报成功,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); log.info("RCS回调-WMS-SERVER任务上报-成功,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); return result; } else { log.warn("任务执行通知上报回调返回非200状态,任务编号:{},批次:{},响应:{}", params.getTaskNo(), params.getBatchNo(), exchange.getBody()); log.warn("RCS回调-WMS-SERVER任务上报-返回非200状态,任务编号:{},批次:{},响应:{}", params.getTaskNo(), params.getBatchNo(), exchange.getBody()); return result; } } catch (JsonProcessingException e) { log.error("任务执行通知上报回调响应解析失败,任务编号:{},批次:{},错误:{}", params.getTaskNo(), params.getBatchNo(), e.getMessage()); log.error("RCS回调-WMS-SERVER任务上报-响应解析失败,任务编号:{},批次:{},错误:{}", params.getTaskNo(), params.getBatchNo(), e.getMessage()); // 解析失败时返回成功响应,避免RCS重复回调 CommonResponse response = new CommonResponse(); response.setCode(200); @@ -400,4 +403,79 @@ } } } /** * @author Ryan * @date 2026/2/6 * @description: 申请入库任务,分配库位 * @version 1.0 */ @Override @Transactional(rollbackFor = Exception.class) public R allocateLocation(LocationAllocateParams params) { log.info("========== 开始申请入库任务,分配库位 =========="); log.info("料箱码:{},入库站点:{},入库类型:{}", params.getBarcode(), params.getStaNo(), params.getType()); // 调用WMS server内部接口进行库位分配 String wmsUrl = wmsApi.getHost() + ":" + wmsApi.getPort() + "/rsf-server/wcs/allocate/location"; log.info("WMS请求地址:{}", wmsUrl); // 构建请求参数 JSONObject requestParams = new JSONObject(); requestParams.put("barcode", params.getBarcode()); requestParams.put("staNo", params.getStaNo()); requestParams.put("type", params.getType()); log.info("请求参数:{}", requestParams.toJSONString()); HttpHeaders headers = new HttpHeaders(); headers.add("Content-Type", "application/json"); HttpEntity httpEntity = new HttpEntity(requestParams, headers); long startTime = System.currentTimeMillis(); ResponseEntity<String> exchange = restTemplate.exchange(wmsUrl, HttpMethod.POST, httpEntity, String.class); long endTime = System.currentTimeMillis(); log.info("WMS响应耗时:{}ms", (endTime - startTime)); log.info("WMS响应状态码:{}", exchange.getStatusCode()); log.info("WMS响应体:{}", exchange.getBody()); if (Objects.isNull(exchange.getBody())) { log.error("========== 申请入库任务失败 =========="); log.error("WMS响应体为空,无法解析响应结果"); return R.error("申请入库任务失败,WMS响应体为空!!"); } else { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.coercionConfigDefaults() .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty); try { JSONObject responseJson = JSONObject.parseObject(exchange.getBody()); Integer code = responseJson.getInteger("code"); String msg = responseJson.getString("msg"); if (code != null && code == 200) { JSONObject data = responseJson.getJSONObject("data"); if (data != null) { String locNo = data.getString("locNo"); log.info("========== 申请入库任务成功 =========="); log.info("分配库位号:{}", locNo); LocationAllocateResponse response = new LocationAllocateResponse(); response.setLocNo(locNo); return R.ok(response); } else { log.error("========== 申请入库任务失败 =========="); log.error("响应数据为空"); return R.error("申请入库任务失败,响应数据为空!!"); } } else { log.error("========== 申请入库任务失败 =========="); log.error("WMS返回错误 - code:{},msg:{}", code, msg); return R.error(msg != null ? msg : "申请入库任务失败!!"); } } catch (Exception e) { log.error("========== 申请入库任务异常 =========="); log.error("解析WMS响应失败,响应体:{}", exchange.getBody(), e); return R.error("解析WMS响应失败:" + e.getMessage()); } } } } rsf-server/src/main/java/com/vincent/rsf/server/api/controller/WcsController.java
@@ -18,6 +18,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Map; @RestController @RequestMapping("/wcs") @Api(tags = "wcs接口对接") @@ -121,5 +123,34 @@ return wcsService.receiveExMsg(params); } /** * @author Ryan * @date 2026/2/6 * @description: 申请入库任务,分配库位(内部接口) * @version 1.0 */ @ApiOperation("申请入库任务,分配库位") @PostMapping("/allocate/location") public R allocateLocation(@RequestBody Map<String, Object> params) { if (Cools.isEmpty(params)) { return R.error("参数不能为空!!"); } String barcode = (String) params.get("barcode"); String staNo = (String) params.get("staNo"); Integer type = params.get("type") != null ? Integer.valueOf(params.get("type").toString()) : null; if (Cools.isEmpty(barcode)) { return R.error("料箱码不能为空!!"); } if (Cools.isEmpty(staNo)) { return R.error("入库站点不能为空!!"); } if (type == null) { return R.error("入库类型不能为空!!"); } return wcsService.allocateLocation(barcode, staNo, type); } } rsf-server/src/main/java/com/vincent/rsf/server/api/service/WcsService.java
@@ -18,4 +18,6 @@ R receiveExMsg(ExMsgParams params); R pubWcsTask(WcsTaskParams params); R allocateLocation(String barcode, String staNo, Integer type); } rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
@@ -914,6 +914,7 @@ int deviceNo = 0; Loc loc = new Loc(); InTaskMsgDto inTaskMsgDto = new InTaskMsgDto(); locTypeDto.setLocType1(18); List<Loc> loc1 = locService.list(new LambdaQueryWrapper<Loc>() .eq(Loc::getAreaId, area) .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type) @@ -969,4 +970,46 @@ inTaskMsgDto.setLocNo(locNo); return inTaskMsgDto; } /** * @author Ryan * @date 2026/2/6 * @description: 申请入库任务,分配库位 * @version 1.0 */ @Override @Transactional(rollbackFor = Exception.class) public R allocateLocation(String barcode, String staNo, Integer type) { log.info("========== 开始申请入库任务,分配库位 =========="); log.info("料箱码:{},入库站点:{},入库类型:{}", barcode, staNo, type); // 构建 TaskInParam 参数,与 /wcs/create/in/task 接口参数一致 TaskInParam param = new TaskInParam(); param.setBarcode(barcode); param.setSourceStaNo(staNo); param.setIoType(TaskType.TASK_TYPE_IN.type); // 入库类型 param.setLocType1(type); // 库位类型(高低检测信号) param.setUser(1L); // 默认用户ID,可以根据实际需求调整 // 调用 createInTask 方法,创建完整的入库任务 // 该方法会执行以下流程: // 1. 验证设备站点 // 2. 验证组拖状态 // 3. 生成任务编码 // 4. 获取库位号 // 5. 创建并保存任务 // 6. 更新库位状态 // 7. 获取并验证组拖明细 // 8. 创建并保存任务明细 // 9. 更新组托状态 InTaskMsgDto msgDto = createInTask(param); log.info("========== 申请入库任务成功 =========="); log.info("任务编码:{},库位号:{}", msgDto.getWorkNo(), msgDto.getLocNo()); // 返回结果,只返回库位号(根据接口文档要求) JSONObject result = new JSONObject(); result.put("locNo", msgDto.getLocNo()); return R.ok(result); } } rsf-server/src/main/java/com/vincent/rsf/server/common/domain/PageParam.java
@@ -320,8 +320,10 @@ // column, temp[0], cls != null ? cls.getSimpleName() : "null", requestInfo); continue; } // 检查实体类字段的 @TableField 注解,如果字段是保留关键字,使用注解中指定的列名(带反引号) String dbColumn = getDbColumnName(column); boolean asc = temp.length == 1 || !temp[temp.length - 1].toLowerCase().equals(ORDER_DESC_VALUE); orders.add(new OrderItem(column, asc)); orders.add(new OrderItem(dbColumn, asc)); } } } @@ -329,6 +331,57 @@ } /** * 获取数据库列名,如果是保留关键字则添加反引号 * @param fieldName 字段名(下划线格式) * @return 数据库列名 */ private String getDbColumnName(String fieldName) { if (cls == null) { // 如果没有实体类,检查是否是常见的保留关键字 return wrapReservedKeyword(fieldName); } // 查找实体类中对应的字段 for (Field field : Cools.getAllFields(cls)) { String column = Utils.toSymbolCase(field.getName(), '_'); if (column.equals(fieldName)) { // 检查是否有 @TableField 注解 if (field.isAnnotationPresent(TableField.class)) { TableField annotation = field.getAnnotation(TableField.class); String value = annotation.value(); // 如果注解值不为空,使用注解值(可能已经包含反引号) if (!Cools.isEmpty(value) && !value.equals(fieldName)) { return value; } } // 如果没有注解或注解值为空,检查是否是保留关键字 return wrapReservedKeyword(fieldName); } } // 如果找不到字段,检查是否是保留关键字 return wrapReservedKeyword(fieldName); } /** * 如果是 MySQL 保留关键字,则添加反引号 * @param column 列名 * @return 处理后的列名 */ private String wrapReservedKeyword(String column) { // MySQL 常见保留关键字列表 Set<String> reservedKeywords = new HashSet<>(Arrays.asList( "row", "type", "length", "channel", "status", "order", "group", "key", "index", "table", "database", "user", "select", "insert", "update", "delete", "from", "where" )); if (reservedKeywords.contains(column.toLowerCase())) { return "`" + column + "`"; } return column; } /** * 获取当前请求信息(路径和方法) * @return 请求信息字符串,格式:HTTP方法 请求路径 */ rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
@@ -1516,26 +1516,23 @@ @Override @Transactional(rollbackFor = Exception.class) public void pubTaskToWcs(List<Task> tasks) { WcsTaskParams taskParams = new WcsTaskParams(); List<TaskItemParam> items = new ArrayList<>(); /**任务下发接口*/ String pubTakUrl = rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.pubTask; // 设置批次编号(使用第一个任务的barcode,如果为null则使用任务编码) String batchNo = null; if (!tasks.isEmpty()) { Task firstTask = tasks.get(0); batchNo = StringUtils.isNotBlank(firstTask.getBarcode()) ? firstTask.getBarcode() : firstTask.getTaskCode(); } if (StringUtils.isBlank(batchNo)) { // 如果批次编号仍为空,生成一个默认值 batchNo = "BATCH_" + System.currentTimeMillis(); } taskParams.setBatchNo(batchNo); log.info("设置批次编号:{}", batchNo); tasks.forEach(task -> { for (Task task : tasks) { WcsTaskParams taskParams = new WcsTaskParams(); List<TaskItemParam> items = new ArrayList<>(); // 设置批次编号(使用当前任务的任务编码) String batchNo = task.getTaskCode(); if (StringUtils.isBlank(batchNo)) { // 如果任务编号为空,生成一个默认值 batchNo = "BATCH_" + System.currentTimeMillis(); } taskParams.setBatchNo(batchNo); log.info("任务批次编号:{}", batchNo); // 构建当前任务的参数 TaskItemParam itemParam = new TaskItemParam(); //任务编码(对应seqNum) itemParam.setTaskNo(task.getTaskCode()); @@ -1597,58 +1594,91 @@ throw new CoolException("当前站点不是F.在库状态!!"); } } if (station.getType().equals(StationTypeEnum.STATION_TYPE_NORMAL.type)) { if (!station.getUseStatus().equals(LocStsType.LOC_STS_TYPE_O.type)) { // 站点间移库需要获取目标站点 BasStation targetStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>().eq(BasStation::getStationName, task.getTargSite())); if (Objects.isNull(targetStation)) { throw new CoolException("目标站点不存在!!"); } if (targetStation.getType().equals(StationTypeEnum.STATION_TYPE_NORMAL.type)) { if (!targetStation.getUseStatus().equals(LocStsType.LOC_STS_TYPE_O.type)) { throw new CoolException("目标站点不是O.空闲状态!!"); } } } items.add(itemParam); }); taskParams.setTasks(items); /**任务下发接口*/ String pubTakUrl = rcsApi.getHost() + ":" + rcsApi.getPort() + RcsConstant.pubTask; /**RCS基础配置链接*/ log.info("========== 开始下发任务到RCS =========="); log.info("RCS请求地址:{}", pubTakUrl); log.info("批次编号:{}", batchNo); log.info("任务数量:{}", tasks.size()); log.info("任务列表详情:"); tasks.forEach(task -> { log.info(" - 任务编码:{},任务类型:{},源库位:{},目标库位:{},源站点:{},目标站点:{}", taskParams.setTasks(items); // 记录当前任务信息 log.info(" RCS- 任务编码:{},任务类型:{},源库位:{},目标库位:{},源站点:{},目标站点:{}", task.getTaskCode(), task.getTaskType(), task.getOrgLoc(), task.getTargLoc(), task.getOrgSite(), task.getTargSite()); }); log.info("请求参数:{}", JSONObject.toJSONString(taskParams)); HttpHeaders headers = new HttpHeaders(); headers.add("Content-Type", "application/json"); headers.add("api-version", "v2.0"); HttpEntity httpEntity = new HttpEntity(taskParams, headers); long startTime = System.currentTimeMillis(); ResponseEntity<String> exchange = restTemplate.exchange(pubTakUrl, 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())) { log.error("========== RCS任务下发失败 =========="); log.error("RCS响应体为空,无法解析响应结果"); log.error("请求地址:{}", pubTakUrl); log.error("请求参数:{}", JSONObject.toJSONString(taskParams)); throw new CoolException("任务下发失败,RCS响应体为空!!"); } else { log.info("RCS-请求参数:{}", JSONObject.toJSONString(taskParams)); // 发送当前任务 HttpHeaders headers = new HttpHeaders(); headers.add("Content-Type", "application/json"); headers.add("api-version", "v2.0"); HttpEntity httpEntity = new HttpEntity(taskParams, headers); /**RCS基础配置链接*/ log.info("========== 开始下发任务到RCS =========="); log.info("请求RCS-地址:{}", pubTakUrl); log.info("请求RCS-参数:{}", JSONObject.toJSONString(taskParams)); long startTime = System.currentTimeMillis(); ResponseEntity<String> exchange = null; try { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.coercionConfigDefaults() .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty); CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class); log.info("RCS响应解析结果 - code:{},msg:{},data:{}", result.getCode(), result.getMsg(), result.getData()); if (result.getCode() == 200) { log.info("RCS任务下发成功,开始更新任务状态"); tasks.forEach(task -> { log.info("更新任务状态 - 任务编码:{},任务类型:{}", task.getTaskCode(), task.getTaskType()); exchange = restTemplate.exchange(pubTakUrl, 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()); } catch (org.springframework.web.client.ResourceAccessException e) { long endTime = System.currentTimeMillis(); log.error("========== RCS任务下发资源访问异常 =========="); log.error("请求RCS-资源访问异常(可能包含连接超时),耗时:{}ms,任务编码:{}", (endTime - startTime), task.getTaskCode(), e); log.error("请求RCS-请求地址:{}", pubTakUrl); log.error("请求RCS-请求参数:{}", JSONObject.toJSONString(taskParams)); // 检查是否是连接超时异常 Throwable cause = e.getCause(); String errorMsg = e.getMessage(); if (cause instanceof java.net.SocketTimeoutException || (cause instanceof java.net.ConnectException && cause.getMessage() != null && cause.getMessage().contains("timed out")) || (errorMsg != null && (errorMsg.contains("Connection timed out") || errorMsg.contains("timed out") || errorMsg.contains("timeout")))) { throw new CoolException("RCS连接超时,任务下发失败!任务编码:" + task.getTaskCode() + ",错误信息:" + errorMsg); } throw new CoolException("RCS资源访问异常,任务下发失败!任务编码:" + task.getTaskCode() + ",错误信息:" + errorMsg); } catch (Exception e) { long endTime = System.currentTimeMillis(); log.error("========== RCS任务下发异常 =========="); log.error("请求RCS-异常,耗时:{}ms,任务编码:{}", (endTime - startTime), task.getTaskCode(), e); log.error("请求RCS-地址:{}", pubTakUrl); log.error("请求RCS-参数:{}", JSONObject.toJSONString(taskParams)); String errorMsg = e.getMessage(); // 检查是否是连接超时相关的异常 if (errorMsg != null && (errorMsg.contains("Connection timed out") || errorMsg.contains("timed out") || errorMsg.contains("timeout"))) { throw new CoolException("RCS连接超时,任务下发失败!任务编码:" + task.getTaskCode() + ",错误信息:" + errorMsg); } throw new CoolException("RCS任务下发异常!任务编码:" + task.getTaskCode() + ",错误信息:" + errorMsg); } if (Objects.isNull(exchange) || Objects.isNull(exchange.getBody())) { log.error("========== RCS任务下发失败 =========="); log.error("请求RCS-RCS响应体为空,无法解析响应结果"); log.error("请求RCS-地址:{}", pubTakUrl); log.error("请求RCS-参数:{}", JSONObject.toJSONString(taskParams)); log.error("请求RCS-失败的任务编码:{}", task.getTaskCode()); throw new CoolException("任务下发失败,RCS响应体为空!!任务编码:" + task.getTaskCode()); } else { try { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.coercionConfigDefaults() .setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty); CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class); log.info("RCS响应解析结果 - code:{},msg:{},data:{}", result.getCode(), result.getMsg(), result.getData()); if (result.getCode() == 200) { log.info("RCS任务下发成功,开始更新任务状态 - 任务编码:{}", task.getTaskCode()); if (task.getTaskType().equals(TaskType.TASK_TYPE_IN.type) || task.getTaskType().equals(TaskType.TASK_TYPE_PICK_IN.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type) @@ -1701,28 +1731,25 @@ } } } }); log.info("========== RCS任务下发完成,共{}个任务状态已更新 ==========", tasks.size()); } else { log.error("========== RCS任务下发失败 =========="); log.error("RCS返回错误 - code:{},msg:{},data:{}", result.getCode(), result.getMsg(), result.getData()); log.error("失败的任务列表:"); tasks.forEach(task -> { log.error(" - 任务编码:{},任务类型:{}", task.getTaskCode(), task.getTaskType()); }); // throw new CoolException("任务下发失败!!"); } else { log.error("========== RCS任务下发失败 =========="); log.error("RCS返回错误 - code:{},msg:{},data:{}", result.getCode(), result.getMsg(), result.getData()); log.error("失败的任务编码:{},任务类型:{}", task.getTaskCode(), task.getTaskType()); throw new CoolException("任务下发失败!!任务编码:" + task.getTaskCode()); } } catch (JsonProcessingException e) { log.error("========== RCS任务下发异常 =========="); log.error("解析RCS响应失败,响应体:{},任务编码:{}", exchange.getBody(), task.getTaskCode(), e); throw new CoolException("解析RCS响应失败:" + e.getMessage() + ",任务编码:" + task.getTaskCode()); } catch (Exception e) { log.error("========== RCS任务下发异常 =========="); log.error("任务下发过程中发生异常,任务编码:{}", task.getTaskCode(), e); throw e; } } catch (JsonProcessingException e) { 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; } } log.info("========== RCS任务下发完成,共{}个任务已处理 ==========", tasks.size()); }/**