Browse Source

2.0 修改版本

pms 2 years ago
parent
commit
60bd6dfb40

+ 15 - 19
mainFactory/src/main/java/org/bfkj/MainFactoryApplication.java

@@ -44,20 +44,13 @@ public class MainFactoryApplication {
         }
         String systemParams = env.getProperty("systemParams");
         if (Objects.nonNull(systemParams) && !"".equals(systemParams)) {
-            Map<String, Object> inSystemParams = MapTools.stringToMap(systemParams);
+            Map<String, Object> inSystemParams =(Map<String, Object>) MapTools.strToObj(systemParams);
             for (String key : inSystemParams.keySet()) {
                 String keyValue = inSystemParams.get(key).toString().replace("path", path);
-                ObjectMapper mapper = new ObjectMapper();
-                try {
-                    mapper.registerModule(new JavaTimeModule());
-                    if (MapTools.stringToMap(keyValue).isEmpty()) {
-                        systemDefaultParams.put(key, keyValue);
-                    } else {
-                        systemDefaultParams.put(key, mapper.writeValueAsString(MapTools.stringToMap(keyValue)));
-                    }
-                } catch (JsonProcessingException e) {
-                    System.out.println("程序启动,传入参数格式异常");
-                    return;
+                if (Objects.isNull(MapTools.strToObj(keyValue))) {
+                    systemDefaultParams.put(key, keyValue);
+                } else {
+                    systemDefaultParams.put(key,keyValue);
                 }
             }
         }
@@ -89,12 +82,12 @@ public class MainFactoryApplication {
             if (!"".equals(workID) && !"0".equals(workID)) {
                 AppConfig.WORK_ID = workID;
             } else {
-                Map<String, Object> returnKeyValues = myDbHelper.insertReturnKeyValues("insert into deploynode(serviceURL)  values(?)", serviceURL);
+                Map<String, String> returnKeyValues = myDbHelper.insertReturnKeyValues("insert into deploynode(serviceURL)  values(?)", serviceURL);
                 if (returnKeyValues.get("code").equals("-1")) {
                     System.out.println("根据serviceURL新增入库失败: " + ("insert into deploynode(serviceURL)  values(?)") + " 参数: " + serviceURL);
                     return;
                 }
-                AppConfig.WORK_ID = returnKeyValues.get("returnData").toString();
+                AppConfig.WORK_ID = returnKeyValues.get("returnData");
                 if (!MapTools.isNumber(AppConfig.WORK_ID)) {
                     System.out.println("初始化workID异常: " + AppConfig.WORK_ID);
                     return;
@@ -149,7 +142,7 @@ public class MainFactoryApplication {
             returnMap.put("serviceURL", serviceURL);
         }
         if (null != url && null != uname && null != type && null != cipher) {
-            returnMap.put("remote_db_connect", MapTools.jacksonObjToStr(remoteDBConnect));
+            returnMap.put("remote_db_connect", MapTools.objToJSONStr(remoteDBConnect));
         }
         return returnMap;
     }
@@ -284,9 +277,12 @@ public class MainFactoryApplication {
                 ObjectMap.getordropInput(serviceId, false);
             }
         }
-        for (MyDbHelper myDbHelper : ObjectMap.myDbHelperMaps.values()) {
-            String connectStr = myDbHelper.getConnectConfig();
-            ObjectMap.getordropMyDbHelper(connectStr, false);
-        }
+    }
+
+
+    /*1每一分钟手动释放资源*/
+    @Scheduled(cron = "0 1 * * * ?")
+    public void clearGc() {
+        Runtime.getRuntime().gc();
     }
 }

+ 1 - 2
mainFactory/src/main/java/org/bfkj/api/CommonApi.java

@@ -173,8 +173,7 @@ public class CommonApi {
             Map<String, Object> sendData = new HashMap<>();
             sendData.put("serviceId", serviceID);
             sendData.put("dataContent", uploadFile.get("returnData"));
-            commonInterface(tokenMap, sendData, "1");
-            return  MapTools.processSuccess("上传成功");
+            return  commonInterface(tokenMap, sendData, "1");
         }
     }
 }

+ 1 - 1
mainFactory/src/main/java/org/bfkj/application/AuthApplicationImpl.java

@@ -486,7 +486,7 @@ public class AuthApplicationImpl {
                 if (Objects.nonNull(iNDataContent)) {
                     ObjectMapper objectMapper = new ObjectMapper();
                     List<Map<String, Object>> abnormalData = objectMapper.readValue(iNDataContent.toString(), List.class);
-                    dataProcessObj.execCalultion(abnormalData, queryMap.get("calculationLocation").toString(), event, queryMap.get("dataObjectId").toString(), null, null);
+//                    dataProcessObj.execCalultion(abnormalData, queryMap.get("calculationLocation").toString(), event.toString(), queryMap.get("dataObjectId").toString(), null, null);
                 }
             }
             myDbHelper.updateByCondition("delete  from log_error where dataObjectId = ?", deleteIds);

+ 274 - 377
mainFactory/src/main/java/org/bfkj/application/DataProcess.java

@@ -2,75 +2,71 @@ package org.bfkj.application;
 
 
 import org.bfkj.config.AppConfig;
-import org.bfkj.config.ObjectMap;
 import org.bfkj.utils.LogUtils;
 import org.bfkj.utils.MapTools;
 import org.bfkj.utils.MyDbHelper;
 import org.bfkj.utils.ScriptEnginePro;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 
 import java.util.*;
+import java.util.concurrent.ThreadPoolExecutor;
 
