liding
2025-04-29 ce5c5e897b288a27f00804b68e73647fdfc5b6a7
cnas-device/src/main/java/com/ruoyi/device/utils/DataAcquisition.java
@@ -15,6 +15,7 @@
import javax.script.ScriptEngineManager;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
@@ -139,6 +140,9 @@
                case ".pdf":
                    map = readPdfString(data, userMap, device);
                    break;
                case ".et":
                    map = readEtString(data, userMap, device);
                    break;
                default:
                    map = null;
                    break;
@@ -152,40 +156,262 @@
        }
    }
    private static Map<String, Object> readPdfString(String data, Map<String, List<DataConfig>> dataConfig, Device device) {
    private static Map<String, Object> readEtString(String data, Map<String, List<DataConfig>> dataConfig, Device device) {
        Map<String, Object> map = new HashMap<>();
        // 定义 RoHS 指标列表
        List<String> rohsIndicators = Arrays.asList("RoHS指标,镉(Cd)", "RoHS指标,总溴联苯(Br)", "RoHS指标,总铬(Cr)", "RoHS指标,汞(Hg)", "RoHS指标,铅(Pb)");
        dataConfig.forEach((k, v) -> {
            List<Object> list = new ArrayList<>();
            for (int config = 0; config < v.size(); config++) {
                String referx = getRefer(v.get(config).getReferx());
                String result = null;
                // 通过\n将字符串分割为行
                String[] aColumnY = data.split("\n");
                List<String> list1 = new ArrayList<>();
                // 该循环得出用户配置的y轴
                for (int i = 0; i < aColumnY.length; i++) {
                    String addDataWithSpaces = referx.replaceAll("", " ");
                    int x = getXOrY(v.get(config).getX(), k, "X");
                    if (aColumnY[i].contains(addDataWithSpaces)) {
                        Matcher matcher = SPATTERN.matcher(aColumnY[i]);
                        while (matcher.find()) {
                            String group = matcher.group();
                            list1.add(group);
                        }
                    }
                    if (ObjectUtils.isNotEmpty(list1)) {
                        result = list1.get(x);
                    }
            List<Object> list;
            boolean containsRoHS = false;
            for (DataConfig item : v) {
                if (rohsIndicators.contains(item.getInsProductItem())) {
                    containsRoHS = true;
                    break;
                }
                if (ObjectUtils.isNotEmpty(result)) {
                    list.add(result);
                }
            }
            if (containsRoHS) {
                list = analyzeEt1Data(data, v, splitIdentifier);
            } else {
                list = analyzeEtData(data, v, splitIdentifier);
            }
            // 进行公式计算
            Object resultValue = calculationFormula(list, v.get(0), k, device);
            map.put(k, resultValue);
        });
        return map;
    }
    /**
     * 荧光光谱仪 .et文件
     *
     * @param data
     * @param v
     * @param splitIdentifier
     * @return
     */
    private static List<Object> analyzeEt1Data(String data, List<DataConfig> v, String splitIdentifier) {
        List<Object> finalResult = new ArrayList<>();
        List<String> matchingLines = new ArrayList<>();
        // 遍历 DataConfig 列表
        for (DataConfig config : v) {
            String referx = getRefer(config.getReferx());
            if (ObjectUtils.isEmpty(referx)) {
                continue;
            }
            // 使用正则表达式构建完整匹配的模式
            String regex = "\\b" + Pattern.quote(referx) + "\\b";
            Pattern pattern = Pattern.compile(regex);
            String[] lines = data.replaceAll(" ", "").split("\n");
            // 筛选出包含 referx 的行
            for (String line : lines) {
                if (pattern.matcher(line).find()) {
                    matchingLines.add(line);
                }
            }
        }
        // 遍历匹配的行,提取 splitIdentifier 第七个和第八个分隔符中间的值
        for (String line : matchingLines) {
            int startIndex = -1;
            int endIndex = -1;
            int count = 0;
            int index = 0;
            while ((index = line.indexOf(splitIdentifier, index)) != -1) {
                count++;
                if (count == 7) {
                    startIndex = index + splitIdentifier.length();
                } else if (count == 8) {
                    endIndex = index;
                    break;
                }
                index++;
            }
            if (startIndex != -1 && endIndex != -1) {
                finalResult.add(line.substring(startIndex, endIndex));
            }
        }
        // 确保返回值为数组格式
        if (finalResult.size() == 1) {
            List<Object> singleResultAsArray = new ArrayList<>();
            singleResultAsArray.add(finalResult.get(0));
            return singleResultAsArray;
        }
        return finalResult;
    }
    /**
     * 拉力机.et文件
     *
     * @param data
     * @param v
     * @param splitIdentifier
     * @return
     */
    public static List<Object> analyzeEtData(String data, List<DataConfig> v, String splitIdentifier) {
        List<Object> finalResult = new ArrayList<>();
        for (DataConfig config : v) {
            String referx = getRefer(config.getReferx());
            if (ObjectUtils.isEmpty(referx)) {
                continue;
            }
            String[] lines = data.replaceAll(" ", "").split("\n");
            boolean foundReferx = false;
            List<String> validLines = new ArrayList<>();
            int referxColumnIndex = -1; // 用于存储referx所在列索引
            // 先找出referx所在列索引
            for (String line : lines) {
                String[] parts = line.split(splitIdentifier);
                for (int i = 0; i < parts.length; i++) {
                    if (parts[i].contains(referx)) {
                        referxColumnIndex = i;
                        break;
                    }
                }
                if (referxColumnIndex != -1) {
                    break;
                }
            }
            // 若未找到匹配的referx,抛出异常
            if (referxColumnIndex == -1) {
                throw new IllegalArgumentException("请输入正确的x值,文件中未找到与 " + referx + " 匹配的值。");
            }
            for (int i = 0; i < lines.length; i++) {
                String line = lines[i];
                String[] parts = line.split(splitIdentifier, 2);
                if (!foundReferx) {
                    if (containsReferx(parts, referx)) {
                        foundReferx = true;
                    }
                    continue;
                }
                if (i > 0 && foundReferx) {
                    if (parts.length > 0 && isNumeric(parts[0])) {
                        validLines.add(line);
                    }
                }
            }
            for (String line : validLines) {
                String[] parts = line.split(splitIdentifier);
                if (referxColumnIndex < parts.length) {
                    String value = parts[referxColumnIndex].trim();
                    if (value.isEmpty()) {
                        value = "";
                    }
                    finalResult.add(value);
                } else {
                    finalResult.add("");
                }
            }
        }
        return finalResult;
    }
    private static boolean containsReferx(String[] parts, String referx) {
        for (String part : parts) {
            if (part.contains(referx)) {
                return true;
            }
        }
        return false;
    }
    private static boolean isNumeric(String str) {
        try {
            Double.parseDouble(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }
    /**
     * 色谱pdf文件需要定位x,y
     *
     * @param data
     * @param dataConfig
     * @param device
     * @return
     */
    private static Map<String, Object> readPdfString(String data, Map<String, List<DataConfig>> dataConfig, Device device) {
        Map<String, Object> map = new HashMap<>();
        dataConfig.forEach((k, v) -> {
            List<Object> list = new ArrayList<>();
            for (int config = 0; config < v.size(); config++) {
                String referX = getRefer(v.get(config).getReferx());
                String referY = getRefer(v.get(config).getRefery());
                String[] aColumnY = data.split("\n");
                for (String line : aColumnY) {
                    if (line.contains(referX) || line.contains(referY)) {
                        list.add(line);
                    }
                }
                int referYColumnIndex = -1;
                for (Object item : list) {
                    // 使用正则表达式 \\s+ 分割字符串
                    String[] columns = ((String) item).split("\\s+");
                    for (int i = 0; i < columns.length; i++) {
                        if (columns[i].equals(referY)) {
                            referYColumnIndex = i;
                            break;
                        }
                    }
                    if (referYColumnIndex != -1) {
                        break;
                    }
                }
                List<Object> targetColumnValues = new ArrayList<>();
                if (referYColumnIndex != -1) {
                    for (Object item : list) {
                        String line = (String) item;
                        // 过滤掉包含 referY 的行
                        if (!line.contains(referY)) {
                            String[] columns = line.split("\\s+");
                            if (columns.length > referYColumnIndex) {
                                targetColumnValues.add(columns[referYColumnIndex]);
                            }
                        }
                    }
                }
                Object resultValue = calculationFormula(targetColumnValues, v.get(0), k, device);
                map.put(k, resultValue);
            }
        });
        return map;
    }
    public static List<Object> extractColumnValues(List<Object> list, String columnName) {
        List<Object> columnValues = new ArrayList<>();
        if (list.isEmpty()) {
            return columnValues;
        }
        String[] headers = ((String) list.get(0)).split(",");
        int columnIndex = -1;
        for (int i = 0; i < headers.length; i++) {
            if (headers[i].equals(columnName)) {
                columnIndex = i;
                break;
            }
        }
        if (columnIndex == -1) {
            return columnValues;
        }
        for (int i = 1; i < list.size(); i++) {
            String[] columns = ((String) list.get(i)).split(",");
            if (columnIndex < columns.length) {
                columnValues.add(columns[columnIndex]);
            }
        }
        return columnValues;
    }
    public static Map<String, Object> createFrequency(String entrustCode, String sampleCode, Map<String, Object> map) {
@@ -465,7 +691,7 @@
        ArrayList<Object> listResult = new ArrayList<>();
        Map<String, Object> hashMap = new HashMap<>();
        // 如果不为空,进行公式计算
        if (ObjectUtils.isNotEmpty(dataConfig.getFormula())) {
        if (ObjectUtils.isNotEmpty(dataConfig.getFormula()) && !"(null)".equals(dataConfig.getFormula())) {
            // 否则:没有公式代表不需要计算,直接提取List里面的数据
            if (ObjectUtils.isEmpty(device.getEntrustCode()) && ObjectUtils.isEmpty(device.getSampleCode())) {
                String s = calculationFormulaList(list, dataConfig.getFormula());
@@ -479,6 +705,12 @@
            }
        } else {
            listResult.addAll(list);
        }
        // 替换 "n.a." 为空字符串
        for (int i = 0; i < listResult.size(); i++) {
            if ("n.a.".equals(listResult.get(i))) {
                listResult.set(i, "");
            }
        }
        // 为了给前端做数据区分
        if (listResult.size() > 1) {
@@ -566,20 +798,208 @@
    public static Map<String, Object> analysisList(String data, Map<String, List<DataConfig>> dataConfig,
                                                   Device device, String entrustCode, String sampleCode) {
        Map<String, Object> map = new HashMap<>();
        List<String> rohsIndicators = Arrays.asList("成束释放,SPR", "成束释放,HRR", "成束释放,THR", "成束释放,TSP", "成束释放,FIGRA");
        dataConfig.forEach((k, v) -> {
            List<Object> list = new ArrayList<>();
            // 委托编号与样品编号不存在,定:1、Y定范围,X定横坐标;2、只存在Y;3、只存在X
            if (ObjectUtils.isEmpty(device.getEntrustCode()) && ObjectUtils.isEmpty(device.getSampleCode())) {
                list = analyzeXlsData(data, v, k, splitIdentifier);
                // 委托编号与样品编号存在
            } else if (ObjectUtils.isNotEmpty(device.getEntrustCode()) && ObjectUtils.isNotEmpty(device.getSampleCode())) {
                list = analyzeDataEntrustCodAndSampleCode(data, v, k, splitIdentifier, device, entrustCode, sampleCode);
//            // 委托编号与样品编号不存在,定:1、Y定范围,X定横坐标;2、只存在Y;3、只存在X
//            if (ObjectUtils.isEmpty(device.getEntrustCode()) && ObjectUtils.isEmpty(device.getSampleCode())) {
//                list = analyzeXlsData(data, v, k, splitIdentifier);
//                // 委托编号与样品编号存在
//            } else if (ObjectUtils.isNotEmpty(device.getEntrustCode()) && ObjectUtils.isNotEmpty(device.getSampleCode())) {
//                list = analyzeDataEntrustCodAndSampleCode(data, v, k, splitIdentifier, device, entrustCode, sampleCode);
//            }
            boolean containsRoHS = false;
            for (DataConfig item : v) {
                if (rohsIndicators.contains(item.getInsProductItem())) {
                    containsRoHS = true;
                    break;
                }
            }
            if (containsRoHS) {
                list = analyzeXlsxData(data, v, k, splitIdentifier);
            } else {
                list =  analyzeXlsx1Data(data, v, k, splitIdentifier);
            }
            // 进行公式计算
            Object resultValue = calculationFormula(list, v.get(0), k, device);
            map.put(k, resultValue);
        });
        return map;
    }
    private static List<Object> analyzeXlsx1Data(String data, List<DataConfig> v, String k, String splitIdentifier) {
        List<Object> finalResult = new ArrayList<>();
        if (data == null || data.isEmpty()) {
            throw new IllegalArgumentException("输入的数据为空,请检查输入。");
        }
        // 分割数据为行
        String[] lines = data.replaceAll(" ", "").split("\n");
        if (lines.length == 0) {
            throw new IllegalArgumentException("输入的数据没有有效的行,请检查输入。");
        }
        // 获取表头
        String[] headers = lines[0].split("\\s+");
        if (headers.length == 0) {
            throw new IllegalArgumentException("表头数据为空,请检查输入格式。");
        }
        // 查找测试时间列的索引
        int testTimeIndex = -1;
        for (int i = 0; i < headers.length; i++) {
            if (headers[i].contains("测试时间")) {
                testTimeIndex = i;
                break;
            }
        }
        // 若未找到测试时间列,抛出异常
        if (testTimeIndex == -1) {
            throw new IllegalArgumentException("未找到包含 '测试时间' 的列,请检查表头。");
        }
        // 用于存储测试时间为 2400 的行数据
        String[] targetLine = null;
        // 查找测试时间为 2400 的行
        for (int i = 1; i < lines.length; i++) {
            try {
                String[] lineData = lines[i].split("\\s+");
                double testTime = Double.parseDouble(lineData[testTimeIndex]);
                if (testTime == 2400) {
                    targetLine = lineData;
                    break;
                }
            } catch (NumberFormatException e) {
                throw new RuntimeException("第 " + (i + 1) + " 行的 '测试时间' 列数据无法转换为数字,请检查数据格式。", e);
            } catch (ArrayIndexOutOfBoundsException e) {
                throw new RuntimeException("第 " + (i + 1) + " 行的数据列数不足,无法获取 '测试时间' 列,请检查数据格式。", e);
            }
        }
        // 若未找到测试时间为 2400 的行,抛出异常
        if (targetLine == null) {
            throw new RuntimeException("未找到测试时间为 2400 的数据,请检查数据内容。");
        }
        for (DataConfig config : v) {
            String referx = getRefer(config.getReferx());
            if (ObjectUtils.isEmpty(referx)) {
                continue;
            }
            // 查找 referx 列的索引
            int referxIndex = -1;
            for (int i = 0; i < headers.length; i++) {
                if (headers[i].trim().contains(referx.trim())) {
                    referxIndex = i;
                    break;
                }
            }
            // 若未找到 referx 列,抛出异常
            if (referxIndex == -1) {
                throw new IllegalArgumentException("未找到 '" + referx + "' 列,请检查表头和配置。");
            }
            try {
                double value = Double.parseDouble(targetLine[referxIndex]);
                // 四舍五入保留两位小数
                DecimalFormat df = new DecimalFormat("#.00");
                String formattedValue = df.format(value);
                finalResult.add(Double.parseDouble(formattedValue));
            } catch (NumberFormatException e) {
                throw new RuntimeException("'测试时间' 为 2400 的行中,'" + referx + "' 列的数据无法转换为数字,请检查数据格式。", e);
            } catch (ArrayIndexOutOfBoundsException e) {
                throw new RuntimeException("'测试时间' 为 2400 的行的数据列数不足,无法获取 '" + referx + "' 列,请检查数据格式。", e);
            }
        }
        return finalResult;
    }
    private static List<Object> analyzeXlsxData(String data, List<DataConfig> v, String k, String splitIdentifier) {
        List<Object> finalResult = new ArrayList<>();
        String ss = k;
        // 存储符合测试时间范围的数据行
        List<String[]> validLines = new ArrayList<>();
        String[] lines = data.replaceAll(" ", "").split("\n");
        String[] headers = lines[0].split("\\s+");
        int testTimeIndex = -1;
        for (int i = 0; i < headers.length; i++) {
            if ("测试时间".equals(headers[i])) {
                testTimeIndex = i;
                break;
            }
        }
        if (testTimeIndex == -1) {
            return finalResult;
        }
        // 筛选出测试时间在 300 到 1500 之间的数据行
        for (int i = 1; i < lines.length; i++) {
            String[] lineData = lines[i].split("\\s+");
            try {
                double testTime = Double.parseDouble(lineData[testTimeIndex]);
                if (testTime > 300 && testTime <= 1500) {
                    validLines.add(lineData);
                } else if (testTime > 1500) {
                    break;
                }
            } catch (NumberFormatException e) {
                continue;
            }
        }
        for (DataConfig config : v) {
            String referx = getRefer(config.getReferx());
            if (ObjectUtils.isEmpty(referx)) {
                continue;
            }
            int referxIndex = -1;
            for (int i = 0; i < headers.length; i++) {
                if (referx.equals(headers[i])) {
                    referxIndex = i;
                    break;
                }
            }
            if (referxIndex == -1) {
                continue;
            }
            List<Double> values = new ArrayList<>();
            for (String[] lineData : validLines) {
                try {
                    double value = Double.parseDouble(lineData[referxIndex]);
                    values.add(value);
                } catch (NumberFormatException e) {
                    continue;
                }
            }
            Object result;
            if ("HRR".equals(referx) || "SPR".equals(referx) || "FIGRA".equals(referx)) {
                result = values.stream().mapToDouble(Double::doubleValue).max().orElse(0);
            } else if ("THR".equals(referx) || "TSP".equals(referx)) {
                result = values.stream().mapToDouble(Double::doubleValue).sum();
            } else {
                continue;
            }
            if (result != null) {
                // 四舍五入保留两位小数
                DecimalFormat df = new DecimalFormat("#.00");
                result = Double.parseDouble(df.format(result));
                finalResult.add(result);
            }
        }
        return finalResult;
    }
    /**
@@ -590,7 +1010,7 @@
     * @return
     */
    public static Map<String, Object> analysisXlsList(String data, Map<String, List<DataConfig>> dataConfig,
                                                   Device device, String entrustCode, String sampleCode) {
                                                      Device device, String entrustCode, String sampleCode) {
        Map<String, Object> map = new HashMap<>();
        dataConfig.forEach((k, v) -> {
            List<Object> list = new ArrayList<>();