| | |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.ZoneId; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static java.util.stream.IntStream.range; |
| | | |
| | | /** |
| | | * 玻璃信息服务实现类 |
| | |
| | | final String filmsIdDefaultFinal = filmsIdDefault; |
| | | final double thicknessDefaultFinal = thicknessDefault; |
| | | |
| | | // 用于按 flowCardId 全局计数序号 |
| | | Map<String, Integer> flowCardSequenceCounter = new HashMap<>(); |
| | | // 生成日期字符串(yyMMdd格式),用于流程卡ID生成 |
| | | LocalDate localDate = new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); |
| | | String dateStr = localDate.format(DateTimeFormatter.ofPattern("yyMMdd")); |
| | | |
| | | // 用于存储每个玻璃ID对应的流程卡ID(同一玻璃ID的多个玻璃共享同一个流程卡ID) |
| | | Map<String, String> glassIdFlowCardIdMap = new HashMap<>(); |
| | | |
| | | // 用于按 flowCardId 计数 temperingFeedSequence |
| | | Map<String, Integer> temperingFeedSequenceCounter = new HashMap<>(); |
| | | // 用于按 flowCardId 分配 temperingLayoutId |
| | |
| | | } |
| | | } |
| | | |
| | | List<Map<String, Object>> glassInfolList = excelRows.stream() |
| | | .flatMap(row -> { |
| | | Object qtyObj = row.getOrDefault("quantity", 1); |
| | | int qty = parseDouble(qtyObj, 1) > 0 ? (int) parseDouble(qtyObj, 1) : 1; |
| | | List<Map<String, Object>> glassInfolList = new ArrayList<>(); |
| | | for (Map<String, Object> row : excelRows) { |
| | | Object qtyObj = row.getOrDefault("quantity", 1); |
| | | int qty = parseDouble(qtyObj, 1) > 0 ? (int) parseDouble(qtyObj, 1) : 1; |
| | | |
| | | String glassId = str(row.get("glassId")); |
| | | String filmsId = strOrDefault(row.get("filmsId"), filmsIdDefaultFinal); |
| | | String flowCardId = str(row.get("flowCardId")); |
| | | // orderNumber 是整型(玻璃类型),从 Excel 读取或使用默认值 1 |
| | | Object orderNumberObj = row.get("orderNumber"); |
| | | final Integer finalOrderNumber = orderNumberObj != null |
| | | ? (int) parseDouble(orderNumberObj, 1) |
| | | : 1; |
| | | String productName = str(row.get("productName")); |
| | | String customerName = str(row.get("customerName")); |
| | | double width = parseDouble(row.get("width"), 0d); |
| | | double height = parseDouble(row.get("length"), 0d); |
| | | double thickness = parseDouble(row.get("thickness"), thicknessDefaultFinal); |
| | | |
| | | // 计算 rawSequence |
| | | String rawKey = width + "_" + height + "_" + thickness + "_" + filmsId; |
| | | Integer rawSequence = rawSequenceMap.get(rawKey); |
| | | String glassId = str(row.get("glassId")); |
| | | String filmsId = strOrDefault(row.get("filmsId"), filmsIdDefaultFinal); |
| | | String flowCardId = str(row.get("flowCardId")); |
| | | |
| | | // 如果流程卡ID为空,按新规则生成:NG + yyMMdd + 序号(两位,使用玻璃ID) + A001 |
| | | if (flowCardId.isEmpty()) { |
| | | // 检查是否已为该玻璃ID生成过流程卡ID(同一玻璃ID的多个玻璃共享同一个流程卡ID) |
| | | String generatedFlowCardId = glassIdFlowCardIdMap.get(glassId); |
| | | if (generatedFlowCardId == null) { |
| | | // 使用玻璃ID作为序号(解析为整数,如果解析失败则使用1) |
| | | int sequence; |
| | | try { |
| | | sequence = Integer.parseInt(glassId.trim()); |
| | | if (sequence <= 0) { |
| | | sequence = 1; |
| | | } |
| | | } catch (NumberFormatException e) { |
| | | log.warn("玻璃ID无法解析为整数,使用默认值1: glassId={}", glassId); |
| | | sequence = 1; |
| | | } |
| | | generatedFlowCardId = "NG" + dateStr + String.format("%02d", sequence) + "A001"; |
| | | glassIdFlowCardIdMap.put(glassId, generatedFlowCardId); |
| | | log.info("为玻璃ID {} 生成流程卡ID: flowCardId={}", glassId, generatedFlowCardId); |
| | | } |
| | | flowCardId = generatedFlowCardId; |
| | | } |
| | | // 去掉尾部 "/数字"(如果有) |
| | | String baseFlowCardId = flowCardId.replaceFirst("/\\d+$", ""); |
| | | |
| | | // orderNumber 是整型(玻璃类型),从 Excel 读取或使用默认值 1 |
| | | Object orderNumberObj = row.get("orderNumber"); |
| | | final Integer finalOrderNumber = orderNumberObj != null |
| | | ? (int) parseDouble(orderNumberObj, 1) |
| | | : 1; |
| | | String productName = str(row.get("productName")); |
| | | String customerName = str(row.get("customerName")); |
| | | double width = parseDouble(row.get("width"), 0d); |
| | | double height = parseDouble(row.get("length"), 0d); |
| | | double thickness = parseDouble(row.get("thickness"), thicknessDefaultFinal); |
| | | |
| | | // 计算 rawSequence |
| | | String rawKey = width + "_" + height + "_" + thickness + "_" + filmsId; |
| | | Integer rawSequence = rawSequenceMap.get(rawKey); |
| | | |
| | | int finalQty = qty; |
| | | log.info("解析到数量:row={}, quantity={}, 最终qty={}", row, qtyObj, finalQty); |
| | | return range(0, qty).mapToObj(idx -> { |
| | | String baseGlassId = engineerIdFinal + glassId; |
| | | String finalGlassId = finalQty > 1 ? baseGlassId + (idx + 1) : baseGlassId; |
| | | int finalQty = qty; |
| | | log.info("解析到数量:row={}, quantity={}, 最终qty={}", row, qtyObj, finalQty); |
| | | |
| | | // 按 flowCardId 分配 temperingLayoutId |
| | | Integer temperingLayoutId = temperingLayoutIdMap.computeIfAbsent(baseFlowCardId, k -> nextTemperingLayoutId.getAndIncrement()); |
| | | |
| | | // 为同一行的多个玻璃生成数据 |
| | | for (int idx = 0; idx < qty; idx++) { |
| | | String baseGlassId = engineerIdFinal + glassId; |
| | | String finalGlassId = finalQty > 1 ? baseGlassId + (idx + 1) : baseGlassId; |
| | | |
| | | // 按 flowCardId 递增 temperingFeedSequence |
| | | int temperingFeedSequence = temperingFeedSequenceCounter.compute(baseFlowCardId, (k, v) -> (v == null ? 0 : v) + 1); |
| | | String finalFlowCardSequence = baseFlowCardId + "/" + 1; |
| | | |
| | | log.debug("生成玻璃信息: glassId={}, idx={}, baseFlowCardId={}, finalFlowCardSequence={}, temperingLayoutId={}, temperingFeedSequence={}", |
| | | glassId, idx, baseFlowCardId, finalFlowCardSequence, temperingLayoutId, temperingFeedSequence); |
| | | |
| | | String baseFlowCardId = flowCardId.isEmpty() ? baseGlassId : flowCardId; |
| | | // 如果 baseFlowCardId 已经包含尾部 "/数字",先去掉,再由后端统一追加序号 |
| | | baseFlowCardId = baseFlowCardId.replaceFirst("/\\d+$", ""); |
| | | // 按 flowCardId 全局递增序号 |
| | | int sequenceNum = flowCardSequenceCounter.compute(baseFlowCardId, (k, v) -> (v == null ? 0 : v) + 1); |
| | | String finalFlowCardSequence = baseFlowCardId + "/" + 1; |
| | | |
| | | // 按 flowCardId 分配 temperingLayoutId |
| | | Integer temperingLayoutId = temperingLayoutIdMap.computeIfAbsent(baseFlowCardId, k -> nextTemperingLayoutId.getAndIncrement()); |
| | | // 按 flowCardId 递增 temperingFeedSequence |
| | | int temperingFeedSequence = temperingFeedSequenceCounter.compute(baseFlowCardId, (k, v) -> (v == null ? 0 : v) + 1); |
| | | |
| | | log.debug("生成flowCardSequence: idx={}, baseFlowCardId={}, sequenceNum={}, finalFlowCardSequence={}, temperingLayoutId={}, temperingFeedSequence={}", |
| | | idx, baseFlowCardId, sequenceNum, finalFlowCardSequence, temperingLayoutId, temperingFeedSequence); |
| | | |
| | | Map<String, Object> m = new HashMap<>(); |
| | | m.put("xAxis", 0); |
| | | m.put("xCoordinate", 0); |
| | | m.put("yAxis", 0); |
| | | m.put("yCoordinate", 0); |
| | | m.put("glassId", finalGlassId); |
| | | m.put("engineerId", engineerIdFinal); |
| | | m.put("flowCardId", baseFlowCardId); |
| | | m.put("orderNumber", finalOrderNumber); |
| | | m.put("productSortNumber", 1); // 统一为1 |
| | | m.put("hollowCombineDirection", ""); |
| | | m.put("width", width); |
| | | m.put("height", height); |
| | | m.put("thickness", thickness); |
| | | m.put("filmsId", filmsId); |
| | | m.put("layer", 1); |
| | | m.put("totalLayer", 1); |
| | | m.put("edgWidth", width); |
| | | m.put("edgHeight", height); |
| | | m.put("isMultiple", finalQty > 1 ? 1 : 0); // 数量>1时为1 |
| | | m.put("maxWidth", width); |
| | | m.put("maxHeight", height); |
| | | m.put("isHorizontal", 0); |
| | | m.put("rawSequence", rawSequence != null ? rawSequence : 0); |
| | | m.put("temperingLayoutId", temperingLayoutId); |
| | | m.put("temperingFeedSequence", temperingFeedSequence); |
| | | m.put("angle", 0); |
| | | m.put("ruleId", 0); |
| | | m.put("combine", 0); |
| | | m.put("markIcon", ""); |
| | | m.put("filmRemove", 0); |
| | | m.put("flowCardSequence", finalFlowCardSequence); |
| | | m.put("process", ""); |
| | | m.put("rawAngle", 0); |
| | | m.put("graphNo", 0); |
| | | m.put("processParam", ""); |
| | | return m; |
| | | }); |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | Map<String, Object> m = new HashMap<>(); |
| | | m.put("xAxis", 0); |
| | | m.put("xCoordinate", 0); |
| | | m.put("yAxis", 0); |
| | | m.put("yCoordinate", 0); |
| | | m.put("glassId", finalGlassId); |
| | | m.put("engineerId", engineerIdFinal); |
| | | m.put("flowCardId", baseFlowCardId); |
| | | m.put("orderNumber", finalOrderNumber); |
| | | m.put("productSortNumber", 1); |
| | | m.put("hollowCombineDirection", ""); |
| | | m.put("width", width); |
| | | m.put("height", height); |
| | | m.put("thickness", thickness); |
| | | m.put("filmsId", filmsId); |
| | | m.put("layer", 1); |
| | | m.put("totalLayer", 1); |
| | | m.put("edgWidth", width); |
| | | m.put("edgHeight", height); |
| | | m.put("isMultiple", finalQty > 1 ? 1 : 0); |
| | | m.put("maxWidth", width); |
| | | m.put("maxHeight", height); |
| | | m.put("isHorizontal", 0); |
| | | m.put("rawSequence", rawSequence != null ? rawSequence : 0); |
| | | m.put("temperingLayoutId", temperingLayoutId); |
| | | m.put("temperingFeedSequence", temperingFeedSequence); |
| | | m.put("angle", 0); |
| | | m.put("ruleId", 0); |
| | | m.put("combine", 0); |
| | | m.put("markIcon", ""); |
| | | m.put("filmRemove", 0); |
| | | m.put("flowCardSequence", finalFlowCardSequence); |
| | | m.put("process", ""); |
| | | m.put("rawAngle", 0); |
| | | m.put("graphNo", 0); |
| | | m.put("processParam", ""); |
| | | glassInfolList.add(m); |
| | | } |
| | | } |
| | | |
| | | // 原片信息去重 |
| | | Map<String, Map<String, Object>> rawGlassMap = new HashMap<>(); |
| | |
| | | String glassId = str(row.get("glassId")); |
| | | String flowCardId = str(row.get("flowCardId")); |
| | | if (flowCardId.isEmpty()) { |
| | | flowCardId = engineerIdFinal + glassId; |
| | | // 使用已生成的流程卡ID(与glassInfolList中的逻辑保持一致) |
| | | flowCardId = glassIdFlowCardIdMap.get(glassId); |
| | | if (flowCardId == null) { |
| | | // 如果未生成,则按规则生成(理论上不应该走到这里,因为glassInfolList已经生成过) |
| | | int sequence; |
| | | try { |
| | | sequence = Integer.parseInt(glassId.trim()); |
| | | if (sequence <= 0) { |
| | | sequence = 1; |
| | | } |
| | | } catch (NumberFormatException e) { |
| | | log.warn("玻璃ID无法解析为整数,使用默认值1: glassId={}", glassId); |
| | | sequence = 1; |
| | | } |
| | | flowCardId = "NG" + dateStr + String.format("%02d", sequence) + "A001"; |
| | | glassIdFlowCardIdMap.put(glassId, flowCardId); |
| | | log.warn("流程卡ID未在glassInfolList中生成,此处补充生成: flowCardId={}, glassId={}", flowCardId, glassId); |
| | | } |
| | | } |
| | | // 去掉尾部 "/数字"(如果有) |
| | | flowCardId = flowCardId.replaceFirst("/\\d+$", ""); |