1、增加组件接口调用日志;2、贴皮分解、贴皮管理、未排贴皮适配orderPage和goodsPage的相互调用模式;

This commit is contained in:
gaoqr
2026-08-04 14:12:04 +08:00
parent 4ebdd20826
commit 147e1529ea
21 changed files with 716 additions and 83 deletions
@@ -65,7 +65,7 @@ public class UnplannedVeneerController {
/** /**
* 按订单或板材查询未排贴皮、原板件及板件造型数据。 * 按订单或板材查询未排贴皮、原板件及板件造型数据。
* *
* @param req 互斥查询范围及可选房间、柜体条件 * @param req 订单和/或板材查询范围及可选房间、柜体条件
* @return 未排贴皮排单基础数据 * @return 未排贴皮排单基础数据
*/ */
@PostMapping("/plate/data") @PostMapping("/plate/data")
@@ -14,10 +14,10 @@ import java.util.List;
@Data @Data
public class UnplannedVeneerPlateDataReqVO { public class UnplannedVeneerPlateDataReqVO {
@Schema(description = "订单ID列表,与板材商品编码列表互斥") @Schema(description = "订单ID列表,与板材商品编码列表至少传入一项")
private List<Long> orderIds; private List<Long> orderIds;
@Schema(description = "板材商品编码列表,与订单ID列表互斥") @Schema(description = "板材商品编码列表,与订单ID列表至少传入一项")
private List<String> goodsIds; private List<String> goodsIds;
@Schema(description = "房间ID列表") @Schema(description = "房间ID列表")
@@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List;
/** /**
* 贴皮分解材质分页查询请求参数。 * 贴皮分解材质分页查询请求参数。
@@ -12,6 +13,15 @@ import java.math.BigDecimal;
@Data @Data
public class VeneerDecomposeGoodsPageReqVO extends PageParam { public class VeneerDecomposeGoodsPageReqVO extends PageParam {
@Schema(description = "订单ID列表")
private List<Long> orderIds;
@Schema(description = "房间ID列表")
private List<Long> roomIds;
@Schema(description = "柜体ID列表")
private List<Long> bodyIds;
@Schema(description = "板材名称") @Schema(description = "板材名称")
private String goodsName; private String goodsName;
@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List;
/** /**
* 贴皮分解板材分页响应参数。 * 贴皮分解板材分页响应参数。
@@ -11,6 +12,9 @@ import java.math.BigDecimal;
@Data @Data
public class VeneerDecomposeGoodsRespVO { public class VeneerDecomposeGoodsRespVO {
@Schema(description = "当前板材分组关联的订单")
private List<VeneerGoodsOrderRelationRespVO> orderIds;
@Schema(description = "板材名称") @Schema(description = "板材名称")
private String goodsName; private String goodsName;
@@ -6,6 +6,7 @@ import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List;
import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; 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 @Data
public class VeneerDecomposeOrderPageReqVO extends PageParam { public class VeneerDecomposeOrderPageReqVO extends PageParam {
@Schema(description = "精确限定的订单ID列表")
private List<Long> orderIds;
@Schema(description = "板材商品编码列表")
private List<String> goodsIds;
@Schema(description = "订单号") @Schema(description = "订单号")
private String orderId; private String orderId;
@@ -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;
}
@@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List;
/** /**
* 贴皮管理板材分页查询请求参数。 * 贴皮管理板材分页查询请求参数。
@@ -12,6 +13,15 @@ import java.math.BigDecimal;
@Data @Data
public class VeneerManageGoodsPageReqVO extends PageParam { public class VeneerManageGoodsPageReqVO extends PageParam {
@Schema(description = "订单ID列表")
private List<Long> orderIds;
@Schema(description = "房间ID列表")
private List<Long> roomIds;
@Schema(description = "柜体ID列表")
private List<Long> bodyIds;
@Schema(description = "板材名称") @Schema(description = "板材名称")
private String goodsName; private String goodsName;
@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List;
/** /**
* 贴皮管理板材分页响应参数。 * 贴皮管理板材分页响应参数。
@@ -11,6 +12,9 @@ import java.math.BigDecimal;
@Data @Data
public class VeneerManageGoodsRespVO { public class VeneerManageGoodsRespVO {
@Schema(description = "当前板材分组关联的订单")
private List<VeneerGoodsOrderRelationRespVO> orderIds;
@Schema(description = "板材名称") @Schema(description = "板材名称")
private String goodsName; private String goodsName;
@@ -6,6 +6,7 @@ import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List;
import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; 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 @Data
public class VeneerManageOrderPageReqVO extends PageParam { public class VeneerManageOrderPageReqVO extends PageParam {
@Schema(description = "精确限定的订单ID列表")
private List<Long> orderIds;
@Schema(description = "板材商品编码列表")
private List<String> goodsIds;
@Schema(description = "订单号") @Schema(description = "订单号")
private String orderId; private String orderId;
@@ -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.VeneerDecomposeOrderRespVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposePlatePageReqVO; 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.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.plate.PlateDO;
import com.cf.imes.module.executor.dal.dataobject.veneer.VeneerDecomposedPlateCountDO; import com.cf.imes.module.executor.dal.dataobject.veneer.VeneerDecomposedPlateCountDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@@ -67,6 +68,17 @@ public interface VeneerDecomposeMapper {
IPage<VeneerDecomposeGoodsRespVO> selectGoodsPage(@Param("page") IPage<VeneerDecomposeGoodsRespVO> page, IPage<VeneerDecomposeGoodsRespVO> selectGoodsPage(@Param("page") IPage<VeneerDecomposeGoodsRespVO> page,
@Param("req") VeneerDecomposeGoodsPageReqVO req); @Param("req") VeneerDecomposeGoodsPageReqVO req);
/**
* 查询当前页板材分组关联的订单。
*
* @param goodsIds 当前页板材商品编码
* @param req 订单、房间及柜体筛选条件
* @return 板材与订单关系
*/
List<VeneerGoodsOrderRelationRespVO> selectGoodsOrderRelationList(
@Param("goodsIds") List<String> goodsIds,
@Param("req") VeneerDecomposeGoodsPageReqVO req);
/** /**
* 按订单查询未贴皮分解板件原始列表。 * 按订单查询未贴皮分解板件原始列表。
* 同一板件可能因多个加工组返回多条记录,由 Service 层按板件主键去重。 * 同一板件可能因多个加工组返回多条记录,由 Service 层按板件主键去重。
@@ -3,6 +3,7 @@ package com.cf.imes.module.executor.dal.mysql.veneer;
import com.baomidou.mybatisplus.core.metadata.IPage; 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.UnplannedVeneerPlateDataReqVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.UnplannedVeneerPlateRespVO; 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.VeneerManageGoodsPageReqVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageGoodsRespVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageGoodsRespVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageOrderPageReqVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageOrderPageReqVO;
@@ -67,6 +68,17 @@ public interface VeneerManageMapper {
IPage<VeneerManageGoodsRespVO> selectGoodsPage(@Param("page") IPage<VeneerManageGoodsRespVO> page, IPage<VeneerManageGoodsRespVO> selectGoodsPage(@Param("page") IPage<VeneerManageGoodsRespVO> page,
@Param("req") VeneerManageGoodsPageReqVO req); @Param("req") VeneerManageGoodsPageReqVO req);
/**
* 查询当前页贴皮管理板材分组关联的订单。
*
* @param goodsIds 当前页板材商品编码
* @param req 订单、房间及柜体筛选条件
* @return 板材与订单关系
*/
List<VeneerGoodsOrderRelationRespVO> selectGoodsOrderRelationList(
@Param("goodsIds") List<String> goodsIds,
@Param("req") VeneerManageGoodsPageReqVO req);
/** /**
* 分页查询存在待排单贴皮的根订单ID。 * 分页查询存在待排单贴皮的根订单ID。
* *
@@ -104,6 +116,17 @@ public interface VeneerManageMapper {
@Param("page") IPage<VeneerManageGoodsRespVO> page, @Param("page") IPage<VeneerManageGoodsRespVO> page,
@Param("req") VeneerManageGoodsPageReqVO req); @Param("req") VeneerManageGoodsPageReqVO req);
/**
* 查询当前页未排贴皮板材分组关联的订单。
*
* @param goodsIds 当前页板材商品编码
* @param req 订单、房间及柜体筛选条件
* @return 板材与订单关系
*/
List<VeneerGoodsOrderRelationRespVO> selectUnplannedGoodsOrderRelationList(
@Param("goodsIds") List<String> goodsIds,
@Param("req") VeneerManageGoodsPageReqVO req);
/** /**
* 按订单查询可维护的未排单板件贴皮列表。 * 按订单查询可维护的未排单板件贴皮列表。
* *
@@ -115,13 +138,14 @@ public interface VeneerManageMapper {
/** /**
* 按板材商品编码查询可维护的未排单板件贴皮列表。 * 按板材商品编码查询可维护的未排单板件贴皮列表。
* *
* @param goodsIds 板材商品编码列表 * @param req 订单、板材、房间及柜体查询条件
* @return 未排单板件贴皮列表 * @return 未排单板件贴皮列表
*/ */
List<VeneerManagePlateRespVO> selectGoodsPlateList(@Param("goodsIds") List<String> goodsIds); List<VeneerManagePlateRespVO> selectGoodsPlateList(
@Param("req") VeneerManagePlateListReqVO req);
/** /**
* 按互斥业务范围查询待排单贴皮及其原板件信息。 * 按订单和/或板材范围查询待排单贴皮及其原板件信息。
* 同一贴皮可能因多个加工组返回多条,由 Service 层合并。 * 同一贴皮可能因多个加工组返回多条,由 Service 层合并。
* *
* @param req 订单或板材范围及房间、柜体筛选条件 * @param req 订单或板材范围及房间、柜体筛选条件
@@ -115,6 +115,8 @@ public class ProducingPlanOrderClient {
private HttpResponse<String> send(String url, String token, String method, private HttpResponse<String> send(String url, String token, String method,
String body, String operation) { 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.BodyPublisher publisher = body == null
? HttpRequest.BodyPublishers.noBody() ? HttpRequest.BodyPublishers.noBody()
: HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8); : HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8);
@@ -128,6 +130,10 @@ public class ProducingPlanOrderClient {
try { try {
HttpResponse<String> response = httpClient.send( HttpResponse<String> response = httpClient.send(
request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); 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) { if (response.statusCode() < 200 || response.statusCode() >= 300) {
logRequestFailure(operation, method, url, body, logRequestFailure(operation, method, url, body,
response.statusCode(), response.body(), null); response.statusCode(), response.body(), null);
@@ -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.VeneerDecomposePlateDataRespVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposePlatePageReqVO; 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.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.goods.GoodsDO;
import com.cf.imes.module.executor.dal.dataobject.order.OrderDO; import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
import com.cf.imes.module.executor.dal.dataobject.ordermodel.OrderModelDO; import com.cf.imes.module.executor.dal.dataobject.ordermodel.OrderModelDO;
@@ -151,7 +152,35 @@ public class VeneerDecomposeServiceImpl implements VeneerDecomposeService {
public PageResult<VeneerDecomposeGoodsRespVO> getGoodsPage(VeneerDecomposeGoodsPageReqVO req) { public PageResult<VeneerDecomposeGoodsRespVO> getGoodsPage(VeneerDecomposeGoodsPageReqVO req) {
IPage<VeneerDecomposeGoodsRespVO> result = veneerDecomposeMapper.selectGoodsPage( IPage<VeneerDecomposeGoodsRespVO> result = veneerDecomposeMapper.selectGoodsPage(
new PageDTO<>(req.getPageNo(), req.getPageSize()), req); new PageDTO<>(req.getPageNo(), req.getPageSize()), req);
return new PageResult<>(result.getRecords(), result.getTotal()); List<VeneerDecomposeGoodsRespVO> goodsList = result.getRecords();
if (CollUtil.isNotEmpty(goodsList)) {
List<String> 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<VeneerDecomposeGoodsRespVO> goodsList,
List<VeneerGoodsOrderRelationRespVO> relations) {
Map<String, List<VeneerGoodsOrderRelationRespVO>> 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 @Override
@@ -70,7 +70,7 @@ public interface VeneerManageService {
/** /**
* 按订单或板材查询未排贴皮、原板件及板件造型数据。 * 按订单或板材查询未排贴皮、原板件及板件造型数据。
* *
* @param req 互斥查询范围及可选房间、柜体条件 * @param req 订单和/或板材范围及可选房间、柜体条件
* @return 未排贴皮排单基础数据 * @return 未排贴皮排单基础数据
*/ */
UnplannedVeneerPlateDataRespVO getUnplannedPlateData(UnplannedVeneerPlateDataReqVO req); UnplannedVeneerPlateDataRespVO getUnplannedPlateData(UnplannedVeneerPlateDataReqVO req);
@@ -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.UnplannedVeneerPlateDataReqVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.UnplannedVeneerPlateDataRespVO; 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.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.VeneerManageGoodsPageReqVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageGoodsRespVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageGoodsRespVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageOrderPageReqVO; import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageOrderPageReqVO;
@@ -110,7 +111,9 @@ public class VeneerManageServiceImpl implements VeneerManageService {
public PageResult<VeneerManageGoodsRespVO> getGoodsPage(VeneerManageGoodsPageReqVO req) { public PageResult<VeneerManageGoodsRespVO> getGoodsPage(VeneerManageGoodsPageReqVO req) {
IPage<VeneerManageGoodsRespVO> result = veneerManageMapper.selectGoodsPage( IPage<VeneerManageGoodsRespVO> result = veneerManageMapper.selectGoodsPage(
new PageDTO<>(req.getPageNo(), req.getPageSize()), req); new PageDTO<>(req.getPageNo(), req.getPageSize()), req);
return new PageResult<>(result.getRecords(), result.getTotal()); List<VeneerManageGoodsRespVO> goodsList = result.getRecords();
fillGoodsOrderRelations(goodsList, req, false);
return new PageResult<>(goodsList, result.getTotal());
} }
@Override @Override
@@ -154,7 +157,39 @@ public class VeneerManageServiceImpl implements VeneerManageService {
public PageResult<VeneerManageGoodsRespVO> getUnplannedGoodsPage(VeneerManageGoodsPageReqVO req) { public PageResult<VeneerManageGoodsRespVO> getUnplannedGoodsPage(VeneerManageGoodsPageReqVO req) {
IPage<VeneerManageGoodsRespVO> result = veneerManageMapper.selectUnplannedGoodsPage( IPage<VeneerManageGoodsRespVO> result = veneerManageMapper.selectUnplannedGoodsPage(
new PageDTO<>(req.getPageNo(), req.getPageSize()), req); new PageDTO<>(req.getPageNo(), req.getPageSize()), req);
return new PageResult<>(result.getRecords(), result.getTotal()); List<VeneerManageGoodsRespVO> goodsList = result.getRecords();
fillGoodsOrderRelations(goodsList, req, true);
return new PageResult<>(goodsList, result.getTotal());
}
/**
* 查询并回填当前页板材分组关联的订单。
*
* @param goodsList 当前页板材分组
* @param req 订单、房间及柜体筛选条件
* @param unplanned 是否使用未排贴皮查询口径
*/
private void fillGoodsOrderRelations(List<VeneerManageGoodsRespVO> goodsList,
VeneerManageGoodsPageReqVO req,
boolean unplanned) {
if (CollUtil.isEmpty(goodsList)) {
return;
}
List<String> goodsIds = goodsList.stream()
.map(VeneerManageGoodsRespVO::getGoodsId)
.distinct()
.toList();
List<VeneerGoodsOrderRelationRespVO> relations = unplanned
? veneerManageMapper.selectUnplannedGoodsOrderRelationList(goodsIds, req)
: veneerManageMapper.selectGoodsOrderRelationList(goodsIds, req);
Map<String, List<VeneerGoodsOrderRelationRespVO>> 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 @Override
@@ -170,14 +205,14 @@ public class VeneerManageServiceImpl implements VeneerManageService {
if (CollUtil.isEmpty(req.getGoodsIds())) { if (CollUtil.isEmpty(req.getGoodsIds())) {
return List.of(); return List.of();
} }
return veneerManageMapper.selectGoodsPlateList(req.getGoodsIds()); return veneerManageMapper.selectGoodsPlateList(req);
} }
@Override @Override
public UnplannedVeneerPlateDataRespVO getUnplannedPlateData(UnplannedVeneerPlateDataReqVO req) { public UnplannedVeneerPlateDataRespVO getUnplannedPlateData(UnplannedVeneerPlateDataReqVO req) {
boolean byOrder = CollUtil.isNotEmpty(req.getOrderIds()); boolean byOrder = CollUtil.isNotEmpty(req.getOrderIds());
boolean byGoods = CollUtil.isNotEmpty(req.getGoodsIds()); boolean byGoods = CollUtil.isNotEmpty(req.getGoodsIds());
if (byOrder == byGoods) { if (!byOrder && !byGoods) {
throw new ServiceException(VENEER_UNPLANNED_SCOPE_INVALID); throw new ServiceException(VENEER_UNPLANNED_SCOPE_INVALID);
} }
@@ -31,6 +31,24 @@
FROM orders o FROM orders o
WHERE o.deleted = false WHERE o.deleted = false
AND IFNULL(o.plate_num, 0) &gt; IFNULL(o.decomposed_veneer_plate_num, 0) AND IFNULL(o.plate_num, 0) &gt; IFNULL(o.decomposed_veneer_plate_num, 0)
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND o.id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
<if test="req.goodsIds != null and req.goodsIds.size() > 0">
AND EXISTS (
SELECT 1 FROM order_goods og
WHERE og.order_id = o.id
AND og.deleted = false
AND og.plate_num &gt; IFNULL(og.decomposed_veneer_plate_num, 0)
AND og.goods_id IN
<foreach collection="req.goodsIds" item="goodsId" open="(" close=")" separator=",">
#{goodsId}
</foreach>
)
</if>
<if test="req.orderId != null and req.orderId != ''"> <if test="req.orderId != null and req.orderId != ''">
AND CAST(o.id AS CHAR) LIKE CONCAT('%', #{req.orderId}, '%') AND CAST(o.id AS CHAR) LIKE CONCAT('%', #{req.orderId}, '%')
</if> </if>
@@ -82,6 +100,24 @@
FROM orders o FROM orders o
WHERE o.deleted = false WHERE o.deleted = false
AND IFNULL(o.plate_num, 0) &gt; IFNULL(o.decomposed_veneer_plate_num, 0) AND IFNULL(o.plate_num, 0) &gt; IFNULL(o.decomposed_veneer_plate_num, 0)
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND o.id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
<if test="req.goodsIds != null and req.goodsIds.size() > 0">
AND EXISTS (
SELECT 1 FROM order_goods og
WHERE og.order_id = o.id
AND og.deleted = false
AND og.plate_num &gt; IFNULL(og.decomposed_veneer_plate_num, 0)
AND og.goods_id IN
<foreach collection="req.goodsIds" item="goodsId" open="(" close=")" separator=",">
#{goodsId}
</foreach>
)
</if>
AND o.parent_id IN AND o.parent_id IN
<foreach collection="rootIds" item="id" open="(" close=")" separator=","> <foreach collection="rootIds" item="id" open="(" close=")" separator=",">
#{id} #{id}
@@ -110,14 +146,57 @@
og.material, og.material,
og.color, og.color,
og.thickness, og.thickness,
<choose>
<when test="(req.roomIds != null and req.roomIds.size() > 0)
or (req.bodyIds != null and req.bodyIds.size() > 0)">
COUNT(op.id) AS num,
SUM(op.area) AS area
</when>
<otherwise>
SUM(og.plate_num) AS num, SUM(og.plate_num) AS num,
SUM(og.area) AS area SUM(og.area) AS area
</otherwise>
</choose>
FROM orders o FROM orders o
JOIN order_goods og ON og.order_id = o.id JOIN order_goods og ON og.order_id = o.id
<if test="(req.roomIds != null and req.roomIds.size() > 0)
or (req.bodyIds != null and req.bodyIds.size() > 0)">
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
</if>
WHERE o.deleted = false WHERE o.deleted = false
AND o.status IN (1, 2, 3) AND o.status IN (1, 2, 3)
AND og.deleted = false AND og.deleted = false
AND og.plate_num &gt; IFNULL(og.decomposed_veneer_plate_num, 0) AND og.plate_num &gt; IFNULL(og.decomposed_veneer_plate_num, 0)
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND og.order_id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
<if test="(req.roomIds != null and req.roomIds.size() > 0)
or (req.bodyIds != null and req.bodyIds.size() > 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
<if test="req.roomIds != null and req.roomIds.size() > 0">
AND oi.room_id IN
<foreach collection="req.roomIds" item="roomId" open="(" close=")" separator=",">
#{roomId}
</foreach>
</if>
<if test="req.bodyIds != null and req.bodyIds.size() > 0">
AND oi.body_id IN
<foreach collection="req.bodyIds" item="bodyId" open="(" close=")" separator=",">
#{bodyId}
</foreach>
</if>
)
</if>
<if test="req.goodsName != null and req.goodsName != ''"> <if test="req.goodsName != null and req.goodsName != ''">
AND og.goods_name LIKE CONCAT('%', #{req.goodsName}, '%') AND og.goods_name LIKE CONCAT('%', #{req.goodsName}, '%')
</if> </if>
@@ -137,6 +216,59 @@
ORDER BY og.thickness DESC ORDER BY og.thickness DESC
</select> </select>
<select id="selectGoodsOrderRelationList"
resultType="com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerGoodsOrderRelationRespVO">
SELECT DISTINCT og.goods_id AS goodsId,
og.order_id AS orderId,
og.id AS orderGoodsId
FROM orders o
JOIN order_goods og ON og.order_id = o.id
WHERE o.deleted = false
AND o.status IN (1, 2, 3)
AND og.deleted = false
AND og.plate_num &gt; IFNULL(og.decomposed_veneer_plate_num, 0)
AND og.goods_id IN
<foreach collection="goodsIds" item="goodsId" open="(" close=")" separator=",">
#{goodsId}
</foreach>
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND og.order_id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
<if test="(req.roomIds != null and req.roomIds.size() > 0)
or (req.bodyIds != null and req.bodyIds.size() > 0)">
AND EXISTS (
SELECT 1
FROM order_plate op
WHERE op.order_id = og.order_id
AND op.goods_id = og.id
AND op.deleted = false
AND op.is_decomposed = false
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
<if test="req.roomIds != null and req.roomIds.size() > 0">
AND oi.room_id IN
<foreach collection="req.roomIds" item="roomId" open="(" close=")" separator=",">
#{roomId}
</foreach>
</if>
<if test="req.bodyIds != null and req.bodyIds.size() > 0">
AND oi.body_id IN
<foreach collection="req.bodyIds" item="bodyId" open="(" close=")" separator=",">
#{bodyId}
</foreach>
</if>
)
)
</if>
ORDER BY og.goods_id, og.order_id
</select>
<resultMap id="PlateMap" <resultMap id="PlateMap"
type="com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposePlateRespVO" type="com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposePlateRespVO"
autoMapping="true"> autoMapping="true">
@@ -233,6 +365,12 @@
#{orderId} #{orderId}
</foreach> </foreach>
</if> </if>
<if test="req.goodsIds != null and req.goodsIds.size() > 0">
AND og.goods_id IN
<foreach collection="req.goodsIds" item="goodsId" open="(" close=")" separator=",">
#{goodsId}
</foreach>
</if>
<if test="req.roomIds != null and req.roomIds.size() > 0"> <if test="req.roomIds != null and req.roomIds.size() > 0">
AND oi.room_id IN AND oi.room_id IN
<foreach collection="req.roomIds" item="roomId" open="(" close=")" separator=","> <foreach collection="req.roomIds" item="roomId" open="(" close=")" separator=",">
@@ -270,6 +408,24 @@
#{goodsId} #{goodsId}
</foreach> </foreach>
</if> </if>
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND op.order_id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
<if test="req.roomIds != null and req.roomIds.size() > 0">
AND oi.room_id IN
<foreach collection="req.roomIds" item="roomId" open="(" close=")" separator=",">
#{roomId}
</foreach>
</if>
<if test="req.bodyIds != null and req.bodyIds.size() > 0">
AND oi.body_id IN
<foreach collection="req.bodyIds" item="bodyId" open="(" close=")" separator=",">
#{bodyId}
</foreach>
</if>
ORDER BY op.id DESC, oi.group_id ORDER BY op.id DESC, oi.group_id
</select> </select>
@@ -58,6 +58,28 @@
WHERE o.deleted = false WHERE o.deleted = false
AND IFNULL(o.decomposed_veneer_plate_num, 0) AND IFNULL(o.decomposed_veneer_plate_num, 0)
&gt; IFNULL(o.planned_veneer_plate_num, 0) &gt; IFNULL(o.planned_veneer_plate_num, 0)
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND o.id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
<if test="req.goodsIds != null and req.goodsIds.size() > 0">
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
<foreach collection="req.goodsIds" item="goodsId" open="(" close=")" separator=",">
#{goodsId}
</foreach>
)
</if>
<if test="req.orderId != null and req.orderId != ''"> <if test="req.orderId != null and req.orderId != ''">
AND CAST(o.id AS CHAR) LIKE CONCAT('%', #{req.orderId}, '%') AND CAST(o.id AS CHAR) LIKE CONCAT('%', #{req.orderId}, '%')
</if> </if>
@@ -113,6 +135,28 @@
WHERE o.deleted = false WHERE o.deleted = false
AND IFNULL(o.decomposed_veneer_plate_num, 0) AND IFNULL(o.decomposed_veneer_plate_num, 0)
&gt; IFNULL(o.planned_veneer_plate_num, 0) &gt; IFNULL(o.planned_veneer_plate_num, 0)
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND o.id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
<if test="req.goodsIds != null and req.goodsIds.size() > 0">
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
<foreach collection="req.goodsIds" item="goodsId" open="(" close=")" separator=",">
#{goodsId}
</foreach>
)
</if>
AND o.parent_id IN AND o.parent_id IN
<foreach collection="rootIds" item="id" open="(" close=")" separator=","> <foreach collection="rootIds" item="id" open="(" close=")" separator=",">
#{id} #{id}
@@ -138,21 +182,108 @@
ORDER BY o.id DESC ORDER BY o.id DESC
</select> </select>
<sql id="PendingVeneerFilter">
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
<if test="(req.roomIds != null and req.roomIds.size() > 0)
or (req.bodyIds != null and req.bodyIds.size() > 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
<if test="req.roomIds != null and req.roomIds.size() > 0">
AND oi.room_id IN
<foreach collection="req.roomIds" item="roomId" open="(" close=")" separator=",">
#{roomId}
</foreach>
</if>
<if test="req.bodyIds != null and req.bodyIds.size() > 0">
AND oi.body_id IN
<foreach collection="req.bodyIds" item="bodyId" open="(" close=")" separator=",">
#{bodyId}
</foreach>
</if>
)
</if>
)
</sql>
<sql id="PendingPlateRoomBodyFilter">
<if test="(req.roomIds != null and req.roomIds.size() > 0)
or (req.bodyIds != null and req.bodyIds.size() > 0)">
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
<if test="req.roomIds != null and req.roomIds.size() > 0">
AND oi.room_id IN
<foreach collection="req.roomIds" item="roomId" open="(" close=")" separator=",">
#{roomId}
</foreach>
</if>
<if test="req.bodyIds != null and req.bodyIds.size() > 0">
AND oi.body_id IN
<foreach collection="req.bodyIds" item="bodyId" open="(" close=")" separator=",">
#{bodyId}
</foreach>
</if>
)
</if>
</sql>
<select id="selectGoodsPage" resultMap="GoodsMap"> <select id="selectGoodsPage" resultMap="GoodsMap">
SELECT og.goods_id AS goodsId, SELECT og.goods_id AS goodsId,
og.goods_name AS goodsName, og.goods_name AS goodsName,
og.material, og.material,
og.color, og.color,
og.thickness, og.thickness,
<choose>
<when test="(req.roomIds != null and req.roomIds.size() > 0)
or (req.bodyIds != null and req.bodyIds.size() > 0)">
COUNT(op.id) AS num,
SUM(op.area) AS area
</when>
<otherwise>
SUM(og.plate_num) AS num, SUM(og.plate_num) AS num,
SUM(og.area) AS area SUM(og.area) AS area
</otherwise>
</choose>
FROM orders o FROM orders o
JOIN order_goods og ON og.order_id = o.id JOIN order_goods og ON og.order_id = o.id
<if test="(req.roomIds != null and req.roomIds.size() > 0)
or (req.bodyIds != null and req.bodyIds.size() > 0)">
JOIN order_plate op ON op.order_id = og.order_id
AND op.goods_id = og.id
AND op.deleted = false
</if>
WHERE o.deleted = false WHERE o.deleted = false
AND o.status IN (1, 2, 3) AND o.status IN (1, 2, 3)
AND og.deleted = false AND og.deleted = false
AND IFNULL(og.decomposed_veneer_plate_num, 0) AND IFNULL(og.decomposed_veneer_plate_num, 0)
&gt; IFNULL(og.planned_veneer_plate_num, 0) &gt; IFNULL(og.planned_veneer_plate_num, 0)
<include refid="PendingVeneerFilter"/>
<include refid="PendingPlateRoomBodyFilter"/>
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND og.order_id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
<if test="req.goodsName != null and req.goodsName != ''"> <if test="req.goodsName != null and req.goodsName != ''">
AND og.goods_name LIKE CONCAT('%', #{req.goodsName}, '%') AND og.goods_name LIKE CONCAT('%', #{req.goodsName}, '%')
</if> </if>
@@ -172,6 +303,32 @@
ORDER BY og.thickness DESC ORDER BY og.thickness DESC
</select> </select>
<select id="selectGoodsOrderRelationList"
resultType="com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerGoodsOrderRelationRespVO">
SELECT DISTINCT og.goods_id AS goodsId,
og.order_id AS orderId,
og.id AS orderGoodsId
FROM orders o
JOIN order_goods og ON og.order_id = o.id
WHERE o.deleted = false
AND o.status IN (1, 2, 3)
AND og.deleted = false
AND IFNULL(og.decomposed_veneer_plate_num, 0)
&gt; IFNULL(og.planned_veneer_plate_num, 0)
<include refid="PendingVeneerFilter"/>
AND og.goods_id IN
<foreach collection="goodsIds" item="goodsId" open="(" close=")" separator=",">
#{goodsId}
</foreach>
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND og.order_id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
ORDER BY og.goods_id, og.order_id
</select>
<select id="selectUnplannedRootOrderIdList" resultType="java.lang.Long"> <select id="selectUnplannedRootOrderIdList" resultType="java.lang.Long">
SELECT o.root_id SELECT o.root_id
FROM orders o FROM orders o
@@ -184,6 +341,28 @@
AND opv.deleted = false AND opv.deleted = false
AND opv.plan_id = 0 AND opv.plan_id = 0
) )
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND o.id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
<if test="req.goodsIds != null and req.goodsIds.size() > 0">
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
<foreach collection="req.goodsIds" item="goodsId" open="(" close=")" separator=",">
#{goodsId}
</foreach>
)
</if>
<if test="req.orderId != null and req.orderId != ''"> <if test="req.orderId != null and req.orderId != ''">
AND CAST(o.id AS CHAR) LIKE CONCAT('%', #{req.orderId}, '%') AND CAST(o.id AS CHAR) LIKE CONCAT('%', #{req.orderId}, '%')
</if> </if>
@@ -212,22 +391,37 @@
og.material, og.material,
og.color, og.color,
og.thickness, og.thickness,
<choose>
<when test="(req.roomIds != null and req.roomIds.size() > 0)
or (req.bodyIds != null and req.bodyIds.size() > 0)">
COUNT(op.id) AS num,
SUM(op.area) AS area
</when>
<otherwise>
SUM(og.plate_num) AS num, SUM(og.plate_num) AS num,
SUM(og.area) AS area SUM(og.area) AS area
</otherwise>
</choose>
FROM orders o FROM orders o
JOIN order_goods og ON og.order_id = o.id JOIN order_goods og ON og.order_id = o.id
<if test="(req.roomIds != null and req.roomIds.size() > 0)
or (req.bodyIds != null and req.bodyIds.size() > 0)">
JOIN order_plate op ON op.order_id = og.order_id
AND op.goods_id = og.id
AND op.deleted = false
</if>
WHERE o.deleted = false WHERE o.deleted = false
AND o.status IN (1, 2, 3) AND o.status IN (1, 2, 3)
AND og.deleted = false AND og.deleted = false
AND IFNULL(og.plate_num, 0) &gt; IFNULL(og.planned_veneer_plate_num, 0) AND IFNULL(og.plate_num, 0) &gt; IFNULL(og.planned_veneer_plate_num, 0)
AND EXISTS ( <include refid="PendingVeneerFilter"/>
SELECT 1 <include refid="PendingPlateRoomBodyFilter"/>
FROM order_plate_veneer opv <if test="req.orderIds != null and req.orderIds.size() > 0">
WHERE opv.order_id = og.order_id AND og.order_id IN
AND opv.order_goods_id = og.id <foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
AND opv.deleted = false #{orderId}
AND opv.plan_id = 0 </foreach>
) </if>
<if test="req.goodsName != null and req.goodsName != ''"> <if test="req.goodsName != null and req.goodsName != ''">
AND og.goods_name LIKE CONCAT('%', #{req.goodsName}, '%') AND og.goods_name LIKE CONCAT('%', #{req.goodsName}, '%')
</if> </if>
@@ -247,6 +441,31 @@
ORDER BY og.thickness DESC ORDER BY og.thickness DESC
</select> </select>
<select id="selectUnplannedGoodsOrderRelationList"
resultType="com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerGoodsOrderRelationRespVO">
SELECT DISTINCT og.goods_id AS goodsId,
og.order_id AS orderId,
og.id AS orderGoodsId
FROM orders o
JOIN order_goods og ON og.order_id = o.id
WHERE o.deleted = false
AND o.status IN (1, 2, 3)
AND og.deleted = false
AND IFNULL(og.plate_num, 0) &gt; IFNULL(og.planned_veneer_plate_num, 0)
<include refid="PendingVeneerFilter"/>
AND og.goods_id IN
<foreach collection="goodsIds" item="goodsId" open="(" close=")" separator=",">
#{goodsId}
</foreach>
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND og.order_id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
ORDER BY og.goods_id, og.order_id
</select>
<select id="selectUnplannedOrderChildList" resultMap="OrderMap"> <select id="selectUnplannedOrderChildList" resultMap="OrderMap">
SELECT o.id AS orderId, SELECT o.id AS orderId,
o.parent_id AS parentId, o.parent_id AS parentId,
@@ -271,6 +490,28 @@
AND opv.deleted = false AND opv.deleted = false
AND opv.plan_id = 0 AND opv.plan_id = 0
) )
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND o.id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
<if test="req.goodsIds != null and req.goodsIds.size() > 0">
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
<foreach collection="req.goodsIds" item="goodsId" open="(" close=")" separator=",">
#{goodsId}
</foreach>
)
</if>
<if test="req.orderId != null and req.orderId != ''"> <if test="req.orderId != null and req.orderId != ''">
AND CAST(o.id AS CHAR) LIKE CONCAT('%', #{req.orderId}, '%') AND CAST(o.id AS CHAR) LIKE CONCAT('%', #{req.orderId}, '%')
</if> </if>
@@ -312,12 +553,21 @@
SELECT SELECT
<include refid="PlateVeneerColumns"/> <include refid="PlateVeneerColumns"/>
FROM order_plate_veneer opv 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.deleted = false WHERE opv.deleted = false
AND opv.plan_id = 0 AND opv.plan_id = 0
AND og.deleted = false
AND opv.order_id IN AND opv.order_id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=","> <foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId} #{orderId}
</foreach> </foreach>
<if test="req.goodsIds != null and req.goodsIds.size() > 0">
AND og.goods_id IN
<foreach collection="req.goodsIds" item="goodsId" open="(" close=")" separator=",">
#{goodsId}
</foreach>
</if>
<if test="(req.roomIds != null and req.roomIds.size() > 0) <if test="(req.roomIds != null and req.roomIds.size() > 0)
or (req.bodyIds != null and req.bodyIds.size() > 0)"> or (req.bodyIds != null and req.bodyIds.size() > 0)">
AND EXISTS ( AND EXISTS (
@@ -353,9 +603,36 @@
AND opv.plan_id = 0 AND opv.plan_id = 0
AND og.deleted = false AND og.deleted = false
AND og.goods_id IN AND og.goods_id IN
<foreach collection="goodsIds" item="goodsId" open="(" close=")" separator=","> <foreach collection="req.goodsIds" item="goodsId" open="(" close=")" separator=",">
#{goodsId} #{goodsId}
</foreach> </foreach>
<if test="req.orderIds != null and req.orderIds.size() > 0">
AND opv.order_id IN
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
#{orderId}
</foreach>
</if>
<if test="(req.roomIds != null and req.roomIds.size() > 0)
or (req.bodyIds != null and req.bodyIds.size() > 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
<if test="req.roomIds != null and req.roomIds.size() > 0">
AND oi.room_id IN
<foreach collection="req.roomIds" item="roomId" open="(" close=")" separator=",">
#{roomId}
</foreach>
</if>
<if test="req.bodyIds != null and req.bodyIds.size() > 0">
AND oi.body_id IN
<foreach collection="req.bodyIds" item="bodyId" open="(" close=")" separator=",">
#{bodyId}
</foreach>
</if>
)
</if>
ORDER BY opv.order_plate_id DESC, opv.veneer_side ASC ORDER BY opv.order_plate_id DESC, opv.veneer_side ASC
</select> </select>
@@ -454,20 +731,18 @@
AND opv.plan_id = 0 AND opv.plan_id = 0
AND op.deleted = false AND op.deleted = false
AND og.deleted = false AND og.deleted = false
<choose> <if test="req.orderIds != null and req.orderIds.size() > 0">
<when test="req.orderIds != null and req.orderIds.size() > 0"> AND opv.order_id IN
AND opv.order_id IN <foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=",">
<foreach collection="req.orderIds" item="orderId" open="(" close=")" separator=","> #{orderId}
#{orderId} </foreach>
</foreach> </if>
</when> <if test="req.goodsIds != null and req.goodsIds.size() > 0">
<otherwise> AND og.goods_id IN
AND og.goods_id IN <foreach collection="req.goodsIds" item="goodsId" open="(" close=")" separator=",">
<foreach collection="req.goodsIds" item="goodsId" open="(" close=")" separator=","> #{goodsId}
#{goodsId} </foreach>
</foreach> </if>
</otherwise>
</choose>
<if test="req.veneerNo != null and req.veneerNo != ''"> <if test="req.veneerNo != null and req.veneerNo != ''">
AND opv.veneer_no LIKE CONCAT('%', #{req.veneerNo}, '%') AND opv.veneer_no LIKE CONCAT('%', #{req.veneerNo}, '%')
</if> </if>
@@ -85,7 +85,7 @@ veneer.reselect.source.required=請選擇新的貼皮
veneer.reselect.record.status.changed=板件貼皮資料狀態已變更,請重新整理後再試 veneer.reselect.record.status.changed=板件貼皮資料狀態已變更,請重新整理後再試
veneer.remove.record.required=請選擇需要移除的貼皮資料 veneer.remove.record.required=請選擇需要移除的貼皮資料
veneer.remove.record.status.changed=所選貼皮資料已刪除、已排單或狀態發生變化,請重新整理後再試 veneer.remove.record.status.changed=所選貼皮資料已刪除、已排單或狀態發生變化,請重新整理後再試
veneer.unplanned.scope.invalid=訂單ID列表和板材商品編碼列表必須且只能傳入一項 veneer.unplanned.scope.invalid=訂單ID列表和板材商品編碼列表至少傳入一項
veneer.plan.record.required=請選擇需要排單的貼皮資料 veneer.plan.record.required=請選擇需要排單的貼皮資料
veneer.plan.record.status.changed=所選貼皮資料已排單、已刪除或狀態發生變化,請重新整理後再試 veneer.plan.record.status.changed=所選貼皮資料已排單、已刪除或狀態發生變化,請重新整理後再試
veneer.plan.area.data.invalid=貼皮記錄{0}的面積資料異常,無法建立貼皮排單 veneer.plan.area.data.invalid=貼皮記錄{0}的面積資料異常,無法建立貼皮排單
@@ -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.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.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.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.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.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 veneer.plan.area.data.invalid=Veneer record {0} has invalid area data and cannot create a veneer plan
@@ -85,7 +85,7 @@ veneer.reselect.source.required=请选择新的贴皮
veneer.reselect.record.status.changed=板件贴皮数据状态已变更,请刷新后重试 veneer.reselect.record.status.changed=板件贴皮数据状态已变更,请刷新后重试
veneer.remove.record.required=请选择需要移除的贴皮数据 veneer.remove.record.required=请选择需要移除的贴皮数据
veneer.remove.record.status.changed=所选贴皮数据已删除、已排单或状态发生变化,请刷新后重试 veneer.remove.record.status.changed=所选贴皮数据已删除、已排单或状态发生变化,请刷新后重试
veneer.unplanned.scope.invalid=订单ID列表和板材商品编码列表必须且只能传入一项 veneer.unplanned.scope.invalid=订单ID列表和板材商品编码列表至少传入一项
veneer.plan.record.required=请选择需要排单的贴皮数据 veneer.plan.record.required=请选择需要排单的贴皮数据
veneer.plan.record.status.changed=所选贴皮数据已排单、已删除或状态发生变化,请刷新后重试 veneer.plan.record.status.changed=所选贴皮数据已排单、已删除或状态发生变化,请刷新后重试
veneer.plan.area.data.invalid=贴皮记录{0}的面积数据异常,无法创建贴皮排单 veneer.plan.area.data.invalid=贴皮记录{0}的面积数据异常,无法创建贴皮排单
@@ -34,11 +34,6 @@ import static com.cf.imes.module.plan.enums.ErrorCodeConstants.PRODUCING_ORDER_S
@Slf4j @Slf4j
public class ProducingOrderClient { public class ProducingOrderClient {
/**
* 外部接口报文的最大日志长度,避免批量序列号同步失败时输出过大的日志。
*/
private static final int MAX_LOG_PAYLOAD_LENGTH = 16_384;
private final ProducingOrderImportProperties properties; private final ProducingOrderImportProperties properties;
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final HttpClient httpClient; private final HttpClient httpClient;
@@ -71,15 +66,19 @@ public class ProducingOrderClient {
int maxAttempts = Math.max(1, properties.getNetworkRetryTimes() + 1); int maxAttempts = Math.max(1, properties.getNetworkRetryTimes() + 1);
IOException lastNetworkError = null; IOException lastNetworkError = null;
for (int attempt = 1; attempt <= maxAttempts; attempt++) { for (int attempt = 1; attempt <= maxAttempts; attempt++) {
long startedAt = System.nanoTime();
HttpRequest request = HttpRequest.newBuilder(uri) HttpRequest request = HttpRequest.newBuilder(uri)
.timeout(properties.getReadTimeout()) .timeout(properties.getReadTimeout())
.header("Authorization", "Bearer " + token) .header("Authorization", "Bearer " + token)
.header("Accept", "application/json") .header("Accept", "application/json")
.GET() .GET()
.build(); .build();
logComponentRequest("pull-order", "GET", uri, attempt, maxAttempts, null);
try { try {
HttpResponse<String> response = httpClient.send( HttpResponse<String> response = httpClient.send(
request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); 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) { if (response.statusCode() < 200 || response.statusCode() >= 300) {
throw new ServiceException(PRODUCING_ORDER_PULL_FAILED, throw new ServiceException(PRODUCING_ORDER_PULL_FAILED,
"HTTP " + response.statusCode()); "HTTP " + response.statusCode());
@@ -96,13 +95,13 @@ public class ProducingOrderClient {
"invalid JSON response"); "invalid JSON response");
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
logComponentFailure("pull-order", "GET", uri, attempt, maxAttempts,
elapsedMillis(startedAt), "request interrupted", ex);
throw new ServiceException(PRODUCING_ORDER_PULL_FAILED, "request interrupted"); throw new ServiceException(PRODUCING_ORDER_PULL_FAILED, "request interrupted");
} catch (IOException ex) { } catch (IOException ex) {
lastNetworkError = ex; lastNetworkError = ex;
if (attempt < maxAttempts) { logComponentFailure("pull-order", "GET", uri, attempt, maxAttempts,
log.warn("Pull producing order {} failed on attempt {}, retrying", elapsedMillis(startedAt), ex.getMessage(), ex);
orderId, attempt, ex);
}
} }
} }
String message = lastNetworkError == null ? "network error" : lastNetworkError.getMessage(); String message = lastNetworkError == null ? "network error" : lastNetworkError.getMessage();
@@ -123,8 +122,9 @@ public class ProducingOrderClient {
ProducingOrderExtraSyncRequest request) { ProducingOrderExtraSyncRequest request) {
String encodedOrderId = URLEncoder.encode(orderId, StandardCharsets.UTF_8); String encodedOrderId = URLEncoder.encode(orderId, StandardCharsets.UTF_8);
URI uri = URI.create(properties.getOrderExtraUrl().replace("{id}", encodedOrderId)); URI uri = URI.create(properties.getOrderExtraUrl().replace("{id}", encodedOrderId));
String requestBody = serializeSyncRequest(request, uri);
HttpResponse<String> response = sendPut( HttpResponse<String> response = sendPut(
uri, token, serializeSyncRequest(request), "order-extra"); uri, token, requestBody, "order-extra");
if (!StringUtils.hasText(response.body())) { if (!StringUtils.hasText(response.body())) {
throw new ServiceException(PRODUCING_ORDER_SYNC_FAILED, throw new ServiceException(PRODUCING_ORDER_SYNC_FAILED,
"order-extra: empty response"); "order-extra: empty response");
@@ -147,10 +147,13 @@ public class ProducingOrderClient {
/** /**
* 序列化反向同步请求。 * 序列化反向同步请求。
*/ */
private String serializeSyncRequest(Object request) { private String serializeSyncRequest(Object request, URI uri) {
try { try {
return objectMapper.writeValueAsString(request); return objectMapper.writeValueAsString(request);
} catch (JsonProcessingException ex) { } 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, throw new ServiceException(PRODUCING_ORDER_SYNC_FAILED,
"cannot serialize request"); "cannot serialize request");
} }
@@ -176,49 +179,30 @@ public class ProducingOrderClient {
IOException lastNetworkError = null; IOException lastNetworkError = null;
for (int attempt = 1; attempt <= maxAttempts; attempt++) { for (int attempt = 1; attempt <= maxAttempts; attempt++) {
long startedAt = System.nanoTime(); long startedAt = System.nanoTime();
log.info("[producing-order-http] operation={} method=PUT uri={} attempt={}/{} requestBytes={}", logComponentRequest(operation, "PUT", uri, attempt, maxAttempts, body);
operation, uri, attempt, maxAttempts, utf8Length(body));
log.debug("[producing-order-http-request] operation={} uri={} body={}",
operation, uri, logPayload(body));
try { try {
HttpResponse<String> response = httpClient.send( HttpResponse<String> response = httpClient.send(
request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)); request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
long elapsedMs = elapsedMillis(startedAt); long elapsedMs = elapsedMillis(startedAt);
String responseBody = response.body(); String responseBody = response.body();
logComponentResponse(operation, "PUT", uri, attempt, maxAttempts,
response.statusCode(), elapsedMs, responseBody);
if (response.statusCode() < 200 || response.statusCode() >= 300) { 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, throw new ServiceException(PRODUCING_ORDER_SYNC_FAILED,
operation + ": HTTP " + response.statusCode() 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; return response;
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
log.error("[producing-order-http-error] operation={} method=PUT uri={} " logComponentFailure(operation, "PUT", uri, attempt, maxAttempts,
+ "attempt={}/{} elapsedMs={} error=request-interrupted", elapsedMillis(startedAt), "request interrupted", ex);
operation, uri, attempt, maxAttempts, elapsedMillis(startedAt));
throw new ServiceException(PRODUCING_ORDER_SYNC_FAILED, throw new ServiceException(PRODUCING_ORDER_SYNC_FAILED,
operation + ": request interrupted"); operation + ": request interrupted");
} catch (IOException ex) { } catch (IOException ex) {
lastNetworkError = ex; lastNetworkError = ex;
if (attempt < maxAttempts) { logComponentFailure(operation, "PUT", uri, attempt, maxAttempts,
log.warn("[producing-order-http-error] operation={} method=PUT uri={} " elapsedMillis(startedAt), ex.getMessage(), ex);
+ "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);
}
} }
} }
String message = lastNetworkError == null 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)) { if (!StringUtils.hasText(payload)) {
return "<empty>"; return "<empty>";
} }
if (payload.length() <= MAX_LOG_PAYLOAD_LENGTH) { return payload;
return payload;
}
return payload.substring(0, MAX_LOG_PAYLOAD_LENGTH)
+ "...<truncated,totalChars=" + payload.length() + ">";
} }
/** /**