diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/UnplannedVeneerController.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/UnplannedVeneerController.java index 7039246ff..a7e1f21a1 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/UnplannedVeneerController.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/UnplannedVeneerController.java @@ -65,7 +65,7 @@ public class UnplannedVeneerController { /** * 按订单或板材查询未排贴皮、原板件及板件造型数据。 * - * @param req 互斥查询范围及可选房间、柜体条件 + * @param req 订单和/或板材查询范围及可选房间、柜体条件 * @return 未排贴皮排单基础数据 */ @PostMapping("/plate/data") diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/UnplannedVeneerPlateDataReqVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/UnplannedVeneerPlateDataReqVO.java index a133b5929..f70d8942e 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/UnplannedVeneerPlateDataReqVO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/UnplannedVeneerPlateDataReqVO.java @@ -14,10 +14,10 @@ import java.util.List; @Data public class UnplannedVeneerPlateDataReqVO { - @Schema(description = "订单ID列表,与板材商品编码列表互斥") + @Schema(description = "订单ID列表,与板材商品编码列表至少传入一项") private List orderIds; - @Schema(description = "板材商品编码列表,与订单ID列表互斥") + @Schema(description = "板材商品编码列表,与订单ID列表至少传入一项") private List goodsIds; @Schema(description = "房间ID列表") diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeGoodsPageReqVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeGoodsPageReqVO.java index b807e6b1f..7f26c4a80 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeGoodsPageReqVO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeGoodsPageReqVO.java @@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.math.BigDecimal; +import java.util.List; /** * 贴皮分解材质分页查询请求参数。 @@ -12,6 +13,15 @@ import java.math.BigDecimal; @Data public class VeneerDecomposeGoodsPageReqVO extends PageParam { + @Schema(description = "订单ID列表") + private List orderIds; + + @Schema(description = "房间ID列表") + private List roomIds; + + @Schema(description = "柜体ID列表") + private List bodyIds; + @Schema(description = "板材名称") private String goodsName; diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeGoodsRespVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeGoodsRespVO.java index 0f36c8ab2..c12322838 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeGoodsRespVO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeGoodsRespVO.java @@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.math.BigDecimal; +import java.util.List; /** * 贴皮分解板材分页响应参数。 @@ -11,6 +12,9 @@ import java.math.BigDecimal; @Data public class VeneerDecomposeGoodsRespVO { + @Schema(description = "当前板材分组关联的订单") + private List orderIds; + @Schema(description = "板材名称") private String goodsName; diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeOrderPageReqVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeOrderPageReqVO.java index db2ee98a3..af8ba34f0 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeOrderPageReqVO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeOrderPageReqVO.java @@ -6,6 +6,7 @@ import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDate; +import java.util.List; import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; @@ -15,6 +16,12 @@ import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH @Data public class VeneerDecomposeOrderPageReqVO extends PageParam { + @Schema(description = "精确限定的订单ID列表") + private List orderIds; + + @Schema(description = "板材商品编码列表") + private List goodsIds; + @Schema(description = "订单号") private String orderId; diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerGoodsOrderRelationRespVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerGoodsOrderRelationRespVO.java new file mode 100644 index 000000000..5226d4012 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerGoodsOrderRelationRespVO.java @@ -0,0 +1,20 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 贴皮板材分组关联订单响应参数。 + */ +@Data +public class VeneerGoodsOrderRelationRespVO { + + @Schema(description = "板材商品编码") + private String goodsId; + + @Schema(description = "订单ID") + private Long orderId; + + @Schema(description = "订单板材ID,对应 order_goods.id") + private Long orderGoodsId; +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageGoodsPageReqVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageGoodsPageReqVO.java index ef801d649..1946a68b7 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageGoodsPageReqVO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageGoodsPageReqVO.java @@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.math.BigDecimal; +import java.util.List; /** * 贴皮管理板材分页查询请求参数。 @@ -12,6 +13,15 @@ import java.math.BigDecimal; @Data public class VeneerManageGoodsPageReqVO extends PageParam { + @Schema(description = "订单ID列表") + private List orderIds; + + @Schema(description = "房间ID列表") + private List roomIds; + + @Schema(description = "柜体ID列表") + private List bodyIds; + @Schema(description = "板材名称") private String goodsName; diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageGoodsRespVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageGoodsRespVO.java index 4a704bbe0..cf3039be6 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageGoodsRespVO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageGoodsRespVO.java @@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.math.BigDecimal; +import java.util.List; /** * 贴皮管理板材分页响应参数。 @@ -11,6 +12,9 @@ import java.math.BigDecimal; @Data public class VeneerManageGoodsRespVO { + @Schema(description = "当前板材分组关联的订单") + private List orderIds; + @Schema(description = "板材名称") private String goodsName; diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageOrderPageReqVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageOrderPageReqVO.java index 246a888a9..7b34fcbf1 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageOrderPageReqVO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageOrderPageReqVO.java @@ -6,6 +6,7 @@ import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDate; +import java.util.List; import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; @@ -15,6 +16,12 @@ import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH @Data public class VeneerManageOrderPageReqVO extends PageParam { + @Schema(description = "精确限定的订单ID列表") + private List orderIds; + + @Schema(description = "板材商品编码列表") + private List goodsIds; + @Schema(description = "订单号") private String orderId; diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/VeneerDecomposeMapper.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/VeneerDecomposeMapper.java index 6276059d3..d7f366262 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/VeneerDecomposeMapper.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/VeneerDecomposeMapper.java @@ -8,6 +8,7 @@ import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeOrd import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeOrderRespVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposePlatePageReqVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposePlateRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerGoodsOrderRelationRespVO; import com.cf.imes.module.executor.dal.dataobject.plate.PlateDO; import com.cf.imes.module.executor.dal.dataobject.veneer.VeneerDecomposedPlateCountDO; import org.apache.ibatis.annotations.Mapper; @@ -67,6 +68,17 @@ public interface VeneerDecomposeMapper { IPage selectGoodsPage(@Param("page") IPage page, @Param("req") VeneerDecomposeGoodsPageReqVO req); + /** + * 查询当前页板材分组关联的订单。 + * + * @param goodsIds 当前页板材商品编码 + * @param req 订单、房间及柜体筛选条件 + * @return 板材与订单关系 + */ + List selectGoodsOrderRelationList( + @Param("goodsIds") List goodsIds, + @Param("req") VeneerDecomposeGoodsPageReqVO req); + /** * 按订单查询未贴皮分解板件原始列表。 * 同一板件可能因多个加工组返回多条记录,由 Service 层按板件主键去重。 diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/VeneerManageMapper.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/VeneerManageMapper.java index 7111d1033..bbc42d7f5 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/VeneerManageMapper.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/VeneerManageMapper.java @@ -3,6 +3,7 @@ package com.cf.imes.module.executor.dal.mysql.veneer; import com.baomidou.mybatisplus.core.metadata.IPage; import com.cf.imes.module.executor.controller.admin.veneer.vo.UnplannedVeneerPlateDataReqVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.UnplannedVeneerPlateRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerGoodsOrderRelationRespVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageGoodsPageReqVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageGoodsRespVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageOrderPageReqVO; @@ -67,6 +68,17 @@ public interface VeneerManageMapper { IPage selectGoodsPage(@Param("page") IPage page, @Param("req") VeneerManageGoodsPageReqVO req); + /** + * 查询当前页贴皮管理板材分组关联的订单。 + * + * @param goodsIds 当前页板材商品编码 + * @param req 订单、房间及柜体筛选条件 + * @return 板材与订单关系 + */ + List selectGoodsOrderRelationList( + @Param("goodsIds") List goodsIds, + @Param("req") VeneerManageGoodsPageReqVO req); + /** * 分页查询存在待排单贴皮的根订单ID。 * @@ -104,6 +116,17 @@ public interface VeneerManageMapper { @Param("page") IPage page, @Param("req") VeneerManageGoodsPageReqVO req); + /** + * 查询当前页未排贴皮板材分组关联的订单。 + * + * @param goodsIds 当前页板材商品编码 + * @param req 订单、房间及柜体筛选条件 + * @return 板材与订单关系 + */ + List selectUnplannedGoodsOrderRelationList( + @Param("goodsIds") List goodsIds, + @Param("req") VeneerManageGoodsPageReqVO req); + /** * 按订单查询可维护的未排单板件贴皮列表。 * @@ -115,13 +138,14 @@ public interface VeneerManageMapper { /** * 按板材商品编码查询可维护的未排单板件贴皮列表。 * - * @param goodsIds 板材商品编码列表 + * @param req 订单、板材、房间及柜体查询条件 * @return 未排单板件贴皮列表 */ - List selectGoodsPlateList(@Param("goodsIds") List goodsIds); + List selectGoodsPlateList( + @Param("req") VeneerManagePlateListReqVO req); /** - * 按互斥业务范围查询待排单贴皮及其原板件信息。 + * 按订单和/或板材范围查询待排单贴皮及其原板件信息。 * 同一贴皮可能因多个加工组返回多条,由 Service 层合并。 * * @param req 订单或板材范围及房间、柜体筛选条件 diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/plan/producing/ProducingPlanOrderClient.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/plan/producing/ProducingPlanOrderClient.java index 63265906e..5dc7e1e23 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/plan/producing/ProducingPlanOrderClient.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/plan/producing/ProducingPlanOrderClient.java @@ -115,6 +115,8 @@ public class ProducingPlanOrderClient { private HttpResponse send(String url, String token, String method, String body, String operation) { + log.info("Submitting producing plan order operation {}, method={}, url={}, requestBody={}", + operation, method, url, body == null ? "" : body); HttpRequest.BodyPublisher publisher = body == null ? HttpRequest.BodyPublishers.noBody() : HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8); @@ -128,6 +130,10 @@ public class ProducingPlanOrderClient { try { HttpResponse response = httpClient.send( request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + log.info("Producing plan order operation {} response, method={}, url={}, " + + "httpStatus={}, responseBody={}", + operation, method, url, response.statusCode(), + responseBodyForLog(response.body())); if (response.statusCode() < 200 || response.statusCode() >= 300) { logRequestFailure(operation, method, url, body, response.statusCode(), response.body(), null); diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerDecomposeServiceImpl.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerDecomposeServiceImpl.java index 143f1f19c..bd48cb2bb 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerDecomposeServiceImpl.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerDecomposeServiceImpl.java @@ -21,6 +21,7 @@ import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeOrd import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposePlateDataRespVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposePlatePageReqVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposePlateRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerGoodsOrderRelationRespVO; import com.cf.imes.module.executor.dal.dataobject.goods.GoodsDO; import com.cf.imes.module.executor.dal.dataobject.order.OrderDO; import com.cf.imes.module.executor.dal.dataobject.ordermodel.OrderModelDO; @@ -151,7 +152,35 @@ public class VeneerDecomposeServiceImpl implements VeneerDecomposeService { public PageResult getGoodsPage(VeneerDecomposeGoodsPageReqVO req) { IPage result = veneerDecomposeMapper.selectGoodsPage( new PageDTO<>(req.getPageNo(), req.getPageSize()), req); - return new PageResult<>(result.getRecords(), result.getTotal()); + List goodsList = result.getRecords(); + if (CollUtil.isNotEmpty(goodsList)) { + List goodsIds = goodsList.stream() + .map(VeneerDecomposeGoodsRespVO::getGoodsId) + .distinct() + .toList(); + fillGoodsOrderRelations(goodsList, + veneerDecomposeMapper.selectGoodsOrderRelationList(goodsIds, req)); + } + return new PageResult<>(goodsList, result.getTotal()); + } + + /** + * 将当前页板材对应的订单关系回填到板材分组。 + * + * @param goodsList 当前页板材分组 + * @param relations 板材与订单关系 + */ + private void fillGoodsOrderRelations( + List goodsList, + List relations) { + Map> relationMap = new HashMap<>(); + for (VeneerGoodsOrderRelationRespVO relation : relations) { + relationMap.computeIfAbsent(relation.getGoodsId(), key -> new ArrayList<>()) + .add(relation); + } + for (VeneerDecomposeGoodsRespVO goods : goodsList) { + goods.setOrderIds(relationMap.getOrDefault(goods.getGoodsId(), List.of())); + } } @Override diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerManageService.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerManageService.java index 53183ef7f..fcbd56ab3 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerManageService.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerManageService.java @@ -70,7 +70,7 @@ public interface VeneerManageService { /** * 按订单或板材查询未排贴皮、原板件及板件造型数据。 * - * @param req 互斥查询范围及可选房间、柜体条件 + * @param req 订单和/或板材范围及可选房间、柜体条件 * @return 未排贴皮排单基础数据 */ UnplannedVeneerPlateDataRespVO getUnplannedPlateData(UnplannedVeneerPlateDataReqVO req); diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerManageServiceImpl.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerManageServiceImpl.java index d187e2c93..c116da230 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerManageServiceImpl.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerManageServiceImpl.java @@ -14,6 +14,7 @@ import com.cf.imes.framework.common.util.json.JsonUtils; import com.cf.imes.module.executor.controller.admin.veneer.vo.UnplannedVeneerPlateDataReqVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.UnplannedVeneerPlateDataRespVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.UnplannedVeneerPlateRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerGoodsOrderRelationRespVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageGoodsPageReqVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageGoodsRespVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageOrderPageReqVO; @@ -110,7 +111,9 @@ public class VeneerManageServiceImpl implements VeneerManageService { public PageResult getGoodsPage(VeneerManageGoodsPageReqVO req) { IPage result = veneerManageMapper.selectGoodsPage( new PageDTO<>(req.getPageNo(), req.getPageSize()), req); - return new PageResult<>(result.getRecords(), result.getTotal()); + List goodsList = result.getRecords(); + fillGoodsOrderRelations(goodsList, req, false); + return new PageResult<>(goodsList, result.getTotal()); } @Override @@ -154,7 +157,39 @@ public class VeneerManageServiceImpl implements VeneerManageService { public PageResult getUnplannedGoodsPage(VeneerManageGoodsPageReqVO req) { IPage result = veneerManageMapper.selectUnplannedGoodsPage( new PageDTO<>(req.getPageNo(), req.getPageSize()), req); - return new PageResult<>(result.getRecords(), result.getTotal()); + List goodsList = result.getRecords(); + fillGoodsOrderRelations(goodsList, req, true); + return new PageResult<>(goodsList, result.getTotal()); + } + + /** + * 查询并回填当前页板材分组关联的订单。 + * + * @param goodsList 当前页板材分组 + * @param req 订单、房间及柜体筛选条件 + * @param unplanned 是否使用未排贴皮查询口径 + */ + private void fillGoodsOrderRelations(List goodsList, + VeneerManageGoodsPageReqVO req, + boolean unplanned) { + if (CollUtil.isEmpty(goodsList)) { + return; + } + List goodsIds = goodsList.stream() + .map(VeneerManageGoodsRespVO::getGoodsId) + .distinct() + .toList(); + List relations = unplanned + ? veneerManageMapper.selectUnplannedGoodsOrderRelationList(goodsIds, req) + : veneerManageMapper.selectGoodsOrderRelationList(goodsIds, req); + Map> relationMap = new HashMap<>(); + for (VeneerGoodsOrderRelationRespVO relation : relations) { + relationMap.computeIfAbsent(relation.getGoodsId(), key -> new ArrayList<>()) + .add(relation); + } + for (VeneerManageGoodsRespVO goods : goodsList) { + goods.setOrderIds(relationMap.getOrDefault(goods.getGoodsId(), List.of())); + } } @Override @@ -170,14 +205,14 @@ public class VeneerManageServiceImpl implements VeneerManageService { if (CollUtil.isEmpty(req.getGoodsIds())) { return List.of(); } - return veneerManageMapper.selectGoodsPlateList(req.getGoodsIds()); + return veneerManageMapper.selectGoodsPlateList(req); } @Override public UnplannedVeneerPlateDataRespVO getUnplannedPlateData(UnplannedVeneerPlateDataReqVO req) { boolean byOrder = CollUtil.isNotEmpty(req.getOrderIds()); boolean byGoods = CollUtil.isNotEmpty(req.getGoodsIds()); - if (byOrder == byGoods) { + if (!byOrder && !byGoods) { throw new ServiceException(VENEER_UNPLANNED_SCOPE_INVALID); } diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/veneer/VeneerDecomposeMapper.xml b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/veneer/VeneerDecomposeMapper.xml index 2c96a611c..6c90741aa 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/veneer/VeneerDecomposeMapper.xml +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/veneer/VeneerDecomposeMapper.xml @@ -31,6 +31,24 @@ FROM orders o WHERE o.deleted = false AND IFNULL(o.plate_num, 0) > IFNULL(o.decomposed_veneer_plate_num, 0) + + AND o.id IN + + #{orderId} + + + + AND EXISTS ( + SELECT 1 FROM order_goods og + WHERE og.order_id = o.id + AND og.deleted = false + AND og.plate_num > IFNULL(og.decomposed_veneer_plate_num, 0) + AND og.goods_id IN + + #{goodsId} + + ) + AND CAST(o.id AS CHAR) LIKE CONCAT('%', #{req.orderId}, '%') @@ -82,6 +100,24 @@ FROM orders o WHERE o.deleted = false AND IFNULL(o.plate_num, 0) > IFNULL(o.decomposed_veneer_plate_num, 0) + + AND o.id IN + + #{orderId} + + + + AND EXISTS ( + SELECT 1 FROM order_goods og + WHERE og.order_id = o.id + AND og.deleted = false + AND og.plate_num > IFNULL(og.decomposed_veneer_plate_num, 0) + AND og.goods_id IN + + #{goodsId} + + ) + AND o.parent_id IN #{id} @@ -110,14 +146,57 @@ og.material, og.color, og.thickness, + + + COUNT(op.id) AS num, + SUM(op.area) AS area + + SUM(og.plate_num) AS num, SUM(og.area) AS area + + FROM orders o JOIN order_goods og ON og.order_id = o.id + + JOIN order_plate op ON op.order_id = og.order_id + AND op.goods_id = og.id + AND op.deleted = false + AND op.is_decomposed = false + WHERE o.deleted = false AND o.status IN (1, 2, 3) AND og.deleted = false AND og.plate_num > IFNULL(og.decomposed_veneer_plate_num, 0) + + AND og.order_id IN + + #{orderId} + + + + AND EXISTS ( + SELECT 1 FROM order_item oi + WHERE oi.order_id = op.order_id + AND oi.plate_id = op.id + AND oi.plate_id != 0 + + AND oi.room_id IN + + #{roomId} + + + + AND oi.body_id IN + + #{bodyId} + + + ) + AND og.goods_name LIKE CONCAT('%', #{req.goodsName}, '%') @@ -137,6 +216,59 @@ ORDER BY og.thickness DESC + + @@ -233,6 +365,12 @@ #{orderId} + + AND og.goods_id IN + + #{goodsId} + + AND oi.room_id IN @@ -270,6 +408,24 @@ #{goodsId} + + AND op.order_id IN + + #{orderId} + + + + AND oi.room_id IN + + #{roomId} + + + + AND oi.body_id IN + + #{bodyId} + + ORDER BY op.id DESC, oi.group_id diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/veneer/VeneerManageMapper.xml b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/veneer/VeneerManageMapper.xml index fec2dd7ac..4db12285a 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/veneer/VeneerManageMapper.xml +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/veneer/VeneerManageMapper.xml @@ -58,6 +58,28 @@ WHERE o.deleted = false AND IFNULL(o.decomposed_veneer_plate_num, 0) > IFNULL(o.planned_veneer_plate_num, 0) + + AND o.id IN + + #{orderId} + + + + AND EXISTS ( + SELECT 1 + FROM order_plate_veneer opv + JOIN order_goods og ON og.order_id = opv.order_id + AND og.id = opv.order_goods_id + WHERE opv.order_id = o.id + AND opv.deleted = false + AND opv.plan_id = 0 + AND og.deleted = false + AND og.goods_id IN + + #{goodsId} + + ) + AND CAST(o.id AS CHAR) LIKE CONCAT('%', #{req.orderId}, '%') @@ -113,6 +135,28 @@ WHERE o.deleted = false AND IFNULL(o.decomposed_veneer_plate_num, 0) > IFNULL(o.planned_veneer_plate_num, 0) + + AND o.id IN + + #{orderId} + + + + AND EXISTS ( + SELECT 1 + FROM order_plate_veneer opv + JOIN order_goods og ON og.order_id = opv.order_id + AND og.id = opv.order_goods_id + WHERE opv.order_id = o.id + AND opv.deleted = false + AND opv.plan_id = 0 + AND og.deleted = false + AND og.goods_id IN + + #{goodsId} + + ) + AND o.parent_id IN #{id} @@ -138,21 +182,108 @@ ORDER BY o.id DESC + + AND EXISTS ( + SELECT 1 + FROM order_plate_veneer opv + WHERE opv.order_id = og.order_id + AND opv.order_goods_id = og.id + AND opv.deleted = false + AND opv.plan_id = 0 + + AND EXISTS ( + SELECT 1 FROM order_item oi + WHERE oi.order_id = opv.order_id + AND oi.plate_id = opv.order_plate_id + AND oi.plate_id != 0 + + AND oi.room_id IN + + #{roomId} + + + + AND oi.body_id IN + + #{bodyId} + + + ) + + ) + + + + + AND EXISTS ( + SELECT 1 FROM order_plate_veneer opv + WHERE opv.order_id = op.order_id + AND opv.order_goods_id = og.id + AND opv.order_plate_id = op.id + AND opv.deleted = false + AND opv.plan_id = 0 + ) + AND EXISTS ( + SELECT 1 FROM order_item oi + WHERE oi.order_id = op.order_id + AND oi.plate_id = op.id + AND oi.plate_id != 0 + + AND oi.room_id IN + + #{roomId} + + + + AND oi.body_id IN + + #{bodyId} + + + ) + + + + + + + @@ -454,20 +731,18 @@ AND opv.plan_id = 0 AND op.deleted = false AND og.deleted = false - - - AND opv.order_id IN - - #{orderId} - - - - AND og.goods_id IN - - #{goodsId} - - - + + AND opv.order_id IN + + #{orderId} + + + + AND og.goods_id IN + + #{goodsId} + + AND opv.veneer_no LIKE CONCAT('%', #{req.veneerNo}, '%') diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_cht.properties b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_cht.properties index 5dd0defe2..efb619f32 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_cht.properties +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_cht.properties @@ -85,7 +85,7 @@ veneer.reselect.source.required=請選擇新的貼皮 veneer.reselect.record.status.changed=板件貼皮資料狀態已變更,請重新整理後再試 veneer.remove.record.required=請選擇需要移除的貼皮資料 veneer.remove.record.status.changed=所選貼皮資料已刪除、已排單或狀態發生變化,請重新整理後再試 -veneer.unplanned.scope.invalid=訂單ID列表和板材商品編碼列表必須且只能傳入一項 +veneer.unplanned.scope.invalid=訂單ID列表和板材商品編碼列表至少傳入一項 veneer.plan.record.required=請選擇需要排單的貼皮資料 veneer.plan.record.status.changed=所選貼皮資料已排單、已刪除或狀態發生變化,請重新整理後再試 veneer.plan.area.data.invalid=貼皮記錄{0}的面積資料異常,無法建立貼皮排單 diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_en.properties b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_en.properties index a429c14e5..c43d9d626 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_en.properties +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_en.properties @@ -85,7 +85,7 @@ veneer.reselect.source.required=Please select a new veneer veneer.reselect.record.status.changed=Plate veneer data has changed. Please refresh and retry veneer.remove.record.required=Please select veneer records to remove veneer.remove.record.status.changed=The selected veneer data has been removed, scheduled, or changed. Please refresh and retry -veneer.unplanned.scope.invalid=Exactly one of the order ID list and goods code list must be provided +veneer.unplanned.scope.invalid=At least one of the order ID list and goods code list must be provided veneer.plan.record.required=Please select veneer records to schedule veneer.plan.record.status.changed=The selected veneer data has been scheduled, removed, or changed. Please refresh and retry veneer.plan.area.data.invalid=Veneer record {0} has invalid area data and cannot create a veneer plan diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_zh.properties b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_zh.properties index 480a7ff20..d0f9ac238 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_zh.properties +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/message_errorcode_zh.properties @@ -85,7 +85,7 @@ veneer.reselect.source.required=请选择新的贴皮 veneer.reselect.record.status.changed=板件贴皮数据状态已变更,请刷新后重试 veneer.remove.record.required=请选择需要移除的贴皮数据 veneer.remove.record.status.changed=所选贴皮数据已删除、已排单或状态发生变化,请刷新后重试 -veneer.unplanned.scope.invalid=订单ID列表和板材商品编码列表必须且只能传入一项 +veneer.unplanned.scope.invalid=订单ID列表和板材商品编码列表至少传入一项 veneer.plan.record.required=请选择需要排单的贴皮数据 veneer.plan.record.status.changed=所选贴皮数据已排单、已删除或状态发生变化,请刷新后重试 veneer.plan.area.data.invalid=贴皮记录{0}的面积数据异常,无法创建贴皮排单 diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/producing/ProducingOrderClient.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/producing/ProducingOrderClient.java index b999c2d0c..d63ffbc78 100644 --- a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/producing/ProducingOrderClient.java +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/producing/ProducingOrderClient.java @@ -34,11 +34,6 @@ import static com.cf.imes.module.plan.enums.ErrorCodeConstants.PRODUCING_ORDER_S @Slf4j public class ProducingOrderClient { - /** - * 外部接口报文的最大日志长度,避免批量序列号同步失败时输出过大的日志。 - */ - private static final int MAX_LOG_PAYLOAD_LENGTH = 16_384; - private final ProducingOrderImportProperties properties; private final ObjectMapper objectMapper; private final HttpClient httpClient; @@ -71,15 +66,19 @@ public class ProducingOrderClient { int maxAttempts = Math.max(1, properties.getNetworkRetryTimes() + 1); IOException lastNetworkError = null; for (int attempt = 1; attempt <= maxAttempts; attempt++) { + long startedAt = System.nanoTime(); HttpRequest request = HttpRequest.newBuilder(uri) .timeout(properties.getReadTimeout()) .header("Authorization", "Bearer " + token) .header("Accept", "application/json") .GET() .build(); + logComponentRequest("pull-order", "GET", uri, attempt, maxAttempts, null); try { HttpResponse response = httpClient.send( request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); + logComponentResponse("pull-order", "GET", uri, attempt, maxAttempts, + response.statusCode(), elapsedMillis(startedAt), response.body()); if (response.statusCode() < 200 || response.statusCode() >= 300) { throw new ServiceException(PRODUCING_ORDER_PULL_FAILED, "HTTP " + response.statusCode()); @@ -96,13 +95,13 @@ public class ProducingOrderClient { "invalid JSON response"); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); + logComponentFailure("pull-order", "GET", uri, attempt, maxAttempts, + elapsedMillis(startedAt), "request interrupted", ex); throw new ServiceException(PRODUCING_ORDER_PULL_FAILED, "request interrupted"); } catch (IOException ex) { lastNetworkError = ex; - if (attempt < maxAttempts) { - log.warn("Pull producing order {} failed on attempt {}, retrying", - orderId, attempt, ex); - } + logComponentFailure("pull-order", "GET", uri, attempt, maxAttempts, + elapsedMillis(startedAt), ex.getMessage(), ex); } } String message = lastNetworkError == null ? "network error" : lastNetworkError.getMessage(); @@ -123,8 +122,9 @@ public class ProducingOrderClient { ProducingOrderExtraSyncRequest request) { String encodedOrderId = URLEncoder.encode(orderId, StandardCharsets.UTF_8); URI uri = URI.create(properties.getOrderExtraUrl().replace("{id}", encodedOrderId)); + String requestBody = serializeSyncRequest(request, uri); HttpResponse response = sendPut( - uri, token, serializeSyncRequest(request), "order-extra"); + uri, token, requestBody, "order-extra"); if (!StringUtils.hasText(response.body())) { throw new ServiceException(PRODUCING_ORDER_SYNC_FAILED, "order-extra: empty response"); @@ -147,10 +147,13 @@ public class ProducingOrderClient { /** * 序列化反向同步请求。 */ - private String serializeSyncRequest(Object request) { + private String serializeSyncRequest(Object request, URI uri) { try { return objectMapper.writeValueAsString(request); } catch (JsonProcessingException ex) { + log.error("[producing-order-http-result] operation=order-extra method=PUT uri={} " + + "status=SERIALIZE_ERROR requestBody={} result={}", + uri, request, ex.getMessage(), ex); throw new ServiceException(PRODUCING_ORDER_SYNC_FAILED, "cannot serialize request"); } @@ -176,49 +179,30 @@ public class ProducingOrderClient { IOException lastNetworkError = null; for (int attempt = 1; attempt <= maxAttempts; attempt++) { long startedAt = System.nanoTime(); - log.info("[producing-order-http] operation={} method=PUT uri={} attempt={}/{} requestBytes={}", - operation, uri, attempt, maxAttempts, utf8Length(body)); - log.debug("[producing-order-http-request] operation={} uri={} body={}", - operation, uri, logPayload(body)); + logComponentRequest(operation, "PUT", uri, attempt, maxAttempts, body); try { HttpResponse response = httpClient.send( request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); long elapsedMs = elapsedMillis(startedAt); String responseBody = response.body(); + logComponentResponse(operation, "PUT", uri, attempt, maxAttempts, + response.statusCode(), elapsedMs, responseBody); if (response.statusCode() < 200 || response.statusCode() >= 300) { - log.error("[producing-order-http-error] operation={} method=PUT uri={} " - + "attempt={}/{} status={} elapsedMs={} requestBody={} responseBody={}", - operation, uri, attempt, maxAttempts, response.statusCode(), elapsedMs, - logPayload(body), logPayload(responseBody)); throw new ServiceException(PRODUCING_ORDER_SYNC_FAILED, operation + ": HTTP " + response.statusCode() - + ", response=" + logPayload(responseBody)); + + ", response=" + payload(responseBody)); } - log.info("[producing-order-http] operation={} method=PUT uri={} attempt={}/{} " - + "status={} elapsedMs={} responseBytes={}", - operation, uri, attempt, maxAttempts, response.statusCode(), elapsedMs, - utf8Length(responseBody)); - log.debug("[producing-order-http-response] operation={} uri={} body={}", - operation, uri, logPayload(responseBody)); return response; } catch (InterruptedException ex) { Thread.currentThread().interrupt(); - log.error("[producing-order-http-error] operation={} method=PUT uri={} " - + "attempt={}/{} elapsedMs={} error=request-interrupted", - operation, uri, attempt, maxAttempts, elapsedMillis(startedAt)); + logComponentFailure(operation, "PUT", uri, attempt, maxAttempts, + elapsedMillis(startedAt), "request interrupted", ex); throw new ServiceException(PRODUCING_ORDER_SYNC_FAILED, operation + ": request interrupted"); } catch (IOException ex) { lastNetworkError = ex; - if (attempt < maxAttempts) { - log.warn("[producing-order-http-error] operation={} method=PUT uri={} " - + "attempt={}/{} elapsedMs={} retry=true", - operation, uri, attempt, maxAttempts, elapsedMillis(startedAt), ex); - } else { - log.error("[producing-order-http-error] operation={} method=PUT uri={} " - + "attempt={}/{} elapsedMs={} retry=false", - operation, uri, attempt, maxAttempts, elapsedMillis(startedAt), ex); - } + logComponentFailure(operation, "PUT", uri, attempt, maxAttempts, + elapsedMillis(startedAt), ex.getMessage(), ex); } } String message = lastNetworkError == null @@ -228,17 +212,67 @@ public class ProducingOrderClient { } /** - * 将外部接口报文限制在可控的日志长度内;空响应使用明确占位符表示。 + * 输出组件接口的完整请求信息,不记录 Authorization 请求头。 */ - private String logPayload(String payload) { + private void logComponentRequest(String operation, + String method, + URI uri, + int attempt, + int maxAttempts, + String requestBody) { + log.info("[producing-order-http-request] operation={} method={} uri={} attempt={}/{} " + + "requestBytes={} requestBody={}", + operation, method, uri, attempt, maxAttempts, + utf8Length(requestBody), payload(requestBody)); + } + + /** + * 输出组件接口的完整 HTTP 响应,非 2xx 响应使用 ERROR 级别。 + */ + private void logComponentResponse(String operation, + String method, + URI uri, + int attempt, + int maxAttempts, + int status, + long elapsedMs, + String responseBody) { + if (status >= 200 && status < 300) { + log.info("[producing-order-http-result] operation={} method={} uri={} attempt={}/{} " + + "status={} elapsedMs={} responseBytes={} result={}", + operation, method, uri, attempt, maxAttempts, status, elapsedMs, + utf8Length(responseBody), payload(responseBody)); + return; + } + log.error("[producing-order-http-result] operation={} method={} uri={} attempt={}/{} " + + "status={} elapsedMs={} responseBytes={} result={}", + operation, method, uri, attempt, maxAttempts, status, elapsedMs, + utf8Length(responseBody), payload(responseBody)); + } + + /** + * 输出没有取得 HTTP 响应时的完整失败结果。 + */ + private void logComponentFailure(String operation, + String method, + URI uri, + int attempt, + int maxAttempts, + long elapsedMs, + String result, + Exception exception) { + log.error("[producing-order-http-result] operation={} method={} uri={} attempt={}/{} " + + "status=NETWORK_ERROR elapsedMs={} result={}", + operation, method, uri, attempt, maxAttempts, elapsedMs, + payload(result), exception); + } + + /** 空报文使用明确占位符,非空报文完整输出。 */ + private String payload(String payload) { if (!StringUtils.hasText(payload)) { return ""; } - if (payload.length() <= MAX_LOG_PAYLOAD_LENGTH) { - return payload; - } - return payload.substring(0, MAX_LOG_PAYLOAD_LENGTH) - + "..."; + return payload; } /**