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> 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<String, List<DataConfig>> userMap = dataConfig.stream().collect(Collectors.groupingBy(DataConfig::getInsProductItem));
|
Map<String, String> 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<String, String> analysisDb(String data, Map<String, List<DataConfig>> dataConfig) {
|
JSONObject jsonObject = JSON.parseObject(data);
|
JSONArray dataList = JSONArray.parseArray(jsonObject.get("data").toString());
|
JSONArray columnList = JSONArray.parseArray(jsonObject.get("column").toString());
|
Map<String, String> map = new HashMap<>();
|
dataConfig.forEach((k, v) -> {
|
List<Object> 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<String, String> analysisMdb(String data, Map<String, List<DataConfig>> 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<String, String> map = new HashMap<>();
|
dataConfig.forEach((k, v) -> {
|
List<Object> 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<String, String> readPngString(String data, Map<String, List<DataConfig>> dataConfig) {
|
Map<String, String> map = new HashMap<>();
|
dataConfig.forEach((k, v) -> {
|
List<Object> 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<String> 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<Object> 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<String, String> analysisTxt(String data, Map<String, List<DataConfig>> dataConfig) {
|
Map<String, String> map = new HashMap<>();
|
dataConfig.forEach((k, v) -> {
|
List<Object> 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<String, String> analysisString(String data, Map<String, List<DataConfig>> dataConfig) {
|
String processingDataAfterSpaces = data.replaceAll(" +", splitIdentifier).replaceAll("\r", "");
|
Map<String, String> map = new HashMap<>();
|
dataConfig.forEach((k, v) -> {
|
List<Object> 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<String, String> analysisList(String data, Map<String, List<DataConfig>> dataConfig) {
|
Map<String, String> map = new HashMap<>();
|
dataConfig.forEach((k, v) -> {
|
List<Object> 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;
|
}
|
}
|