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("未知错误,请联系管理员!"); } } } return Result.success(map); } } 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())) { throw new ErrorException("未给" + k + "进行数采配置x,y!"); } 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)); map.put(k, resultValue); }); return map; } 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)); map.put(k, resultValue); }); return map; } private static Pattern SPATTERN = Pattern.compile("([-+])?\\d+(\\.\\d+)?"); /** * 解析String数据 * @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)); map.put(k, resultValue); }); return map; } /** * 从文件中提取出来的文字,如果有公式,进行公式计算,否则取列表第一个值 * @param list 提取出的数字 * @param dataConfig 存储公式的对象 * @return */ private static String calculationFormula(List list, DataConfig dataConfig) { // 如果不为空,进行公式计算 if (ObjectUtils.isNotEmpty(dataConfig.getFormula())) { return null; // 否则:没有公式代表不需要计算,直接提取List里面的数据 } else { // 这里只会取列表第一个数据 if (list.size() > 0) { return list.get(0).toString(); } return null; } } /** * 解析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)) { int x = Integer.parseInt(v.get(config).getX()); try { xResult = aLineX[j + x]; } catch (Exception e) { throw new ErrorException("数采配置X轴超出!"); } } if (ObjectUtils.isNotEmpty(refery) && aLineX[j].contains(refery)) { int y = Integer.parseInt(v.get(config).getY()); try { String[] split = aColumnY[i + y].split(","); yResult = split[split.length - 1]; } catch (Exception e) { throw new ErrorException("数采配置Y轴超出!"); } } } } if (ObjectUtils.isEmpty(xResult) && ObjectUtils.isEmpty(yResult)) { throw new ErrorException("参照物为:" + referx + "与" + refery + "未取到值!请检查数采配置!"); } list.add(yResult); list.add(xResult); } // 进行公式计算 String resultValue = calculationFormula(list, v.get(0)); map.put(k, resultValue); }); return map; } /** * 解析String数据 * @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 xResult = null; // 通过\n将字符串分割为行 String[] aColumnY = processingDataAfterSpaces.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) && aLineX[j].replaceAll(" ", "").contains(referx.replaceAll(" ", ""))) { int x = Integer.parseInt(v.get(config).getX()); try { xResult = aLineX[j + x]; } catch (Exception e) { throw new ErrorException("数采配置X轴超出!"); } } } } if (ObjectUtils.isEmpty(xResult)) { throw new ErrorException("参照物为:" + referx + "未取到值!请检查数采配置!"); } // 结果包含特殊字符,需要剔除掉 if(xResult.contains("=")) { String[] split = xResult.split("="); list.add(split[split.length - 1]); } else if (xResult.contains(":")) { String[] split = xResult.split(":"); list.add(split[split.length - 1].replaceAll("%", "")); } else { list.add(xResult); } } // 进行公式计算 String resultValue = calculationFormula(list, v.get(0)); map.put(k, resultValue); }); return map; } /** * 解析String数据 * @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])) { int x = Integer.parseInt(v.get(config).getX()); try { xResult = aLineX[j + x]; } catch (Exception e) { throw new ErrorException("数采配置X轴超出!"); } } if (ObjectUtils.isNotEmpty(refery) && refery.equals(aLineX[j])) { int y = Integer.parseInt(v.get(config).getY()); String aColumnData = aColumnY[i + y]; // 获取到第Y行的数据 try { yResult = aColumnData.split(splitIdentifier)[j]; } catch (Exception e) { throw new ErrorException("数采配置Y轴超出!"); } } } } if (ObjectUtils.isEmpty(xResult) || ObjectUtils.isEmpty(yResult)) { throw new ErrorException("X轴或Y轴未取到值!请检查数采配置!"); } if(xResult.equals(yResult)) { list.add(xResult); } else { throw new ErrorException("X轴与Y轴取得的数据不相同!请检查数采配置!"); } } // 进行公式计算 String resultValue = calculationFormula(list, v.get(0)); map.put(k, resultValue); }); return map; } }