chenlu
2025-11-21 d473c7b2b07cfeee3740f40dfdc95d722d8da3c2
north-glass-erp/src/main/java/com/example/erp/service/pp/GlassOptimizeService.java
@@ -14,8 +14,11 @@
import com.example.erp.entity.userInfo.SysError;
import com.example.erp.mapper.pp.GlassOptimizeMapper;
import com.example.erp.service.userInfo.SysErrorService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
@@ -43,6 +46,9 @@
    GlassOptimizeMapper glassOptimizeMapper;
    @Autowired
    SysErrorService sysErrorService;
    @Value("${mesIp:localhost}")  // 注入mesIp配置,默认值为10.153.19.31
    private String mesIp;
    RabbitMQUtil rabbitMQUtil;
    //模拟计算
@@ -260,26 +266,127 @@
            List<Map<String, Object>> originalFilm = (List<Map<String, Object>>) object.get("originalFilm");
            glassOptimizeMapper.addOptimizeUse(originalFilm,projectId,"admin");
            Map<String, Object> glassInfo = glassOptimizeMapper.getGlassInfo(projectId);
            ObjectMapper mapper = new ObjectMapper();
            String json = mapper.writeValueAsString(optimalResults);
            glassOptimizeMapper.addOptimizeProjectFile(json,projectId,"admin");
            List<Map<String, Object>> objectMapList = (List<Map<String, Object>>) optimalResults.get("layouts");
            glassOptimizeMapper.addOptimizeLayout(objectMapList,projectId);
            // 收集所有需要保存的玻璃明细数据
            List<Map<String, Object>> allGlassDetails = new ArrayList<>();
            for(Map<String, Object> objectMap:objectMapList){
                List<Map<String, Object>> objectMap2 = (List<Map<String, Object>>) objectMap.get("glassDetails");
                //迭代玻璃明细集合删除余料
                //迭代玻璃明细集合处理余料和其他
                Iterator<Map<String, Object>> iterator = objectMap2.iterator();
                while (iterator.hasNext()) {
                    Map<String, Object> map = iterator.next();
                    if (map.get("isRemain").toString()=="true") {
                        iterator.remove();
                    // 修改isRemain判断逻辑,支持数字0/1和字符串"0"/"1"
                    boolean isRemain = false;
                    if (map.containsKey("isRemain")) {
                        Object isRemainObj = map.get("isRemain");
                        if (isRemainObj != null) {
                            if (isRemainObj instanceof Number) {
                                // 数字类型: 1表示true,0表示false
                                isRemain = ((Number) isRemainObj).intValue() == 1;
                            } else {
                                // 字符串类型: "1"表示true,"0"表示false
                                isRemain = "1".equals(isRemainObj.toString());
                            }
                        }
                    }
                    if (isRemain) {
                        System.out.println( map);
                        if (glassInfo != null) {
                            String glassType = (String) glassInfo.get("glass_type");
                            String glassThickness = (String) glassInfo.get("glass_thickness");
                            // 余料存入optimizeoffcut
                            glassOptimizeMapper.addOptimizeOffcut(map, projectId, glassType, glassThickness);
                        }
                        iterator.remove(); // 从原列表中移除
                    }else {
                        // 处理isRotate字段转换 (现在是0/1)
                        if (map.containsKey("isRotate")) {
                            Object isRotateObj = map.get("isRotate");
                            if (isRotateObj != null) {
                                if (isRotateObj instanceof Number) {
                                    // 直接使用数字值
                                    map.put("isRotate", ((Number) isRotateObj).intValue());
                                } else {
                                    // 字符串形式的"0"/"1"
                                    String isRotateStr = isRotateObj.toString();
                                    if ("1".equals(isRotateStr)) {
                                        map.put("isRotate", 1);
                                    } else {
                                        map.put("isRotate", 0);
                                    }
                                }
                            } else {
                                map.put("isRotate", 0); // 默认值
                            }
                        }
                    }
                }
                glassOptimizeMapper.addOptimizeDetail(objectMap2,projectId);
                // 在保存之前处理 glassPoint 数据
                for (Map<String, Object> detail : objectMap2) {
                    if (detail.containsKey("glassPoint")) {
                        Object glassPointObj = detail.get("glassPoint");
                        if (glassPointObj != null) {
                            try {
                                // 如果 glassPointObj 已经是字符串,则不需要转换
                                if (!(glassPointObj instanceof String)) {
                                    // 将对象转换为 JSON 字符串
                                    String glassPointStr = mapper.writeValueAsString(glassPointObj);
                                    detail.put("glassPoint", glassPointStr);
                                }
                            } catch (Exception e) {
                                // 如果转换失败,记录错误并移除该字段
                                System.err.println("转换 glassPoint 失败: " + e.getMessage());
                                detail.remove("glassPoint");
                            }
                        } else {
                            // 如果 glassPointObj 为 null,移除该字段
                            detail.remove("glassPoint");
                        }
                    }
                }
                // 将当前批次的玻璃明细添加到总列表中
                allGlassDetails.addAll(objectMap2);
            }
            glassOptimizeMapper.updateProjectOptimizeStateMp(projectId,1);
            Map<String, Object> projectInfo = glassOptimizeMapper.getGlassProjectList(projectId);
            if (projectInfo != null && Integer.parseInt(projectInfo.get("tempering_state").toString()) == 1) {
                // tempering_state 为 1 时的处理逻辑
                glassOptimizeMapper.addOptimizeDetail(allGlassDetails,projectId);
                List<OptimizeHeatDetail> optimizeHeatDetail = glassOptimizeMapper.selectOptimizeHeatDetail(projectId);
                for (OptimizeHeatDetail projectdetail:optimizeHeatDetail){
                    OptimizeDetail optimizeDetail=glassOptimizeMapper.selectOptimizeDetailById(projectId,projectdetail.getProcessId(),
                            projectdetail.getOrderSort(),projectdetail.getLayer());
                    glassOptimizeMapper.updateOptimizeDetail(optimizeDetail.getId(),projectdetail.getLayoutId(),projectdetail.getSort());
                }
            } else {
                // tempering_state 为 0 时的处理逻辑
                glassOptimizeMapper.addOptimizeDetail(allGlassDetails,projectId);
            }
            List<Map<String, Object>> materialStoreList = glassOptimizeMapper.materialStoreOptimizeUse(projectId);
            double totalUseArea = 0.0;
            for (Map<String, Object> material : materialStoreList) {
                if (material.containsKey("totalArea")) {
                    Object totalAreaObj = material.get("totalArea");
                    if (totalAreaObj != null) {
                        try {
                            double area = Double.parseDouble(totalAreaObj.toString());
                            totalUseArea += area;
                        } catch (NumberFormatException e) {
                            System.err.println("无法解析总面积数据: " + totalAreaObj);
                        }
                    }
                }
            }
            glassOptimizeMapper.updateProjectOptimize(projectId, 1, optimalResults, totalUseArea);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
@@ -288,11 +395,91 @@
    }
    public Boolean updateOptimizeResult(Map<String, Object> object,String processId){
    public Boolean updateOptimizeResult(Map<String, Object> object, String processId) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            List<Map<String, Object>> objectMapList = (List<Map<String, Object>>) object.get("layouts");
            Map<String, Object> glassInfo = glassOptimizeMapper.getGlassInfo(processId);
            glassOptimizeMapper.deleteOffcutDetails(processId);
            int stockId = 1;
            for (Map<String, Object> objectMap : objectMapList) {
                List<Map<String, Object>> objectMap2 = (List<Map<String, Object>>) objectMap.get("glassDetails");
                // 分离 glassDetails 为两部分
                List<Map<String, Object>> normalDetails = new ArrayList<>();  // isRemain 为 false 的部分
                List<Map<String, Object>> offCutDetails = new ArrayList<>();  // isRemain 为 true 的部分
                for (Map<String, Object> detail : objectMap2) {
                    boolean isRemain = false;
                    if (detail.containsKey("isRemain")) {
                        Object isRemainObj = detail.get("isRemain");
                        if (isRemainObj != null) {
                            if (isRemainObj instanceof Number) {
                                // 数字类型: 1表示true,0表示false
                                isRemain = ((Number) isRemainObj).intValue() == 1;
                            } else if (isRemainObj instanceof Boolean) {
                                // 布尔类型
                                isRemain = (Boolean) isRemainObj;
                            } else {
                                // 字符串类型: "1"/"true"表示true,"0"/"false"表示false
                                String isRemainStr = isRemainObj.toString().toLowerCase();
                                isRemain = "1".equals(isRemainStr) || "true".equals(isRemainStr);
                            }
                        }
                    }
                    // 处理 glassPoint 序列化
                    if (detail.containsKey("glassPoint")) {
                        Object glassPointObj = detail.get("glassPoint");
                        if (glassPointObj != null) {
                            try {
                                // 如果 glassPointObj 已经是字符串,则不需要转换
                                if (!(glassPointObj instanceof String)) {
                                    // 将对象转换为 JSON 字符串
                                    String glassPointStr = mapper.writeValueAsString(glassPointObj);
                                    detail.put("glassPoint", glassPointStr);
                                }
                            } catch (Exception e) {
                                // 如果转换失败,记录错误并移除该字段
                                System.err.println("转换 glassPoint 失败: " + e.getMessage());
                                detail.remove("glassPoint");
                            }
                        }
                    }
                    if (isRemain) {
                        offCutDetails.add(detail);
                    } else {
                        normalDetails.add(detail);
                    }
                }
                // 保存所有数据到 optimize_detail
                if (!normalDetails.isEmpty()) {
                    for (Map<String, Object> detail : normalDetails) {
                        glassOptimizeMapper.updateNormalDetails(detail, processId);
                    }
                }
                // 对 remainDetails 部分先删除 offcut 再处理
                if (!offCutDetails.isEmpty()) {
                    if (glassInfo != null) {
                        String glassType = (String) glassInfo.get("glass_type");
                        String glassThickness = (String) glassInfo.get("glass_thickness");
                        // 余料存入optimizeoffcut
                        for (Map<String, Object> detail : offCutDetails) {
                            glassOptimizeMapper.addUpdateOffcut(detail, processId, glassType, glassThickness, stockId);
                        }
                    }
                }
                stockId++;
            }
            // 更新优化结果文件
            String jsonString = mapper.writeValueAsString(object);
            glassOptimizeMapper.updateOptimizeResult(jsonString,processId);
            glassOptimizeMapper.updateOptimizeResult(jsonString, processId);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
@@ -307,6 +494,111 @@
        map.put("optimizeUse", glassOptimizeMapper.materialStoreOptimizeUse(processId));
        return map;
    }
    public Object getOptimizeInfoSv(String processId) {
        // 获取布局信息
        List<Map<String, Object>> layouts = glassOptimizeMapper.getOptimizeLayoutsInfo(processId);
        // 获取玻璃明细信息
        List<Map<String, Object>> glassDetails = glassOptimizeMapper.getOptimizeDetailsInfo(processId);
        // 获取余料信息
        List<Map<String, Object>> offsets = glassOptimizeMapper.getOptimizeOffsetsInfo(processId);
        // 将玻璃明细和余料合并到一个列表中
        List<Map<String, Object>> allDetails = new ArrayList<>();
        if (glassDetails != null) {
            allDetails.addAll(glassDetails);
        }
        if (offsets != null) {
            allDetails.addAll(offsets);
        }
        // 解析 glassPoint 字符串
        ObjectMapper mapper = new ObjectMapper();
        for (Map<String, Object> detail : allDetails) {
            if (detail.containsKey("glassPoint")) {
                Object glassPointObj = detail.get("glassPoint");
                if (glassPointObj instanceof String) {
                    String glassPointStr = (String) glassPointObj;
                    if (glassPointStr != null && !glassPointStr.isEmpty() && !glassPointStr.equals("null")) {
                        try {
                            // 解析 JSON 字符串为对象
                            Object parsedGlassPoint = mapper.readValue(glassPointStr, Object.class);
                            detail.put("glassPoint", parsedGlassPoint);
                        } catch (Exception e) {
                            System.err.println("解析 glassPoint 失败: " + e.getMessage());
                            // 解析失败时保留原字符串或设置默认值
                            detail.put("glassPoint", new ArrayList<>());
                        }
                    } else {
                        // 空字符串或 null 时设置默认值
                        detail.put("glassPoint", new ArrayList<>());
                    }
                }
            }
        }
        // 按照stockId将明细分组并添加到对应的布局中
        if (layouts != null && !layouts.isEmpty()) {
            for (Map<String, Object> layout : layouts) {
                Object stockIdObj = layout.get("stockId");
                if (stockIdObj != null) {
                    Integer stockId = null;
                    if (stockIdObj instanceof Number) {
                        stockId = ((Number) stockIdObj).intValue();
                    } else {
                        try {
                            stockId = Integer.valueOf(stockIdObj.toString());
                        } catch (NumberFormatException e) {
                            // 如果无法转换为数字,则跳过该布局
                            continue;
                        }
                    }
                    List<Map<String, Object>> matchedDetails = new ArrayList<>();
                    for (Map<String, Object> detail : allDetails) {
                        Object layoutIdObj = detail.get("layoutId");
                        Object stockSortObj = detail.get("stockSort");
                        Integer detailStockId = null;
                        if (layoutIdObj != null) {
                            if (layoutIdObj instanceof Number) {
                                detailStockId = ((Number) layoutIdObj).intValue();
                            } else {
                                try {
                                    detailStockId = Integer.valueOf(layoutIdObj.toString());
                                } catch (NumberFormatException e) {
                                    // 跳过无效的layoutId
                                    continue;
                                }
                            }
                        } else if (stockSortObj != null) {
                            if (stockSortObj instanceof Number) {
                                detailStockId = ((Number) stockSortObj).intValue();
                            } else {
                                try {
                                    detailStockId = Integer.valueOf(stockSortObj.toString());
                                } catch (NumberFormatException e) {
                                    // 跳过无效的stockSort
                                    continue;
                                }
                            }
                        }
                        // 如果detail的stockId与layout的stockId匹配,则添加到匹配列表中
                        if (detailStockId != null && detailStockId.equals(stockId)) {
                            matchedDetails.add(detail);
                        }
                    }
                    // 将匹配的明细添加到布局的glassDetails字段中
                    layout.put("glassDetails", matchedDetails);
                }
            }
        }
//        Map<String, Object> result = new HashMap<>();
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("layouts", layouts);
        result.put("optimizeUse", glassOptimizeMapper.materialOptimizeUse(processId));
        return result;
    }
    //工程信息
    public Map<String, Object> projectInfoSv(String projectNo,String username) {
@@ -365,7 +657,10 @@
                }
            }
        }
        map.put("optimizeState", Integer.parseInt(stringObjectMap.get("optimize_state").toString()));
        map.put("data", dataList);
        map.put("project", glassOptimizeMapper.selectProjectCount(projectNo));
        map.put("grindingTrimming", glassOptimizeMapper.getGrindingTrimming(username));
        return map;
    }
