cnas-server/src/main/java/com/yuanchu/mom/controller/DeviceController.java
@@ -224,12 +224,4 @@ public Result<?> temDataAcquisition2(@RequestBody PkMaster pkMaster) { return Result.success(pkMasterService.temDataAcquisition2(pkMaster)); } @ApiOperation(value = "数采-公式计算") @PostMapping("/formulaCalculation") @ValueAuth public Result<?> formulaCalculation(@RequestBody Map<String, Object> map) { return Result.success(map); } } cnas-server/src/main/java/com/yuanchu/mom/service/DeviceService.java
@@ -43,6 +43,4 @@ List<Map<String, Object>> treeDevice(String deviceName); Result<?> determineWhetherToCollectData(String managementNumber, HttpServletRequest request); Object formulaCalculation(Map<String, Object> map, Boolean isAdopt); } cnas-server/src/main/java/com/yuanchu/mom/service/impl/DeviceServiceImpl.java
@@ -1,8 +1,6 @@ package com.yuanchu.mom.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -31,13 +29,11 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** @@ -176,18 +172,18 @@ .orderBy(false, false, DataConfig::getId)); list1.addAll(list); }); // 3、采集,取数据,参与公式计算 // 3、采集,取数据 Map<String, Object> map = DataAcquisition.dataAcquisitionEntrance(list1, device.get(0), entrustCode, sampleCode, ip); // 4、造循环次数 // 4、造循环次数,参与公式计算 if (ObjectUtils.isNotEmpty(map)) { Object result; Map<String, Object> frequency = DataAcquisition.createFrequency(entrustCode, sampleCode, map); if (ObjectUtils.isEmpty(device.get(0).getEntrustCode()) && ObjectUtils.isEmpty(device.get(0).getSampleCode())) { result = formulaCalculation(frequency, true); } else { result = formulaCalculation(frequency, false); } return Result.success(result); // if (ObjectUtils.isEmpty(device.get(0).getEntrustCode()) && ObjectUtils.isEmpty(device.get(0).getSampleCode())) { // result = formulaCalculation(frequency, true); // } else { // result = formulaCalculation(frequency, false); // } return Result.success(frequency); } else { return Result.success(null); } @@ -994,172 +990,5 @@ } else { return Result.success(true); } } @Override public Object formulaCalculation(Map<String, Object> map, Boolean isAdopt) { map.forEach((key, value) -> { Map<String, Object> jsonObject = JSONObject.parseObject(JSON.toJSONString(map.get(key)), Map.class); for (Map.Entry<String, Object> entry : jsonObject.entrySet()) { String sonKey = entry.getKey(); Object sonValue = entry.getValue(); if (!sonKey.equals("frequency")) { Map<String, Object> formulaData = JSONObject.parseObject(JSON.toJSONString(sonValue), Map.class); if (formulaData.containsKey("result") && formulaData.containsKey("isCalculation") && formulaData.containsKey("formula")) { String formula = formulaData.get("formula").toString(); List<Object> resultList = new ArrayList<>(); try { resultList = JSONObject.parseArray(JSON.toJSONString(formulaData.get("result")), Object.class); } catch (Exception e) { Object result = formulaData.get("result").toString(); resultList.add(result); } ArrayList<Object> list = new ArrayList<>(); if (isAdopt) { String result = calculationFormula(resultList, formula); list.add(result); } else { resultList.forEach(i -> { List<Object> strings = Arrays.asList(i.toString().split(",")); String result = calculationFormula(strings, formula); list.add(result); }); } formulaData.put("isCalculation", false); formulaData.put("result", list); } jsonObject.put(sonKey, formulaData); } } map.put(key, jsonObject); }); return map; } public String calculationFormula(List<Object> list, String formula) { //首先将list转换为bigdecmic List<BigDecimal> bigDecimalList = list.stream() .map(obj -> { return new BigDecimal((obj).toString()); }).collect(Collectors.toList()); System.out.println(bigDecimalList); //将中文的(转换英文的()) formula = formula.replace("(", "(") .replace(")", ")") .replace(",", ","); //然后提取公式 String strs = formula.substring(0, formula.indexOf("(")); String upperStr = strs.toUpperCase(); if (upperStr.matches(".*\\d.*")) { upperStr = ""; } System.out.println(upperStr); //然后获取最外面括号里面的值,再根据","分割 int start = formula.indexOf("("); int end = -1; int a = 0; for (int i = start; i < formula.length(); i++) { char c = formula.charAt(i); if (c == '(') { a++; } else if (c == ')') { a--; if (a == 0) { end = i; } } } if (start == -1 || end == -1) { throw new ErrorException("公式括号不匹配: " + formula); } String argumentsStr = formula.substring(start + 1, end); List<String> arguments = new ArrayList<>(); int bracketCount = 0; StringBuilder currentArgument = new StringBuilder(); for (char c : argumentsStr.toCharArray()) { if (c == ',' && bracketCount == 0) { arguments.add(currentArgument.toString()); currentArgument.setLength(0); } else { if (c == '(') bracketCount++; if (c == ')') bracketCount--; currentArgument.append(c); } } arguments.add(currentArgument.toString()); String[] bracketStrs = arguments.toArray(new String[0]); List<BigDecimal> results = new ArrayList<>(); for (String expr : bracketStrs) { System.out.println("替换前" + expr); Pattern pattern = Pattern.compile("([A-Z])(\\d+)"); Matcher matcher = pattern.matcher(expr); StringBuffer sb = new StringBuffer(); while (matcher.find()) { String letter = matcher.group(1); int index = Integer.parseInt(matcher.group(2)) - 1; // 将1-based转为0-based if (index < bigDecimalList.size()) { matcher.appendReplacement(sb, bigDecimalList.get(index).toString()); } else { throw new RuntimeException("公式中的下标 " + index + " 超出范围"); } } matcher.appendTail(sb); System.out.println("替换后" + sb.toString()); // 计算表达式 ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); try { Object result = engine.eval(sb.toString()); results.add(new BigDecimal(result.toString())); } catch (Exception e) { throw new IllegalArgumentException("无法计算公式: " + sb, e); } } // 根据函数名称进行相应计算 BigDecimal finalResult; if (upperStr.equals("") || upperStr == null) { finalResult = results.get(0); } else { switch (upperStr) { case "MAX": finalResult = results.stream().max(BigDecimal::compareTo) .orElseThrow(() -> new IllegalArgumentException("无法计算MAX值")); break; case "MIN": finalResult = results.stream().min(BigDecimal::compareTo) .orElseThrow(() -> new IllegalArgumentException("无法计算MIN值")); break; case "SUM": finalResult = results.stream().reduce(BigDecimal.ZERO, BigDecimal::add); break; case "ABS": finalResult = results.stream().map(BigDecimal::abs).reduce(BigDecimal.ZERO, BigDecimal::add); break; case "AVERAGE": finalResult = results.stream().reduce(BigDecimal.ZERO, BigDecimal::divide) .divide(BigDecimal.valueOf(results.size()), 2, BigDecimal.ROUND_HALF_UP); break; case "MEDIAN": int size = results.size(); if (size % 2 == 1) { finalResult = results.get(size / 2); } else { BigDecimal sum = results.get(size / 2 - 1).add(results.get(size / 2)); finalResult = sum.divide(BigDecimal.valueOf(2), 2, BigDecimal.ROUND_HALF_UP); } break; default: throw new UnsupportedOperationException("暂不支持函数: " + upperStr); } } System.out.println(results); System.out.println("计算结果: " + finalResult); return finalResult.toString(); // 否则:没有公式代表不需要计算,直接提取List里面的数据 } } cnas-server/src/main/java/com/yuanchu/mom/utils/DataAcquisition.java
@@ -10,7 +10,10 @@ import com.yuanchu.mom.pojo.DataConfig; import com.yuanchu.mom.pojo.Device; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; @@ -61,7 +64,11 @@ } JSONObject jsonObject = JSON.parseObject(result); if (Objects.equals(jsonObject.get("code"), 1)) { if (ObjectUtils.isEmpty(jsonObject.get("msg"))) { throw new ErrorException("未查询到文件!可能该路径(" + device.getCollectUrl() + ")下并没有所需(" + device.getFileType() +")文件!"); } else { throw new ErrorException(jsonObject.get("msg") + ""); } } else { String data = jsonObject.get("data") + ""; // 考虑到一个检测项可能会存在多个数采配置,所以需要进行分组 @@ -85,10 +92,10 @@ map = analysisList(data, userMap, device, entrustCode, sampleCode); break; case ".mdb": map = analysisMdb(data, userMap); map = analysisMdb(data, userMap, device); break; case ".db": map = analysisDb(data, userMap); map = analysisDb(data, userMap, device); break; case ".png": map = readPngString(data, userMap, device); @@ -158,7 +165,7 @@ * @param dataConfig * @return */ private static Map<String, Object> analysisDb(String data, Map<String, List<DataConfig>> dataConfig) { private static Map<String, Object> analysisDb(String data, Map<String, List<DataConfig>> dataConfig, Device device) { JSONObject jsonObject = JSON.parseObject(data); Map<String, Object> map = new HashMap<>(); if (jsonObject.isEmpty()) { @@ -205,7 +212,7 @@ result.add(substring); } // 进行公式计算 Object resultValue = calculationFormula(result, v.get(0), k); Object resultValue = calculationFormula(result, v.get(0), k, device); map.put(k, resultValue); }); return map; @@ -216,7 +223,7 @@ * @param dataConfig * @return */ private static Map<String, Object> analysisMdb(String data, Map<String, List<DataConfig>> dataConfig) { private static Map<String, Object> analysisMdb(String data, Map<String, List<DataConfig>> dataConfig, Device device) { JSONObject jsonObject = JSON.parseObject(data); Map<String, Object> map = new HashMap<>(); if (jsonObject.isEmpty()) { @@ -255,7 +262,7 @@ result.add(substring); } // 进行公式计算 Object resultValue = calculationFormula(result, v.get(0), k); Object resultValue = calculationFormula(result, v.get(0), k, device); map.put(k, resultValue); }); return map; @@ -300,7 +307,7 @@ } } // 进行公式计算 Object resultValue = calculationFormula(list, v.get(0), k); Object resultValue = calculationFormula(list, v.get(0), k, device); map.put(k, resultValue); }); return map; @@ -313,25 +320,36 @@ * @param dataConfig 存储公式的对象 * @return */ private static Object calculationFormula(List<Object> list, DataConfig dataConfig, String insProductItem) { private static Object calculationFormula(List<Object> list, DataConfig dataConfig, String insProductItem, Device device) { if (list.size() == 0) { return null; } ArrayList<Object> listResult = new ArrayList<>(); Map<String, Object> hashMap = new HashMap<>(); // 如果不为空,进行公式计算 if (ObjectUtils.isNotEmpty(dataConfig.getFormula())) { hashMap.put("isCalculation", true); hashMap.put("formula", dataConfig.getFormula()); // 否则:没有公式代表不需要计算,直接提取List里面的数据 if (ObjectUtils.isEmpty(device.getEntrustCode()) && ObjectUtils.isEmpty(device.getSampleCode())) { String s = calculationFormulaList(list, dataConfig.getFormula()); listResult.add(s); } else { hashMap.put("isCalculation", false); list.forEach(i -> { List<Object> strings = Arrays.asList(i.toString().split(",")); String s = calculationFormulaList(strings, dataConfig.getFormula()); listResult.add(s); }); } } else { listResult.addAll(list); } // 为了给前端做数据区分 if (list.size() > 1) { hashMap.put("result", list); if (listResult.size() > 1) { hashMap.put("result", listResult); } else { hashMap.put("result", list.get(0).toString()); hashMap.put("result", listResult.get(0).toString()); } hashMap.put("equipName", device.getDeviceName()); hashMap.put("equipValue", device.getManagementNumber()); return hashMap; } @@ -355,7 +373,7 @@ list = analyzeDataEntrustCodAndSampleCode(data, v, k, ",", device, entrustCode, sampleCode); } // 进行公式计算 Object resultValue = calculationFormula(list, v.get(0), k); Object resultValue = calculationFormula(list, v.get(0), k, device); map.put(k, resultValue); }); return map; @@ -383,7 +401,7 @@ list = analyzeDataEntrustCodAndSampleCode(processingDataAfterSpaces, v, k, splitIdentifier, device, entrustCode, sampleCode); } // 进行公式计算 Object resultValue = calculationFormula(list, v.get(0), k); Object resultValue = calculationFormula(list, v.get(0), k, device); map.put(k, resultValue); }); return map; @@ -409,7 +427,7 @@ list = analyzeDataEntrustCodAndSampleCode(data, v, k, splitIdentifier, device, entrustCode, sampleCode); } // 进行公式计算 Object resultValue = calculationFormula(list, v.get(0), k); Object resultValue = calculationFormula(list, v.get(0), k, device); map.put(k, resultValue); }); return map; @@ -613,4 +631,129 @@ // 防止回环地址变为IPv6 return ipAddress.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ipAddress; } public static String calculationFormulaList(List<Object> list, String formula) { //首先将list转换为bigdecmic List<BigDecimal> bigDecimalList = list.stream() .map(obj -> { return new BigDecimal((obj).toString()); }).collect(Collectors.toList()); System.out.println(bigDecimalList); //将中文的(转换英文的()) formula = formula.replace("(", "(") .replace(")", ")") .replace(",", ","); //然后提取公式 String strs = formula.substring(0, formula.indexOf("(")); String upperStr = strs.toUpperCase(); if (upperStr.matches(".*\\d.*")) { upperStr = ""; } System.out.println(upperStr); //然后获取最外面括号里面的值,再根据","分割 int start = formula.indexOf("("); int end = -1; int a = 0; for (int i = start; i < formula.length(); i++) { char c = formula.charAt(i); if (c == '(') { a++; } else if (c == ')') { a--; if (a == 0) { end = i; } } } if (start == -1 || end == -1) { throw new ErrorException("公式括号不匹配: " + formula); } String argumentsStr = formula.substring(start + 1, end); List<String> arguments = new ArrayList<>(); int bracketCount = 0; StringBuilder currentArgument = new StringBuilder(); for (char c : argumentsStr.toCharArray()) { if (c == ',' && bracketCount == 0) { arguments.add(currentArgument.toString()); currentArgument.setLength(0); } else { if (c == '(') bracketCount++; if (c == ')') bracketCount--; currentArgument.append(c); } } arguments.add(currentArgument.toString()); String[] bracketStrs = arguments.toArray(new String[0]); List<BigDecimal> results = new ArrayList<>(); for (String expr : bracketStrs) { System.out.println("替换前" + expr); Pattern pattern = Pattern.compile("([A-Z])(\\d+)"); Matcher matcher = pattern.matcher(expr); StringBuffer sb = new StringBuffer(); while (matcher.find()) { String letter = matcher.group(1); int index = Integer.parseInt(matcher.group(2)) - 1; // 将1-based转为0-based if (index < bigDecimalList.size()) { matcher.appendReplacement(sb, bigDecimalList.get(index).toString()); } else { throw new RuntimeException("公式中的下标 " + index + " 超出范围"); } } matcher.appendTail(sb); System.out.println("替换后" + sb.toString()); // 计算表达式 ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); try { Object result = engine.eval(sb.toString()); results.add(new BigDecimal(result.toString())); } catch (Exception e) { throw new IllegalArgumentException("无法计算公式: " + sb, e); } } // 根据函数名称进行相应计算 BigDecimal finalResult; if (upperStr.equals("") || upperStr == null) { finalResult = results.get(0); } else { switch (upperStr) { case "MAX": finalResult = results.stream().max(BigDecimal::compareTo) .orElseThrow(() -> new IllegalArgumentException("无法计算MAX值")); break; case "MIN": finalResult = results.stream().min(BigDecimal::compareTo) .orElseThrow(() -> new IllegalArgumentException("无法计算MIN值")); break; case "SUM": finalResult = results.stream().reduce(BigDecimal.ZERO, BigDecimal::add); break; case "ABS": finalResult = results.stream().map(BigDecimal::abs).reduce(BigDecimal.ZERO, BigDecimal::add); break; case "AVERAGE": finalResult = results.stream().reduce(BigDecimal.ZERO, BigDecimal::divide) .divide(BigDecimal.valueOf(results.size()), 2, BigDecimal.ROUND_HALF_UP); break; case "MEDIAN": int size = results.size(); if (size % 2 == 1) { finalResult = results.get(size / 2); } else { BigDecimal sum = results.get(size / 2 - 1).add(results.get(size / 2)); finalResult = sum.divide(BigDecimal.valueOf(2), 2, BigDecimal.ROUND_HALF_UP); } break; default: throw new UnsupportedOperationException("暂不支持函数: " + upperStr); } } System.out.println(results); System.out.println("计算结果: " + finalResult); return finalResult.toString(); // 否则:没有公式代表不需要计算,直接提取List里面的数据 } } inspect-server/src/main/java/com/yuanchu/mom/mapper/InsOrderMapper.java
@@ -53,9 +53,4 @@ List<Map<Integer, Object>> selectReportModelByOrderId(@Param("id") Integer id, @Param("laboratory") String laboratory); String seldepLimsId(int depLimsId); Map<String, Object> getDeviceMessage(@Param("ip")String ip, @Param("inspectionItem") String inspectionItem, @Param("inspectionItemSubclass") String inspectionItemSubclass, @Param("sample") String sample); } inspect-server/src/main/java/com/yuanchu/mom/service/impl/InsOrderPlanServiceImpl.java
@@ -238,8 +238,6 @@ insProducts = insSampleMapper.getInsProduct3(id); break; } // 数采新增 getDeviceMessage(insProducts, request); Set<Integer> set = new HashSet<>(); Map<Integer, String> map2 = new HashMap<>(); @@ -248,33 +246,6 @@ return insProducts; } private List<InsProduct> getDeviceMessage(List<InsProduct> insProducts, HttpServletRequest request) { String ipAddress = request.getRemoteAddr(); // 防止回环地址变为IPv6 String ip = ipAddress.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ipAddress; insProducts.forEach(i -> { Map<String, Object> devices = baseMapper.getDeviceMessage(ip, i.getInspectionItem(), i.getInspectionItemSubclass(), i.getSampleType()); if (ObjectUtils.isNotEmpty(devices) && ObjectUtils.isNotEmpty(devices.get("file_type")) && ObjectUtils.isNotEmpty(devices.get("collect_url"))) { InsProductResult insProductResult = i.getInsProductResult(); if (ObjectUtils.isEmpty(insProductResult)) { insProductResult = new InsProductResult(); } List<Object> list = new ArrayList<>(); Map<Object, Object> hashMap = new HashMap<>(); hashMap.put("v", devices.get("device_name")); list.add(hashMap); insProductResult.setEquipName(JSON.toJSON(list).toString()); List<Object> listValue = new ArrayList<>(); Map<Object, Object> hashMapValue = new HashMap<>(); hashMapValue.put("v", devices.get("management_number")); listValue.add(hashMapValue); insProductResult.setEquipName(JSON.toJSON(list).toString()); insProductResult.setEquipValue(JSON.toJSON(listValue).toString()); i.setInsProductResult(insProductResult); } }); return insProducts; } @Override public List<String> checkSubmitPlan(Integer orderId, String laboratory) { List<String> collect = new ArrayList<>(); inspect-server/src/main/resources/mapper/InsOrderMapper.xml
@@ -475,22 +475,4 @@ from department_lims where id = #{depLimsId} </select> <select id="getDeviceMessage" resultType="java.util.Map"> select d.device_name, d.management_number, d.file_type, d.collect_url FROM device d, device_data_config ddc <if test="sample != '' and sample != null"> inner join structure_item_parameter sip on sip.sample like concat('%', #{sample}, '%') and sip.id = ddc.structure_item_parameter_id </if> where d.ip = #{ip} and ddc.inspection_item = #{inspectionItem} <if test="inspectionItemSubclass != '' and inspectionItemSubclass != null"> and ddc.inspection_item_subclass = #{inspectionItemSubclass} </if> and d.device_status = 0 and d.ins_product_ids is not null limit 1 </select> </mapper>