-
-/**
- * z
- * 数据收集
- */
-public class DataProcess {
-
-
+public class DataProcess {//数据处理对象
     private String serviceId;//作为实例化服务对象的Key
     private long lastActive; //服务最后活跃时间
     private String errorMessage = null;  //当前数据输入处理对象不可用信息
-    private List<Map<String, Object>> calculationLibraryList;//输出计算库
-    private final Map<String, Integer> serviceErrorCount = new HashMap<>();   //服务错误次数:针对脚本异常
+    private MyDbHelper baseDbHelper = null;//数据底座的数据库服务对象:捆绑到服务实例上,避免并发导致线程不安全
 
-    private final Map<String, ScriptEnginePro> ScriptEngineProMaps = new HashMap<>();//用于缓存当前服务的算法引擎对象,数据库的无需缓存
+    private Map<String, Integer> serviceErrorCount = new HashMap<>();   //服务错误次数:针对脚本异常
 
-    private  final List<String> baseInfo = new ArrayList<>() {{
-        add("serviceId");
-        add("event");
-        add("page");
-        add("pageSize");
-        add("dataObjectId");
-    }};
+    private List<Map<String, Object>> calcList;//缓存计算库配置信息
+    private Map<String, ScriptEnginePro> ScriptEngineProMaps = new HashMap<>();//用于缓存当前服务的算法引擎对象
+    private Map<String, MyDbHelper> calcDbHelperMaps = new HashMap<>();//算法的数据库服务对象:捆绑到服务实例上,避免并发导致线程不安全:多个数据处理服务对象操作同一个对象
 
+    private List<String> serviceAuthMap = new ArrayList<>();//缓存当前服务的安全等级,对应各应用
 
     public DataProcess(String service_Id) {//初始化构造,实例化一个服务对象
         lastActive = System.currentTimeMillis();//默认最后活跃时间
         serviceId = service_Id;
-        MyDbHelper myDbHelper = ObjectMap.getordropMyDbHelper(AppConfig.getSystemParams(AppConfig.REMOTE_DB_CONNECT));
-        if (Objects.nonNull(myDbHelper.getErrorMessage())) {
-            errorMessage = "获取myDbHelper对象异常: " + myDbHelper.getErrorMessage();
-            return;
-        }
-        Map<String, Object> serviceInfoResult = myDbHelper.queryByParamsReturnList("select * from serviceinfo where serviceID = ?", service_Id);//直接数据库查询
-        List<Map<String, Object>> mapList = MapTools.getMapList(serviceInfoResult);
-        if (!serviceInfoResult.get("code").equals("0") || Objects.isNull(mapList) || mapList.isEmpty()) {//查询数据库失败
-            errorMessage = !serviceInfoResult.get("code").equals("0") ? ("查询" + serviceId + "服务配置失败:" + serviceInfoResult.get("message")) : ("未配置服务:" + serviceId);
-            return;
-        }
-        //算法信息
-        String calculationListSql = "SELECT CL.*,DI.*  FROM calculation_library CL  left JOIN datasourceinfo DI ON DI.dataSourceID = CL.datasource_id WHERE CL.service_id  =? order by library_sort,library_id";
-        Map<String, Object> calculationResult = myDbHelper.queryByParamsReturnList(calculationListSql, service_Id);//直接数据库查询
-        calculationLibraryList = MapTools.getMapList(calculationResult);
-        if (!calculationResult.get("code").equals("0")) {//查询数据库失败
-            errorMessage = "查询" + service_Id + "的算法失败:" + calculationResult.get("message");
-        }
-        if (calculationLibraryList == null || calculationLibraryList.isEmpty()) {//查询数据库失败
-            errorMessage = "服务ID " + service_Id + "没有找到对应的算法";
+        try{
+            baseDbHelper = new MyDbHelper(AppConfig.getSystemParams(AppConfig.REMOTE_DB_CONNECT));//获取底座数据库对象
+            if (Objects.nonNull(baseDbHelper.getErrorMessage())) {
+                errorMessage = "获取底座myDbHelper对象异常: ".concat(baseDbHelper.getErrorMessage());
+                return;
+            }
+            //算法信息
+            Map<String, Object> calculationMap = baseDbHelper.queryByParamsReturnList("SELECT CL.*,DI.*  FROM calculation_library CL  left JOIN datasourceinfo DI ON DI.dataSourceID = CL.datasource_id WHERE CL.service_id  =? and  CL.library_type is not null order by library_sort,library_id", service_Id);//直接数据库查询
+            calcList = Objects.isNull(calculationMap.get("returnData"))?null:(List<Map<String, Object>>) calculationMap.get("returnData");
+            if (!calculationMap.get("code").equals("0") || calcList == null || calcList.isEmpty()) {//查询数据库失败
+                errorMessage = "查询".concat(serviceId).concat("的算法失败:").concat(calculationMap.get("message").toString());
+                return;
+            }
+            //获取当前服务的安全等级
+            Map<String, Object> serviceAuth = baseDbHelper.queryByParamsReturnList("SELECT app_id FROM appService WHERE serviceID = ?", service_Id);//直接数据库查询
+            if (!serviceAuth.get("code").equals("0")) {//查询数据库失败
+                errorMessage = "获取".concat(service_Id).concat("的应用安全等级出错:").concat(serviceAuth.get("message").toString());
+                return;
+            }
+            Object serviceAuthList = serviceAuth.get("returnData");//获取服务应用等级   List<Map>    key:字段名,value
+            if (!Objects.isNull(serviceAuthList)) {//将ListMap合并为一个Map,方便使用 // map:{1,appid},{2,appidd}
+                serviceAuthMap = ((List<Map<String, Object>>) serviceAuthList).stream().map(map -> map.get("app_id").toString()).toList();
+            }
+        }catch (Exception e) {
+            errorMessage = "数据处理对象初始化异常: ".concat(serviceId).concat(";异常信息:").concat(LogUtils.getException(e));
         }
     }
-
-    /**
-     * 关闭的连接信息
-     */
+    //数据处理服务对象关闭时,关闭缓存的数据库对象以及脚本引擎对象
     public void close() {//销毁当前服务对象时,需要将缓存的算法引擎实例同步销毁
-        for (ScriptEnginePro scriptEnginePro : ScriptEngineProMaps.values()) {
-            scriptEnginePro.close();
+        for (ScriptEnginePro scriptEnginePro : ScriptEngineProMaps.values()) {//脚本引擎
+            scriptEnginePro.close();//关闭动态方法实例、缓存等
+        }
+        ScriptEngineProMaps.clear();//清除缓存
+        for (MyDbHelper calcMyDbHelper : calcDbHelperMaps.values()) {//数据库对象
+            calcMyDbHelper.close();//关闭数据库连接池
         }
-        ScriptEngineProMaps.clear();
+        calcDbHelperMaps.clear();//清除缓存
+        baseDbHelper.close();//底座数据库对象
     }
-
     //统一成功信息处理
     public Map<String, Object> processSuccess(Object returnData) {
         if (returnData instanceof Map) {
@@ -83,7 +79,6 @@ public class DataProcess {
         returnMap.put("returnData", returnData);
         return returnMap;
     }
-
     //统一错误信息处理
     public Map<String, Object> processFail(String errorMessage, String libraryId) {
         Map<String, Object> returnMap = new HashMap<>();//用于当前方法统一返回参数,不存在深拷贝问题
@@ -94,383 +89,290 @@ public class DataProcess {
         }
         return returnMap;
     }
-
-    //数据收集----目前应该是数据处理
+    //数据处理对外接口
     public Map<String, Object> processData(Map<String, Object> inputData, String... user_id) { //{serviceid:1,datacontent:[{key:value},{key:value}],event:0,page:1,pagesize:10}
-        //事件判断由算法进行,不再作为入口必须条件  ?
         if (!MapTools.isBlank(errorMessage)) {//如果当前服务存在问题,代表数据库对象不可用,此时应该重构当前对象,调用方控制
-            LogUtils.log("processData:1", "-1", null, "服务不可用" + errorMessage, serviceId, AppConfig.WORK_ID, MapTools.jacksonObjToStr(inputData), null, null, null);
-            return processFail("服务不可用" + errorMessage, null);
+            LogUtils.log("processData:1", "-1", null, "服务不可用".concat(errorMessage), serviceId, inputData, null, null, null);
+            return processFail("服务不可用".concat(errorMessage), null);
         }
         if (System.currentTimeMillis() - lastActive > 2000) {  //        更新数据库中的服务最新活跃时间
             lastActive = System.currentTimeMillis();//更新最后活跃时间  //------更新当前服务的最后活跃时间,用于服务监控
-            Runtime.getRuntime().gc();
-            //更新服务的活跃时间
-            MyDbHelper myDbHelper = ObjectMap.getordropMyDbHelper(AppConfig.getSystemParams(AppConfig.REMOTE_DB_CONNECT));
-            if (Objects.nonNull(myDbHelper.getErrorMessage())) {
-                LogUtils.log("processData:2", "-1", null, "数据接收错误,获取远程数据库对象: " + myDbHelper.getErrorMessage(), serviceId, AppConfig.WORK_ID, MapTools.jacksonObjToStr(inputData), null, null, null);
-                return processFail("数据接收错误,获取远程数据库对象: " + myDbHelper.getErrorMessage(), null);
-            }
-            myDbHelper.updateByCondition("update serviceinfo set runState = 1 ,lastactive = now() where  serviceID =?", null, serviceId); // 服务表增加最后活跃时间
+            baseDbHelper.updateByCondition("update serviceinfo set runState = ? ,lastactive = ? where  serviceID =?", null, "1", lastActive, serviceId); // 服务表增加最后活跃时间
         }
         //创建生命周期ID;//默认继承
         if (!inputData.containsKey("dataObjectId")) {
-//            生成新的生命周期ID
-            inputData.put("dataObjectId", createLifeCycleCol(Long.valueOf(AppConfig.WORK_ID), Integer.parseInt(serviceId)));
+            inputData.put("dataObjectId", createLifeCycleCol(Long.valueOf(AppConfig.WORK_ID), Integer.parseInt(serviceId))); // 生成新的生命周期ID
         }
-        String dataObjectId = (String) inputData.get("dataObjectId");
-        Object event = inputData.get("event"); //  服务表新增一个字段:用于标识当前服务支持的事件,用于限制入参的事件
-
-        //初始化 列权限为空
-        // 如果存在用户编号 且事件为查询
-        //通过用户编号,服务编号,从用户权限表获取行列权限
-        // 如果列权限为空则 直接返回空
-        // 重新组建入口参数:添加filter(行权限)
-        if (!event.equals("1") && Objects.nonNull(user_id) && inputData.containsKey("auth_id")) {
-            MyDbHelper myDbHelper = ObjectMap.getordropMyDbHelper(AppConfig.getSystemParams(AppConfig.REMOTE_DB_CONNECT));
-            if (Objects.nonNull(myDbHelper.getErrorMessage())) {
-                LogUtils.log("processData:2", "-1", null, "数据接收错误,获取远程数据库对象: " + myDbHelper.getErrorMessage(), serviceId, AppConfig.WORK_ID, MapTools.jacksonObjToStr(inputData), null, null, null);
-                return processFail("数据接收错误,获取远程数据库对象: " + myDbHelper.getErrorMessage(), null);
-            }
-            Map<String, Object> authServiceMap = myDbHelper.queryByParamsReturnList("SELECT auth_id FROM t_auth WHERE serviceID = ? and auth_id = ? ", serviceId, inputData.get("auth_id"));
-            if (authServiceMap.get("code").equals("-1") || (authServiceMap.get("returnData") instanceof List<?> returnDataList && returnDataList.isEmpty())) return authServiceMap;
-            //判断filter不为空 且 filter不包含left---{"filter":[{"user_id":""}]} ---- >[{filter:[{left:,column:},{left:,column:}
-            /*获取权限filter*/
-            Map<String, Object> userDataAuthMap = myDbHelper.queryByParamsReturnList("SELECT QCS.columnName,TUA.row_auth FROM t_user_group_auth  TUA LEFT JOIN querytemplatecolumnset QCS on TUA.queryTemplateColumnSetID = QCS.queryTemplateColumnSetID WHERE TUA.user_id = ?  AND TUA.auth_id = ? AND TUA.queryTemplateColumnSetID IS NOT NULL", user_id[0], inputData.get("auth_id"));
-            if (userDataAuthMap.get("code").equals("-1")) return userDataAuthMap;
-            List<Object> userList = new ArrayList<>();
-            ((List<Map<String, Object>>) userDataAuthMap.get("returnData")).stream().filter(map -> Objects.nonNull(map.get("row_auth"))).forEach(tempMap -> {
-                String[] row_auths = tempMap.get("row_auth").toString().split(",");
-                for (String row_auth : row_auths) {
-                    if (Objects.isNull(row_auth)) continue;
-                    HashMap<String, Object> hashMap = new HashMap<>();
-                    hashMap.put(tempMap.get("columnName").toString(), row_auth.startsWith("!") ? row_auth.substring(1) : row_auth);
-                    if (row_auth.startsWith("!")) {
-                        userList.addAll(changeSignFilter(hashMap, "!", "or"));
-                    } else {
-                        userList.addAll(changeSignFilter(hashMap, null, "or"));
-                    }
-                }
-            });
-            /*userList第一个以及最后一个添加()*/
-            ((Map<String, Object>) userList.get(0)).put("left", "(");
-            ((Map<String, Object>) userList.get(userList.size() - 1)).put("connector", "  and ");
-            ((Map<String, Object>) userList.get(userList.size() - 1)).put("right", " ) ");
-            inputData = initParam(inputData, "0", userList);
-        }
-
-        List<Map<String, Object>> calculationResult = new ArrayList<>();//定义算法全量结果列表
-        calculationResult.add(inputData);//默认接收数据为第0个算法的结果
-        Map<String, List<Map<String, Object>>> execResult = execCalultion(calculationResult, null, event, dataObjectId, inputData.get("page"), inputData.get("pageSize"));
-        calculationResult = execResult.get("calcData");//执行当前服务对应的算法库
-        Map<String, Object> lastResult = calculationResult.get(calculationResult.size() - 1);//获取最后一个计算结果
-        String libraryId = lastResult.containsKey("library_id") ? lastResult.get("library_id").toString() : null;
+        String dataObjectId = inputData.get("dataObjectId").toString();
+        inputData = authCheck(inputData, user_id); /*权限检查,添加列权限以及行权限到inputData中*/
+        List<Map<String, Object>> calcData = new ArrayList<>();//定义算法全量结果列表
+        calcData.add(inputData);//默认入口参数为第0个算法的结果
+        Map<String, Object> execResult = execCalultion(calcData, null, dataObjectId);//执行所有的算法库
+        String library_id = execResult.get("library_id").toString();//获取最后一个算法的编号
+        List<Map<String, Object>> preListData = (List<Map<String, Object>>) execResult.get("preData");//获取所有的前置检测结果
+        calcData = (List<Map<String, Object>>) execResult.get("calcData");//所有的算法结果
+        //依据算法编号规则确定最后一个算法结果,是前置还是算法
+        Map<String, Object> lastResult = library_id.endsWith("N")?preListData.get(preListData.size() - 1):calcData.get(calcData.size() - 1);//获取最后一个计算结果
         if (Objects.equals(lastResult.get("code"), "-1")) {//最后一个计算结果为-1则记录异常,否则全部记录正常
             Object message = lastResult.get("message");
-            LogUtils.log("processData:3", "-1", libraryId, Objects.nonNull(message) ? message.toString() : null, serviceId, AppConfig.WORK_ID, MapTools.jacksonObjToStr(calculationResult), dataObjectId, MapTools.jacksonObjToStr(execResult.get("calcData")), event);
-            setServiceErrorCount(libraryId, serviceId, "-1");//标记错误的算法:连续错误累加
-            return processFail(libraryId + "数据计算错误:" + lastResult.get("message"), libraryId);
+            LogUtils.log("processData:3", "-1", library_id, Objects.nonNull(message)?message.toString():null, serviceId, calcData, dataObjectId, preListData, inputData.get("event"));
+            return processFail(library_id.concat("数据计算错误:").concat(lastResult.get("message").toString()), library_id);
         }
         //写入 成功日志
-        LogUtils.log("DataProcess:9999", "0", libraryId, "数据接收后处理成功", serviceId, AppConfig.WORK_ID, MapTools.jacksonObjToStr(calculationResult), dataObjectId, MapTools.jacksonObjToStr(execResult.get("calcData")), event);  //此处无法把所有的记过集返回过去
-        // 如果列权限不为空
-        // 循环lastResult
-        // 遍历map
-        // 如果key不在列权限则删除
-        List<Map<String, Object>> collect = calculationResult.stream().filter(map -> Objects.isNull(map.get("library_id")) || !map.get("library_id").toString().contains("_N")).toList();
-        return processSuccess(collect.get(collect.size() - 1));
+        LogUtils.log("DataProcess:9999", "0", library_id, "数据接收后处理成功", serviceId, calcData, dataObjectId, preListData, inputData.get("event"));  //此处无法把所有的记过集返回过去
+        return processSuccess(lastResult); /*可订阅任意算法结果,也可以订阅全量结果,由最后一个算法决定*/
     }
-
-
-    private  Map<String, Object> initParam(Map<String, Object> inputData, String event, List<Object> authList) { //  authList 转换:left过后的
-        Object dataContent = inputData.get("dataContent");//这个就是最终的dataContent,所有的变化都是针对它进行
-        if (Objects.isNull(dataContent)) {//如果为空则默认为inputData中除去常规变量的其它变量,最终可以是一个空Map
-            Map<String, Object> tempDataContent = new HashMap<>(inputData);//因为inputData并不会发生变化,所以使用浅拷贝即可:
-            baseInfo.forEach(tempDataContent.keySet()::remove);//移除常规不参与计算的键值
-            dataContent = tempDataContent;//处理为Map,后续继续处理
-        }
-        if (dataContent instanceof Map<?, ?> dataContentMap) {//如果是一个Map则转数组
-            List<Map<?, ?>> tempDataContent = new ArrayList<>();//初始化一个数组
-            tempDataContent.add(dataContentMap);
-            dataContent = tempDataContent;
+    /*权限检查*/
+    public Map<String, Object> authCheck(Map<String, Object> inputData, String... user_id) {
+        Object appid = inputData.get("appid");//获取应用编号
+        if (Objects.nonNull(appid) && !serviceAuthMap.contains(appid.toString())) {//上传了应用编号但是不在当前服务授权的应用列表中则返回错误
+            return processFail("服务未授权", null);
         }
-        if (dataContent instanceof List dataContentList) {//如果是一个数组则循环转标准格式
-            List<Map<String, Object>> returnDataContent = new ArrayList<>();
-            for (Object signDataContent : dataContentList) {//循环List
-                if (!(signDataContent instanceof Map)) return inputData;  //如果不是一个Map则不进行处理
-                returnDataContent.add(createStandardParameters((Map<String, Object>) signDataContent, event, authList));  //得到Filter里面的内容
-            }
-            dataContent = returnDataContent;
-        }
-        inputData.put("dataContent", dataContent);
-        return inputData;//
-    }
-
-    @SuppressWarnings("unchecked")
-    private  Map<String, Object> createStandardParameters(Map<String, Object> inDataContent, String event, List<Object> authList) {
-        Map<String, Object> returnData = new HashMap<>();//创建返回值returnData{}
-        if ("1,2".contains(event)) {//如果事件是新增或更新则(查询和删除无需处理value)
-            Object tempValueObject = inDataContent.get("Value");//获取Value----{c1:"123",c2:}
-            if (Objects.isNull(tempValueObject)) {//如果入参数inDataContent不包含Value则等于整个inDataContent --   //处理value
-                HashMap<String, Object> tempValue = new HashMap<>(inDataContent);//深拷贝
-                tempValue.remove("filter");//先移除filter,理论上不存在
-                tempValueObject = tempValue;
-            }
-            returnData.put((tempValueObject instanceof Map) ? "Value" : "newValue", tempValueObject);//重命名避免后期处理错误
-        }
-        if (!("1".equals(event))) {//如果事件不是新增(新增无需处理filter)
-            Object tempFilterObject = inDataContent.get("filter");//获取filter
-            tempFilterObject = Objects.isNull(tempFilterObject) ? inDataContent : tempFilterObject;//如果不存在filter则等于原始MAP
-            if (tempFilterObject instanceof Map) {////如果filter是单个Map则
-                authList.addAll(changeSignFilter((Map<String, Object>) tempFilterObject, null, null));
-                returnData.put("filter", authList);//转换为标准条件集
-            } else {
-                if (tempFilterObject instanceof List tempFilterObjectList && tempFilterObjectList.get(0) instanceof Map) {//如果filter是List则"123"
-                    List<Object> tempFilterList = new ArrayList<>(authList);
-                    for (Object o : tempFilterObjectList) {//循环List -{c1:c2,c3:c4}
-                        tempFilterList.addAll(changeSignFilter((Map<String, Object>) o, null, null)); //循环添加
-                    }
-                    returnData.put("filter", tempFilterList);//转换为标准条件集
-                } else {//此时tempFilterObject既不是List也不是Map:1、dataContent包含filter且filter是一个字符串
-                    returnData.put("newFilter", tempFilterObject);
+        /*在构造函数中获取超级用户名单,方便此处的判定*/
+        if (Objects.nonNull(user_id) && inputData.containsKey("authId") && !"1,9999".contains(user_id[0])) {//用户编号不为空,权限编号不为空,不是超级用户
+            Map<String, Object> userDataAuthMap = baseDbHelper.queryByParamsReturnList("SELECT QCS.columnName,TUA.row_auth FROM t_user_group_auth  TUA LEFT JOIN querytemplatecolumnset QCS on TUA.queryTemplateColumnSetID = QCS.queryTemplateColumnSetID WHERE TUA.user_id = ?  AND TUA.auth_id = ? AND TUA.queryTemplateColumnSetID IS NOT NULL", user_id[0], inputData.get("authId"));
+            if (userDataAuthMap.get("code").equals("-1") || Objects.isNull(userDataAuthMap.get("returnData")) || ((List<Map<String, Object>>) userDataAuthMap.get("returnData")).isEmpty()) {
+                if (userDataAuthMap.get("code").equals("0")) {
+                    userDataAuthMap.put("message", "服务未授任何数据权限");
                 }
+                return userDataAuthMap;
             }
-        }
-        return returnData;//返回组建好的参数
-    }
-
-    private  List<Map<String, Object>> changeSignFilter(Map<String, Object> filterMap, String compare, String connect) {
-        List<Map<String, Object>> objects = new ArrayList<>();
-        if (filterMap.containsKey("left")) {
-            objects.add(filterMap);
-            return objects;
-        }
-        for (String filterKey : filterMap.keySet()) {
-            Map<String, Object> returnMap = new HashMap<>();
-            Object keyValues = filterMap.get(filterKey);
-            returnMap.put("left", "");
-            returnMap.put("column", filterKey);
-            returnMap.put("comparator", (Objects.nonNull(compare) && compare.startsWith("!")) ? "!=" : " = ");
-            if (Objects.isNull(keyValues)) {
-                returnMap.put("comparator", " is null ");
+            List<Map<String, Object>> rowAuth = new ArrayList<>();//初始化行权限
+            List<String> authColumn = new ArrayList<>();//初始化列权限
+            List<Map<String, Object>> dataAuth = (List<Map<String, Object>>) userDataAuthMap.get("returnData");
+            dataAuth.forEach(dataAuthMap -> {//循环获取到的权限
+                String columnName = dataAuthMap.get("columnName").toString();//字段名
+                authColumn.add(columnName);//添加到列权限
+                Object rowAuthObj = dataAuthMap.get("row_auth");//获取对应列的行权限
+                if (Objects.nonNull(rowAuthObj)) {//如果存在则组建标准的限制条件
+                    String tempRowAuth = rowAuthObj.toString();
+                    String connect = tempRowAuth.startsWith("!") ? "!=" : "=";//如果首位是!代表不等于,否则代表等于
+                    tempRowAuth = tempRowAuth.startsWith("!") ? tempRowAuth.substring(1) : tempRowAuth;//修订行权限表达式
+                    String[] row_auths = tempRowAuth.split(","); //按,号进行分组!PEK,
+                    for (String row_auth : row_auths) {//循环进行标准化
+                        if (MapTools.isBlank(row_auth)) continue;//为空不设置--误操作填写了空格或者删除未设置为NULL
+                        Map<String, Object> signRowAuth = new HashMap<>();
+                        signRowAuth.put(columnName, row_auth);
+                        rowAuth.addAll(baseDbHelper.changeSignFilter(signRowAuth, connect, connect.equals("!=") ? "and" : "or"));
+                    }
+                    if (rowAuth.size() > 0) {//存在行权限则进行括号包裹
+                        rowAuth.get(0).put("left", "(");
+                        rowAuth.get(rowAuth.size() - 1).put("connector", "  and ");
+                        rowAuth.get(rowAuth.size() - 1).put("right", " ) ");
+                    }   //(c1 = pek )
+                 }
+            });
+            if (rowAuth.size() > 0) {//存在行权限则进行括号包裹
+                rowAuth.get(0).put("left", "(".concat(rowAuth.get(0).get("left").toString()));
+                rowAuth.get(rowAuth.size() - 1).put("connector", "  and ");
+                rowAuth.get(rowAuth.size() - 1).put("right", " ) ".concat(rowAuth.get(rowAuth.size() - 1).get("right").toString()));
+                inputData.put("rowAuth", rowAuth);//添加到入参,方便后面调用
             }
-            returnMap.put("value", keyValues);
-            returnMap.put("right", "");
-            returnMap.put("connector", Objects.nonNull(connect) ? (" " + connect) : " and ");
-            objects.add(returnMap);
+            inputData.put("authColumn", authColumn);//添加到入参,方便后面调用
         }
-        return objects;
+        return inputData;
     }
-
-    public Map<String, List<Map<String, Object>>> execCalultion(List<Map<String, Object>> inData, String beginLibraryId, Object event, String dataObjectId, Object page, Object pageSize) {
-        Map<String, List<Map<String, Object>>> returnData = new HashMap<>();
-        List<Map<String, Object>> preData = new ArrayList<>();
-        List<Map<String, Object>> calcData = Objects.isNull(inData) || inData.isEmpty() ? new ArrayList<>() : inData;
-//        long l2 = System.currentTimeMillis();
-        for (Map<String, Object> calculationLibrary : calculationLibraryList) {//循环算法库
-//            long l = System.currentTimeMillis();
-            String library_id = calculationLibrary.get("library_id").toString();//算法编号
-            if (MapTools.isNotBlank(beginLibraryId) && !beginLibraryId.equals(library_id)) {
+    /*执行算法*/
+    public Map<String, Object> execCalultion(List<Map<String, Object>> inData, String beginLibraryId, String dataObjectId) {
+        Map<String, Object> returnData = new HashMap<>();//初始化最终返回结果
+        List<Map<String, Object>> preData = new ArrayList<>();//初始化前置检测结果列表
+        String lastLibraryId = "";//初始化最后一个算法的编号
+        List<Map<String, Object>> calcData = Objects.isNull(inData) || inData.isEmpty() ? new ArrayList<>() : inData;//默认算法全量计算结果等于入口参数
+        Map<String, Object> preCalMap = new HashMap<>();//用于组建前置检测算法配置
+        for (Map<String, Object> calculationLibrary : calcList) {//循环算法库
+            lastLibraryId = calculationLibrary.get("library_id").toString();//当前进行的算法编号
+            if (MapTools.isNotBlank(beginLibraryId) && !beginLibraryId.equals(lastLibraryId)) {
                 continue;//如果异常恢复开始算法编号不为空且不等于当前循环的算法编号则跳过
             }
             beginLibraryId = null;//为避免异常恢复开始后的后续算法编号不等于当前循环的算法编号的跳过
-            String library_type = calculationLibrary.get("library_type").toString();
-            String service_id = calculationLibrary.get("service_id").toString();
-            String computing_expression = MapTools.objectToString(calculationLibrary.get("computing_expression"));
-            Object is_exec = calculationLibrary.get("is_exec");
-            Map<String, Object> currentResult;
-            if (Objects.nonNull(is_exec)) {
-                Map<String, Object> preCalMap = new HashMap<>();
-                preCalMap.put("library_id", library_id + "_N");
-                preCalMap.put("service_id", service_id);
-                preCalMap.put("library_type", 2);
-                preCalMap.put("computing_expression", is_exec); //
-                Map<String, Object> preEnginResult = execEngine(preCalMap, calcData, dataObjectId);   //todo 前置算法的结果添加到里面 ,在数据恢复时,是否会恢复成功呢
-                preEnginResult.put("library_id", library_id + "_N");// 补充算法编号,方便上层处理异常
-//                inData.add(preEnginResult);
-                preData.add(preEnginResult);
-                returnData.put("preData", preData);
-                //如果code为-1 则表示脚本计算错误 退出计算;如果code为2 则后续算法都不执行
-                if ("-1".equals(preEnginResult.get("code")) || Objects.equals("2", preEnginResult.get("returnData"))) { //执行错误
-                    return returnData;
+            Object is_exec = calculationLibrary.get("is_exec");//获取前置检测表达式
+            if (Objects.nonNull(is_exec) && !MapTools.isBlank(is_exec.toString())) {//存在则进行前置检测
+                lastLibraryId = lastLibraryId.concat("_N");//修订算法编号,避免与正式算法冲突
+                preCalMap.put("library_id", lastLibraryId);//组建前置算法配置信息
+                preCalMap.put("library_type", 2);/*如果脚本包含function则js否则java*/
+                preCalMap.put("computing_expression", is_exec); //组建前置算法配置信息
+                Map<String, Object> preEnginResult = execEngine(lastLibraryId, preCalMap, calcData);//调用算法引擎进行执行
+                preData.add(preEnginResult);//添加执行结果到前置检测结果列表
+                setServiceErrorCount(lastLibraryId, preEnginResult.get("code").toString());//依据返回的code进行连续错误计数和重置
+                if ("-1".equals(preEnginResult.get("code")) || Objects.equals("2", preEnginResult.get("returnData"))) {
+                    break; //如果code为-1 则表示脚本计算错误 退出计算;如果code为2 则后续算法都不执行
                 }
-                setServiceErrorCount(library_id + "_N", serviceId, "0");
                 if (Objects.equals("1", preEnginResult.get("returnData"))) { //前置检查不通过,当前算法不执行,后续 还需执行
+                    calcData.add(null);//自动添加算法空结果,避免数据订阅时的序号出现错误
                     continue;
                 }
+                lastLibraryId = calculationLibrary.get("library_id").toString();//当前进行的算法编号
             }
-            if (library_type.equals("3")) {//数据库算法
-                String connectConfig = calculationLibrary.get("connectConfig").toString();//数据库链接字符串
-                MyDbHelper myDbHelper = ObjectMap.getordropMyDbHelper(connectConfig);//获取对应连接的数据库处理对象
-                if (Objects.nonNull(myDbHelper.getErrorMessage())) {//获取出错
-                    calcData.add(processFail("算法获取数据库连接异常:" + myDbHelper.getErrorMessage(), library_id));
-                    returnData.put("calcData", calcData);
-                    return returnData;
-                }
-                //目标对象名(表名)
-                String tableName = Objects.isNull(calculationLibrary.get("sourceObjectName")) ? null : calculationLibrary.get("sourceObjectName").toString();
-                Object isActiveTable = calculationLibrary.get("isActiveTable");//是否动态表
-                //指定当前算法事件
-                String eventFlag = Objects.isNull(calculationLibrary.get("event")) ? (MapTools.isNotBlank(tableName) ? event.toString() : AppConfig.staticEvent.get(Objects.requireNonNull(computing_expression).trim().toLowerCase().substring(0, 6))) : calculationLibrary.get("event").toString();
-                if (null == eventFlag) {
-                    calcData.add(processFail("事件标志为空", library_id));
-                    returnData.put("calcData", calcData);
-                    return returnData;
-                }
-                //算法取参
-                List<Map<String,Object>> dbPrams = new ArrayList<>();
-                Object tempDBPrams = null;
-                try {//添加try捕获异常
-                    if (Objects.isNull(calculationLibrary.get("parmIndex"))) {//未配置取参则默认取上一个算法
-                        Map<String, Object> tempMap = calcData.get(calcData.size() - 1);
-                        tempDBPrams = tempMap.containsKey("dataContent") ? tempMap.get("dataContent") : tempMap.get("returnData");
-                    } else {//算法取值位置表达式不为空
-                        tempDBPrams = calcData;//默认等于全量参数
-                        String[] parmSplit = calculationLibrary.get("parmIndex").toString().split("\\.");//按.进行分割
-                        for (String item : parmSplit) {//循环提取参数
-                            if (MapTools.isNumber(item) && tempDBPrams instanceof List<?> tempList) {//数字代表数组中的位置
-                                tempDBPrams = tempList.get(Integer.parseInt(item));
-                            } else {
-                                if (tempDBPrams instanceof Map<?,?> tempMap){
-                                    tempDBPrams = tempMap.get(item);
-                                }
-                            }
-                        }
-                    }
-                    if (tempDBPrams instanceof Map tempMap) {//最终参数是Map则转换为List<Map<String, Object>>
-//                        if (tempMap.isEmpty()) {
-//                            calcData.add(new HashMap<>());
-//                            returnData.put("calcData", calcData);
-//                            return returnData;
-//                        }
-                        dbPrams.add(tempMap);
-                    } else if (tempDBPrams instanceof List tempList) {
-//                        if (tempMap.isEmpty()) {
-//                            calcData.add(new HashMap<>());
-//                            returnData.put("calcData", calcData);
-//                            return returnData;
-//                        }
-                        dbPrams = tempList;
-                    }
-                } catch (Exception e) {
-                    calcData.add(processFail("入参数据格式错误:不是List<Map<String,Object> " + tempDBPrams, library_id));
-                    returnData.put("calcData", calcData);
-                    return returnData;
-                }
-                // 事件6 在算法表中的event定义,实现自动的新增或更新
-                if (eventFlag.equals("6")) {
-                    currentResult = myDbHelper.insertOrUpdate(tableName, dbPrams);
-                } else {
-                    if (eventFlag.equals("7")){
-                        currentResult = myDbHelper.bathEvent7(computing_expression, dbPrams);
-                    }else {
-                        currentResult = myDbHelper.generalProcess(eventFlag, tableName, computing_expression, null, dbPrams, Objects.nonNull(isActiveTable) && Objects.equals(isActiveTable, "true"), page, pageSize);
-                    }
-                }
-            } else {
-                currentResult = execEngine(calculationLibrary, inData, dataObjectId);
+            //依据算法类型调用数据库对象或脚本引擎对象进行算法执行
+            Map<String, Object> currentResult = calculationLibrary.get("library_type").toString().equals("3") ? execDB(lastLibraryId, calculationLibrary, inData, dataObjectId) : execEngine(lastLibraryId, calculationLibrary, inData);
+            setServiceErrorCount(lastLibraryId, Objects.nonNull(currentResult) && currentResult.containsKey("code") ? currentResult.get("code").toString() : "0");//依据返回的code进行连续错误计数和重置
+            calcData.add(currentResult);//添加到全量算法结果中
+            if (Objects.nonNull(currentResult) && !currentResult.get("code").equals("0")) {//算法执行异常则退出
+                break;
             }
-//            if (!currentResult.get("code").equals("0")) {//算法执行异常
-//                currentResult.put("library_id", library_id);
-//            }
-            currentResult.put("library_id", library_id);
-            calcData.add(currentResult);
-            returnData.put("calcData", calcData);
-//            System.out.println("算法ID : " + library_id + "  执行时间为:" + (System.currentTimeMillis() - l));
-            setServiceErrorCount(library_id, serviceId, "0");    ///  错误次数恢复??
         }
-//        System.out.println("服务ID : " + serviceId + "  执行时间为:" + (System.currentTimeMillis() - l2));
+        returnData.put("library_id", lastLibraryId);
+        returnData.put("preData", preData);
+        returnData.put("calcData", calcData);
         return returnData;
     }
-
-    /**
-     * 算法连续错误次数判定
-     *
-     * @param location
-     * @param serviceId
-     * @param success
-     */
-    public  void setServiceErrorCount(String location, String serviceId, String success) {
-        String key = String.format("processData %s_%s", location, serviceId);
-        if (!success.equals("0")) {
-            Integer errCount = serviceErrorCount.get(key);
-            errCount = (null == errCount) ? 1 : errCount + 1;
-            serviceErrorCount.put(key, errCount);
-            if (errCount > AppConfig.SERVICE_ERR_MAX) {
-                ServiceInputControl.stop(serviceId);
-            }
-        } else {
-           serviceErrorCount.put(key, 0);
-        }
-    }
-
-    private Map<String, Object> execEngine(Map<String, Object> currentCalMap, List<Map<String, Object>> allData, String dataObjectId) {
-        String library_id = currentCalMap.get("library_id").toString();//获取算法编号
+    //脚本引擎执行
+    private Map<String, Object> execEngine(String library_id, Map<String, Object> currentCalMap, List<Map<String, Object>> calcAllData) {
         if (!ScriptEngineProMaps.containsKey(library_id)) {//不存在缓存则创建
             ScriptEngineProMaps.put(library_id, new ScriptEnginePro(currentCalMap));
         }
         ScriptEnginePro currentEngin = ScriptEngineProMaps.get(library_id);//依据算法编号获取算法引擎
-        if (Objects.nonNull(currentEngin) && Objects.nonNull(currentEngin.getErrorMessage())) {//获取错误引擎
+        String errMessage = "";
+        if (Objects.nonNull(currentEngin) && Objects.nonNull(currentEngin.getErrorMessage())) {//获取引擎出错则进行关闭
+            errMessage = currentEngin.getErrorMessage();
             currentEngin.close();
             currentEngin = null;
+        }
+        if (Objects.isNull(currentEngin)) {//未获取到引擎则返回异常
             ScriptEngineProMaps.remove(library_id);
+            return processFail("创建引擎失败".concat(errMessage), library_id);
         }
-        if (Objects.isNull(currentEngin) || Objects.nonNull(currentEngin.getErrorMessage())) {
-            return processFail("创建引擎失败" + (Objects.nonNull(currentEngin) ? currentEngin.getErrorMessage() : ""), library_id);
+        Map<String, String> parmaNames = currentEngin.getParmaNames();//获取对应脚本订阅的变量列表/*依据当前算法 数据订阅规则 进行数据的提取*/
+        Map<String, Object> paramValue = new HashMap<>();
+        for (String key : parmaNames.keySet()) {//理论上此处最多单个key是list[],如果存在多个list[]则应开启迪卡乘积
+            Object currentData = dataSubscription(calcAllData, key, currentCalMap);//获取数据
+            //if(key.indexOf("[") > 0){//订阅规则明确开启线程:String[3] 代表开启3个线程执行;Map[col1] 代表按COL1数据分组数开启多线程执行
+            //开启多线程操作同一个脚本对象会存在数据污染情况,除非开启多线程时,每个线程对应一个独立脚本对象,或者脚本对象做了数据隔离,目前解析并没有出现性能瓶颈,暂时不考虑
+            //}else{
+            if (currentCalMap.get("library_type").toString().equals("2")){
+                paramValue.put(parmaNames.get(key), currentData);
+            }else {
+                paramValue.put(key, currentData);
+            }
+            //}
         }
-        return currentEngin.execScript(allData);
+        return currentEngin.execScript(paramValue);
     }
+    //数据库算法执行
+    private Map<String, Object> execDB(String library_id, Map<String, Object> calculationLibrary, List<Map<String, Object>> calcData, String dataObjectId) {
+        Object connectConfigObj = calculationLibrary.get("connectConfig");
+        if (Objects.isNull(connectConfigObj)) {
+            return processFail("连接信息未配置 ", library_id);
+        }
+        if (!calcDbHelperMaps.containsKey(library_id)) {//不存在缓存则创建
+            calcDbHelperMaps.put(library_id, new MyDbHelper(connectConfigObj.toString()));
+        }
+        MyDbHelper myDbHelper = calcDbHelperMaps.get(library_id);//依据算法编号获取数据库处理对象
+        String errMessage = "";
+        if (Objects.nonNull(myDbHelper) && MapTools.isNotBlank(errMessage)) {//获取出现错误则进行关闭
+            errMessage = myDbHelper.getErrorMessage();
+            myDbHelper.close();
+            myDbHelper = null;
+        }
+        if (Objects.isNull(myDbHelper)) {//未获取到则返回异常
+            calcDbHelperMaps.remove(library_id);
+            return processFail("获取业务数据库对象失败".concat(errMessage), library_id);
+        }
+        //未指定订阅则默认为上一个算法的结果:
+        String paramIndex = Objects.isNull(calculationLibrary.get("parmIndex")) ? (String.valueOf(calcData.size() - 1)).concat(".returnData") : calculationLibrary.get("parmIndex").toString();
+        Object tempDBPrams = dataSubscription(calcData, "List.".concat(paramIndex), calculationLibrary);//获取数据订阅结果
+        //如果表名和SQL同时不为空且事件为7则,分解为先查询,后更新方式,可以有效使用预编译,性能会更高
+        //事件7的select应该是固定为书名号方式,而不是动态组建方式,因为要跟insert或update对应,如果是动态条件则不使用事件7而是采用算法分离方式进行
+        if("7".equals(calculationLibrary.get("event")) && !Objects.isNull(calculationLibrary.get("tableName")) && !Objects.isNull(calculationLibrary.get("computing_expression"))){
+            Map<String,Object> tempCalcInfo = calculationLibrary;
+            String tableName = tempCalcInfo.get("tableName").toString();//先记录表名
+            String sqlStr = tempCalcInfo.get("computing_expression").toString();//记录SQL语句,方便获取查询条件,用于组建事件6的filter
+            tempCalcInfo.put("tableName","");//清空表名,方便执行SQL
+            tempDBPrams = myDbHelper.generalProcess(tempCalcInfo, tempDBPrams, dataObjectId, calcData.get(0));//先执行sql获取结果后
+            //从myDbHelper获取sqlStrVarList.get(sqlStr)可以获取到查询条件,用于组建事件6的filter
+            //获取tempDBPrams,循环returnData,添加filter,否则无法执行事件6
+            tempCalcInfo.put("tableName",tableName);//还原表名
+            tempCalcInfo.put("computing_expression","");//清除SQL
+            tempCalcInfo.put("event","6");//执行新增或更新
+            return myDbHelper.generalProcess(tempCalcInfo, tempDBPrams, dataObjectId, calcData.get(0));//调用表名方式执行事件
+        }
+        return myDbHelper.generalProcess(calculationLibrary, tempDBPrams, dataObjectId, calcData.get(0));
+    }
+    /*数据订阅:注意因前置导致算法未执行时,全量结果集的序号会存在问题*/
+    private Object dataSubscription(List<Map<String, Object>> calcAllData, String paramRule, Map<String, Object> calculationLibrary) { // List.1.returnData
+        String[] itemRule = paramRule.split("\\.");//订阅规则按.进行分割
+        String dataType = itemRule.length > 0 ? itemRule[0] : "List"; //首位是最终返回的数据类型
+        dataType = dataType.endsWith("]")?dataType.substring(0,dataType.indexOf("[")):dataType;//订阅时需要把[]去掉,在调用脚本引擎时进行分解
+        String dataLocation = itemRule.length > 1 ? itemRule[1] : ""; //数据位置:代表从哪个算法结果中进行取值
+        if (dataLocation.equals("T")) {//固定参数 //JSON.T.{"BSM":""}----String.T.代表"",List.T.代表[],Map.T.代表{},任意类型.T代表null
+            Object tempObj = itemRule.length > 2 ? MapTools.isBlank(itemRule[2])?("List".equals(dataType)?new ArrayList<>():("JSON,Map".contains(dataType)?new HashMap<>():null)):itemRule[2]:null;
+            if ("Boolean".equals(dataType)){
+                tempObj =  itemRule[2].equals("true");
+            }
+            return tempObj;
 
-    /**
-     * 支持的最大机器id,结果是31 (这个移位算法可以很快计算出几位二进制数所能表示的最大十进制数)
-     */
-    private final  String maxWorkerId = "4";
-    /**
-     * 支持的最大数据标识id,结果是31
-     */
-    private final  String maxServiceId = "4";
-    /**
-     * 毫秒内序列(0~4095)
-     */
-    private  final Long maxSequence = 999L;
-
-    private  long sequence = 0L;
-
-    /**
-     * 上次生成ID的时间截
-     */
-    private  long lastTimestamp = -1L;
-
-    /**
-     * 生命周期ID生成
-     *
-     * @param workerId
-     * @param serviceId
-     * @return
-     */
-    public  String createLifeCycleCol(Long workerId, Integer serviceId) {
+        }
+        //如果是L则从算法配置信息中获取,否则从全量计算结果中获取
+        Object returnData = dataLocation.equals("L") ? calculationLibrary : MapTools.isNumber(dataLocation) ? calcAllData.get(Integer.parseInt(dataLocation)) : null; // String.L.connectConfig.username
+        for (int index = 2; index < itemRule.length; index++) {
+            if(Objects.isNull(returnData)) return null;
+            if (returnData instanceof String) {//如果获取的是字符串则自动转MAP--XML字符串也自动转Map
+                returnData = MapTools.strToObj(returnData.toString());//  1.  简单字符串 , 2. map字符串 3. List字符串
+            }
+            if (MapTools.isNumber(itemRule[index])) {//数字代表从当前参数中取第N位,如果当前参数并不是List应该返回全部不应该返回空
+                //
+                returnData = returnData instanceof List ? ((List<?>) returnData).get(Integer.parseInt(itemRule[index])) : returnData;
+            } else {//不是数字代表从当前参数中取对应的键,如果当前参数是List应该返回List中首个对应的键值
+                if(returnData instanceof Map){//是MAP则直接获取对应Key的值
+                    returnData = ((Map<?, ?>) returnData).get(itemRule[index]);
+                }else{//简单的错误兼容,尤其是某些时候数据可能是单条可能是数组时
+                    if(returnData instanceof List && ((List<?>) returnData).size() > 0 && ((List<?>) returnData).get(0) instanceof Map){//如果是数组则且有下层
+                        returnData = ((Map<?, ?>) ((List<?>) returnData).get(0)).get(itemRule[index]);
+                    }
+                }
+            }
+        }
+        if (Objects.nonNull(returnData)) {//获取到了订阅的数据则进行数据格式转换
+            if ("List,Map".contains(dataType) && returnData instanceof String) {//订阅是数组或对象则字符串转对象
+                returnData = MapTools.strToObj(returnData.toString());
+            }
+            if ("List".equals(dataType) && !(returnData instanceof List<?>)) {//订阅是数组但是实际不是数组则添加到数组
+                List<Object> tempList = new ArrayList<>();
+                tempList.add(returnData);
+                returnData = tempList;
+            }
+//            if ("List".equals(dataType) && returnData instanceof List<?> && MapTools.isXMLList(returnData)) {//订阅是数组但是实际是XML字符串数组则自动转换为list<map>
+//                returnData = MapTools.XMLListToListMap(returnData);//减少JAVA的动态调用,目前主要就是航班报文,BSMBPM等订阅的是String,所以不会进入这里
+//            }
+            returnData = "Map".equals(dataType) && !(returnData instanceof Map<?, ?>) ? null//是不是不妥
+                    : ("String".equals(dataType) ? returnData.toString()
+                    : ("Boolean".equals(dataType) ? returnData.toString().equals("true")
+                    : ("JSONStr".equals(dataType) ? MapTools.objToJSONStr(returnData)
+                    : returnData)));
+        }
+        return returnData;
+    }
+    /*算法连续错误次数判定*/
+    public void setServiceErrorCount(String library_id, String success) {
+        if (!success.equals("0")) {//如果是异常
+            Integer errCount = Objects.isNull(serviceErrorCount.get(library_id))?1:serviceErrorCount.get(library_id)+1;//获取当前异常连续数
+            serviceErrorCount.put(library_id,errCount);//连续数加1
+            if (errCount > AppConfig.SERVICE_ERR_MAX) {//如果连续错误数超过设定值则停止当前服务
+                ServiceInputControl.stop(serviceId);
+            }
+        } else {
+            serviceErrorCount.put(library_id, 0);//如果是成功则重置连续错误数为0
+        }
+    }
+    private long sequence = 0L;
+    private long lastTimestamp = -1L;
+    public String createLifeCycleCol(Long workerId, Integer serviceId) {
         long timestamp = System.currentTimeMillis();
         //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
-        //如果是同一时间生成的,则进行毫秒内序列
-        if (lastTimestamp == timestamp) {
+        if (lastTimestamp == timestamp) { //如果是同一时间生成的,则进行毫秒内序列
             sequence++;
-            //毫秒内序列溢出
-            if (sequence > maxSequence) {
-                //阻塞到下一个毫秒,获得新的时间戳
+            if (sequence > 999L) {//毫秒内序列溢出
                 sequence = 0;
-                while (lastTimestamp == System.currentTimeMillis()) {
+                while (lastTimestamp == System.currentTimeMillis()) {//阻塞到下一个毫秒,获得新的时间戳
                 }
                 timestamp = System.currentTimeMillis();
             }
-        }
-        //时间戳改变,毫秒内序列重置
-        else {
+        } else {
             sequence = 0L;
         }
-        //上次生成ID的时间截
-        lastTimestamp = timestamp;
+        lastTimestamp = timestamp;//上次生成ID的时间截
         //移位并通过或运算拼到一起组成64位的ID
-        return timestamp + "" + (String.format("%0" + (maxSequence.toString().length()) + "d", sequence)) + (String.format("%0" + maxWorkerId + "d", workerId)) + (String.format("%0" + maxServiceId + "d", serviceId));
+        return String.valueOf(timestamp).concat(String.format("%03d", sequence)).concat(String.format("%04d", workerId)).concat(String.format("%04d", serviceId));
     }
 
     public String getServiceId() {
@@ -481,12 +383,7 @@ public class DataProcess {
         return errorMessage;
     }
 
-    public  long getLastTimestamp() {
-        return lastTimestamp;
-    }
-
     public long getLastActive() {
         return lastActive;
     }
-
 }

+ 2 - 2
mainFactory/src/main/java/org/bfkj/application/ServiceInputControl.java

@@ -64,7 +64,7 @@ public class ServiceInputControl {
         }
         // todo 记录日志
         boolean start = ScheduleUtil.start(scheduleTask, (frequencyCount * frequencyUnit), cronExpress, taskType);
-        LogUtils.log("start: 2", "0", null, (start ? "启动成功" : "启动失败"), service_id, AppConfig.WORK_ID, null, null, null,null);//无条件记录数据接收日志
+        LogUtils.log("start: 2", "0", null, (start ? "启动成功" : "启动失败"), service_id,  null, null, null,null);//无条件记录数据接收日志
         if (start) {
             return processSuccess("启动成功");
         }
@@ -92,7 +92,7 @@ public class ServiceInputControl {
             return processFail("服务:" + service_id +" 停止 获取数据库对象失败,异常信息 " + myDbHelper.getErrorMessage());
         }
         myDbHelper.updateByCondition("update serviceinfo set runState = 0 where  serviceID =?",null,service_id);
-        LogUtils.log("stop: 2", "0", null, (reset ? "停止成功" : "停止失败"), service_id, AppConfig.WORK_ID, null, null, null,null);//无条件记录数据接收日志
+        LogUtils.log("stop: 2", "0", null, (reset ? "停止成功" : "停止失败"), service_id, null, null, null,null);//无条件记录数据接收日志
         return processSuccess("停止" + (reset ? "成功" : "失败"));
     }
 

+ 1 - 1
mainFactory/src/main/java/org/bfkj/protocol/EsAlgorithm.java

@@ -37,7 +37,7 @@ public class EsAlgorithm {
     private Map<String, Object> getRestHighLevelClient(String connectConfig) {
         RestHighLevelClient restHighLevelClient = restHighLevelClientHashMap.get(connectConfig);
         if (null == restHighLevelClient) {
-            Map<String, Object> connectConfigMaps = MapTools.mapStrToMap_connect(connectConfig);
+            Map<String, Object>  connectConfigMaps = (Map<String, Object>) MapTools.strToObj(connectConfig);
             if (Objects.isNull(connectConfigMaps.get("scheme"))) {
                 return MapTools.processFail("请求类型为空,此值应该为http或则https");
             }

+ 5 - 6
mainFactory/src/main/java/org/bfkj/protocol/MyKafKa.java

@@ -28,8 +28,7 @@ public class MyKafKa {
             if (Objects.isNull(sourceObjectName)) {
                 return MapTools.processFail("队列为空");
             }
-            Map<String, Object> connectConfigMaps;
-            connectConfigMaps = MapTools.mapStrToMap_connect(connectConfig);
+            Map<String, Object>  connectConfigMaps = (Map<String, Object>) MapTools.strToObj(connectConfig);
             if (!connectConfigMaps.containsKey("group.id")) {
                 connectConfigMaps.put("group.id", "groupid" + (String.format("%s", library_id)));
             }
@@ -46,14 +45,14 @@ public class MyKafKa {
         //todo 1. 如果一次行读取多条 2.偏移修改  : // Duration.ofSeconds(1): 如果没有数据则此处会等待1秒
         isPool = true;
         ConsumerRecords<String, Object> records = consumer.poll(Duration.ofSeconds(1));
-        String message = "";
+        List<String> messageList = new ArrayList<>();
         if (records.count() > 0) {
             for (ConsumerRecord<String, Object> record : records.records(sourceObjectName)) {
-                message = message.concat(record.value().toString());
+                messageList.add(record.value().toString());
             }
         }
         isPool =false;
-        return MapTools.processSuccess(message);
+        return MapTools.processSuccess(messageList);
     }
 
     /**
@@ -68,7 +67,7 @@ public class MyKafKa {
         if (Objects.isNull(dataContent)) {
             return MapTools.processSuccess(null);
         }
-        Map<String, Object> connectConfigMaps = MapTools.mapStrToMap_connect(connectConfig);
+        Map<String, Object>  connectConfigMaps = (Map<String, Object>) MapTools.strToObj(connectConfig);
         connectConfigMaps.put("request.timeout.ms", 60000);
         connectConfigMaps.put("max.request.size", 10240000);
         connectConfigMaps.put("compression.type", "gzip");

+ 2 - 2
mainFactory/src/main/java/org/bfkj/protocol/MyRabbitMQ.java

@@ -27,7 +27,7 @@ public class MyRabbitMQ {
             return MapTools.processFail(Objects.isNull(sourceObjectName) ? "队列为空" : "连接字符串为空");
         }
 
-        Map<String, Object> connectConfigMaps = MapTools.mapStrToMap_connect(connectConfig);
+        Map<String, Object>  connectConfigMaps = (Map<String, Object>) MapTools.strToObj(connectConfig);
         try (Connection connection = createConnectFactory(connectConfigMaps).newConnection(); Channel currentChannel = connection.createChannel();) {
             //创建消息通道
             currentChannel.queueDeclare(sourceObjectName, true, false, false, null);
@@ -69,7 +69,7 @@ public class MyRabbitMQ {
         if (Objects.isNull(sourceObjectName) || Objects.isNull(data)) {
             return MapTools.processFail(Objects.isNull(sourceObjectName) ? ("队列为空 " + data) : ("数据内容为空 " + data));
         }
-        Map<String, Object> connectConfigMaps = MapTools.mapStrToMap_connect(connectConfig);
+        Map<String, Object>  connectConfigMaps = (Map<String, Object>) MapTools.strToObj(connectConfig);
         ConnectionFactory connectFactory = createConnectFactory(connectConfigMaps);
         try (Connection connection = connectFactory.newConnection()) {
             try (Channel channel = connection.createChannel()) {

+ 1 - 1
mainFactory/src/main/java/org/bfkj/protocol/WebAPI.java

@@ -26,7 +26,7 @@ public class WebAPI {
      * webapi 执行入口函数
      */
     public Map<String,Object> execWebApi(Object header, String method, Object body, String connectConfig) {
-        Map<String, Object> connectConfigMaps = MapTools.mapStrToMap_connect(connectConfig);
+        Map<String, Object>  connectConfigMaps = (Map<String, Object>) MapTools.strToObj(connectConfig);
         Map<String,Object> restTemplateResult = initWebApiParams(connectConfigMaps); // 通过连接配置 获取restTemplate
         if (!restTemplateResult.get("code").equals("0")) {
             return MapTools.processFail(restTemplateResult.get("message").toString());

+ 8 - 0
mainFactory/src/main/java/org/bfkj/utils/DataFormat.java

@@ -13,6 +13,10 @@ import java.util.stream.Collectors;
 
 /**
  * 数据格式转换
+ *
+ *
+ * 1. 添加多线程
+ * 2. 数据项结构项表
  */
 public class DataFormat {
     private static Map<String, String> messageRules = new HashMap<>();
@@ -188,6 +192,10 @@ public class DataFormat {
             for (String dataType : messageRules.keySet()) {//循环报文提取规则MAP:为了兼容一条字符串中既有BSM又有BPM的情况
                 List<String> messagList = new ArrayList<>();
                 for (String tempTypeStr : typeStrList) {
+                    if (tempTypeStr.indexOf("dataObjectId") > 0){
+                        String tempDataObjectId = tempTypeStr.substring(tempTypeStr.indexOf("dataObjectId"));
+                        dataObjectId =  tempDataObjectId.replaceAll("[^0-9]+","");
+                    }
                     List<String> tempMessageList = MapTools.patternContent(tempTypeStr, messageRules.get(dataType)); //使用对应的提取正则表达式进行报文提取
                     if (tempMessageList.size() > 0) {
                         messagList.addAll(tempMessageList);

+ 5 - 13
mainFactory/src/main/java/org/bfkj/utils/ImportExcelUtils.java

@@ -25,27 +25,19 @@ public class ImportExcelUtils {
             FileInputStream fileInputStream = new FileInputStream(file);
             Workbook workbook = getWorkbook(file.getName(), fileInputStream);
             List<Map<String, Object>> tempMapList = new ArrayList<>();
-            int number = workbook.getNumberOfSheets(); // 获取sheet值
+            int number = workbook.getNumberOfSheets(); // 如果sheet为空则
             DataFormatter formatter = new DataFormatter();
             for (int i = 0; i < number; i++) {
                 Sheet sheet = workbook.getSheetAt(i); // 获取表格页码
                 if (sheet != null) {
                     int rowNum = sheet.getLastRowNum(); // 获取该页表共有多少行
-                    Row row1 = sheet.getRow(0);
-                    int rowNum1 = row1.getLastCellNum(); // 第一行
-                    List<String> colList = new ArrayList<>();
-                    for (int k = 0; k < rowNum1; k++) {
-                        Cell cell = row1.getCell(k);
-                        if (cell != null) {
-                            colList.add(formatter.formatCellValue(cell));
-                        }
-                    }
-                    for (int j = 1; j <= rowNum; j++) {  // 一般来说第一行是标题,所以第二行开始读取
+                    for (int j = 1; j < rowNum; j++) {  // 一般来说第一行是标题,所以第二行开始读取
                         Row row = sheet.getRow(j); // 获取表格行
+                        int rowNum1 = row.getLastCellNum(); // 第一行
                         HashMap<String, Object> tempMap = new HashMap<>();
-                        for (int col = 0; col < colList.size(); col++) {
+                        for (int col = 0; col < rowNum1; col++) {
                             Cell cell = row.getCell(col);
-                            tempMap.put(colList.get(col), cell == null ? null : formatter.formatCellValue(cell));
+                            tempMap.put("C"+col, cell == null ? null : formatter.formatCellValue(cell));
                         }
                         tempMapList.add(tempMap);
                     }

+ 37 - 30
mainFactory/src/main/java/org/bfkj/utils/LogUtils.java

@@ -1,6 +1,7 @@
 package org.bfkj.utils;
 
 
+import com.mysql.cj.log.Log;
 import org.bfkj.config.AppConfig;
 import org.bfkj.config.ObjectMap;
 import org.bfkj.config.SpringContextBeans;
@@ -10,35 +11,35 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 public class LogUtils { // 依据服务编号ID获取服务类型,如果是异步 异常日志无条件写入到本地数据库(每个服务都有这样的一个数据库) ,在程序启动时会扫描此表,重新进行,如果成功则从此表中移除
-    public static  void log(String location, String success, Object calculationLocation, String logContent, String serviceId, String workId, Object iNDataContent, String dataObjectId, Object OutDataContent, Object event) {
+    public static void log(String location, String success, Object calculationLocation, String logContent, String serviceId, Object iNDataContent, String dataObjectId, Object OutDataContent, Object event) {
         ThreadPoolTaskExecutor threadPoolTaskExecutor = SpringContextBeans.getBean("ThreadPoolTaskExecutor");
-        threadPoolTaskExecutor.submit(() -> logWrite(location, success, calculationLocation, logContent, serviceId, workId, iNDataContent, dataObjectId, OutDataContent, event));
+        threadPoolTaskExecutor.submit(() -> logWrite(location, success, calculationLocation, logContent, serviceId, iNDataContent, dataObjectId, OutDataContent, event));
     }
 
-    private static  Long deleteTime = 0L;
+    private static Long deleteTime = 0L;
+
     /*
     算法输入数据
     算法返回结果
     前置执行条件输出数据
     前置执行条件返回结果
     * */
-    public static void logWrite(String location, String success, Object calculationLocation, String logContent, String serviceId, String workId, Object iNDataContent, String dataObjectId, Object OutDataContent, Object event) {
-        String inData = MapTools.objectToString(iNDataContent);
-        String shortData = MapTools.isNotBlank(inData)?(inData.length()>20480?inData.substring(0, 20480):inData):null;
-        List<Map<String, Object>> logParam = new ArrayList<>() {{
-            HashMap<String, Object> hashMap = new HashMap<>();
-            hashMap.put("location", location);
-            hashMap.put("success", success);
-            hashMap.put("calculationLocation", Objects.isNull(calculationLocation) ? null : calculationLocation.toString());
-            hashMap.put("logContent", logContent);
-            hashMap.put("serviceId", serviceId);
-            hashMap.put("workId", workId);
-            hashMap.put("iNDataContent", shortData);
-            hashMap.put("fullData", inData);
-            hashMap.put("OutDataContent", MapTools.objectToString(OutDataContent));
-            hashMap.put("dataObjectId", dataObjectId);
-            hashMap.put("event", Objects.isNull(event) ? null : event.toString());
-            add(hashMap);
+    public static void logWrite(String location, String success, Object calculationLocation, String logContent, String serviceId, Object iNDataContent, String dataObjectId, Object OutDataContent, Object event) {
+        String inData = MapTools.objToJSONStr(iNDataContent);
+        String shortData = MapTools.isNotBlank(inData) ? (inData.length() > 20480 ? inData.substring(0, 20480) : inData) : null;
+        List<Object> logParam = new ArrayList<>() {{
+            add(success);
+            add(location);
+            add(logContent);
+            add(new Date());
+            add(serviceId);
+            add(AppConfig.WORK_ID);
+            add(Objects.isNull(event) ? null : event.toString());
+            add(shortData);
+            add(MapTools.objToJSONStr(OutDataContent));
+            add(Objects.isNull(calculationLocation) ? null : calculationLocation.toString());
+            add(dataObjectId);
+//            add(inData);
         }};
         if (MapTools.isBlank(dataObjectId) && (!success.equals("0") || location.equals("start: 1"))) {
             System.out.println("系统错误日志" + logParam); //系统错误日志
@@ -54,20 +55,26 @@ public class LogUtils { // 依据服务编号ID获取服务类型,如果是异
         if (Objects.nonNull(myDbHelper.getErrorMessage())) {
             System.out.println("记录日志: 获取" + dbText + "MyDbHelper对象失败,日志信息 :" + myDbHelper.getErrorMessage());
         }
-        if (MapTools.isNotBlank(serviceId) && (System.currentTimeMillis()-deleteTime) > 10000){
-            myDbHelper.updateByCondition("DELETE FROM log_success  WHERE id  < (SELECT MIN(T.ID)  FROM  (SELECT ID FROM log_success  WHERE serviceId =? ORDER BY createtime DESC    LIMIT 100 ) as T  )",null,serviceId);
+        if (MapTools.isNotBlank(serviceId) && (System.currentTimeMillis() - deleteTime) > 10000) {
+            myDbHelper.updateByCondition("delete log_success where serviceId =? and id not in (select id  from log_success  where serviceId = ? order by id desc limit 100 ) ", null, serviceId,serviceId);
             deleteTime = System.currentTimeMillis();
         }
-        Map<String, Object> shortMap = myDbHelper.generalProcess("1", tableName, null, null, logParam, false, null, null);
-        if (!shortMap.get("code").equals("0")) {
-            System.out.println("记录日志: 写入" + dbText + "日志失败 :" + shortMap.get("message") + "\n数据:" + MapTools.objectToString(logParam));
-        }
-        if (MapTools.isNotBlank(inData) && inData.length()>20480){
-            Map<String, Object> fullMap = myDbHelper.generalProcess("1", "log_fulldata", null, null, logParam, false, null, null);
-            if (!fullMap.get("code").equals("0")) {
-                System.out.println("记录日志(超长全量数据): 写入" + dbText + "日志失败 :" + fullMap.get("message") + "\n数据:" + MapTools.objectToString(logParam));
+        String insertSQL = "INSERT INTO log_success ( success, location, logContent, createtime, serviceId, workId, event, iNDataContent, outDataContent, calculationLocation, dataObjectId) VALUES (?,?,?,?,?,?,?,?,?,?)";
+
+        try {
+            myDbHelper.updateByCondition(insertSQL,null,logParam.toArray() );
+            if (MapTools.isNotBlank(inData) && inData.length() > 20480) {
+                myDbHelper.updateByCondition("INSERT INTO log_fulldata ( dataObjectId, fullData) VALUES (?,?)",null,inData);
             }
+        }catch (Exception e){
+            System.out.println("日志记录异常"+LogUtils.getException(e));
         }
+//
+//        Map<String, Object> shortMap = myDbHelper.generalProcess("1", tableName, null, null, logParam, false, null, null);
+//        if (!shortMap.get("code").equals("0")) {
+//            System.out.println("记录日志: 写入" + dbText + "日志失败 :" + shortMap.get("message") + "\n数据:" + MapTools.objectToString(logParam));
+//        }
+
     }
 
     /**

+ 87 - 271
mainFactory/src/main/java/org/bfkj/utils/MapTools.java

@@ -3,11 +3,7 @@ package org.bfkj.utils;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.databind.util.JSONPObject;
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
-import org.dom4j.DocumentException;
-import org.dom4j.DocumentHelper;
-import org.json.JSONArray;
 
 import java.io.*;
 import java.math.BigInteger;
@@ -23,6 +19,93 @@ import java.util.regex.Pattern;
 public class MapTools implements Serializable {
     public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
+
+    /*对象转JSON字符串*/
+    public static String objToJSONStr(Object inObj) { //
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JavaTimeModule());
+        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); //关闭
+        try {
+            if (Objects.isNull(inObj)) {
+                return null;
+            }
+            if (inObj instanceof String) {
+                inObj = strToObj(inObj.toString());
+            }
+            return mapper.writeValueAsString(inObj);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    /*字符串转对象*/
+    public static Object strToObj(String inStr) {
+        ObjectMapper mapper = new ObjectMapper();
+        try {
+            mapper.registerModule(new JavaTimeModule());
+            return mapper.readValue(inStr, Map.class);
+        } catch (JsonProcessingException e) {
+            return mapStrToObj(inStr, null);
+        }
+    }
+
+    private static Object mapStrToObj(String inMapStr, List<Object> itemMapList, String... strType) {//
+        String beginChar = strType.length == 0 ? "{" : "[";//为了递归数组准备
+        String endChar = strType.length == 0 ? "}" : "]"; //}
+        String midChar = strType.length < 2 ? "=" : strType[1];//兼容JSON格式
+        itemMapList = (Objects.isNull(itemMapList) || itemMapList.isEmpty()) ? new ArrayList<>() : itemMapList;//中间计算结果:从入口进入是为了递归数组准备
+        String tempMapStr = inMapStr;//为避免入口参数污染 [A]
+        while (true) {//遍历字符串
+            int lastLocation = tempMapStr.lastIndexOf(beginChar);//查找最后一个{,一定是独立层,无论在哪 《0》
+            int mapEndLocation = tempMapStr.indexOf(endChar, lastLocation);//查找第一个匹配的内容
+            if (lastLocation < 0 || mapEndLocation < 0) break;//找不到代表数据遍历完或数据格式有错误
+            String itemMapStr = tempMapStr.substring(lastLocation, mapEndLocation + 1);//获取一个子MAP,注意不要去掉两头括号,方便进行计算替换[1]
+            String replaceStr = itemMapStr;//为后面替换进行准备,避免数据污染 {A=[a]}
+            if (itemMapStr.indexOf("[") > 0 && itemMapStr.indexOf("]") > 0) {
+                Map<String, Object> tempObj = (Map<String, Object>) mapStrToObj(itemMapStr, itemMapList, "arr");
+                itemMapStr = tempObj.get("itemMapStr").toString();
+                itemMapList = (List<Object>) tempObj.get("itemMapList");
+            }
+            String[] columnList = itemMapStr.replace(beginChar, "").replace(endChar, "").replaceAll("\"","").split(",");//使用逗号分割 //
+            Map<String, Object> itemMap = new HashMap<>();
+            List<Object> itemList = new ArrayList<>();
+            for (String s : columnList) { //s= [1]
+                Object columnValue = "";
+                String keyName = null;
+                if (strType.length == 0) { //
+                    //{A="12:00:00"}
+                    midChar = !s.contains(":") ? "=" : !s.contains("=") ? ":" : s.indexOf("=") > s.indexOf(":") ? ":" : "=";
+                    String[] colValue = s.split(midChar); // [X1,1]
+                    if (colValue.length != 2 || Objects.equals(colValue[0], "")) continue;
+                    keyName = colValue[0].replace("'", "").replace("\"", "").trim(); //X1
+                    columnValue = Objects.equals(colValue[1], "") ? null : (colValue[1].trim()); //1
+                } else {
+                    columnValue = s;
+                }
+                if (columnValue != null && columnValue.toString().startsWith("《") && columnValue.toString().endsWith("》")) {
+                    String columnValueIndex = columnValue.toString().replace("《", "").replace("》", "");
+                    if (!MapTools.isNumber(columnValueIndex)) continue;
+                    columnValue = itemMapList.get(Integer.parseInt(columnValueIndex));
+                }
+                if (strType.length == 0) {
+                    itemMap.put(keyName, columnValue); // X1,1
+                } else {
+                    itemList.add(columnValue);
+                }
+            }
+            tempMapStr = tempMapStr.replace(replaceStr, "《" + itemMapList.size() + "》");//用于父级获取对应的值   《0》
+            itemMapList.add(strType.length == 0 ? itemMap : itemList); //[{X1:1}]
+        }
+        if (tempMapStr.contains("[") && tempMapStr.contains("]")) {  // 《0》
+            Object tempMapData = mapStrToObj(" " + tempMapStr + " ", itemMapList, "arr", midChar);
+            tempMapStr = tempMapData.toString();
+        }
+        Map<Object, Object> temMap = new HashMap<>();
+        temMap.put("itemMapStr", tempMapStr);
+        temMap.put("itemMapList", itemMapList);
+        return strType.length == 0  ? (itemMapList.size() ==0 ?itemMapList :itemMapList.get(itemMapList.size() - 1))  : temMap;
+    }
+
     /**
      * 字符串对象转时间
      *
@@ -45,39 +128,6 @@ public class MapTools implements Serializable {
     }
 
 
-    public static String objectToString(Object object) {
-        if (Objects.nonNull(object) && !Objects.equals(object, "")) {
-            if (object instanceof List) {
-                List tempData = (List) object;
-                StringBuilder sb = new StringBuilder();
-                for (Object tempDatum : tempData) {
-                    sb.append(tempDatum).append("-");
-                }
-                return sb.toString();
-            }
-            if (object instanceof Map) {
-                HashMap<Object, Object> hashMap = new HashMap<>();
-                hashMap.putAll((Map) object);
-                return hashMap.toString();
-            }
-            return object.toString();
-        }
-        return null;
-    }
-
-    /**
-     * 正则表达式 判断字符串是否是自定类型
-     *
-     * @param str     字符串
-     * @param pattern 表达式
-     * @return
-     */
-    public static boolean isTrue(String str, String pattern) {
-        Pattern pat = Pattern.compile(pattern);
-        Matcher matcher = pat.matcher(str);
-        return matcher.find();
-    }
-
     /**
      * java正则提取多个结果
      *
@@ -100,19 +150,6 @@ public class MapTools implements Serializable {
         return arrayList;
     }
 
-    public static String patternTableName(String str, String pattern) {
-        // 编写正则表达式
-        // 匹配当前正则表达式
-        Matcher matcher = Pattern.compile(pattern).matcher(str);
-        // 定义当前文件的文件名称
-        // 判断是否可以找到匹配正则表达式的字符
-        while (matcher.find()) {
-            // 将匹配当前正则表达式的字符串即文件名称进行赋值
-            return matcher.group(1);
-        }
-        // 返回
-        return null;
-    }
 
 
     public static String patternKey(String str, String pattern) {
@@ -129,21 +166,6 @@ public class MapTools implements Serializable {
         return null;
     }
 
-    /**
-     * 判断字符串是否是xml
-     *
-     * @param XMLStr xml字符串
-     * @return true:false
-     */
-    public static boolean isXMl(String XMLStr) {
-        try {
-            DocumentHelper.parseText(XMLStr);//将XML字符串转为Document
-        } catch (DocumentException e) {
-            return false;
-        }
-        return true;
-    }
-
     /**
      * 获得字符串的值,如果是空字符串则为null
      *
@@ -153,25 +175,6 @@ public class MapTools implements Serializable {
         return MapTools.isBlank(str) ? null : str;
     }
 
-    /**
-     * 判断字符串是覅否报文
-     *
-     * @param Str 字符串
-     * @return true:false
-     */
-    public static boolean isTypeB(String Str) {
-        Map<String, String> dataTypeMaps = new HashMap<>();
-        dataTypeMaps.put("BSM", "BSM[\\s\\S]+?ENDBSM");
-        dataTypeMaps.put("BPM", "BPM[\\s\\S]+?ENDPSM");
-        for (String dataType : dataTypeMaps.keySet()) {
-            if (isTrue(Str, dataType)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-
     /**
      * list 深拷贝
      *
@@ -210,24 +213,6 @@ public class MapTools implements Serializable {
         return clonedObj;
     }
 
-
-    /**
-     * 取出字符串空格和换行
-     *
-     * @param str
-     * @return
-     */
-    public static String replaceBlank(String str) {
-        String dest = "";
-        if (str != null) {
-            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
-            Matcher m = p.matcher(str);
-            dest = m.replaceAll("");
-        }
-        return dest;
-    }
-
-
     /**
      * 从map中获取returnData获取List
      *
@@ -246,20 +231,6 @@ public class MapTools implements Serializable {
     }
 
 
-    public static boolean isStartWithNumber(String str) {
-        try {
-            Pattern pattern = Pattern.compile("[0-9]*");
-            Matcher isNum = pattern.matcher(str.charAt(0) + "");
-            if (!isNum.matches()) {
-                return false;
-            }
-            return true;
-        } catch (Exception e) {
-            return false;
-        }
-
-    }
-
     /*字符串空判断*/
     public static boolean isBlank(final String s) {
         if (s == null || s.isEmpty()) {
@@ -295,156 +266,6 @@ public class MapTools implements Serializable {
         }
     }
 
-    /**
-     * 字符串转map
-     *
-     * @param mapStr map字符串: 如果不是map字符串则返回空,注意: map中不包含“”
-     * @return Map对象
-     */
-    public static Map<String, Object> stringToMap(String mapStr) {
-        Map<String, Object> map = new HashMap<>();
-        String str = "";
-        String key = "";
-        Object value = "";
-        char[] charList = mapStr.toCharArray();
-        boolean valueBegin = false;
-        for (int i = 0; i < charList.length; i++) {
-            char c = charList[i];
-            if (c == '{') {
-                if (valueBegin == true) {
-                    value = stringToMap(mapStr.substring(i, mapStr.length()));
-                    i = mapStr.indexOf('}', i) + 1;
-                    map.put(key, value);
-                }
-            } else if (c == '=') {
-                valueBegin = true;
-                key = str;
-                str = "";
-            } else if (c == ',') {
-                valueBegin = false;
-                value = str;
-                str = "";
-                map.put(key, value);
-            } else if (c == '}') {
-                if (!str.equals("")) {
-                    value = str;
-                }
-                map.put(key, value);
-                return map;
-            } else if (c != ' ') {
-                str += c;
-            }
-        }
-        return map;
-    }
-
-    /**
-     * JSON字符串转map
-     *
-     * @param mapStr 字符串:JSON字符串
-     * @return Map对象:返回map对象
-     */
-    public static Map jsonStringToMap(String mapStr) {
-        ObjectMapper mapper = new ObjectMapper();
-        try {
-            mapper.registerModule(new JavaTimeModule());
-            return mapper.readValue(mapStr, Map.class);
-        } catch (JsonProcessingException e) {
-            return null;
-        }
-    }
-
-    public static JSONPObject jsonStringToJSON(String mapStr) {
-        ObjectMapper mapper = new ObjectMapper();
-        try {
-            mapper.registerModule(new JavaTimeModule());
-            return mapper.readValue(mapStr, JSONPObject.class);
-        } catch (JsonProcessingException e) {
-            return null;
-        }
-    }
-
-    public static String mapToJSONString(Object mapStr) {
-        ObjectMapper mapper = new ObjectMapper();
-        try {
-            mapper.registerModule(new JavaTimeModule());
-            mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); //关闭
-            return mapper.writeValueAsString(mapStr);
-        } catch (JsonProcessingException e) {
-            return null;
-        }
-    }
-
-    public static String jacksonObjToStr(Object obj) { //"[1111]","[{"A":"B"}]"
-        ObjectMapper mapper = new ObjectMapper();
-        try {
-            if (null ==  obj){
-                return "";
-            }
-            mapper.registerModule(new JavaTimeModule());
-            if (!(obj instanceof String) && obj.toString().contains("{") && obj.toString().contains("}")||
-                    !(obj instanceof String) && obj.toString().contains("[") && obj.toString().contains("]")){
-                return mapper.writeValueAsString(obj);
-            }
-             return obj.toString();
-        } catch (JsonProcessingException e) {
-            return "日志数据转json字符串异常: " + e.getMessage() + ": " + obj;
-        }
-    }
-    /**
-     * list为空
-     *
-     * @param list list列表
-     * @param <T>  list中对象类型
-     * @return true:无元素  false : 存在元素
-     */
-    public static <T> boolean listIsEmpty(List<T> list) {
-        if (null == list) {
-            return true;
-        }
-        for (T t : list) {
-            if (t instanceof Map) {
-                for (Object value : ((Map<?, ?>) t).values()) {
-                    if (null != value) {
-                        return false;
-                    }
-                }
-            } else {
-                if (null != t) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * 判断list<Map>中指定元素是否为空
-     *
-     * @param list list<Map>列表
-     * @param key  指定字符串
-     * @param <T>  list中对象类型
-     * @return true: 不为空,false:为空
-     */
-    public static <T> boolean listIsEmpty(List<Map<String, Object>> list, String key) {
-        return listIsEmpty(list) || list.get(0).get(key) == null || list.get(0).get(key).toString().length() <= 0;
-    }
-
-    /**
-     * 数据库连接信息转map对象
-     *
-     * @param mapStr
-     * @return
-     */
-    public static Map<String, Object> mapStrToMap_connect(String mapStr) {
-        ObjectMapper objectMapper = new ObjectMapper();
-        try {
-            return objectMapper.readValue(mapStr, Map.class);
-        } catch (JsonProcessingException e) {
-            return new HashMap<>();
-        }
-    }
-
     public static Map<String, Object> processSuccess(Object returnData) {
         Map<String, Object> returnMap = new HashMap<>();//用于当前方法统一返回参数,不存在深拷贝问题
         returnMap.put("code", "0");
@@ -472,9 +293,4 @@ public class MapTools implements Serializable {
         //16是表示转换为16进制数
         return null;
     }
-
-    public static Map<String, Object> removeKey(Map<String, Object> inputData, List<String> arrayList) {
-        arrayList.forEach(inputData::remove);
-        return inputData;
-    }
 }

File diff suppressed because it is too large
+ 648 - 781
mainFactory/src/main/java/org/bfkj/utils/MyDbHelper.java


+ 1 - 1
mainFactory/src/main/java/org/bfkj/utils/ScheduleTask.java

@@ -46,7 +46,7 @@ public class ScheduleTask implements Runnable {
                 count++;
                 DataProcess dataProcess = ObjectMap.getordropInput(id);
                 if (Objects.isNull(dataProcess) || Objects.nonNull(dataProcess.getErrorMessage())) {
-                    LogUtils.log("run: 1", "-1",  null,"启动服务失败,获取采集对象异常:" + (Objects.isNull(dataProcess) ? "" : dataProcess.getErrorMessage()), id, AppConfig.WORK_ID, "服务编号:" + id, null,null,null);//无条件记录数据接收日志
+                    LogUtils.log("run: 1", "-1",  null,"启动服务失败,获取采集对象异常:" + (Objects.isNull(dataProcess) ? "" : dataProcess.getErrorMessage()), id,"服务编号:" + id, null,null,null);//无条件记录数据接收日志
                 }
                 dataProcess.processData(new HashMap<>() {{
                     put("dataContent", "1");

+ 1 - 1
mainFactory/src/main/java/org/bfkj/utils/ScheduleUtil.java

@@ -38,7 +38,7 @@ public class ScheduleUtil {
             scheduledFuture = threadPoolTaskScheduler.scheduleWithFixedDelay(scheduleTask, new Date(), cycleFrequency);
         } else {
             if (Objects.isNull(cronExpress)) {
-                LogUtils.log("ScheduleUtil: 2", "0",  null,"定时任务表达式为空", scheduleTask.getId(), AppConfig.WORK_ID, null, null,"定时任务表达式为空",null);//无条件记录数据接收日志
+                LogUtils.log("ScheduleUtil: 2", "0",  null,"定时任务表达式为空", scheduleTask.getId(), null, null,"定时任务表达式为空",null);//无条件记录数据接收日志
                 return false;
             }
             scheduledFuture = threadPoolTaskScheduler.schedule(scheduleTask, new CronTrigger(cronExpress.toString()));

+ 127 - 215
mainFactory/src/main/java/org/bfkj/utils/ScriptEnginePro.java

@@ -13,72 +13,72 @@ import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+/***
+ *   //如果是java,可以通过事件和数据源自动完成算法配置,实现省略各类协议读写的配置
+ *   //数据结构项的使用,可以减少JS的编写,在此处从数据结构项表获取,实现对JAVA算法返回结果的深加工
+ */
 public class ScriptEnginePro {
     private final Map<Long, Bindings> bindingMap = new HashMap<>(50); //JS执行绑定参数Map
-    private long lastActive; //服务最后活跃时间
     private String errorMessage = null; //初始化时,对象异常信息
 
-    /*java变量*/
     private Method javaMethod; //java执行函数
     private Method javaMethodClose; //java执行函数
     private Object classInstance;//java执行实例
 
-    /*JS变量*/
     private ScriptEngine scriptEngine; //脚本执行引擎
     private CompiledScript scriptCompile;//脚本编译
 
-
-    private final Object library_id; //算法ID
-    private final Object library_type; //算法类型: // 1. java 2. js 脚本 3. 数据库  4. webapi
+    private  String library_id; //算法ID
+    private String library_type; //算法类型: // 1. java 2. js 脚本 3. 数据库  4. webapi
     private String computing_expression; //脚本: 1. java输出执行名称 2.JS脚本 3.sql语句 4.空
 
-    Map<String, Object> parmaNames = new HashMap<>();
-    List<Object> javaParams = new ArrayList<>();
-    Map<String, Object> jsParams = new HashMap<>();
-    private Map<String, Object> calculationLibrary;
+    private Map<String, String> parmaNames = new HashMap<>();//脚本参数名称,用于数据处理对象进行参数订阅
+    List<Object> javaParams = new ArrayList<>();//java执行参数:因为没有变量名需要对应参数顺序
 
     private long threadId = Thread.currentThread().getId();//当前引擎线程编号
 
-
-    /**
-     * 引擎构造函数
-     *
-     * @param calculationLibrary 算法
-     */
-    public ScriptEnginePro(Map<String, Object> calculationLibrary) {
-        lastActive = System.currentTimeMillis();
-
-        this.calculationLibrary = calculationLibrary;
-        library_id = calculationLibrary.get("library_id");
-        library_type = calculationLibrary.get("library_type");
-        //通过数据源ID 获取到对应的信息
-        computing_expression = Objects.isNull(calculationLibrary.get("computing_expression")) ? "" : calculationLibrary.get("computing_expression").toString();
-        //初始化java执行对象
-        if (library_type.equals(1)) {
-            initJava(calculationLibrary.get("filePath"), calculationLibrary.get("className"));
+    public ScriptEnginePro(Map<String, Object> calcInfo) {//引擎构造函数
+        if(Objects.isNull(calcInfo) || Objects.isNull(calcInfo.get("library_type")) || Objects.isNull(calcInfo.get("computing_expression"))){
+            errorMessage = "核心参数为空:".concat(Objects.isNull(calcInfo)?"":calcInfo.toString());
+            return;
+        }
+        library_id = calcInfo.get("library_id").toString();//算法编号
+        library_type = calcInfo.get("library_type").toString();//算法类型
+        if(!"1,2".contains(library_type)){//目前只支持JS和JAVA
+            errorMessage = "未支持的算法类型:".concat(calcInfo.toString());
+            return;
+        }
+        computing_expression = calcInfo.get("computing_expression").toString();//脚本
+        if ("1".equals(library_type)) {
+            errorMessage = initJava(calcInfo.get("filePath"), calcInfo.get("className"));//初始化java执行对象
+            if(MapTools.isBlank(errorMessage)){
+                return;
+            }
         }
         //初始化脚本执行对象
-        if (library_type.equals(2)) { // 1. java时记录方法名 (缺 目标对象字段) 2. js时 记录脚本(后期可以运用数据源中的文件名在加载js文件,此时脚本为方法名) 3. 数据库(缺目标对象:表名) 4. webapi时脚本记录方法名
-            ScriptEngineManager m = new ScriptEngineManager();
-            NashornScriptEngineFactory factory = null;
-            for (ScriptEngineFactory f : m.getEngineFactories()) {
-                if ("OpenJDK Nashorn".equalsIgnoreCase(f.getEngineName())) {
-                    factory = (NashornScriptEngineFactory) f;
+        if ("2".equals(library_type)) { // 1. java时记录方法名 (缺 目标对象字段) 2. js时 记录脚本(后期可以运用数据源中的文件名在加载js文件,此时脚本为方法名)
+            ScriptEngineManager SEManager = new ScriptEngineManager();
+            NashornScriptEngineFactory NSEFactory = null;
+            for (ScriptEngineFactory SEFactory : SEManager.getEngineFactories()) {
+                if ("OpenJDK Nashorn".equalsIgnoreCase(SEFactory.getEngineName())) {
+                    NSEFactory = (NashornScriptEngineFactory) SEFactory;
                     break;
                 }
             }
-            String[] stringArray = new String[]{"--no-java", "--global-per-engine"};  //引擎加速:--global-per-engine ,安全:--no-java
-            assert factory != null;
-            scriptEngine = factory.getScriptEngine(stringArray);
+            if(Objects.isNull(NSEFactory)){
+                errorMessage = "未找到OpenJDK Nashorn";
+                return;
+            }
+            scriptEngine = NSEFactory.getScriptEngine("--no-java", "--global-per-engine");//引擎加速:--global-per-engine ,安全:--no-java
             try {
-                initParam(computing_expression, 2);
+                initParam();
                 scriptCompile = ((Compilable) scriptEngine).compile(computing_expression);
             } catch (ScriptException e) {
                 errorMessage = "JS脚本预编译时出现错误" + LogUtils.getException(e);
             }
         }
     }
-
+    //脚本引擎对象关闭时的资源释放
     public void close() {
         //如果算法的类型是数据库 则获取jdbctempalte进行关闭;如果是其他协议则 直接调用invoke方法进行关闭
         if (Objects.nonNull(javaMethodClose)) {
@@ -88,9 +88,9 @@ public class ScriptEnginePro {
                 System.out.println("JAVA反射关闭方法调用失败: " + classInstance + "释放资源失败");
             }
         }
-        if (Objects.nonNull(scriptCompile)) { //针对JS
-            scriptCompile = null;
-        }
+//        if (Objects.nonNull(scriptCompile)) { //针对JS
+//            scriptCompile = null;
+//        }
     }
 
     //统一成功信息处理
@@ -114,253 +114,174 @@ public class ScriptEnginePro {
         returnMap.put("library_id", library_id);
         return returnMap;
     }
-
-    /**
-     * 初始化JAVA执行对象
-     */
-    private void initJava(Object filePath, Object className) {
+    //初始化JAVA执行对象
+    private String initJava(Object filePath, Object className) {
         if (Objects.isNull(className) || Objects.isNull(computing_expression)) {
-            errorMessage = "java执行参数不全,类名:" + className + "; 方法名:" + computing_expression;
-            return;
+            return "java执行参数不全,类名:".concat(Objects.isNull(className)?"":className.toString()).concat("; 方法名:").concat(computing_expression);
         }
-
-        if (Objects.nonNull(filePath)) {//加载外部JAR
-            File file = new File(System.getProperty("user.dir") + File.separator + "plugins" + File.separator + filePath);
+        if (Objects.nonNull(filePath)) {//文件名不为空则加载外部JAR
+            File file = new File(System.getProperty("user.dir").concat(File.separator).concat("plugins").concat(File.separator).concat(filePath.toString()));
             if (!file.exists()) {
-                errorMessage = "外部文件加载不存在: " + System.getProperty("user.dir") + File.separator + "plugins" + File.separator + filePath;
-                return;
+                return "外部文件加载不存在:".concat(System.getProperty("user.dir")).concat(File.separator).concat("plugins").concat(File.separator).concat(filePath.toString());
             }
-            // 从URLClassLoader类中获取类所在文件夹的方法,jar也可以认为是一个文件夹
             Method addURLMethod = null;
             boolean accessible = false;
             try {
                 addURLMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
                 URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
-                //获取方法的访问权限以便写回
-                accessible = addURLMethod.canAccess(null); //判读是否可以访问: true  代表可以访问
+                accessible = addURLMethod.canAccess(null); //获取方法的访问权限以便恢复:判读是否可以访问: true  代表可以访问
                 if (!accessible) { //判读是否可以访问,如果是false,那就必须setAccessible(true)
-                    addURLMethod.setAccessible(true);
+                    addURLMethod.setAccessible(true);//实际上是为了提效
                 }
-                // 获取系统类加载器
-                addURLMethod.invoke(classLoader, file.toURI().toURL());
+                addURLMethod.invoke(classLoader, file.toURI().toURL());//加载到系统中
             } catch (Exception e) {
-                errorMessage = "JAR加载到环境失败" + LogUtils.getException(e);
-                return;
+                return "JAR加载到环境失败".concat(LogUtils.getException(e));
             } finally {
                 if (addURLMethod != null && !accessible) {
-                    addURLMethod.setAccessible(false);
+                    addURLMethod.setAccessible(false);//恢复原访问权限
                 }
             }
         }
         try {
-            initParam(computing_expression, 1); //初始化JAVA执行参数,只处理参数名,避免编译失败
-            Class<?> classExample = Class.forName(className.toString()); //
+            initParam(); //初始化JAVA执行参数,只处理参数名,避免编译失败
+            Class<?> classExample = Class.forName(className.toString()); //获取类实例
             classInstance = classExample.getConstructor().newInstance();//类实例接口 无参数构造
-            Method[] methods = classExample.getMethods();
-            for (Method currentMethod : methods) {
+            for (Method currentMethod : classExample.getMethods()) {//循环所有方法
                 String methodName = currentMethod.getName();
                 if (methodName.equals(computing_expression.substring(0, computing_expression.indexOf("(")))) {
                     javaMethod = currentMethod;
                 }
-                if (methodName.equals("close")) {
+                if ("close".equals(methodName)) {
                     javaMethodClose = currentMethod;
                 }
             }
         } catch (Exception e) {
-            errorMessage = "方法编译异常:" + LogUtils.getException(e);
+            return "方法编译异常:".concat(LogUtils.getException(e));
         }
+        return null;
     }
-
-    private void initParam(String computing_expression, int scriptType) {
-        Pattern regExpression = Pattern.compile("(?<=《)([^》]+)?(?=》)");
-        Matcher parameterNames = regExpression.matcher(computing_expression); //提取书名号中的参数名
+    //初始化执行参数名,同时修正表达式
+    private void initParam() {
+        Pattern regExpression = Pattern.compile("(?<=《)([^》]+)?(?=》)");//书名号方式提取正则表达式
+        Matcher varNameList = regExpression.matcher(computing_expression); //提取书名号中的参数名
         int index = 0; //用于记录JAVA参数对应实际运行参数的位置
-        while (parameterNames.find()) {
-            String groupKey = parameterNames.group();// String.dataContent
-            parmaNames.put(groupKey, scriptType == 1 ? index++ : (groupKey.replaceAll("\\.", "")) + threadId);
-            if (scriptType == 1) {  // java参数
-                javaParams.add(null);//先初始化一个JAVA参数
-            } else {
-                jsParams.put((groupKey.replaceAll("\\.", "")) + Thread.currentThread().getId(), null);
+        while (varNameList.find()) {//循环提取的参数
+            String varName = varNameList.group();//变量名String.dataContent
+            index++;
+            parmaNames.put(varName, "1".equals(library_type)?String.valueOf(index):(varName.replaceAll("\\.", "")).concat(String.valueOf(threadId)));//添加到变量列表中
+            if ("1".equals(library_type)) {  // java参数
+                javaParams.add(null);//先初始化一个JAVA参数,因为没有键名对应,所以只能按顺序对应(数据订阅)
             }
-            computing_expression = computing_expression.replaceFirst("《" + groupKey + "》", scriptType == 1 ? "" : parmaNames.get(groupKey).toString());
+            computing_expression = computing_expression.replaceFirst("《" + varName + "》", "1".equals(library_type) ? "" : parmaNames.get(varName));
         }
-        this.computing_expression = computing_expression;
     }
-
-
-    /**
-     * 引擎执行入口函数
-     *
-     * @param data 数据内容
-     * @return 执行后结果
-     */
-    public Map<String, Object> execScript(List<Map<String, Object>> data) {
-        lastActive = System.currentTimeMillis();
+    //引擎执行入口函数
+    public Map<String, Object> execScript(Map<String, Object> execData) {
         if (null != errorMessage) {
             return processFail(errorMessage);
         }
-        getParams(data); //实例化参数
-        // 1. java时记录方法名 (缺目标对象字段) 2. js时 记录脚本(后期可以运用数据源中的文件名在加载js文件,此时脚本为方法名) 3. 数据库(缺目标对象:表名) 4. webapi时脚本记录方法名
-        if (Objects.equals(library_type, 1)) {
+        if ("1".equals(library_type)) {
             try {
-                // javaMethod.invoke(classInstance, javaParams.toArray()) --- Map:{code,returnData}
+                for (String varName : execData.keySet()) {
+                    javaParams.set(Integer.parseInt(parmaNames.get(varName)) -1, execData.get(varName));
+                }
+
+                //如果当前算法存在数据结构项,则对返回结果进行处理后再返回
+                //数据结构项完成字段名映射,映射取值、拼接,新字段名,取值类型,取值表达式
+                //[{keyName:"航班号",getType:1,expression:"msg_f1||msg_i1"}
+                //,{keyName:"航班日期",getType:1,expression:"date(msg_f2)||date(msg_i2)"}
+                //,{keyName:"航司行李牌号",getType:1,expression:"substr(msg_x3,0,1)&&msg_x4&&substr(msg_x3,4)"}]
+                //循环数据结构项列表
+                //获取单个字段的定义
+                //如果是取值则getType=1
+                //如果包含||则
+                //||分割取值表达式
+                //循环分割后的取值表达式
+                //如果存在substr则
+                //提取括号内的原始字段名、开始位置、结束位置
+                //通过substr从返回结果中进行提取
+                //如果存在date则
+                //提取括号内的原始字段名
+                //通过date从返回结果中进行转换
+                //其它
+                //从返回结果中进行提取
+                //如果值不为空则跳出循环
+                //如果包含&&则
+                //&&分割取值表达式
+                //循环分割后的取值表达式
+                //如果存在substr则
+                //提取括号内的原始字段名、开始位置、结束位置
+                //通过substr从返回结果中进行提取
+                //如果存在date则
+                //提取括号内的原始字段名
+                //通过date从返回结果中进行转换
+                //其它
+                //从返回结果中进行提取
+                //如果值不为空则拼接值
+                //否则使用JS脚本
+                //
                 return processSuccess(javaMethod.invoke(classInstance, javaParams.toArray()));//数组方式传参,无需参数名,按顺序对应
             } catch (Exception e) {
-                return processFail("JAVA执行失败,执行参数:" + javaParams.toString() + ";异常信息:" + LogUtils.getException(e));
+                return processFail("JAVA执行失败,执行参数:".concat(javaParams.toString()).concat(";异常信息:").concat(LogUtils.getException(e)));
             }
         }
-        if (Objects.equals(library_type, 2)) {
+        if ("2".equals(library_type)) {
             Bindings bindings = bindingMap.computeIfAbsent(threadId, k -> scriptEngine.createBindings());
-            bindings.putAll(jsParams);//JS的参数是MAP,需要参数名对应
+            bindings.putAll(execData);//JS的参数是MAP,需要参数名对应
             try {
                 Object jsReturnData = scriptCompile.eval(bindings);
-                if (jsReturnData instanceof ScriptObjectMirror) {
-                    ScriptObjectMirror scriptObjec = (ScriptObjectMirror) jsReturnData;
-                    recursionEencapsulation(scriptObjec); // List<Map<String,Object>   // {0:{},1:{}}   [{},{},{}]
+                if (jsReturnData instanceof ScriptObjectMirror scriptObjec) {
+                    recursionEencapsulation(scriptObjec); //处理JS返回MAP时变成了数组 List<Map<String,Object>   // {0:{},1:{}}   [{},{},{}]
                     if (scriptObjec.isArray()) {// -- >  [{},{},{}]  []
                         List<Object> tempList = new ArrayList<>();
                         scriptObjec.forEach((index, o) -> tempList.add(o));
                         jsReturnData = tempList;
                     }
+                    jsReturnData =  MapTools.strToObj(MapTools.objToJSONStr(jsReturnData));//JS脚本对象转为JAVA数据对象
                 }
                 return processSuccess(jsReturnData);
             } catch (ScriptException e) {
-                return processFail("JS执行失败,执行参数:" + jsParams.toString() + ";异常信息:" + LogUtils.getException(e));
+                return processFail("JS执行失败,执行参数:".concat(execData.toString()).concat(";异常信息:").concat(LogUtils.getException(e)));
             }
         }
-        return processFail("未支持的算法类型:" + calculationLibrary.toString());
+        return processFail("未支持的算法类型:");
     }
-
-    private void getParams(List<Map<String, Object>> calculationResult) {
-        for (String paramName : parmaNames.keySet()) {    //  key: //String.1.dataContent.name   --   [{"code","message","dataContent":[]}}]
-            String[] param = paramName.split("\\.");
-            Object returnData = calculationResult; // {"code":"0","returnData":"JOSN"}
-            String dataType = param.length > 0 ? param[0] : null; //Map.L
-            String dataLocation = param.length > 1 ? param[1] : "";
-            if (dataLocation.equals("L")) {//类变量参数
-                returnData = param.length > 2 ? calculationLibrary.get(param[2]) : calculationLibrary;
-            }
-            if (dataLocation.equals("T")) {//固定参数 //JSON.T.{"BSM":""},
-                returnData = param.length > 2 ? param[2] : null;
-            }
-            if (MapTools.isNumber(dataLocation)) {//全量参数中取值
-                if (returnData instanceof List) {//如果是数组则取对应序号的值  ["abc"]
-                    returnData = ((List<?>) returnData).get(Integer.parseInt(dataLocation));  // {"code","message","dataContent":[]}}
-                }
-                for (int index = 2; index < param.length; index++) {   // todo  占时 不支持 String.1.dataContent.name
-                    if (MapTools.isNumber(param[index]) && returnData instanceof List) {
-                        returnData = ((List<?>) returnData).get(Integer.parseInt(param[index]));
-                    } else {
-                        if (!MapTools.isNumber(param[index])) {
-                            if (returnData instanceof Map) {
-                                returnData = ((Map<?, ?>) returnData).get(param[index]);
-                            } else {
-                                if (returnData instanceof String) {
-                                    String tempDataStr = returnData.toString().trim();
-                                    if ((tempDataStr.indexOf("[") == 0 && tempDataStr.lastIndexOf("]") == tempDataStr.length() - 1)) {
-                                        tempDataStr = tempDataStr.substring(1, tempDataStr.length() - 2);
-                                    }
-                                    returnData = MapTools.jsonStringToMap(tempDataStr);
-                                    if (Objects.nonNull(returnData)) {
-                                        returnData = ((Map) returnData).get(param[index]);   // dataContent:"<xml>……"
-                                    }
-                                }
-                            }
-
-                        } else {
-                            if (!dataLocation.equals("L") && !dataLocation.equals("T")) {
-                                returnData = null;//不符合参数订阅格式或者不符合实际参数
-                                break;//停止当前循环
-                            }
-                        }
-                    }
-                }
-            }
-
-            if (Objects.nonNull(returnData)) {//订阅类型转换
-                if (Objects.equals(dataType, "String")) {
-                    returnData = MapTools.jacksonObjToStr(returnData);
-                } else if (Objects.equals(dataType, "List")) {
-                    if (!(returnData instanceof List)) {
-                        ArrayList<Object> objects = new ArrayList<>();
-                        objects.add(returnData);
-                        returnData = objects;
-                    }
-                } else if (Objects.equals(dataType, "Map")) {
-                    if (returnData instanceof String) {
-                        returnData = MapTools.jsonStringToMap(returnData.toString());
-                    }
-                } else if (Objects.equals(dataType, "JSON")) {
-                    if (returnData instanceof String) {
-                        returnData = MapTools.jsonStringToJSON(returnData.toString());
-                    }else {
-                        returnData = MapTools.mapToJSONString(returnData);
-                    }
-                } else if (Objects.equals(dataType, "Boolean")) {
-                    if (returnData instanceof String) {
-                        returnData = returnData.equals("true") || returnData.equals("0");
-                    }
-                } else if (Objects.equals(dataType, "Integer")) {
-                    if (returnData instanceof String) {
-                        returnData = Integer.parseInt(returnData.toString());
-                    }
-                }
-            }
-            if (library_type.toString().equals("1")) { //java
-                javaParams.set(Integer.parseInt(parmaNames.get(paramName).toString()), returnData);
-            } else {
-                jsParams.put(parmaNames.get(paramName).toString(), returnData);  //
-            }
-        }
-    }
-
-    /**
-     * 脚本执行结果函数:   { 0:map<String,Object> ,1:map<String,Object} == > [map{},map{}]
-     *
-     * @param scriptObject 脚本执行结果
-     */
-    public void recursionEencapsulation(ScriptObjectMirror scriptObject) {
+    //修订JS返回值MAP变数组的问题
+    private void recursionEencapsulation(ScriptObjectMirror scriptObject) {
         for (String key : scriptObject.keySet()) { // scriptObject 实际是Map 循环map的所有key--- > {"A","B"}
             Object mirror = scriptObject.get(key); // 获取当前可以的值mirror "B"
             if (mirror instanceof ScriptObjectMirror) {// 如果当前值是map
                 recursionEencapsulation((ScriptObjectMirror) mirror); // 继续下一层
-                Boolean isArray = isArray((ScriptObjectMirror) mirror); // 如果当前值是一个数组则 转换成List<Map<String,Object>>
-                if (isArray) {
+                if (isArray((ScriptObjectMirror) mirror)) {//如果当前值是一个数组则 转换成List<Map<String,Object>>
                     List<Object> list = parseArray((ScriptObjectMirror) mirror);
                     scriptObject.put(key, list);
                 }
             }
         }
     }
-
-
     /**
      * 数组判定
      *
      * @param scriptObject 数据内容
      * @return true、false
      */
-    public Boolean isArray(ScriptObjectMirror scriptObject) {
-        boolean isArray = true;
+    private Boolean isArray(ScriptObjectMirror scriptObject) {
         int index = 0;
         for (String key : scriptObject.keySet()) {
             if (!key.equals(index + "")) {
-                isArray = false;
+                return false;
             }
             index++;
         }
-        return isArray;
+        return true;
     }
-
-
     /**
      * 对象转数组
      *
      * @param scriptObject 对象
      * @return list数组
      */
-    public List<Object> parseArray(ScriptObjectMirror scriptObject) {
+    private List<Object> parseArray(ScriptObjectMirror scriptObject) {
         List<Object> arrayList = new ArrayList<Object>();
         for (String key : scriptObject.keySet()) {
             Object obj = scriptObject.get(key);
@@ -369,19 +290,10 @@ public class ScriptEnginePro {
         return arrayList;
     }
 
-    public long getLastActive() {
-        return lastActive;
-    }
-
     public String getErrorMessage() {
         return errorMessage;
     }
-
-    public Method getMethodClose() {
-        return javaMethodClose;
-    }
-
-    public Object getLibrary_id() {
-        return library_id;
+    public Map<String, String> getParmaNames() {
+        return parmaNames;
     }
 }

Some files were not shown because too many files changed in this diff