diff --git a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/DataTypeEnum.java b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/DataTypeEnum.java index 4a5399262..b335ab4e9 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/DataTypeEnum.java +++ b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/DataTypeEnum.java @@ -9,7 +9,8 @@ public enum DataTypeEnum { FILE_IMPORT(0, "文件导入"), API_IMPORT(1, "API导入"), - SOURCE_IMPORT(2, "数据源导入"); + SOURCE_IMPORT(2, "数据源导入"), + WEBCAD_IMPORT(3, "webcad导入"); private final Integer status; private String description; diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/OrderController.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/OrderController.java index 057282b69..dfdbb4939 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/OrderController.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/OrderController.java @@ -112,6 +112,16 @@ public class OrderController { public static final String ORDER_PLATE_MODEL = "imes_order_plate_model"; // public static final String ORDER_PLATE_MODEL_COMPRESS = "imes_order_plate_model_compress"; public static final String ORDER_PARTS_REMARK_MODEL = "imes_order_parts_remark_model"; + + + + @PostMapping("/create") + @Operation(summary = "创建生产单") + @PreAuthorize("@ss.hasPermission('production:manager-list:create')") + public CommonResult createOrder(@Valid @RequestBody OrderSaveReqVO createReqVO) { + return success(orderService.createOrder(createReqVO)); + } + @PutMapping("/update") @Operation(summary = "更新生产单") @PreAuthorize("@ss.hasPermission('production:manager-list:edit')") diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/ordermodel/OrderModelDO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/ordermodel/OrderModelDO.java index f77b52931..c400549ad 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/ordermodel/OrderModelDO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/ordermodel/OrderModelDO.java @@ -114,4 +114,7 @@ public class OrderModelDO extends ESDocument { private String remarkJson; // 普通备注(板材数据中) @Schema(description = "特殊备注(板材数据中)") private String specialRemark; // 特殊备注(板材数据中) + + @Schema(description = "webcad板材数据") + private String boardData; } \ 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/service/order/OrderService.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderService.java index 317a82484..c3e651c45 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderService.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderService.java @@ -26,6 +26,13 @@ import java.util.Set; */ public interface OrderService { + /** + * 创建生产单表 order_{N} + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createOrder(@Valid OrderSaveReqVO createReqVO); /** * 更新生产单表 order_{N} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderServiceImpl.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderServiceImpl.java index 877299da3..170c1fbad 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderServiceImpl.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderServiceImpl.java @@ -81,7 +81,11 @@ import java.io.*; import java.math.BigDecimal; import java.net.URLEncoder; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.function.Function; @@ -172,6 +176,28 @@ public class OrderServiceImpl implements OrderService { @Autowired private OrderImportHandlerFactory orderImportHandlerFactory; + @Override + public Long createOrder(OrderSaveReqVO createReqVO) { + //校验手机号是否合法 + validatePhoneNumber(createReqVO.getPhoneNumber()); + + //验证自定义单号是否存在,业务员、拆单员是否存在 + validateCustomOrderNoExists(createReqVO.getCustomOrderNo()); + LocalDate orderDate = LocalDate.from(createReqVO.getOrderDate()); + LocalDate deliveryDate = LocalDate.from(createReqVO.getDeliveryDate()); + if (deliveryDate.isBefore(orderDate)) { + // 将 deliveryDate 设置为 orderDate 后的第 30 天 + deliveryDate = orderDate.plusMonths(1); + } + createReqVO.setDeliveryDate(deliveryDate.atStartOfDay()); + // 插入 + OrderDO order = BeanUtils.toBean(createReqVO, OrderDO.class); + order.setId((Long)identifierGenerator.nextId(null)); + orderMapper.insert(order); + // 返回 + return order.getId(); + } + @Override public void updateOrder(OrderSaveReqVO updateReqVO) { // 校验存在, 生产单未删除 diff --git a/cf-module-prod-plan/cf-module-prod-plan-api/src/main/java/com/cf/imes/module/plan/enums/ErrorCodeConstants.java b/cf-module-prod-plan/cf-module-prod-plan-api/src/main/java/com/cf/imes/module/plan/enums/ErrorCodeConstants.java index d9c2f3e98..163b52115 100644 --- a/cf-module-prod-plan/cf-module-prod-plan-api/src/main/java/com/cf/imes/module/plan/enums/ErrorCodeConstants.java +++ b/cf-module-prod-plan/cf-module-prod-plan-api/src/main/java/com/cf/imes/module/plan/enums/ErrorCodeConstants.java @@ -11,4 +11,9 @@ public class ErrorCodeConstants { public static final ErrorCode ORDER_IMPORT_PLATE_GOODS_NOT_EXISTS = new ErrorCode(1_005_000_000, "{}小板数据不存在:{}"); public static final ErrorCode ORDER_IMPORT_ORGANID_NOT_EXISTS = new ErrorCode(1_005_000_001, "不存在组织id,导入终止"); public static final ErrorCode ORDER_IMPORT_FAIL = new ErrorCode(1_005_000_002, "导入失败"); + public static final ErrorCode WEBCAD_ORDER_NOT_EXISTS_ERROR = new ErrorCode(1_005_000_004, "导入失败:生产单号【{}】不存在"); + public static final ErrorCode WEBCAD_ORDER_IMPORT_MATERIALS_EMPTY_ERROR = new ErrorCode(1_005_000_005, "导入失败:板材对应列表不能为空"); + public static final ErrorCode WEBCAD_ORDER_IMPORT_ROOMBODY_EMPTY_ERROR = new ErrorCode(1_005_000_006, "导入失败:房间柜体列表不能为空"); + public static final ErrorCode WEBCAD_ORDER_IMPORT_ORGANID_EMPTY_ERROR = new ErrorCode(1_005_000_007, "导入失败:无法获取机构信息,请检查cadtoken是否配置正确"); + public static final ErrorCode WEBCAD_ORDER_IMPORT_FAILED = new ErrorCode(1_005_000_008, "导入失败:请检查拆单数据"); } diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/OrderImportController.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/OrderImportController.java new file mode 100644 index 000000000..b8afa9f78 --- /dev/null +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/OrderImportController.java @@ -0,0 +1,38 @@ +package com.cf.imes.module.plan.controller.admin.orderImport; + +import com.cf.imes.framework.operatelog.core.annotations.OperateLog; +import com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo.WebCadDataReqVO; +import com.cf.imes.module.plan.service.orderImport.WebCadOrderImportService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +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 javax.annotation.Resource; + +import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.IMPORT; + +/** + * @author Gqr + * @since 2025/3/4 10:22 + */ +@Tag(name = "管理后台 - 生产单导入管理") +@RestController +@RequestMapping("/plan/order") +@Validated +@Slf4j +public class OrderImportController { + @Resource + private WebCadOrderImportService webCadOrderImportService; + + @PostMapping("/webcad/import") + @Operation(summary = "生产单导入新增") + @OperateLog(type = IMPORT) + public void webCadOrderImport(@RequestBody WebCadDataReqVO webCadDataReqVO) { + webCadOrderImportService.webCadOrderImport(webCadDataReqVO); + } +} diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataBlockReqVO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataBlockReqVO.java new file mode 100644 index 000000000..3756581ed --- /dev/null +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataBlockReqVO.java @@ -0,0 +1,475 @@ +package com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Gqr + * @since 2025/3/3 17:57 + */ +@NoArgsConstructor +@Schema(description = "管理后台 - webcad板件信息 - RequestVO") +@Data +public class WebCadDataBlockReqVO { + private Integer orginId; + private Integer objectId; + private String name; + private Integer type; + private Integer custBlockNo; + private Double width; + private Double height; + private String material; + private String materialName; + private Integer thickness; + private Integer boardType; + private Double area; + private Integer texture; + private Integer holeFace; + private Integer holeArrange; + @JsonProperty(value = "unregular_point_count") + private Integer unregularPointCount; + private List frontBackHoles; + private List sideHoles; + private Integer frontHoleCount; + private Integer backHoleCount; + private Integer sideHoleCount; + private Integer frontModelCount; + private Integer backModelCount; + private Boolean isDoor; + private Integer openDoorType; + private Double offsetX; + private Double offsetY; + private Boolean isArcBase; + private Boolean isSpecialShape; + private String remark; + private Double kaiLiaoHeight; + private Double kaiLiaoWidth; + private InfoDTO info; + private String cabinetName; + private String roomName; + private Double cabinetDepth; + private Double cabinetWidth; + private Double cabinetHeight; + private BoadrData boardData; + + private String plateGoodsId; + private String goodsId; + + private List groupInfos = new ArrayList<>(); + + @NoArgsConstructor + @Data + public static class GroupInfo { + private String groupTypeName; + private String groupName; + private Double width; + private Double height; + private Double depth; + } + + @NoArgsConstructor + @Data + public static class InfoDTO { + private Integer id; + private String name; + private String roomName; + private String cabinetName; + private String material; + private String boardName; + private String color; + private Integer lines; + private String drillType; + private Integer thickness; + private String spliteHeight; + private String spliteThickness; + private String spliteWidth; + private Boolean isRect; + private List> remarks; + private Double kaiLiaoWidth; + private Double kaiLiaoHeight; + private Integer openDir; + } + + @NoArgsConstructor + @Data + public static class FrontBackHolesDTO { + private Integer type; + private PositionDTO position; + private Double radius; + private Double depth; + private Integer face; + private Double angle; + private String name; + private String goodsId; + + @NoArgsConstructor + @Data + public static class PositionDTO { + private Double x; + private Double y; + private Double z; + } + } + + @NoArgsConstructor + @Data + public static class SideHolesDTO { + private Integer type; + private PositionDTO position; + private EndPtDTO endPt; + private Integer radius; + private Double depth; + private Integer face; + private String name; + private String goodsId; + + @NoArgsConstructor + @Data + public static class PositionDTO { + private Double x; + private Double y; + private Double z; + } + + @NoArgsConstructor + @Data + public static class EndPtDTO { + private Double x; + private Double y; + private Integer z; + } + } + + @NoArgsConstructor + @Data + public static class BoadrData { + @JsonProperty("originOutlin") + private OriginOutlinDTO originOutlin; + @JsonProperty("outline") + private OutlineDTO outline; + @JsonProperty("sealing") + private List sealing; + @JsonProperty("boardEdgeRemark") + private List boardEdgeRemark; + @JsonProperty("reservedEdge") + private List reservedEdge; + @JsonProperty("modeling") + private List modeling; + @JsonProperty("curveBoardModeling") + private List curveBoardModeling; + @JsonProperty("holes") + private HolesDTO holes; + @JsonProperty("sideModeling") + private List sideModeling; + @JsonProperty("offsetTanslation") + private OffsetTanslationDTO offsetTanslation; + @JsonProperty("metalsData") + private MetalsDataDTO metalsData; + @JsonProperty("modeling2D") + private List modeling2D; + @JsonProperty("modeling3D") + private List modeling3D; + @JsonProperty("isReverse") + private Boolean isReverse; + + @NoArgsConstructor + @Data + public static class InfoDTO { + @JsonProperty("id") + private Integer id; + @JsonProperty("name") + private String name; + @JsonProperty("roomName") + private String roomName; + @JsonProperty("cabinetName") + private String cabinetName; + @JsonProperty("material") + private String material; + @JsonProperty("boardName") + private String boardName; + @JsonProperty("color") + private String color; + @JsonProperty("lines") + private Integer lines; + @JsonProperty("drillType") + private String drillType; + @JsonProperty("thickness") + private Integer thickness; + @JsonProperty("spliteHeight") + private String spliteHeight; + @JsonProperty("spliteThickness") + private String spliteThickness; + @JsonProperty("spliteWidth") + private String spliteWidth; + @JsonProperty("isRect") + private Boolean isRect; + @JsonProperty("remarks") + private List> remarks; + @JsonProperty("kaiLiaoWidth") + private Double kaiLiaoWidth; + @JsonProperty("kaiLiaoHeight") + private Double kaiLiaoHeight; + @JsonProperty("openDir") + private Integer openDir; + } + + @NoArgsConstructor + @Data + public static class OriginOutlinDTO { + @JsonProperty("pts") + private List pts; + @JsonProperty("buls") + private List buls; + + @NoArgsConstructor + @Data + public static class PtsDTO { + @JsonProperty("x") + private Double x; + @JsonProperty("y") + private Integer y; + } + } + + @NoArgsConstructor + @Data + public static class OutlineDTO { + @JsonProperty("pts") + private List pts; + @JsonProperty("buls") + private List buls; + + @NoArgsConstructor + @Data + public static class PtsDTO { + @JsonProperty("x") + private Double x; + @JsonProperty("y") + private Integer y; + } + } + + @NoArgsConstructor + @Data + public static class HolesDTO { + @JsonProperty("frontBackHoles") + private List frontBackHoles; + @JsonProperty("sideHoles") + private List sideHoles; + } + + @NoArgsConstructor + @Data + public static class OffsetTanslationDTO { + @JsonProperty("x") + private Double x; + @JsonProperty("y") + private Double y; + @JsonProperty("z") + private Integer z; + } + + @NoArgsConstructor + @Data + public static class MetalsDataDTO { + @JsonProperty("metals") + private Integer metals; + @JsonProperty("comp") + private Integer comp; + } + + @NoArgsConstructor + @Data + public static class SealingDTO { + @JsonProperty("length") + private Double length; + @JsonProperty("size") + private Integer size; + @JsonProperty("sealColor") + private String sealColor; + } + + @NoArgsConstructor + @Data + public static class BoardEdgeRemarkDTO { + @JsonProperty("description") + private String description; + } + + @NoArgsConstructor + @Data + public static class ReservedEdgeDTO { + @JsonProperty("size") + private Integer size; + } + + @NoArgsConstructor + @Data + public static class ModelingDTO { + @JsonProperty("feeding") + private List feeding; + @JsonProperty("thickness") + private Integer thickness; + @JsonProperty("dir") + private Integer dir; + @JsonProperty("knifeRadius") + private Integer knifeRadius; + @JsonProperty("origin") + private OriginDTO origin; + + @NoArgsConstructor + @Data + public static class OriginDTO { + @JsonProperty("outline") + private OutlineDTO outline; + @JsonProperty("holes") + private List holes; + @JsonProperty("addLen") + private Integer addLen; + @JsonProperty("addWidth") + private Integer addWidth; + @JsonProperty("addDepth") + private Integer addDepth; + + @NoArgsConstructor + @Data + public static class OutlineDTO { + @JsonProperty("pts") + private List pts; + @JsonProperty("buls") + private List buls; + + @NoArgsConstructor + @Data + public static class PtsDTO { + @JsonProperty("x") + private Double x; + @JsonProperty("y") + private Double y; + } + } + } + + @NoArgsConstructor + @Data + public static class FeedingDTO { + @JsonProperty("pts") + private List pts; + @JsonProperty("buls") + private List buls; + + @NoArgsConstructor + @Data + public static class PtsDTO { + @JsonProperty("x") + private Double x; + @JsonProperty("y") + private Double y; + } + } + } + + @NoArgsConstructor + @Data + public static class SideModelingDTO { + @JsonProperty("thickness") + private Integer thickness; + @JsonProperty("dir") + private Integer dir; + @JsonProperty("knifeRadius") + private Integer knifeRadius; + @JsonProperty("outline") + private OutlineDTO outline; + @JsonProperty("holes") + private List holes; + @JsonProperty("addLen") + private Integer addLen; + @JsonProperty("addWidth") + private Integer addWidth; + @JsonProperty("addDepth") + private Integer addDepth; + @JsonProperty("chaiDanName") + private String chaiDanName; + @JsonProperty("modelType") + private Integer modelType; + + @NoArgsConstructor + @Data + public static class OutlineDTO { + @JsonProperty("pts") + private List pts; + @JsonProperty("buls") + private List buls; + + @NoArgsConstructor + @Data + public static class PtsDTO { + @JsonProperty("x") + private Double x; + @JsonProperty("y") + private Double y; + } + } + } + + @NoArgsConstructor + @Data + public static class Modeling2DDTO { + @JsonProperty("path") + private PathDTO path; + @JsonProperty("dir") + private Integer dir; + @JsonProperty("items") + private List items; + + @NoArgsConstructor + @Data + public static class PathDTO { + @JsonProperty("pts") + private List pts; + @JsonProperty("buls") + private List buls; + + @NoArgsConstructor + @Data + public static class PtsDTO { + @JsonProperty("x") + private Double x; + @JsonProperty("y") + private Double y; + } + } + + @NoArgsConstructor + @Data + public static class ItemsDTO { + @JsonProperty("depth") + private Integer depth; + @JsonProperty("offset") + private Integer offset; + @JsonProperty("knife") + private KnifeDTO knife; + @JsonProperty("depthExpr") + private String depthExpr; + + @NoArgsConstructor + @Data + public static class KnifeDTO { + @JsonProperty("id") + private String id; + @JsonProperty("radius") + private Integer radius; + @JsonProperty("angle") + private Double angle; + @JsonProperty("name") + private String name; + } + } + } + } +} diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataDoubleRoomTreeReqVO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataDoubleRoomTreeReqVO.java new file mode 100644 index 000000000..20c449d74 --- /dev/null +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataDoubleRoomTreeReqVO.java @@ -0,0 +1,31 @@ +package com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author Gqr + * @since 2025/3/3 18:04 + */ +@NoArgsConstructor +@Data +public class WebCadDataDoubleRoomTreeReqVO { + + + private String name; + + private Integer count; + + private List children; + + @NoArgsConstructor + @Data + public static class ChildrenDTO { + + private String name; + + private Integer count; + } +} diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataMaterialReqVO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataMaterialReqVO.java new file mode 100644 index 000000000..32548a802 --- /dev/null +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataMaterialReqVO.java @@ -0,0 +1,34 @@ +package com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * @author Gqr + * @since 2025/3/3 17:50 + */ +@Schema(description = "管理后台 - webcad板材对应信息 - RequestVO") +@Data +public class WebCadDataMaterialReqVO { + + private Integer thickness; + + private String material; + + private String color; + + private String brand; + + private String goodsId; + + private List orginIds; + + private String name; + + /** + * imes板材id + */ + private String id; +} diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataOrderReqVO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataOrderReqVO.java new file mode 100644 index 000000000..bbaae200b --- /dev/null +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataOrderReqVO.java @@ -0,0 +1,86 @@ +package com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; + +import java.time.LocalDate; + +import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; + +/** + * @author Gqr + * @since 2025/3/3 17:40 + */ +@Schema(description = "管理后台 - webcad生产单信息 - RequestVO") +@Data +public class WebCadDataOrderReqVO { + /** + * 生产单号 + */ + @JsonProperty(value = "OrderNo") + private String OrderNo; + + /** + * 自定义单号 + */ + @JsonProperty(value = "CustomOrderNo") + private String CustomOrderNo; + + /** + * 客户 + */ + @JsonProperty(value = "CustomName") + private String CustomName; + + /** + * 状态 + */ + @JsonProperty(value = "Status") + private int Status; + + /** + * 经销商 + */ + @JsonProperty(value = "SalePerson") + private String SalePerson; + + /** + * 订单日期 + */ + @JsonProperty(value = "OrderDate") + @NotNull(message = "订单日期不能为空") + private String OrderDate; + + /** + * 交付日期 + */ + @NotNull(message = "交付日期不能为空") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + @JsonProperty(value = "DeliveryDate") + private LocalDate DeliveryDate; + + @JsonProperty(value = "Consigee") + private String Consigee; + + @JsonProperty(value = "ConsigeePhone") + private String ConsigeePhone; + + @JsonProperty(value = "ConsigeeAddress") + private String ConsigeeAddress; + + /** + * 拆单员 + */ + @JsonProperty(value = "Splitter") + private String Splitter; + + /** + * 备注 + */ + @JsonProperty(value = "Remark") + private String Remark; +} diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataPartsReqVO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataPartsReqVO.java new file mode 100644 index 000000000..fddc9fffa --- /dev/null +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataPartsReqVO.java @@ -0,0 +1,114 @@ +package com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Gqr + * @since 2025/3/3 17:57 + */ +@NoArgsConstructor +@Schema(description = "管理后台 - webcad配件信息 - RequestVO") +@Data +public class WebCadDataPartsReqVO { + + + private List blockObjectList; + + private List leftEdges; + + @NoArgsConstructor + @Data + public static class BlockObjectListDTO { + + private String roomName; + + private String cabinetName; + + private String name; + + private String type; + + private String model; + + private String spec; + + private String width; + + private String height; + + private String thickness; + + private String material; + + private String brand; + + private String factory; + + private String unit; + + private Double num; + + private Boolean isComposite; + + private String remark; + + private String goodsId; + + private String partId; + + private Integer objectId; + + private Long imesPartsId; + + private List groupInfos = new ArrayList<>(); + + @NoArgsConstructor + @Data + public static class GroupInfo { + private String groupTypeName; + private String groupName; + private Double width; + private Double height; + private Double depth; + } + } + + @NoArgsConstructor + @Data + public static class LeftEdgesDTO { + @JsonProperty("thickness") + private Double thickness; + @JsonProperty("width") + private Double width; + @JsonProperty("height") + private Double height; + @JsonProperty("color") + private String color; + @JsonProperty("material") + private String material; + @JsonProperty("name") + private String name; + @JsonProperty("goodsId") + private String goodsId; + @JsonProperty("id") + private String id; + @JsonProperty("objectIds") + private List objectIds; + @JsonProperty("cabinetNames") + private List cabinetNames; + @JsonProperty("roomNames") + private List roomNames; + @JsonProperty("roomName") + private String roomName; + @JsonProperty("cabinetName") + private String cabinetName; + @JsonProperty("num") + private Double num; + } +} diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataProcessConfigReqVO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataProcessConfigReqVO.java new file mode 100644 index 000000000..130b297fd --- /dev/null +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataProcessConfigReqVO.java @@ -0,0 +1,242 @@ +package com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author Gqr + * @since 2025/3/3 18:06 + */ +@NoArgsConstructor +@Data +public class WebCadDataProcessConfigReqVO { + + private InfoDTO info; + private HolesDTO holes; + private List modeling2D; + private List modeling3D; + private List sealing; + private OutlineDTO outline; + private List modeling; + private OriginOutlinDTO originOutlin; + private List config; + + @NoArgsConstructor + @Data + public static class InfoDTO { + private Integer id; + private String name; + private String roomName; + private String cabinetName; + private String material; + private String boardName; + private String color; + private Integer lines; + private String drillType; + private Integer thickness; + private String spliteHeight; + private String spliteThickness; + private String spliteWidth; + private Boolean isRect; + private List> remarks; + private Double kaiLiaoWidth; + private Double kaiLiaoHeight; + private Integer openDir; + } + + @NoArgsConstructor + @Data + public static class HolesDTO { + private List frontBackHoles; + private List sideHoles; + + @NoArgsConstructor + @Data + public static class FrontBackHolesDTO { + private Integer type; + private PositionDTO position; + private Double radius; + private Double depth; + private Integer face; + private Double angle; + private String name; + private String goodsId; + + @NoArgsConstructor + @Data + public static class PositionDTO { + private Double x; + private Double y; + private Double z; + } + } + + @NoArgsConstructor + @Data + public static class SideHolesDTO { + private Integer type; + private PositionDTO position; + private EndPtDTO endPt; + private Integer radius; + private Double depth; + private Integer face; + private String name; + private String goodsId; + + @NoArgsConstructor + @Data + public static class PositionDTO { + private Double x; + private Double y; + private Integer z; + } + + @NoArgsConstructor + @Data + public static class EndPtDTO { + private Double x; + private Double y; + private Integer z; + } + } + } + + @NoArgsConstructor + @Data + public static class OutlineDTO { + private List pts; + private List buls; + + @NoArgsConstructor + @Data + public static class PtsDTO { + private Double x; + private Integer y; + } + } + + @NoArgsConstructor + @Data + public static class OriginOutlinDTO { + private List pts; + private List buls; + + @NoArgsConstructor + @Data + public static class PtsDTO { + private Double x; + private Integer y; + } + } + + @NoArgsConstructor + @Data + public static class Modeling2DDTO { + private PathDTO path; + private Integer dir; + private List items; + + @NoArgsConstructor + @Data + public static class PathDTO { + private List pts; + private List buls; + + @NoArgsConstructor + @Data + public static class PtsDTO { + private Double x; + private Double y; + } + } + + @NoArgsConstructor + @Data + public static class ItemsDTO { + private Integer depth; + private Integer offset; + private KnifeDTO knife; + private String depthExpr; + + @NoArgsConstructor + @Data + public static class KnifeDTO { + private String id; + private Integer radius; + private Double angle; + private String name; + } + } + } + + @NoArgsConstructor + @Data + public static class SealingDTO { + private Double length; + private Integer size; + private String sealColor; + } + + @NoArgsConstructor + @Data + public static class ModelingDTO { + private List feeding; + private Integer thickness; + private Integer dir; + private Integer knifeRadius; + private OriginDTO origin; + + @NoArgsConstructor + @Data + public static class OriginDTO { + private OutlineDTO outline; + private List holes; + private Integer addLen; + private Integer addWidth; + private Integer addDepth; + + @NoArgsConstructor + @Data + public static class OutlineDTO { + private List pts; + private List buls; + + @NoArgsConstructor + @Data + public static class PtsDTO { + private Double x; + private Double y; + } + } + } + + @NoArgsConstructor + @Data + public static class FeedingDTO { + private List pts; + private List buls; + + @NoArgsConstructor + @Data + public static class PtsDTO { + private Double x; + private Double y; + } + } + } + + @NoArgsConstructor + @Data + public static class ConfigDTO { + private Integer thickness; + private Integer width; + private Integer height; + private String color; + private String material; + private String name; + private String goodsId; + private String id; + } +} diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataProcessGroupReqVO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataProcessGroupReqVO.java new file mode 100644 index 000000000..8f74150cb --- /dev/null +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataProcessGroupReqVO.java @@ -0,0 +1,48 @@ +package com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author Gqr + * @since 2025/3/3 17:57 + */ +@NoArgsConstructor +@Schema(description = "管理后台 - webcad加工组信息 - RequestVO") +@Data +public class WebCadDataProcessGroupReqVO { + + + private String type; + + private List projects; + + @NoArgsConstructor + @Data + public static class ProjectsDTO { + + private String projName; + + private List brIds; + + private List objIds; + + private BoxSizeDTO boxSize; + + private Integer groupID; + + @NoArgsConstructor + @Data + public static class BoxSizeDTO { + + private Double width; + + private Double height; + + private Double depth; + } + } +} diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataReqVO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataReqVO.java new file mode 100644 index 000000000..9277ac01e --- /dev/null +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/admin/orderImport/webcad/vo/WebCadDataReqVO.java @@ -0,0 +1,35 @@ +package com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * @author Gqr + * @since 2025/3/3 17:40 + */ +@Schema(description = "管理后台 - webcad导入数据 - RequestVO") +@Data +public class WebCadDataReqVO { + + @JsonProperty(value = "Orders") + private WebCadDataOrderReqVO orders; + + @JsonProperty(value = "Materials") + private List Materials; + + @JsonProperty(value = "Blocks") + private List Blocks; + + @JsonProperty(value = "Parts") + private WebCadDataPartsReqVO Parts; + + @JsonProperty(value = "ProcessGroup") + private List ProcessGroup; + + private List douleRoomTree; + + private String orderType; +} diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderModelDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderModelDO.java index db8241cea..42e51440c 100644 --- a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderModelDO.java +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderModelDO.java @@ -118,4 +118,7 @@ public class OrderModelDO extends ESDocument { private String remarkJson; // 普通备注(板材数据中) @Schema(description = "特殊备注(板材数据中)") private String specialRemark; // 特殊备注(板材数据中) + + @Schema(description = "webcad板材数据") + private String boardData; } \ No newline at end of file diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/WebCadOrderImportService.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/WebCadOrderImportService.java new file mode 100644 index 000000000..14dca894e --- /dev/null +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/WebCadOrderImportService.java @@ -0,0 +1,19 @@ +package com.cf.imes.module.plan.service.orderImport; + +import com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo.WebCadDataReqVO; + +/** + * 生产单导入服务Service + * + * @author Gqr + * @since 2025/3/4 10:25 + */ +public interface WebCadOrderImportService { + + /** + * webcad生产单导入 + * + * @param webCadDataReqVO + */ + void webCadOrderImport(WebCadDataReqVO webCadDataReqVO); +} diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/WebCadOrderImportServiceImpl.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/WebCadOrderImportServiceImpl.java new file mode 100644 index 000000000..a55b68039 --- /dev/null +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/WebCadOrderImportServiceImpl.java @@ -0,0 +1,109 @@ +package com.cf.imes.module.plan.service.orderImport; + +import cn.hutool.core.util.ObjectUtil; +import com.cf.imes.framework.common.exception.ErrorCode; +import com.cf.imes.framework.common.exception.ServiceException; +import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd; +import com.cf.imes.framework.mybatis.core.generator.SnowFlakeGenerator; +import com.cf.imes.framework.organ.core.context.OrganContextHolder; +import com.cf.imes.framework.redis.config.ChenfengCacheProperties; +import com.cf.imes.framework.redis.constants.RedisKeyConstants; +import com.cf.imes.framework.redis.util.RedisLockUtil; +import com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo.WebCadDataReqVO; +import com.cf.imes.module.plan.dal.mysql.order.OrderMapper; +import com.cf.imes.module.plan.dal.mysql.orderBody.OrderBodyMapper; +import com.cf.imes.module.plan.dal.mysql.orderGroup.OrderGroupMapper; +import com.cf.imes.module.plan.dal.mysql.orderItem.OrderItemMapper; +import com.cf.imes.module.plan.dal.mysql.orderParts.OrderPartsMapper; +import com.cf.imes.module.plan.dal.mysql.orderParts.PartsMapper; +import com.cf.imes.module.plan.dal.mysql.plate.PlateMapper; +import com.cf.imes.module.plan.service.customplateno.CustomPlateNoGenerateService; +import com.cf.imes.module.plan.service.order.OrderInputProcessor; +import com.cf.imes.module.plan.service.orderImport.factory.WebCadOrderImportFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_IMPORT_ORGAN_LOCK_ERROR; +import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_FAILED; +import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_ORGANID_EMPTY_ERROR; + +/** + * 生产单导入服务Service实现类 + * + * @author Gqr + * @since 2025/3/4 10:27 + */ +@Service +public class WebCadOrderImportServiceImpl implements WebCadOrderImportService { + + private static final Logger log = LoggerFactory.getLogger(WebCadOrderImportServiceImpl.class); + @Resource + private OrderMapper orderMapper; + + @Resource + private SnowFlakeGenerator snowFlakeGenerator; + + @Resource + private OrderBodyMapper orderBodyMapper; + + @Resource + private PlateMapper plateMapper; + + @Resource + private OrderItemMapper orderItemMapper; + + @Resource + private OrderGroupMapper orderGroupMapper; + + @Resource + private SnowflakeIdWorker3rd idWorker; + + @Resource + private OrderInputProcessor orderInputProcessor; + + @Resource + private PartsMapper partsMapper; + + @Resource + private OrderPartsMapper orderPartsMapper; + + @Resource + private CustomPlateNoGenerateService customPlateNoGenerateService; + + @Resource + private RedisLockUtil redisLockUtil; + + @Resource + private ChenfengCacheProperties chenfengCacheProperties; + + @Override + public void webCadOrderImport(WebCadDataReqVO webCadDataReqVO) { + Long organId = OrganContextHolder.getOrganId(); + String redisUniqueKey = "webcad"; + if (ObjectUtil.isNull(organId)) { + throw new ServiceException(WEBCAD_ORDER_IMPORT_ORGANID_EMPTY_ERROR); + } + try { + String importLockKey = String.format(RedisKeyConstants.ORDER_IMPORT_LOCK_KEY, organId); + // 检查机构导入锁 + boolean lockResult = redisLockUtil.lock(importLockKey, redisUniqueKey, chenfengCacheProperties.getLockTimeout()); + if (!lockResult) { + throw new ServiceException(ORDER_IMPORT_ORGAN_LOCK_ERROR); + } + WebCadOrderImportFactory webCadOrderImportFactory = new WebCadOrderImportFactory(organId, orderMapper, snowFlakeGenerator, orderBodyMapper, plateMapper, orderItemMapper, orderGroupMapper, idWorker, orderInputProcessor, partsMapper, orderPartsMapper, customPlateNoGenerateService); + webCadOrderImportFactory.analyzeTempData(webCadDataReqVO); + } catch (ServiceException se) { + throw se; + } catch (Exception e) { + ErrorCode webcadOrderImportFailed = WEBCAD_ORDER_IMPORT_FAILED; + log.error(webcadOrderImportFailed.getMsg(), e); + throw new ServiceException(webcadOrderImportFailed); + } finally { + // 导入锁解锁 + redisLockUtil.unlock(String.format(RedisKeyConstants.ORDER_IMPORT_LOCK_KEY, organId), redisUniqueKey); + } + } +} diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/factory/DefaultXmlOrderImportFactory.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/factory/DefaultXmlOrderImportFactory.java index f13eabc4e..43864d087 100644 --- a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/factory/DefaultXmlOrderImportFactory.java +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/factory/DefaultXmlOrderImportFactory.java @@ -91,6 +91,7 @@ import com.cf.imes.module.plan.dal.mysql.rawgoods.RawGoodsMapper; import com.cf.imes.module.plan.service.customplateno.CustomPlateNoGenerateService; import com.cf.imes.module.plan.service.customplateno.vo.CustomPlateNoGenerateConfigVO; import com.cf.imes.module.plan.service.order.OrderInputProcessor; +import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.session.ResultContext; import org.apache.ibatis.session.ResultHandler; import org.slf4j.Logger; @@ -118,12 +119,12 @@ import static com.cf.imes.module.plan.service.order.OrderInputProcessor.ORDER_PL * @author Gqr * @since 2025/2/19 16:26 */ +@Slf4j public class DefaultXmlOrderImportFactory { /** * 分组中做分页的阈值,如:总数100以上就边分组边分页,否则一次性查出来 */ private static final int BATCH_THRESHOLD_NUMBER = 100; - private static final Logger log = LoggerFactory.getLogger(DefaultXmlOrderImportFactory.class); private Long organId; diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/factory/WebCadOrderImportFactory.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/factory/WebCadOrderImportFactory.java new file mode 100644 index 000000000..84f788045 --- /dev/null +++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/factory/WebCadOrderImportFactory.java @@ -0,0 +1,988 @@ +package com.cf.imes.module.plan.service.orderImport.factory; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.BooleanUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.excel.util.ListUtils; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.cf.imes.framework.common.exception.ServiceException; +import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil; +import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd; +import com.cf.imes.framework.mybatis.core.generator.SnowFlakeGenerator; +import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper; +import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils; +import com.cf.imes.module.executor.enums.DataTypeEnum; +import com.cf.imes.module.executor.enums.OrderItemTypeEnum; +import com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo.WebCadDataBlockReqVO; +import com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo.WebCadDataDoubleRoomTreeReqVO; +import com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo.WebCadDataMaterialReqVO; +import com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo.WebCadDataOrderReqVO; +import com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo.WebCadDataPartsReqVO; +import com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo.WebCadDataProcessGroupReqVO; +import com.cf.imes.module.plan.controller.admin.orderImport.webcad.vo.WebCadDataReqVO; +import com.cf.imes.module.plan.dal.dataobject.order.OrderDO; +import com.cf.imes.module.plan.dal.dataobject.orderBody.OrderBodyDO; +import com.cf.imes.module.plan.dal.dataobject.orderGroup.OrderGroupDO; +import com.cf.imes.module.plan.dal.dataobject.orderItem.OrderItemDO; +import com.cf.imes.module.plan.dal.dataobject.orderParts.OrderPartsDO; +import com.cf.imes.module.plan.dal.dataobject.orderParts.PartsDO; +import com.cf.imes.module.plan.dal.dataobject.ordermodel.OrderModelDO; +import com.cf.imes.module.plan.dal.dataobject.plate.PlateDO; +import com.cf.imes.module.plan.dal.mysql.order.OrderMapper; +import com.cf.imes.module.plan.dal.mysql.orderBody.OrderBodyMapper; +import com.cf.imes.module.plan.dal.mysql.orderGroup.OrderGroupMapper; +import com.cf.imes.module.plan.dal.mysql.orderItem.OrderItemMapper; +import com.cf.imes.module.plan.dal.mysql.orderParts.OrderPartsMapper; +import com.cf.imes.module.plan.dal.mysql.orderParts.PartsMapper; +import com.cf.imes.module.plan.dal.mysql.plate.PlateMapper; +import com.cf.imes.module.plan.service.customplateno.CustomPlateNoGenerateService; +import com.cf.imes.module.plan.service.customplateno.vo.CustomPlateNoGenerateConfigVO; +import com.cf.imes.module.plan.service.order.OrderInputProcessor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_MATERIALS_EMPTY_ERROR; +import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_IMPORT_ROOMBODY_EMPTY_ERROR; +import static com.cf.imes.module.plan.enums.ErrorCodeConstants.WEBCAD_ORDER_NOT_EXISTS_ERROR; + +/** + * webcad导入生产单工厂服务 + * + * @author Gqr + * @since 2025/3/8 14:39 + */ +@Slf4j +public class WebCadOrderImportFactory { + /** + * 分组中做分页的阈值,如:总数100以上就边分组边分页,否则一次性查出来 + */ + private static final int BATCH_THRESHOLD_NUMBER = 100; + + private OrderMapper orderMapper; + + private SnowFlakeGenerator snowFlakeGenerator; + + private OrderBodyMapper orderBodyMapper; + + private PlateMapper plateMapper; + + private OrderItemMapper orderItemMapper; + + private OrderGroupMapper orderGroupMapper; + + private SnowflakeIdWorker3rd idWorker; + + private OrderInputProcessor orderInputProcessor; + + private PartsMapper partsMapper; + + private OrderPartsMapper orderPartsMapper; + + private CustomPlateNoGenerateService customPlateNoGenerateService; + + private Long organId; + + private Long orderId; + + private OrderDO orderDO; + + // 是否入库的第一块板件 + private boolean isFirstPlate; + + private CustomPlateNoGenerateConfigVO plateNoGenerateConfigVO; + + + // 柜体成倍信息缓存:{ 房间名+柜体名:childrenDTO } + private Map roomBodyMap = new HashMap<>(); + + // 柜体缓存 + private Map bodyMap = new HashMap<>(); + + // 房间名+柜体名+加工组名 + private Map orderGroupMap = new HashMap<>(); + + private List plateDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER); + private List orderItemDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER); + private List orderGroupDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER); + private List orderPartsDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER); + private List orderModelDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER); + + + private static String PART_CATEGORY_ONE = "封边条"; + private static String PART_CATEGORY_TWO = "五金"; + private static String PART_CATEGORY_THREE = "组件"; + private static final String EMPTY_STRING = new String(); + + public WebCadOrderImportFactory(Long organId, + OrderMapper orderMapper, + SnowFlakeGenerator snowFlakeGenerator, + OrderBodyMapper orderBodyMapper, + PlateMapper plateMapper, + OrderItemMapper orderItemMapper, + OrderGroupMapper orderGroupMapper, + SnowflakeIdWorker3rd idWorker, + OrderInputProcessor orderInputProcessor, + PartsMapper partsMapper, + OrderPartsMapper orderPartsMapper, + CustomPlateNoGenerateService customPlateNoGenerateService) { + this.organId = organId; + this.orderMapper = orderMapper; + this.snowFlakeGenerator = snowFlakeGenerator; + this.orderBodyMapper = orderBodyMapper; + this.plateMapper = plateMapper; + this.orderItemMapper = orderItemMapper; + this.orderGroupMapper = orderGroupMapper; + this.idWorker = idWorker; + this.orderInputProcessor = orderInputProcessor; + this.partsMapper = partsMapper; + this.orderPartsMapper = orderPartsMapper; + this.customPlateNoGenerateService = customPlateNoGenerateService; + } + + public void analyzeTempData(WebCadDataReqVO webCadDataReqVO) { + try { + // 获取自定义板编号配置 + plateNoGenerateConfigVO = customPlateNoGenerateService.getPlateNoGenerateConfig(orderId); + + // 解析生产单信息 + analyzeOrder(webCadDataReqVO.getOrders()); + + // 板材id对应板件 + analyzeMaterials(webCadDataReqVO.getMaterials(), webCadDataReqVO.getBlocks()); + + // 解析加工组类型 + analyzeGroups(webCadDataReqVO.getProcessGroup(), webCadDataReqVO.getBlocks(), webCadDataReqVO.getParts()); + + // 缓存柜体成倍信息 + analyzeRoomBody(webCadDataReqVO.getDouleRoomTree()); + + // 解析板件列表 + analyzeBlockList(webCadDataReqVO.getBlocks()); + + // 解析配件列表 + analyzeParts(webCadDataReqVO.getParts()); + + // 数据保存入库 + saveData(); + + } catch (Exception e) { + throw e; + } finally { + // 清理数据 + clearAll(); + } + } + + /** + * 解析生产单信息 + * + * @param orderReqVO + */ + private void analyzeOrder(WebCadDataOrderReqVO orderReqVO) { + // 查询生产单信息 + String orderNo = orderReqVO.getOrderNo(); + OrderDO orderDOFromOrderNo = orderMapper.selectById(NumberUtil.parseLong(orderNo)); + if (ObjectUtil.isNull(orderDOFromOrderNo)) { + throw ServiceExceptionUtil.exception(WEBCAD_ORDER_NOT_EXISTS_ERROR, orderNo); + } else { + // 更新生产单来源为webcad + orderMapper.update(new LambdaUpdateWrapper().eq(OrderDO::getId, orderDOFromOrderNo.getId()).set(OrderDO::getDataType, DataTypeEnum.WEBCAD_IMPORT.getStatus())); + } + orderDO = orderDOFromOrderNo; + orderId = orderDOFromOrderNo.getId(); + } + + /** + * 板材id赋值对应板材 + * + * @param materialReqVOS + */ + private void analyzeMaterials(List materialReqVOS, List blockReqVOS) { + if (CollUtil.isEmpty(materialReqVOS)) { + throw new ServiceException(WEBCAD_ORDER_IMPORT_MATERIALS_EMPTY_ERROR); + } + for (WebCadDataMaterialReqVO materialReqVO : materialReqVOS) { + for (Integer blockIndex : materialReqVO.getOrginIds()) { + // blockIndex序号获取对应板件 + WebCadDataBlockReqVO webCadDataBlockReqVO = blockReqVOS.get(blockIndex - 1); + // 把板材的id和goodsId赋给cad板件 + webCadDataBlockReqVO.setGoodsId(materialReqVO.getGoodsId()); + webCadDataBlockReqVO.setPlateGoodsId(materialReqVO.getId()); + } + } + } + + /** + * 缓存加工组类型 + * + * @param processGroupList + */ + private void analyzeGroups(List processGroupList, List blockReqVOS, WebCadDataPartsReqVO partsReqVO) { + if (CollUtil.isNotEmpty(processGroupList)) { + for (WebCadDataProcessGroupReqVO processGroup : processGroupList) { + String groupTypeName = processGroup.getType(); + List projects = processGroup.getProjects(); + // 加工组信息缓存到cad block和part上 + if (CollUtil.isNotEmpty(projects)) { + for (WebCadDataProcessGroupReqVO.ProjectsDTO project : projects) { + // 板件 + processBlocksGroup(project, blockReqVOS, groupTypeName); + // 配件 + processPartsGroup(project, partsReqVO, groupTypeName); + } + } + } + } + } + + /** + * 存板件加工组 + * + * @param project + * @param blockReqVOS + * @param groupTypeName + */ + private void processBlocksGroup(WebCadDataProcessGroupReqVO.ProjectsDTO project, List blockReqVOS, String groupTypeName) { + List brIds = project.getBrIds(); + if (CollUtil.isNotEmpty(brIds)) { + for (Integer brId : brIds) { + // brId 板件序号获取板件 + WebCadDataBlockReqVO webCadDataBlockReqVO = blockReqVOS.get(brId - 1); + WebCadDataBlockReqVO.GroupInfo groupInfo = new WebCadDataBlockReqVO.GroupInfo(); + groupInfo.setGroupTypeName(groupTypeName); + groupInfo.setGroupName(project.getProjName()); + groupInfo.setWidth(project.getBoxSize().getWidth()); + groupInfo.setHeight(project.getBoxSize().getHeight()); + groupInfo.setDepth(project.getBoxSize().getDepth()); + webCadDataBlockReqVO.getGroupInfos().add(groupInfo); + } + } + } + + /** + * 存配件加工组 + * + * @param project + * @param partsReqVO + * @param groupTypeName + */ + private void processPartsGroup(WebCadDataProcessGroupReqVO.ProjectsDTO project, WebCadDataPartsReqVO partsReqVO, String groupTypeName) { + List objIds = project.getObjIds(); + if (CollUtil.isNotEmpty(objIds)) { + for (Integer objId : objIds) { + // objId 配件序号获取配件 + WebCadDataPartsReqVO.BlockObjectListDTO part = partsReqVO.getBlockObjectList().get(objId - 1); + WebCadDataBlockReqVO.GroupInfo groupInfo = new WebCadDataBlockReqVO.GroupInfo(); + groupInfo.setGroupTypeName(groupTypeName); + groupInfo.setGroupName(project.getProjName()); + groupInfo.setWidth(project.getBoxSize().getWidth()); + groupInfo.setHeight(project.getBoxSize().getHeight()); + groupInfo.setDepth(project.getBoxSize().getDepth()); + part.getGroupInfos().add(groupInfo); + } + } + } + + /** + * 生成并缓存成倍房间柜体信息 + * + * @param douleRoomTree + */ + private void analyzeRoomBody(List douleRoomTree) { + if (CollUtil.isEmpty(douleRoomTree)) { + throw new ServiceException(WEBCAD_ORDER_IMPORT_ROOMBODY_EMPTY_ERROR); + } + for (WebCadDataDoubleRoomTreeReqVO room : douleRoomTree) { + String roomName = room.getName(); + List bodys = room.getChildren(); + if (CollUtil.isNotEmpty(bodys)) { + for (WebCadDataDoubleRoomTreeReqVO.ChildrenDTO body : bodys) { + String bodyName = body.getName(); + // 缓存柜体成倍信息 + roomBodyMap.put(roomName + bodyName, body); + } + } + } + } + + /** + * 解析生产单信息板材列表 + * + * @param blockList + */ + private void analyzeBlockList(List blockList) { + // 基于房间名分组 + Map> roomCollect = blockList.stream() + .collect(Collectors.groupingBy(WebCadDataBlockReqVO::getRoomName, Collectors.toList())); + roomCollect.forEach((roomName, listRoom) -> { + Long roomId = (Long) snowFlakeGenerator.nextId(null); + // 基于柜体名分组 + Map> bodyCollect = listRoom.stream() + .collect(Collectors.groupingBy(WebCadDataBlockReqVO::getCabinetName, Collectors.toList())); + bodyCollect.forEach((bodyName, listBody) -> { + String roomBodyKey = roomName + bodyName; + WebCadDataDoubleRoomTreeReqVO.ChildrenDTO cadBody = roomBodyMap.get(roomBodyKey); + + if (ObjectUtil.isNull(cadBody)) { + // 房间+柜体不在成倍缓存中, 再检查bodyMap, 再没有创建房间,缓存房间到bodyMap + createBlockUnknownBody(roomId, roomName, bodyName, listBody); + } else { + // 成倍数量 + Integer bodyMultipleNum = cadBody.getCount(); + for (int i = 0; i < bodyMultipleNum; i++) { + Long bodyId = (Long) snowFlakeGenerator.nextId(null); + OrderBodyDO orderBodyDO = OrderBodyDO.builder().id(bodyId).orderId(orderId).organId(organId) + .roomId(roomId).roomName(roomName).name(bodyName).width(0.0).height(0.0) + .depth(0.0).multiNum(0).plateNum(0).unregularNum(0).filename("无").remark("无").build(); + + // 缓存成倍的柜体信息 + bodyMap.put(roomBodyKey + i, orderBodyDO); + + listBody.forEach(block -> { + // 创建板件相关数据:order_plate、order_item、es.orderModels + createPlate(orderBodyDO, block); + }); + } + } + }); + }); + // 所有自定义板编号生成完成后更新配置到生产单 + customPlateNoGenerateService.updateCustomPlateNoGenerateConfig(plateNoGenerateConfigVO, orderDO); + // 批量插入板件 + orderInfoBatchInsertWithinThreshold(plateMapper, plateDOS, true); + // 批量插入造型数据 + orderModelsBatchInsertWithinThreshold(true); + } + + /** + * 创建不需要成倍的房间柜体以及其下的板件 + * + * @param roomName + * @param bodyName + * @param bodyCollect + */ + private void createBlockUnknownBody(Long roomId, String roomName, String bodyName, List bodyCollect) { + String roomBodyKey = roomName + bodyName; + OrderBodyDO orderBodyDO = bodyMap.get(roomBodyKey); + if (ObjectUtil.isNull(orderBodyDO)) { + Long bodyId = (Long) snowFlakeGenerator.nextId(null); + orderBodyDO = OrderBodyDO.builder().id(bodyId).orderId(orderId).organId(organId) + .roomId(roomId).roomName(roomName).name(bodyName).width(0.0).height(0.0) + .depth(0.0).multiNum(0).plateNum(0).unregularNum(0).filename("无").remark("无").deleted(false).build(); + + // 缓存成倍的柜体信息 + bodyMap.put(roomBodyKey, orderBodyDO); + } + + for (WebCadDataBlockReqVO block : bodyCollect) { + // 创建板件相关数据:order_plate、order_item、es.orderModels + createPlate(orderBodyDO, block); + } + } + + /** + * 创建板件数据 + * + * @param orderBodyDO + * @param block + */ + private void createPlate(OrderBodyDO orderBodyDO, WebCadDataBlockReqVO block) { + orderBodyDO.setPlateNum(orderBodyDO.getPlateNum() + 1); + orderBodyDO.setUnregularNum(orderBodyDO.getUnregularNum() + BooleanUtil.toInt(block.getIsSpecialShape())); + Boolean isSpecialShape = block.getIsSpecialShape(); + + // 柜体长宽深 + orderBodyDO.setWidth(block.getCabinetWidth()); + orderBodyDO.setHeight(block.getCabinetHeight()); + orderBodyDO.setDepth(block.getCabinetDepth()); + + Long plateId = (Long) snowFlakeGenerator.nextId(null); + long plateNo = idWorker.nextId(); + long obtainingTime = idWorker.obtainingTime(); + + WebCadDataBlockReqVO.InfoDTO blockInfo = block.getInfo(); + + // 创建order_plate + PlateDO plateDO = PlateDO.builder() + .id(plateId) + .orderId(orderId) + .name(block.getName()) + .plateNo(obtainingTime + Long.toString(plateNo).substring(2)) + .type(block.getType()) + .goodsId(NumberUtil.parseLong(block.getPlateGoodsId())) + .width(BigDecimal.valueOf(block.getWidth())) + .height(BigDecimal.valueOf(block.getHeight())) + .thickness(BigDecimal.valueOf(block.getThickness())) + .splitHeight(BigDecimal.valueOf(NumberUtil.parseDouble(blockInfo.getSpliteHeight()))) + .splitThickness(BigDecimal.valueOf(NumberUtil.parseDouble(blockInfo.getSpliteThickness()))) + .splitWidth(BigDecimal.valueOf(NumberUtil.parseDouble(blockInfo.getSpliteWidth()))) + .area(BigDecimal.valueOf(block.getArea())) + .texture(block.getTexture()) + .holeFace(block.getHoleFace()) + .isDoor(block.getIsDoor()) + .openDoorType(block.getOpenDoorType()) + .isSculpt(false) + .isSpecialShaped(isSpecialShape) + .customPlateNoBuilder(new StringBuilder()) + .holeArrange(block.getHoleArrange()) + .unregularPointCount(block.getUnregularPointCount()) + .frontHoleCount(block.getFrontHoleCount()) + .backHoleCount(block.getBackHoleCount()) + .sideHoleCount(block.getSideHoleCount()) + .frontModelCount(block.getFrontModelCount()) + .backModelCount(block.getBackModelCount()) + .offsetX(BigDecimal.valueOf(block.getOffsetX())) + .offsetY(BigDecimal.valueOf(block.getOffsetY())) + .isArcAcross(block.getIsArcBase()) + .moduleTypeId(0L) + .isRowHole(false) + .isOptimized(false) + .isCutted(0) + .isCancel(false) + .filterType(EMPTY_STRING) + .sealLeft(BigDecimal.ZERO) + .sealRight(BigDecimal.ZERO) + .sealUp(BigDecimal.ZERO) + .sealDown(BigDecimal.ZERO) + .remark(block.getRemark()) + .deleted(false) + .organId(organId) + .build(); + String operatorName = SecurityFrameworkUtils.getLoginUser().getNickname(); + plateDO.setCreator(operatorName); + plateDO.setUpdater(operatorName); + LocalDateTime now = LocalDateTime.now(); + plateDO.setCreateTime(now); + plateDO.setUpdateTime(now); + + // 生成自定义板编号 + generateCustomPlateNo(plateDO); + + // 获取封边厚度 + calculateSealThickness(plateDO, block.getBoardData().getSealing()); + + //批量保存板件 + plateDOS.add(plateDO); + orderInfoBatchInsertWithinThreshold(plateMapper, plateDOS, false); + + OrderModelDO orderModelDO = OrderModelDO.builder() + .orderId(orderId) + .plateId(plateId) + .boardData(JSON.toJSONString(block.getBoardData())) + .build(); + orderModelDO.setGoodsId(block.getGoodsId()); + orderModelDO.setPlateGoodsId(plateDO.getGoodsId()); + orderModelDO.setOrganId(organId); + orderModelDO.setCreator(operatorName); + orderModelDO.setUpdater(operatorName); + orderModelDOS.add(orderModelDO); + // 批量插入造型数据 + orderModelsBatchInsertWithinThreshold(false); + + // 遍历加工组信息,生成对应的加工组和item + analyzeBlockProcessGroup(orderBodyDO, block, plateId); + } + + /** + * 生成自定义板编号 + * + * @param plateDO + */ + private void generateCustomPlateNo(PlateDO plateDO) { + if (!isFirstPlate) { + isFirstPlate = true; + } + // 配置不为空时,生成自定义板编号 + if (ObjectUtil.isNotNull(plateNoGenerateConfigVO)) { + customPlateNoGenerateService.generateCustomPlateNo(orderId, plateDO, plateNoGenerateConfigVO, isFirstPlate); + } + } + + /** + * 解析板件加工组 + * + * @param orderBodyDO + * @param block + * @param plateId + */ + private void analyzeBlockProcessGroup(OrderBodyDO orderBodyDO, WebCadDataBlockReqVO block, Long plateId) { + Long bodyId = orderBodyDO.getId(); + Long roomId = orderBodyDO.getRoomId(); + String roomName = orderBodyDO.getRoomName(); + String bodyName = orderBodyDO.getName(); + Boolean isSpecialShape = block.getIsSpecialShape(); + + List groupInfos = block.getGroupInfos(); + if (CollUtil.isNotEmpty(groupInfos)) { + // 加工组缓存存在,一个加工组一个orderGroup+orderItem + for (WebCadDataBlockReqVO.GroupInfo groupInfo : groupInfos) { + String groupMapKey = roomName + bodyName + groupInfo.getGroupName(); + OrderGroupDO orderGroupDO = orderGroupMap.get(groupMapKey); + // 房间+柜体+加工组名称存在累加板件和异形数量,不存在新增groupDO和orderGroupMap缓存 + if (ObjectUtil.isNull(orderGroupDO)) { + orderGroupDO = OrderGroupDO + .builder() + .id((Long) snowFlakeGenerator.nextId(null)) + .organId(organId) + .orderId(orderId) + .bodyId(bodyId) + .groupTypeId((Long) snowFlakeGenerator.nextId(null)) + .groupTypeName(groupInfo.getGroupTypeName()) + .name(groupInfo.getGroupTypeName()) + .width(groupInfo.getWidth()) + .height(groupInfo.getHeight()) + .depth(groupInfo.getDepth()) + .multiNum(0) + .plateNum(1) + .unregularNum(BooleanUtil.toInt(isSpecialShape)) + .filename("无") + .remark("无") + .deleted(false) + .build(); + orderGroupMap.put(groupMapKey, orderGroupDO); + orderGroupDOS.add(orderGroupDO); + } else { + orderGroupDO.setPlateNum(orderGroupDO.getPlateNum() + 1); + orderGroupDO.setUnregularNum(orderGroupDO.getUnregularNum() + BooleanUtil.toInt(isSpecialShape)); + } + + OrderItemDO orderItemDO = OrderItemDO + .builder() + .id((Long) snowFlakeGenerator.nextId(null)) + .orderId(orderId) + .type(OrderItemTypeEnum.PLATE_ITEM.getStatus()) + .roomId(roomId) + .bodyId(bodyId) + .groupId(orderGroupDO.getId()) + .plateId(plateId) + .packageId(0L) + .partsId(0L) + .num(1.0) + .build(); + orderItemDOS.add(orderItemDO); + } + } else { + // 没有归属的加工组,只创建一个orderItem + OrderItemDO orderItemDO = OrderItemDO + .builder() + .id((Long) snowFlakeGenerator.nextId(null)) + .orderId(orderId) + .type(OrderItemTypeEnum.PLATE_ITEM.getStatus()) + .roomId(roomId) + .bodyId(bodyId) + .groupId(0L) + .plateId(plateId) + .packageId(0L) + .partsId(0L) + .num(1.0) + .build(); + orderItemDOS.add(orderItemDO); + } + } + + /** + * 解析配件列表 + * + * @param parts + */ + private void analyzeParts(WebCadDataPartsReqVO parts) { + List blockObjectList = parts.getBlockObjectList(); + // 配件对应列表 + matchLeftEdge(parts, blockObjectList); + + // 解析orderParts + analyzeOrderParts(blockObjectList); + + // 解析配件的orderItem + // 基于房间名分组 + Map> roomCollect = blockObjectList.stream() + .collect(Collectors.groupingBy(WebCadDataPartsReqVO.BlockObjectListDTO::getRoomName, Collectors.toList())); + roomCollect.forEach((roomName, listRoom) -> { + Long roomId = (Long) snowFlakeGenerator.nextId(null); + + // 基于柜体名分组 + Map> bodyCollect = listRoom.stream() + .collect(Collectors.groupingBy(WebCadDataPartsReqVO.BlockObjectListDTO::getCabinetName, Collectors.toList())); + for (Map.Entry> entry : bodyCollect.entrySet()) { + String bodyName = entry.getKey(); + List listBody = entry.getValue(); + + String roomNameKey = roomName + bodyName; + WebCadDataDoubleRoomTreeReqVO.ChildrenDTO cadBody = roomBodyMap.get(roomNameKey); + + if (ObjectUtil.isNull(cadBody)) { + // 房间+柜体不在成倍缓存中, 再检查bodyMap, 再没有创建房间,缓存房间到bodyMap + createPartsUnknownBody(roomId, roomName, bodyName, listBody); + } else { + // 成倍数量 + Integer bodyMultipleNum = cadBody.getCount(); + for (int j = 0; j < bodyMultipleNum; j++) { + // 获取板材已经创建的柜体,缓存key:房间名+柜体名+成倍序号 + OrderBodyDO orderBodyDO = bodyMap.get(roomNameKey + j); + // 解析配件的加工组,创建对应的orderItem + for (WebCadDataPartsReqVO.BlockObjectListDTO part : listBody) { + analyzePartProcessGroup(orderBodyDO, part); + } + } + } + } + }); + } + + /** + * 创建不需要成倍的房间柜体以及其下的板件 + * + * @param roomName + * @param bodyName + * @param listBody + */ + private void createPartsUnknownBody(Long roomId, String roomName, String bodyName, List listBody) { + String roomBodyKey = roomName + bodyName; + OrderBodyDO orderBodyDO = bodyMap.get(roomBodyKey); + if (ObjectUtil.isNull(orderBodyDO)) { + Long bodyId = (Long) snowFlakeGenerator.nextId(null); + orderBodyDO = OrderBodyDO.builder().id(bodyId).orderId(orderId).organId(organId) + .roomId(roomId).roomName(roomName).name(bodyName).width(0.0).height(0.0) + .depth(0.0).multiNum(0).plateNum(0).unregularNum(0).filename("无").remark("无").deleted(false).build(); + + // 缓存成倍的柜体信息 + bodyMap.put(roomBodyKey, orderBodyDO); + } + + for (WebCadDataPartsReqVO.BlockObjectListDTO part : listBody) { + analyzePartProcessGroup(orderBodyDO, part); + } + } + + private void analyzePartProcessGroup(OrderBodyDO orderBodyDO, WebCadDataPartsReqVO.BlockObjectListDTO part) { + Long bodyId = orderBodyDO.getId(); + Long roomId = orderBodyDO.getRoomId(); + String roomName = orderBodyDO.getRoomName(); + String bodyName = orderBodyDO.getName(); + + // 遍历加工组信息,生成对应的orderItem + List groupInfos = part.getGroupInfos(); + if (CollUtil.isNotEmpty(groupInfos)) { + Double partNum = 0.0; + // 带加工组的配件增加item只记录配件id和数量 + partNum += part.getNum(); + for (WebCadDataBlockReqVO.GroupInfo groupInfo : groupInfos) { + String groupMapKey = roomName + bodyName + groupInfo.getGroupName(); + OrderGroupDO orderGroupDO = orderGroupMap.get(groupMapKey); + // + if (ObjectUtil.isNull(orderGroupDO)) { + orderGroupDO = OrderGroupDO + .builder() + .id((Long) snowFlakeGenerator.nextId(null)) + .organId(organId) + .orderId(orderId) + .bodyId(bodyId) + .groupTypeId((Long) snowFlakeGenerator.nextId(null)) + .groupTypeName(groupInfo.getGroupTypeName()) + .name(groupInfo.getGroupTypeName()) + .width(groupInfo.getWidth()) + .height(groupInfo.getHeight()) + .depth(groupInfo.getDepth()) + .multiNum(0) + .plateNum(0) + .unregularNum(0) + .filename("无") + .remark("无") + .deleted(false) + .build(); + orderGroupMap.put(groupMapKey, orderGroupDO); + orderGroupDOS.add(orderGroupDO); + } + + OrderItemDO orderItemDO = OrderItemDO + .builder() + .id((Long) snowFlakeGenerator.nextId(null)) + .orderId(orderId) + .type(OrderItemTypeEnum.PLATE_ITEM.getStatus()) + .roomId(roomId) + .bodyId(bodyId) + .groupId(orderGroupDO.getId()) + .partsId(part.getImesPartsId()) + .packageId(0L) + .plateId(0L) + .num(part.getNum()) + .build(); + orderItemDOS.add(orderItemDO); + } + OrderItemDO orderItemDO = OrderItemDO + .builder() + .id((Long) snowFlakeGenerator.nextId(null)) + .orderId(orderId) + .type(OrderItemTypeEnum.PLATE_ITEM.getStatus()) + .roomId(roomId) + .bodyId(bodyId) + .groupId(0L) + .partsId(part.getImesPartsId()) + .packageId(0L) + .plateId(0L) + .num(partNum) + .build(); + orderItemDOS.add(orderItemDO); + } else { + OrderItemDO orderItemDO = OrderItemDO + .builder() + .id((Long) snowFlakeGenerator.nextId(null)) + .orderId(orderId) + .type(OrderItemTypeEnum.PLATE_ITEM.getStatus()) + .roomId(roomId) + .bodyId(bodyId) + .groupId(0L) + .partsId(part.getImesPartsId()) + .packageId(0L) + .plateId(0L) + .num(part.getNum()) + .build(); + orderItemDOS.add(orderItemDO); + } + } + + /** + * 分组配件解析出orderParts,id回显到cad配件 + * + * @param blockObjectList + */ + private void analyzeOrderParts(List blockObjectList) { + // 筛选出组件配件 + List moduleCollect = blockObjectList.stream().filter(p -> PART_CATEGORY_THREE.equals(p.getType())).collect(Collectors.toList()); + // 基于以下属性分组非组件的配件 + Map, List> partsMap = blockObjectList.stream().filter(p -> !PART_CATEGORY_THREE.equals(p.getType())).collect(Collectors.groupingBy( + p -> Arrays.asList( + p.getIsComposite(), + p.getType(), + p.getFactory(), + p.getModel(), + p.getSpec(), + p.getHeight(), + p.getWidth(), + p.getThickness(), + p.getUnit(), + p.getBrand()), + Collectors.toList() + )); + partsMap.forEach((partKey, partValue) -> { + Long partId = (Long) snowFlakeGenerator.nextId(null); + WebCadDataPartsReqVO.BlockObjectListDTO part = partValue.get(0); + + String partType = part.getType(); + String model = part.getModel(); + String spec = part.getSpec(); + String brand = part.getBrand(); + String factory = part.getFactory(); + if (PART_CATEGORY_ONE.equals(partType)) { + // 封边对应查询配件库中的封边条配件,使用配件库的model、spec、brand、factory + PartsDO partsDO = partsMapper.selectById(part.getPartId()); + if (ObjectUtil.isNotNull(partsDO)) { + model = partsDO.getModel(); + spec = partsDO.getSpec(); + brand = partsDO.getBrand(); + factory = partsDO.getFactory(); + } + } + + String type = changePartType(partType, part.getIsComposite()); + String goodsId = part.getGoodsId(); + // todo orderId、color、remark、备注信息到es + OrderPartsDO orderPartsDO = OrderPartsDO.builder() + .id(partId) + .orderId(orderId) + .color(EMPTY_STRING) + .category(type) + .type(type) + .goodsId(StringUtils.isNotEmpty(goodsId) ? goodsId : EMPTY_STRING) + .length(NumberUtil.parseDouble(part.getHeight())) + .width(NumberUtil.parseDouble(part.getWidth())) + .thickness(NumberUtil.parseDouble(part.getThickness())) + .isComposite(part.getIsComposite()) + .name(part.getName()) + .material(EMPTY_STRING) + .model(StringUtils.isNotEmpty(model) ? model : EMPTY_STRING) + .spec(StringUtils.isNotEmpty(spec) ? spec : EMPTY_STRING) + .brand(StringUtils.isNotEmpty(brand) ? brand : EMPTY_STRING) + .factory(StringUtils.isNotEmpty(factory) ? factory : EMPTY_STRING) + .unit(part.getUnit()) + .price(0.0) + .subparts(EMPTY_STRING) + .remark("") + .organId(organId) + .deleted(false) + .build(); + orderPartsDOS.add(orderPartsDO); + orderInfoBatchInsertWithinThreshold(orderPartsMapper, orderPartsDOS, false); + + // 配件id回显到列表 + partValue.forEach(p -> { + p.setImesPartsId(partId); + }); + }); + // 组件不分组,每一个组件认为是一种组件 + for (WebCadDataPartsReqVO.BlockObjectListDTO module : moduleCollect) { + Long partId = (Long) snowFlakeGenerator.nextId(null); + String type = changePartType(module.getType(), module.getIsComposite()); + String goodsId = module.getGoodsId(); + // todo color、remark、备注信息到es + OrderPartsDO orderPartsDO = OrderPartsDO.builder() + .id(partId) + .orderId(orderId) + .goodsId(StringUtils.isNotEmpty(goodsId) ? goodsId : EMPTY_STRING) + .color(EMPTY_STRING) + .category(type) + .type(type) + .length(NumberUtil.parseDouble(module.getHeight())) + .width(NumberUtil.parseDouble(module.getWidth())) + .thickness(NumberUtil.parseDouble(module.getThickness())) + .isComposite(module.getIsComposite()) + .name(module.getName()) + .material(EMPTY_STRING) + .model(module.getModel()) + .spec(module.getSpec()) + .brand(module.getBrand()) + .factory(module.getFactory()) + .unit(module.getUnit()) + .price(0.0) + .subparts(EMPTY_STRING) + .remark("") + .organId(organId) + .deleted(false) + .build(); + orderPartsDOS.add(orderPartsDO); + orderInfoBatchInsertWithinThreshold(orderPartsMapper, orderPartsDOS, false); + + // 配件id回显到列表 + module.setImesPartsId(partId); + } + orderInfoBatchInsertWithinThreshold(orderPartsMapper, orderPartsDOS, true); + } + + /** + * 配件对应 + * + * @param parts + * @param blockObjectList + */ + private void matchLeftEdge(WebCadDataPartsReqVO parts, List blockObjectList) { + List leftEdges = parts.getLeftEdges(); + if (CollUtil.isNotEmpty(leftEdges)) { + for (WebCadDataPartsReqVO.LeftEdgesDTO leftEdge : leftEdges) { + List objectIds = leftEdge.getObjectIds(); + if (CollUtil.isNotEmpty(objectIds)) { + for (Integer partIndex : objectIds) { + // partIndex序号对应配件 + WebCadDataPartsReqVO.BlockObjectListDTO part = blockObjectList.get(partIndex - 1); + // id、goodsId赋值到对应的cad配件上 + part.setGoodsId(leftEdge.getGoodsId()); + part.setPartId(leftEdge.getId()); + } + } + } + } + } + + /** + * 配件类型转换 + * + * @param objectType + * @param isComposite + * @return + */ + private String changePartType(String objectType, boolean isComposite) { + if (PART_CATEGORY_ONE.equals(objectType)) { + return PART_CATEGORY_ONE; + } else { + if (isComposite) { + return PART_CATEGORY_THREE; + } else { + return PART_CATEGORY_TWO; + } + } + } + + /** + * 每达到阈值就批量插入一次 + * + * @param baseBatchMapper + * @param list + * @param isLast 是否最后一次插入,不是就需要清理list + */ + private void orderInfoBatchInsertWithinThreshold(BaseBatchMapper baseBatchMapper, List list, boolean isLast) { + // 达到批量的阈值就做一次插入 + if (CollUtil.isNotEmpty(list) && (list.size() >= BATCH_THRESHOLD_NUMBER || isLast)) { + baseBatchMapper.insertBatchSomeColumn(list); + if (!isLast) { + // 存储完成清理 list + list.clear(); + } + } + } + + /** + * 每达到阈值就批量插入一次生产单造型数据和压缩数据 + * + * @param isLast 是否最后一次插入,不是就需要清理list + */ + private void orderModelsBatchInsertWithinThreshold(boolean isLast) { + // 达到批量的阈值就做一次插入 + if (CollUtil.isNotEmpty(orderModelDOS) && (orderModelDOS.size() >= BATCH_THRESHOLD_NUMBER || isLast)) { + // 保存生产单造型数据 + orderInputProcessor.batchSaveModel(orderModelDOS); + if (!isLast) { + // 存储完成清理 list + orderModelDOS.clear(); + } + } + } + + /** + * 获取板件封边厚度 + * cad封边列表的顺序:下右上左 + * + * @param plateDO + * @param sealingList + */ + private void calculateSealThickness(PlateDO plateDO, List sealingList) { + if (CollUtil.isNotEmpty(sealingList) && sealingList.size() == 4) { + plateDO.setSealDown(BigDecimal.valueOf(sealingList.get(0).getSize())); + plateDO.setSealLeft(BigDecimal.valueOf(sealingList.get(1).getSize())); + plateDO.setSealUp(BigDecimal.valueOf(sealingList.get(2).getSize())); + plateDO.setSealRight(BigDecimal.valueOf(sealingList.get(3).getSize())); + } + } + + /** + * 数据保存入库 + */ + private void saveData() { + orderInfoBatchInsertWithinThreshold(orderBodyMapper, bodyMap.values().stream().toList(), true); + orderInfoBatchInsertWithinThreshold(orderItemMapper, orderItemDOS, true); + orderInfoBatchInsertWithinThreshold(orderGroupMapper, orderGroupDOS, true); + } + + + /** + * 清空所有列表 + */ + private void clearAll() { + orderPartsDOS.clear(); + orderGroupDOS.clear(); + orderGroupMap.clear(); + plateDOS.clear(); + orderItemDOS.clear(); + orderModelDOS.clear(); + roomBodyMap.clear(); + bodyMap.clear(); + } +}