package com.yuanchu.mom.utils; import cn.hutool.core.io.IORuntimeException; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.yuanchu.mom.exception.ErrorException; import com.yuanchu.mom.pojo.DataConfig; import com.yuanchu.mom.pojo.Device; import com.yuanchu.mom.vo.Result; import javax.servlet.http.HttpServletRequest; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; public class DataAcquisition { private static final String HTTP = "http://"; private static final String GETFILE = ":9527/lims/getFile"; // 获取文件接口 private static final String MOVEFILE = ":9527/lims/moveFile"; // 文件移动地址 private static final String splitIdentifier = "@-@"; // 自定义唯一标识分割符 /** * 数采入口 * @param request * @param dataConfig * @param device * @return */ public static Result dataAcquisitionEntrance(HttpServletRequest request, List dataConfig, Device device, String entrustCode, String sampleCode) { String ipAddress = request.getRemoteAddr(); // 防止回环地址变为IPv6 String ip = ipAddress.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ipAddress; String http = HTTP + ip + GETFILE + "?filePath=" + device.getCollectUrl() + "&fileExtension=" + device.getFileType(); String result = null; try { result = HttpUtil.get(http); } catch (IORuntimeException e) { throw new ErrorException("所在电脑未安装或未启动:LIMS文件采集器!"); } JSONObject jsonObject = JSON.parseObject(result); if (Objects.equals(jsonObject.get("code"), 1)) { if (ObjectUtils.isEmpty(jsonObject.get("msg"))) { throw new ErrorException("未查询到数据,可能文件路径配置错误!"); } else { System.out.println(jsonObject); throw new ErrorException("未知错误,请联系管理员!"); } } else { String data = jsonObject.get("data").toString(); // 考虑到一个检测项可能会存在多个数采配置,所以需要进行分组 Map> userMap = dataConfig.stream().collect(Collectors.groupingBy(DataConfig::getInsProductItem)); Map map; switch (device.getFileType()) { case ".docx": map = analysisString(data, userMap); break; case ".xlsx": map = analysisList(data, userMap); break; case ".txt": map = analysisTxt(data, userMap); break; case ".csv": map = analysisList(data, userMap); break; case ".mdb": map = analysisMdb(data, userMap, entrustCode, sampleCode); break; case ".db": map = analysisDb(data, userMap); break; case ".png": map = readPngString(data, userMap); break; default: map = null; break; } // 如果存在存储地址,则移动地址 if (ObjectUtils.isNotEmpty(device.getStorageUrl())) { String s = HTTP + ip + MOVEFILE + "?startFilePath=" + device.getCollectUrl() + "&endFilePath=" + device.getStorageUrl(); String storageUrlResult = HttpUtil.get(s); JSONObject storageUrlResultJson = JSON.parseObject(storageUrlResult); if (Objects.equals(storageUrlResultJson.get("code"), 1)) { if (ObjectUtils.isEmpty(storageUrlResultJson.get("msg"))) { throw new ErrorException("存储地址错误,可能文件路径配置错误!"); } else { throw new ErrorException("未知错误,请联系管理员!"); } } } map.put("frequency", "1"); return Result.success(map); } } /** * 需要通过X,Y轴定位 * @param data * @param dataConfig * @return */ private static Map analysisDb(String data, Map> dataConfig) { JSONObject jsonObject = JSON.parseObject(data); JSONArray dataList = JSONArray.parseArray(jsonObject.get("data").toString()); JSONArray columnList = JSONArray.parseArray(jsonObject.get("column").toString()); Map map = new HashMap<>(); dataConfig.forEach((k, v) -> { List list = new ArrayList<>(); for (int config = 0; config < v.size(); config++) { String referx = v.get(config).getReferx(); if(ObjectUtils.isEmpty(v.get(config).getX()) && ObjectUtils.isEmpty(v.get(config).getY())) { continue; } int x = Integer.parseInt(v.get(config).getX()); int y = Integer.parseInt(v.get(config).getY()); String key = ""; for (int i = 0; i < columnList.size(); i++) { if (columnList.get(i).equals(referx)) { key = columnList.get(i + x).toString(); } } JSONObject jsonObject1 = JSON.parseObject(dataList.get(y).toString()); Object o = jsonObject1.get(key); if (ObjectUtils.isNotEmpty(o)) { list.add(o); } } // 进行公式计算 String resultValue = calculationFormula(list, v.get(0), k); map.put(k, resultValue); }); return map; } /** * 需要通过X,Y轴定位 * @param data * @param dataConfig * @return */ private static Map analysisMdb(String data, Map> dataConfig, String entrustCode, String sampleCode) { JSONObject jsonObject = JSON.parseObject(data); JSONArray dataList = JSONArray.parseArray(jsonObject.get("data").toString()); JSONArray columnList = JSONArray.parseArray(jsonObject.get("column").toString()); Map map = new HashMap<>(); dataConfig.forEach((k, v) -> { List list = new ArrayList<>(); for (int config = 0; config < v.size(); config++) { String referx = v.get(config).getReferx(); int x = Integer.parseInt(v.get(config).getX()); String key = ""; for (int i = 0; i < columnList.size(); i++) { if (columnList.get(i).equals(referx)) { key = columnList.get(i + x).toString(); } } for (int i = 0; i < dataList.size(); i++) { JSONObject jsonObject1 = JSON.parseObject(dataList.get(i).toString()); if (entrustCode.equals(jsonObject1.get("OrderNumber")) && sampleCode.equals(jsonObject1.get("SampleNumber"))) { Object o = jsonObject1.get(key); if (ObjectUtils.isNotEmpty(o)) { list.add(o); } } } } // 进行公式计算 String resultValue = calculationFormula(list, v.get(0), k); map.put(k, resultValue); }); return map; } private static Pattern SPATTERN = Pattern.compile("([-+])?\\d+(\\.\\d+)?"); /** * 只需X轴 * @param data 采集到的文件字符串 * @param dataConfig 用户配置好的x,y轴定位数据与参照物 * @return */ private static Map readPngString(String data, Map> dataConfig) { Map map = new HashMap<>(); dataConfig.forEach((k, v) -> { List list = new ArrayList<>(); for (int config = 0; config < v.size(); config++) { String referx = v.get(config).getReferx(); String xResult = null; // 通过\n将字符串分割为行 String[] aColumnY = data.split("\n"); List list1 = new ArrayList<>(); // 该循环得出用户配置的y轴 for (int i = 0; i < aColumnY.length; i++) { String addDataWithSpaces = referx.replaceAll("", " "); int x = Integer.parseInt(v.get(config).getX()); 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)) { xResult = list1.get(x); } } if (ObjectUtils.isNotEmpty(xResult)) { list.add(xResult); } } // 进行公式计算 String resultValue = calculationFormula(list, v.get(0), k); map.put(k, resultValue); }); return map; } /** * 从文件中提取出来的文字,如果有公式,进行公式计算,否则取列表第一个值 * @param list 提取出的数字 * @param dataConfig 存储公式的对象 * @return */ private static String calculationFormula(List list, DataConfig dataConfig, String insProductItem) { // 如果不为空,进行公式计算 if (ObjectUtils.isNotEmpty(dataConfig.getFormula())) { return null; // 否则:没有公式代表不需要计算,直接提取List里面的数据 } else { // 这里只会取列表第一个数据 if (list.size() > 1) { throw new ErrorException("未给:" + insProductItem + " 配置公式,可是却采集到了" + list.size() + "个值!分别为:" + list); } else { return list.get(0).toString(); } } } /** * 解析String数据 * @param data 采集到的文件字符串 * @param dataConfig 用户配置好的x,y轴定位数据与参照物 * @return */ private static Map analysisTxt(String data, Map> dataConfig) { Map map = new HashMap<>(); dataConfig.forEach((k, v) -> { List list = new ArrayList<>(); for (int config = 0; config < v.size(); config++) { String referx = v.get(config).getReferx(); String refery = v.get(config).getRefery(); String xResult = null; String yResult = null; // 通过\n将字符串分割为行 String[] aColumnY = data.split("\n"); // 该循环得出用户配置的y轴 for (int i = 0; i < aColumnY.length; i++) { // 得出用户配置的x轴 String[] aLineX = aColumnY[i].split(","); for (int j = 0; j < aLineX.length; j++) { if (ObjectUtils.isNotEmpty(referx) && aLineX[j].contains(referx)) { try { int x = Integer.parseInt(v.get(config).getX()); xResult = aLineX[j + x]; } catch (Exception e) {} } if (ObjectUtils.isNotEmpty(refery) && aLineX[j].contains(refery)) { try { int y = Integer.parseInt(v.get(config).getY()); String[] split = aColumnY[i + y].split(","); yResult = split[split.length - 1]; } catch (Exception e) {} } } } if (ObjectUtils.isNotEmpty(xResult) && ObjectUtils.isNotEmpty(yResult)) { if(xResult.equals(yResult)) { list.add(xResult); } else { throw new ErrorException(k + "项目X轴值:" + xResult + ",Y轴值:" + yResult + "取得的数据不相同!请检查数采配置!"); } } } // 进行公式计算 if (list.size() > 0) { String resultValue = calculationFormula(list, v.get(0), k); map.put(k, resultValue); } else { map.put(k, null); } }); return map; } /** * * @param data 采集到的文件字符串 * @param dataConfig 用户配置好的x,y轴定位数据与参照物 * @return */ private static Map analysisString(String data, Map> dataConfig) { String processingDataAfterSpaces = data.replaceAll(" +", splitIdentifier).replaceAll("\r", ""); Map map = new HashMap<>(); dataConfig.forEach((k, v) -> { List list = new ArrayList<>(); for (int config = 0; config < v.size(); config++) { String referx = v.get(config).getReferx(); String refery = v.get(config).getRefery(); String xResult = null; String yResult = null; // 通过\n将字符串分割为行 String[] aColumnY = processingDataAfterSpaces.split("\n"); // 该循环得出用户配置的y轴 for (int i = 0; i < aColumnY.length; i++) { if (aColumnY[i].replaceAll(" ", "").contains(refery.replaceAll(" ", ""))) { int y = Integer.parseInt(v.get(config).getY()); int x = Integer.parseInt(v.get(config).getX()); String[] split = aColumnY[i + y].split(splitIdentifier); for (int i1 = 0; i1 < split.length; i1++) { if (split[i1].replaceAll(" ", "").equals(referx.replaceAll(" ", ""))) { // split[i1 + x] } } // String[] aLineX = aColumnY[i].split(splitIdentifier); // try { // int y = Integer.parseInt(v.get(config).getY()); // String[] split = aColumnY[i + y].split(splitIdentifier); // yResult = split[split.length - 1]; // } catch (Exception e) {} } // 得出用户配置的x轴 // for (int j = 0; j < aLineX.length; j++) { // if (ObjectUtils.isNotEmpty(referx) && aLineX[j].replaceAll(" ", "").contains(referx.replaceAll(" ", ""))) { // try { // int x = Integer.parseInt(v.get(config).getX()); // xResult = aLineX[j + x]; // } catch (Exception e) {} // } // // } } if (ObjectUtils.isNotEmpty(yResult)) { yResult = yResult.replaceAll(" ", ""); // 结果包含特殊字符,需要剔除掉 if(yResult.contains("=")) { String[] split = yResult.split("="); list.add(split[split.length - 1]); } else if (yResult.contains(":")) { String[] split = yResult.split(":"); list.add(split[split.length - 1].replaceAll("%", "")); } } System.out.println(xResult + "=========" + yResult); if (ObjectUtils.isNotEmpty(xResult) && ObjectUtils.isNotEmpty(yResult)) { if(xResult.equals(yResult)) { list.add(xResult); } else { throw new ErrorException("X轴值:" + xResult + ",Y轴值:" + yResult + "取得的数据不相同!请检查数采配置!"); } } } // 进行公式计算 if (list.size() > 0) { String resultValue = calculationFormula(list, v.get(0), k); map.put(k, resultValue); } else { map.put(k, null); } }); return map; } /** * 取X,Y两个定位 * @param data 采集到的文件字符串 * @param dataConfig 用户配置好的x,y轴定位数据与参照物 * @return */ public static Map analysisList(String data, Map> dataConfig) { Map map = new HashMap<>(); dataConfig.forEach((k, v) -> { List list = new ArrayList<>(); for (int config = 0; config < v.size(); config++) { String referx = v.get(config).getReferx(); String refery = v.get(config).getRefery(); String xResult = null; String yResult = null; // 通过\n将字符串分割为行 String[] aColumnY = data.split("\n"); // 该循环得出用户配置的y轴 for (int i = 0; i < aColumnY.length; i++) { // 得出用户配置的x轴 String[] aLineX = aColumnY[i].split(splitIdentifier); for (int j = 0; j < aLineX.length; j++) { if (ObjectUtils.isNotEmpty(referx) && referx.equals(aLineX[j])) { try { int x = Integer.parseInt(v.get(config).getX()); xResult = aLineX[j + x]; } catch (Exception e) {} } if (ObjectUtils.isNotEmpty(refery) && refery.equals(aLineX[j])) { try { int y = Integer.parseInt(v.get(config).getY()); String aColumnData = aColumnY[i + y]; // 获取到第Y行的数据 yResult = aColumnData.split(splitIdentifier)[j]; } catch (Exception e) {} } } } if (ObjectUtils.isNotEmpty(xResult) && ObjectUtils.isNotEmpty(yResult)) { if(xResult.equals(yResult)) { list.add(xResult); } else { throw new ErrorException("X轴值:" + xResult + ",Y轴值:" + yResult + "取得的数据不相同!请检查数采配置!"); } } } // 进行公式计算 if (list.size() > 0) { String resultValue = calculationFormula(list, v.get(0), k); map.put(k, resultValue); } else { map.put(k, null); } }); return map; } }