@@ -437,29 +732,68 @@
    }
    //修改排版状态
    public Boolean updateProjectState(String projectNumber, Integer state,Integer states, Integer code) {
    public Boolean updateProjectState(String projectNumber, Integer state,Integer states, Integer code) throws JsonProcessingException {
        if (!projectNumber.isEmpty()) {
            //撤销模拟计算
            if(code==1){
                glassOptimizeMapper.deleteOptimizeHeatDetail(projectNumber);
                glassOptimizeMapper.deleteOptimizeHeatLayout(projectNumber);
                glassOptimizeMapper.updateProjectTemperingStateMp(projectNumber, states);
                Map<String, Object> temperingState = glassOptimizeMapper.getProjectState(projectNumber);
                if (temperingState != null && temperingState.containsKey("optimize_state")) {
                    Object optimizeStateObj = temperingState.get("optimize_state");
                    if (optimizeStateObj != null) {
                        try {
                            int optimizeState = Integer.parseInt(optimizeStateObj.toString());
                            if (optimizeState == 1) {
                                glassOptimizeMapper.updateProjectTemperingId(projectNumber);
                            }
                        } catch (NumberFormatException e) {
                            // 处理转换异常,记录日志或采取其他适当措施
                            System.err.println("解析 optimize_state 失败: " + e.getMessage());
                        }
                    }
                }
            }
            //撤销优化排版
            else if(code==2){
                glassOptimizeMapper.deleteOptimizeDetail(projectNumber);
                glassOptimizeMapper.deleteOptimizeLayout(projectNumber);
                glassOptimizeMapper.deleteOptimizeOffcut(projectNumber);
                glassOptimizeMapper.deleteOptimizeProjectFile(projectNumber);
                glassOptimizeMapper.updateOptimizeUse(projectNumber);
                glassOptimizeMapper.updateProjectOptimizeStateMp(projectNumber, states);
            }
            //允许生产
            else if(code==3){
                glassOptimizeMapper.updateProjectStateMp(projectNumber, state);
                Boolean isSeccess = issuingProjects(projectNumber);
                if(isSeccess){
                    glassOptimizeMapper.updateProjectStateMp(projectNumber, state);
                }else{
                    return false;
                }
            }
            //生产不可见
            else if(code==4){
                glassOptimizeMapper.updateProjectStateMp(projectNumber, state);
                Map<String, Object> cancelResult = issuingCancelProject(projectNumber);
                // 获取返回结果中的data字段
                Map<String, Object> responseData = (Map<String, Object>) cancelResult.get("data");
                // 检查响应中的code字段,只有当code为200或202时才允许更新状态
                if (responseData != null && responseData.containsKey("code")) {
                    Object responseCode = responseData.get("code");
                    if (responseCode.equals(200) || responseCode.equals(202)) {
                        glassOptimizeMapper.updateProjectStateMp(projectNumber, state);
                    } else if (responseCode.equals(201)) {
                        // 当返回201时,抛出自定义异常或返回错误信息
                        throw new RuntimeException(responseData.get("message").toString());
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            }
            //初始化工程
            else if(code==5){
@@ -590,11 +924,25 @@
                if(projectType.equals("2")){
                    deleteProject(projectId,2);
                }
                // 创建一个映射来存储 (processId-technologyNumber) 组合到 rack 编号的映射
                Map<String, Integer> rackMap = new HashMap<>();
                int rackCounter = 1;
                for (FlowCard flowCard : flowCardList) {
                    // 为每个唯一的 processId-technologyNumber 组合分配 rack 编号
                    String key = flowCard.getProcessId() + "-" + flowCard.getTechnologyNumber();
                    if (!rackMap.containsKey(key)) {
                        rackMap.put(key, rackCounter++);
                    }
                    int rackValue = rackMap.get(key);
                    if(flowCard.getPatchState().equals(0)){
                        state1=1;
                        //给流程卡表添加对应的工程号
                        Boolean a=glassOptimizeMapper.updateFlowCardProject(flowCard.getProcessId(),flowCard.getTechnologyNumber(),projectId);
                        Boolean a = glassOptimizeMapper.updateFlowCardProject(flowCard.getProcessId(),flowCard.getTechnologyNumber(),projectId);
                        // 更新流程卡的rack字段
                        glassOptimizeMapper.updateFlowCardRack(flowCard.getProcessId(), flowCard.getTechnologyNumber(), rackValue);
                        area = glassOptimizeMapper.getSelectArea(flowCard.getProcessId(),flowCard.getTechnologyNumber()).doubleValue();
                        sumArea = sumArea.add(BigDecimal.valueOf(area));
                        sumQuantity +=flowCard.getQuantity();
@@ -668,11 +1016,30 @@
            json = object.get("json").toString();
        }
        if(type.equals("钢化")){
            glassOptimizeMapper.updateOptimizeConfig(json,1,username);
            String existingConfig = glassOptimizeMapper.selectConfigByUserAndType(username, 1);
            if (existingConfig == null) {
                String configName = "钢化推荐";
                glassOptimizeMapper.insertOptimizeConfig(json,1,username,configName);
            }else {
                glassOptimizeMapper.updateOptimizeConfig(json,1,username);
            }
        } else if (type.equals("修边")) {
            glassOptimizeMapper.updateOptimizeConfig(json,5,username);
            String existingConfig = glassOptimizeMapper.selectConfigByUserAndType(username, 5);
            if (existingConfig == null) {
                String configName = "修边配置";
                glassOptimizeMapper.insertOptimizeConfig(json,5,username,configName);
            }else {
                glassOptimizeMapper.updateOptimizeConfig(json,5,username);
            }
        }else if (type.equals("磨量")) {
            glassOptimizeMapper.updateOptimizeConfig(json,4,username);
            String existingConfig = glassOptimizeMapper.selectConfigByUserAndType(username, 4);
            if (existingConfig == null) {
                String configName = "磨量配置";
                glassOptimizeMapper.insertOptimizeConfig(json,4,username,configName);
            }else{
                glassOptimizeMapper.updateOptimizeConfig(json,4,username);
            }
        }
        return true;
@@ -878,4 +1245,313 @@
        return map;
    }
    public Boolean issuingProjects(String projectNo) throws JsonProcessingException {
        boolean  saveState=false;
        try {
            // 1. 创建URL对象
            URL url = new URL("http://" + mesIp + ":88/api/loadGlass/engineering/importEngineer");
            // 2. 打开连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Accept", "application/json");
            conn.setDoOutput(true);
            // 3. 准备请求体
            Map<String, Object> optimizeProject=glassOptimizeMapper.selectOptimizeProject(projectNo);
            optimizeProject.put("engineeringRawQueueList", glassOptimizeMapper.selectOptimizeLayout(projectNo));
            optimizeProject.put("glassInfolList", glassOptimizeMapper.selectOptimizeDetail(projectNo));
            optimizeProject.put("flowCardInfoList", glassOptimizeMapper.selectFlowCardInfoList(projectNo));
            ObjectMapper mapper = new ObjectMapper();
            mapper.registerModule(new JavaTimeModule());
            String jsonInputString = mapper.writeValueAsString(optimizeProject);
            //发送请求
            try(OutputStream os = conn.getOutputStream()) {
                byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
                os.write(input, 0, input.length);
            }
            // 获取响应
            try(BufferedReader br = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
                StringBuilder response = new StringBuilder();
                String responseLine;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
                System.out.println("Response: " + response.toString());
                JSONObject obj = JSONObject.parseObject(response.toString());
                if(obj.get("code").equals(200)&&obj.get("data").equals(true)){
                    saveState=true;
                }
            }
            //关闭连接
            conn.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
            saveState= false;
        }
        return saveState;
    }
    public Map<String, Object> getReportDataSv(String processId) {
        Map<String, Object> perimap = new HashMap<>();
        perimap.put("peridata", glassOptimizeMapper.getPeriMeterDataSv(processId));
        Map<String, Object> map = new HashMap<>();
        Object layoutSetObj = glassOptimizeMapper.getReportDataProcessIdSv(processId);
        map.put("reportData", layoutSetObj);
        List<Map<String, Object>> peridata = (List<Map<String, Object>>) perimap.get("peridata");
        double totalPerimeter = 0.0;
        if (peridata != null && !peridata.isEmpty()) {
            for (Map<String, Object> perimeterData : peridata) {
                if (perimeterData.containsKey("perimeter") && perimeterData.get("perimeter") != null) {
                    try {
                        Object perimeterObj = perimeterData.get("perimeter");
                        if (perimeterObj instanceof Number) {
                            totalPerimeter += ((Number) perimeterObj).doubleValue();
                        } else {
                            totalPerimeter += Double.parseDouble(perimeterObj.toString());
                        }
                    } catch (NumberFormatException e) {
                        System.err.println("无法解析周长数据: " + perimeterData.get("perimeter"));
                    }
                }
            }
        }
        if (layoutSetObj instanceof List) {
            List<Map<String, Object>> layoutSet = (List<Map<String, Object>>) layoutSetObj;
            if (!layoutSet.isEmpty()) {
                layoutSet.get(0).put("rectanglePerimeter", totalPerimeter);
            }
        }
        return map;
    }
    public Map<String, Object> getMaterialInfoSv(String processId) {
        Map<String, Object> map = new HashMap<>();
//        List<Map<String, Object>> materialList = glassOptimizeMapper.getMaterialInfoSv(processId);
        List<Map<String, Object>> layoutSet = glassOptimizeMapper.getLayoutSetSv(processId);
//        // 创建一个Map来存储每个stock_code的总面积
//        Map<String, Double> stockCodeAreaMap = new HashMap<>();
//
//        // 遍历layoutSet计算每个stock_code的总面积(面积*使用率)
//        for (Map<String, Object> layout : layoutSet) {
//            Object stockCodeObj = layout.get("stock_code");
//            Object widthObj = layout.get("width");
//            Object heightObj = layout.get("height");
//            Object usageRateObj = layout.get("usage_rate");
//
//            if (stockCodeObj != null && widthObj != null && heightObj != null && usageRateObj != null) {
//                try {
//                    String stockCode = stockCodeObj.toString();
//                    double width = Double.parseDouble(widthObj.toString());
//                    double height = Double.parseDouble(heightObj.toString());
//                    double usageRate = Double.parseDouble(usageRateObj.toString());
//
//                    // 计算单条数据的面积(平方米)
//                    double area = (width * height * usageRate) / 1000000.0;
//
//                    // 累加到对应stock_code的总面积
//                    stockCodeAreaMap.put(stockCode, stockCodeAreaMap.getOrDefault(stockCode, 0.0) + area);
//                } catch (NumberFormatException e) {
//                    System.err.println("数据转换错误: " + e.getMessage());
//                }
//            }
//        }
//
//        // 将计算出的总面积添加到materialList中对应的物料数据
//        for (Map<String, Object> material : materialList) {
//            Object stockCodeObj = material.get("code");
//            if (stockCodeObj != null) {
//                String stockCode = stockCodeObj.toString();
//                if (stockCodeAreaMap.containsKey(stockCode)) {
//                    material.put("totalArea", stockCodeAreaMap.get(stockCode));
//                }
//            }
//        }
        map.put("materialList", layoutSet);
        return map;
    }
    public Map<String, Object> getProductListSv(String processId) {
        Map<String, Object> productMap = new HashMap<>();
        List<Map<String, Object>> productInfo = glassOptimizeMapper.selectProjectList(processId);
        productMap.put("productInfo", productInfo);
        Map<String, Object> map = new HashMap<>();
        if (productInfo != null && !productInfo.isEmpty()) {
            // 按照 processCard 分组
            Map<String, List<Map<String, Object>>> groupedByProcessCard = new HashMap<>();
            for (Map<String, Object> item : productInfo) {
                String processCard = (String) item.get("processCard");
                if (processCard != null) {
                    groupedByProcessCard.computeIfAbsent(processCard, k -> new ArrayList<>()).add(item);
                }
            }
            // 为每个 processCard 计算统计信息
            List<Map<String, Object>> result = new ArrayList<>();
            for (Map.Entry<String, List<Map<String, Object>>> entry : groupedByProcessCard.entrySet()) {
                String processCard = entry.getKey();
                List<Map<String, Object>> items = entry.getValue();
                // 计算统计信息
                double longestSide = 0;
                double shortestSide = Double.MAX_VALUE;
                int specQuantity = items.size();
                int totalQuantity = 0;
                // 使用 BigDecimal 精确计算面积
                BigDecimal totalArea = BigDecimal.ZERO;
                for (Map<String, Object> item : items) {
                    // 安全获取长和宽
                    Number widthObj = (Number) item.get("width");
                    Number heightObj = (Number) item.get("height");
                    if (widthObj == null || heightObj == null) {
                        continue;
                    }
                    double width = widthObj.doubleValue();
                    double height = heightObj.doubleValue();
                    // 更新最长边和最短边
                    double maxSide = Math.max(width, height);
                    double minSide = Math.min(width, height);
                    if (maxSide > longestSide) {
                        longestSide = maxSide;
                    }
                    if (minSide < shortestSide) {
                        shortestSide = minSide;
                    }
                    // 安全获取数量
                    Number quantityObj = (Number) item.get("quantity");
                    if (quantityObj != null) {
                        totalQuantity += quantityObj.intValue();
                    }
                    // 安全获取面积 —— 使用 BigDecimal 精确累加
                    Object areaObj = item.get("Area");
                    if (areaObj != null) {
                        // 关键:通过 toString() 转为字符串再构造 BigDecimal,避免 double 精度损失
                        BigDecimal area = new BigDecimal(areaObj.toString());
                        totalArea = totalArea.add(area);
                    }
                }
                // 处理 shortestSide 的边界情况
                if (shortestSide == Double.MAX_VALUE) {
                    shortestSide = 0;
                }
                // 构造返回数据
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("processCard", processCard);
                resultMap.put("longestSide", longestSide);
                resultMap.put("shortestSide", shortestSide);
                resultMap.put("specQuantity", specQuantity);
                resultMap.put("totalQuantity", totalQuantity);
                resultMap.put("totalArea", totalArea);
                result.add(resultMap);
            }
            map.put("productList", result);
        }
        return map;
    }
    public Map<String, Object>  getProjectState(String projectNo) {
        Map<String, Object> map = new HashMap<>();
        map.put("data", glassOptimizeMapper.getProjectState(projectNo));
        return map;
    }
    public Map<String, Object> issuingCancelProject(String projectNo){
        Map<String, Object> result = new HashMap<>();
        Map<String, Object> responseData = new HashMap<>();
        try {
            // 1. 创建URL对象
            URL url = new URL("http://" + mesIp + ":88/api/loadGlass/engineering/optimizeCancelTask");
//            URL url = new URL("http://localhost:88/api/loadGlass/engineering/optimizeCancelTask");
            // 2. 打开连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Accept", "application/json");
            conn.setDoOutput(true);
            // 3. 准备请求体 - 将projectNo转换为engineerId格式
            String engineerId = projectNo;
            // 如果传入的是JSON字符串,需要提取真正的projectNo值
            if (projectNo.startsWith("{") && projectNo.contains("\"projectNo\"")) {
                try {
                    JSONObject jsonObject = JSONObject.parseObject(projectNo);
                    engineerId = jsonObject.getString("projectNo");
                } catch (Exception e) {
                    // 解析失败时使用原始值
                    System.err.println("解析projectNo JSON失败: " + e.getMessage());
                }
            }
            // 构建新的JSON请求体,使用engineerId字段
            String jsonInputString = "{\"engineerId\":\"" + engineerId + "\"}";
            System.out.println("engineerId: " + engineerId);
            System.out.println("Request: " + jsonInputString);
            //发送请求
            try(OutputStream os = conn.getOutputStream()) {
                byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
                os.write(input, 0, input.length);
            }
            // 获取响应
            try(BufferedReader br = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
                StringBuilder response = new StringBuilder();
                String responseLine;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
                String fullResponse = response.toString();
                System.out.println("Response: " + fullResponse);
                // 直接将响应内容解析为Map
                responseData = JSONObject.parseObject(fullResponse, Map.class);
            }
            //关闭连接
            conn.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
            // 异常情况下将异常信息放入data
            responseData.put("error", e.getMessage());
        }
        // 构造最终返回结果
        result.put("data", responseData);
        return result;
    }
}