前后端分目录

This commit is contained in:
andywang
2022-07-14 12:55:31 +08:00
parent cd72c43d62
commit bb8cf90f53
1155 changed files with 47237 additions and 14446 deletions

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ddp-enginex</artifactId>
<groupId>com.fibo.ddp</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ddp-enginex-risk-engine</artifactId>
<dependencies>
<dependency>
<groupId>com.fibo.ddp</groupId>
<artifactId>ddp-enginex-runner-node</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,81 @@
package com.fibo.ddp.enginex.riskengine.controller;
import com.fibo.ddp.common.model.authx.system.SysUser;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.enginex.risk.Engine;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.enginex.risk.request.EngineListParam;
import com.fibo.ddp.common.service.common.SessionManager;
import com.fibo.ddp.common.service.enginex.risk.EngineNodeService;
import com.fibo.ddp.common.service.enginex.risk.EngineService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* 子引擎节点接口
*/
@RestController
@RequestMapping("childEngineNode")
public class ChildEngineNodeController {
@Autowired
private EngineService engineService;
@Autowired
private EngineNodeService engineNodeService;
/**
* @api {POST} /childEngineNode/getEngineList 7.81. 子引擎节点 获取引擎列表
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Integer} pageNo 页数
* @apiParam {Integer} pageSize 每页的条数
* @apiParam {Long} nodeId 节点id
* @apiParam {Long} engineId 引擎id
* @apiParam {String} [searchString] 搜索关键字
* @apiSuccess {String} status 状态: 1成功, 0失败
* @apiParamExample {json} 请求示例:
* {"pageNo":1,"pageSize":5,"nodeId":0,"engineId":220,"searchString":"信用卡"}
* @apiSuccessExample {json} 成功返回数据示例:
* {"status":"1","error":"00000000","msg":null,"data":{"pager":{"pageNum":1,"pageSize":5,"size":2,"startRow":1,"endRow":2,"total":2,"pages":1,"list":null,"prePage":0,"nextPage":0,"isFirstPage":true,"isLastPage":true,"hasPreviousPage":false,"hasNextPage":false,"navigatePages":8,"navigatepageNums":[1],"navigateFirstPage":1,"navigateLastPage":1,"lastPage":1,"firstPage":1},"engineList":[{"userId":220,"versionCode":"7eb07302-cbf3-4f6e-95b5-075e89b59f4c","name":"信用卡引擎2","description":"信用卡引擎2","status":1,"createDatetime":1610505340000,"updateDatetime":1610505340000,"creator":142,"userId":null,"organId":46,"searchString":null,"engineVersionList":null,"runState":0,"checked":false,"callbackType":1,"callbackUrl":null},{"userId":219,"versionCode":"5bc79716-8c62-4248-bf91-de07f654668a","name":"信用卡引擎1","description":"信用卡引擎1","status":1,"createDatetime":1610505333000,"updateDatetime":1610505333000,"creator":142,"userId":null,"organId":46,"searchString":null,"engineVersionList":null,"runState":0,"checked":false,"callbackType":1,"callbackUrl":null}]}}
*/
@RequestMapping(value = "getEngineList", method = RequestMethod.POST)
public ResponseEntityDto getEngineList(@RequestBody EngineListParam param) {
String searchString = param.getSearchString();
Long nodeId = param.getNodeId();
List<Integer> list = new ArrayList<Integer>();
SysUser user = SessionManager.getLoginAccount();
Long organId = user.getOrganId();
PageHelper.startPage(param.getPageNo(), param.getPageSize());
//查询对应的引擎
List<Engine> engineList = engineService.getEngineList(organId, searchString, list);
EngineNode engineNode = engineNodeService.findById(nodeId);
if (engineNode != null) {
for (Engine engine : engineList) {
if (engine.getId().toString().equals(engineNode.getNodeJson())) {
engine.setChecked(true);
break;
}
}
}
PageInfo<Engine> pageInfo = new PageInfo<Engine>(engineList);
pageInfo.setList(null);
HashMap<String, Object> resultMap = new HashMap();
resultMap.put("pager", pageInfo);
resultMap.put("engineList", engineList);
return ResponseEntityBuilder.buildNormalResponse(resultMap);
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,358 @@
package com.fibo.ddp.enginex.riskengine.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.common.enums.ErrorCodeEnum;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.enginex.risk.EngineVersion;
import com.fibo.ddp.common.service.common.SessionManager;
import com.fibo.ddp.common.service.enginex.risk.EngineNodeService;
import com.fibo.ddp.common.service.enginex.risk.EngineVersionService;
import com.fibo.ddp.common.service.monitor.logger.ArchivesLog;
import com.fibo.ddp.common.utils.constant.OpTypeConst;
import com.fibo.ddp.common.utils.constant.enginex.EngineConst;
import com.fibo.ddp.common.utils.constant.enginex.EngineMsg;
import com.fibo.ddp.common.utils.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@Controller("EngineVersionControllerV2")
@RequestMapping("/v2/engineVersion")
@ResponseBody
public class EngineVersionController {
@Autowired
private EngineVersionService engineVersionService;
@Autowired
private EngineNodeService engineNodeService;
/**
* @api {POST} /v2/engineVersion/add/{engineId}/{version} 7.56. 新增版本
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} engineId 路径参数engineId
* @apiParam {Number} version 路径参数version
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* {无请求体}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/add/{engineId}/{version}", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.SAVE_VERSION)
public ResponseEntityDto<Object> addEngineVersion(@PathVariable Long engineId, @PathVariable Integer version) {
Map<String, Object> map = new HashMap<>();
// 获取当前系统登录用户,即引擎的创建者
Long userId = SessionManager.getLoginAccount().getUserId();
//获取当前选中的版本的最大子版本
EngineVersion engineVer = new EngineVersion();
engineVer.setEngineId(engineId);
engineVer.setVersion(version);
EngineVersion engineVersion = engineVersionService.getLatestEngineSubVersion(engineVer);
if (engineVersion != null) {
//无论引擎是否正在运行,皆在此版本下创建子版本
EngineVersion newEngineVersion = new EngineVersion();
newEngineVersion.setBootState(0);
newEngineVersion.setCreateTime(new Date().toString());
newEngineVersion.setEngineId(engineVersion.getEngineId());
newEngineVersion.setLatestTime(new Date().toString());
newEngineVersion.setLatestUser(userId);
newEngineVersion.setLayout(0);
newEngineVersion.setStatus(1);
newEngineVersion.setSubVersion(engineVersion.getSubVersion() + 1); // 子版本 +1
newEngineVersion.setUserId(userId);
newEngineVersion.setVersion(engineVersion.getVersion());
//新增版本
Long versionId = saveEngineVersion(newEngineVersion);
map.put("result", 1);
map.put("versionId", versionId);
} else {
map.put("result", -1);
map.put("versionId", 0);
}
return ResponseEntityBuilder.buildNormalResponse(map);
}
/**
* @api {POST} /v2/engineVersion/clear/{versionId} 7.57. 清空引擎节点根据versionId清空
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} versionId 路径参数versionId
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* {无请求体}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/clear/{versionId}", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.CLEAR_NODE)
public ResponseEntityDto<Object> clear(@PathVariable Long versionId) {
Map<String, Object> map = new HashMap<>();
// 正在部署的不能清除
EngineVersion engineVersion = engineVersionService.selectByPrimaryKey(versionId);
if (engineVersion != null) {
if (engineVersion.getBootState() == 1) {
map.put("result", "-1");
map.put("msg", "版本正在运行,请先停止部署!");
} else {
boolean flag = engineVersionService.clear(versionId);
if (flag) {
map.put("result", "1");
map.put("msg", "清除成功!");
} else {
map.put("result", "-1");
map.put("msg", "清除失败,请联系管理员!");
}
}
} else {
map.put("result", "-1");
map.put("msg", "数据错误,目标版本不存在!");
}
return ResponseEntityBuilder.buildNormalResponse(map);
}
/**
* @api {POST} /v2/engineVersion/deploy/{versionId} 7.50.1. 根据versionId部署引擎
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} versionId 路径参数versionId
* @apiSuccess {String} status 状态1成功0失败
* @apiSuccess {Object} data
* @apiSuccess {Number} data.status 部署结果1成功0失败
* @apiSuccess {String} data.msg 部署结果提示信息
* @apiParamExample {json} 请求示例:
* {无请求体}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/deploy/{versionId}", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.ENGINDE_DEPLOY)
public ResponseEntityDto<Object> deployEngineVersion(@PathVariable Long versionId) {
int count = engineVersionService.deployEngine(versionId);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("versionId", versionId);
if (count == 1) {
resultMap.put("status", EngineMsg.STATUS_SUCCESS);
resultMap.put("msg", EngineMsg.DEPLOY_SUCCESS);
} else {
resultMap.put("status", EngineMsg.STATUS_FAILED);
resultMap.put("msg", EngineMsg.DEPLOY_FAILED);
}
return ResponseEntityBuilder.buildNormalResponse(resultMap);
}
@RequestMapping(value = "/applyDeploy/{versionId}", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.ENGINDE_DEPLOY)
public ResponseEntityDto<Object> applyDeployEngineVersion(@PathVariable Long versionId) {
Map<String,Object> map = engineVersionService.applyDeployEngine(versionId);
if (map!=null&&!map.isEmpty()){
return ResponseEntityBuilder.buildNormalResponse(map);
}else {
return ResponseEntityBuilder.buildErrorResponse(ErrorCodeEnum.PARAMS_EXCEPTION);
}
}
/**
* @api {POST} /v2/engineVersion/undeploy/{versionId} 7.50.2. 根据versionId停用部署的引擎
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} versionId 路径参数versionId
* @apiSuccess {String} status 状态1成功0失败
* @apiSuccess {Object} data
* @apiSuccess {Number} data.status 停用部署结果1已停用0停用失败
* @apiSuccess {String} data.msg 停用部署结果提示信息
* @apiParamExample {json} 请求示例:
* {无请求体}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/undeploy/{versionId}", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.ENGINDE_UNDEPLOY)
public ResponseEntityDto<Object> undeployEngineVersion(@PathVariable Long versionId) {
int count = engineVersionService.undeployEngine(versionId);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("versionId", versionId);
if (count == 1) {
resultMap.put("status", EngineMsg.STATUS_SUCCESS);
resultMap.put("msg", EngineMsg.UNDEPLOY_SUCCESS);
} else {
resultMap.put("status", EngineMsg.STATUS_FAILED);
resultMap.put("msg", EngineMsg.UNDEPLOY_FAILED);
}
return ResponseEntityBuilder.buildNormalResponse(resultMap);
}
/**
* @api {POST} /v2/engineVersion/nodeList/{versionId} 7.66.20. 根据版本编号获取节点列表(这个接口没什么用)
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} versionId 路径参数versionId
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* {无请求体}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/nodeList/{versionId}", method = RequestMethod.POST)
public ResponseEntityDto<Object> getEngineNodeListByVerionId(@PathVariable Long versionId) {
List<EngineNode> nodeList = engineNodeService.getEngineNodeListByEngineVersionId(versionId);
// if (CollectionUtil.isNotNullOrEmpty(nodeList)) {
// return ResponseEntityBuilder.buildNormalResponse(nodeList);
// }
// return ResponseEntityBuilder.buildNormalResponse(null);
return ResponseEntityBuilder.buildNormalResponse(nodeList);
}
/**
* @api {POST} /v2/engineVersion/getTypedNodes/{versionId} 7.58. 根据类型获取节点
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} versionId 路径参数versionId
* @apiParam {JSONArray} types 节点类型
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* [3,7]
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/getTypedNodes/{versionId}", method = RequestMethod.POST)
public ResponseEntityDto<Object> getEngineNodesByType(@PathVariable Long versionId, @RequestBody List<Integer> types) {
// @RequestParam Map<String, Object> paramMap,
// @RequestParam("types[]") List<Integer> types
// Long versionId = Long.parseLong(paramMap.get("versionId").toString());
HashMap<String, Object> paramMap = new HashMap<>();
List<EngineNode> nodeList = engineNodeService.getEngineTypedNodeListByEngineVersionId(versionId, types);
boolean flag = true;
boolean flag1 = true;
if (nodeList != null && nodeList.size() > 0) {
for (EngineNode engineNode : nodeList) {
if ((int) engineNode.getNodeType() == 7 && flag) {
if (!StringUtil.isBlank(engineNode.getNodeJson())) {
JSONArray json = JSONArray.parseArray(engineNode.getNodeJson());
if (!StringUtil.isBlank(engineNode.getNextNodes())) {
String[] nextNodes = engineNode.getNextNodes().split(",");
paramMap.put("sanBoxNode", engineNode);
if (json.size() == nextNodes.length) {
paramMap.put("sanbox", "1");
} else {
paramMap.put("sanbox", "0");
flag = false;
}
} else {
paramMap.put("sanbox", "0");
flag = false;
}
}
}
if ((int) engineNode.getNodeType() == 3 && flag1) {
if (!StringUtil.isBlank(engineNode.getNodeJson())) {
JSONObject jsonObj = JSONObject.parseObject(engineNode.getNodeJson());
JSONArray json = jsonObj.getJSONArray("conditions");
if (!StringUtil.isBlank(engineNode.getNextNodes())) {
String[] nextNodes = engineNode.getNextNodes().split(",");
paramMap.put("groupNode", engineNode);
if (json.size() == nextNodes.length) {
paramMap.put("group", "1");
} else {
paramMap.put("group", "0");
flag1 = false;
}
} else {
paramMap.put("group", "0");
flag1 = false;
}
}
}
}
} else {
paramMap.put("sanbox", "-1");
paramMap.put("group", "-1");
}
return ResponseEntityBuilder.buildNormalResponse(paramMap);
}
/**
* @api {POST} /v2/engineVersion/delete/{versionId} 7.66.21. 删除当前版本
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} versionId 路径参数versionId
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* {无请求体}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/delete/{versionId}", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.DELETE_VERSION)
public ResponseEntityDto<Object> deleteEngineVersion(@PathVariable Long versionId) {
EngineVersion engineVersion = engineVersionService.selectByPrimaryKey(versionId);
Map<String, Object> map = new HashMap<>();
// 当前版本是否正在运行
int bootState = engineVersion.getBootState();
if (EngineConst.BOOT_STATE_DEPLOY == bootState) {
// 如果正在运行,则提示用户不能删除
map.put("status", EngineMsg.STATUS_FAILED);
map.put("msg", EngineMsg.DELETE_RUNNING_FAILED);
} else {
// 假删除,是否删除 (0:在回收站中,可恢复,1:正常,2彻底删除)
engineVersion.setStatus(0); // 状态改为0
int count = engineVersionService.update(engineVersion);
if (count == 1) {
map.put("status", EngineMsg.STATUS_SUCCESS);
map.put("msg", EngineMsg.DELETE_VERSION_SUCCESS);
} else {
map.put("status", EngineMsg.STATUS_FAILED);
map.put("msg", EngineMsg.DELETE_VERSION_FAILED);
}
}
return ResponseEntityBuilder.buildNormalResponse(map);
}
/**
* 新增版本
* 新增分为两种情况,一种是自然地新增,
* 一种是当前版本正在运行修改的新增
*
* @param engineVersion
* @return
*/
@RequestMapping("save")
@ArchivesLog(operationType = OpTypeConst.SAVE_VERSION)
public Long saveEngineVersion(EngineVersion engineVersion) {
List<EngineNode> nodeList = new ArrayList<>();
EngineNode engineNode = new EngineNode();
engineNode.setNodeX(200d);
engineNode.setNodeY(200d);
engineNode.setNodeName("开始");
engineNode.setNodeType(1);
engineNode.setNodeOrder(1);
engineNode.setNodeCode("ND_START");
engineNode.setParams("{\"arr_linkId\":\"\",\"dataId\":\"-1\",\"url\":\"/Riskmanage/resource/images/decision/start.png\",\"type\":\"1\"}");
nodeList.add(engineNode);
Long versionId = engineVersionService.saveEngineVersion(engineVersion, nodeList);
return versionId;
}
}

View File

@@ -0,0 +1,105 @@
package com.fibo.ddp.enginex.riskengine.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.enginex.risk.EngineVersion;
import com.fibo.ddp.common.service.common.SessionManager;
import com.fibo.ddp.common.service.datax.datamanage.FieldService;
import com.fibo.ddp.common.service.enginex.risk.EngineNodeService;
import com.fibo.ddp.common.service.enginex.risk.EngineVersionService;
import com.fibo.ddp.common.service.monitor.logger.ArchivesLog;
import com.fibo.ddp.common.service.strategyx.listlibrary.ListDbService;
import com.fibo.ddp.common.utils.constant.OpTypeConst;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* 黑白名单节点接口
*/
@Controller("listDbNodeControllerV2")
@RequestMapping("v2/bwListNode")
@ResponseBody
public class ListDbNodeController {
@Autowired
private ListDbService listDbService;
@Autowired
private EngineNodeService engineNodeService;
@Autowired
private EngineVersionService engineVersionService;
@Autowired
private FieldService fieldService;
/**
* @api {POST} /v2/bwListNode/update 7.73. 黑白名单节点 修改节点信息
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} nodeId 节点编号
* @apiParam {Number} versionId 版本编号
* @apiParam {Number} nodeType 节点类型5黑名单6白名单
* @apiParam {Number} nodeOrder 节点顺序
* @apiParam {String} nodeName 节点名称
* @apiParam {String} nodeCode 节点code
* @apiParam {Number} nodeX 节点X轴
* @apiParam {Number} nodeY 节点Y轴
* @apiParam {String} innerListdbs 内部黑名单id逗号分隔
* @apiParam {String} outerListdbs 外部黑名单id逗号分隔
* @apiParam {String} [nodeJson] 节点json
* @apiParam {String} [nodeScript] 节点脚本
* @apiParam {String} [params] 节点类型,图标等信息
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* {"nodeId":3361,"versionId":454,"nodeType":5,"nodeOrder":13,"nodeName":"黑名单66","nodeCode":"ND_13","nodeX":666.66,"nodeY":666.77,"innerListdbs":"112,115","outerListdbs":""}
* @apiSuccessExample {json} 成功返回数据示例:
* {"status":"1","error":"00000000","msg":null,"data":true}
*/
@RequestMapping(value = "update", method = RequestMethod.POST)
@ArchivesLog(operationType = OpTypeConst.UPDATE_NODE)
public ResponseEntityDto update(@RequestBody HashMap<String, Object> paramMap) {
//增加黑白名单库用到的字段绑定传递engineId和字段id
Long userId = SessionManager.getLoginAccount().getUserId();
paramMap.put("userId", userId); //listDbIds
String innerListdbs = String.valueOf(paramMap.get("innerListdbs"));
String outerListdbs = String.valueOf(paramMap.get("outerListdbs"));
Object nodeJson = paramMap.get("nodeJson");
List<Long> listDbIds = new ArrayList<>();
if (nodeJson!=null){
JSONObject jsonObject = JSON.parseObject(nodeJson.toString());
JSONArray listDbList = jsonObject.getJSONArray("listDbList");
if (listDbList!=null&&listDbList.size()>0){
for (Object o : listDbList) {
JSONObject listDbJson = JSON.parseObject(JSON.toJSONString(o));
Long listDbId = listDbJson.getLong("listDbId");
if (listDbId!=null){
listDbIds.add(listDbId);
}
}
}
}
String snapshot = String.valueOf(paramMap.get("snapshot"));
paramMap.put("listDbIds", listDbIds);
String strFieldIds = listDbService.findFieldsByListDbIds(paramMap);
Long versionId = Long.valueOf(String.valueOf(paramMap.get("versionId")));
EngineVersion engineVesion = engineVersionService.selectByPrimaryKey(versionId);
Long engineId = engineVesion.getEngineId();
paramMap.put("engineId", engineId);
paramMap.put("fieldIds", strFieldIds);
fieldService.bindEngineField(paramMap);
paramMap.put("snapshot",snapshot);
engineNodeService.updateNodeSnapshot(paramMap);
return ResponseEntityBuilder.buildNormalResponse();
}
}

View File

@@ -0,0 +1,77 @@
package com.fibo.ddp.enginex.riskengine.controller;
import com.fibo.ddp.common.model.authx.system.SysUser;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.enginex.risk.request.ModelListParam;
import com.fibo.ddp.common.model.strategyx.aimodel.MachineLearningModels;
import com.fibo.ddp.common.service.common.SessionManager;
import com.fibo.ddp.common.service.enginex.risk.EngineNodeService;
import com.fibo.ddp.common.service.strategyx.aimodel.ModelsService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
/**
* 模型节点接口
*/
@RestController
@RequestMapping("modelNode")
public class ModelNodeController {
@Autowired
private ModelsService modelsService;
@Autowired
private EngineNodeService engineNodeService;
/**
* @api {POST} /modelNode/getModelList 7.91. 模型节点 获取模型列表
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Integer} pageNo 页数
* @apiParam {Integer} pageSize 每页的条数
* @apiParam {Long} nodeId 节点id
* @apiParam {Long} engineId 引擎id
* @apiParam {String} [searchString] 搜索关键字
* @apiSuccess {String} status 状态: 1成功, 0失败
* @apiParamExample {json} 请求示例:
* {"pageNo":1,"pageSize":5,"nodeId":3247,"engineId":214,"searchString":"模型"}
* @apiSuccessExample {json} 成功返回数据示例:
* {"status":"1","error":"00000000","msg":null,"data":{"pager":{"pageNum":1,"pageSize":5,"size":1,"startRow":1,"endRow":1,"total":1,"pages":1,"list":null,"prePage":0,"nextPage":0,"isFirstPage":true,"isLastPage":true,"hasPreviousPage":false,"hasNextPage":false,"navigatePages":8,"navigatepageNums":[1],"navigateFirstPage":1,"navigateLastPage":1,"lastPage":1,"firstPage":1},"modelsList":[{"userId":1,"modelName":"老户模型","description":"老户模型描述","modelType":"pmml","fileName":"1614578067937_model_RF.pmml","filePath":"/usr/local/tomcat_riskmanage/webapps/Riskmanage/upload/models/fieldUpload/1614578067937_model_RF.pmml","modelField":"x16,x17,x8,x19,x6,x10,x5,x1,x13,x2,x3,x15,x21,x18,x11,x7,x14,x12,x20","mappingField":"588,590,591,592,593,594,605,606,611,613,610,612,614,615,616,609,617,620,589","status":1,"creator":135,"modifier":135,"organId":46,"createTime":1614578104000,"updateTime":1614578104000,"modelFieldArr":null,"mappingFieldArr":null,"checked":true}]}}
*/
@RequestMapping(value = "getModelList", method = RequestMethod.POST)
public ResponseEntityDto<Object> getModelList(@RequestBody ModelListParam param) {
String searchString = param.getSearchString();
Long nodeId = param.getNodeId();
SysUser sysUser = SessionManager.getLoginAccount();
Integer organId = Integer.valueOf(sysUser.getOrganId().toString());
PageHelper.startPage(param.getPageNo(), param.getPageSize());
List<MachineLearningModels> modelsList = modelsService.getModelsListByOrganId(organId, searchString);
EngineNode engineNode = engineNodeService.findById(nodeId);
if (engineNode != null) {
for (MachineLearningModels models : modelsList) {
if (models.getId().toString().equals(engineNode.getNodeJson())) {
models.setChecked(true);
break;
}
}
}
PageInfo<MachineLearningModels> pageInfo = new PageInfo<MachineLearningModels>(modelsList);
pageInfo.setList(null);
HashMap<String, Object> modelMap = new HashMap<>();
modelMap.put("pager", pageInfo);
modelMap.put("modelsList", modelsList);
return ResponseEntityBuilder.buildNormalResponse(modelMap);
}
}

View File

@@ -0,0 +1,152 @@
package com.fibo.ddp.enginex.riskengine.controller;
import com.fibo.ddp.common.model.authx.system.SysUser;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.enginex.risk.request.KnowledgeTreeListParam;
import com.fibo.ddp.common.model.strategyx.guiderule.RuleInfo;
import com.fibo.ddp.common.model.strategyx.guiderule.request.RuleListParamV2;
import com.fibo.ddp.common.model.strategyx.knowledge.KnowledgeTree;
import com.fibo.ddp.common.service.common.SessionManager;
import com.fibo.ddp.common.service.strategyx.guiderule.RuleService;
import com.fibo.ddp.common.service.strategyx.guiderule.RuleVersionService;
import com.fibo.ddp.common.service.strategyx.knowledge.KnowledgeTreeService;
import com.fibo.ddp.common.service.strategyx.scriptrule.RuleScriptVersionService;
import com.fibo.ddp.common.utils.util.StringUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller("RuleNodeController")
@RequestMapping("/v2/ruleNode")
@ResponseBody
public class RuleNodeController {
@Autowired
private RuleService ruleService;
@Autowired
private RuleVersionService versionService;
@Autowired
private RuleScriptVersionService ruleScriptVersionService;
@Autowired
private KnowledgeTreeService knowledgeTreeService;
/**
* @api {POST} /v2/ruleNode/getTreeDataForEngine 7.61. 获取树形节点集合
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Integer} status 值为1
* @apiParam {Integer} type 1规则集2
* @apiParam {Integer} [pageNo=1] 第几页
* @apiParam {Integer} [pageSize=5] 每页的条数
* @apiParam {Integer} [engineId] 引擎id
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例:
* {"status":1,"type":1,"pageNo":1,"pageSize":5,"engineId":211}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/getTreeDataForEngine", method = RequestMethod.POST)
public ResponseEntityDto<Object> getTreeDataForEngine(@RequestBody Map<String, Object> param) {
// @RequestParam Map<String,Object> inputParam,
// @RequestParam(defaultValue = "1") Integer pageNo,
// @RequestParam(defaultValue = "5") Integer pageSize
Integer pageNo = param.get("pageNo") == null ? 1 : Integer.valueOf(param.get("pageNo").toString());
Integer pageSize = param.get("pageSize") == null ? 5 : Integer.valueOf(param.get("pageSize").toString());
param.putAll(getParam(param));
param.put("sort", false);
param.put("tree_type", StringUtil.toLongList("0"));
param.put("status", StringUtil.toLongList(param.get("status").toString()));
PageHelper.startPage(pageNo, pageSize);
List<KnowledgeTree> klist = knowledgeTreeService.getTreeDataForEngine(param);
PageInfo<KnowledgeTree> pageInfo = new PageInfo<>(klist);
param.put("klist", klist);
param.put("pager", pageInfo);
return ResponseEntityBuilder.buildNormalResponse(param);
}
/**
* @api {POST} /v2/ruleNode/getRuleDataForEngine 7.62. 获取规则数据为引擎节点
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Integer} status 值为1
* @apiParam {Integer} parentIds XXXXX
* @apiParam {Integer} [is_select] 值为1
* @apiParam {Integer} [dictKey] 值为ruleName
* @apiParam {Integer} [dictValue] 搜索关键字
* @apiParam {Integer} [engineId] 引擎id
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例1
* {"status":1,"parentIds":1038,"engineId":211}
* @apiParamExample {json} 请求示例2
* {"status":1,"is_select":1,"dictKey":"ruleName","dictValue":"欺诈","engineId":211}
* @apiSuccessExample {json} 成功返回数据示例:
* {待完善}
*/
@RequestMapping(value = "/getRuleDataForEngine", method = RequestMethod.POST)
public ResponseEntityDto<Object> getRuleDataForEngine(@RequestBody Map<String, Object> param) {
param.putAll(getParam(param));
param.put("status", StringUtil.toLongList(param.get("status").toString()));
RuleInfo rule = new RuleInfo();
rule.setStatus(1);
rule.setOrganId(SessionManager.getLoginAccount().getOrganId());
if (param.containsKey("parentIds")) {
List<Long> parentIds = StringUtil.toLongList(param.get("parentIds").toString());
param.put("parentIds",parentIds );
rule.setParentIds(parentIds);
}
// List<Rule> rlist = s.ruleService.getRuleList(inputParam);
RuleListParamV2 ruleListParam = new RuleListParamV2();
ruleListParam.setPageNum(0);
ruleListParam.setPageSize(0);
ruleListParam.setRuleInfo(rule);
List<RuleInfo> list = ruleService.queryByEntity(ruleListParam).getList();
if (list != null && list.size() > 0) {
for (RuleInfo info : list) {
if (info.getDifficulty() == 2) {
info.setRuleVersionList(versionService.queryVersionListByRuleId(info.getId()));
}else
if (info.getDifficulty() == 3){
info.setRuleScriptVersionList(ruleScriptVersionService.queryVersionListByRuleId(info.getId()));
}
}
}
param.put("rlist", list);
return ResponseEntityBuilder.buildNormalResponse(param);
}
// 已选规则预览(待完善)(待讨论)
@RequestMapping(value = "/previewRule", method = RequestMethod.POST)
public ModelAndView previewRule(@RequestParam Map<String, Object> paramMap) {
ModelAndView mav = new ModelAndView("decision/rulesDetails");
mav.addAllObjects(paramMap);
return mav;
}
// 根据用户角色或权限,获取所需参数集合
private Map<String, Object> getParam(Map<String, Object> paramMap) {
SysUser sysUser = SessionManager.getLoginAccount();
paramMap.put("userId", sysUser.getUserId());
paramMap.put("organId", sysUser.getOrganId());
return paramMap;
}
@RequestMapping(value = "/getFolderList", method = RequestMethod.POST)
public ResponseEntityDto<Object> getFolderList(@RequestBody KnowledgeTreeListParam param) {
List<KnowledgeTree> list = knowledgeTreeService.getFolderList(param);
Map<String, Object> map = new HashMap<>();
map.put("klist", list);
return ResponseEntityBuilder.buildNormalResponse(map);
}
}

View File

@@ -0,0 +1,144 @@
package com.fibo.ddp.enginex.riskengine.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.strategyx.scorecard.Scorecard;
import com.fibo.ddp.common.model.strategyx.scorecard.vo.ScorecardVersionVo;
import com.fibo.ddp.common.model.strategyx.scorecard.vo.ScorecardVo;
import com.fibo.ddp.common.service.enginex.risk.EngineNodeService;
import com.fibo.ddp.common.service.strategyx.scorecard.ScorecardService;
import com.fibo.ddp.common.service.strategyx.scorecard.ScorecardVersionService;
import com.fibo.ddp.common.utils.util.StringUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller("ScorecardNodeControllerV2")
@RequestMapping("/v2/cardNode")
@ResponseBody
public class ScorecardNodeController {
@Autowired
private ScorecardVersionService scorecardVersionService;
@Autowired
private ScorecardService scorecardService;
@Autowired
private EngineNodeService engineNodeService;
// 决策流
@RequestMapping("toCardNode")
public ModelAndView toCardNode() {
ModelAndView mav = new ModelAndView("decision/decisions");
return mav;
}
/**
* @api {POST} /v2/cardNode/cardList 7.60. 返回评分卡列表
* @apiGroup zzzzz01
* @apiVersion 2.0.0
* @apiParam {Number} nodeId 节点id0表示新建的
* @apiParam {Number} status 1
* @apiParam {String} [dictKey] 值为"scorecardName"
* @apiParam {String} [dictValue] 搜索关键字
* @apiParam {Number} [pageNo=1] 第几页
* @apiParam {Number} [pageSize=10] 每页的条数
* @apiParam {Number} [engineId] 引擎id
* @apiSuccess {String} status 状态1成功0失败
* @apiParamExample {json} 请求示例1
* {"nodeId":3223,"status":1}
* @apiParamExample {json} 请求示例2
* {"nodeId":3223,"status":1,"dictKey":"scorecardName","dictValue":"客户","pageNo":1,"pageSize":10,"engineId":211}
* @apiSuccessExample {json} 成功返回数据示例:
* {"status":"1","error":"00000000","msg":null,"data":{"pager":{"pageNum":1,"pageSize":1,"size":1,"startRow":1,"endRow":1,"total":9,"pages":9,"list":[{"userId":99,"name":"客户评分卡-有盾","versionCode":"SC_test_card2","description":"客户评分卡-有盾值","version":null,"parentId":1076,"userId":135,"author":135,"authorName":"管理员","engineId":211,"type":1,"status":1,"sFieldList":[],"sContentList":[],"created":1520236208000,"updated":1615889385000,"checked":false,"score":"{\"output\":{\"field_id\":0,\"field_code\":\"score\",\"field_name\":\"信用得分\",\"field_type\":1},\"formula\":\"300+#{f_yd_realNameScore}\",\"formula_show\":\"300+@有盾实名认证分值@\",\"fields\":[{\"field_id\":642,\"field_code\":\"f_yd_realNameScore\",\"field_type\":1,\"field_name\":\"有盾实名认证分值\",\"segments\":[{\"segment\":\"(,29]\",\"dictValue\":0},{\"segment\":\"(29,69]\",\"dictValue\":50},{\"segment\":\"(69,)\",\"dictValue\":100}]}]}","pd":null,"odds":null,"engineName":null,"organId":46,"sRuleContentList":[]}],"prePage":0,"nextPage":2,"isFirstPage":true,"isLastPage":false,"hasPreviousPage":false,"hasNextPage":true,"navigatePages":8,"navigatepageNums":[1,2,3,4,5,6,7,8],"navigateFirstPage":1,"navigateLastPage":8,"firstPage":1,"lastPage":8},"keySearch":"客户","list":[{"userId":99,"name":"客户评分卡-有盾","versionCode":"SC_test_card2","description":"客户评分卡-有盾值","version":null,"parentId":1076,"userId":135,"author":135,"authorName":"管理员","engineId":211,"type":1,"status":1,"sFieldList":[],"sContentList":[],"created":1520236208000,"updated":1615889385000,"checked":false,"score":"{\"output\":{\"field_id\":0,\"field_code\":\"score\",\"field_name\":\"信用得分\",\"field_type\":1},\"formula\":\"300+#{f_yd_realNameScore}\",\"formula_show\":\"300+@有盾实名认证分值@\",\"fields\":[{\"field_id\":642,\"field_code\":\"f_yd_realNameScore\",\"field_type\":1,\"field_name\":\"有盾实名认证分值\",\"segments\":[{\"segment\":\"(,29]\",\"dictValue\":0},{\"segment\":\"(29,69]\",\"dictValue\":50},{\"segment\":\"(69,)\",\"dictValue\":100}]}]}","pd":null,"odds":null,"engineName":null,"organId":46,"sRuleContentList":[]}]}}
*/
@RequestMapping(value = "/cardList", method = RequestMethod.POST)
public ResponseEntityDto<Object> getCardNode(@RequestBody Map<String, Object> param) {
Long nodeId = Long.parseLong(param.get("nodeId").toString());
Integer pageNo = param.get("pageNo") == null ? 1 : Integer.parseInt(param.get("pageNo").toString());
Integer pageSize = param.get("pageSize") == null ? 10 : Integer.parseInt(param.get("pageSize").toString());
String keySearch = "1";
param.put("status", StringUtil.toLongList(param.get("status").toString()));
PageHelper.startPage(pageNo, pageSize);
List<Scorecard> list = scorecardService.getScorecardList(param);
// 回显
if (nodeId != null && nodeId != 0) {
EngineNode byId = engineNodeService.findById(nodeId);
if (byId != null) {
//获取评分卡id
//long knowledgeId = nodeKnowledge.getKnowledgeId();//
if (StringUtils.isNotBlank(byId.getNodeJson())) {
// && !"".equals(byId.getNodeJson())
// long knowledgeId = Long.valueOf(byId.getNodeJson());
long knowledgeId = 0;
if(byId.getNodeJson()!=null&&!byId.getNodeJson().contains("{")){
knowledgeId = StringUtil.getStrToLong(byId.getNodeJson());
}
//原来存储id现在被转换为存储的是json
Map<Long,Long> scorecardIdMap = new HashMap();
if (knowledgeId == 0) {
try {
JSONObject jsonObject = JSON.parseObject(byId.getNodeJson());
JSONArray scorecardList = jsonObject.getJSONArray("scorecardList");
if (scorecardList!=null&&!scorecardList.isEmpty()){
for (int i = 0; i < scorecardList.size(); i++) {
JSONObject scorecard = scorecardList.getJSONObject(i);
scorecardIdMap.put(scorecard.getLong("scorecardId"),scorecard.getLong("versionId"));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}else {
ScorecardVersionVo version = scorecardVersionService.queryById(knowledgeId);
if (version!=null){
scorecardIdMap.put(version.getScorecardId(),version.getId());
}
}
//判断并回显
if (scorecardIdMap != null&& !scorecardIdMap.isEmpty() && list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
Long cardId = list.get(i).getId();
if (scorecardIdMap.containsKey(cardId)) {
ScorecardVo scorecardInfo = scorecardService.getScorecardInfo(cardId);
scorecardInfo.setChecked(true);
scorecardInfo.setCheckedId(scorecardIdMap.get(cardId));
list.set(i, scorecardInfo);
}
}
}
}
}
}
PageInfo<Scorecard> pageInfo = new PageInfo<>(list);
if (param.containsKey("dictValue")) {
keySearch = param.get("dictValue").toString();
}
HashMap<String, Object> modelMap = new HashMap<>();
modelMap.put("list", list);
modelMap.put("pager", pageInfo);
modelMap.put("keySearch", keySearch);
return ResponseEntityBuilder.buildNormalResponse(modelMap);
}
}

View File

@@ -0,0 +1,67 @@
package com.fibo.ddp.enginex.riskengine.runner.api;
import com.fibo.ddp.common.service.common.runner.RunnerSessionManager;
import com.fibo.ddp.common.service.common.runner.SessionData;
import com.fibo.ddp.enginex.riskengine.runner.business.DecisionApiBizData;
import com.fibo.ddp.enginex.riskengine.runner.business.DecisionApiRequest;
import com.fibo.ddp.enginex.riskengine.runner.business.RiskEngineBusiness;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("runner")
public class RiskEngineApi {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
public RiskEngineBusiness riskEngineBusiness;
@RequestMapping(value = "/decision", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public String decision(@RequestBody DecisionApiRequest apiRequest) {
long start = System.currentTimeMillis();
DecisionApiBizData bizData = apiRequest.getBiz_data();
Map<String, Object> map = new HashMap<>();
map.put("pid", bizData.getBusinessId());
map.put("uid", "");
map.put("reqType", 1);
map.put("engineId", bizData.getEngineId());
map.put("organId", bizData.getOrganId());
SessionData sessionData = new SessionData();
sessionData.setOrganId(bizData.getOrganId());
sessionData.setEngineId(bizData.getEngineId());
sessionData.setReqType(1);
RunnerSessionManager.setSession(sessionData);
if(bizData.getFields() != null){
map.put("fields", bizData.getFields());
} else {
map.put("fields", new HashMap<>());
}
String result = riskEngineBusiness.engineApi(map);
long end = System.currentTimeMillis();
logger.info("============ 接口调用耗时:{}ms ============", (end -start));
return result;
}
@RequestMapping(value = "/batchExecute", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public List batchExecute(@RequestBody List<DecisionApiRequest> requestList){
List<String> list = new ArrayList<>();
for (DecisionApiRequest apiRequest : requestList) {
String decision = this.decision(apiRequest);
list.add(decision);
}
return list;
}
}

View File

@@ -0,0 +1,18 @@
package com.fibo.ddp.enginex.riskengine.runner.business;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Map;
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public class DecisionApiBizData {
private String businessId; // 业务id
private Long organId; // 组织id
private Long engineId; // 引擎id
private Map<String, Object> fields; // 指标字段键值对
}

View File

@@ -0,0 +1,17 @@
package com.fibo.ddp.enginex.riskengine.runner.business;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public class DecisionApiRequest {
private String tp_code; // 调用方编码
private String timestamp; // 精确到毫秒
private String sign; // 签名
private String biz_enc; // biz_data加密方式0不加密1加密
private DecisionApiBizData biz_data; // 请求的业务数据json格式的字符串
}

View File

@@ -0,0 +1,8 @@
package com.fibo.ddp.enginex.riskengine.runner.business;
import java.util.Map;
public interface RiskEngineBusiness {
String engineApi(Map<String, Object> paramJson);
}

View File

@@ -0,0 +1,558 @@
package com.fibo.ddp.enginex.riskengine.runner.business.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.dao.enginex.risk.EngineResultSetMapper;
import com.fibo.ddp.common.model.enginex.risk.Engine;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.enginex.risk.EngineResultSet;
import com.fibo.ddp.common.model.enginex.risk.EngineVersion;
import com.fibo.ddp.common.model.monitor.decisionflow.MonitorNode;
import com.fibo.ddp.common.service.enginex.risk.EngineNodeService;
import com.fibo.ddp.common.service.enginex.risk.EngineService;
import com.fibo.ddp.common.service.enginex.risk.EngineVersionService;
import com.fibo.ddp.common.service.monitor.runner.MonitorCenterFactoryRunner;
import com.fibo.ddp.common.service.monitor.runner.MonitorCommonService;
import com.fibo.ddp.common.service.monitor.runner.hbase.IFeatureRecordService;
import com.fibo.ddp.common.utils.constant.enginex.NodeTypeEnum;
import com.fibo.ddp.common.utils.constant.monitor.MonitorStorageType;
import com.fibo.ddp.enginex.riskengine.runner.business.RiskEngineBusiness;
import com.fibo.ddp.enginex.runner.node.impl.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.client.AsyncRestTemplate;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class RiskEngineBusinessImpl implements RiskEngineBusiness {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
public EngineService engineService;
@Resource
public EngineVersionService engineVersionService;
@Resource
public EngineNodeService engineNodeService;
@Resource
public EngineResultSetMapper resultSetMapper;
@Resource
private DecisionTablesNode decisionTablesNode;
@Resource
private DecisionTreeNode decisionTreeNode;
@Autowired
private DecisionOptionsNode decisionOptionsNode;
@Autowired
private ScorecardNode scorecardNode;
@Autowired
private RuleSetNode ruleSetNode;
@Autowired
private GroupNode groupNode;
@Autowired
private ModelNode modelNode;
@Autowired
private ChildEngineNode childEngineNode;
@Autowired
private BlackOrWhiteNode blackOrWhiteNode;
@Autowired
private AggregationNode aggregationNode;
@Autowired
private ParallelNode parallelNode;
@Autowired
private ChampionChallengeNode championChallengeNode;
@Autowired
private RpcNode rpcNode;
@Autowired
private SandboxProportionNode sandboxProportionNode;
@Autowired
private MonitorCommonService monitorCommonService;
@Autowired
private IFeatureRecordService featureRecordService;
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Autowired(required = false)
private AsyncRestTemplate asyncRestTemplate;
@Value("${monitor.data.storage.type}")
private String storageType;
@Override
public String engineApi(Map<String, Object> paramJson) {
logger.info("请求参数paramJson: {}", JSONObject.toJSONString(paramJson));
JSONObject jsonObject = new JSONObject();
JSONArray resultJson = new JSONArray();
Map<String, Map<String, Object>> featureMaps = new ConcurrentHashMap<>();
Long organId = Long.valueOf(paramJson.get("organId").toString());
Long engineId = Long.valueOf(paramJson.get("engineId").toString());
//获取引擎信息
Engine engine = engineService.getEngineById(engineId);
//获取引擎正在运行中的版本
EngineVersion engineVersion = engineVersionService.getRunningVersion(engineId);
if (engineVersion == null) {
jsonObject.put("status", "0x0004");
jsonObject.put("msg", "请求引擎不存在或尚未部署运行");
jsonObject.put("data", resultJson);
return jsonObject.toString();
}
//返回引擎下的所有节点集合
List<EngineNode> engineNodeList = engineNodeService.getEngineNodeListByVersionId(engineVersion.getVersionId());
Map<String, EngineNode> engineNodeMap = getEngineNodeListByMap(engineNodeList);
try {
//变量池
Map<String, Object> inputParam = new ConcurrentHashMap<>();
inputParam.putAll(JSONObject.parseObject(JSONObject.toJSONString(paramJson.get("fields")), Map.class));
EngineNode engineNode = engineNodeMap.get("ND_START");
if (null != engineNode && null != engineNode.getNextNodes()) {
//返回输出结果
Map<String, Object> outMap = new ConcurrentHashMap<>();
// 记录执行前全量指标
featureMaps.put("before", inputParam);
//节点执行方法
recursionEngineNode(inputParam, engineNodeMap.get(engineNode.getNextNodes()), engineNodeMap, outMap);
jsonObject.put("status", "0x0000");
jsonObject.put("msg", "执行成功");
//记录执行后的全量指标
featureMaps.put("after", inputParam);
paramJson.put("versionId", engineNode.getVersionId());
// featureRecordService.recordAllFeature(featureMaps, engine, paramJson);
String json = JSONObject.toJSONString(inputParam);
jsonObject.put("input", JSONObject.parseObject(json));
EngineResultSet resultSet = new EngineResultSet();
resultSet.setEngineCode(engine.getCode());
resultSet.setInput(json);
resultSet.setEngineId(engine.getId());
resultSet.setEngineName(engine.getName());
resultSet.setType(2);
resultSet.setSubVersion(engineVersion.getSubVersion());
resultSet.setUid(String.valueOf(paramJson.get("uid")));
resultSet.setPid(String.valueOf(paramJson.get("pid")));
// 节点终止输出
if (outMap.containsKey("result")) {
resultSet.setResult(outMap.get("result").toString());
//决策选项输出
jsonObject.put("result", outMap.get("result").toString());
}
// 黑名单节点输出
if (outMap.containsKey("blackJson")) {
resultJson.add(new JSONObject().parse(outMap.get("blackJson").toString()));
}
// 白名单节点输出
if (outMap.containsKey("whiteJson")) {
resultJson.add(new JSONObject().parse(outMap.get("whiteJson").toString()));
}
// 规则集节点输出
if (outMap.containsKey("ruleJson")) {
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 2);
ruleJson.put("resultJson", outMap.get("ruleJson"));
resultJson.add(ruleJson);
}
// 评分卡节点输出
if (outMap.containsKey("scoreJson")) {
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 4);
ruleJson.put("resultJson", outMap.get("scoreJson"));
resultJson.add(ruleJson);
}
// 决策选项节点输出
if (outMap.containsKey("decisionJson")) {
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 9);
ruleJson.put("resultJson", outMap.get("decisionJson"));
resultJson.add(ruleJson);
}
// 子引擎节点输出
if (outMap.containsKey("childEngineJson")) {
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 14);
ruleJson.put("resultJson", outMap.get("childEngineJson"));
resultJson.add(ruleJson);
}
// 模型节点输出
if (outMap.containsKey("modelJson")) {
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 15);
ruleJson.put("resultJson", outMap.get("modelJson"));
resultJson.add(ruleJson);
}
// 决策表节点输出
if (outMap.containsKey("decisionTablesJson")) {
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 16);
ruleJson.put("resultJson", outMap.get("decisionTablesJson"));
resultJson.add(ruleJson);
}
// 决策树节点输出
if (outMap.containsKey("decisionTreeJson")) {
JSONObject ruleJson = new JSONObject();
ruleJson.put("resultType", 17);
ruleJson.put("resultJson", outMap.get("decisionTreeJson"));
resultJson.add(ruleJson);
}
jsonObject.put("data", resultJson);
String result = JSONObject.toJSONString(jsonObject);
JSONObject tmpJsonObject = JSONObject.parseObject(result);
tmpJsonObject.remove("input");
resultSet.setOutput(JSONObject.toJSONString(tmpJsonObject));
resultSetMapper.insertResultSet(resultSet);
Integer resultId = resultSet.getId();
// this.monitorDecisionFlow(inputParam, engine, engineVersion, engineNodeList, outMap, paramJson, resultId);
// 正常返回结果回调
decisionCallback(engine.getCallbackUrl(), paramJson, result);
}
} catch (Exception e) {
logger.error("接口请求异常", e);
jsonObject.put("status", "0x0005");
jsonObject.put("msg", "执行失败");
jsonObject.put("data", resultJson);
// 异常回调
decisionCallback(engine.getCallbackUrl(), paramJson, "执行失败");
}
return jsonObject.toString();
}
/**
* 决策流监控
*
* @param inputParam
* @param engine
* @param engineVersion
* @param engineNodeList
* @param outMap
* @param paramJson
* @param resultId
*/
private void monitorDecisionFlow(Map<String, Object> inputParam, Engine engine, EngineVersion engineVersion, List<EngineNode> engineNodeList, Map<String, Object> outMap, Map<String, Object> paramJson, Integer resultId) {
switch (storageType) {
case MonitorStorageType.Mysql:
MonitorCenterFactoryRunner.getMonitorCenterServiceImp(MonitorStorageType.Mysql).monitorDecisionFlow(inputParam, engine, engineVersion, engineNodeList, outMap, paramJson, resultId);
break;
case MonitorStorageType.HBase:
MonitorCenterFactoryRunner.getMonitorCenterServiceImp(MonitorStorageType.HBase).monitorDecisionFlow(inputParam, engine, engineVersion, engineNodeList, outMap, paramJson, resultId);
break;
default:
logger.info("检查监控存储类型配置是否正确");
break;
}
}
/**
* 递归执行节点
*
* @param inputParam
* @param engineNode
* @param engineNodeMap
* @param outMap
*/
private EngineNode recursionEngineNode(Map<String, Object> inputParam, EngineNode engineNode, Map<String, EngineNode> engineNodeMap, Map<String, Object> outMap) {
logger.info("请求参数--" + "inputParam:" + JSONObject.toJSONString(inputParam));
EngineNode resultNode = null; // 结束时返回节点: 串行流程返回null、并行流程返回聚合节点
if (engineNode == null) {
return null;
}
// 获取节点所需的指标
getNodeField(engineNode, inputParam);
// 执行节点逻辑
runNode(engineNode, inputParam, outMap);
//用于存储执行过的节点
List<String> executedNodeList = new ArrayList<>();
//用于存储执行过的节点以及其对应的配置信息(节点id,对应的配置信息,以及结果)
List<MonitorNode> monitorNodeInfoList = new ArrayList<>();
if (outMap.containsKey("monitorNodes")) {
monitorNodeInfoList = (List<MonitorNode>) outMap.get("monitorNodes");
}
if (outMap.containsKey("executedNodes")) {
executedNodeList = (List<String>) outMap.get("executedNodes");
}
executedNodeList.add(engineNode.getNodeId() + "");
// 更新执行过节点数组
outMap.put("executedNodes", executedNodeList);
monitorCommonService.buildMonitorNode(inputParam, engineNode, outMap, monitorNodeInfoList);
// 所有节点监控信息数组放入 输出变量池中
outMap.put("monitorNodes", monitorNodeInfoList);
// 递归执行下一个节点
if (StringUtils.isNotBlank(engineNode.getNextNodes())) {
if (engineNode.getNodeType() == NodeTypeEnum.PARALLEL.getValue()) {
// 并行节点执行
EngineNode aggregationNode = parallelNode(inputParam, engineNode, engineNodeMap, outMap);
recursionEngineNode(inputParam, aggregationNode, engineNodeMap, outMap);
} else {
// 串行节点执行
EngineNode nextEngineNode = engineNodeMap.get(engineNode.getNextNodes());
//如果输出的map里面有nextNode则说明有分组需要走分组下面的节点
if (outMap.containsKey("nextNode")) {
nextEngineNode = engineNodeMap.get(outMap.get("nextNode"));
outMap.remove("nextNode");
}
if (nextEngineNode != null && nextEngineNode.getNodeType() == NodeTypeEnum.AGGREGATION.getValue()) {
// 并行节点后面的分支为多线程执行,执行到聚合节点则结束
resultNode = nextEngineNode;
} else {
resultNode = recursionEngineNode(inputParam, nextEngineNode, engineNodeMap, outMap);
}
}
}
return resultNode;
}
/**
* 并行节点处理(并行执行后面的分支,并返回最后的聚合节点)
*
* @param inputParam
* @param engineNode
* @param engineNodeMap
* @param outMap
* @return
*/
private EngineNode parallelNode(Map<String, Object> inputParam, EngineNode engineNode, Map<String, EngineNode> engineNodeMap, Map<String, Object> outMap) {
EngineNode aggregationNode = null; // 聚合节点code
String[] nextNodeArr = engineNode.getNextNodes().split(",");
List<CompletableFuture<EngineNode>> futureList = new ArrayList<>();
for (String nextNodeCode : nextNodeArr) {
CompletableFuture<EngineNode> future = CompletableFuture.supplyAsync(() -> {
EngineNode nextEngineNode = engineNodeMap.get(nextNodeCode);
EngineNode resultNode = recursionEngineNode(inputParam, nextEngineNode, engineNodeMap, outMap);
return resultNode;
}, threadPoolTaskExecutor);
futureList.add(future);
}
for (CompletableFuture<EngineNode> future : futureList) {
try {
EngineNode result = future.get();
aggregationNode = result;
} catch (Exception e) {
e.printStackTrace();
}
}
return aggregationNode;
}
/**
* 获取节点所需的指标
*
* @param engineNode
* @param inputParam
*/
private void getNodeField(EngineNode engineNode, Map<String, Object> inputParam) {
switch (engineNode.getNodeType()) {
case 2:
//规则
ruleSetNode.getNodeField(engineNode, inputParam);
break;
case 3:
//分组
groupNode.getNodeField(engineNode, inputParam);
break;
case 4:
//评分卡
scorecardNode.getNodeField(engineNode, inputParam);
break;
case 5:
//黑名单
blackOrWhiteNode.getNodeField(engineNode, inputParam);
break;
case 6:
//白名单
blackOrWhiteNode.getNodeField(engineNode, inputParam);
break;
case 9:
//决策选项
decisionOptionsNode.getNodeField(engineNode, inputParam);
break;
case 14:
//子引擎
childEngineNode.getNodeField(engineNode, inputParam);
break;
case 15:
//模型
modelNode.getNodeField(engineNode, inputParam);
break;
case 16:
//决策表
decisionTablesNode.getNodeField(engineNode, inputParam);
break;
case 17:
//决策树
decisionTreeNode.getNodeField(engineNode, inputParam);
break;
case 18:
//远程调用节点
rpcNode.getNodeField(engineNode, inputParam);
break;
case 19:
//并行节点
parallelNode.getNodeField(engineNode, inputParam);
break;
case 20:
//聚合节点
aggregationNode.getNodeField(engineNode, inputParam);
break;
case 21:
//冠军挑战节点
championChallengeNode.getNodeField(engineNode, inputParam);
break;
default:
break;
}
}
/**
* 执行节点逻辑
*
* @param engineNode
* @param inputParam
* @param outMap
*/
private void runNode(EngineNode engineNode, Map<String, Object> inputParam, Map<String, Object> outMap) {
switch (engineNode.getNodeType()) {
case 2:
//规则
ruleSetNode.runNode(engineNode, inputParam, outMap);
break;
case 3:
//分组
groupNode.runNode(engineNode, inputParam, outMap);
break;
case 4:
//评分卡
scorecardNode.runNode(engineNode, inputParam, outMap);
break;
case 5:
//黑名单
blackOrWhiteNode.runNode(engineNode, inputParam, outMap);
break;
case 6:
//白名单
blackOrWhiteNode.runNode(engineNode, inputParam, outMap);
break;
case 7:
//沙盒比例
sandboxProportionNode.runNode(engineNode, inputParam, outMap);
break;
case 9:
//决策选项
decisionOptionsNode.runNode(engineNode, inputParam, outMap);
break;
case 14:
//子引擎
childEngineNode.runNode(engineNode, inputParam, outMap);
break;
case 15:
//模型
modelNode.runNode(engineNode, inputParam, outMap);
break;
case 16:
//决策表
decisionTablesNode.runNode(engineNode, inputParam, outMap);
break;
case 17:
//决策树
decisionTreeNode.runNode(engineNode, inputParam, outMap);
break;
case 18:
//远程调用节点
rpcNode.runNode(engineNode, inputParam, outMap);
break;
case 19:
//并行节点
parallelNode.runNode(engineNode, inputParam, outMap);
break;
case 20:
//聚合节点
aggregationNode.runNode(engineNode, inputParam, outMap);
break;
case 21:
//冠军挑战节点
championChallengeNode.runNode(engineNode, inputParam, outMap);
break;
default:
break;
}
}
/**
* 把引擎节点以序号为key放入map
*
* @param nodelist 引擎节点
* @return map
* @see
*/
private Map<String, EngineNode> getEngineNodeListByMap(List<EngineNode> nodelist) {
Map<String, EngineNode> map = new HashMap<>();
for (int i = 0; i < nodelist.size(); i++) {
map.put(nodelist.get(i).getNodeCode(), nodelist.get(i));
}
return map;
}
/**
* 决策流执行完回调(包括决策流正常返回结果回调、以及异常回调)
*
* @param url
* @param paramJson
* @param result
*/
private void decisionCallback(String url, Map<String, Object> paramJson, String result) {
if (StringUtils.isBlank(url)) {
return;
}
Map<String, String> paramMap = new HashMap<>();
paramMap.put("paramJson", JSONObject.toJSONString(paramJson));
paramMap.put("result", result);
// 设置请求头
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
// 封装请求体
JSONObject body = JSONObject.parseObject(JSONObject.toJSONString(paramMap));
// 封装参数和头信息
HttpEntity<JSONObject> httpEntity = new HttpEntity(body, httpHeaders);
ListenableFuture<ResponseEntity<String>> future = asyncRestTemplate.postForEntity(url, httpEntity, String.class);
if (future != null) {
future.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
@Override
public void onFailure(Throwable throwable) {
logger.info("引擎回调异步调用失败", throwable);
}
@Override
public void onSuccess(ResponseEntity<String> stringResponseEntity) {
String result = stringResponseEntity.getBody();
logger.info("引擎回调异步调用成功result:{}", result);
}
});
}
}
}