Compare commits

...

48 Commits

Author SHA1 Message Date
9baf7220b9 开始 > 分组 > 聚合 > 决策选项 聚合之后节点不会执行问题bugfix 2025-04-27 14:16:18 +08:00
9ba4c9a98d 决策引擎接口 决策流监控数据写入 2025-03-25 14:29:14 +08:00
90f055b7eb 表结构增量更新sql整理 2025-03-04 16:29:17 +08:00
b629bcb059 新增决策表问题 待确认问题处理 ,不改字段映射 ,新增字段 2025-03-04 16:24:18 +08:00
4646cd6424 新增决策表 待确认问题 2025-03-04 16:11:23 +08:00
f1f84fc4b2 新增决策表bugfix 2025-03-04 16:11:07 +08:00
86f41c849f 修复决策新增因为实体类字段与数据库字段名称映射失败导致的报错 2025-02-19 15:51:52 +08:00
7eaa7de140 修复数字决策平台-引擎管理-引擎列表 点击引擎名称跳转因地址错误出现的403报错 2025-02-18 15:43:46 +08:00
刘通
afcf60ef4b Merge remote-tracking branch 'origin/feature/初版/base' into feature/初版/base 2025-02-18 15:03:36 +08:00
刘通
7cf69bb30c 左侧文件夹之前注释,现在放开 2025-02-18 15:03:24 +08:00
c35000738c 模型取值逻辑修改 ,使用原来的取值逻辑 2025-02-17 18:00:09 +08:00
74103d4663 bugs update ,t_machine_learning_models model_field 字段长度加长 2025-02-17 17:10:10 +08:00
97059278e1 bugs update 2025-02-17 14:43:45 +08:00
25f51b1293 bug列表更新 2025-02-17 14:00:11 +08:00
54da4065db add bugs 2025-02-17 13:56:27 +08:00
034b9c6ed5 /Riskmanage/info/status 免token 访问 2025-02-14 17:38:37 +08:00
9d034fb303 CommUtil 放到 util模块 ,增加 status http 接口 2025-02-14 17:07:53 +08:00
e87eab5460 版本更新 2025-02-14 16:54:01 +08:00
5b41070529 衍生指标优化及bugfix 2025-02-14 15:08:43 +08:00
2d4ddc2857 http 接口 请求 优化 ,post application/x-www-form-urlencoded 问题修复 2025-02-13 22:47:20 +08:00
2480af577b 添加 RestTemplateTest 2025-02-13 21:57:56 +08:00
16cf3dcd2d 各种空指针 bugfix 及 优化 2025-02-13 11:00:21 +08:00
3f42770cd6 FieldCallLog 增加默认构造函数 2025-02-13 08:41:19 +08:00
5044b3106b 增加 建表SQL t_list_db_version 2025-02-12 18:33:48 +08:00
2e59537866 本地缓存 优化 增加各种统计信息 2025-02-12 16:44:34 +08:00
3667ff7715 本地缓存 刷新 bugfix 2025-02-12 16:17:48 +08:00
f537ec0588 增加模型文件文件目录配置 model.uploadDir 2025-02-12 15:14:23 +08:00
217b499c26 模型字段取值bugfix 2025-02-12 15:07:47 +08:00
49644c99a9 缓存初始化加载 改为不抛异常 2025-02-12 14:05:35 +08:00
58204692a6 增加字段和模型本地缓存 2025-02-12 14:03:24 +08:00
554286c88c 模型取值逻辑修改 2025-02-11 22:49:14 +08:00
a8aece404d gitignore修改 2025-02-11 22:30:58 +08:00
36184d8cc2 增加pmml测试 2025-02-11 22:29:21 +08:00
a84ec9dff5 模型bugfix 2025-02-11 21:39:58 +08:00
刘通
f9f00ea4bd 机器学习模型上传文件问题修改 2025-02-11 16:11:12 +08:00
admin
ca6466d59a 风控bug代码优化:基础指标,SQL指标,常量指标,衍生指标页面 2025-01-15 10:33:21 +08:00
刘通
0430e8d010 删除不要的文件 2024-10-30 15:24:02 +08:00
刘通
9dde3cf3c2 first commit 2024-10-30 15:10:27 +08:00
FiboAI
35e92433e3 结尾 2022-08-10 17:57:40 +08:00
FiboAI
3ba4f8a341 登记表 2022-08-10 17:56:44 +08:00
FiboAI
a5bc7208cd 图片大小调整 2022-08-10 17:43:58 +08:00
FiboAI
d558598066 使用者图片 2022-08-10 17:37:27 +08:00
FiboAI
69f11309fb 交流群图片 2022-08-10 17:36:13 +08:00
FiboAI
a41e6b1a62 交流群 2022-08-10 15:47:00 +08:00
FiboAI
f2af0e874e Update README.md 2022-08-10 15:28:45 +08:00
FiboAI
2f87a91d59 客户名单 2022-08-10 15:12:28 +08:00
FiboAI
abbee93cbf Merge pull request #18 from andybbc/master
规则命中返回配置
2022-08-10 14:27:03 +08:00
andywang
34f868b21b 规则命中返回配置 2022-08-10 14:25:46 +08:00
79 changed files with 3460 additions and 2283 deletions

View File

View File

