From e29ee200881d8d552644adbca62d75108416df30 Mon Sep 17 00:00:00 2001 From: lym <1994302445@qq.com> Date: Tue, 12 Nov 2024 17:26:48 +0800 Subject: [PATCH] =?UTF-8?q?api=E9=85=8D=E4=BB=B6=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E3=80=81excel=E5=AF=BC=E5=85=A5=E6=A3=80=E6=9F=A5=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/executor/enums/CategoryEnum.java | 23 + .../module/executor/enums/IsHavaeEnum.java | 32 + .../module/executor/enums/QuarrelEnum.java | 22 + .../admin/order/OrderController.java | 11 + .../dataobject/orderParts/OrderPartsDO.java | 24 + .../dal/dataobject/orderParts/PartsDO.java | 101 ++++ .../dal/mysql/orderParts/PartsMapper.java | 19 + .../service/order/OrderInputProcessor.java | 9 +- .../service/order/OrderServiceImpl.java | 34 +- .../admin/files/excel/ExcelReadUtil.java | 566 ++++++++---------- .../admin/files/excel/ExcelTypeRealize.java | 6 + .../files/excel/OrderPlateImportExcelVO.java | 18 +- .../mapper/orderItem/OrderItemMapper.xml | 13 +- .../main/resources/type/order_add_excel.xlsx | Bin 28882 -> 28268 bytes .../resources/type/order_add_excel_err.xlsx | Bin 25038 -> 26314 bytes 15 files changed, 558 insertions(+), 320 deletions(-) create mode 100644 cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/CategoryEnum.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/IsHavaeEnum.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/QuarrelEnum.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderParts/PartsDO.java create mode 100644 cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/orderParts/PartsMapper.java diff --git a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/CategoryEnum.java b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/CategoryEnum.java new file mode 100644 index 000000000..11415888f --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/CategoryEnum.java @@ -0,0 +1,23 @@ +package com.cf.imes.module.executor.enums; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 配件主类的枚举值 + */ +@Getter +@AllArgsConstructor +public enum CategoryEnum { + + ASSEMBLY("组件"), + HARDWARE("五金"), + EDGING("封边条"); + + /** + * 类别名称 + */ + private final String value; + +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/IsHavaeEnum.java b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/IsHavaeEnum.java new file mode 100644 index 000000000..5ac70416b --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/IsHavaeEnum.java @@ -0,0 +1,32 @@ +package com.cf.imes.module.executor.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum IsHavaeEnum { + + HAVE_ITEM(0, "有"), + BI_ITEM(1, "无"); + + + private final Integer status; + private final String value; + + public Integer getStatus() { + return status; + } + + public String getValue() { + return value; + } + + public boolean equals(Integer status) { + return this.status .equals(status) ; + } + + public boolean equals(IsHavaeEnum quarrelEnum) { + return quarrelEnum != null && quarrelEnum.status .equals(this.getStatus()) ; + } +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/QuarrelEnum.java b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/QuarrelEnum.java new file mode 100644 index 000000000..99b257a96 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/QuarrelEnum.java @@ -0,0 +1,22 @@ +package com.cf.imes.module.executor.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum QuarrelEnum { + PLATE_ITEM(0, "是"), + OTHER_ITEM(1, "否"); + + private final Integer status; + private String value; + + public boolean equals(Integer status) { + return this.status .equals(status) ; + } + + public boolean equals(QuarrelEnum quarrelEnum) { + return quarrelEnum != null && quarrelEnum.status .equals(this.getStatus()) ; + } +} 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 6d2db10a9..e3dcdb2c1 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 @@ -8,6 +8,7 @@ import com.cf.imes.framework.common.pojo.PageResult; import com.cf.imes.framework.common.util.object.BeanUtils; import com.cf.imes.framework.mybatis.core.generator.SnowFlakeGenerator; import com.cf.imes.framework.operatelog.core.annotations.OperateLog; +import com.cf.imes.framework.redis.util.RedisLockUtil; import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils; import com.cf.imes.module.executor.controller.admin.order.vo.order.*; import com.cf.imes.module.executor.controller.admin.order.vo.product.OrderBodyRespVO; @@ -94,6 +95,10 @@ public class OrderController { @Resource private XmlTypeRealize xmlTypeRealize; + + @Resource + private RedisLockUtil redisLockUtil; + @PutMapping("/update") @Operation(summary = "更新生产单") @PreAuthorize("@ss.hasPermission('production:manager-list:edit')") @@ -195,6 +200,7 @@ public class OrderController { @PreAuthorize("@ss.hasPermission('production:manager-list:create')") public CommonResult getApiData(@RequestParam(value = "orderNo") String orderNo){ + redisLockUtil.lock(orderNo); try { Long orderId = (Long) identifierGenerator.nextId(null); Long organId = getUserOrganId(); @@ -232,6 +238,8 @@ public class OrderController { } catch (Exception e) { log.error("api数据导入异常", e); return success(e.getMessage()); + } finally { + redisLockUtil.unlock(orderNo); } } @@ -260,6 +268,7 @@ public class OrderController { Boolean flag = true; String customOrderNoKey = "自定义单号"; + redisLockUtil.lock(file.getOriginalFilename()); try { if (type == 0) { //excel excelReadUtil.setErr(0); @@ -365,6 +374,8 @@ public class OrderController { String xmlStr = XmlBuilder.objectToXmlStr(orderXmlVO); XMLUtil.writeErr(response, xmlStr, " order_add_xml_err.xml"); } + } finally { + redisLockUtil.unlock(file.getOriginalFilename()); } } diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderParts/OrderPartsDO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderParts/OrderPartsDO.java index db717429e..7f0efe4b1 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderParts/OrderPartsDO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderParts/OrderPartsDO.java @@ -38,6 +38,10 @@ public class OrderPartsDO extends BaseDO { * 配件名称 */ private String name; + /** + * 颜色 + */ + private String color; /** * 材质 */ @@ -45,7 +49,23 @@ public class OrderPartsDO extends BaseDO { /** * 配件类型 */ + private String category; + /** + * 配件子类 + */ private String type; + /** + * 宽度 + */ + private Double width; + /** + * 长度 + */ + private Double length; + /** + * 厚度 + */ + private Double thickness; /** * 型号 */ @@ -74,6 +94,10 @@ public class OrderPartsDO extends BaseDO { * 是否复合部件:0 否 1 是 */ private Boolean isComposite; + /** + * 子配件ID列表,复合部件时记录子配件ID,半角逗号分隔 + */ + private String subparts; /** * 备注 */ diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderParts/PartsDO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderParts/PartsDO.java new file mode 100644 index 000000000..584a3cb39 --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderParts/PartsDO.java @@ -0,0 +1,101 @@ +package com.cf.imes.module.executor.dal.dataobject.orderParts; + +import lombok.*; +import com.baomidou.mybatisplus.annotation.*; +import com.cf.imes.framework.mybatis.core.dataobject.BaseDO; + +/** + * 配件表 parts_{N} DO + * + * @author 晨丰科技 + */ +@TableName("parts") +@KeySequence("parts_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PartsDO extends BaseDO { + + /** + * 配件 ID + */ + @TableId + private Long id; + /** + * 组织id + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long organId; + /** + * 设计端商品ID + */ + private String goodsId; + /** + * 配件名称 + */ + private String name; + /** + * 材质:颗粒板、欧松板、多层板、生态板、禾香板、密度板、实木、铝蜂窝板、铝塑板 + */ + private String material; + /** + * 颜色 + */ + private String color; + /** + * 配件类型 + */ + private String type; + /** + * 配件主类 + */ + private String category; + /** + * 型号 + */ + private String model; + /** + * 宽度 + */ + private Double width; + /** + * 长度 + */ + private Double length; + /** + * 厚度 + */ + private Double thickness; + /** + * 规格 + */ + private String spec; + /** + * 品牌 + */ + private String brand; + /** + * 厂家 + */ + private String factory; + /** + * 单位 + */ + private String unit; + /** + * 是否复合部件:0 否 1 是 + */ + private Boolean isComposite; + /** + * 子配件ID列表,复合部件时记录子配件ID,半角逗号分隔 + */ + private String subparts; + /** + * 备注 + */ + private String remark; + +} \ 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/mysql/orderParts/PartsMapper.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/orderParts/PartsMapper.java new file mode 100644 index 000000000..84436426b --- /dev/null +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/orderParts/PartsMapper.java @@ -0,0 +1,19 @@ +package com.cf.imes.module.executor.dal.mysql.orderParts; + +import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX; +import com.cf.imes.module.executor.dal.dataobject.orderParts.PartsDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 配件表 parts_{N} Mapper + * + * @author 晨丰科技 + */ +@Mapper +public interface PartsMapper extends BaseMapperX { + + default PartsDO selectByGoodID(String goodId , Long organId) { + return selectOne(PartsDO::getGoodsId, goodId, PartsDO::getOrganId, organId); + } + +} diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderInputProcessor.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderInputProcessor.java index 184e6201d..8b369b3e1 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderInputProcessor.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderInputProcessor.java @@ -16,6 +16,7 @@ import com.cf.imes.module.executor.dal.dataobject.orderGroup.OrderGroupDO; import com.cf.imes.module.executor.dal.dataobject.orderItem.OrderItemDO; import com.cf.imes.module.executor.dal.dataobject.orderModuleExtra.OrderModuleExtraDO; import com.cf.imes.module.executor.dal.dataobject.orderParts.OrderPartsDO; +import com.cf.imes.module.executor.dal.dataobject.orderParts.PartsDO; import com.cf.imes.module.executor.dal.dataobject.ordermodel.OrderModelDO; import com.cf.imes.module.executor.dal.dataobject.plate.PlateDO; import com.cf.imes.module.executor.dal.dataobject.plate.PlateGoodDO; @@ -27,6 +28,7 @@ import com.cf.imes.module.executor.dal.mysql.orderGroup.OrderGroupMapper; import com.cf.imes.module.executor.dal.mysql.orderItem.OrderItemMapper; import com.cf.imes.module.executor.dal.mysql.orderModuleExtra.OrderModuleExtraMapper; import com.cf.imes.module.executor.dal.mysql.orderParts.OrderPartsMapper; +import com.cf.imes.module.executor.dal.mysql.orderParts.PartsMapper; import com.cf.imes.module.executor.dal.mysql.plate.PlateGoodMapper; import com.cf.imes.module.executor.dal.mysql.plate.PlateMapper; import com.cf.imes.module.executor.dal.mysql.rawgoods.RawGoodsMapper; @@ -85,6 +87,9 @@ public class OrderInputProcessor { @Resource private ESDocumentService esDocumentService; + @Resource + private PartsMapper partsMapper; + @Resource private ElasticsearchClient elasticsearchClient; @@ -112,7 +117,8 @@ public class OrderInputProcessor { Collection plateDOS, Collection itemDOS, Collection goodsDOS, - Collection plateGoodDOS) { + Collection plateGoodDOS, + Collection partsDOS) { // if (rawGoodsDOS != null) @@ -159,6 +165,7 @@ public class OrderInputProcessor { insertInBatches(itemDOS, 1000, (batch, index) -> orderItemMapper.insertBatch((Collection) batch)); insertInBatches(goodsDOS, 1000, (batch, index) -> goodsMapper.insertBatch((Collection) batch)); insertInBatches(plateGoodDOS, 1000, (batch, index) -> plateGoodMapper.insertBatch((Collection) batch)); + insertInBatches(partsDOS, 1000, (batch, index) -> partsMapper.insertBatch((Collection) batch)); } private void insertInBatches(Collection entities, int batchSize, BiConsumer, Integer> insertFunction) { 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 60b210ed0..41bd8cf41 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 @@ -28,6 +28,7 @@ import com.cf.imes.module.executor.dal.dataobject.orderBody.OrderBodyDO; import com.cf.imes.module.executor.dal.dataobject.orderGroup.OrderGroupDO; import com.cf.imes.module.executor.dal.dataobject.orderItem.OrderItemDO; import com.cf.imes.module.executor.dal.dataobject.orderParts.OrderPartsDO; +import com.cf.imes.module.executor.dal.dataobject.orderParts.PartsDO; import com.cf.imes.module.executor.dal.dataobject.ordermodel.OrderModelDO; import com.cf.imes.module.executor.dal.dataobject.pack.OrderPackageDO; import com.cf.imes.module.executor.dal.dataobject.plan.PlanDO; @@ -40,6 +41,7 @@ import com.cf.imes.module.executor.dal.mysql.orderBody.OrderBodyMapper; import com.cf.imes.module.executor.dal.mysql.orderGroup.OrderGroupMapper; import com.cf.imes.module.executor.dal.mysql.orderItem.OrderItemMapper; import com.cf.imes.module.executor.dal.mysql.orderParts.OrderPartsMapper; +import com.cf.imes.module.executor.dal.mysql.orderParts.PartsMapper; import com.cf.imes.module.executor.dal.mysql.pack.OrderPackageMapper; import com.cf.imes.module.executor.dal.mysql.pack.OrderPrepackagedMapper; import com.cf.imes.module.executor.dal.mysql.plan.PlanMapper; @@ -130,6 +132,9 @@ public class OrderServiceImpl implements OrderService { @Resource private SnowflakeIdWorker3rd idWorker; + @Resource + private PartsMapper partsMapper; + private static final String SUBMIT_STATE = "1"; // 空订单 原生产系统 @@ -391,9 +396,11 @@ public class OrderServiceImpl implements OrderService { Map> map = getPlateGoods(goodsDO);// 检验商品板材信息是否存在 goodsDO = (List) map.get(GOODSDO_KEY); List plateGoodDOS = (List) map.get(PLATE_GOODS_LIST_KEY); + // 配件信息 + List partsDOS = getPartsGoods(partsDO); - orderInputProcessor.batchInsert(rawGoodsDO, bodyDO, groupDO, partsDO, plateDO, itemDO, goodsDO, plateGoodDOS); + orderInputProcessor.batchInsert(rawGoodsDO, bodyDO, groupDO, partsDO, plateDO, itemDO, goodsDO, plateGoodDOS, partsDOS); List orderModelDOs = BeanUtils.toBean(plateDetail, OrderModelDO.class); if (!orderModelDOs.isEmpty()) { @@ -446,7 +453,8 @@ public class OrderServiceImpl implements OrderService { Map> map = getPlateGoods(goodsDO);// 检验商品板材信息是否存在 excel goodsDO = (List) map.get(GOODSDO_KEY); List plateGoodDOS = (List) map.get(PLATE_GOODS_LIST_KEY); - + // 配件库匹配 + List partsDOList = getPartsGoods(partsDO); if (index != 0) { roomCabinetProcessGroupMatch(orderDO.getId(), bodyDO, itemDO); @@ -463,7 +471,7 @@ public class OrderServiceImpl implements OrderService { updateOrder(BeanUtils.toBean(orderDO, OrderSaveReqVO.class)); } } - orderInputProcessor.batchInsert(rawGoodsDO, bodyDO, groupDO, partsDO, plateDO, itemDO, goodsDO, plateGoodDOS); + orderInputProcessor.batchInsert(rawGoodsDO, bodyDO, groupDO, partsDO, plateDO, itemDO, goodsDO, plateGoodDOS, partsDOList); if (orderModelDOS != null && !orderModelDOS.isEmpty()) { orderInputProcessor.batchSaveModel(orderModelDOS); } @@ -693,12 +701,28 @@ public class OrderServiceImpl implements OrderService { private PlateGoodDO getPlateGood(String goodsId, Long organId) { List plateGoodDOs = plateGoodMapper.selectGoodOne(goodsId, organId); - if (plateGoodDOs.size() > 0) { + if (!plateGoodDOs.isEmpty()) { return plateGoodDOs.get(0); } return null; } + // 配件匹配 + private List getPartsGoods(List partsLists) { + List partsDOS = new ArrayList<>(); + + for (OrderPartsDO partsDO : partsLists) { + if (partsDO.getGoodsId() != null) { // 有goodsId + PartsDO part = partsMapper.selectByGoodID(partsDO.getGoodsId(), OrganContextHolder.getOrganId()); + if (part == null) { // 不存在记录,存入数据库 + partsDOS.add(BeanUtils.toBean(partsDO, PartsDO.class).setOrganId(OrganContextHolder.getOrganId())); + + } + } + } + return partsDOS; + } + private Map> getPlateGoods(List goodsLists) { Map> map = new HashMap<>(); List plateGoodLists = new ArrayList<>(); @@ -717,7 +741,7 @@ public class OrderServiceImpl implements OrderService { goodsDO.setGoodsId((obtainingTime) + Long.toString(plateNo).substring(2)); } - if (plateGoodDOS != null && plateGoodDOS.size() > 0) {//存在板材 + if (plateGoodDOS != null && !plateGoodDOS.isEmpty()) {//存在板材 goodsDO.setGoodsId(plateGoodDOS.get(0).getGoodsId()); } else if (plateGoodDO != null) { // 存在板材 goodsDO.setGoodsId(plateGoodDO.getGoodsId()); diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/ExcelReadUtil.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/ExcelReadUtil.java index f845fa1f5..732afa425 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/ExcelReadUtil.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/ExcelReadUtil.java @@ -6,12 +6,10 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.nacos.common.utils.StringUtils; import com.cf.imes.framework.organ.core.context.OrganContextHolder; import com.cf.imes.module.executor.dal.dataobject.order.OrderDO; -import com.cf.imes.module.executor.enums.DataTypeEnum; -import com.cf.imes.module.executor.enums.OrderTypeEnum; +import com.cf.imes.module.executor.enums.*; import com.cf.imes.module.executor.util.fileConversion.admin.ToolUtil; import com.cf.imes.module.system.api.dict.DictDataApi; import com.cf.imes.module.system.api.dict.dto.DictDataRespDTO; -import com.cf.imes.module.executor.enums.DictTypeConstants; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.MapUtils; import org.springframework.stereotype.Component; @@ -19,6 +17,7 @@ import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.*; +import java.lang.reflect.Field; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -27,8 +26,6 @@ import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import static com.mysql.cj.util.TimeUtil.DATE_FORMATTER; - @Slf4j @Component public class ExcelReadUtil { // 文件读取 @@ -40,6 +37,11 @@ public class ExcelReadUtil { // 文件读取 private static final String ERR = "error"; private static final String DEALER_PHONE = "dealerPhoneNumber"; private static final String NUMBER_TYPE_ERR = "数量类型错误"; + private static final String NOT_EMPTY= "不可为空"; + private static final String NUMBER_ERR = "数量错误"; + private static final String ACCORD_ENUM = "请按照提示词语选择填入"; + private static final String POSITIVE_ERR = "数据需为正数"; + private static final String NUMBER_LENGTH_ERR = "数据长度过长"; // 读excel public Map read(MultipartFile file) throws IOException { Map map = new HashMap<>(); @@ -64,34 +66,38 @@ public class ExcelReadUtil { // 文件读取 if (index.get()) { orderMap.put(item.get(0), item.get(1)); - orderMap.put(item.get(16), item.get(17)); + orderMap.put(item.get(19), item.get(20)); i.getAndIncrement(); } else { if (i.getAndIncrement() > 6){ list.add(changeValue(item)); } -// if (item.get(1).equals("配件") || item.get(1).equals("板材")) { -// list.add(changeValue(item)); -// } } } ); index.set(true); -// if (MapUtil.isEmpty(orderMap) || CollectionUtil.isEmpty(list)) { -// isErr.set(-1); -// } map.put("orderPri", orderMap); map.put("plate", list); return map; } - private void setIfInvalid(String key, String errValue, Map orderMap, AtomicBoolean error) { - if (orderMap.get(key) == null) { - orderMap.put(key, errValue); - error.set(false); - } + // + private void setIfInvalid(String key, String errValue, Map orderMap,int length, AtomicBoolean error) { + orderMap.compute(key, (k, v) -> { + if (v == null) { + error.set(false); + return errValue; + } else { + int size = ((String) v).length(); + if (size > length) { + error.set(false); + return NUMBER_LENGTH_ERR; + } + } + return v; + }); } private void setPhone(String key, String errValue, Map orderMap, AtomicBoolean error) { @@ -111,10 +117,10 @@ public class ExcelReadUtil { // 文件读取 AtomicBoolean error = new AtomicBoolean(true); - setIfInvalid("客户", "---< 客户不能为空 >---", orderMap, error); - setIfInvalid("经销商", "---< 经销商不能为空 >---", orderMap, error); - setIfInvalid("客户地址", "---< 客户地址不能为空 >---", orderMap, error); - setIfInvalid("客户地址", "---< 客户地址不能为空 >---", orderMap, error); + setIfInvalid("客户", "---< 客户不能为空 >---", orderMap, 255, error); + setIfInvalid("经销商", "---< 经销商不能为空 >---", orderMap, 255, error); + setIfInvalid("客户地址", "---< 客户地址不能为空 >---", orderMap, 255, error); + setIfInvalid("客户地址", "---< 客户地址不能为空 >---", orderMap, 255, error); if (orderMap.get("客户电话") == null) { orderMap.put("客户电话", "---< 客户电话不能为空 >---"); @@ -198,115 +204,124 @@ public class ExcelReadUtil { // 文件读取 case 6:// 颜色 vo.setColor(value); break; - case 7:// 厂家 + case 7:// 复合部件 + vo.setIsComposite(value); + break; + case 8:// 配件类型 + vo.setCategory(value); + break; + case 9:// 子类 + vo.setType(value); + break; + case 10:// 厂家 vo.setFactory(value); break; - case 8:// 品牌 + case 11:// 品牌 vo.setBrand(value); break; - case 9:// 型号 + case 12:// 型号 vo.setModel(value); break; - case 10:// 板材长 + case 13:// 板材/配件长 vo.setGoodsHeight(value); break; - case 11:// 板材宽 + case 14:// 板材/配件宽 vo.setGoodsWidth(value); break; - case 12:// 板材厚 + case 15:// 板材/配件厚 vo.setGoodsThickness(value); break; - case 13:// 规格 + case 16:// 规格 vo.setSpec(value); break; - case 14:// 单位 + case 17:// 单位 vo.setUnit(value); break; - case 15:// 数量 + case 18:// 数量 vo.setGoodsNumber(value); break; - case 16:// 房间 + case 19:// 房间 vo.setRoomsName(value); break; - case 17:// 柜体 + case 20:// 柜体 vo.setCabinetsName(value); break; - case 18:// 加工组类型 + case 21:// 加工组类型 vo.setSynthesisTypeName(value); break; - case 19:// 加工组名称 + case 22:// 加工组名称 vo.setCombinationName(value); break; - case 20://板名称 + case 23://板名称 vo.setName(value); break; - case 21:// 自定义板编号 + case 24:// 自定义板编号 vo.setPlateNo(value); break; - case 22:// 成品长 + case 25:// 成品长 vo.setHeight(value); break; - case 23:// 成品宽 + case 26:// 成品宽 vo.setWidth(value); break; - case 24:// 拆单长 + case 27:// 拆单长 vo.setSplitHeight(value); break; - case 25:// 拆单宽 + case 28:// 拆单宽 vo.setSplitWidth(value); break; - case 26:// 厚 + case 29:// 厚 vo.setThickness(value); break; - case 27:// 左封边 + case 30:// 左封边 vo.setSealLeft(value); break; - case 28:// 右封边 + case 31:// 右封边 vo.setSealRight(value); break; - case 29:// 上封边 + case 32:// 上封边 vo.setSealUp(value); break; - case 30:// 下封边 + case 33:// 下封边 vo.setSealDown(value); break; - case 31:// 排版面 + case 34:// 排版面 vo.setTypographicFace(value); break; - case 32:// 纹路 + case 35:// 纹路 vo.setTexture(value); break; - case 33:// 开门方向 + case 36:// 开门方向 vo.setOpenDoorType(value); break; - case 34://备注1 + case 37://备注1 vo.setRemark1(value); break; - case 35://备注2 + case 38://备注2 vo.setRemark2(value); break; - case 36://备注3 + case 39://备注3 vo.setRemark3(value); break; - case 37://备注4 + case 40://备注4 vo.setRemark4(value); break; - case 38://备注5 + case 41://备注5 vo.setRemark5(value); break; - case 39://备注6 + case 42://备注6 vo.setRemark6(value); break; - case 40://备注7 + case 43://备注7 vo.setRemark7(value); break; - case 41://备注8 + case 44://备注8 vo.setRemark8(value); break; - case 42://备注9 + case 45://备注9 vo.setRemark9(value); break; - case 43://备注10 + case 46://备注10 vo.setRemark10(value); break; default: @@ -318,272 +333,215 @@ public class ExcelReadUtil { // 文件读取 return vo; } - // OrderPlateImportExcelVO 数据验证 - private Boolean checkVO(OrderPlateImportExcelVO vo) { - List errList = new ArrayList<>(); - Boolean flag = true; - // 检查非空 类型、数量 - if (StringUtils.isEmpty(vo.getGoodType())) { - errList.add("类型不能为空"); - flag = false; + // 错误判断通用方法 + // 判断非零,错误返回;不为空时,判断是否符合枚举类 + private void isNotEmptyAndBack(String value, Class> enumClass, List errList, String errValue, int length , AtomicBoolean flag) { + if (StringUtils.isEmpty(value)) { + errList.add(errValue + NOT_EMPTY); + flag.set(false); + } else { + isEmptyAndSize(value, length, errList, errValue, flag); + try { + // 获取枚举类的所有值 + Enum[] enums = enumClass.getEnumConstants(); + boolean isValid = false; + for (Enum enumValue : enums) { + Field valueField = enumValue.getClass().getDeclaredField("value"); + valueField.setAccessible(true); + String enumValueStr = (String) valueField.get(enumValue); + if (enumValueStr.equals(value)) { + isValid = true; + break; + } + } + if (!isValid) { + errList.add(errValue + ACCORD_ENUM); + flag.set(false); + } + } catch (IllegalArgumentException e) { + errList.add(errValue + ACCORD_ENUM); + flag.set(false); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } } - if (StringUtils.isEmpty(vo.getGoodsNumber())) { - errList.add("数量不能为空"); - flag = false; - }else { - if (!convertToDouble(vo.getGoodsNumber())) { - flag = false; - errList.add(NUMBER_TYPE_ERR); + } + + // 非零判断,有值判断---判断数值类型,数值长度 + private void isEmptyAndPositiveNumberSize(String value, Class targetType, Integer length, Integer decimalLength, List errList, String errValue, AtomicBoolean flag) { + if (StringUtils.isNotEmpty(value)) { + if (Boolean.TRUE.equals(ToolUtil.convertToType(value, targetType))) { + if (Boolean.TRUE.equals(ToolUtil.checkNumber(value))) { + if (!ToolUtil.checkPrecision(value, length, decimalLength)) { + errList.add(errValue + NUMBER_LENGTH_ERR); + flag.set(false); + } + } else { + errList.add(errValue + POSITIVE_ERR); + flag.set(false); + } + } else { + errList.add(errValue + NUMBER_TYPE_ERR); + flag.set(false); + } + } + } + + // 判断非零,错误返回 + private void isNotEmptyAndBack(String value, List errList, String errValue, AtomicBoolean flag) { + if (StringUtils.isEmpty(value)) { + errList.add(errValue + NOT_EMPTY); + flag.set(false); + } + } + + // 判断非空,有值判断字符串的长度 + private void isEmptyAndSize(String value, Integer length, List errList, String errValue, AtomicBoolean flag) { + if (StringUtils.isNotEmpty(value)) { + int size = value.length(); + if (size > length) { + errList.add(errValue + NUMBER_LENGTH_ERR); + flag.set(false); + } + } + } + + // 非空判断,错误填入 + private void isEmpty(String value, List errList, String errValue, int length, AtomicBoolean flag) { + if (StringUtils.isEmpty(value)) { + errList.add(errValue + NOT_EMPTY); + flag.set(false); + } else { + // 字符串长度检查 + int size = value.length(); + if (size > length) { + errList.add(errValue + NUMBER_LENGTH_ERR); + flag.set(false); + } + } + } + + // 判断非空,大于零判断 + public void isEmptyAndPositiveNumber(String value, Class targetType, List errList, String errValue, AtomicBoolean flag) { + if (StringUtils.isNotEmpty(value)) { + if (Boolean.FALSE.equals(ToolUtil.convertToType(value, targetType))) { + errList.add(errValue + NUMBER_TYPE_ERR); + flag.set(false); }else { - if (!checkNumber(vo.getGoodsNumber())) { - flag = false; - errList.add("数量不能为0"); + if (Boolean.FALSE.equals(checkNumber(value))) { + errList.add(errValue + "数量不能为0"); + flag.set(false); } } } + } + + // 判断非空,字典值判断 + public void isNotEmptyAndDict(String value, String dictType, List errList, String errValue, AtomicBoolean flag) { + if (StringUtils.isEmpty(value)) { + errList.add(errValue + NOT_EMPTY); + flag.set(false); + } else { + DictDataRespDTO dictDataRespDTO = dictDataApi.parseDictData(dictType, value).getData(); + if (dictDataRespDTO == null) { + errList.add(errValue + ACCORD_ENUM); + flag.set(false); + } + } + } + + // 板材的数据以及长度的检验 + public void checkPlate(OrderPlateImportExcelVO vo, List errList , AtomicBoolean flag) { + // 数量类型判断 + isEmptyAndPositiveNumber(vo.getGoodsNumber(), Integer.class, errList, "板材数量", flag); + // 板材纹理 + isNotEmptyAndBack(vo.getWave(), IsHavaeEnum.class, errList, "板材纹理", 4, flag); + // 大板的长宽厚存在以及是否符合数个 + isNotEmptyAndBack(vo.getGoodsWidth(), errList, "板材长度", flag); + isEmptyAndPositiveNumberSize(vo.getGoodsWidth(), Double.class, 5, 3, errList, "板材长度", flag); + isNotEmptyAndBack(vo.getGoodsHeight(), errList, "板材宽度", flag); + isEmptyAndPositiveNumberSize(vo.getGoodsHeight(), Double.class, 5, 3, errList, "板材宽度", flag); + isNotEmptyAndBack(vo.getGoodsThickness(), errList, "板材厚度", flag); + isEmptyAndPositiveNumberSize(vo.getGoodsThickness(), Double.class, 5, 3, errList, "板材厚度", flag); + // 房间、柜体、板名称 不可以为空 + isEmpty(vo.getRoomsName(), errList, "房间名称", 64, flag); + isEmpty(vo.getCabinetsName(), errList, "柜体名称", 64, flag); + isEmpty(vo.getName(), errList, "板材名称", 64, flag); + //成品长、成品宽、拆单长、拆单宽、厚、左封边、右封边、上封边、下封边 不能为空 + isNotEmptyAndBack(vo.getHeight(), errList, "成品长度", flag); + isEmptyAndPositiveNumberSize(vo.getHeight(), Double.class, 5, 3, errList, "成品长度", flag); + isNotEmptyAndBack(vo.getWidth(), errList, "成品宽度", flag); + isEmptyAndPositiveNumberSize(vo.getWidth(), Double.class, 5, 3, errList, "成品宽度", flag); + isNotEmptyAndBack(vo.getSplitHeight(), errList, "拆单长度", flag); + isEmptyAndPositiveNumberSize(vo.getSplitHeight(), Double.class, 5, 3, errList, "拆单长度", flag); + isNotEmptyAndBack(vo.getSplitWidth(), errList, "拆单宽度", flag); + isEmptyAndPositiveNumberSize(vo.getSplitWidth(), Double.class, 5, 3, errList, "拆单宽度", flag); + isNotEmptyAndBack(vo.getThickness(), errList, "厚度", flag); + isEmptyAndPositiveNumberSize(vo.getThickness(), Double.class, 5, 3, errList, "厚度", flag); + isNotEmptyAndBack(vo.getSealLeft(), errList, "左封边", flag); + isEmptyAndPositiveNumberSize(vo.getSealLeft(), Double.class, 5, 3, errList, "左封边", flag); + isNotEmptyAndBack(vo.getSealRight(), errList, "右封边", flag); + isEmptyAndPositiveNumberSize(vo.getSealRight(), Double.class, 5, 3, errList, "右封边", flag); + isNotEmptyAndBack(vo.getSealUp(), errList, "上封边", flag); + isEmptyAndPositiveNumberSize(vo.getSealUp(), Double.class, 5, 3, errList, "上封边", flag); + isNotEmptyAndBack(vo.getSealDown(), errList, "下封边", flag); + isEmptyAndPositiveNumberSize(vo.getSealDown(), Double.class, 5, 3, errList, "下封边", flag); + // 排版面、纹路、开门方向 + isNotEmptyAndDict(vo.getTypographicFace(), DictTypeConstants.TYPOGRAPHY_TYPE, errList, "排版面", flag); + isNotEmptyAndDict(vo.getTexture(), DictTypeConstants.GRAIN_TYPE, errList, "纹路", flag); + isNotEmptyAndDict(vo.getOpenDoorType(), DictTypeConstants.DOOR_OPENING_DIRECTIONS, errList, "开门方向", flag); + + } + // OrderPlateImportExcelVO 数据验证 + private Boolean checkVO(OrderPlateImportExcelVO vo) { + List errList = new ArrayList<>(); + AtomicBoolean flag = new AtomicBoolean(true); + + // 全部需要值的字段 + // 检查非空 类型、数量 + isEmpty(vo.getGoodType(), errList, "类型",32, flag); + isEmpty(vo.getGoodsNumber(), errList, "数量", 10000000 ,flag); + // 检查商品物料编码或是商品名称、规格、材质、颜色不可全为空 if (StringUtils.isEmpty(vo.getGoodsName()) || StringUtils.isEmpty(vo.getSpec()) || StringUtils.isEmpty(vo.getMaterial()) || StringUtils.isEmpty(vo.getColor()) || StringUtils.isEmpty(vo.getUnit())) { errList.add("商品商品名称、规格、材质、颜色、单位不可为空"); - flag = false; + flag.set(false); + } + + + if (StringUtils.equals(vo.getGoodType(), "配件")) { + // 复合部件必填 + isNotEmptyAndBack(vo.getIsComposite(), QuarrelEnum.class, errList, "是否复合部件", 1, flag); // 判断传入的值,是否符合字典中的枚举类 + // 配件类型必填 + isNotEmptyAndBack(vo.getCategory(), CategoryEnum.class, errList, "配件类型", 32, flag); + // 配件长宽厚,存在判断是否可以转义 + isEmptyAndPositiveNumberSize(vo.getGoodsWidth(), Double.class, 5, 3, errList, "配件宽", flag); + isEmptyAndPositiveNumberSize(vo.getGoodsHeight(), Double.class, 5, 3, errList, "配件高", flag); + isEmptyAndPositiveNumberSize(vo.getGoodsThickness(), Double.class, 5, 3, errList, "配件厚", flag); + // 配件类型为封边条的时候,需要填写配件宽厚 + if (StringUtils.equals(vo.getCategory(), CategoryEnum.EDGING.getValue())) { // 封边条必须有宽高 + isNotEmptyAndBack(vo.getGoodsWidth(), errList, "封边条宽", flag); + isNotEmptyAndBack(vo.getGoodsThickness(), errList, "封边条厚", flag); + } + // 配件数量判断 + isEmptyAndPositiveNumber(vo.getGoodsNumber(), Double.class, errList, "配件数量", flag); } // 若商品类型为板材,需检查房间、柜体、板名称、成品长、成品宽、拆单长、拆单宽、厚、左封边、右封边、上封边、下封边、排版面、纹路、开门方向不能为空 if (StringUtils.equals(vo.getGoodType(), "板材")) { - // 数量类型判断 - if (!convertToInteger(vo.getGoodsNumber())) { - flag = false; - if (errList.contains(NUMBER_TYPE_ERR)){ - Iterator iterator = errList.iterator(); - while (iterator.hasNext()) { - String element = iterator.next(); - if (NUMBER_TYPE_ERR.equals(element)) { - iterator.remove(); - } - } - errList.add("板材数量类型需为整数"); - }else { - errList.add(NUMBER_TYPE_ERR); - } - - } - // 纹理有效性判断 - if (StringUtils.isEmpty(vo.getWave())) { - errList.add("板材纹理不可为空"); - flag = false; - } else { - if (!StringUtils.equals(vo.getWave().trim(), "无") && !StringUtils.equals(vo.getWave().trim(), "有")) { - flag = false; - errList.add("纹理无效"); - } - } - // 大板长宽厚数据不可为空 - if (StringUtils.isEmpty(vo.getGoodsHeight()) && StringUtils.isEmpty(vo.getGoodsWidth()) && StringUtils.isEmpty(vo.getGoodsThickness())) { - flag = false; - errList.add("板材长宽厚数据不能为空"); - } else { - // 大板长宽厚数据不为空,检查数据格式 - if (!convertToDouble(vo.getGoodsHeight())) { - flag = false; - errList.add("板材长数据类型错误"); - } else { - if (!checkPrecision(vo.getGoodsHeight())) { - flag = false; - errList.add("板材长数据长度错误"); - } - } - if (!convertToDouble(vo.getGoodsWidth())) { - flag = false; - errList.add("板材宽数据类型错误"); - } else { - if (!checkPrecision(vo.getGoodsWidth())) { - flag = false; - errList.add("板材宽数据长度错误"); - } - } - if (!convertToDouble(vo.getGoodsThickness())) { - flag = false; - errList.add("板材厚数据类型错误"); - } else { - if (!checkPrecision(vo.getGoodsThickness())) { - flag = false; - errList.add("板材厚数据长度错误"); - } - } - } - if (StringUtils.isEmpty(vo.getRoomsName()) && StringUtils.isEmpty(vo.getCabinetsName()) && StringUtils.isEmpty(vo.getName())) { - flag = false; - errList.add("房间、柜体、板名称不能为空"); - } - //成品长、成品宽、拆单长、拆单宽、厚、左封边、右封边、上封边、下封边 不能为空 - if (StringUtils.isEmpty(vo.getHeight()) || StringUtils.isEmpty(vo.getWidth()) || StringUtils.isEmpty(vo.getSplitHeight()) - || StringUtils.isEmpty(vo.getSplitWidth()) || StringUtils.isEmpty(vo.getThickness()) || StringUtils.isEmpty(vo.getSealLeft()) - || StringUtils.isEmpty(vo.getSealRight()) || StringUtils.isEmpty(vo.getSealUp()) || StringUtils.isEmpty(vo.getSealDown())) { - - flag = false; - errList.add("小板轮廓数据不能为空"); - } else { // 成品长、成品宽、拆单长、拆单宽、厚、左封边、右封边、上封边、下封边 数据类型以及长度验证 - if (!convertToDouble(vo.getHeight())) { - flag = false; - errList.add("成品长数据类型错误"); - } else { - if (!checkPrecision(vo.getHeight())) { - flag = false; - errList.add("成品长数据长度错误"); - } - } - if (!convertToDouble(vo.getWidth())) { - flag = false; - errList.add("成品宽数据类型错误"); - } else { - if (!checkPrecision(vo.getWidth())) { - flag = false; - errList.add("成品宽数据长度错误"); - } - } - - if (flag) { - Double plateHeight = Double.parseDouble(vo.getHeight()); - Double plateWidth = Double.parseDouble(vo.getWidth()); - vo.setArea(plateHeight * plateWidth * 0.000001); - } - - if (!convertToDouble(vo.getSplitHeight())) { - flag = false; - errList.add("拆单长数据类型错误"); - } else { - if (!checkPrecision(vo.getSplitHeight())) { - flag = false; - errList.add("拆单长数据长度错误"); - } - } - if (!convertToDouble(vo.getSplitWidth())) { - flag = false; - errList.add("拆单宽数据类型错误"); - } else { - if (!checkPrecision(vo.getSplitWidth())) { - flag = false; - errList.add("拆单宽数据长度错误"); - } - } - if (!convertToDouble(vo.getThickness())) { - flag = false; - errList.add("厚数据类型错误"); - } else { - if (!checkPrecision(vo.getThickness())) { - flag = false; - errList.add("厚数据长度错误"); - } - } - if (!convertToDouble(vo.getSealLeft())) { - flag = false; - errList.add("左封边数据类型错误"); - } else { - if (!checkPrecision(vo.getSealLeft())) { - flag = false; - errList.add("左封边数据长度错误"); - } - } - if (!convertToDouble(vo.getSealRight())) { - flag = false; - errList.add("右封边数据类型错误"); - } else { - if (!checkPrecision(vo.getSealRight())) { - flag = false; - errList.add("右封边数据长度错误"); - } - } - if (!convertToDouble(vo.getSealUp())) { - flag = false; - errList.add("上封边数据类型错误"); - } else { - if (!checkPrecision(vo.getSealUp())) { - flag = false; - errList.add("上封边数据长度错误"); - } - } - if (!convertToDouble(vo.getSealDown())) { - flag = false; - errList.add("下封边数据类型错误"); - } else { - if (!checkPrecision(vo.getSealDown())) { - flag = false; - errList.add("下封边数据长度错误"); - } - } - } - // 排版面、纹路、开门方向 - if (StringUtils.isEmpty(vo.getTypographicFace()) && StringUtils.isEmpty(vo.getTexture()) && StringUtils.isEmpty(vo.getOpenDoorType())) { - flag = false; - errList.add("排版面、纹路、开门方向不能为空"); - } else { - DictDataRespDTO typographyDTO = dictDataApi.parseDictData(DictTypeConstants.TYPOGRAPHY_TYPE, vo.getTypographicFace()).getData();// 排版面 - if (typographyDTO == null) { - flag = false; - errList.add("排版面数据不存在"); - } - DictDataRespDTO grainDTO = dictDataApi.parseDictData(DictTypeConstants.GRAIN_TYPE, vo.getTexture()).getData();// 纹路 - if (grainDTO == null) { - flag = false; - errList.add("纹路数据不存在"); - } - DictDataRespDTO doorDTO = dictDataApi.parseDictData(DictTypeConstants.DOOR_OPENING_DIRECTIONS, vo.getOpenDoorType()).getData(); - if (doorDTO == null) { - flag = false; - errList.add("开门方向数据不存在"); - } - } + checkPlate(vo, errList, flag); } - if (!flag) { + + if (!flag.get()) { isErr.getAndIncrement(); } JSONArray jsonArray = JSON.parseArray(JSON.toJSONString(errList));// 错误列表 vo.setResult(String.valueOf(jsonArray)); - return flag; + return flag.get(); + } - // 数据类型可否转换判断 - public Boolean convertToDouble(String str) { - try { - Double.parseDouble(str); - } catch (NumberFormatException e) { - return false; - } - return true; - } - - // 数据类型可否转换判断 - public Boolean convertToInteger(String str) { - try { - Integer.parseInt(str); - } catch (NumberFormatException e) { - return false; - } - return true; - } - - // 数据长度判断 - public boolean checkPrecision(String numberStr) { - if (numberStr == null) { - return false; - } - - // 分割整数部分和小数部分 - String[] parts = numberStr.split("\\."); - String integerPart = parts[0]; - String decimalPart = parts.length > 1 ? parts[1] : ""; - - // 检查整数部分位数 - if (integerPart.length() > 5) { - return false; - } - - // 检查小数部分位数 - if (decimalPart.length() > 3) { - return false; - } - return true; - } public int isErr() { return isErr.get(); diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/ExcelTypeRealize.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/ExcelTypeRealize.java index b43fdc805..0df206bef 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/ExcelTypeRealize.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/ExcelTypeRealize.java @@ -238,8 +238,14 @@ public class ExcelTypeRealize { } else { //配件 + Long partsId = (Long) snowFlakeGenerator.nextId(null); OrderPartsDO orderPartsDO = OrderPartsDO.builder().id(partsId).orderId(orderId).goodsId(combination.getGoodsId()) + .color(combination.getColor()).category(combination.getCategory()).type(combination.getType()) + .length(Double.valueOf(StringUtils.isEmpty(combination.getGoodsHeight()) ? "0" : combination.getGoodsHeight())) + .width(Double.valueOf(StringUtils.isEmpty(combination.getGoodsWidth()) ? "0" : combination.getGoodsWidth())) + .thickness(Double.valueOf(StringUtils.isEmpty(combination.getGoodsThickness()) ? "0" : combination.getGoodsThickness())) + .isComposite(Boolean.valueOf(combination.getIsComposite())) .name(combination.getGoodsName()).material(combination.getMaterial()).type(combination.getGoodType()) .model(combination.getModel()).spec(combination.getSpec()).brand(combination.getBrand()).factory(combination.getFactory()) .unit(combination.getUnit()).price(0.0).isComposite(false).remark(remarkExtract(combination.remarkJSON())).isComposite(false).build(); diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/OrderPlateImportExcelVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/OrderPlateImportExcelVO.java index 02b9f592f..64fc3355e 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/OrderPlateImportExcelVO.java +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/OrderPlateImportExcelVO.java @@ -60,6 +60,18 @@ public class OrderPlateImportExcelVO { @JsonIgnore private String color; + @ExcelProperty(value = "复合部件") + @JsonIgnore + private String isComposite; + + @ExcelProperty(value = "配件类型") + @JsonIgnore + private String category; + + @ExcelProperty(value = "配件子类") + @JsonIgnore + private String type; + @ExcelProperty(value = "厂家") @JsonIgnore private String factory; @@ -72,15 +84,15 @@ public class OrderPlateImportExcelVO { @JsonIgnore private String model; - @ExcelProperty(value = "板材长") + @ExcelProperty(value = "板材/配件长") @JsonIgnore private String goodsHeight; - @ExcelProperty(value = "板材宽") + @ExcelProperty(value = "板材/配件宽") @JsonIgnore private String goodsWidth; - @ExcelProperty(value = "板材厚") + @ExcelProperty(value = "板材/配件厚") @JsonIgnore private String goodsThickness; diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/orderItem/OrderItemMapper.xml b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/orderItem/OrderItemMapper.xml index c34ad5f49..5f5f36656 100644 --- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/orderItem/OrderItemMapper.xml +++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/mapper/orderItem/OrderItemMapper.xml @@ -225,12 +225,9 @@ g.thickness, g.remark, g.spec, - sub.order_id, - sub.totalPlates AS number, - sub.totalArea AS area, - sub.room_id, - sub.body_id, - sub.group_id + SUM(sub.totalPlates) AS number, + SUM(sub.totalArea) AS area + FROM ( SELECT i.room_id, @@ -243,7 +240,7 @@ SUM(p.area) AS totalArea FROM order_item i - RIGHT JOIN + RIGHT JOIN order_plate p ON i.organ_id = p.organ_id AND i.order_id = p.order_id AND i.plate_id = p.id WHERE i.organ_id = #{organId} AND i.order_id = #{orderId} AND p.deleted = #{deleted} @@ -277,6 +274,8 @@ ) sub LEFT JOIN order_goods g ON sub.organ_id = g.organ_id AND sub.order_id = g.order_id AND sub.goods_id = g.id + GROUP BY + g.id, g.order_id, g.brand, g.goods_id, g.goods_name, g.material, g.texture, g.color, g.color_black, g.width, g.height, g.thickness, g.remark, g.spec; \ No newline at end of file diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/type/order_add_excel.xlsx b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/type/order_add_excel.xlsx index 0778999da3827f8b8c37acb127d4dac2db374156..52cf7b4d474e70a81d4956a1e9b7485bb18bf16b 100644 GIT binary patch delta 17349 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 z%0D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 W_9I@6ASRr()$cV~?N delta 17957 zcmeIacQl+|yEm>z?oHzVG|myYraiKQZZaHL-E1G45dC zV_;ygVJJ$5jk;lCVBp}^(1EakC;e_+!sM;S+X|1`jA9C+%gXQ>n;Fg6H}Nw3Qcc(! z*6F!#g1GGT3~TT^IrLmc%{Y%`=_+P9pDI0EbrHOJs>5zYRGd)Zc_@d3aSSTw+F_l-#x2wpqEi* zdFc2Nv&2=Dg;*?#fV@V8`iRv&Qbowa$>=m}42&wYGsw{X@N*IJb@z0(c6WCc z^mBFjX!y*%T#7u%(h-HdvVcn^kLC25hH}ivsj5t3uI*7Qqj0ZT$4A$!6QlF?{fvnE z)|qFv0gW22yYz{pLpdTFmJL3(vIcDQ?wp+Rbz0#P^rKIYr9=SBA_tdy`YD`T0FC=* zPhi3LjpyNx&<2BG-c*hPJ;oR!<|*%Y)pU-!)Tu{#hv^blJfBNq!ruGU+wgJs+p3qA z@eS6vE|n2D4>2jRYj-ZIbc)JsJT;zB-Ft{r0mZtiwW(kn+uo)AoCPheRH3gj3o)sS zEq%*8DZb6$9O&|yb%(HP(R%a;A#ibdkmO32^OIeeiOI0;@ymW9pF3kyi6?qDKN^H@ zlf(8rNVSzc1r+l$D}RQj9VqksO>9h2&UjI(s*X^)M z#o05yQlIy{6D80m>Lb*{Ty_|mZ3Qe6kEXvem3M4^E=+l0dKXW62_IaHyTuE9!eApi z7^81vk;yy5dH$GBMMar9_fR#I^xOma@z?9!r~QgQzX~AhUW6&V2yJ6EqEn|$`P9Nz zCN86=HRNCKf{O~bbLy{zeX%wAXri^Qp^r&IqWR>wrJNh9it(GkuuLz?gQa4o@jdm7 z{`nfE_ODz-iFw)EbipOZTt>+$0MLEV?@cIx_$fHDaGZ1*@lr*c`%0AnJ5OlCSoiyb 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 diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/type/order_add_excel_err.xlsx b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/resources/type/order_add_excel_err.xlsx index f171ef9a6a1e4b311be6b789dadcf73599107a95..4a9f64c539dbc92cde19954b5101535e56b8c2d2 100644 GIT binary patch delta 14716 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 delta 13541 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