From 4d52264e6f859eed6cd7656a1a3dbb486cf2c7fa Mon Sep 17 00:00:00 2001 From: gaoqr <13665037151@163.com> Date: Thu, 16 Jul 2026 18:06:21 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=96=B0=E5=A2=9E=E8=B4=B4=E7=9A=AE?= =?UTF-8?q?=E6=9C=AA=E5=88=86=E8=A7=A3=E6=8C=89=E8=AE=A2=E5=8D=95/?= =?UTF-8?q?=E6=8C=89=E6=9D=90=E8=B4=A8=E6=9F=A5=E8=AF=A2=E4=B8=BB=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=EF=BC=8C=E6=9F=A5=E8=AF=A2=E6=9C=AA=E5=88=86=E8=A7=A3?= =?UTF-8?q?=E6=9D=BF=E4=BB=B6=E5=88=97=E8=A1=A8=E6=8E=A5=E5=8F=A3=EF=BC=9B?= =?UTF-8?q?2=E3=80=81=E6=96=B0=E5=A2=9E=E8=B4=B4=E7=9A=AE=E5=B7=B2?= =?UTF-8?q?=E5=88=86=E8=A7=A3=E6=8C=89=E8=AE=A2=E5=8D=95/=E6=8C=89?= =?UTF-8?q?=E6=9D=90=E8=B4=A8=E6=9F=A5=E8=AF=A2=E4=B8=BB=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=EF=BC=8C=E6=9F=A5=E8=AF=A2=E5=B7=B2=E5=88=86=E8=A7=A3=E6=9D=BF?= =?UTF-8?q?=E4=BB=B6=E5=88=97=E8=A1=A8=E6=8E=A5=E5=8F=A3=EF=BC=9B3?= =?UTF-8?q?=E3=80=81=E6=96=B0=E5=A2=9E=E6=9D=BF=E4=BB=B6=E8=B4=B4=E7=9A=AE?= =?UTF-8?q?=E5=88=86=E8=A7=A3=E6=8E=A5=E5=8F=A3=EF=BC=9B4=E3=80=81?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=87=8D=E9=80=89=E8=B4=B4=E7=9A=AE=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../executor/enums/ErrorCodeConstants.java | 6 + .../veneer/VeneerDecomposeController.java | 109 +++++ .../admin/veneer/VeneerManageController.java | 110 +++++ .../veneer/vo/VeneerDecomposeCreateReqVO.java | 49 +++ .../vo/VeneerDecomposeGoodsPageReqVO.java | 29 ++ .../veneer/vo/VeneerDecomposeGoodsRespVO.java | 34 ++ .../vo/VeneerDecomposeOrderPageReqVO.java | 33 ++ .../veneer/vo/VeneerDecomposeOrderRespVO.java | 43 ++ .../vo/VeneerDecomposePlatePageReqVO.java | 25 ++ .../veneer/vo/VeneerDecomposePlateRespVO.java | 50 +++ .../veneer/vo/VeneerManageGoodsPageReqVO.java | 29 ++ .../veneer/vo/VeneerManageGoodsRespVO.java | 34 ++ .../veneer/vo/VeneerManageOrderPageReqVO.java | 33 ++ .../veneer/vo/VeneerManageOrderRespVO.java | 38 ++ .../veneer/vo/VeneerManagePlateListReqVO.java | 19 + .../veneer/vo/VeneerManagePlateRespVO.java | 49 +++ .../veneer/vo/VeneerManageReselectReqVO.java | 19 + .../dal/dataobject/goods/GoodsDO.java | 7 +- .../dal/dataobject/order/OrderDO.java | 5 + .../dataobject/veneer/OrderPlateVeneerDO.java | 130 ++++++ .../veneer/VeneerDecomposedPlateCountDO.java | 24 ++ .../mysql/veneer/OrderPlateVeneerMapper.java | 12 + .../mysql/veneer/VeneerDecomposeMapper.java | 120 ++++++ .../dal/mysql/veneer/VeneerManageMapper.java | 68 +++ .../veneer/VeneerDecomposeService.java | 57 +++ .../veneer/VeneerDecomposeServiceImpl.java | 396 ++++++++++++++++++ .../service/veneer/VeneerManageService.java | 57 +++ .../veneer/VeneerManageServiceImpl.java | 152 +++++++ .../mapper/veneer/VeneerDecomposeMapper.xml | 278 ++++++++++++ .../mapper/veneer/VeneerManageMapper.xml | 160 +++++++ .../message_errorcode_cht.properties | 8 + .../resources/message_errorcode_en.properties | 8 + .../resources/message_errorcode_zh.properties | 8 + 33 files changed, 2198 insertions(+), 1 deletion(-) create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/VeneerDecomposeController.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/VeneerManageController.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeCreateReqVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeGoodsPageReqVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeGoodsRespVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeOrderPageReqVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeOrderRespVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposePlatePageReqVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposePlateRespVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageGoodsPageReqVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageGoodsRespVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageOrderPageReqVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageOrderRespVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManagePlateListReqVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManagePlateRespVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageReselectReqVO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/veneer/OrderPlateVeneerDO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/veneer/VeneerDecomposedPlateCountDO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/OrderPlateVeneerMapper.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/VeneerDecomposeMapper.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/VeneerManageMapper.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerDecomposeService.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerDecomposeServiceImpl.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerManageService.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerManageServiceImpl.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/veneer/VeneerDecomposeMapper.xml create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/veneer/VeneerManageMapper.xml diff --git a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/ErrorCodeConstants.java b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/ErrorCodeConstants.java index b8f87017a..c31153fae 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/ErrorCodeConstants.java +++ b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/ErrorCodeConstants.java @@ -176,6 +176,12 @@ public class ErrorCodeConstants { public static final ErrorCode VENEER_IMPORT_VENEER_NO_DUPLICATE = new ErrorCode(1_003_009_014, "veneer.import.veneer.no.duplicate"); public static final ErrorCode VENEER_IMPORT_VENEER_NO_FORMAT_ERROR = new ErrorCode(1_003_009_015, "veneer.import.veneer.no.format.error"); public static final ErrorCode VENEER_IMPORT_PRODUCT_LEVEL_ERROR = new ErrorCode(1_003_009_016, "veneer.import.product.level.error"); + public static final ErrorCode VENEER_DECOMPOSE_SCOPE_REQUIRED = new ErrorCode(1_003_009_017, "veneer.decompose.scope.required"); + public static final ErrorCode VENEER_DECOMPOSE_SIDE_REQUIRED = new ErrorCode(1_003_009_018, "veneer.decompose.side.required"); + public static final ErrorCode VENEER_DECOMPOSE_PLATE_STATUS_CHANGED = new ErrorCode(1_003_009_019, "veneer.decompose.plate.status.changed"); + public static final ErrorCode VENEER_RESELECT_RECORD_REQUIRED = new ErrorCode(1_003_009_020, "veneer.reselect.record.required"); + public static final ErrorCode VENEER_RESELECT_SOURCE_REQUIRED = new ErrorCode(1_003_009_021, "veneer.reselect.source.required"); + public static final ErrorCode VENEER_RESELECT_RECORD_STATUS_CHANGED = new ErrorCode(1_003_009_022, "veneer.reselect.record.status.changed"); //=========== 部件管理 1-003-010-000 ============ public static final ErrorCode ORDER_COMPONENT_NOT_EXIST = new ErrorCode(1_003_010_000, "order.component.not.exist"); diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/VeneerDecomposeController.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/VeneerDecomposeController.java new file mode 100644 index 000000000..04d75f6ad --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/VeneerDecomposeController.java @@ -0,0 +1,109 @@ +package com.cf.imes.module.executor.controller.admin.veneer; + +import com.cf.imes.framework.common.pojo.CommonResult; +import com.cf.imes.framework.common.pojo.PageResult; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeCreateReqVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeGoodsPageReqVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeGoodsRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeOrderPageReqVO; +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.service.veneer.VeneerDecomposeService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +import static com.cf.imes.framework.common.pojo.CommonResult.success; + +/** + * 贴皮分解接口。 + */ +@Tag(name = "生产管理 - 贴皮分解") +@RestController +@RequestMapping("/executor/veneer-decompose") +@Validated +public class VeneerDecomposeController { + + @Resource + private VeneerDecomposeService veneerDecomposeService; + + /** + * 分页查询存在未贴皮分解板件的订单。 + * + * @param req 分页及筛选条件 + * @return 订单分页列表 + */ + @PostMapping("/order/page") + @Operation(summary = "获取贴皮分解订单分页列表") + @PreAuthorize("@ss.hasPermission('unplannedOrders:query')") + public CommonResult> getOrderPage( + @Valid @RequestBody VeneerDecomposeOrderPageReqVO req) { + return success(veneerDecomposeService.getOrderPage(req)); + } + + /** + * 分页查询存在未贴皮分解板件的板材。 + * + * @param req 分页及筛选条件 + * @return 板材分页列表 + */ + @PostMapping("/goods/page") + @Operation(summary = "获取贴皮分解板材分页列表") + @PreAuthorize("@ss.hasPermission('unplannedOrders:query')") + public CommonResult> getGoodsPage( + @Valid @RequestBody VeneerDecomposeGoodsPageReqVO req) { + return success(veneerDecomposeService.getGoodsPage(req)); + } + + /** + * 按订单查询未贴皮分解板件列表。 + * + * @param req 查询条件,必须包含订单ID列表 + * @return 板件列表 + */ + @PostMapping("/order/plate/page") + @Operation(summary = "获取订单下待贴皮分解板件列表") + @PreAuthorize("@ss.hasPermission('unplannedOrders:query')") + public CommonResult> getOrderPlateList( + @Valid @RequestBody VeneerDecomposePlatePageReqVO req) { + return success(veneerDecomposeService.getOrderPlateList(req)); + } + + /** + * 按板材查询未贴皮分解板件列表。 + * + * @param req 查询条件,必须包含商品编码列表 + * @return 板件列表 + */ + @PostMapping("/goods/plate/page") + @Operation(summary = "获取材质下待贴皮分解板件列表") + @PreAuthorize("@ss.hasPermission('unplannedOrders:query')") + public CommonResult> getGoodsPlateList( + @Valid @RequestBody VeneerDecomposePlatePageReqVO req) { + return success(veneerDecomposeService.getGoodsPlateList(req)); + } + + /** + * 将选中的未分解原板件分解为 A 面和/或 B 面贴皮记录。 + * + * @param req 分解参数 + * @return 是否成功 + */ + @PostMapping("/decompose") + @Operation(summary = "执行贴皮分解") + @PreAuthorize("@ss.hasPermission('unplannedOrders:query')") + public CommonResult decompose(@Valid @RequestBody VeneerDecomposeCreateReqVO req) { + veneerDecomposeService.decompose(req); + return success(true); + } +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/VeneerManageController.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/VeneerManageController.java new file mode 100644 index 000000000..069332947 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/VeneerManageController.java @@ -0,0 +1,110 @@ +package com.cf.imes.module.executor.controller.admin.veneer; + +import com.cf.imes.framework.common.pojo.CommonResult; +import com.cf.imes.framework.common.pojo.PageResult; +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; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageOrderRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManagePlateListReqVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManagePlateRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageReselectReqVO; +import com.cf.imes.module.executor.service.veneer.VeneerManageService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +import static com.cf.imes.framework.common.pojo.CommonResult.success; + +/** + * 贴皮管理接口。 + */ +@Tag(name = "生产管理 - 贴皮管理") +@RestController +@RequestMapping("/executor/veneer-manage") +@Validated +public class VeneerManageController { + + @Resource + private VeneerManageService veneerManageService; + + /** + * 分页查询存在已分解贴皮板件的订单。 + * + * @param req 分页及筛选条件 + * @return 订单分页列表 + */ + @PostMapping("/order/page") + @Operation(summary = "获取贴皮管理订单分页列表") + @PreAuthorize("@ss.hasPermission('unplannedOrders:query')") + public CommonResult> getOrderPage( + @Valid @RequestBody VeneerManageOrderPageReqVO req) { + return success(veneerManageService.getOrderPage(req)); + } + + /** + * 分页查询存在已分解贴皮板件的板材。 + * + * @param req 分页及筛选条件 + * @return 板材分页列表 + */ + @PostMapping("/goods/page") + @Operation(summary = "获取贴皮管理板材分页列表") + @PreAuthorize("@ss.hasPermission('unplannedOrders:query')") + public CommonResult> getGoodsPage( + @Valid @RequestBody VeneerManageGoodsPageReqVO req) { + return success(veneerManageService.getGoodsPage(req)); + } + + /** + * 按订单查询已分解板件贴皮列表。 + * + * @param req 查询条件,必须包含订单ID列表 + * @return 已分解板件贴皮列表 + */ + @PostMapping("/order/plate/list") + @Operation(summary = "按订单获取已分解板件贴皮列表") + @PreAuthorize("@ss.hasPermission('unplannedOrders:query')") + public CommonResult> getOrderPlateList( + @Valid @RequestBody VeneerManagePlateListReqVO req) { + return success(veneerManageService.getOrderPlateList(req)); + } + + /** + * 按板材查询已分解板件贴皮列表。 + * + * @param req 查询条件,必须包含板材商品编码列表 + * @return 已分解板件贴皮列表 + */ + @PostMapping("/goods/plate/list") + @Operation(summary = "按板材获取已分解板件贴皮列表") + @PreAuthorize("@ss.hasPermission('unplannedOrders:query')") + public CommonResult> getGoodsPlateList( + @Valid @RequestBody VeneerManagePlateListReqVO req) { + return success(veneerManageService.getGoodsPlateList(req)); + } + + /** + * 批量为已分解板件贴皮重新选择贴皮库数据。 + * + * @param req 板件贴皮记录ID及新贴皮库ID + * @return 是否成功 + */ + @PostMapping("/plate/reselect") + @Operation(summary = "批量重选贴皮") + @PreAuthorize("@ss.hasPermission('unplannedOrders:query')") + public CommonResult reselectVeneer( + @Valid @RequestBody VeneerManageReselectReqVO req) { + veneerManageService.reselectVeneer(req); + return success(true); + } +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeCreateReqVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeCreateReqVO.java new file mode 100644 index 000000000..0710c6a0e --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeCreateReqVO.java @@ -0,0 +1,49 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import cn.hutool.core.collection.CollUtil; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.DecimalMin; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 贴皮分解请求参数。 + */ +@Data +public class VeneerDecomposeCreateReqVO { + + @Schema(description = "订单ID列表;非空时按订单范围分解") + private List orderIds; + + @Schema(description = "板材商品编码;orderIds为空时必填") + private String goodsId; + + @Schema(description = "原板件编号列表", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "{veneer.decompose.plate.no.required}") + private List plateNos; + + @Schema(description = "A面贴皮库ID") + @JsonProperty("aVeneerId") + private Long aVeneerId; + + @Schema(description = "B面贴皮库ID") + @JsonProperty("bVeneerId") + private Long bVeneerId; + + @Schema(description = "外扩余量(mm),默认10") + @DecimalMin(value = "0", message = "{veneer.decompose.outer.margin.min}") + private BigDecimal outerMargin = new BigDecimal("10"); + + /** + * 判断是否按订单入口提交。 + * + * @return {@code true} 表示按订单范围分解,{@code false} 表示按板材范围分解 + */ + public boolean isByOrder() { + return CollUtil.isNotEmpty(orderIds); + } +} 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 new file mode 100644 index 000000000..b807e6b1f --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeGoodsPageReqVO.java @@ -0,0 +1,29 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import com.cf.imes.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 贴皮分解材质分页查询请求参数。 + */ +@Data +public class VeneerDecomposeGoodsPageReqVO extends PageParam { + + @Schema(description = "板材名称") + private String goodsName; + + @Schema(description = "商品编号") + private String goodsId; + + @Schema(description = "材质") + private String material; + + @Schema(description = "颜色") + private String color; + + @Schema(description = "厚度") + private BigDecimal thickness; +} 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 new file mode 100644 index 000000000..0f36c8ab2 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeGoodsRespVO.java @@ -0,0 +1,34 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 贴皮分解板材分页响应参数。 + */ +@Data +public class VeneerDecomposeGoodsRespVO { + + @Schema(description = "板材名称") + private String goodsName; + + @Schema(description = "商品编码") + private String goodsId; + + @Schema(description = "材质") + private String material; + + @Schema(description = "颜色") + private String color; + + @Schema(description = "厚度") + private BigDecimal thickness; + + @Schema(description = "总片数") + private Integer num; + + @Schema(description = "总平方数") + private BigDecimal area; +} 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 new file mode 100644 index 000000000..db2ee98a3 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeOrderPageReqVO.java @@ -0,0 +1,33 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import com.cf.imes.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDate; + +import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; + +/** + * 贴皮分解订单分页查询请求参数。 + */ +@Data +public class VeneerDecomposeOrderPageReqVO extends PageParam { + + @Schema(description = "订单号") + private String orderId; + + @Schema(description = "自定义单号") + private String customOrderNo; + + @Schema(description = "客户") + private String customer; + + @Schema(description = "地址") + private String address; + + @Schema(description = "订单日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDate[] orderDate; +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeOrderRespVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeOrderRespVO.java new file mode 100644 index 000000000..616c72b4c --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposeOrderRespVO.java @@ -0,0 +1,43 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; +import static com.cf.imes.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; + +/** + * 贴皮分解订单分页响应参数。 + */ +@Data +public class VeneerDecomposeOrderRespVO { + + @Schema(description = "订单号") + private Long orderId; + + @Schema(description = "自定义单号") + private String customOrderNo; + + @Schema(description = "订单类型") + private Integer orderType; + + @Schema(description = "客户") + private String customer; + + @Schema(description = "地址") + private String address; + + @Schema(description = "片数") + private Integer num; + + @Schema(description = "平方数") + private BigDecimal area; + + @Schema(description = "订单日期") + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY, timezone = TIME_ZONE_DEFAULT) + private LocalDateTime orderDate; +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposePlatePageReqVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposePlatePageReqVO.java new file mode 100644 index 000000000..cdacfe13a --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposePlatePageReqVO.java @@ -0,0 +1,25 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 待贴皮分解板件列表查询参数。 + */ +@Data +public class VeneerDecomposePlatePageReqVO { + + @Schema(description = "订单ID列表") + private List orderIds; + + @Schema(description = "房间ID列表") + private List roomIds; + + @Schema(description = "柜体ID列表") + private List bodyIds; + + @Schema(description = "板材商品编码列表") + private List goodsIds; +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposePlateRespVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposePlateRespVO.java new file mode 100644 index 000000000..b88abc06b --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerDecomposePlateRespVO.java @@ -0,0 +1,50 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 待贴皮分解板件响应参数。 + */ +@Data +public class VeneerDecomposePlateRespVO { + + /** + * 板件主键,仅用于 Service 层按板件去重,不返回前端。 + */ + @JsonIgnore + private Long plateId; + + @Schema(description = "房名") + private String roomName; + + @Schema(description = "柜名") + private String bodyName; + + @Schema(description = "板件编号") + private String plateNo; + + @Schema(description = "材质") + private String material; + + @Schema(description = "颜色") + private String color; + + @Schema(description = "板名称") + private String plateName; + + @Schema(description = "长度") + private BigDecimal length; + + @Schema(description = "宽度") + private BigDecimal width; + + @Schema(description = "厚度") + private BigDecimal thickness; + + @Schema(description = "面积") + private BigDecimal area; +} 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 new file mode 100644 index 000000000..ef801d649 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageGoodsPageReqVO.java @@ -0,0 +1,29 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import com.cf.imes.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 贴皮管理板材分页查询请求参数。 + */ +@Data +public class VeneerManageGoodsPageReqVO extends PageParam { + + @Schema(description = "板材名称") + private String goodsName; + + @Schema(description = "商品编码") + private String goodsId; + + @Schema(description = "材质") + private String material; + + @Schema(description = "颜色") + private String color; + + @Schema(description = "厚度") + private BigDecimal thickness; +} 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 new file mode 100644 index 000000000..4a704bbe0 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageGoodsRespVO.java @@ -0,0 +1,34 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 贴皮管理板材分页响应参数。 + */ +@Data +public class VeneerManageGoodsRespVO { + + @Schema(description = "板材名称") + private String goodsName; + + @Schema(description = "商品编码") + private String goodsId; + + @Schema(description = "材质") + private String material; + + @Schema(description = "颜色") + private String color; + + @Schema(description = "厚度") + private BigDecimal thickness; + + @Schema(description = "总片数") + private Integer num; + + @Schema(description = "总平方数") + private BigDecimal area; +} 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 new file mode 100644 index 000000000..863a90b00 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageOrderPageReqVO.java @@ -0,0 +1,33 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import com.cf.imes.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDate; + +import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; + +/** + * 贴皮管理订单分页查询请求参数。 + */ +@Data +public class VeneerManageOrderPageReqVO extends PageParam { + + @Schema(description = "订单号") + private String orderId; + + @Schema(description = "自定义单号") + private String customOrderNo; + + @Schema(description = "客户") + private String customer; + + @Schema(description = "地址") + private String address; + + @Schema(description = "订单日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDate[] orderDate; +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageOrderRespVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageOrderRespVO.java new file mode 100644 index 000000000..755961323 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageOrderRespVO.java @@ -0,0 +1,38 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 贴皮管理订单分页响应参数。 + */ +@Data +public class VeneerManageOrderRespVO { + + @Schema(description = "订单号") + private Long orderId; + + @Schema(description = "自定义单号") + private String customOrderNo; + + @Schema(description = "订单类型") + private String orderType; + + @Schema(description = "客户") + private String customer; + + @Schema(description = "地址") + private String address; + + @Schema(description = "片数") + private Integer num; + + @Schema(description = "平方数") + private BigDecimal area; + + @Schema(description = "订单日期") + private LocalDateTime orderDate; +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManagePlateListReqVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManagePlateListReqVO.java new file mode 100644 index 000000000..e9694595f --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManagePlateListReqVO.java @@ -0,0 +1,19 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 已分解板件贴皮列表查询参数。 + */ +@Data +public class VeneerManagePlateListReqVO { + + @Schema(description = "订单ID列表") + private List orderIds; + + @Schema(description = "板材商品编码列表") + private List goodsIds; +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManagePlateRespVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManagePlateRespVO.java new file mode 100644 index 000000000..5aa43b68a --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManagePlateRespVO.java @@ -0,0 +1,49 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 已分解板件贴皮响应参数。 + */ +@Data +public class VeneerManagePlateRespVO { + + @Schema(description = "板件贴皮记录ID") + private Long id; + + @Schema(description = "生成贴皮编号") + private String veneerNo; + + @Schema(description = "原板件编号") + private String plateNo; + + @Schema(description = "原板件名称") + private String plateName; + + @Schema(description = "原板件长(mm)") + private BigDecimal length; + + @Schema(description = "原板件宽(mm)") + private BigDecimal width; + + @Schema(description = "原板件厚(mm)") + private BigDecimal thickness; + + @Schema(description = "贴皮商品号") + private String sourceVeneerNo; + + @Schema(description = "贴皮名称") + private String veneerName; + + @Schema(description = "产品等级") + private Integer productLevel; + + @Schema(description = "颜色") + private String color; + + @Schema(description = "材质") + private String material; +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageReselectReqVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageReselectReqVO.java new file mode 100644 index 000000000..afe81609b --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/veneer/vo/VeneerManageReselectReqVO.java @@ -0,0 +1,19 @@ +package com.cf.imes.module.executor.controller.admin.veneer.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 批量重选贴皮请求参数。 + */ +@Data +public class VeneerManageReselectReqVO { + + @Schema(description = "板件贴皮记录ID列表", requiredMode = Schema.RequiredMode.REQUIRED) + private List ids; + + @Schema(description = "重新选择的贴皮库ID", requiredMode = Schema.RequiredMode.REQUIRED) + private Long veneerId; +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/goods/GoodsDO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/goods/GoodsDO.java index ac810dbfa..d5a3347d5 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/goods/GoodsDO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/goods/GoodsDO.java @@ -108,6 +108,11 @@ public class GoodsDO extends BaseDO { */ private Integer plannedPlateNum; + /** + * 已分解贴皮板件数量 + */ + private Integer decomposedVeneerPlateNum; + /** * 板件总面积 */ @@ -122,4 +127,4 @@ public class GoodsDO extends BaseDO { * 版本号:乐观锁用 */ private int version; -} \ No newline at end of file +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/order/OrderDO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/order/OrderDO.java index 18fa2c8e2..739590999 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/order/OrderDO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/order/OrderDO.java @@ -142,6 +142,11 @@ public class OrderDO extends BaseDO { */ private Integer plannedPlateNum; + /** + * 已分解贴皮板件数量 + */ + private Integer decomposedVeneerPlateNum; + /** * 板件总面积 */ diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/veneer/OrderPlateVeneerDO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/veneer/OrderPlateVeneerDO.java new file mode 100644 index 000000000..8a6925b62 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/veneer/OrderPlateVeneerDO.java @@ -0,0 +1,130 @@ +package com.cf.imes.module.executor.dal.dataobject.veneer; + +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableName; +import com.cf.imes.framework.mybatis.core.dataobject.BaseDO; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * 订单板件贴皮记录 DO。 + */ +@TableName("order_plate_veneer") +@KeySequence("order_plate_veneer_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class OrderPlateVeneerDO extends BaseDO { + + /** + * 主键。 + */ + private Long id; + + /** + * 组织ID,也是 MyCat 分片键。 + */ + private Long organId; + + /** + * 订单主键。 + */ + private Long orderId; + + /** + * 订单板材主键,对应 {@code order_goods.id}。 + */ + private Long orderGoodsId; + + /** + * 原板件主键,对应 {@code order_plate.id}。 + */ + private Long orderPlateId; + + /** + * 原板件编号。 + */ + private String plateNo; + + /** + * 原板件名称。 + */ + private String plateName; + + /** + * 原板件长度,单位:mm。 + */ + private BigDecimal plateLength; + + /** + * 原板件宽度,单位:mm。 + */ + private BigDecimal plateWidth; + + /** + * 原板件厚度,单位:mm。 + */ + private BigDecimal plateThickness; + + /** + * 原板件排版面:0-正面,1-反面,2-随意面。 + */ + private Integer holeArrange; + + /** + * 贴皮逻辑面:A-A面,B-B面。 + */ + private String veneerSide; + + /** + * 实际板件面:0-正面,1-反面。 + */ + private Integer plateSurface; + + /** + * 分解后生成的贴皮编号,规则为原板件编号加 A/B 后缀。 + */ + private String veneerNo; + + /** + * 贴皮外扩余量,单位:mm。 + */ + private BigDecimal outerMargin; + + /** + * 来源贴皮库记录主键,对应 {@code veneers.id}。 + */ + private Long sourceVeneerId; + + /** + * 贴皮商品编号快照。 + */ + private String sourceVeneerNo; + + /** + * 贴皮名称快照。 + */ + private String veneerName; + + /** + * 产品等级快照。 + */ + private Integer productLevel; + + /** + * 颜色快照。 + */ + private String color; + + /** + * 材质快照。 + */ + private String material; +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/veneer/VeneerDecomposedPlateCountDO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/veneer/VeneerDecomposedPlateCountDO.java new file mode 100644 index 000000000..b0c2f8ec9 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/veneer/VeneerDecomposedPlateCountDO.java @@ -0,0 +1,24 @@ +package com.cf.imes.module.executor.dal.dataobject.veneer; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 已分解贴皮板件数量统计结果。 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class VeneerDecomposedPlateCountDO { + + /** + * 订单ID或 {@code order_goods} 主键。 + */ + private Long targetId; + + /** + * 从数据库重新统计的已分解板件数量。 + */ + private Integer decomposedPlateNum; +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/OrderPlateVeneerMapper.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/OrderPlateVeneerMapper.java new file mode 100644 index 000000000..2693c0b29 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/OrderPlateVeneerMapper.java @@ -0,0 +1,12 @@ +package com.cf.imes.module.executor.dal.mysql.veneer; + +import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX; +import com.cf.imes.module.executor.dal.dataobject.veneer.OrderPlateVeneerDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 订单板件贴皮记录 Mapper。 + */ +@Mapper +public interface OrderPlateVeneerMapper extends BaseMapperX { +} 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 new file mode 100644 index 000000000..b3f42ed42 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/VeneerDecomposeMapper.java @@ -0,0 +1,120 @@ +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.VeneerDecomposeCreateReqVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeGoodsPageReqVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeGoodsRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeOrderPageReqVO; +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.dal.dataobject.plate.PlateDO; +import com.cf.imes.module.executor.dal.dataobject.veneer.VeneerDecomposedPlateCountDO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 贴皮分解 Mapper。 + */ +@Mapper +public interface VeneerDecomposeMapper { + + /** + * 分页查询存在未完成贴皮分解板件的根订单ID。 + * + * @param page 分页参数 + * @param req 订单查询条件 + * @param orderDateTime 完整订单日期时间范围 + * @return 根订单ID分页结果 + */ + IPage selectRootOrderIdList(@Param("page") IPage page, + @Param("req") VeneerDecomposeOrderPageReqVO req, + @Param("orderDateTime") LocalDateTime[] orderDateTime); + + /** + * 根据根订单ID查询订单及子订单信息。 + * + * @param page 分页参数 + * @param rootIds 根订单ID列表 + * @return 订单分页结果 + */ + IPage selectOrderList(@Param("page") IPage page, + @Param("rootIds") List rootIds); + + /** + * 分页查询存在未完成贴皮分解板件的材质。 + * + * @param page 分页参数 + * @param req 材质查询条件 + * @return 材质分页结果 + */ + IPage selectGoodsPage(@Param("page") IPage page, + @Param("req") VeneerDecomposeGoodsPageReqVO req); + + /** + * 按订单查询未贴皮分解板件原始列表。 + * 同一板件可能因多个加工组返回多条记录,由 Service 层按板件主键去重。 + * + * @param req 查询条件 + * @return 板件原始列表 + */ + List selectOrderPlateList( + @Param("req") VeneerDecomposePlatePageReqVO req); + + /** + * 按板材查询未贴皮分解板件原始列表。 + * 同一板件可能因多个加工组返回多条记录,由 Service 层按板件主键去重。 + * + * @param req 查询条件 + * @return 板件原始列表 + */ + List selectGoodsPlateList( + @Param("req") VeneerDecomposePlatePageReqVO req); + + /** + * 查询本次可分解的原板件。 + * + * @param req 分解请求参数 + * @param plateNos 本批待查询的板件编号 + * @return 未分解原板件 + */ + List selectUndecomposedPlateList(@Param("req") VeneerDecomposeCreateReqVO req, + @Param("plateNos") List plateNos); + + /** + * 按固定顺序锁定受影响订单,串行化同一订单的分解与计数重算。 + * + * @param orderIds 订单ID列表 + * @return 已锁定订单ID列表 + */ + List selectOrderIdForUpdate(@Param("orderIds") List orderIds); + + /** + * 将指定原板件标记为已分解。 + * + * @param plateIds 原板件ID列表 + * @return 更新行数 + */ + int updatePlateDecomposed(@Param("plateIds") List plateIds); + + /** + * 按订单重新统计已分解贴皮板件数量。 + * + * @param orderIds 订单ID列表 + * @return 订单及其已分解板件数量 + */ + List selectOrderDecomposedPlateCount( + @Param("orderIds") List orderIds); + + /** + * 按订单板材重新统计已分解贴皮板件数量。 + * + * @param orderGoodsIds {@code order_goods} 主键列表 + * @return 订单板材及其已分解板件数量 + */ + List selectGoodsDecomposedPlateCount( + @Param("orderGoodsIds") List orderGoodsIds); +} 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 new file mode 100644 index 000000000..c93ff0973 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/veneer/VeneerManageMapper.java @@ -0,0 +1,68 @@ +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.VeneerManageGoodsPageReqVO; +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.VeneerManageOrderRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManagePlateRespVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 贴皮管理 Mapper。 + */ +@Mapper +public interface VeneerManageMapper { + + /** + * 分页查询存在已分解贴皮板件的根订单 ID。 + * + * @param page 分页参数 + * @param req 订单查询条件 + * @param orderDateTime 完整订单日期时间范围 + * @return 根订单 ID 分页结果 + */ + IPage selectRootOrderIdList(@Param("page") IPage page, + @Param("req") VeneerManageOrderPageReqVO req, + @Param("orderDateTime") LocalDateTime[] orderDateTime); + + /** + * 根据根订单 ID 查询订单及子订单信息。 + * + * @param page 分页参数 + * @param rootIds 根订单 ID 列表 + * @return 订单列表 + */ + IPage selectOrderList(@Param("page") IPage page, + @Param("rootIds") List rootIds); + + /** + * 分页查询存在已分解贴皮板件的板材。 + * + * @param page 分页参数 + * @param req 板材查询条件 + * @return 板材分页结果 + */ + IPage selectGoodsPage(@Param("page") IPage page, + @Param("req") VeneerManageGoodsPageReqVO req); + + /** + * 按订单查询已分解板件贴皮列表。 + * + * @param orderIds 订单ID列表 + * @return 已分解板件贴皮列表 + */ + List selectOrderPlateList(@Param("orderIds") List orderIds); + + /** + * 按板材商品编码查询已分解板件贴皮列表。 + * + * @param goodsIds 板材商品编码列表 + * @return 已分解板件贴皮列表 + */ + List selectGoodsPlateList(@Param("goodsIds") List goodsIds); +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerDecomposeService.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerDecomposeService.java new file mode 100644 index 000000000..2914a00f2 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerDecomposeService.java @@ -0,0 +1,57 @@ +package com.cf.imes.module.executor.service.veneer; + +import com.cf.imes.framework.common.pojo.PageResult; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeCreateReqVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeGoodsPageReqVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeGoodsRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeOrderPageReqVO; +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 java.util.List; + +/** + * 贴皮分解 Service。 + */ +public interface VeneerDecomposeService { + + /** + * 查询待贴皮分解订单分页列表。 + * + * @param req 订单查询参数 + * @return 订单分页结果 + */ + PageResult getOrderPage(VeneerDecomposeOrderPageReqVO req); + + /** + * 查询待贴皮分解材质分页列表。 + * + * @param req 材质查询参数 + * @return 材质分页结果 + */ + PageResult getGoodsPage(VeneerDecomposeGoodsPageReqVO req); + + /** + * 按订单查询未贴皮分解板件列表。 + * + * @param req 查询条件,必须包含订单 ID 列表 + * @return 去重后的板件列表 + */ + List getOrderPlateList(VeneerDecomposePlatePageReqVO req); + + /** + * 按板材查询未贴皮分解板件列表。 + * + * @param req 查询条件,必须包含商品编码列表 + * @return 去重后的板件列表 + */ + List getGoodsPlateList(VeneerDecomposePlatePageReqVO req); + + /** + * 将原板件分解为 A 面和/或 B 面贴皮记录。 + * + * @param req 分解参数 + */ + void decompose(VeneerDecomposeCreateReqVO req); +} 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 new file mode 100644 index 000000000..4ead987b4 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerDecomposeServiceImpl.java @@ -0,0 +1,396 @@ +package com.cf.imes.module.executor.service.veneer; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO; +import com.cf.imes.framework.common.exception.ServiceException; +import com.cf.imes.framework.common.pojo.PageResult; +import com.cf.imes.framework.common.util.date.LocalDateTimeUtils; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeCreateReqVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeGoodsPageReqVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeGoodsRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDecomposeOrderPageReqVO; +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.dal.dataobject.goods.GoodsDO; +import com.cf.imes.module.executor.dal.dataobject.order.OrderDO; +import com.cf.imes.module.executor.dal.dataobject.plate.PlateDO; +import com.cf.imes.module.executor.dal.dataobject.veneer.OrderPlateVeneerDO; +import com.cf.imes.module.executor.dal.dataobject.veneer.VeneerDecomposedPlateCountDO; +import com.cf.imes.module.executor.dal.dataobject.veneer.VeneerDO; +import com.cf.imes.module.executor.dal.mysql.goods.GoodsMapper; +import com.cf.imes.module.executor.dal.mysql.order.OrderMapper; +import com.cf.imes.module.executor.dal.mysql.veneer.OrderPlateVeneerMapper; +import com.cf.imes.module.executor.dal.mysql.veneer.VeneerDecomposeMapper; +import com.cf.imes.module.executor.dal.mysql.veneer.VeneerMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static com.cf.imes.framework.common.pojo.PageParam.PAGE_SIZE_NONE; +import static com.cf.imes.module.executor.enums.ErrorCodeConstants.GOODS_PLATE_UPDATE_CONCURRENCY_ERROR; +import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_PLATE_UPDATE_CONCURRENCY_ERROR; +import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_DECOMPOSE_PLATE_STATUS_CHANGED; +import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_DECOMPOSE_SCOPE_REQUIRED; +import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_DECOMPOSE_SIDE_REQUIRED; +import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_NOT_EXIST; + +/** + * 贴皮分解 Service 实现。 + */ +@Service +public class VeneerDecomposeServiceImpl implements VeneerDecomposeService { + + /** + * 板件查询、状态更新及贴皮记录插入的单批处理数量。 + */ + private static final int DECOMPOSE_BATCH_SIZE = 1000; + + /** + * 订单及订单板材分解数量重新统计的单批处理数量。 + */ + private static final int DECOMPOSE_STAT_BATCH_SIZE = 100; + + /** + * 贴皮逻辑 A 面。 + */ + private static final String VENEER_SIDE_A = "A"; + + /** + * 贴皮逻辑 B 面。 + */ + private static final String VENEER_SIDE_B = "B"; + + /** + * WebCAD 反面排版标识。 + */ + private static final int HOLE_ARRANGE_REVERSE = 1; + + /** + * 板件正面标识。 + */ + private static final int PLATE_SURFACE_FRONT = 0; + + /** + * 板件反面标识。 + */ + private static final int PLATE_SURFACE_BACK = 1; + + @Resource + private VeneerDecomposeMapper veneerDecomposeMapper; + + @Resource + private OrderPlateVeneerMapper orderPlateVeneerMapper; + + @Resource + private VeneerMapper veneerMapper; + + @Resource + private OrderMapper orderMapper; + + @Resource + private GoodsMapper goodsMapper; + + @Override + public PageResult getOrderPage(VeneerDecomposeOrderPageReqVO req) { + PageDTO page = new PageDTO<>(req.getPageNo(), req.getPageSize()); + IPage rootPage = veneerDecomposeMapper.selectRootOrderIdList( + page, req, LocalDateTimeUtils.generateTimeSection(req.getOrderDate())); + List rootIds = rootPage.getRecords(); + if (CollUtil.isEmpty(rootIds)) { + return new PageResult<>(); + } + IPage result = veneerDecomposeMapper.selectOrderList( + new PageDTO<>(req.getPageNo(), PAGE_SIZE_NONE), rootIds); + return new PageResult<>(result.getRecords(), rootPage.getTotal()); + } + + @Override + public PageResult getGoodsPage(VeneerDecomposeGoodsPageReqVO req) { + IPage result = veneerDecomposeMapper.selectGoodsPage( + new PageDTO<>(req.getPageNo(), req.getPageSize()), req); + return new PageResult<>(result.getRecords(), result.getTotal()); + } + + @Override + public List getOrderPlateList(VeneerDecomposePlatePageReqVO req) { + if (CollUtil.isEmpty(req.getOrderIds())) { + return List.of(); + } + return distinctPlate(veneerDecomposeMapper.selectOrderPlateList(req)); + } + + @Override + public List getGoodsPlateList(VeneerDecomposePlatePageReqVO req) { + if (CollUtil.isEmpty(req.getGoodsIds())) { + return List.of(); + } + return distinctPlate(veneerDecomposeMapper.selectGoodsPlateList(req)); + } + + /** + * 一块板可关联多个加工组,查询结果按板件主键保留第一条。 + * 房间、柜体是板件的唯一归属,因此同一板的多条加工组记录展示信息一致。 + * + * @param plates 数据库查询得到的板件原始列表 + * @return 按板件主键去重后的列表 + */ + private List distinctPlate(List plates) { + if (CollUtil.isEmpty(plates)) { + return plates; + } + Map plateMap = new LinkedHashMap<>(); + for (VeneerDecomposePlateRespVO plate : plates) { + plateMap.putIfAbsent(plate.getPlateId(), plate); + } + return new ArrayList<>(plateMap.values()); + } + + /** + * 执行贴皮分解:一块原板按所选 A/B 面生成一条或两条贴皮记录,原板计数只增加一次。 + * + * @param req 贴皮分解参数 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void decompose(VeneerDecomposeCreateReqVO req) { + // orderIds 非空表示按订单分解;否则必须指定板材商品编码。 + if (!req.isByOrder() && (req.getGoodsId() == null || req.getGoodsId().isBlank())) { + throw new ServiceException(VENEER_DECOMPOSE_SCOPE_REQUIRED); + } + // A、B 面允许分别选择贴皮,但至少需要选择一面。 + if (req.getAVeneerId() == null && req.getBVeneerId() == null) { + throw new ServiceException(VENEER_DECOMPOSE_SIDE_REQUIRED); + } + + List plateNos = req.getPlateNos().stream().distinct().sorted().toList(); + // 板件编号分批查询,避免一次生成过长的 IN 条件。 + List plates = new ArrayList<>(); + for (List plateNoBatch : CollUtil.split(plateNos, DECOMPOSE_BATCH_SIZE)) { + plates.addAll(veneerDecomposeMapper.selectUndecomposedPlateList(req, plateNoBatch)); + } + // 数量不一致通常表示板件已被其他用户分解,阻止本次请求继续覆盖状态。 + if (plates.size() != plateNos.size()) { + throw new ServiceException(VENEER_DECOMPOSE_PLATE_STATUS_CHANGED); + } + + // 先锁定受影响订单,避免同一订单的并发分解互相覆盖重新统计的结果。 + List affectedOrderIds = plates.stream().map(PlateDO::getOrderId).distinct().sorted().toList(); + for (List orderIdBatch : CollUtil.split(affectedOrderIds, DECOMPOSE_BATCH_SIZE)) { + veneerDecomposeMapper.selectOrderIdForUpdate(orderIdBatch); + } + + // 从贴皮库加载 A/B 面贴皮,并将贴皮属性以快照形式写入板件贴皮表。 + Map sourceVeneerMap = loadSourceVeneers(req); + List plateVeneers = new ArrayList<>(); + for (PlateDO plate : plates) { + if (req.getAVeneerId() != null) { + plateVeneers.add(buildPlateVeneer( + plate, sourceVeneerMap.get(req.getAVeneerId()), VENEER_SIDE_A, req.getOuterMargin())); + } + if (req.getBVeneerId() != null) { + plateVeneers.add(buildPlateVeneer( + plate, sourceVeneerMap.get(req.getBVeneerId()), VENEER_SIDE_B, req.getOuterMargin())); + } + } + + // 原板状态分批更新;租户插件追加 organ_id 后由 MyCat 按组织路由。 + List plateIds = plates.stream().map(PlateDO::getId).toList(); + for (List plateIdBatch : CollUtil.split(plateIds, DECOMPOSE_BATCH_SIZE)) { + // 条件中包含 is_decomposed=false,通过每批更新行数进行第二次并发校验。 + int updated = veneerDecomposeMapper.updatePlateDecomposed(plateIdBatch); + if (updated != plateIdBatch.size()) { + throw new ServiceException(VENEER_DECOMPOSE_PLATE_STATUS_CHANGED); + } + } + + // A/B 贴皮记录分批插入,控制单条 INSERT 的参数数量和报文大小。 + for (List plateVeneerBatch + : CollUtil.split(plateVeneers, DECOMPOSE_BATCH_SIZE)) { + orderPlateVeneerMapper.insertBatch(plateVeneerBatch); + } + + // 以 order_plate 当前状态为准重新统计,不使用本次请求数量做增量计算。 + List affectedOrderGoodsIds = plates.stream() + .map(PlateDO::getGoodsId).distinct().sorted().toList(); + refreshOrderDecomposedPlateCount(affectedOrderIds); + refreshGoodsDecomposedPlateCount(affectedOrderGoodsIds); + } + + /** + * 从 order_plate 重新统计并覆盖订单的已分解贴皮板件数量。 + * 每批处理 100 个订单,更新时使用 version 进行乐观锁校验。 + * + * @param orderIds 需要重新统计的订单ID列表 + */ + private void refreshOrderDecomposedPlateCount(List orderIds) { + for (List orderIdBatch : CollUtil.split(orderIds, DECOMPOSE_STAT_BATCH_SIZE)) { + // 先读取当前版本,后续任何并发修改都会使版本条件更新失败。 + Map orderMap = new HashMap<>(); + for (OrderDO order : orderMapper.selectByIds(orderIdBatch)) { + orderMap.put(order.getId(), order); + } + List databaseCounts = + veneerDecomposeMapper.selectOrderDecomposedPlateCount(orderIdBatch); + Map countMap = convertDecomposedPlateCount(databaseCounts); + + for (Long orderId : orderIdBatch) { + OrderDO order = orderMap.get(orderId); + if (order == null) { + throw new ServiceException(ORDER_PLATE_UPDATE_CONCURRENCY_ERROR, orderId); + } + int version = order.getVersion(); + int update = orderMapper.update(new LambdaUpdateWrapper() + .eq(OrderDO::getId, orderId) + .eq(OrderDO::getVersion, version) + .set(OrderDO::getDecomposedVeneerPlateNum, countMap.getOrDefault(orderId, 0)) + .set(OrderDO::getVersion, version + 1)); + if (update == 0) { + throw new ServiceException(ORDER_PLATE_UPDATE_CONCURRENCY_ERROR, orderId); + } + } + } + } + + /** + * 从 order_plate 重新统计并覆盖订单板材的已分解贴皮板件数量。 + * 每批处理 100 条订单板材,更新时使用 version 进行乐观锁校验。 + * + * @param orderGoodsIds 需要重新统计的 {@code order_goods} 主键列表 + */ + private void refreshGoodsDecomposedPlateCount(List orderGoodsIds) { + for (List orderGoodsIdBatch : CollUtil.split(orderGoodsIds, DECOMPOSE_STAT_BATCH_SIZE)) { + // 先读取当前版本,防止用旧统计结果覆盖其他业务刚完成的更新。 + Map goodsMap = new HashMap<>(); + for (GoodsDO goods : goodsMapper.selectByIds(orderGoodsIdBatch)) { + goodsMap.put(goods.getId(), goods); + } + List databaseCounts = + veneerDecomposeMapper.selectGoodsDecomposedPlateCount(orderGoodsIdBatch); + Map countMap = convertDecomposedPlateCount(databaseCounts); + + for (Long orderGoodsId : orderGoodsIdBatch) { + GoodsDO goods = goodsMap.get(orderGoodsId); + if (goods == null) { + throw new ServiceException(GOODS_PLATE_UPDATE_CONCURRENCY_ERROR, orderGoodsId); + } + int version = goods.getVersion(); + int update = goodsMapper.update(new LambdaUpdateWrapper() + .eq(GoodsDO::getId, orderGoodsId) + .eq(GoodsDO::getVersion, version) + .set(GoodsDO::getDecomposedVeneerPlateNum, + countMap.getOrDefault(orderGoodsId, 0)) + .set(GoodsDO::getVersion, version + 1)); + if (update == 0) { + throw new ServiceException(GOODS_PLATE_UPDATE_CONCURRENCY_ERROR, orderGoodsId); + } + } + } + } + + /** + * 将数据库聚合结果转换为目标ID与已分解数量的映射。 + * 未出现在映射中的目标由调用方按 0 处理。 + * + * @param databaseCounts 数据库聚合统计结果 + * @return 目标ID与已分解板件数量的映射 + */ + private Map convertDecomposedPlateCount( + List databaseCounts) { + Map countMap = new HashMap<>(); + for (VeneerDecomposedPlateCountDO databaseCount : databaseCounts) { + countMap.put(databaseCount.getTargetId(), databaseCount.getDecomposedPlateNum()); + } + return countMap; + } + + /** + * 加载 A/B 面选中的贴皮库数据,并按贴皮库主键构建映射。 + * + * @param req 贴皮分解参数 + * @return 贴皮库主键与贴皮数据的映射 + */ + private Map loadSourceVeneers(VeneerDecomposeCreateReqVO req) { + // A、B 可能选择同一贴皮,先去重,避免重复查询贴皮库。 + Set veneerIds = new HashSet<>(); + if (req.getAVeneerId() != null) { + veneerIds.add(req.getAVeneerId()); + } + if (req.getBVeneerId() != null) { + veneerIds.add(req.getBVeneerId()); + } + Map result = new HashMap<>(); + for (Long veneerId : veneerIds) { + VeneerDO veneer = veneerMapper.selectById(veneerId); + if (veneer == null) { + throw new ServiceException(VENEER_NOT_EXIST); + } + result.put(veneerId, veneer); + } + return result; + } + + /** + * 根据原板件、贴皮逻辑面及贴皮库快照构建一条板件贴皮记录。 + * + * @param plate 原板件 + * @param sourceVeneer 选中的贴皮库数据 + * @param veneerSide 贴皮逻辑面 + * @param outerMargin 外扩余量 + * @return 待保存的板件贴皮记录 + */ + private OrderPlateVeneerDO buildPlateVeneer(PlateDO plate, VeneerDO sourceVeneer, + String veneerSide, BigDecimal outerMargin) { + int plateSurface = resolvePlateSurface(plate.getHoleArrange(), veneerSide); + return OrderPlateVeneerDO.builder() + .organId(plate.getOrganId()) + .orderId(plate.getOrderId()) + .orderGoodsId(plate.getGoodsId()) + .orderPlateId(plate.getId()) + .plateNo(plate.getPlateNo()) + .plateName(plate.getName()) + .plateLength(plate.getHeight()) + .plateWidth(plate.getWidth()) + .plateThickness(plate.getThickness()) + .holeArrange(plate.getHoleArrange()) + .veneerSide(veneerSide) + .plateSurface(plateSurface) + .veneerNo(plate.getPlateNo() + veneerSide) + .outerMargin(outerMargin) + .sourceVeneerId(sourceVeneer.getId()) + .sourceVeneerNo(sourceVeneer.getVeneerNo()) + .veneerName(sourceVeneer.getVeneerName()) + .productLevel(sourceVeneer.getProductLevel()) + .color(ObjectUtil.defaultIfNull(sourceVeneer.getColor(), "")) + .material(ObjectUtil.defaultIfNull(sourceVeneer.getMaterial(), "")) + .build(); + } + + /** + * 根据 WebCAD 排版面和贴皮逻辑面确定实际板件面。 + * 反面排版时 A 面对应反面、B 面对应正面;正面或随意面排版时关系相反。 + * + * @param holeArrange WebCAD 排版面 + * @param veneerSide 贴皮逻辑面 + * @return 实际板件面 + */ + private int resolvePlateSurface(Integer holeArrange, String veneerSide) { + boolean reverseArrange = Integer.valueOf(HOLE_ARRANGE_REVERSE).equals(holeArrange); + if (VENEER_SIDE_A.equals(veneerSide)) { + return reverseArrange ? PLATE_SURFACE_BACK : PLATE_SURFACE_FRONT; + } + return reverseArrange ? PLATE_SURFACE_FRONT : PLATE_SURFACE_BACK; + } +} 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 new file mode 100644 index 000000000..003971bbd --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerManageService.java @@ -0,0 +1,57 @@ +package com.cf.imes.module.executor.service.veneer; + +import com.cf.imes.framework.common.pojo.PageResult; +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; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageOrderRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManagePlateListReqVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManagePlateRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageReselectReqVO; + +import java.util.List; + +/** + * 贴皮管理 Service。 + */ +public interface VeneerManageService { + + /** + * 分页查询存在已分解贴皮板件的订单。 + * + * @param req 订单查询条件 + * @return 订单分页结果 + */ + PageResult getOrderPage(VeneerManageOrderPageReqVO req); + + /** + * 分页查询存在已分解贴皮板件的板材。 + * + * @param req 板材查询条件 + * @return 板材分页结果 + */ + PageResult getGoodsPage(VeneerManageGoodsPageReqVO req); + + /** + * 按订单查询已分解板件贴皮列表。 + * + * @param req 查询条件,必须包含订单ID列表 + * @return 已分解板件贴皮列表 + */ + List getOrderPlateList(VeneerManagePlateListReqVO req); + + /** + * 按板材查询已分解板件贴皮列表。 + * + * @param req 查询条件,必须包含板材商品编码列表 + * @return 已分解板件贴皮列表 + */ + List getGoodsPlateList(VeneerManagePlateListReqVO req); + + /** + * 批量为已分解板件贴皮重新选择贴皮库数据。 + * + * @param req 板件贴皮记录ID及新贴皮库ID + */ + void reselectVeneer(VeneerManageReselectReqVO 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 new file mode 100644 index 000000000..1163548ea --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/veneer/VeneerManageServiceImpl.java @@ -0,0 +1,152 @@ +package com.cf.imes.module.executor.service.veneer; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO; +import com.cf.imes.framework.common.exception.ServiceException; +import com.cf.imes.framework.common.pojo.PageResult; +import com.cf.imes.framework.common.util.date.LocalDateTimeUtils; +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; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageOrderRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManagePlateListReqVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManagePlateRespVO; +import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerManageReselectReqVO; +import com.cf.imes.module.executor.dal.dataobject.veneer.OrderPlateVeneerDO; +import com.cf.imes.module.executor.dal.dataobject.veneer.VeneerDO; +import com.cf.imes.module.executor.dal.mysql.veneer.OrderPlateVeneerMapper; +import com.cf.imes.module.executor.dal.mysql.veneer.VeneerManageMapper; +import com.cf.imes.module.executor.dal.mysql.veneer.VeneerMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Objects; + +import static com.cf.imes.framework.common.pojo.PageParam.PAGE_SIZE_NONE; +import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_NOT_EXIST; +import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_RESELECT_RECORD_REQUIRED; +import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_RESELECT_RECORD_STATUS_CHANGED; +import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_RESELECT_SOURCE_REQUIRED; + +/** + * 贴皮管理 Service 实现。 + */ +@Service +public class VeneerManageServiceImpl implements VeneerManageService { + + /** + * 重选贴皮单批处理数量。 + */ + private static final int RESELECT_BATCH_SIZE = 1000; + + @Resource + private VeneerManageMapper veneerManageMapper; + + @Resource + private OrderPlateVeneerMapper orderPlateVeneerMapper; + + @Resource + private VeneerMapper veneerMapper; + + @Override + public PageResult getOrderPage(VeneerManageOrderPageReqVO req) { + PageDTO page = new PageDTO<>(req.getPageNo(), req.getPageSize()); + IPage rootPage = veneerManageMapper.selectRootOrderIdList( + page, req, LocalDateTimeUtils.generateTimeSection(req.getOrderDate())); + List rootIds = rootPage.getRecords(); + if (CollUtil.isEmpty(rootIds)) { + return new PageResult<>(); + } + IPage result = veneerManageMapper.selectOrderList( + new PageDTO<>(req.getPageNo(), PAGE_SIZE_NONE), rootIds); + return new PageResult<>(result.getRecords(), rootPage.getTotal()); + } + + @Override + public PageResult getGoodsPage(VeneerManageGoodsPageReqVO req) { + IPage result = veneerManageMapper.selectGoodsPage( + new PageDTO<>(req.getPageNo(), req.getPageSize()), req); + return new PageResult<>(result.getRecords(), result.getTotal()); + } + + @Override + public List getOrderPlateList(VeneerManagePlateListReqVO req) { + if (CollUtil.isEmpty(req.getOrderIds())) { + return List.of(); + } + return veneerManageMapper.selectOrderPlateList(req.getOrderIds()); + } + + @Override + public List getGoodsPlateList(VeneerManagePlateListReqVO req) { + if (CollUtil.isEmpty(req.getGoodsIds())) { + return List.of(); + } + return veneerManageMapper.selectGoodsPlateList(req.getGoodsIds()); + } + + /** + * 批量重选贴皮,仅替换所选 A/B 面记录的贴皮库关联及贴皮属性快照。 + * + * @param req 批量重选贴皮参数 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void reselectVeneer(VeneerManageReselectReqVO req) { + if (CollUtil.isEmpty(req.getIds())) { + throw new ServiceException(VENEER_RESELECT_RECORD_REQUIRED); + } + if (ObjectUtil.isNull(req.getVeneerId())) { + throw new ServiceException(VENEER_RESELECT_SOURCE_REQUIRED); + } + + List ids = req.getIds().stream() + .filter(Objects::nonNull) + .distinct() + .sorted() + .toList(); + if (CollUtil.isEmpty(ids)) { + throw new ServiceException(VENEER_RESELECT_RECORD_REQUIRED); + } + + // 查询新贴皮数据,后续统一更新为当前贴皮库属性快照。 + VeneerDO veneer = veneerMapper.selectById(req.getVeneerId()); + if (ObjectUtil.isNull(veneer)) { + throw new ServiceException(VENEER_NOT_EXIST); + } + + for (List idBatch : CollUtil.split(ids, RESELECT_BATCH_SIZE)) { + // 锁定本批有效记录,避免重选过程中记录被移除。 + List records = orderPlateVeneerMapper.selectList( + new LambdaQueryWrapper() + .select(OrderPlateVeneerDO::getId) + .in(OrderPlateVeneerDO::getId, idBatch) + .last("FOR UPDATE")); + if (records.size() != idBatch.size()) { + throw new ServiceException(VENEER_RESELECT_RECORD_STATUS_CHANGED); + } + + // 生成贴皮编号及原板信息保持不变,只替换贴皮库关联和五个展示快照字段。 + int updated = orderPlateVeneerMapper.update( + new LambdaUpdateWrapper() + .in(OrderPlateVeneerDO::getId, idBatch) + .set(OrderPlateVeneerDO::getSourceVeneerId, veneer.getId()) + .set(OrderPlateVeneerDO::getSourceVeneerNo, veneer.getVeneerNo()) + .set(OrderPlateVeneerDO::getVeneerName, veneer.getVeneerName()) + .set(OrderPlateVeneerDO::getProductLevel, veneer.getProductLevel()) + .set(OrderPlateVeneerDO::getColor, + ObjectUtil.defaultIfNull(veneer.getColor(), "")) + .set(OrderPlateVeneerDO::getMaterial, + ObjectUtil.defaultIfNull(veneer.getMaterial(), ""))); + if (updated != idBatch.size()) { + throw new ServiceException(VENEER_RESELECT_RECORD_STATUS_CHANGED); + } + } + } +} 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 new file mode 100644 index 000000000..c8baa1b6f --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/veneer/VeneerDecomposeMapper.xml @@ -0,0 +1,278 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UPDATE order_plate + SET is_decomposed = true + WHERE is_decomposed = false + AND id IN + + #{plateId} + + + + + + + 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 new file mode 100644 index 000000000..11f6ecb5f --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/veneer/VeneerManageMapper.xml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + opv.id, + opv.veneer_no AS veneerNo, + opv.plate_no AS plateNo, + opv.plate_name AS plateName, + opv.plate_length AS length, + opv.plate_width AS width, + opv.plate_thickness AS thickness, + opv.source_veneer_no AS sourceVeneerNo, + opv.veneer_name AS veneerName, + opv.product_level AS productLevel, + opv.color, + opv.material + + + + + + 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 a0b81f29d..85c790d9f 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 @@ -70,6 +70,14 @@ plate.is.source=小板:{0} 為來源板,無法刪除 plate.attr.group.exists=名稱、材質、顏色、厚度、品牌組合已存在,請檢查後提交 veneer.not.exist=貼皮不存在 +veneer.decompose.scope.required=訂單ID列表和板材商品編碼不能同時為空 +veneer.decompose.side.required=A面和B面貼皮至少選擇一個 +veneer.decompose.plate.status.changed=板件分解狀態已變更,請重新整理後再試 +veneer.decompose.plate.no.required=板件編號不能為空 +veneer.decompose.outer.margin.min=外擴餘量不能小於0 +veneer.reselect.record.required=請選擇需要重選貼皮的資料 +veneer.reselect.source.required=請選擇新的貼皮 +veneer.reselect.record.status.changed=板件貼皮資料狀態已變更,請重新整理後再試 veneer.no.exist=貼皮編號已存在 veneer.import.required.lack=第{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 818615efb..f8da0e3fb 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 @@ -70,6 +70,14 @@ plate.is.source=Plate {0} is a source plate and cannot be deleted plate.attr.group.exists=Combination of name, material, color, thickness, and brand already exists veneer.not.exist=veneer not exist +veneer.decompose.scope.required=Order ID list and goods code cannot both be empty +veneer.decompose.side.required=At least one veneer must be selected for side A or B +veneer.decompose.plate.status.changed=Plate decomposition status has changed. Please refresh and retry +veneer.decompose.plate.no.required=Plate numbers cannot be empty +veneer.decompose.outer.margin.min=Outer margin cannot be less than 0 +veneer.reselect.record.required=Please select records for veneer reselection +veneer.reselect.source.required=Please select a new veneer +veneer.reselect.record.status.changed=Plate veneer data has changed. Please refresh and retry veneer.no.exist=veneer no already exists veneer.import.required.lack=The required field is empty in line {0}, please check the file 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 f5ec6ddd2..ec8d0c24f 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 @@ -70,6 +70,14 @@ plate.is.source=小板:{0} 为源小板,无法删除 plate.attr.group.exists=当前名称、材质、颜色、厚度、品牌的组合已存在,请检查后提交 veneer.not.exist=贴皮不存在 +veneer.decompose.scope.required=订单ID列表和板材商品编码不能同时为空 +veneer.decompose.side.required=A面和B面贴皮至少选择一个 +veneer.decompose.plate.status.changed=板件分解状态已变更,请刷新后重试 +veneer.decompose.plate.no.required=板件编号不能为空 +veneer.decompose.outer.margin.min=外扩余量不能小于0 +veneer.reselect.record.required=请选择需要重选贴皮的数据 +veneer.reselect.source.required=请选择新的贴皮 +veneer.reselect.record.status.changed=板件贴皮数据状态已变更,请刷新后重试 veneer.no.exist=贴皮编号已存在 veneer.import.required.lack=第{0}行存在带*必填项为空,请检查文件