@@ -15,18 +15,7 @@ h5-datax-manager --- 指标中心前端代码
h5-enginex-manager -- 规则引擎前端代码
sql --- sql初始化脚本
## 开源交流
加官方微信号,进开源交流群。
![|](https://www.fibo.cn/standard/image/git_weixin.jpg)
扫描二维码添加WhatsApp。
![|](https://www.fibo.cn/standard/image/whatsApp.jpg)
## FiboRule整体功能架构介绍
FiboRule整体功能架构如下图所示
@@ -160,3 +149,23 @@ https://docs.qq.com/sheet/DSnpRV1JWdkNvaG9u
### 9 视频demo
https://www.bilibili.com/video/BV12N4y1L7Kt
### 10 使用者列表
至今多家公司的线上产品已接入FiboRule接入场景如银行信用卡保险理赔业务和政府大数据部门等。
<!-- ![使用者列表](https://www.fibo.cn/standard/image/git_customer.jpg) -->
> 更多接入的公司,欢迎在 [登记地址](https://github.com/FiboAI/FiboRule/issues/19 ) 登记,登记仅仅为了产品推广。
### 11 开源交流
加官方微信号,进开源交流群
![|](https://www.fibo.cn/standard/image/git_weixin1.jpg)
扫描二维码添加WhatsApp
![|](https://www.fibo.cn/standard/image/git_whatsApp1.jpg)
欢迎大家的关注和使用FiboRule也将拥抱变化持续发展。

25
bugs/note.txt Normal file
View File

@@ -0,0 +1,25 @@
BUG
基础指标模版下载报错
数据源指标编辑 这些变量值 没有绑定到界面上接口返回是ok的 ,前端需要改一下
引擎列表 点名称 一直加载中
决策复制版本 ,报错
t_machine_learning_models model_field (模型解析字段) 字段长度太小
ALTER TABLE t_machine_learning_models MODIFY COLUMN model_field varchar(4096) NOT NULL DEFAULT '' COMMENT '模型解析字段';
优化点:
数据中心 / 接口源 / 接口新建 修改 查看 请求地址 输入框加长
com.fibo.ddp.common.model.strategyx.decisiontable.DecisionTablesResult
TODO 注意 添加决策表 时 实际对应的字段是 ro 和 colum ,待确认

View File

@@ -167,4 +167,6 @@ public interface FieldMapper extends BaseMapper<Field> {
public Field findByFieldCnbyorganId(Map<String, Object> paramMap);
List<Field> selectFieldListByEns(@Param("ens")List<String> ens);
List<Field> getAllFieldList();
}

View File

@@ -367,6 +367,12 @@
<!-- )-->
</update>
<select id="getAllFieldList" resultType="com.fibo.ddp.common.model.datax.datamanage.Field">
select
<include refid="Base_Column"></include>
from t_field
</select>
<select id="getFieldList" parameterType="map" resultType="com.fibo.ddp.common.model.datax.datamanage.Field">
select
t.id,

View File

@@ -16,4 +16,7 @@ public interface MachineLearningModelsMapper extends BaseMapper<MachineLearningM
* @return
*/
List<MachineLearningModels> getModelsListByOrganId(@Param("organId") Integer organId, @Param("searchString") String searchString);
List<MachineLearningModels> getAllModelList();
}

View File

@@ -15,4 +15,12 @@
and (model_name like CONCAT('%',TRIM('${searchString}'),'%' ) or description like CONCAT('%',TRIM('${searchString}'),'%' ))
</if>
</select>
<select id="getAllModelList" resultType="com.fibo.ddp.common.model.strategyx.aimodel.MachineLearningModels">
select
<include refid="Base_Column_List" />
from t_machine_learning_models
where status = 1
</select>
</mapper>

View File

@@ -66,6 +66,11 @@ public class FieldCallLog implements Serializable {
*/
private Date updateTime;
public FieldCallLog(){
}
public FieldCallLog(Long fieldId, String fieldType,String sourceType,Long sourceId, String inputParam, String fieldValue, Long duration, Long organId) {
this.fieldId = fieldId;
this.fieldType = fieldType;

View File

@@ -0,0 +1,61 @@
package com.fibo.ddp.common.model.strategyx.aimodel;
import org.jpmml.evaluator.Evaluator;
import java.time.LocalDateTime;
public class ModelDTO {
public String createTime = LocalDateTime.now().toString();
private MachineLearningModels model;
private String errorMsg;
private String text;
private Evaluator evaluator;
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public MachineLearningModels getModel() {
return model;
}
public void setModel(MachineLearningModels model) {
this.model = model;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public Evaluator fetchEvaluator() {
return evaluator;
}
public String getEvaluatorInfo() {
return evaluator+"";
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public void setEvaluator(Evaluator evaluator) {
this.evaluator = evaluator;
}
}

View File

@@ -1,6 +1,7 @@
package com.fibo.ddp.common.model.strategyx.decisiontable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
@@ -29,9 +30,14 @@ public class DecisionTablesResult implements Serializable {
private Long versionId;//决策表版本id
private Integer rows;//行数
// 注意 添加决策表 时 实际对应的字段是 ro 和 colum ,待确认
private Integer columns;//列数
// 先注释 数据库表加字段 解决
// @TableField(value = "rowss")
private Integer ro;//行数
// @TableField(value = "columnss")
private Integer colum;//列数
private String resultValue;//结果集二维数组

View File

@@ -0,0 +1,214 @@
package com.fibo.ddp.common.service.cache;
import com.fibo.ddp.common.dao.datax.datamanage.FieldMapper;
import com.fibo.ddp.common.dao.strategyx.aimodel.MachineLearningModelsMapper;
import com.fibo.ddp.common.model.datax.datamanage.Field;
import com.fibo.ddp.common.model.strategyx.aimodel.MachineLearningModels;
import com.fibo.ddp.common.model.strategyx.aimodel.ModelDTO;
import com.fibo.ddp.common.service.strategyx.aimodel.PMMLExecutor.PMMLExecutor;
import com.fibo.ddp.common.utils.util.CommUtil;
import org.jpmml.evaluator.Evaluator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
@Service
public class LocalCacheService {
private static final Logger logger = LoggerFactory.getLogger(LocalCacheService.class);
//
private static final long ONE_SECOND_MS = 1000L;
// 10s
private static final long UPDATE_SLEEP_TIME_MS = 10 * ONE_SECOND_MS;
//
private final AtomicLong runCount = new AtomicLong(0);
// key is id
private volatile Map<String, Field> fieldsMap = new ConcurrentHashMap<>();
private volatile Map<String, ModelDTO> modelMap = new ConcurrentHashMap<>();
private final Map<String, String> infoMap = new ConcurrentHashMap<>();
private volatile boolean stop = false;
//
@Resource
FieldMapper fieldMapper;
@Autowired
MachineLearningModelsMapper machineLearningModelsMapper;
@Resource
PMMLExecutor pmmlExecutor;
private final String startTime = LocalDateTime.now().toString();
@PostConstruct
public void init() {
logger.info("LocalCacheService_init_start");
// 这里先不抛异常,后面会定时刷新缓存
updateAllCache(false);
// CommUtil.doSleep(UPDATE_SLEEP_TIME_MS);
Thread t = new LocalCacheUpdateThread();
t.start();
logger.info("LocalCacheService_init_done");
}
@PreDestroy
public void preDestroy(){
stop = true;
}
public Map<String,Object> getInfo(){
Map<String,Object> info = new HashMap<>();
info.put("VERSION",CommUtil.getVersion());
info.put("startTime",startTime);
info.put("runCount",runCount.longValue());
info.put("info",infoMap);
Map fieldsMapTmp = fieldsMap;
Map modelMapTmp = modelMap;
if(fieldsMapTmp!=null){
info.put("fieldsNum",fieldsMapTmp.size());
}
if(modelMapTmp!=null){
info.put("modelNum",modelMapTmp.size());
}
return info;
}
public Map<String, Field> getFieldsMap(){
return fieldsMap;
}
public Map<String, ModelDTO> getModelMap(){
return modelMap;
}
public void updateModelCache()throws Exception{
Map<String, ModelDTO> modelMapTmp = new ConcurrentHashMap<>();
List<MachineLearningModels> models = machineLearningModelsMapper.getAllModelList();
if(models!=null){
for(MachineLearningModels item:models){
Integer id = item.getId();
if(id==null){
continue;
}
String filePath = item.getFilePath();
// ModelDTO modelDTOOld = modelMap.get(id+"");
ModelDTO modelDTO = new ModelDTO();
modelDTO.setModel(item);
try {
Evaluator evaluator = pmmlExecutor.loadPmml(filePath);
modelDTO.setEvaluator(evaluator);
if (evaluator == null) {
modelDTO.setErrorMsg("evaluator_null");
}
}catch(Throwable e){
modelDTO.setErrorMsg("loadPmml_error,"+e);
}
modelMapTmp.put(id+"",modelDTO);
}
}
modelMap = modelMapTmp;
}
public void updateAllCache(boolean throwsError){
boolean error = false;
try{
updateFieldsCache();
}catch(Throwable e){
error = true;
infoMap.put("updateFieldsCache_error",LocalDateTime.now()+":"+e);
logger.error("updateFieldsCache_error",e);
}
try{
updateModelCache();
}catch(Throwable e){
error = true;
infoMap.put("updateModelCache_error",LocalDateTime.now()+":"+e);
logger.error("updateModelCache_error",e);
}
if(throwsError && error){
throw new RuntimeException("updateAllCacheError");
}
}
public void updateFieldsCache(){
Map<String, Field> fieldsMapTmp = new ConcurrentHashMap<>();
List<Field> fields = fieldMapper.getAllFieldList();
if(fields!=null) {
for(Field item:fields){
Long id = item.getId();
if(id!=null){
fieldsMapTmp.put(id+"",item);
}
}
}
fieldsMap = fieldsMapTmp;
}
private class LocalCacheUpdateThread extends Thread{
public void run(){
while(true) {
if(stop){
logger.info("LocalCacheUpdateThread_exit_for_stop");
break;
}
CommUtil.doSleep(UPDATE_SLEEP_TIME_MS);
runCount.getAndIncrement();
long start = System.currentTimeMillis();
updateAllCache(false);
long end = System.currentTimeMillis();
long time = end - start;
infoMap.put("updateAllCache_use_time",time+"MS");
infoMap.put("updateAllCache_time",LocalDateTime.now().toString());
}
}
}
}

View File

@@ -12,4 +12,5 @@ public class SessionData {
private Long organId; // 组织id
private Long engineId; // 引擎id
private Integer reqType;//请求类型
private Integer ruleHitRspConfig; // 规则命中返回配置默认10未命中不返回1未命中返回
}

View File

@@ -32,6 +32,8 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.client.AsyncRestTemplate;
@@ -244,20 +246,49 @@ public class InterfaceServiceImpl extends ServiceImpl<InterfaceMapper, Interface
// 请求参数中的变量赋值
String requestBody = setRequestBodyParams(interfaceInfo.getRequestBody(), inputParam);
if(HttpMethod.POST.name().equals(interfaceInfo.getMethod())){
HttpHeaders httpHeaders = new HttpHeaders();
// 设置请求头
httpHeaders.setAll(JSONObject.parseObject(interfaceInfo.getRequestHeaders(), Map.class));
// 封装请求体
JSONObject body = JSONObject.parseObject(requestBody);
// 封装参数和头信息
HttpEntity<JSONObject> httpEntity = new HttpEntity(body, httpHeaders);
// 发送请求
if(callType == 2){
responseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
} else {
listenableFuture = asyncRestTemplate.postForEntity(url, httpEntity, String.class);
final String requestHeaders = interfaceInfo.getRequestHeaders();
if(requestHeaders!=null && requestHeaders.contains(MediaType.APPLICATION_JSON_VALUE)) {
HttpHeaders httpHeaders = new HttpHeaders();
// 设置请求头
httpHeaders.setAll(JSONObject.parseObject(requestHeaders, Map.class));
// 封装请求体
JSONObject body = JSONObject.parseObject(requestBody);
// 封装参数和头信息
HttpEntity<JSONObject> httpEntity = new HttpEntity(body, httpHeaders);
// 发送请求
if (callType == 2) {
responseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
} else {
listenableFuture = asyncRestTemplate.postForEntity(url, httpEntity, String.class);
}
}else{
HttpHeaders httpHeaders = new HttpHeaders();
// 设置请求头
httpHeaders.setAll(JSONObject.parseObject(interfaceInfo.getRequestHeaders(), Map.class));
// 封装请求体
JSONObject body = JSONObject.parseObject(requestBody);
MultiValueMap<String, Object> bodyMap = new LinkedMultiValueMap<>();
bodyMap.setAll(body);
// 封装参数和头信息
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity(bodyMap, httpHeaders);
// 发送请求
if (callType == 2) {
// 这里调用还是报错 ,已修复
// post http://47.99.93.74:8090/mockapi/hello2?name={name} 会报错
// java.lang.IllegalArgumentException: Not enough variable values available to expand 'name'
responseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
} else {
listenableFuture = asyncRestTemplate.postForEntity(url, httpEntity, String.class);
}
}
} else if(HttpMethod.GET.name().equals(interfaceInfo.getMethod())){
// 封装uri地址路径变量
Map<String, Object> uriVariables = new HashMap<>();

View File

@@ -75,14 +75,22 @@ public class CommonServiceImpl implements CommonService {
}
SessionData sessionData = RunnerSessionManager.getSession();
Long organId = sessionData.getOrganId();
List<Field> fieldList = fieldService.findFieldByIdsbyorganId(organId, ids);
List<Field> list = new ArrayList<>();
ids = new ArrayList<>();
for (int i = 0; i < fieldList.size(); i++) {
if (fieldList.get(i).getIsDerivative() == 1) {
ids.addAll(StringUtil.toLongList(fieldList.get(i).getOrigFieldId()));
} else
list.add(fieldList.get(i));
}
// 20250214 bugfix 这个不能放在 else分支里
// 否则后面取不到值
list.add(fieldList.get(i));
}
if (ids.size() > 0) {
List<Field> lists = fieldService.findFieldByIdsbyorganId(organId, ids);
@@ -140,17 +148,22 @@ public class CommonServiceImpl implements CommonService {
// 常量指标
// 常量JOSN指标直接获取定义好的常量的value
String value = field.getJsonValue();
inputParam.put(field.getFieldEn(), JSONObject.parseObject(value));
// inputParam.put(field.getFieldEn(), JSONObject.parseObject(value));
putValue(inputParam,field.getFieldEn(), value);
remainFields.remove(field);
} else if (field.getIsUseSql()) {
// 通过sql方式获取指标
Object value = getFieldValueBySql(field, inputParam);
inputParam.put(field.getFieldEn(), value);
// inputParam.put(field.getFieldEn(), value);
putValue(inputParam,field.getFieldEn(), value);
remainFields.remove(field);
} else if (field.getIsInterface()) {
// 解析接口指标
String value = getFieldValueByInterface(field, inputParam);
inputParam.put(field.getFieldEn(), value);
// inputParam.put(field.getFieldEn(), value);
putValue(inputParam,field.getFieldEn(), value);
remainFields.remove(field);
}
}
@@ -169,6 +182,17 @@ public class CommonServiceImpl implements CommonService {
return false;
}
private void putValue(Map map,String key,Object value){
// ConcurrentHashMap key value 不能为 null
if(key==null || value==null){
return;
}
map.put(key,value);
}
// 决策选项 测试时 ,这个方法 没被调用
@Override
public Map<String, Object> getFields(List<Field> fields, Map<String, Object> inputParam) {
logger.info("start getEngineField, fields:{},inputParam:{}", JSONObject.toJSONString(fields), JSONObject.toJSONString(inputParam));
@@ -355,9 +379,12 @@ public class CommonServiceImpl implements CommonService {
} else if (jedis != null) {
resultValue = jedis.eval(parameterMap.get("sqlStr").toString());
}
if (resultValue == null) {
throw new ApiException(ErrorCodeEnum.GET_DATABASE_FIELD_ERROR.getCode(), ErrorCodeEnum.GET_DATABASE_FIELD_ERROR.getMessage());
}
// 20250213 获取不到值 不报错
// com.fibo.ddp.common.utils.exception.ApiException: 获取数据库指标失败
// if (resultValue == null) {
// throw new ApiException(ErrorCodeEnum.GET_DATABASE_FIELD_ERROR.getCode(), ErrorCodeEnum.GET_DATABASE_FIELD_ERROR.getMessage());
// }
} finally {
// 执行完成后切换到系统数据源
DataSourceContextHolder.setDBType("default");
@@ -367,12 +394,24 @@ public class CommonServiceImpl implements CommonService {
}
long end = System.currentTimeMillis();
fieldCallLogService.save(new FieldCallLog(field.getId(), FieldTypeConsts.DATABASE,dataSource.getType(),dataSource.getId().longValue(),JSON.toJSONString(parameterMap),
JSON.toJSONString(resultValue),(end - start),field.getOrganId()));
toJSONString(resultValue),(end - start),field.getOrganId()));
logger.info("【获取数据库指标】fieldEn:{}, 耗时:{}, result:{}, parameterMap:{}", field.getFieldEn(), (end - start), resultValue, parameterMap);
return resultValue;
}
private String toJSONString(Object resultValue){
if(resultValue==null){
return null;
}
try{
return JSON.toJSONString(resultValue);
}catch(Throwable e){
logger.error("toJSONString_error,"+e);
return resultValue.toString();
}
}
/**
* 解析接口指标
*

View File

@@ -24,6 +24,7 @@ public class PMMLExecutorRFImpl implements PMMLExecutor {
@Override
public Evaluator loadPmml(String filePath) {
// String filePath = "D:\\models\\model_RF.pmml";
Evaluator modelEvaluator = null;
PMML pmml = new PMML();
InputStream inputStream = null;
@@ -52,10 +53,15 @@ public class PMMLExecutorRFImpl implements PMMLExecutor {
}
}
/*ModelEvaluatorFactory modelEvaluatorFactory = ModelEvaluatorFactory.newInstance();
Evaluator evaluator = modelEvaluatorFactory.newModelEvaluator(pmml,pmml.getModels().get(0));
pmml = null;*/
ModelEvaluatorBuilder modelEvaluatorBuilder = new ModelEvaluatorBuilder(pmml);
ModelEvaluatorFactory modelEvaluatorFactory = ModelEvaluatorFactory.newInstance();
Evaluator evaluator = modelEvaluatorFactory.newModelEvaluator(pmml);
pmml = null;
return evaluator;
modelEvaluatorBuilder.setModelEvaluatorFactory(modelEvaluatorFactory);
modelEvaluator = modelEvaluatorBuilder.build();
modelEvaluator.verify();
return modelEvaluator;
}
@Override
@@ -70,18 +76,33 @@ public class PMMLExecutorRFImpl implements PMMLExecutor {
}
Map<FieldName, ?> results = evaluator.evaluate(arguments);
System.out.println("pmml_predict_results: " + results);
List<TargetField> targetFields = evaluator.getTargetFields();
TargetField targetField = targetFields.get(0);
FieldName targetFieldName = targetField.getName();
Object targetFieldValue = results.get(targetFieldName);
System.out.println("target: " + targetFieldName.getValue() + ", value: " + targetFieldValue);
System.out.println("target: " + targetFieldName.getValue() + ", value: " + targetFieldValue+",valueType="+targetFieldValue.getClass());
double value_1 = 0.0f;
// 2025-02-11 新增
if(targetFieldValue instanceof Number){
Number tmpnum = (Number)targetFieldValue;
value_1 = tmpnum.doubleValue();
}
// TODO 模型取值逻辑待确认
if (targetFieldValue instanceof ProbabilityDistribution) {
value_1 = ((ProbabilityDistribution) targetFieldValue).getValue("1");
}
return value_1;
}

View File

@@ -81,7 +81,8 @@ public class ModelsServiceImpl extends ServiceImpl<MachineLearningModelsMapper,
String key = RedisUtils.getPrimaryKey(TableEnum.T_MACHINE_LEARNING_MODELS, id);
machineLearningModels = redisManager.getByPrimaryKey(key, MachineLearningModels.class);
} else {
machineLearningModels = this.selectById(id);
// machineLearningModels = this.selectById(id);
machineLearningModels = machineLearningModelsMapper.selectById(id);
}
return machineLearningModels;

View File

@@ -116,9 +116,9 @@ public class DecisionTablesResultServiceImpl extends ServiceImpl<DecisionTablesR
DecisionTablesResult resultInfo = new DecisionTablesResult();
BeanUtils.copyProperties(vo,resultInfo);
JSONArray resultList = vo.getResultList();
resultInfo.setRows(resultList.size());
resultInfo.setRo(resultList.size());
JSONArray childList = JSON.parseArray(JSON.toJSONString(resultList.get(0)));
resultInfo.setColumns(childList.size());
resultInfo.setColum(childList.size());
String resultValue = JSON.toJSONString(resultList);
resultInfo.setResultValue(resultValue);
return resultInfo;

View File

@@ -272,10 +272,7 @@ public class RuleServiceImpl extends ServiceImpl<RuleInfoMapper, RuleInfo> imple
@Override
public List<JSONObject> setComplexRuleOutput(Long versionId, Map<String,Object> temp, Map<String, Object> input, String outType) {
List<JSONObject> jsonObjectList = outputService.setOutput(new StrategyOutput(versionId, StrategyType.COMPLEX_RULE,outType), temp);
// for (JSONObject jsonObject : jsonObjectList) {
// input.putAll(jsonObject);
// }
List<JSONObject> jsonObjectList = outputService.setOutput(new StrategyOutput(versionId, StrategyType.COMPLEX_RULE,outType), input, temp);
return jsonObjectList;
}

View File

@@ -231,7 +231,7 @@ public class ListDbServiceImp extends ServiceImpl<ListDbMapper, ListDb> implemen
ListDb listDb = listDbMapper.selectById(id);
String tableName = "organ" + "_" + listDb.getOrganId() + "_" + listDb.getListType() + "_" + id;
// 插入多行数据 insertOne into user_info (user_account,user_name,user_age,user_class) values ('00001', '张三 ','20','计算机系'), ('00002', '李四','19','计算机系');
String sqlStr = "insertOne into " + tableName + "(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, user_id) values ";
String sqlStr = "insert into " + tableName + "(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, user_id) values ";
// 只取第一个Sheet页
sheet = workbook.getSheetAt(0);

View File

@@ -304,10 +304,10 @@ public class ScorecardVersionServiceImpl extends ServiceImpl<ScorecardVersionMap
}
scorecardDetailVo.setChildren(children);
Long userId = SessionManager.getLoginAccount().getUserId();
//Long userId = SessionManager.getLoginAccount().getUserId();
HashMap<String, Object> param = new HashMap<>();
param.put("userId", scorecardDetail.getFieldId());
param.put("userId", userId);
//param.put("userId", userId);
param.put("engineId", null);
Field field = fieldService.findByFieldId(param);
if (field != null) {

View File

@@ -24,5 +24,7 @@ public interface StrategyOutputService extends IService<StrategyOutput> {
List<JSONObject> setOutput(StrategyOutput entity, Map<String,Object> input);
List<JSONObject> setOutput(StrategyOutput entity, Map<String,Object> input, Map<String,Object> temp);
boolean judgeOutCondition(String condition,Map<String,Object> input);
}

View File

@@ -130,6 +130,11 @@ public class StrategyOutputServiceImpl extends ServiceImpl<StrategyOutputMapper,
//设置输出传入map向map中放入输出并且返回输出列表
@Override
public List<JSONObject> setOutput(StrategyOutput entity, Map<String, Object> input) {
return setOutput(entity, input, null);
}
@Override
public List<JSONObject> setOutput(StrategyOutput entity, Map<String, Object> input, Map<String,Object> temp) {
List<StrategyOutput> strategyOutputList = this.queryByTactics(entity);
List<JSONObject> jsonList = new ArrayList<>();
if (strategyOutputList != null && strategyOutputList.size() > 0) {
@@ -161,6 +166,9 @@ public class StrategyOutputServiceImpl extends ServiceImpl<StrategyOutputMapper,
if(!field.getIsLocalVariable()){
input.put(fieldEn, value);
}
if(temp != null){
temp.put(fieldEn, value);
}
jsonList.add(json);
}
}

View File

@@ -13,6 +13,7 @@ public class ServiceFilterConstant {
uriSet.add("/Riskmanage/v2/datamanage/datamanage/downTemplate");// 指标模板下载
uriSet.add("/Riskmanage/v2/datamanage/listmanage/downTemplate");// 名单库模板下载
uriSet.add("/Riskmanage/v3/analyse/decision");
uriSet.add("/Riskmanage/info/status");
}
public static boolean isSessionFilter(String uri) {

View File

@@ -0,0 +1,24 @@
package com.fibo.ddp.common.utils.util;
public class CommUtil {
private static final String VERSION = "2025-02-14 17:00";
public static String getVersion(){
return VERSION;
}
public static void doSleep(long time){
if(time<=0){
return;
}
try{
Thread.sleep(time);
}catch(Throwable e){
// do nothing
}
}
}

View File

@@ -157,8 +157,17 @@ public class JevalUtil {
}
//2代表字符串
if(value == 2){
String variableValue = CommonConst.SYMBOL_SINGLE_QUOTA+variablesMap.get(key).toString()+CommonConst.SYMBOL_SINGLE_QUOTA;
variablesMap.put(key, variableValue);
// 20250213 空指针修复
// String variableValue = CommonConst.SYMBOL_SINGLE_QUOTA+variablesMap.get(key).toString()+CommonConst.SYMBOL_SINGLE_QUOTA;
Object v = variablesMap.get(key);
if(v!=null) {
String variableValue = CommonConst.SYMBOL_SINGLE_QUOTA+v.toString()+CommonConst.SYMBOL_SINGLE_QUOTA;
variablesMap.put(key, variableValue);
}else{
String variableValue = CommonConst.SYMBOL_SINGLE_QUOTA+CommonConst.SYMBOL_SINGLE_QUOTA;
variablesMap.put(key, variableValue);
}
}
}
}

View File

@@ -1,5 +1,6 @@
package com.fibo.ddp.enginex.riskengine.runner.api;
import com.fibo.ddp.common.service.cache.LocalCacheService;
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;
@@ -27,6 +28,9 @@ public class RiskEngineApi {
@Autowired
public RiskEngineBusiness riskEngineBusiness;
@Autowired
LocalCacheService localCacheService;
@RequestMapping(value = "/decision", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public String decision(@RequestBody DecisionApiRequest apiRequest) {
long start = System.currentTimeMillis();
@@ -42,6 +46,7 @@ public class RiskEngineApi {
sessionData.setOrganId(bizData.getOrganId());
sessionData.setEngineId(bizData.getEngineId());
sessionData.setReqType(1);
sessionData.setRuleHitRspConfig(bizData.getRuleHitRspConfig());
RunnerSessionManager.setSession(sessionData);
if(bizData.getFields() != null){
@@ -64,4 +69,21 @@ public class RiskEngineApi {
}
return list;
}
@RequestMapping(value = "/getLocalCacheInfo")
public Object getLocalCacheInfo(){
return localCacheService.getInfo();
}
@RequestMapping(value = "/getFieldCache")
public Object getFieldCache(){
return localCacheService.getFieldsMap();
}
@RequestMapping(value = "/getModelCache")
public Object getModelCache(){
return localCacheService.getModelMap();
}
}

View File

@@ -15,4 +15,5 @@ public class DecisionApiBizData {
private Long organId; // 组织id
private Long engineId; // 引擎id
private Map<String, Object> fields; // 指标字段键值对
private Integer ruleHitRspConfig; // 规则命中返回配置0未命中不返回1未命中返回
}

View File

@@ -98,7 +98,7 @@ public class RiskEngineBusinessImpl implements RiskEngineBusiness {
logger.info("请求参数paramJson: {}", JSONObject.toJSONString(paramJson));
JSONObject jsonObject = new JSONObject();
JSONArray resultJson = new JSONArray();
Map<String, Map<String, Object>> featureMaps = new ConcurrentHashMap<>();
// Map<String, Map<String, Object>> featureMaps = new ConcurrentHashMap<>();
Long organId = Long.valueOf(paramJson.get("organId").toString());
Long engineId = Long.valueOf(paramJson.get("engineId").toString());
//获取引擎信息
@@ -124,13 +124,18 @@ public class RiskEngineBusinessImpl implements RiskEngineBusiness {
//返回输出结果
Map<String, Object> outMap = new ConcurrentHashMap<>();
// 记录执行前全量指标
featureMaps.put("before", inputParam);
// featureMaps.put("before", inputParam);
logger.info("recursionEngineNode_before_inputParam="+inputParam);
//节点执行方法
recursionEngineNode(inputParam, engineNodeMap.get(engineNode.getNextNodes()), engineNodeMap, outMap);
logger.info("recursionEngineNode_after_inputParam="+inputParam);
jsonObject.put("status", "0x0000");
jsonObject.put("msg", "执行成功");
//记录执行后的全量指标
featureMaps.put("after", inputParam);
// featureMaps.put("after", inputParam);
paramJson.put("versionId", engineNode.getVersionId());
// featureRecordService.recordAllFeature(featureMaps, engine, paramJson);
@@ -218,7 +223,12 @@ public class RiskEngineBusinessImpl implements RiskEngineBusiness {
resultSet.setOutput(JSONObject.toJSONString(tmpJsonObject));
resultSetMapper.insertResultSet(resultSet);
Integer resultId = resultSet.getId();
// this.monitorDecisionFlow(inputParam, engine, engineVersion, engineNodeList, outMap, paramJson, resultId);
// 20250325 去掉注释 ,写入监控表
try {
this.monitorDecisionFlow(inputParam, engine, engineVersion, engineNodeList, outMap, paramJson, resultId);
}catch(Exception e){
logger.error("monitorDecisionFlow_error", e);
}
// 正常返回结果回调
decisionCallback(engine.getCallbackUrl(), paramJson, result);
}
@@ -313,11 +323,16 @@ public class RiskEngineBusinessImpl implements RiskEngineBusiness {
nextEngineNode = engineNodeMap.get(outMap.get("nextNode"));
outMap.remove("nextNode");
}
if (nextEngineNode != null && nextEngineNode.getNodeType() == NodeTypeEnum.AGGREGATION.getValue()) {
// 会导致 开始 > 分组 > 聚合 > 决策选项 不会执行 ,先注释掉 20250427
// if (nextEngineNode != null && nextEngineNode.getNodeType() == NodeTypeEnum.AGGREGATION.getValue()) {
// 并行节点后面的分支为多线程执行,执行到聚合节点则结束
resultNode = nextEngineNode;
} else {
//resultNode = nextEngineNode;
//} else {
// resultNode = recursionEngineNode(inputParam, nextEngineNode, engineNodeMap, outMap);
//}
// 20250427 之前的逻辑 会导致 开始 > 分组 > 聚合 > 决策选项 不会执行 使用以下代码
if (nextEngineNode != null){
resultNode = recursionEngineNode(inputParam, nextEngineNode, engineNodeMap, outMap);
}
}

View File

@@ -24,7 +24,7 @@ import java.util.Optional;
* Canal数据同步
* 实现ApplicationRunner接口springboot启动成功后会执行run方法
*/
@Component
public class CanalClient implements ApplicationRunner {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

View File

@@ -210,7 +210,7 @@ public class DecisionTablesNode implements EngineRunnerNode {
if (row >= 0 && column >= 0) {
//根据行列去结果集中找结果返回
DecisionTablesResultVo resultSet = versionVo.getResultSet();
if (row < resultSet.getRows() && column < resultSet.getColumns()) {
if (row < resultSet.getRo() && column < resultSet.getColum()) {
String resultValue = resultSet.getResultValue();
JSONArray array = JSON.parseArray(resultValue);
JSONArray rowArray = JSON.parseArray(JSON.toJSONString(array.get(row)));

View File

@@ -2,9 +2,11 @@ package com.fibo.ddp.enginex.runner.node.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fibo.ddp.common.model.datax.datamanage.Field;
import com.fibo.ddp.common.model.enginex.risk.EngineNode;
import com.fibo.ddp.common.model.strategyx.aimodel.MachineLearningModels;
import com.fibo.ddp.common.model.strategyx.strategyout.StrategyOutput;
import com.fibo.ddp.common.service.cache.LocalCacheService;
import com.fibo.ddp.common.service.datax.runner.CommonService;
import com.fibo.ddp.common.service.datax.runner.ExecuteUtils;
import com.fibo.ddp.common.service.strategyx.aimodel.ModelsService;
@@ -37,6 +39,9 @@ public class ModelNode implements EngineRunnerNode {
@Resource
private StrategyOutputService outputService;
@Autowired
LocalCacheService localCacheService;
private List<Long> getExecuteVersionIdList(EngineNode engineNode) {
return ExecuteUtils.getExecuteIdList(engineNode, "modelId");
}
@@ -82,16 +87,26 @@ public class ModelNode implements EngineRunnerNode {
Map<String, Object> input = new HashMap<>();
String[] modelFieldArr = models.getModelField().split(",");
// mappingFieldArr 是 字段id t_field.id ,需要根据 id 取出 field_en
String[] mappingFieldArr = models.getMappingField().split(",");
// 获取字段缓存信息
Map<String, Field> fieldMap = localCacheService.getFieldsMap();
for (int i = 0; i < modelFieldArr.length; i++) {
input.put(modelFieldArr[i], inputParam.get(mappingFieldArr[i]));
String fieldId = mappingFieldArr[i];
// 根据字段id 获取字段英文名
String fieldEn = getFieldEnById(fieldMap,fieldId);
if(fieldEn!=null) {
input.put(modelFieldArr[i], inputParam.get(fieldEn));
}
}
// 调用模型
double modelResult = 0d;
try {
modelResult =pmmlExecutor.predict(evaluator, input);
}catch (Exception e){
logger.error("模型节点执行异常,node{}",engineNode);
logger.error("模型节点执行异常,node{}",engineNode,e);
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("nodeId", engineNode.getNodeId());
@@ -125,4 +140,17 @@ public class ModelNode implements EngineRunnerNode {
map.put(resultKey, executeResult);
ExecuteUtils.terminalCondition(engineNode, inputParam, outMap, map);
}
// 根据字段id 获取字段英文名
private static String getFieldEnById(Map<String, Field> fieldMap,String id){
if(fieldMap==null || id==null){
return null;
}
Field f = fieldMap.get(id);
if(f==null){
return null;
}
return f.getFieldEn();
}
}

View File

@@ -12,6 +12,8 @@ import com.fibo.ddp.common.model.strategyx.guiderule.vo.RuleBlockVo;
import com.fibo.ddp.common.model.strategyx.guiderule.vo.RuleConditionVo;
import com.fibo.ddp.common.model.strategyx.guiderule.vo.RuleVersionVo;
import com.fibo.ddp.common.model.strategyx.scriptrule.RuleScriptVersion;
import com.fibo.ddp.common.service.common.runner.RunnerSessionManager;
import com.fibo.ddp.common.service.common.runner.SessionData;
import com.fibo.ddp.common.service.datax.datamanage.FieldService;
import com.fibo.ddp.common.service.datax.runner.CommonService;
import com.fibo.ddp.common.service.datax.runner.ExecuteUtils;
@@ -346,12 +348,16 @@ public class RuleSetNode implements EngineRunnerNode {
}
String resultFieldEn = hitRuleBlock.getResultFieldEn();
String outputFieldEn = hitRuleBlock.getResultFieldEn();
if (resultFieldEn == null || "".equals(resultFieldEn)) {
resultFieldEn = "rule_" + rule.getId() + "_" + ruleVersion.getId() + "_" + hitRuleBlock.getId() + "_hitResult";
outputFieldEn = "ruleResult";
}
String scoreFieldEn = hitRuleBlock.getScoreFieldEn();
String outputScoreEn = hitRuleBlock.getScoreFieldEn();
if (StringUtils.isBlank(scoreFieldEn)) {
scoreFieldEn = "rule_" + rule.getId() + "_" + ruleVersion.getId() + "_" + hitRuleBlock.getId() + "_score";
outputScoreEn = "ruleScore";
}
input.put(resultFieldEn, "未命中");
//根据执行的最终结果处理此规则输出内容
@@ -361,27 +367,30 @@ public class RuleSetNode implements EngineRunnerNode {
ruleMap.put("ruleResult", "命中");
ruleMap.put("ruleScore", hitRuleBlock.getScore());
JSONObject scoreJson = new JSONObject();
resultJson.put(resultFieldEn, "命中");
resultJson.put(outputFieldEn, "命中");
fieldList.add(resultJson);
// if (StringUtils.isNotBlank(ruleVersion.getScoreFieldEn())) {
scoreJson.put(scoreFieldEn, hitRuleBlock.getScore());
scoreJson.put(outputScoreEn, hitRuleBlock.getScore());
fieldList.add(scoreJson);
input.put(scoreFieldEn, hitRuleBlock.getScore());
// }
input.put(resultFieldEn, "命中");
//处理此规则需要输出的内容
fieldList.addAll(ruleService.setComplexRuleOutput(hitRuleBlock.getId(), temp, input, StrategyType.OutType.SUCCESS_OUT));
ruleMap.put("fieldList", fieldList);
hitFlag = true;
ruleResultList.add(ruleMap);
} else {
resultJson.put(resultFieldEn, "未命中");
resultJson.put(outputFieldEn, "未命中");
ruleMap.put("ruleScore", 0);
input.put(scoreFieldEn, 0);
fieldList.add(resultJson);
fieldList.addAll(ruleService.setComplexRuleOutput(hitRuleBlock.getId(), temp, input, StrategyType.OutType.FAIL_OUT));
ruleMap.put("fieldList", fieldList);
SessionData sessionData = RunnerSessionManager.getSession();
if(sessionData.getRuleHitRspConfig() == null || sessionData.getRuleHitRspConfig() == 1){
ruleResultList.add(ruleMap);
}
}
ruleResultList.add(ruleMap);
return hitFlag;
}

View File

@@ -13,9 +13,9 @@ public class ConfigHolder {
private String redisHost;
@Value("${redis.port}")
private int redisPort;
@Value("${redis.db}")
private int redisDb;
@Value("${redis.password}")
private String redisPwd;
@Value("${redis.pool.maxTotal}")
private int redisMaxTotal;

View File

@@ -0,0 +1,41 @@
package com.fibo.ddp.manager.web.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fibo.ddp.common.model.common.ResponseEntityBuilder;
import com.fibo.ddp.common.model.common.ResponseEntityDto;
import com.fibo.ddp.common.model.common.message.template.entity.AppTemplate;
import com.fibo.ddp.common.model.common.message.template.vo.AppTemplateReqVo;
import com.fibo.ddp.common.service.common.SessionManager;
import com.fibo.ddp.common.service.common.message.template.AppTemplateService;
import com.fibo.ddp.common.utils.util.CommUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("info")
public class InfoController {
@Autowired
private AppTemplateService appTemplateService;
@RequestMapping("status")
public Object status(HttpServletRequest request){
Map map = new HashMap();
map.put("version", CommUtil.getVersion());
map.put("now", LocalDateTime.now().toString());
return map;
}
}

View File

@@ -1,12 +1,12 @@
server.port=8080
server.port=8082
server.servlet.context-path=/Riskmanage
logging.config=classpath:logging-config.xml
# mysql
spring.datasource.druid.url=jdbc:mysql://ip:3306/riskmanage?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.datasource.druid.username=<EFBFBD>˺<EFBFBD>
spring.datasource.druid.password=<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
spring.datasource.druid.url=jdbc:mysql://127.0.0.1:3306/riskmanage?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.datasource.druid.username=root
spring.datasource.druid.password=root123123
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.initialSize=20
spring.datasource.druid.minIdle=20
@@ -24,10 +24,10 @@ spring.datasource.druid.validation-query-timeout=500
spring.datasource.druid.filters=stat
# redis
redis.host=ip
redis.port=<EFBFBD>˿<EFBFBD>
redis.db=<EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD>
redis.password=<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
redis.host=127.0.0.1
redis.port=6379
redis.db=
redis.password=
redis.pool.maxTotal=3000
redis.pool.maxIdle=100
redis.pool.maxWait=1000
@@ -35,8 +35,8 @@ redis.pool.timeout=100000
# mail <20><>ѡ
spring.mail.host=smtp.exmail.qq.com
spring.mail.username=xxx
spring.mail.password=xxx
spring.mail.username=1404823045@qq.com
spring.mail.password=lt520111111
spring.mail.port=465
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.timeout=50000

View File

@@ -1 +1,68 @@
spring.profiles.active=dev
# spring.profiles.active=dev
server.port=8070
server.servlet.context-path=/Riskmanage
logging.config=classpath:logging-config.xml
# mysql
spring.datasource.druid.url=jdbc:mysql://120.27.225.67:9609/riskmanage?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.datasource.druid.username=riskmanage
spring.datasource.druid.password=riskmanage@Farben2023
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.initialSize=20
spring.datasource.druid.minIdle=20
spring.datasource.druid.maxActive=100
spring.datasource.druid.maxWait=60000
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=true
spring.datasource.druid.testOnReturn=false
spring.datasource.druid.poolPreparedStatements=true
spring.datasource.druid.maxOpenPreparedStatements=20
spring.datasource.druid.validationQuery=SELECT 1
spring.datasource.druid.validation-query-timeout=500
spring.datasource.druid.filters=stat
# redis
redis.host=127.0.0.1
redis.port=6379
redis.db=0
redis.password=
redis.pool.maxTotal=3000
redis.pool.maxIdle=100
redis.pool.maxWait=1000
redis.pool.timeout=100000
# mail
spring.mail.host=smtp.exmail.qq.com
spring.mail.username=xxx
spring.mail.password=xxx
spring.mail.port=465
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.timeout=50000
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.socketFactory.port=465
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.socketFactory.fallback=false
## hbase
spring.data.hbase.quorum: ip:2181
spring.data.hbase.rootDir: /usr/local/hbase/datatest
spring.data.hbase.nodeParent: /hbase
runner.url: http://localhost:8071
# hbase
monitor.data.storage.type=mysql
# canal
switch.use.cache=off
switch.canal.cache=off
canal.hostname=127.0.0.1
canal.port=11111
model.uploadDir=/tmp/model/upload/

View File

@@ -47,7 +47,9 @@ public class MonitorController {
Integer pageNo = param.get("pageNo") == null ? 1 : Integer.valueOf(param.get("pageNo").toString());
Integer pageSize = param.get("pageSize") == null ? 10 : Integer.valueOf(param.get("pageSize").toString());
PageHelper.startPage(pageNo, pageSize);
List<EngineResultSet> resultSets = MonitorCenterFactory.getMonitorCenterServiceImp(MonitorStorageType.HBase).getEngineResultSetBySegment(param);
// MonitorStorageType.HBase
// 20250325 MonitorStorageType.Mysql
List<EngineResultSet> resultSets = MonitorCenterFactory.getMonitorCenterServiceImp(MonitorStorageType.Mysql).getEngineResultSetBySegment(param);
PageInfo<EngineResultSet> pageInfo = new PageInfo<>(resultSets);
HashMap<String, Object> modelMap = new HashMap<>();
modelMap.put("pager", pageInfo);

View File

@@ -13,9 +13,9 @@ public class ConfigHolder {
private String redisHost;
@Value("${redis.port}")
private int redisPort;
@Value("${redis.db}")
private int redisDb;
@Value("${redis.password}")
private String redisPwd;
@Value("${redis.pool.maxTotal}")
private int redisMaxTotal;

View File

@@ -1,11 +1,11 @@
server.port=8081
server.port=8083
logging.config=classpath:logging-config.xml
# mysql
spring.datasource.druid.url=jdbc:mysql://ip:3306/riskmanage?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.datasource.druid.username=<EFBFBD>˺<EFBFBD>
spring.datasource.druid.password=<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
spring.datasource.druid.url=jdbc:mysql://127.0.0.1:3306/riskmanage?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.datasource.druid.username=root
spring.datasource.druid.password=root123123
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.initialSize=20
spring.datasource.druid.minIdle=20
@@ -23,10 +23,10 @@ spring.datasource.druid.validation-query-timeout=500
spring.datasource.druid.filters=stat
# redis
redis.host=ip
redis.port=<EFBFBD>˿<EFBFBD>
redis.db=1
redis.password=<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
redis.host=127.0.0.1
redis.port=6379
redis.db=
redis.password=
redis.pool.maxTotal=3000
redis.pool.maxIdle=100
redis.pool.maxWait=1000
@@ -34,8 +34,8 @@ redis.pool.timeout=100000
# mail
spring.mail.host=smtp.exmail.qq.com
spring.mail.username=xxx
spring.mail.password=xxx
spring.mail.username=1404823045@qq.com
spring.mail.password=lt520111111
spring.mail.port=465
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.timeout=50000

View File

@@ -1 +1,66 @@
spring.profiles.active=dev
# spring.profiles.active=dev
server.port=8071
logging.config=classpath:logging-config.xml
# mysql
spring.datasource.druid.url=jdbc:mysql://120.27.225.67:9609/riskmanage?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.datasource.druid.username=riskmanage
spring.datasource.druid.password=riskmanage@Farben2023
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.initialSize=20
spring.datasource.druid.minIdle=20
spring.datasource.druid.maxActive=100
spring.datasource.druid.maxWait=60000
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=true
spring.datasource.druid.testOnReturn=false
spring.datasource.druid.poolPreparedStatements=true
spring.datasource.druid.maxOpenPreparedStatements=20
spring.datasource.druid.validationQuery=SELECT 1
spring.datasource.druid.validation-query-timeout=500
spring.datasource.druid.filters=stat
# redis
redis.host=127.0.0.1
redis.port=6379
redis.db=0
redis.password=
redis.pool.maxTotal=3000
redis.pool.maxIdle=100
redis.pool.maxWait=1000
redis.pool.timeout=100000
# mail
spring.mail.host=smtp.exmail.qq.com
spring.mail.username=xxx
spring.mail.password=xxx
spring.mail.port=465
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.timeout=50000
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.socketFactory.port=465
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.socketFactory.fallback=false
# hbase no use
spring.data.hbase.quorum:127.0.0.1
spring.data.hbase.rootDir: /usr/local/hbase/datatest
spring.data.hbase.nodeParent: /hbase
# canal
switch.use.cache=off
switch.canal.cache=off
canal.hostname=127.0.0.1
canal.port=11111
# monitor
monitor.data.storage.type=mysql
model.uploadDir=/tmp/model/upload/

View File

@@ -77,7 +77,7 @@
<loggers>
<!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
<logger name="org.mybatis" level="info" additivity="false">
<logger name="org.mybatis" level="debug" additivity="false">
<AppenderRef ref="Console"/>
</logger>
<!--监控系统信息-->
@@ -86,7 +86,7 @@
<AppenderRef ref="Console"/>
</Logger>
<root level="info">
<root level="debug">
<appender-ref ref="Console"/>
<appender-ref ref="Filelog"/>
<appender-ref ref="RollingFileInfo"/>

View File

@@ -0,0 +1,74 @@
package pmml;
import com.fibo.ddp.common.service.strategyx.aimodel.PMMLExecutor.PMMLExecutor;
import com.fibo.ddp.common.service.strategyx.aimodel.PMMLExecutor.impl.PMMLExecutorRFImpl;
import org.jpmml.evaluator.InputField;
import org.jpmml.evaluator.OutputField;
import org.jpmml.evaluator.TargetField;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PmmlTest {
public static void main(String[] args)throws Exception{
PMMLExecutor pmmlExecutor = new PMMLExecutorRFImpl();
String file = "/Users/dugang/work/2025/risk/fibo-rule/ddp/ddp-runner-api/src/test/resources/demo001.pmml";
// 加载模型文件
org.jpmml.evaluator.Evaluator evaluator = pmmlExecutor.loadPmml(file);
System.out.println("summary="+ evaluator.getSummary());
List<InputField> inputFields = evaluator.getInputFields();
System.out.println("inputFields.size="+inputFields.size());
for(InputField item:inputFields){
System.out.println(item);
}
List<InputField> activeFields = evaluator.getActiveFields();
System.out.println("activeFields.size="+activeFields.size());
for(InputField item:activeFields){
System.out.println(item);
}
List<TargetField> targetFields = evaluator.getTargetFields();
System.out.println("targetFields.size="+targetFields.size());
for(TargetField item:targetFields){
System.out.println(item);
}
List<OutputField> outputFields = evaluator.getOutputFields();
System.out.println("outputFields.size="+outputFields.size());
for(OutputField item:outputFields){
System.out.println(item);
}
Map<String, Object> input = new HashMap<>();
input.put("x1",1.0);
input.put("x2",2.0);
double modelResult = pmmlExecutor.predict(evaluator, input);
System.out.println("modelResult="+modelResult);
input.put("x1","1.0");
input.put("x2","2.0");
modelResult = pmmlExecutor.predict(evaluator, input);
System.out.println("modelResult="+modelResult);
input.put("x1","1.7");
input.put("x2","2.1");
modelResult = pmmlExecutor.predict(evaluator, input);
System.out.println("modelResult="+modelResult);
}
}

View File

@@ -0,0 +1,46 @@
package pmml;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
public class RestTemplateTest {
public static void main(String[] args)throws Exception{
RestTemplate rt = new RestTemplate();
MultiValueMap<String, Object> map= new LinkedMultiValueMap<>();
map.add("name", "tiger");
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// 创建HTTP实体
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(map, headers);
// 发送POST请求
String url = "http://47.99.93.74:8090/mockapi/hello2";
String response = rt.postForObject(url, request, String.class);
System.out.println(response);
ResponseEntity<String> responseEntity = rt.postForEntity(url, request, String.class);
System.out.println(responseEntity.getBody());
}
}

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<PMML xmlns="http://www.dmg.org/PMML-4_4" version="4.4">
<Header copyright="Example Corp" description="Simple Linear Regression Model">
<Application name="Example App" version="1.0"/>
</Header>
<DataDictionary numberOfFields="3">
<DataField name="x1" optype="continuous" dataType="double"/>
<DataField name="x2" optype="continuous" dataType="double"/>
<DataField name="y" optype="continuous" dataType="double"/>
</DataDictionary>
<RegressionModel modelName="SimpleLinearRegression" functionName="regression">
<MiningSchema>
<MiningField name="x1" usageType="active"/>
<MiningField name="x2" usageType="active"/>
<MiningField name="y" usageType="predicted"/>
</MiningSchema>
<RegressionTable intercept="1.0">
<NumericPredictor name="x1" exponent="1" coefficient="0.5"/>
<NumericPredictor name="x2" exponent="1" coefficient="0.3"/>
</RegressionTable>
</RegressionModel>
</PMML>

View File

@@ -21,6 +21,7 @@ import org.jpmml.evaluator.Evaluator;
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.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
@@ -50,6 +51,13 @@ public class ModelsController {
@Autowired
private MachineLearningModelsMapper machineLearningModelsMapper;
@Value("${model.uploadDir}")
private String modelUploadDir;
private static final String SLASH = "/";
/**
* 获取模型列表信息
* @return
@@ -110,13 +118,16 @@ public class ModelsController {
while (iter.hasNext()) {
MultipartFile file = multiRequest.getFile(iter.next().toString());
if (file != null) {
String uploadDir = request.getSession().getServletContext().getRealPath("/") + "upload/models/fieldUpload/";
// String uploadDir = request.getSession().getServletContext().getRealPath("/") + "upload/models/fieldUpload/";
final String uploadDir = modelUploadDir;
logger.info("modelUploadDir="+modelUploadDir);
if (!new File(uploadDir).exists()) {
File dir = new File(uploadDir);
dir.mkdirs();
}
fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
String path = uploadDir + fileName;
final String path = buildPath(uploadDir,fileName);
logger.info("modelFilePath"+path);
//上传
file.transferTo(new File(path));
accessUrl = path;
@@ -138,6 +149,18 @@ public class ModelsController {
}
}
@RequestMapping(value = "getModelUploadDir")
public String getModelUploadDir(){
return modelUploadDir;
}
private String buildPath(String dir,String fileName){
if(dir.endsWith(SLASH)){
return dir + fileName;
}
return dir + SLASH + fileName;
}
/**
* 添加模型
* @param models

View File

@@ -247,13 +247,18 @@
<dependency>
<groupId>org.jpmml</groupId>
<artifactId>pmml-evaluator</artifactId>
<version>1.4.1</version>
<version>1.5.11</version>
</dependency>
<dependency>
<groupId>org.jpmml</groupId>
<artifactId>pmml-evaluator-extension</artifactId>
<version>1.4.1</version>
<version>1.5.11</version>
</dependency>
<!--<dependency>
<groupId>org.jpmml</groupId>
<artifactId>pmml-model</artifactId>
<version>1.7.1</version>
</dependency>-->
<!-- swagger -->
<dependency>

View File

@@ -5,7 +5,7 @@ switch (process.env.NODE_ENV) {
case 'development': // 开发环境代理地址
proxyObj = {
'/Riskmanage': {
target: 'http://47.102.125.25:80', // 开发环境
target: 'http://127.0.0.1:8082', // 开发环境
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/Riskmanage': '/Riskmanage'
@@ -13,7 +13,7 @@ switch (process.env.NODE_ENV) {
},
'/trading': {
target: 'http://47.242.85.45:80', // 开发环境
target: 'http://127.0.0.1:8083', // 开发环境
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/trading': '/trading'
@@ -84,6 +84,25 @@ switch (process.env.NODE_ENV) {
}
}
break
case 'produce': // 生产环境
proxyObj = {
'/Riskmanage': {
target: 'http://47.99.93.74:8099', // 生产环境
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/Riskmanage': '/Riskmanage'
}
},
'/trading': {
target: 'http://47.99.93.74:8099', // 开发环境
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/trading': '/trading'
}
}
}
break
}
module.exports = proxyObj

File diff suppressed because it is too large Load Diff

View File

@@ -108,7 +108,7 @@
methods: {
go(value) {
var url = window.location.href
if (value[url.split('#')[0]]) {
window.open(value[url.split('#')[0]])
} else {

View File

@@ -5,7 +5,7 @@ switch (process.env.NODE_ENV) {
case 'development': // 开发环境代理地址
proxyObj = {
'/Riskmanage': {
target: 'http://47.102.125.25:80', // 开发环境
target: 'http://127.0.0.1:8082', // 开发环境
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/Riskmanage': '/Riskmanage'
@@ -13,7 +13,7 @@ switch (process.env.NODE_ENV) {
},
'/trading': {
target: 'http://47.242.85.45:80', // 开发环境
target: 'http://127.0.0.1:8071', // 开发环境
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/trading': '/trading'
@@ -84,6 +84,25 @@ switch (process.env.NODE_ENV) {
}
}
break
case 'produce': // 生产环境
proxyObj = {
'/Riskmanage': {
target: 'http://47.99.93.74:8099', // 生产环境
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/Riskmanage': '/Riskmanage'
}
},
'/trading': {
target: 'http://47.99.93.74:8099', // 开发环境
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/trading': '/trading'
}
}
}
break
}
module.exports = proxyObj

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
"version": "4.2.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"serve": "vue-cli-service serve --mode development",
"serve:test": "vue-cli-service serve --mode test",
"serve:jia": "vue-cli-service serve --mode jia",
"serve:niu": "vue-cli-service serve --mode niu",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -54,7 +54,7 @@
</div> -->
<!-- 用户头像 -->
<div class="user-avator">
<img src="../../assets/img/img.jpg" />
<img src="../../assets/img/img2.png" />
</div>
<!-- 用户名下拉菜单 -->
<el-dropdown class="user-name" trigger="click" @command="handleCommand">

View File

@@ -2,8 +2,7 @@
<template>
<div class="cont_cont">
<div class="cont_left" v-loading="leftloading">
<div class="cont_left" v-loading="leftloading">
<div class="cont_header">
<p class="cont_header_title">{{title}}</p>
<p class="cont_header_subtitle">{{title}}</p>
@@ -16,26 +15,96 @@
</fileHome>
</div>
</div>
<div class="cont_right" v-loading="contloading" @click="tempHintLeft=null;tempHintTop=null;">
<div
class="cont_right"
v-loading="contloading"
@click="tempHintLeft = null; tempHintTop = null;">
<div v-if="!listRedact" class="search-form">
<el-form :model="searchForm" label-width="100px">
<el-row :gutter="20">
<!-- 用户名查询 -->
<el-col :span="6" v-for="item in getSearch" :key="item.name">
<el-form-item :label="item.name">
<el-input
v-if="item.type==='1'"
v-model="searchForm[item.key]"
placeholder="请输入用户名"></el-input>
</el-form-item>
</el-col>
</el-row>
<!-- 角色查询 -->
<!-- <el-col :span="6">
<el-form-item label="字段中文名">
<el-input v-model="searchForm.username" placeholder="请输入用户名"></el-input>
</el-form-item>
</el-col>
&lt;!&ndash; 注册日期查询 &ndash;&gt;
<el-col :span="6">
<el-form-item label="创建时间">
<el-date-picker v-model="searchForm.registrationDate" type="daterange" range-separator="至"
start-placeholder="开始日期" end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
</el-col>
&lt;!&ndash; 状态查询 &ndash;&gt;
<el-col :span="6">
<el-form-item label="状态">
<el-select v-model="searchForm.role" placeholder="状态">
<el-option label="启用" value="admin"></el-option>
<el-option label="禁用" value="user"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row> -->
<!-- 查询和重置按钮放在一行 -->
<el-row>
<el-col :span="24" class="button-container">
<el-form-item>
<el-button type="primary" @click="handleSearch">查询</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<div v-if="!listRedact">
<div v-if="showRight===false" class="cont_right_hint">
<div v-if="showRight === false" class="cont_right_hint">
请先选择左侧文件夹
</div>
<div v-else>
<div class="cont_right_top">
<div>
<el-button type="primary" @click="listRedact=true" :disabled="currid!=99999999?false:'disabled'">新增</el-button>
<!-- <el-button typeof="primary" @click="listRedact=true" :disabled="currid!=99999999?false:'disabled'">新增</el-button> -->
<el-button type="primary" @click="listRedact=true">新增</el-button>
<el-button type="danger" @click="using(-1)" :disabled="this.selection.length>0?false:'disabled'">删除</el-button>
<el-button type="success" @click="using(1)" :disabled="this.selection.length>0?false:'disabled'">启用</el-button>
<el-button type="warning" @click="using(0)" :disabled="this.selection.length>0?false:'disabled'">停用</el-button>
<!-- <el-select v-model="tempMove" placeholder="移动到:" style="margin-left: 10px;" :disabled="this.selection.length>0?false:'disabled'" filterable @change="mixinMoveChange"> -->
<el-select v-model="tempMove" placeholder="移动到:" style="margin-left: 10px;" :disabled="this.selection.length>0?false:'disabled'"
filterable @change="moveChange">
<el-option v-for="value in listunfold" :key="value.id" :label="value.name" :value="value.id" v-show="value.id!=99999999"></el-option>
</el-select>
<!-- <el-select
v-model="tempMove"
placeholder="移动到:"
style="margin-left: 10px;"
:disabled="this.selection.length > 0 ? false : 'disabled'"
filterable
@change="mixinMoveChange"> -->
<!-- <el-select
v-model="tempMove"
placeholder="移动到:"
style="margin-left: 10px;"
:disabled="this.selection.length > 0 ? false : 'disabled'"
filterable @change="moveChange">
<el-option
v-for="value in listunfold"
:key="value.id"
:label="value.name"
:value="value.id"
v-show="value.id != 99999999"></el-option>
</el-select> -->
<!-- 断点 准备移动 -->
</div>
<div v-if="getData.type==1">
<div v-if="getData.type == 1">
<el-button @click="upShow=true">批量导入</el-button>
<el-button @click="down">模板下载</el-button>
</div>
@@ -46,26 +115,35 @@
:cell-style="{padding: '10px'}">
<el-table-column type="selection" width="70">
</el-table-column>
<el-table-column v-for="item in getData.row" :key="item.id" :prop="item.row" :label="item.label" align="center">
<el-table-column
v-for="item in getData.row"
:key="item.id"
:prop="item.row"
:label="item.label"
align="center">
<template slot-scope="scope">
<span v-if="item.type==='Blooen'">
{{scope.row[item.row]?"":""}}
</span>
<span v-else-if="item.type==='State'">
{{scope.row[item.row]=="1"?'启用':'未启用'}}
</span>
<span v-else-if="item.type==='type'">
{{scope.row[item.row]=="1"?'':(scope.row[item.row]=="2"?'字符型':(scope.row[item.row]=="3"?'枚举型':(scope.row[item.row]=="4"?'小数型':(scope.row[item.row]=="5"?'数组型':(scope.row[item.row]=="6"?'JSON型':'')))))}}
</span>
<span v-else-if="item.fn">
{{item.fn(scope.row[item.row])}}
</span>
<span v-else-if="item.type==='Time'" style="white-space: nowrap;" class="contText">{{
new Date(scope.row[item.row]).toLocaleDateString().replace(/\//g, "-") + " " + new Date(scope.row[item.row]).toTimeString().substr(0, 8)
}}</span>
<span class="contText" v-else>
{{scope.row[item.row]}}
<span v-if="item.type === 'Blooen'">{{ scope.row[item.row] ? "是" : "否" }}</span>
<span v-else-if="item.type === 'State'">{{ scope.row[item.row] == "1" ? '启用' : '未启用' }}</span>
<span v-else-if="item.type === 'type'">
{{ scope.row[item.row] == "1"
? '数值型' : (scope.row[item.row] == "2"
? '字符型' : (scope.row[item.row] == "3"
? '枚举型' : (scope.row[item.row] == "4"
? '数型' : (scope.row[item.row] == "5"
? '数组型' : (scope.row[item.row] == "6"
? 'JSON型' : '')))))}}
</span>
<span v-else-if="item.fn">{{ item.fn(scope.row[item.row]) }}</span>
<span
v-else-if="item.type === 'Time'"
style="white-space: nowrap;"
class="contText">
{{ new Date(scope.row[item.row]).toLocaleDateString().replace(/\//g, "-")
+ " " +
new Date(scope.row[item.row]).toTimeString().substr(0, 8)
}}
</span>
<span class="contText" v-else>{{ scope.row[item.row] }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" size="s">
@@ -74,29 +152,43 @@
</template>
</el-table-column>
</el-table>
<el-pagination style="float: right;margin-right: 40px;margin-top: 40px;" :current-page="currPage"
@current-change="clickpage" background layout="prev, pager, next" :total="data.data.pager.total">
<el-pagination
style="float: right; margin-right: 40px; margin-top: 40px;"
:current-page="currPage"
@current-change="clickpage"
background
layout="prev, pager, next"
:total="data.data.pager.total">
</el-pagination>
</div>
</div>
</div>
</div>
<template v-else>
<dataManageRedact @close="listRedact=false;tempRedactId=0" @Ok="listRedact=false;tempRedactId=0;getlist();currPage=1"
:updata="getData.updatafield" :id='tempRedactId' :fieldTypeId="currid" :setsave="getData.setsave" :getInfo="getData.getInfo"
<dataManageRedact
@close="listRedact=false;tempRedactId=0"
@Ok="listRedact=false;tempRedactId=0;getlist();currPage=1"
:updata="getData.updatafield"
:id='tempRedactId'
:fieldTypeId="currid"
:setsave="getData.setsave"
:getInfo="getData.getInfo"
:ftype="getData.type"></dataManageRedact>
</template>
</div>
<el-dialog title="上传文件" :visible.sync="upShow" width="30%" :before-close="upShowClose">
<div style="margin: 0 auto;display: flex;justify-content: center;">
<el-upload class="upload-demo" ref="upload" action="doUpload" :limit="1" :file-list="fileList" :before-upload="beforeUpload"
v-loading="Uploadloading">
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<div slot="tip" class="el-upload__tip">只能上传excel文件且不超过5MB</div>
<div slot="tip" class="el-upload-list__item-name">{{fileName}}</div>
<el-upload
class="upload-demo"
ref="upload" action="doUpload"
:limit="1"
:file-list="fileList"
:before-upload="beforeUpload"
v-loading="Uploadloading">
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<div slot="tip" class="el-upload__tip">只能上传excel文件且不超过5MB</div>
<div slot="tip" class="el-upload-list__item-name">{{fileName}}</div>
</el-upload>
</div>
<span slot="footer" class="dialog-footer">
@@ -120,13 +212,14 @@
mixins: [
contmixin
],
components: {
fileHome,
dataManageRedact,
updateFieldFolder,
contNewFule
},
props: {
title: {
type: String,
@@ -136,8 +229,12 @@
type: Object,
default: null
},
getSearch: {
type: Array,
default: null
},
},
watch: {
list() {
if (this.list.length > 0) {
@@ -145,6 +242,7 @@
}
}
},
data() {
return {
list: [],
@@ -165,9 +263,11 @@
tempId: null,
listRedact: false, //新增页面开启
tempRedactId: 0,
selection: []
selection: [],
searchForm: {}
}
},
created() {
this.getData.getTree({
type: this.getData.type
@@ -176,6 +276,7 @@
this.clickCurrid(99999999)
})
},
methods: {
moveChange(e) { //移动文件夹
let arr = this.selection.map((value) => {
@@ -201,7 +302,6 @@
})
this.tempMove = ""
},
down() {
window.open(window.origin + '/Riskmanage/v2/datamanage/field/downTemplate')
},
@@ -221,12 +321,9 @@
type: 'success',
message: '删除成功!'
});
this.deepGetCurr(id, this.list, (value, item, index) => {
item.splice(index, 1)
})
}
this.leftloading = false
this.currid = 99999999
@@ -240,7 +337,6 @@
updatafilelist(params) {
this.leftloading = true
let tempNum = null
this.deepGetCurr(params.id, this.list, (value) => {
tempNum = value.parentId
})
@@ -270,8 +366,6 @@
this.leftloading = false
})
},
getlist() {
this.contloading = true
this.listRedact = false
@@ -284,7 +378,6 @@
this.data = res
this.contloading = false
})
},
clickpage(e) {
this.currPage = e
@@ -303,7 +396,6 @@
})
},
using(id) {
let arr = this.selection.map((value) => {
return value.id
})
@@ -311,23 +403,58 @@
this.$message.error('未选择任何文件');
return
}
let params = {
status: id,
ids: arr.join(','),
fieldTypeId: this.currid
}
this.getData.fieldusing(params).then(res => {
if (res.status == "1") {
this.$message({
message: '操作成功',
type: 'success'
});
this.getlist()
this.selection = []
this.$store.dispatch('reGetfielduser')
}
})
const operations = {
'-1': '删除',
'1': '启用',
'0': '停用'
};
let operationText = operations[id.toString()] || '未知操作';
this.$confirm(`此操作将永久${operationText}, 是否继续?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let params = {
status: id,
ids: arr.join(','),
fieldTypeId: this.currid
}
this.getData.fieldusing(params).then(res => {
if (res.status == "1") {
this.$message({
message: '操作成功',
type: 'success'
});
this.getlist()
this.selection = []
this.$store.dispatch('reGetfielduser')
}
})
}).catch(() => {
this.$message({
type: 'info',
message: `已取消${operationText}`
});
});
// let params = {
// status: id,
// ids: arr.join(','),
// fieldTypeId: this.currid
// }
// this.getData.fieldusing(params).then(res => {
// if (res.status == "1") {
// this.$message({
// message: '操作成功',
// type: 'success'
// });
// this.getlist()
// this.selection = []
// this.$store.dispatch('reGetfielduser')
// }
// })
},
newFileSure() {
this.leftloading = true
@@ -343,10 +470,13 @@
}
this.mixnewFileSure(params)
}
},
handleSearch() {
},
handleReset() {
},
}
}
</script>

View File

@@ -351,7 +351,6 @@ export default {
this.loading = true
this.getInfo(this.id, {}).then(res => {
this.loading = false
if (res.status === "1") {
this.jsonValue = JSON.stringify(JSON.parse(res.data.fieldVo.jsonValue), null, 4)
@@ -368,9 +367,12 @@ export default {
this.fid = res.data.fieldVo.fieldTypeId
this.isOutput = res.data.fieldVo.isOutput == 1 ? true : false
this.isLocalVariable = res.data.fieldVo.isLocalVariable
console.log("3333")
console.log(res.data.fieldVo.isDerivative)
console.log(res.data.fieldVo.isUseSql)
if (res.data.fieldVo.isDerivative) {
this.isDerivative = 'Derivative'
} else if (res.data.fieldVo.useSql) {
} else if (res.data.fieldVo.isUseSql) {
this.isDerivative = 'SQL'
this.SQLType = this.$store.state.Sourcelist.find(x => x.id == res.data.fieldVo
.dataSourceId).type

View File

@@ -4,7 +4,7 @@
<el-col :span="8">
<el-card shadow="hover" class="mgb20" style="height:252px;">
<div class="user-info">
<img src="../../assets/img/img.jpg" class="user-avator" alt />
<img src="../../assets/img/img2.png" class="user-avator" alt />
<div class="user-info-cont">
<div class="user-info-name">{{name}}</div>
<!-- <div>{{role}}</div> -->

View File

@@ -1,17 +1,22 @@
<template>
<div>
<cont title="指标管理" :getData="getDataFun"></cont>
</div>
</template>
<script>
import cont from '@/components/common/cont.vue'
import {
getfieldList,addfieldList,getfieldListTree,updatafieldList,getfieldsave,getfieldInfo,updatafield,fieldusing,fielddownTemplate,fieldupdata
getfieldList,
addfieldList,
getfieldListTree,
updatafieldList,
getfieldsave,
getfieldInfo,
updatafield,
fieldusing,
fielddownTemplate,
fieldupdata,
} from '@/api/index.js'
export default {
@@ -23,31 +28,33 @@
return {
getDataFun: {
type:1,
row: [ {
label: '序号',
row: 'id'
}, {
label: '字段名称',
row: 'fieldEn'
}, {
label: '字段中文名',
row: 'fieldCn'
}, {
label: '字段类型',
row: 'valueType',
type: 'type'
}, {
label: '状态',
row: 'status',
type: 'State'
}, {
label: '创建人',
row: 'nickName'
},{
label: '创建时间',
row: 'created',
type: 'Time'
} ],
row: [
{
label: '序号',
row: 'id'
}, {
label: '字段名称',
row: 'fieldEn'
}, {
label: '字段中文名',
row: 'fieldCn'
}, {
label: '字段类型',
row: 'valueType',
type: 'type'
}, {
label: '状态',
row: 'status',
type: 'State'
}, {
label: '创建人',
row: 'nickName'
}, {
label: '创建时间',
row: 'created',
type: 'Time'
}
],
redact: "dataManageRedact",
async getTree(e){
return await getfieldListTree(e).then(res => {
@@ -66,44 +73,36 @@
})
},
async updatalist(e) {
return await updatafieldList(e).then(res => {
return res
})
},
async setsave(e) {
return await getfieldsave(e).then(res => {
return res
})
},
async getInfo(e) {
// console.log(e)
return await getfieldInfo(e).then(res => {
return res
})
},
async updatafield(e) {
return await updatafield(e).then(res => {
return res
})
},
async fieldusing(e) {
return await fieldusing(e).then(res => {
return res
})
},
async down(e) {
return await fielddownTemplate(e).then(res => {
return res
})
},
async fieldsubmit(e) {
return await fieldupdata(e).then(res => {
return res
})
@@ -112,8 +111,4 @@
};
}
};
</script>
<style>
</style>
</script>

View File

@@ -28,31 +28,33 @@
return {
getDataFun: {
type: 3,
row: [{
label: '序号',
row: 'id'
}, {
label: '字段名称',
row: 'fieldEn'
}, {
label: '字段中文名',
row: 'fieldCn'
}, {
label: '字段类型',
row: 'valueType',
type:'type'
}, {
label: '状态',
row: 'status',
type: 'State'
}, {
label: '创建人',
row: 'nickName'
}, {
label: '创建时间',
row: 'created',
type: 'Time'
}, ],
row: [
{
label: '序号',
row: 'id'
}, {
label: '字段名称',
row: 'fieldEn'
}, {
label: '字段中文名',
row: 'fieldCn'
}, {
label: '字段类型',
row: 'valueType',
type:'type'
}, {
label: '状态',
row: 'status',
type: 'State'
}, {
label: '创建人',
row: 'nickName'
}, {
label: '创建时间',
row: 'created',
type: 'Time'
}
],
redact: "dataManageRedact",
async getTree(e){
return await getfieldListTree(e).then(res => {
@@ -66,49 +68,41 @@
})
},
async addlist(e) {
return await addfieldList(e).then(res => {
return res
})
},
async updatalist(e) {
return await updatafieldList(e).then(res => {
return res
})
},
async setsave(e) {
return await getfieldsave(e).then(res => {
return res
})
},
async getInfo(e) {
return await getfieldInfo(e).then(res => {
return res
})
},
async updatafield(e) {
return await updatafield(e).then(res => {
return res
})
},
async fieldusing(e) {
return await fieldusing(e).then(res => {
return res
})
},
async down(e) {
return await fielddownTemplate(e).then(res => {
return res
})
},
async fieldsubmit(e) {
return await fieldupdata(e).then(res => {
return res
})
@@ -117,8 +111,4 @@
};
}
};
</script>
<style>
</style>
</script>

View File

@@ -1,17 +1,22 @@
<template>
<div>
<cont title="数据源指标" :getData="getDataFun"></cont>
</div>
</template>
<script>
import cont from '@/components/common/cont.vue'
import {
getfieldList,addfieldList,getfieldListTree,updatafieldList,getfieldsave,getfieldInfo,updatafield,fieldusing,fielddownTemplate,fieldupdata
getfieldList,
addfieldList,
getfieldListTree,
updatafieldList,
getfieldsave,
getfieldInfo,
updatafield,
fieldusing,
fielddownTemplate,
fieldupdata
} from '@/api/index.js'
export default {
@@ -24,39 +29,40 @@
return {
getDataFun: {
type:2,
row: [ {
label: '序号',
row: 'id'
}, {
label: '字段名称',
row: 'fieldEn'
}, {
label: '字段中文名',
row: 'fieldCn'
}, {
label: '数据源类型',
row: 'dataSourceId',
fn:(res)=>{
let obj = this.$store.state.Sourcelist.find(x=>x.id==res)
return obj&&obj.type
},
}, {
label: '字段类型',
row: 'valueType',
type:'type'
}, {
label: '状态',
row: 'status',
type:'State'
}, {
label: '创建人',
row: 'nickName'
},{
label: '创建时间',
row: 'created',
type:'Time'
},],
row: [
{
label: '序号',
row: 'id'
}, {
label: '字段名称',
row: 'fieldEn'
}, {
label: '字段中文名',
row: 'fieldCn'
}, {
label: '数据源类型',
row: 'dataSourceId',
fn: (res) => {
let obj = this.$store.state.Sourcelist.find(x=>x.id == res)
return obj && obj.type
},
}, {
label: '字段类型',
row: 'valueType',
type:'type'
}, {
label: '状态',
row: 'status',
type:'State'
}, {
label: '创建人',
row: 'nickName'
},{
label: '创建时间',
row: 'created',
type:'Time'
}
],
redact:"dataManageRedact",
async getTree(e){
return await getfieldListTree(e).then(res => {
@@ -70,49 +76,41 @@
})
},
async addlist(e) {
return await addfieldList(e).then(res => {
return res
})
},
async updatalist(e) {
return await updatafieldList(e).then(res => {
return res
})
},
async setsave(e) {
return await getfieldsave(e).then(res => {
return res
})
},
async getInfo(e){
return await getfieldInfo(e).then(res=>{
return res
})
},
async updatafield(e){
return await updatafield(e).then(res=>{
return res
})
},
async fieldusing(e){
return await fieldusing(e).then(res=>{
return res
})
},
async down(e){
return await fielddownTemplate(e).then(res=>{
return res
})
},
async fieldsubmit(e){
return await fieldupdata(e).then(res=>{
return res
})

View File

@@ -1,17 +1,22 @@
<template>
<div>
<cont title="常量指标" :getData="getDataFun"></cont>
<cont title="常量指标" :getData="getDataFun" :getSearch="getSearchForm"></cont>
</div>
</template>
<script>
import cont from '@/components/common/cont.vue'
import {
getfieldList,addfieldList,getfieldListTree,updatafieldList,getfieldsave,getfieldInfo,updatafield,fieldusing,fielddownTemplate,fieldupdata
getfieldList,
addfieldList,
getfieldListTree,
updatafieldList,
getfieldsave,
getfieldInfo,
updatafield,
fieldusing,
fielddownTemplate,
fieldupdata
} from '@/api/index.js'
export default {
@@ -24,31 +29,33 @@
return {
getDataFun: {
type:5,
row: [ {
label: '序号',
row: 'id'
}, {
label: '字段名称',
row: 'fieldEn'
}, {
label: '字段中文名',
row: 'fieldCn'
}, {
label: '字段类型',
row: 'valueType',
type: 'type'
}, {
label: '状态',
row: 'status',
type: 'State'
}, {
label: '创建人',
row: 'nickName'
},{
label: '创建时间',
row: 'created',
type: 'Time'
} ],
row: [
{
label: '序号',
row: 'id'
}, {
label: '字段名称',
row: 'fieldEn'
}, {
label: '字段中文名',
row: 'fieldCn'
}, {
label: '字段类型',
row: 'valueType',
type: 'type'
}, {
label: '状态',
row: 'status',
type: 'State'
}, {
label: '创建人',
row: 'nickName'
},{
label: '创建时间',
row: 'created',
type: 'Time'
}
],
redact:"dataManageRedact",
async getTree(e){
return await getfieldListTree(e).then(res => {
@@ -62,60 +69,75 @@
})
},
async addlist(e) {
return await addfieldList(e).then(res => {
return res
})
},
async updatalist(e) {
return await updatafieldList(e).then(res => {
return res
})
},
async setsave(e) {
return await getfieldsave(e).then(res => {
return res
})
},
async getInfo(e){
return await getfieldInfo(e).then(res=>{
return res
})
},
async updatafield(e){
return await updatafield(e).then(res=>{
return res
})
},
async fieldusing(e){
return await fieldusing(e).then(res=>{
return res
})
},
async down(e){
return await fielddownTemplate(e).then(res=>{
return res
})
},
async fieldsubmit(e){
return await fieldupdata(e).then(res=>{
return res
})
}
},
getSearchForm: [
{
name:"字段名称",
key:"userName",
type:"1",
},
{
name:"字段中文名",
key:"userName1",
type:"1",
},
{
name:"创建时间",
key:"userName1",
type:"1",
},
{
name:"状态",
key:"userName1",
type:"1",
}
],
};
}
};
</script>
<style>
.button-container {
text-align: right; /* 使按钮右对齐 */
}
</style>

View File

@@ -3,7 +3,7 @@
<el-upload
:headers="header"
class="upload-demo"
action="Riskmanage/models/uploadAndParseFile"
action="/models/uploadAndParseFile"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:before-upload="beforeUpload"

View File

@@ -5,7 +5,7 @@ switch (process.env.NODE_ENV) {
case 'development': // 开发环境代理地址
proxyObj = {
'/Riskmanage': {
target: 'http://47.102.125.25:80', // 开发环境
target: 'http://127.0.0.1:8082', // 开发环境
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/Riskmanage': '/Riskmanage'
@@ -13,7 +13,7 @@ switch (process.env.NODE_ENV) {
},
'/trading': {
target: 'http://47.242.85.45:80', // 开发环境
target: 'http://127.0.0.1:8083', // 开发环境
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/trading': '/trading'
@@ -84,6 +84,25 @@ switch (process.env.NODE_ENV) {
}
}
break
case 'produce': // 生产环境
proxyObj = {
'/Riskmanage': {
target: 'http://47.99.93.74:8099', // 生产环境
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/Riskmanage': '/Riskmanage'
}
},
'/trading': {
target: 'http://47.99.93.74:8099', // 开发环境
changeOrigin: true, // 是否跨域
pathRewrite: {
'^/trading': '/trading'
}
}
}
break
}
module.exports = proxyObj

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
"version": "4.2.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"serve": "vue-cli-service serve --mode development",
"serve:test": "vue-cli-service serve --mode test",
"serve:jia": "vue-cli-service serve --mode jia",
"serve:niu": "vue-cli-service serve --mode niu",

View File

@@ -177,7 +177,7 @@
go(value) {
var url = window.location.href
console.log(url.split('#')[0])
if (value[url.split('#')[0]]) {
window.open(value[url.split('#')[0]])
} else {

View File

@@ -656,7 +656,10 @@
}
if (!value.weight && value.weight != 0) {
console.log(value.weight)
if (!Z.test(value.condition)) {
alert(value.condition)
console.log(value.condition)
issumm.is = false
issumm.msg = '请检查是否有范围未填'
}

View File

@@ -556,6 +556,7 @@
},
getdeepArr(obj) {
console.log(obj)
if (Array.isArray(obj)) {
return false
} else if (typeof obj == 'object') {
@@ -598,6 +599,7 @@
}
},
FieldUserArr() {
console.log(this.FieldUserObj)
if (this.FieldUserObj.length == 0) {
return []
} else {
@@ -613,7 +615,8 @@
obj.children = this.getdeepArr(JSON.parse(value.jsonValue))
return obj
})
// console.log(arr)
console.log(111111)
console.log(arr)
return arr
}
},

View File

@@ -214,7 +214,7 @@
// 表格中点击
engineDisplay: function(id) {
//alert(id);
let h5Path = '';
let h5Path = '/enginex';
window.localStorage.setItem("engineId", id);
bus.$emit('EngineSwitchover',id)

View File

@@ -3,7 +3,7 @@
<el-upload
:headers="header"
class="upload-demo"
action="Riskmanage/models/uploadAndParseFile"
action="/models/uploadAndParseFile"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:before-upload="beforeUpload"

View File

@@ -3,7 +3,7 @@ export default {
title: '数据中心',
'http://ex.fibo.cn/': 'http://dx.fibo.cn',
'http://ex.demo.fibo.cn/': 'http://dx.demo.fibo.cn',
'http://47.102.125.25/': 'http://47.102.125.25:81'
'http://localhost:1025/': 'http://127.0.0.1:1024'
},
{
title: '权限系统',
@@ -36,7 +36,7 @@ export default {
title: '数据中心',
'http://ax.fibo.cn/': 'http://dx.fibo.cn',
'http://ax.demo.fibo.cn/': 'http://dx.demo.fibo.cn',
'http://47.102.125.25:82/': 'http://47.102.125.25:81'
'http://127.0.0.1/': 'http://127.0.0.1/:1024'
},
]

BIN
image/customer.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

View File

@@ -2,7 +2,8 @@
SQLyog v12.2.6 (64 bit)
MySQL - 5.7.24-log : Database - riskmanage
*********************************************************************
*/
*/
/*!40101 SET NAMES utf8 */;
@@ -16,6 +17,28 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/`riskmanage` /*!40100 DEFAULT CHARACTER
USE `riskmanage`;
DROP TABLE IF EXISTS `t_list_db_version`;
create table t_list_db_version(
id int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
list_db_id int(11) NOT NULL,
version_code varchar(255) DEFAULT NULL,
description varchar(4096) DEFAULT NULL,
result_field_en varchar(255) DEFAULT NULL,
status int(4) DEFAULT NULL,
table_column varchar(1024) DEFAULT NULL,
match_type int(4) DEFAULT NULL,
query_type int(4) DEFAULT NULL,
query_field varchar(255) DEFAULT NULL ,
organ_id int(11) NOT NULL DEFAULT '0' COMMENT '组织id',
create_user_id int(11) NOT NULL DEFAULT '0' COMMENT '创建者id',
update_user_id int(11) NOT NULL DEFAULT '0' COMMENT '修改者id',
create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期',
update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改日期',
snapshot json DEFAULT NULL COMMENT '名单库版本配置快照',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
/*Table structure for table `t_analyse_decision_result` */
DROP TABLE IF EXISTS `t_analyse_decision_result`;
@@ -458,6 +481,8 @@ CREATE TABLE `t_decision_tables_result` (
`version_id` int(11) NOT NULL DEFAULT '0' COMMENT '决策表版本id',
`rows` int(11) DEFAULT NULL COMMENT '行数',
`columns` int(11) DEFAULT NULL COMMENT '列数',
`ro` int(11) DEFAULT NULL COMMENT '行数new',
`colum` int(11) DEFAULT NULL COMMENT '列数new',
`result_value` longtext COMMENT '结果集二维数组',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',

31
sql/update.sql Normal file
View File

@@ -0,0 +1,31 @@
create table t_list_db_version(
id int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
list_db_id int(11) NOT NULL,
version_code varchar(255) DEFAULT NULL,
description varchar(4096) DEFAULT NULL,
result_field_en varchar(255) DEFAULT NULL,
status int(4) DEFAULT NULL,
table_column varchar(1024) DEFAULT NULL,
match_type int(4) DEFAULT NULL,
query_type int(4) DEFAULT NULL,
query_field varchar(255) DEFAULT NULL ,
organ_id int(11) NOT NULL DEFAULT '0' COMMENT '组织id',
create_user_id int(11) NOT NULL DEFAULT '0' COMMENT '创建者id',
update_user_id int(11) NOT NULL DEFAULT '0' COMMENT '修改者id',
create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建日期',
update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改日期',
snapshot json DEFAULT NULL COMMENT '名单库版本配置快照',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
ALTER TABLE t_machine_learning_models MODIFY COLUMN model_field varchar(4096) NOT NULL DEFAULT '' COMMENT '模型解析字段';
ALTER TABLE t_decision_tables_result ADD COLUMN `ro` int DEFAULT NULL COMMENT '行数';
ALTER TABLE t_decision_tables_result ADD COLUMN `colum` int DEFAULT NULL COMMENT '列数';