From 0cbbe2c1cbfbf73e02e1796d921c2911c96d370b Mon Sep 17 00:00:00 2001
From: 潘志宝 <979469083@qq.com>
Date: 星期一, 23 十二月 2024 11:46:31 +0800
Subject: [PATCH] Merge branch 'master' of http://dlindusit.com:53929/r/iailab-plat

---
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictModelHandlerImpl.java             |   31 +
 iailab-module-data/iailab-module-data-api/src/main/java/com/iailab/module/data/api/point/DataPointApi.java                                  |    4 
 iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/ScheduleSuggestRespDTO.java                   |   29 +
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/ScheduleSampleInfoConstructor.java             |   19 
 iailab-module-data/iailab-module-data-biz/src/main/resources/logback-spring.xml                                                             |  140 +++----
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/SampleInfoConstructor.java                     |   11 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictItemMergeHandlerImpl.java         |  121 +++---
 iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/api/point/DataPointApiImpl.java                              |   11 
 iailab-module-model/iailab-module-model-biz/src/main/resources/logback-spring.xml                                                           |  154 ++++----
 iailab-module-data/iailab-module-data-api/src/main/java/com/iailab/module/data/api/point/dto/ApiPointDTO.java                               |    3 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/MmItemResultService.java                  |    3 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictItemHandler.java                       |    4 
 iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/point/service/DaPointService.java                            |    3 
 iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleReqDTO.java                        |    2 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/MmPredictItemService.java                 |    2 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/auth/AuthController.java              |    8 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictModuleHandler.java                     |   57 ++-
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/common/exception/ModelResultErrorException.java           |   51 ++
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/factory/ItemEntityFactory.java                        |    2 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/dto/MmPredictItemDTO.java                         |    5 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmModelArithSettingsServiceImpl.java |    2 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/common/enums/OutResultType.java                           |    3 
 iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/user/AdminUserApiImpl.java                         |    2 
 iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/point/service/impl/DaPointServiceImpl.java                   |    9 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/impl/StScheduleSchemeServiceImpl.java    |    2 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/impl/ScheduleModelHandlerImpl.java           |   15 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/vo/StScheduleSuggestSaveReqVO.java               |    3 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/PredictSampleInfoConstructor.java              |   20 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictItemNormalHandlerImpl.java        |    8 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/McsApiImpl.java                                       |    8 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java                                       |   53 +-
 /dev/null                                                                                                                                   |  205 -----------
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmItemResultServiceImpl.java         |   16 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/enums/ItemRunStatusEnum.java                      |    4 
 iailab-cloud/iailab-gateway/src/main/resources/application.yaml                                                                             |    1 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictModelHandler.java                      |    3 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmPredictItemServiceImpl.java        |   39 ++
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictResultHandler.java                     |    4 
 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/vo/PredictResultVO.java                               |    5 
 39 files changed, 543 insertions(+), 519 deletions(-)

diff --git a/iailab-cloud/iailab-gateway/src/main/resources/application.yaml b/iailab-cloud/iailab-gateway/src/main/resources/application.yaml
index f0c4867..600cd0a 100644
--- a/iailab-cloud/iailab-gateway/src/main/resources/application.yaml
+++ b/iailab-cloud/iailab-gateway/src/main/resources/application.yaml
@@ -142,6 +142,7 @@
 server:
   port: 48080
   servlet:
+    context-path: /
     session:
       timeout: 120s
 
diff --git a/iailab-module-data/iailab-module-data-api/src/main/java/com/iailab/module/data/api/point/DataPointApi.java b/iailab-module-data/iailab-module-data-api/src/main/java/com/iailab/module/data/api/point/DataPointApi.java
index a4244f6..6a8c3f5 100644
--- a/iailab-module-data/iailab-module-data-api/src/main/java/com/iailab/module/data/api/point/DataPointApi.java
+++ b/iailab-module-data/iailab-module-data-api/src/main/java/com/iailab/module/data/api/point/DataPointApi.java
@@ -30,6 +30,10 @@
     @Operation(summary = "根据测点ID查询测点信息")
     ApiPointDTO getInfoById(@PathVariable("pointId") String pointId);
 
+    @PostMapping(PREFIX + "/info/ids")
+    @Operation(summary = "根据多个测点ID查询测点信息")
+    List<ApiPointDTO> getInfoByIds(@RequestParam("pointNos") List<String> pointIds);
+
     @PostMapping(PREFIX + "/query-points/real-value")
     @Operation(summary = "查询多个测点当前值")
     Map<String, Object> queryPointsRealValue(@RequestParam("pointNos") List<String> pointNos);
diff --git a/iailab-module-data/iailab-module-data-api/src/main/java/com/iailab/module/data/api/point/dto/ApiPointDTO.java b/iailab-module-data/iailab-module-data-api/src/main/java/com/iailab/module/data/api/point/dto/ApiPointDTO.java
index 24972b3..e98d182 100644
--- a/iailab-module-data/iailab-module-data-api/src/main/java/com/iailab/module/data/api/point/dto/ApiPointDTO.java
+++ b/iailab-module-data/iailab-module-data-api/src/main/java/com/iailab/module/data/api/point/dto/ApiPointDTO.java
@@ -15,6 +15,9 @@
 public class ApiPointDTO implements Serializable {
     private static final long serialVersionUID = 1L;
 
+    @Schema(description = "id", required = true)
+    private String id;
+
     @Schema(description = "测点编码", required = true)
     private String pointNo;
 
diff --git a/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/api/point/DataPointApiImpl.java b/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/api/point/DataPointApiImpl.java
index dd9b84a..d57f185 100644
--- a/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/api/point/DataPointApiImpl.java
+++ b/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/api/point/DataPointApiImpl.java
@@ -38,7 +38,16 @@
 
     @Override
     public ApiPointDTO getInfoById(String pointId) {
-        return ConvertUtils.sourceToTarget(daPointService.getSimpleInfoById(pointId), ApiPointDTO.class);
+        return daPointService.getSimpleInfoById(pointId);
+    }
+
+    @Override
+    public List<ApiPointDTO> getInfoByIds(List<String> pointIds) {
+        List<ApiPointDTO> result = new ArrayList<>(pointIds.size());
+        for (String pointId : pointIds) {
+            result.add(daPointService.getSimpleInfoById(pointId));
+        }
+        return result;
     }
 
     @Override
diff --git a/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/point/service/DaPointService.java b/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/point/service/DaPointService.java
index 34bc23e..5157f2a 100644
--- a/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/point/service/DaPointService.java
+++ b/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/point/service/DaPointService.java
@@ -1,6 +1,7 @@
 package com.iailab.module.data.point.service;
 
 import com.iailab.framework.common.pojo.PageResult;
+import com.iailab.module.data.api.point.dto.ApiPointDTO;
 import com.iailab.module.data.point.dto.DaPointDTO;
 import com.iailab.module.data.point.vo.*;
 
@@ -17,7 +18,7 @@
 
     DaPointDTO info(String id);
 
-    DaPointDTO getSimpleInfoById(String id);
+    ApiPointDTO getSimpleInfoById(String id);
 
     DaPointDTO getSimpleInfoByNo(String no);
 
diff --git a/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/point/service/impl/DaPointServiceImpl.java b/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/point/service/impl/DaPointServiceImpl.java
index 53c8b35..b9742f0 100644
--- a/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/point/service/impl/DaPointServiceImpl.java
+++ b/iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/point/service/impl/DaPointServiceImpl.java
@@ -9,6 +9,7 @@
 import com.iailab.framework.common.pojo.PageResult;
 import com.iailab.framework.common.util.object.BeanUtils;
 import com.iailab.framework.common.util.object.ConvertUtils;
+import com.iailab.module.data.api.point.dto.ApiPointDTO;
 import com.iailab.module.data.channel.common.service.ChannelSourceService;
 import com.iailab.module.data.common.enums.CommonConstant;
 import com.iailab.module.data.common.enums.IsEnableEnum;
@@ -67,7 +68,7 @@
     @Resource
     private DaPointCollectStatusService daPointCollectStatusService;
 
-    private static Map<String, DaPointDTO> pointIdMap = new ConcurrentHashMap<>();
+    private static Map<String, ApiPointDTO> pointIdMap = new ConcurrentHashMap<>();
 
     private static Map<String, DaPointDTO> pointNoMap = new ConcurrentHashMap<>();
 
@@ -112,16 +113,16 @@
     }
 
     @Override
-    public DaPointDTO getSimpleInfoById(String id) {
+    public ApiPointDTO getSimpleInfoById(String id) {
         if (pointIdMap.containsKey(id)) {
             return pointIdMap.get(id);
         }
-        DaPointDTO dto = ConvertUtils.sourceToTarget(daPointDao.selectById(id), DaPointDTO.class);
+        ApiPointDTO dto = ConvertUtils.sourceToTarget(daPointDao.selectById(id), ApiPointDTO.class);
         if (dto == null) {
             return null;
         }
         pointIdMap.put(id, dto);
-        return pointIdMap.get(id);
+        return dto;
     }
 
     @Override
diff --git a/iailab-module-data/iailab-module-data-biz/src/main/resources/application-local.yml b/iailab-module-data/iailab-module-data-biz/src/main/resources/application-local.yml
deleted file mode 100644
index 0f5b469..0000000
--- a/iailab-module-data/iailab-module-data-biz/src/main/resources/application-local.yml
+++ /dev/null
@@ -1,154 +0,0 @@
---- #################### 数据库相关配置 ####################
-spring:
-  # 数据源配置项
-  autoconfigure:
-    exclude:
-      - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
-      - de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration # 禁用 Spring Boot Admin 的 Client 的自动配置
-  datasource:
-    druid: # Druid 【监控】相关的全局配置
-      web-stat-filter:
-        enabled: true
-      stat-view-servlet:
-        enabled: true
-        allow: # 设置白名单,不填则允许所有访问
-        url-pattern: /druid/*
-        login-username: # 控制台管理用户名和密码
-        login-password:
-      filter:
-        stat:
-          enabled: true
-          log-slow-sql: true # 慢 SQL 记录
-          slow-sql-millis: 100
-          merge-sql: true
-        wall:
-          config:
-            multi-statement-allow: true
-    dynamic: # 多数据源配置
-      druid: # Druid 【连接池】相关的全局配置
-        initial-size: 1 # 初始连接数
-        min-idle: 1 # 最小连接池数量
-        max-active: 20 # 最大连接池数量
-        max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
-        time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
-        min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
-        max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
-        validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
-        test-while-idle: true
-        test-on-borrow: false
-        test-on-return: false
-      primary: master
-      datasource:
-        master:
-          url: jdbc:mysql://127.0.0.1:3306/iailab_ntt_data?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
-          #          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai # MySQL Connector/J 5.X 连接的示例
-          #          url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例
-          #          url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
-          #          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro # SQLServer 连接的示例
-          #          url: jdbc:dm://10.211.55.4:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
-          username: root
-          password: 123456
-        #          username: sa # SQL Server 连接的示例
-        #          password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W # SQL Server 连接的示例
-        #          username: SYSDBA # DM 连接的示例
-        #          password: SYSDBA # DM 连接的示例
-        slave: # 模拟从库,可根据自己需要修改
-          lazy: true # 开启懒加载,保证启动速度
-          url: jdbc:mysql://127.0.0.1:3306/iailab_ntt_data?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
-          username: root
-          password: 123456
-
-  # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
-  redis:
-    host: 172.16.8.100 # 地址
-    port: 6379 # 端口
-    database: 0 # 数据库索引
-    password: 123456 # 密码,建议生产环境开启
-
---- #################### MQ 消息队列相关配置 ####################
-
-# rocketmq 配置项,对应 RocketMQProperties 配置类
-rocketmq:
-  name-server: 127.0.0.1:9876 # RocketMQ Namesrv
-
-spring:
-  # RabbitMQ 配置项,对应 RabbitProperties 配置类
-  rabbitmq:
-    host: 127.0.0.1 # RabbitMQ 服务的地址
-    port: 5672 # RabbitMQ 服务的端口
-    username: guest # RabbitMQ 服务的账号
-    password: guest # RabbitMQ 服务的密码
-  # Kafka 配置项,对应 KafkaProperties 配置类
-  kafka:
-    bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
-
---- #################### 定时任务相关配置 ####################
-
-xxl:
-  job:
-    enabled: true # 是否开启调度中心,默认为 true 开启
-    admin:
-      addresses: http://127.0.0.1:9090/xxl-job-admin # 调度中心部署跟地址
-
---- #################### 服务保障相关配置 ####################
-
-# Lock4j 配置项
-lock4j:
-  acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
-  expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
-
---- #################### 监控相关配置 ####################
-
-# Actuator 监控端点的配置项
-management:
-  endpoints:
-    web:
-      base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
-      exposure:
-        include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
-
-# Spring Boot Admin 配置项
-spring:
-  boot:
-    admin:
-      # Spring Boot Admin Client 客户端的相关配置
-      client:
-        instance:
-          service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
-
-# 日志文件配置
-logging:
-  level:
-    # 配置自己写的 MyBatis Mapper 打印日志
-    com.iailab.module.system.dal.mysql: debug
-    com.iailab.module.system.dal.mysql.sensitiveword.SensitiveWordMapper: INFO # 配置 SensitiveWordMapper 的日志级别为 info
-    com.iailab.module.system.dal.mysql.sms.SmsChannelMapper: INFO # 配置 SmsChannelMapper 的日志级别为 info
-
---- #################### 平台相关配置 ####################
-
-# 平台配置项,设置当前项目所有自定义的配置
-iailab:
-  env: # 多环境的配置项
-    tag: ${HOSTNAME}
-  captcha:
-    enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试
-  security:
-    mock-enable: true
-  xss:
-    enable: false
-    exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系
-      - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
-      - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
-  access-log: # 访问日志的配置项
-    enable: false
-  demo: false # 关闭演示模式
-
-influx-db:
-  org: IAILab
-  token: 50m9Kl-7_tvJY9kejwgSwxQpVG258EKKRt4qZeDntRnWetHGpkBhYtOOXrd9gmh85cuikKFZMzkTsw9pm1xlcA==
-  url: http://127.0.0.1:8086
-  username: root
-  password: root123456
-
-iems:
-  upload-dir: D:/DLUT/upload/
diff --git a/iailab-module-data/iailab-module-data-biz/src/main/resources/application-test.yaml b/iailab-module-data/iailab-module-data-biz/src/main/resources/application-test.yaml
deleted file mode 100644
index aee65d8..0000000
--- a/iailab-module-data/iailab-module-data-biz/src/main/resources/application-test.yaml
+++ /dev/null
@@ -1,75 +0,0 @@
-spring:
-  # 数据源配置项
-  autoconfigure:
-    exclude:
-      - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
-  datasource:
-    druid: # Druid 【监控】相关的全局配置
-      web-stat-filter:
-        enabled: true
-      stat-view-servlet:
-        enabled: true
-        allow: # 设置白名单,不填则允许所有访问
-        url-pattern: /druid/*
-        login-username: # 控制台管理用户名和密码
-        login-password:
-      filter:
-        stat:
-          enabled: true
-          log-slow-sql: true # 慢 SQL 记录
-          slow-sql-millis: 100
-          merge-sql: true
-        wall:
-          config:
-            multi-statement-allow: true
-    dynamic: # 多数据源配置
-      druid: # Druid 【连接池】相关的全局配置
-        initial-size: 1 # 初始连接数
-        min-idle: 1 # 最小连接池数量
-        max-active: 20 # 最大连接池数量
-        max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
-        time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
-        min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
-        max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
-        validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
-        test-while-idle: true
-        test-on-borrow: false
-        test-on-return: false
-      primary: master
-      datasource:
-        master:
-          url: jdbc:mysql://172.16.8.100:3306/iailab_expert_master?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
-          username: root
-          password: 123456
-
-  # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
-  redis:
-    host: 127.0.0.1 # 地址
-    port: 6379 # 端口
-    database: 0 # 数据库索引
-    password: 123456 # 密码,建议生产环境开启
-
-influx-db:
-  org: iailab
-  bucket: buk_shasteel
-  token: p-WkLXdPmHD4Cdij2PD-r92dLEQqjQ8V5KhyZYHYroBNVE0ZrW5VgzqWBNmXmiEdxEWaURC7rrKVzuM0XTEraQ==
-  url: http://172.16.8.200:8086
-  username: root
-  password: iailab12345678
-
-iems:
-  upload-dir: D:/DLUT/upload/
-
-video:
-  capture-dir: D:/iailab
-  dahua:
-    path:
-      capture-path: /Dahua/Capture/
-      model-path: /Dahua/Model/
-  hikvision:
-    path:
-      capture-path: /Hikvision/Capture/
-      model-path: /Hikvision/Model/
-    pic-size: 2 # size of picture 0=CIF, 1=QCIF, 2=D1 3=UXGA(1600x1200), 4=SVGA(800x600), 5=HD720p(1280x720),6=VGA
-    pic-quality: 0 # quality of picture 0-best 1-better 2-normal
-
diff --git a/iailab-module-data/iailab-module-data-biz/src/main/resources/application-test_rec.yml b/iailab-module-data/iailab-module-data-biz/src/main/resources/application-test_rec.yml
deleted file mode 100644
index 5cb5172..0000000
--- a/iailab-module-data/iailab-module-data-biz/src/main/resources/application-test_rec.yml
+++ /dev/null
@@ -1,64 +0,0 @@
-spring:
-  cloud:
-    nacos:
-      discovery:
-        server-addr: 172.16.1.148:8848 # 注册中心地址  nacos server
-      config:
-        server-addr: 172.16.1.148:8848 # 配置中心地址 nacos server
-        file-extension: yml # 配置中心的配置后缀
-  datasource:
-    type: com.alibaba.druid.pool.DruidDataSource
-    druid:
-      driver-class-name: com.mysql.cj.jdbc.Driver
-      url: jdbc:mysql://172.16.1.148:3306/iailab_ntt_data?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
-      username: root
-      password: 123456
-      initial-size: 10
-      max-active: 100
-      min-idle: 10
-      max-wait: 60000
-      pool-prepared-statements: true
-      max-pool-prepared-statement-per-connection-size: 20
-      time-between-eviction-runs-millis: 60000
-      min-evictable-idle-time-millis: 300000
-      #validationQuery是用来验证数据库连接的查询语句,这个查询语句必须是至少返回一条结果的SELECT语句。每种数据库都有各自的验证语句
-      #validation-query: select 1 from sysibm.sysdummy1
-      test-while-idle: true
-      test-on-borrow: false
-      test-on-return: false
-      stat-view-servlet:
-        enabled: true
-        url-pattern: /druid/*
-        #login-username: admin
-        #login-password: admin
-      filter:
-        stat:
-          log-slow-sql: true
-          slow-sql-millis: 1000
-          merge-sql: false
-        wall:
-          config:
-            multi-statement-allow: true
-  redis:
-    host: 172.16.8.100 # 地址
-    port: 6379 # 端口
-    database: 0 # 数据库索引
-    password: 123456 # 密码,建议生产环境开启
-    jedis:
-      pool:
-        max-active: 1000  # 连接池最大连接数(使用负值表示没有限制)
-        max-wait: -1ms      # 连接池最大阻塞等待时间(使用负值表示没有限制)
-        max-idle: 10      # 连接池中的最大空闲连接
-        min-idle: 5       # 连接池中的最小空闲连接
-
-oadp:
-  domain: http://172.16.1.148:6010
-
-influx-db:
-  org: IAILab
-  bucket: whs_data
-  token: dUoFsmlooCbyHsleY17w-_KpVf7vaFVRz0xBBuH4GZeOygMekoKpVi8kGIw49K_Qp_UDNf3RHpInoUIi4rTsow==
-  url: http://172.16.1.148:8086
-
-iems:
-  upload-dir: D:/DLUT/znjt/safe/webapp/static/temp/
\ No newline at end of file
diff --git a/iailab-module-data/iailab-module-data-biz/src/main/resources/logback-spring.xml b/iailab-module-data/iailab-module-data-biz/src/main/resources/logback-spring.xml
index 3ac202f..db8f353 100644
--- a/iailab-module-data/iailab-module-data-biz/src/main/resources/logback-spring.xml
+++ b/iailab-module-data/iailab-module-data-biz/src/main/resources/logback-spring.xml
@@ -1,86 +1,76 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration scan="true">
-    <property name="LOG_TEMP" value="./logs"/>
+<configuration>
+    <!-- 引用 Spring Boot 的 logback 基础配置 -->
     <include resource="org/springframework/boot/logging/logback/defaults.xml" />
-    <!-- <include resource="org/springframework/boot/logging/logback/base.xml" /> -->
-    <logger name="org.springframework.web" level="INFO"/>
-    <logger name="org.springboot.sample" level="TRACE" />
+    <!-- 变量 iailab.info.base-package,基础业务包 -->
+    <springProperty scope="context" name="iailab.info.base-package" source="iailab.info.base-package"/>
+    <!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level:级别从左显示 5 个字符宽度,%msg:日志消息,%n是换行符 -->
+    <property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} | %highlight(${LOG_LEVEL_PATTERN:-%5p} ${PID:- }) | %boldYellow(%thread [%tid]) %boldGreen(%-40.40logger{39}) | %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
 
-    <!-- 开发、测试环境 -->
-    <springProfile name="dev,test,prod">
-        <logger name="org.springframework.web" level="INFO"/>
-        <logger name="org.springboot.sample" level="INFO" />
-        <logger name="com.iailab" level="DEBUG" />
-    </springProfile>
-
-    <!-- 生产环境 -->
-    <!--<springProfile name="prod">-->
-    <!--<logger name="org.springframework.web" level="ERROR"/>-->
-    <!--<logger name="org.springboot.sample" level="ERROR" />-->
-    <!--<logger name="io.renren" level="ERROR" />-->
-    <!--</springProfile>-->
-
-    <!-- 日志文件存放路径 -->
-    <property name="log_home" value="./logs" />
-    <!-- 日志输出格式 -->
-    <!--生产用-->
-    <property name="log.pattern" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] | [%thread][%-5level] | [%logger{20}.%method,line : %line] %msg%n" />
-    <!--本地测试使用-->
-    <!--<property name="log.pattern" value="[%boldGreen(%d{yyyy-MM-dd HH:mm:ss.SSS})] | [%highlight(%thread][%-5level)] | [%boldYellow(%logger{20}.%method,%line)] %msg%n" />-->
-    <!-- 日志输出格式【控制台】 -->
-    <!--<property name="log.pattern" value="%date{yyyy-MM-dd HH:mm:ss} | [ line: %line ] | %boldGreen(%thread) | %highlight(%-5level) | %boldYellow(%logger).%method | %msg%n"/>-->
-
-    <!-- 控制台输出 -->
-    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
-        <encoder>
-            <!--<pattern>${logPatternConsoleLog}</pattern>-->
-            <pattern>${log.pattern}</pattern>
+    <!-- 控制台 Appender -->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">     
+        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
+                <pattern>${PATTERN_DEFAULT}</pattern>
+            </layout>
         </encoder>
     </appender>
 
-    <logger name="m-shop-mybatis-sql" level="debug"></logger>
-
-    <!-- debug级别设置 -->
-    <appender name="file_debug"  class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <prudent>true</prudent>
-        <filter class="ch.qos.logback.classic.filter.LevelFilter">
-            <!--过滤 DEBUG-->
-            <level>DEBUG</level>
-            <!--匹配到就禁止-->
-            <!--<onMatch>ACCEPT</onMatch>-->
-            <!--没有匹配到就允许-->
-            <!--<onMismatch>DENY</onMismatch>-->
-        </filter>
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <!--<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">-->
-            <!--日志文件输出的文件名-->
-            <!--<FileNamePattern>${log_home}/log-info.%d{yyyy-MM-dd}.%i.log</FileNamePattern>-->
-            <FileNamePattern>${log_home}/log-debug.%d{yyyy-MM-dd}.log</FileNamePattern>
-            <!--<maxFileSize>100MB</maxFileSize>-->
-            <!-- 日志最大的历史 7天 -->
-            <maxHistory>7</maxHistory>
-            <totalSizeCap>2GB</totalSizeCap>
-            <cleanHistoryOnStart>true</cleanHistoryOnStart>
+    <!-- 文件 Appender -->
+    <!-- 参考 Spring Boot 的 file-appender.xml 编写 -->
+    <appender name="FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
+                <pattern>${PATTERN_DEFAULT}</pattern>
+            </layout>
+        </encoder>
+        <!-- 日志文件名 -->
+        <file>${LOG_FILE}</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- 滚动后的日志文件名 -->
+            <fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
+            <!-- 启动服务时,是否清理历史日志,一般不建议清理 -->
+            <cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
+            <!-- 日志文件,到达多少容量,进行滚动 -->
+            <maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
+            <!-- 日志文件的总大小,0 表示不限制 -->
+            <totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
+            <!-- 日志文件的保留天数 -->
+            <maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
         </rollingPolicy>
-        <!--<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">-->
-        <!--&lt;!&ndash; 单文件最大50MB &ndash;&gt;-->
-        <!--<maxFileSize>50MB</maxFileSize>-->
-        <!--</triggeringPolicy>-->
-        <encoder>
-            <pattern>${log.pattern}</pattern>
+    </appender>
+    <!-- 异步写入日志,提升性能 -->
+    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
+        <!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
+        <discardingThreshold>0</discardingThreshold>
+        <!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
+        <queueSize>256</queueSize>
+        <appender-ref ref="FILE"/>
+    </appender>
+
+    <!-- SkyWalking GRPC 日志收集,实现日志中心。注意:SkyWalking 8.4.0 版本开始支持 -->
+    <appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
+        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
+                <pattern>${PATTERN_DEFAULT}</pattern>
+            </layout>
         </encoder>
     </appender>
 
-    <!-- 系统模块日志级别控制  -->
-    <!--<logger name="com.btrh" level="info" />-->
-
-    <!-- Spring日志级别控制  -->
-    <!--<logger name="org.springframework" level="info" />-->
-
-    <!--系统操作日志-->
-    <root level="INFO">
-        <appender-ref ref="console" />
-        <appender-ref ref="file_debug" />
-    </root>
+    <!-- 本地环境 -->
+    <springProfile name="local">
+        <root level="INFO">
+            <appender-ref ref="STDOUT"/>
+            <appender-ref ref="GRPC"/> <!-- 本地环境下,如果不想接入 SkyWalking 日志服务,可以注释掉本行 -->
+            <appender-ref ref="ASYNC"/>  <!-- 本地环境下,如果不想打印日志,可以注释掉本行 -->
+        </root>
+    </springProfile>
+    <!-- 其它环境 -->
+    <springProfile name="dev,test,stage,prod,default">
+        <root level="INFO">
+            <appender-ref ref="STDOUT"/>
+            <appender-ref ref="ASYNC"/>
+            <appender-ref ref="GRPC"/>
+        </root>
+    </springProfile>
 
 </configuration>
diff --git a/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-local.yaml b/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-local.yaml
deleted file mode 100644
index b9040bd..0000000
--- a/iailab-module-infra/iailab-module-infra-biz/src/main/resources/application-local.yaml
+++ /dev/null
@@ -1,121 +0,0 @@
---- #################### 数据库相关配置 ####################
-spring:
-  autoconfigure:
-    exclude:
-      - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
-  #      - de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration
-  #      - de.codecentric.boot.admin.server.cloud.config.AdminServerDiscoveryAutoConfiguration
-  #      - de.codecentric.boot.admin.server.ui.config.AdminServerUiAutoConfiguration
-  #      - de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration
-  datasource:
-    druid:
-      web-stat-filter:
-        enabled: true
-      stat-view-servlet:
-        enabled: true
-        allow:
-        url-pattern: /druid/*
-        login-username:
-        login-password:
-      filter:
-        stat:
-          enabled: true
-          log-slow-sql: true
-          slow-sql-millis: 100
-          merge-sql: true
-        wall:
-          config:
-            multi-statement-allow: true
-    dynamic:
-      druid:
-        initial-size: 1
-        min-idle: 1
-        max-active: 20
-        max-wait: 600000
-        time-between-eviction-runs-millis: 60000
-        min-evictable-idle-time-millis: 300000
-        max-evictable-idle-time-millis: 900000
-        validation-query: SELECT 1 FROM DUAL
-        test-while-idle: true
-        test-on-borrow: false
-        test-on-return: false
-      primary: master
-      datasource:
-        master:
-          url: jdbc:mysql://172.16.8.100:3306/iailab_plat_system?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
-          #          url: jdbc:mysql://127.0.0.1:3306/iailab-plat?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
-          #          url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro
-          #          url: jdbc:oracle:thin:@127.0.0.1:1521:xe
-          #          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro
-          #          url: jdbc:dm://10.211.55.4:5236?schema=RUOYI_VUE_PRO
-          username: root
-          password: 123456
-        #          username: sa
-        #          password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
-        #          username: SYSDBA
-        #          password: SYSDBA
-        slave:
-          lazy: true
-          url: jdbc:mysql://172.16.8.100:3306/iailab-plat?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
-          username: root
-          password: 123456
-
-  redis:
-    host: 172.16.8.100
-    port: 6379
-    database: 0
-    password: 123456
-
---- #################### MQ 消息队列相关配置 ####################
-rocketmq:
-  name-server: 172.16.8.100:9876
-
-spring:
-  rabbitmq:
-    host: 172.16.8.200
-    port: 5672
-    username: admin
-    password: admin123
-
-  kafka:
-    bootstrap-servers: 172.16.8.100:9092
-
-xxl:
-  job:
-    enabled: false
-    admin:
-      addresses: http://172.16.8.100:9090/xxl-job-admin
-
-lock4j:
-  acquire-timeout: 3000
-  expire: 30000
-
---- #################### 监控相关配置 ####################
-management:
-  endpoints:
-    web:
-      base-path: /actuator
-      exposure:
-        include: '*'
-
-spring:
-  boot:
-    admin:
-      client:
-        instance:
-          service-host-type: IP
-      context-path: /admin
-
-logging:
-  level:
-    com.iailab.module.infra.dal.mysql: debug
-    com.iailab.module.infra.dal.mysql.logger.ApiErrorLogMapper: INFO
-    com.iailab.module.infra.dal.mysql.file.FileConfigMapper: INFO
-
-iailab:
-  env:
-    tag: ${HOSTNAME}
-  security:
-    mock-enable: true
-  access-log:
-    enable: false
diff --git a/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/ScheduleSuggestRespDTO.java b/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/ScheduleSuggestRespDTO.java
index bb11c48..f158797 100644
--- a/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/ScheduleSuggestRespDTO.java
+++ b/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/ScheduleSuggestRespDTO.java
@@ -4,6 +4,7 @@
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.util.Date;
@@ -23,13 +24,19 @@
     private String id;
 
     @Schema(description = "标题")
+    @NotNull(message = "应用编号不能为空")
     private String title;
 
     @Schema(description = "内容")
+    @NotNull(message = "应用编号不能为空")
     private String content;
 
     @Schema(description = "排序")
+    @NotNull(message = "应用编号不能为空")
     private Integer sort;
+
+    @Schema(description = "方案ID")
+    private String schemeId;
 
     @Schema(description = "预警ID")
     private String alarmId;
@@ -41,13 +48,14 @@
     private String modelId;
 
     @Schema(description = "调整对象")
-    private String adjustObj;
+    @NotNull(message = "应用编号不能为空")
+    private String scheduleObj;
 
-    @Schema(description = "调整介质")
-    private String adjustMedium;
+    @Schema(description = "调整类型")
+    private String scheduleType;
 
     @Schema(description = "调整策略")
-    private String adjustStrategy;
+    private String scheduleStrategy;
 
     @Schema(description = "调整方式")
     private String adjustMode;
@@ -69,9 +77,18 @@
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date adjustEnd;
 
-    @Schema(description = "建议时间")
-    private Date suggestTime;
+    @Schema(description = "调度时间")
+    private Date scheduleTime;
 
     @Schema(description = "状态(0未处理 1已采纳 2已忽略)")
     private Integer status;
+
+    @Schema(description = "处理人")
+    private String handler;
+
+    @Schema(description = "处理时间")
+    private Date handleTime;
+
+    @Schema(description = "创建时间")
+    private Date createTime;
 }
\ No newline at end of file
diff --git a/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleReqDTO.java b/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleReqDTO.java
index 6e1d455..589d7f1 100644
--- a/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleReqDTO.java
+++ b/iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkScheduleReqDTO.java
@@ -1,5 +1,6 @@
 package com.iailab.module.model.api.mdk.dto;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
@@ -22,5 +23,6 @@
 
     @Schema(description = "调度方案时间")
     @NotNull(message="调度方案时间不能为空")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date scheduleTime;
 }
\ No newline at end of file
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/McsApiImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/McsApiImpl.java
index fa66d48..4d965a0 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/McsApiImpl.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/McsApiImpl.java
@@ -21,6 +21,7 @@
 import com.iailab.module.model.mcs.sche.entity.StScheduleSuggestEntity;
 import com.iailab.module.model.mcs.sche.service.StScheduleSchemeService;
 import com.iailab.module.model.mcs.sche.service.StScheduleSuggestService;
+import com.iailab.module.model.mcs.sche.vo.StScheduleSuggestSaveReqVO;
 import com.iailab.module.model.mdk.vo.ItemVO;
 import com.iailab.module.model.mpk.service.ChartService;
 import lombok.extern.slf4j.Slf4j;
@@ -134,7 +135,7 @@
         Date predictTime = reqVO.getPredictTime();
         if (predictTime == null) {
             MmItemOutputEntity output = mmItemOutputService.getOutPutById(reqVO.getOutIds().get(0));
-            ItemVO predictItem = mmPredictItemService.getItemById(output.getItemid());
+            ItemVO predictItem = mmPredictItemService.getItemByIdFromCache(output.getItemid());
             if (predictItem.getLastTime() != null) {
                 predictTime = predictItem.getLastTime();
             } else {
@@ -274,7 +275,9 @@
         for (MmItemOutputEntity out : outs) {
             legend.add(out.getResultName());
             PreDataSampleViewRespDTO viewDto = new PreDataSampleViewRespDTO();
-            viewDto.setRealData(getHisData(out.getPointid(), startTime, endTime));
+            if (StringUtils.isNotBlank(out.getPointid())) {
+                viewDto.setRealData(getHisData(out.getPointid(), startTime, endTime));
+            }
             viewDto.setPreDataN(mmItemResultService.getData(out.getId(), startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
             viewMap.put(out.getResultName(), viewDto);
         }
@@ -517,6 +520,7 @@
 
     @Override
     public Boolean createScheduleSuggest(ScheduleSuggestRespDTO dto) {
+        stScheduleSuggestService.create(ConvertUtils.sourceToTarget(dto, StScheduleSuggestSaveReqVO.class));
         return true;
     }
 
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java
index 9fe6967..0d95528 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java
@@ -97,7 +97,16 @@
                     intervalTime = (int) (reqDTO.getPredictTime().getTime() - module.getPredicttime().getTime()) / (1000 * 60);
                 }
                 List<ItemVO> predictItemList = mmPredictItemService.getByModuleId(module.getId());
-                Map<String, PredictResultVO> predictResultMap = predictModuleHandler.predict(predictItemList, reqDTO.getPredictTime(), intervalTime);
+                Map<String, PredictResultVO> predictResultMap = new HashMap<>(predictItemList.size());
+                // 分组,先运行normal预测项,再将结果传递给merge预测项
+                List<ItemVO> normalItems = predictItemList.stream().filter(e -> e.getItemType().equals("NormalItem")).collect(Collectors.toList());
+                if (!CollectionUtils.isEmpty(normalItems)) {
+                    predictModuleHandler.predict(normalItems, reqDTO.getPredictTime(), intervalTime,predictResultMap);
+                    List<ItemVO> mergeItems = predictItemList.stream().filter(e -> e.getItemType().equals("MergeItem")).collect(Collectors.toList());
+                    if (!CollectionUtils.isEmpty(mergeItems)) {
+                        predictModuleHandler.predict(mergeItems, reqDTO.getPredictTime(), intervalTime,predictResultMap);
+                    }
+                }
                 // 更新Module时间
                 dmModuleService.updatePredictTime(module.getId(), reqDTO.getPredictTime());
                 if (reqDTO.getIsResult() == null || !reqDTO.getIsResult()) {
@@ -141,27 +150,31 @@
     @Override
     public MdkPredictItemRespDTO predictItem(MdkPredictReqDTO reqDTO) {
         MdkPredictItemRespDTO resp = new MdkPredictItemRespDTO();
-
         try {
-            log.info("预测计算开始: " + System.currentTimeMillis());
-            Map<String, List<MdkPredictDataDTO>> predictData = new HashMap<>();
-            ItemVO predictItem = itemEntityFactory.getItemByItemNo(reqDTO.getItemNo());
-            PredictItemHandler predictItemHandler = predictItemFactory.create(predictItem.getId());
-            PredictResultVO predictResult = predictItemHandler.predict(reqDTO.getPredictTime(), predictItem);
-            Map<String, List<DataValueVO>> resultMap = predictResultHandler.convertToPredictData(predictResult);
-            if (!CollectionUtils.isEmpty(resultMap)) {
-                for (Map.Entry<String, List<DataValueVO>> entry : resultMap.entrySet()) {
-                    List<MdkPredictDataDTO>  data = ConvertUtils.sourceToTarget(entry.getValue(), MdkPredictDataDTO.class);
-                    predictData.put(entry.getKey(), data);
-                }
+
+            ItemVO itemByItemNo = mmPredictItemService.getItemByItemNo(reqDTO.getItemNo());
+            List<ItemVO> predictItemList = new ArrayList<>();
+            predictItemList.add(itemByItemNo);
+            Map<String, PredictResultVO> predictResultMap = new HashMap<>(predictItemList.size());
+            predictModuleHandler.predict(predictItemList, reqDTO.getPredictTime(), 0,predictResultMap);
+
+            Map<String, List<MdkPredictDataDTO>> itemPredictData = new HashMap<>();
+
+            Map<String, List<DataValueVO>> predictLists = predictResultHandler.convertToPredictData2(predictResultMap.get(reqDTO.getItemNo()));
+            for (Map.Entry<String, List<DataValueVO>> dataListEntry : predictLists.entrySet()) {
+                List<MdkPredictDataDTO> predictData = dataListEntry.getValue().stream().map(t -> {
+                    MdkPredictDataDTO dto1 = new MdkPredictDataDTO();
+                    dto1.setDataTime(t.getDataTime());
+                    dto1.setDataValue(t.getDataValue());
+                    return dto1;
+                }).collect(Collectors.toList());
+                itemPredictData.put(dataListEntry.getKey(), predictData);
             }
-            resp.setPredictData(predictData);
-            resp.setItemId(predictItem.getId());
+            resp.setItemId(reqDTO.getItemNo());
             resp.setPredictTime(reqDTO.getPredictTime());
-            log.info("预测计算结束: " + System.currentTimeMillis());
-        } catch (Exception ex) {
-            log.info("预测计算异常: " + System.currentTimeMillis(), ex);
-            return resp;
+            resp.setPredictData(itemPredictData);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
         }
 
         return resp;
@@ -198,7 +211,7 @@
             log.info("预测计算结束: " + System.currentTimeMillis());
         } catch (Exception ex) {
             log.info("调度计算异常: " + System.currentTimeMillis());
-            ex.printStackTrace();
+//            ex.printStackTrace();
             return resp;
         }
         return resp;
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/common/enums/OutResultType.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/common/enums/OutResultType.java
index 55aa358..95e6608 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/common/enums/OutResultType.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/common/enums/OutResultType.java
@@ -12,7 +12,8 @@
 @AllArgsConstructor
 public enum OutResultType {
     D1(1, "一维数组"),
-    D2(2, "二维数组");
+    D2(2, "二维数组"),
+    D(3, "二维数组");
 
     private Integer code;
     private String desc;
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/common/exception/ModelResultErrorException.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/common/exception/ModelResultErrorException.java
new file mode 100644
index 0000000..99bfe58
--- /dev/null
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/common/exception/ModelResultErrorException.java
@@ -0,0 +1,51 @@
+package com.iailab.module.model.common.exception;
+
+/**
+ * 模型结果错误异常
+ */
+public class ModelResultErrorException extends RuntimeException {
+	private static final long serialVersionUID = 1L;
+
+    private String msg;
+    private int code = 200;
+
+    public ModelResultErrorException(String msg) {
+		super(msg);
+		this.msg = msg;
+	}
+
+	public ModelResultErrorException(String msg, Throwable e) {
+		super(msg, e);
+		this.msg = msg;
+	}
+
+	public ModelResultErrorException(String msg, int code) {
+		super(msg);
+		this.msg = msg;
+		this.code = code;
+	}
+
+	public ModelResultErrorException(String msg, int code, Throwable e) {
+		super(msg, e);
+		this.msg = msg;
+		this.code = code;
+	}
+
+	public String getMsg() {
+		return msg;
+	}
+
+	public void setMsg(String msg) {
+		this.msg = msg;
+	}
+
+	public int getCode() {
+		return code;
+	}
+
+	public void setCode(int code) {
+		this.code = code;
+	}
+
+
+}
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/dto/MmPredictItemDTO.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/dto/MmPredictItemDTO.java
index 871679f..0fb5c26 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/dto/MmPredictItemDTO.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/dto/MmPredictItemDTO.java
@@ -32,4 +32,9 @@
     private List<MmModelParamEntity> mmModelParamList;
 
     private List<MmItemResultEntity> mmItemResultList;
+
+    /**
+     * 计算预测项真实数据点
+     */
+    private String pointId;
 }
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/enums/ItemRunStatusEnum.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/enums/ItemRunStatusEnum.java
index ae3d3f4..c593110 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/enums/ItemRunStatusEnum.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/enums/ItemRunStatusEnum.java
@@ -13,7 +13,9 @@
 public enum ItemRunStatusEnum {
     PROCESSING(1, "处理中"),
     SUCCESS(2, "成功"),
-    FAIL(3, "失败");
+    FAIL(3, "失败"),
+    MODELRESULTERROR(4, "模型结果异常"),
+    MODELRESULTSAVEERROR(5, "模型结果保存异常");
 
     private Integer code;
     private String desc;
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/MmItemResultService.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/MmItemResultService.java
index bc61c47..55dac3f 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/MmItemResultService.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/MmItemResultService.java
@@ -1,5 +1,6 @@
 package com.iailab.module.model.mcs.pre.service;
 
+import com.iailab.module.model.mcs.pre.entity.MmItemOutputEntity;
 import com.iailab.module.model.mdk.vo.DataValueVO;
 
 import java.util.Date;
@@ -17,4 +18,6 @@
     List<DataValueVO> getPredictValue(String outputid, Date startTime, Date endTime);
 
     List<Object[]> getData(String outputid, Date startTime, Date endTime, String timeFormat);
+
+    void savePredictValue(Map<MmItemOutputEntity, Double> predictDoubleValues, Date predictTime);
 }
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/MmPredictItemService.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/MmPredictItemService.java
index e837bf0..72dc043 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/MmPredictItemService.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/MmPredictItemService.java
@@ -8,7 +8,6 @@
 import com.iailab.module.model.mdk.vo.ItemVO;
 import com.iailab.module.model.mdk.vo.MergeItemVO;
 
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -28,6 +27,7 @@
 
     ItemVO getItemByItemNo(String itemNo);
 
+    ItemVO getItemByIdFromCache(String itemId);
     ItemVO getItemById(String itemId);
 
     ItemVO getItemByOutPutId(String outPutId);
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmItemResultServiceImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmItemResultServiceImpl.java
index 99455b0..26ec871 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmItemResultServiceImpl.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmItemResultServiceImpl.java
@@ -5,6 +5,7 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.iailab.framework.common.util.date.DateUtils;
 import com.iailab.module.model.mcs.pre.dao.MmItemResultDao;
+import com.iailab.module.model.mcs.pre.entity.MmItemOutputEntity;
 import com.iailab.module.model.mcs.pre.entity.MmItemResultEntity;
 import com.iailab.module.model.mcs.pre.entity.MmItemResultJsonEntity;
 import com.iailab.module.model.mcs.pre.service.MmItemResultService;
@@ -138,4 +139,19 @@
         });
         return result;
     }
+
+    @Override
+    public void savePredictValue(Map<MmItemOutputEntity, Double> predictDoubleValues, Date predictTime) {
+        for (Map.Entry<MmItemOutputEntity, Double> entry : predictDoubleValues.entrySet()) {
+            MmItemResultJsonEntity resultJson = new MmItemResultJsonEntity();
+            resultJson.setId(UUID.randomUUID().toString());
+            resultJson.setOutputid(entry.getKey().getId());
+            resultJson.setPredicttime(predictTime);
+            resultJson.setCumulant(String.valueOf(entry.getValue()));
+            Map<String, Object> map4 = new HashMap(2);
+            map4.put("TABLENAME", "T_MM_ITEM_RESULT_JSON");
+            map4.put("entity", resultJson);
+            mmItemResultDao.savePredictJsonValue(map4);
+        }
+    }
 }
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmModelArithSettingsServiceImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmModelArithSettingsServiceImpl.java
index ac41e19..dc13a83 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmModelArithSettingsServiceImpl.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmModelArithSettingsServiceImpl.java
@@ -57,5 +57,7 @@
     @Override
     public void updatePyFile(String pyModule, String fileName) {
         baseMapper.updatePyFile(pyModule + "." + fileName.substring(0,fileName.lastIndexOf("_")+1),pyModule + "." + fileName);
+        // 清空缓存
+        modelIdMap.clear();
     }
 }
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmPredictItemServiceImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmPredictItemServiceImpl.java
index 7f4dfec..0bd305c 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmPredictItemServiceImpl.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmPredictItemServiceImpl.java
@@ -118,6 +118,14 @@
             MmPredictMergeItemEntity mMmPredictMergeItem = mmPredictItemDto.getMmPredictMergeItem();
             mMmPredictMergeItem.setItemid(predictItem.getId());
             mmPredictMergeItemService.savePredictMergeItem(mMmPredictMergeItem);
+            // 添加一条默认output
+            List<MmItemOutputEntity> mergeItemOutput = new ArrayList<>(1);
+            MmItemOutputEntity entity = new MmItemOutputEntity();
+            entity.setPointid(mmPredictItemDto.getPointId());
+            entity.setResultName(mmPredictItemDto.getMmPredictItem().getItemname());
+            entity.setResultstr("result");
+            mergeItemOutput.add(entity);
+            mmPredictItemDto.setMmItemOutputList(mergeItemOutput);
         }
         mmPredictItemDao.insert(predictItem);
         DmModuleItemEntity dmModuleItem = mmPredictItemDto.getDmModuleItem();
@@ -160,6 +168,19 @@
         } else if (itemType != null && ItemTypeEnum.MERGE_ITEM.getName().equals(itemType.getItemtypename())) {
             MmPredictMergeItemEntity mMmPredictMergeItem = mmPredictItemDto.getMmPredictMergeItem();
             mmPredictMergeItemService.update(mMmPredictMergeItem);
+            // 修改默认output
+            List<MmItemOutputEntity> mmItemOutputList = mmPredictItemDto.getMmItemOutputList();
+            if (CollectionUtils.isEmpty(mmItemOutputList)) {
+                mmItemOutputList = new ArrayList<>(1);
+                MmItemOutputEntity entity = new MmItemOutputEntity();
+                entity.setPointid(mmPredictItemDto.getPointId());
+                entity.setResultName(mmPredictItemDto.getMmPredictItem().getItemname());
+                entity.setResultstr("result");
+                mmItemOutputList.add(entity);
+                mmPredictItemDto.setMmItemOutputList(mmItemOutputList);
+            } else {
+                mmPredictItemDto.getMmItemOutputList().forEach(e -> e.setPointid(mmPredictItemDto.getPointId()));
+            }
         }
         DmModuleItemEntity dmModuleItem = mmPredictItemDto.getDmModuleItem();
         if (!"".equals(dmModuleItem.getId()) && dmModuleItem.getId() != null) {
@@ -215,6 +236,9 @@
             mmPredictItemDto.setMmModelParamList(new ArrayList<>());
             mmPredictItemDto.setMmPredictMergeItem(new MmPredictMergeItemEntity());
             mmPredictItemDto.setMmPredictMergeItem(mmPredictMergeItemService.getByItemid(id));
+            if (!CollectionUtils.isEmpty(mmPredictItemDto.getMmItemOutputList())) {
+                mmPredictItemDto.setPointId(mmPredictItemDto.getMmItemOutputList().get(0).getPointid());
+            }
         }
         return mmPredictItemDto;
     }
@@ -258,7 +282,7 @@
     }
 
     @Override
-    public ItemVO getItemById(String itemId) {
+    public ItemVO getItemByIdFromCache(String itemId) {
         if (StringUtils.isBlank(itemId)) {
             return null;
         }
@@ -275,6 +299,17 @@
     }
 
     @Override
+    public ItemVO getItemById(String itemId) {
+        Map<String, Object> params = new HashMap<>(1);
+        params.put("ITEMID", itemId);
+        List<ItemVO> list = mmPredictItemDao.getItem(params);
+        if (CollectionUtils.isEmpty(list)) {
+            return null;
+        }
+        return list.get(0);
+    }
+
+    @Override
     public ItemVO getItemByOutPutId(String outPutId) {
         if (StringUtils.isBlank(outPutId)) {
             return null;
@@ -284,7 +319,7 @@
             return null;
         }
         String itemId = outPutById.getItemid();
-        return getItemById(itemId);
+        return getItemByIdFromCache(itemId);
     }
 
     @Override
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/impl/StScheduleSchemeServiceImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/impl/StScheduleSchemeServiceImpl.java
index 2de77b6..623334c 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/impl/StScheduleSchemeServiceImpl.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/impl/StScheduleSchemeServiceImpl.java
@@ -63,7 +63,7 @@
     @Override
     public List<StScheduleSchemeDTO> list(Map<String, Object> params) {
         QueryWrapper<StScheduleSchemeEntity> queryWrapper = new QueryWrapper<>();
-        queryWrapper.eq("trigger_method", "1");
+        queryWrapper.eq("trigger_method", params.get("trigger_method"));
         queryWrapper.eq("trigger_condition", params.get("trigger_condition"));
         List<StScheduleSchemeEntity> list = baseDao.selectList(queryWrapper);
         return ConvertUtils.sourceToTarget(list, StScheduleSchemeDTO.class);
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/vo/StScheduleSuggestSaveReqVO.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/vo/StScheduleSuggestSaveReqVO.java
index fa3a51b..e36dbc1 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/vo/StScheduleSuggestSaveReqVO.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/vo/StScheduleSuggestSaveReqVO.java
@@ -1,5 +1,6 @@
 package com.iailab.module.model.mcs.sche.vo;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
@@ -66,9 +67,11 @@
     private BigDecimal adjustTimes;
 
     @Schema(description = "调整开始时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date adjustStart;
 
     @Schema(description = "调整结束时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date adjustEnd;
 
     @Schema(description = "调度时间")
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/factory/ItemEntityFactory.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/factory/ItemEntityFactory.java
index 52924f1..82634b2 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/factory/ItemEntityFactory.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/factory/ItemEntityFactory.java
@@ -77,7 +77,7 @@
      * @return
      */
     public ItemVO getItemById(String itemId) {
-        ItemVO ItemVO = mmPredictItemService.getItemById(itemId);
+        ItemVO ItemVO = mmPredictItemService.getItemByIdFromCache(itemId);
         if (!ItemVOHashMap.containsKey(itemId)) {
             if (ItemVO != null) {
                 ItemVOHashMap.put(itemId, ItemVO);
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictItemHandler.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictItemHandler.java
index c0d15dc..2c4cf78 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictItemHandler.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictItemHandler.java
@@ -1,10 +1,12 @@
 package com.iailab.module.model.mdk.predict;
 
+import com.iailab.module.model.mcs.pre.enums.ItemRunStatusEnum;
 import com.iailab.module.model.mdk.common.exceptions.ItemInvokeException;
 import com.iailab.module.model.mdk.vo.ItemVO;
 import com.iailab.module.model.mdk.vo.PredictResultVO;
 
 import java.util.Date;
+import java.util.Map;
 
 /**
  * @author PanZhibao
@@ -21,5 +23,5 @@
      * @return
      * @throws ItemInvokeException
      */
-    PredictResultVO predict(Date predictTime, ItemVO predictItemDto) throws ItemInvokeException;
+    PredictResultVO predict(Date predictTime, ItemVO predictItemDto, Map<String, double[]> predictValueMap) throws ItemInvokeException;
 }
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictModelHandler.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictModelHandler.java
index 9379a02..4eee9fe 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictModelHandler.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictModelHandler.java
@@ -1,6 +1,7 @@
 package com.iailab.module.model.mdk.predict;
 
 import com.iailab.module.model.mcs.pre.entity.MmPredictModelEntity;
+import com.iailab.module.model.mcs.pre.enums.ItemRunStatusEnum;
 import com.iailab.module.model.mdk.common.exceptions.ModelInvokeException;
 import com.iailab.module.model.mdk.vo.PredictResultVO;
 
@@ -21,5 +22,5 @@
      * @return
      * @throws ModelInvokeException
      */
-    PredictResultVO predictByModel(Date predictTime, MmPredictModelEntity predictModel) throws ModelInvokeException;
+    PredictResultVO predictByModel(Date predictTime, MmPredictModelEntity predictModel,String itemName) throws ModelInvokeException;
 }
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictModuleHandler.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictModuleHandler.java
index 9a5f462..47596e7 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictModuleHandler.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictModuleHandler.java
@@ -1,5 +1,7 @@
 package com.iailab.module.model.mdk.predict;
 
+import com.iailab.module.model.common.exception.ModelResultErrorException;
+import com.iailab.module.model.mcs.pre.entity.MmItemOutputEntity;
 import com.iailab.module.model.mcs.pre.enums.ItemRunStatusEnum;
 import com.iailab.module.model.mcs.pre.enums.ItemStatus;
 import com.iailab.module.model.mcs.pre.service.MmItemStatusService;
@@ -9,6 +11,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
 
 import java.text.MessageFormat;
 import java.time.Duration;
@@ -46,54 +49,68 @@
      * @param intervalTime
      * @return
      */
-    public Map<String, PredictResultVO> predict(List<ItemVO> predictItemList, Date predictTime, int intervalTime) {
-        Map<String, PredictResultVO> result = new HashMap<>();
-
-        PredictResultVO predictResult = new PredictResultVO();
+    public void predict(List<ItemVO> predictItemList, Date predictTime, int intervalTime,Map<String, PredictResultVO> predictResultMap) {
+        Map<String, double[]> predictValueMap = null;
+        if (!CollectionUtils.isEmpty(predictResultMap)) {
+            // 将predictResultMap处理成Map<outPutId, double[]>
+            predictValueMap = new HashMap<>();
+            for (Map.Entry<String, PredictResultVO> entry : predictResultMap.entrySet()) {
+                for (Map.Entry<MmItemOutputEntity, double[]> mmItemOutputEntityEntry : entry.getValue().getPredictMatrixs().entrySet()) {
+                    predictValueMap.put(mmItemOutputEntityEntry.getKey().getId(),mmItemOutputEntityEntry.getValue());
+                }
+            }
+        }
         for (ItemVO predictItem : predictItemList) {
+            PredictResultVO predictResult;
             if (!predictItem.getStatus().equals(ItemStatus.STATUS1.getCode())) {
                 continue;
             }
             Long totalDur = 0L;
+            ItemRunStatusEnum itemRunStatusEnum = ItemRunStatusEnum.PROCESSING;
             try {
-                mmItemStatusService.recordStatus(predictItem.getId(), ItemRunStatusEnum.PROCESSING, totalDur, predictTime);
+                mmItemStatusService.recordStatus(predictItem.getId(), itemRunStatusEnum, totalDur, predictTime);
                 PredictItemHandler predictItemHandler = predictItemFactory.create(predictItem.getId());
                 long start = System.currentTimeMillis();
                 try {
                     // 预测项开始预测
-                    predictResult = predictItemHandler.predict(predictTime, predictItem);
+                    predictResult = predictItemHandler.predict(predictTime, predictItem, predictValueMap);
+                } catch (ModelResultErrorException e) {
+                    itemRunStatusEnum = ItemRunStatusEnum.MODELRESULTERROR;
+                    continue;
                 } catch (Exception e) {
-                    e.printStackTrace();
-                    log.error(String.valueOf(e));
-                    mmItemStatusService.recordStatus(predictItem.getId(), ItemRunStatusEnum.FAIL, totalDur, predictTime);
+                    itemRunStatusEnum = ItemRunStatusEnum.FAIL;
                     continue;
                 }
                 long end = System.currentTimeMillis();
                 Long drtPre = end - start;
                 log.info(MessageFormat.format("预测项:{0},预测时间:{1}ms", predictItem.getItemName(), drtPre));
                 totalDur = totalDur + drtPre;
-
                 predictResult.setGranularity(predictItem.getGranularity());
                 predictResult.setT(intervalTime);
                 predictResult.setSaveIndex(predictItem.getSaveIndex());
                 predictResult.setLt(1);
+                predictResultMap.put(predictItem.getItemNo(), predictResult);
 
                 // 保存预测结果
-                predictResultHandler.savePredictResult(predictResult);
-                long endSave = System.currentTimeMillis();
-                Long drtSave = endSave - end;
-                log.info(MessageFormat.format("预测项:{0},保存时间:{1}ms", predictItem.getItemName(),
-                        drtSave));
-                totalDur = totalDur + drtSave;
-                mmItemStatusService.recordStatus(predictItem.getId(), ItemRunStatusEnum.SUCCESS, totalDur, predictTime);
-                result.put(predictItem.getItemNo(), predictResult);
+                try {
+                    predictResultHandler.savePredictResult(predictResult);
+                } catch (Exception e) {
+                    itemRunStatusEnum = ItemRunStatusEnum.MODELRESULTSAVEERROR;
+                    throw new RuntimeException("模型结果保存异常,result:" + predictResult);
+                }
+                itemRunStatusEnum = ItemRunStatusEnum.SUCCESS;
+//                long endSave = System.currentTimeMillis();
+//                Long drtSave = endSave - end;
+//                log.info(MessageFormat.format("预测项:{0},保存时间:{1}ms", predictItem.getItemName(),
+//                        drtSave));
+//                totalDur = totalDur + drtSave;
             } catch (Exception e) {
                 e.printStackTrace();
                 log.error(MessageFormat.format("预测项编号:{0},预测项名称:{1},预测失败:{2} 预测时刻:{3}",
                         predictItem.getId(), predictItem.getItemName(), e.getMessage(), predictTime));
-                mmItemStatusService.recordStatus(predictItem.getId(), ItemRunStatusEnum.FAIL, totalDur, predictTime);
+            } finally {
+                mmItemStatusService.recordStatus(predictItem.getId(), itemRunStatusEnum, totalDur, predictTime);
             }
         }
-        return result;
     }
 }
\ No newline at end of file
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictResultHandler.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictResultHandler.java
index 39729a7..d9bfcc7 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictResultHandler.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/PredictResultHandler.java
@@ -91,6 +91,10 @@
     public void savePredictResult(PredictResultVO predictResult) {
         Map<String, List<DataValueVO>> resultMap = convertToPredictData(predictResult);
         mmItemResultService.savePredictValue(resultMap, predictResult.getLt(), "n", predictResult.getPredictTime());
+        // 存double类型输出
+        if (!CollectionUtils.isEmpty(predictResult.getPredictDoubleValues())) {
+            mmItemResultService.savePredictValue(predictResult.getPredictDoubleValues(), predictResult.getPredictTime());
+        }
     }
 
     public List<DataValueVO> getPredictValueByItemNo(String itemNo, Date start, Date end) {
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictItemMergeHandlerImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictItemMergeHandlerImpl.java
index ef85630..31d481e 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictItemMergeHandlerImpl.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictItemMergeHandlerImpl.java
@@ -1,25 +1,22 @@
 package com.iailab.module.model.mdk.predict.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.iailab.module.data.api.point.DataPointApi;
-import com.iailab.module.data.api.point.dto.ApiPointDTO;
-import com.iailab.module.data.enums.DataPointFreqEnum;
 import com.iailab.module.model.mcs.pre.entity.MmItemOutputEntity;
 import com.iailab.module.model.mcs.pre.service.MmItemOutputService;
 import com.iailab.module.model.mcs.pre.service.MmItemResultService;
-import com.iailab.module.model.mdk.common.enums.ItemPredictStatus;
 import com.iailab.module.model.mdk.common.exceptions.ItemInvokeException;
 import com.iailab.module.model.mdk.factory.ItemEntityFactory;
 import com.iailab.module.model.mdk.factory.PredictItemFactory;
 import com.iailab.module.model.mdk.predict.PredictItemHandler;
 import com.iailab.module.model.mdk.predict.PredictResultHandler;
-import com.iailab.module.model.mdk.vo.DataValueVO;
 import com.iailab.module.model.mdk.vo.ItemVO;
 import com.iailab.module.model.mdk.vo.PredictResultVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
 
-import java.sql.Timestamp;
 import java.util.*;
 
 /**
@@ -58,16 +55,14 @@
      * @throws ItemInvokeException
      */
     @Override
-    public PredictResultVO predict(Date predictTime, ItemVO predictItemDto)
+    public PredictResultVO predict(Date predictTime, ItemVO predictItemDto, Map<String, double[]> predictValueMap)
             throws ItemInvokeException {
         PredictResultVO predictResult = new PredictResultVO();
-        ItemPredictStatus itemStatus = ItemPredictStatus.PREDICTING;
         String itemId = predictItemDto.getId();
         try {
             String expression = itemEntityFactory.getMergeItem(itemId).getExpression();
             int predictLength = itemEntityFactory.getItemById(itemId).getPredictLength();
-            double[][] predictResultMat = new double[predictLength][1];
-            Map<String, List<DataValueVO>> predictValueMap = new HashMap<>();
+            double[] predictResultMat = new double[predictLength];
             String[] mathOutPutId = expression.split("[\\+ \\-]");
             ArrayList<Character> operator = new ArrayList<>();
             for (int i = 0; i < expression.length(); i++) {
@@ -75,75 +70,79 @@
                     operator.add(expression.charAt(i));
                 }
             }
-            String[] compositionItem = expression.split(String.valueOf("&".toCharArray()));
+//            String[] compositionItem = expression.split(String.valueOf("&".toCharArray()));
             //是否为计算预测项
             if (mathOutPutId.length > 1) {
-                for (String outPutId : mathOutPutId) {
-                    if (outPutId.length() > 4) {
-                        Date endTime = predictTime;
-//                        ItemVO itemEntity = itemEntityFactory.getItemByItemNo(itemNo);
-//                        List<MmItemOutputEntity> outPutList = itemEntityFactory.getOutPutByItemId(itemEntity.getId());
-                        MmItemOutputEntity outPut = mmItemOutputService.getOutPutById(outPutId);
-                        ApiPointDTO pointEntity = dataPointApi.getInfoById(outPut.getPointid());
+//                Map<String, List<DataValueVO>> predictValueMap = new HashMap<>();
+//                for (String outPutId : mathOutPutId) {
+//                    if (outPutId.length() > 4) {
+//                        Date endTime = predictTime;
+////                        ItemVO itemEntity = itemEntityFactory.getItemByItemNo(itemNo);
+////                        List<MmItemOutputEntity> outPutList = itemEntityFactory.getOutPutByItemId(itemEntity.getId());
+//                        MmItemOutputEntity outPut = mmItemOutputService.getOutPutById(outPutId);
+//                        ApiPointDTO pointEntity = dataPointApi.getInfoById(outPut.getPointid());
+//
+//                        Calendar calendar = Calendar.getInstance();
+//                        calendar.setTime(endTime);
+//                        calendar.add(Calendar.SECOND, (predictLength - 1) * DataPointFreqEnum.getEumByCode(pointEntity.getMinfreqid()).getValue());
+//                        endTime = new Timestamp(calendar.getTime().getTime());
+////                        List<DataValueVO> predictValueList = predictResultHandler.getPredictValueByItemNo(itemNo, predictTime, endTime);
+//                        List<DataValueVO> predictValueList = mmItemResultService.getPredictValue(outPutId, predictTime, endTime);
+//                        if (predictValueList.size() != predictLength) {
+//                            log.debug("merge项融合失败:缺少子项预测数据,对应子项outPutId=" + outPutId);
+//                            return null;
+//                        }
+//                        predictValueMap.put(outPutId, predictValueList);
+//                    }
+//                }
 
-                        Calendar calendar = Calendar.getInstance();
-                        calendar.setTime(endTime);
-                        calendar.add(Calendar.SECOND, (predictLength - 1) * DataPointFreqEnum.getEumByCode(pointEntity.getMinfreqid()).getValue());
-                        endTime = new Timestamp(calendar.getTime().getTime());
-//                        List<DataValueVO> predictValueList = predictResultHandler.getPredictValueByItemNo(itemNo, predictTime, endTime);
-                        List<DataValueVO> predictValueList = mmItemResultService.getPredictValue(outPutId, predictTime, endTime);
-                        if (predictValueList.size() != predictLength) {
-                            log.debug("merge项融合失败:缺少子项预测数据,对应子项outPutId=" + outPutId);
-                            return null;
-                        }
-                        predictValueMap.put(outPutId, predictValueList);
-                    }
-                }
                 for (Integer i = 0; i < predictLength; i++) {
                     double sum =0.0;
-                    sum = predictValueMap.get(mathOutPutId[0]).get(i).getDataValue();
+                    sum = predictValueMap.get(mathOutPutId[0])[i];
                     for (int j = 1; j < mathOutPutId.length; j++) {
                         if (operator.get(j-1)=='+')
-                        {sum += predictValueMap.get(mathOutPutId[j]).get(i).getDataValue();}
+                        {sum += predictValueMap.get(mathOutPutId[j])[i];}
                         if (operator.get(j-1)=='-')
-                        {sum -= predictValueMap.get(mathOutPutId[j]).get(i).getDataValue();}
+                        {sum -= predictValueMap.get(mathOutPutId[j])[i];}
                     }
-                    predictResultMat[i][0] = sum;
+                    predictResultMat[i] = sum;
                 }
             }
             //是否为组合预测项
-            if (compositionItem.length > 1) {
-                Map<String, PredictResultVO> predictResultMap = new HashMap<>();
-                Integer columnTotalNumber = 0;
-                Integer rowNumber = 0;
-                for (String itemNo : compositionItem) {
-                    PredictItemHandler predictItem = (PredictItemHandler) predictItemFactory.create(itemEntityFactory.
-                            getItemByItemNo(itemNo).getId());
-                    predictResult = predictItem.predict(predictTime, predictItemDto);
-                    columnTotalNumber += Integer.valueOf(predictResult.getPredictMatrix().length);
-                    predictResultMap.put(itemNo, predictItem.predict(predictTime, predictItemDto));
-                }
-                double[][] matrix = new double[columnTotalNumber][1];
-                for (String itemNo : compositionItem) {
-                    for (Integer i = 0; i < predictResultMap.get(itemNo).getPredictMatrix().length; i++) {
-                        matrix[rowNumber][0] = predictResultMap.get(itemNo).getPredictMatrix()[i][0];
-                        rowNumber++;
-                    }
-                }
-                predictResult.setPredictMatrix(matrix);
-            }
+//            if (compositionItem.length > 1) {
+//                Map<String, PredictResultVO> predictResultMap = new HashMap<>();
+//                Integer columnTotalNumber = 0;
+//                Integer rowNumber = 0;
+//                for (String itemNo : compositionItem) {
+//                    PredictItemHandler predictItem = (PredictItemHandler) predictItemFactory.create(itemEntityFactory.
+//                            getItemByItemNo(itemNo).getId());
+//                    predictResult = predictItem.predict(predictTime, predictItemDto);
+//                    columnTotalNumber += Integer.valueOf(predictResult.getPredictMatrix().length);
+//                    predictResultMap.put(itemNo, predictItem.predict(predictTime, predictItemDto));
+//                }
+//                double[][] matrix = new double[columnTotalNumber][1];
+//                for (String itemNo : compositionItem) {
+//                    for (Integer i = 0; i < predictResultMap.get(itemNo).getPredictMatrix().length; i++) {
+//                        matrix[rowNumber][0] = predictResultMap.get(itemNo).getPredictMatrix()[i][0];
+//                        rowNumber++;
+//                    }
+//                }
+//                predictResult.setPredictMatrix(matrix);
+//            }
             predictResult.setPredictId(itemId);
-            predictResult.setPredictMatrix(predictResultMat);
+            List<MmItemOutputEntity> outputServiceByItemid = mmItemOutputService.getByItemid(itemId);
+            if (!CollectionUtils.isEmpty(outputServiceByItemid)) {
+                Map<MmItemOutputEntity, double[]> predictMatrixs = new HashMap<>();
+                predictMatrixs.put(outputServiceByItemid.get(0),predictResultMat);
+                predictResult.setPredictMatrixs(predictMatrixs);
+            }
             predictResult.setPredictTime(predictTime);
-            //预测项预测成功的状态
-            itemStatus = ItemPredictStatus.SUCCESS;
         } catch (Exception e) {
-            //预测项预测失败的状态
-            itemStatus = ItemPredictStatus.FAILED;
-            log.debug("merge项预测失败,itemId:" + itemId);
+            log.error("merge项预测失败,itemId:" + itemId);
+            e.printStackTrace();
             throw e;
         }
-        log.debug("预测完成,itemId:" + itemId + ",itemStatus:" + itemStatus.getValue());
+        log.info("merge项预测完成,itemId:" + itemId + ",结果:" + JSON.toJSONString(predictResult));
         return predictResult;
     }
 }
\ No newline at end of file
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictItemNormalHandlerImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictItemNormalHandlerImpl.java
index 855794b..025ce4e 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictItemNormalHandlerImpl.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictItemNormalHandlerImpl.java
@@ -1,6 +1,7 @@
 package com.iailab.module.model.mdk.predict.impl;
 
 import com.iailab.module.model.mcs.pre.entity.MmPredictModelEntity;
+import com.iailab.module.model.mcs.pre.enums.ItemRunStatusEnum;
 import com.iailab.module.model.mcs.pre.service.MmPredictModelService;
 import com.iailab.module.model.mdk.common.exceptions.ItemInvokeException;
 import com.iailab.module.model.mdk.common.exceptions.ModelInvokeException;
@@ -13,6 +14,7 @@
 
 import java.text.MessageFormat;
 import java.util.Date;
+import java.util.Map;
 
 /**
  * @author PanZhibao
@@ -37,17 +39,17 @@
      * @throws ItemInvokeException
      */
     @Override
-    public PredictResultVO predict(Date predictTime, ItemVO predictItemDto) throws ItemInvokeException {
+    public PredictResultVO predict(Date predictTime, ItemVO predictItemDto, Map<String, double[]> predictValueMap) throws ItemInvokeException {
         PredictResultVO predictResult = new PredictResultVO();
         String itemId = predictItemDto.getId();
-        predictResult.setPredictId(itemId);
         try {
             MmPredictModelEntity predictModel = mmPredictModelService.getActiveModelByItemId(itemId);
             if (predictModel == null) {
                 throw new ModelInvokeException(MessageFormat.format("{0},itemId={1}",
                         ModelInvokeException.errorGetModelEntity, itemId));
             }
-            predictResult = predictModelHandler.predictByModel(predictTime, predictModel);
+            predictResult = predictModelHandler.predictByModel(predictTime, predictModel,predictItemDto.getItemName());
+            predictResult.setPredictId(itemId);
         } catch (Exception ex) {
             throw new ItemInvokeException(MessageFormat.format("{0},itemId={1}",
                     ItemInvokeException.errorItemFailed, itemId));
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictModelHandlerImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictModelHandlerImpl.java
index e8a9142..19c8582 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictModelHandlerImpl.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/predict/impl/PredictModelHandlerImpl.java
@@ -1,13 +1,16 @@
 package com.iailab.module.model.mdk.predict.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.iail.model.IAILModel;
 import com.iailab.module.model.common.enums.CommonConstant;
 import com.iailab.module.model.common.enums.OutResultType;
+import com.iailab.module.model.common.exception.ModelResultErrorException;
 import com.iailab.module.model.mcs.pre.entity.MmItemOutputEntity;
 import com.iailab.module.model.mcs.pre.entity.MmModelArithSettingsEntity;
 import com.iailab.module.model.mcs.pre.entity.MmPredictModelEntity;
+import com.iailab.module.model.mcs.pre.enums.ItemRunStatusEnum;
 import com.iailab.module.model.mcs.pre.service.MmItemOutputService;
 import com.iailab.module.model.mcs.pre.service.MmModelArithSettingsService;
 import com.iailab.module.model.mdk.common.enums.TypeA;
@@ -54,7 +57,7 @@
      * @throws ModelInvokeException
      */
     @Override
-    public synchronized PredictResultVO predictByModel(Date predictTime, MmPredictModelEntity predictModel) throws ModelInvokeException {
+    public synchronized PredictResultVO predictByModel(Date predictTime, MmPredictModelEntity predictModel,String itemName) throws ModelInvokeException {
         PredictResultVO result = new PredictResultVO();
         if (predictModel == null) {
             throw new ModelInvokeException("modelEntity is null");
@@ -86,29 +89,30 @@
             param2Values[portLength] = newModelBean.getDataMap().get("models");
             param2Values[portLength + 1] = settings;
 
-            log.info("#######################预测模型 " + predictModel.getItemid() + " ##########################");
-            JSONObject jsonObjNewModelBean = new JSONObject();
-            jsonObjNewModelBean.put("newModelBean", newModelBean);
-            log.info(String.valueOf(jsonObjNewModelBean));
-            JSONObject jsonObjParam2Values = new JSONObject();
-            jsonObjParam2Values.put("param2Values", param2Values);
-            log.info(String.valueOf(jsonObjParam2Values));
+            log.info("####################### 预测模型 "+ "【itemId:" + predictModel.getItemid() + ",itemName" + itemName + "】 ##########################");
+//            JSONObject jsonObjNewModelBean = new JSONObject();
+//            jsonObjNewModelBean.put("newModelBean", newModelBean);
+//            log.info(String.valueOf(jsonObjNewModelBean));
+//            JSONObject jsonObjParam2Values = new JSONObject();
+//            jsonObjParam2Values.put("param2Values", param2Values);
+            log.info("参数: " + JSON.toJSONString(param2Values));
 
             //IAILMDK.run
             HashMap<String, Object> modelResult = DllUtils.run(newModelBean, param2Values, predictModel.getMpkprojectid());
             if (!modelResult.containsKey(CommonConstant.MDK_STATUS_CODE) || !modelResult.containsKey(CommonConstant.MDK_RESULT) ||
                     !modelResult.get(CommonConstant.MDK_STATUS_CODE).toString().equals(CommonConstant.MDK_STATUS_100)) {
-                throw new RuntimeException("模型结果异常:" + modelResult);
+                throw new ModelResultErrorException("模型结果异常:" + modelResult);
             }
             modelResult = (HashMap<String, Object>) modelResult.get(CommonConstant.MDK_RESULT);
             //打印结果
-            log.info("预测模型计算完成:modelId=" + modelId + modelResult);
+            log.info("预测模型计算完成:modelId=" + modelId + ",modelName" + predictModel.getMethodname());
             JSONObject jsonObjResult = new JSONObject();
             jsonObjResult.put("result", modelResult);
             log.info(String.valueOf(jsonObjResult));
 
             List<MmItemOutputEntity> itemOutputList = mmItemOutputService.getByItemid(predictModel.getItemid());
-            Map<MmItemOutputEntity, double[]> predictMatrixs = new HashMap<>(itemOutputList.size());
+            Map<MmItemOutputEntity, double[]> predictMatrixs = new HashMap<>();
+            Map<MmItemOutputEntity, Double> predictDoubleValues = new HashMap<>();
             for (MmItemOutputEntity output : itemOutputList) {
                 if (!modelResult.containsKey(output.getResultstr())) {
                     continue;
@@ -127,11 +131,16 @@
                         }
                         predictMatrixs.put(output, tempColumn);
                         break;
+                    case D:
+                        Double temp3 = (Double) modelResult.get(output.getResultstr());
+                        predictDoubleValues.put(output, temp3);
+                        break;
                     default:
                         break;
                 }
             }
             result.setPredictMatrixs(predictMatrixs);
+            result.setPredictDoubleValues(predictDoubleValues);
             result.setModelResult(modelResult);
             result.setPredictTime(predictTime);
         } catch (Exception ex) {
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/PredictSampleInfoConstructor.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/PredictSampleInfoConstructor.java
index 3a8e085..0be1977 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/PredictSampleInfoConstructor.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/PredictSampleInfoConstructor.java
@@ -1,9 +1,12 @@
 package com.iailab.module.model.mdk.sample;
 
+import com.iailab.module.data.api.point.DataPointApi;
+import com.iailab.module.data.api.point.dto.ApiPointDTO;
 import com.iailab.module.model.mcs.pre.entity.MmModelParamEntity;
 import com.iailab.module.model.mcs.pre.service.MmModelParamService;
 import com.iailab.module.model.mcs.pre.service.MmPredictItemService;
 import com.iailab.module.model.mcs.pre.service.MmPredictModelService;
+import com.iailab.module.model.mdk.common.enums.ModelParamType;
 import com.iailab.module.model.mdk.sample.dto.ColumnItem;
 import com.iailab.module.model.mdk.sample.dto.ColumnItemPort;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -13,6 +16,9 @@
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * @author PanZhibao
@@ -30,6 +36,9 @@
 
     @Autowired
     private MmPredictItemService mmPredictItemService;
+
+    @Autowired
+    private DataPointApi dataPointApi;
 
     /**
      * 返回样本矩阵的列数
@@ -63,14 +72,19 @@
         int curPortOrder = modelInputParamEntityList.get(0).getModelparamportorder();
         //设置当前查询数据长度,初始值为最小端口数据长度
         int curDataLength = modelInputParamEntityList.get(0).getDatalength();
+        // 统一获取测点的信息
+        List<String> pointIds = modelInputParamEntityList.stream().filter(e -> ModelParamType.getEumByCode(e.getModelparamtype()).equals(ModelParamType.DATAPOINT)).map(MmModelParamEntity::getModelparamid).collect(Collectors.toList());
+        List<ApiPointDTO> points = dataPointApi.getInfoByIds(pointIds);
+        Map<String, ApiPointDTO> pointMap = points.stream().collect(Collectors.toMap(ApiPointDTO::getId, Function.identity()));
+
         for (MmModelParamEntity entry : modelInputParamEntityList) {
             columnInfo.setParamType(entry.getModelparamtype());
             columnInfo.setParamId(entry.getModelparamid());
             columnInfo.setDataLength(entry.getDatalength());
             columnInfo.setModelParamOrder(entry.getModelparamorder());
             columnInfo.setModelParamPortOrder(entry.getModelparamportorder());
-            columnInfo.setStartTime(getStartTime(columnInfo, predictTime));
-            columnInfo.setEndTime(getEndTime(columnInfo, predictTime));
+            columnInfo.setStartTime(getStartTime(columnInfo, predictTime,pointMap));
+            columnInfo.setEndTime(getEndTime(columnInfo, predictTime,pointMap));
             columnInfo.setGranularity(super.getGranularity(columnInfo));
 
             //对每一个爪进行数据项归并
@@ -105,7 +119,7 @@
      */
     @Override
     protected Integer getSampleCycle(String modelId) {
-        return mmPredictItemService.getItemById(mmPredictModelService.getInfoFromCatch(modelId).getItemid()).getGranularity();
+        return mmPredictItemService.getItemByIdFromCache(mmPredictModelService.getInfoFromCatch(modelId).getItemid()).getGranularity();
     }
 
 
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/SampleInfoConstructor.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/SampleInfoConstructor.java
index 3d53588..515637b 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/SampleInfoConstructor.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/SampleInfoConstructor.java
@@ -19,6 +19,7 @@
 import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author PanZhibao
@@ -91,13 +92,13 @@
      * @return
      * @throws Exception
      */
-    protected Date getStartTime(ColumnItem columnItem, Date originalTime) {
+    protected Date getStartTime(ColumnItem columnItem, Date originalTime, Map<String, ApiPointDTO> pointMap) {
         Date dateTime = new Date();
         Calendar calendar = Calendar.getInstance();
         calendar.setTime(originalTime);
         switch (ModelParamType.getEumByCode(columnItem.getParamType())) {
             case DATAPOINT:
-                ApiPointDTO dataPoint = dataPointApi.getInfoById(columnItem.getParamId());
+                ApiPointDTO dataPoint = pointMap.get(columnItem.getParamId());
                 if (dataPoint == null) {
                     return null;
                 }
@@ -127,13 +128,13 @@
      * @return
      * @throws Exception
      */
-    protected Date getEndTime(ColumnItem columnItem, Date originalTime) {
+    protected Date getEndTime(ColumnItem columnItem, Date originalTime,Map<String, ApiPointDTO> pointMap) {
         Date dateTime = new Date();
         Calendar calendar = Calendar.getInstance();
         calendar.setTime(originalTime);
         switch (ModelParamType.getEumByCode(columnItem.getParamType())) {
             case DATAPOINT:
-                ApiPointDTO dataPoint = dataPointApi.getInfoById(columnItem.getParamId());
+                ApiPointDTO dataPoint = pointMap.get(columnItem.getParamId());
                 if (dataPoint == null) {
                     return null;
                 }
@@ -179,7 +180,7 @@
                 granularity = mmPredictItemService.getItemByOutPutId(columnItem.getParamId()).getGranularity();
                 break;
             case MERGEITEM:
-                granularity = mmPredictItemService.getItemById(columnItem.getParamId()).getGranularity();
+                granularity = mmPredictItemService.getItemByIdFromCache(columnItem.getParamId()).getGranularity();
                 break;
             case IND:
                 ApiIndItemDTO indItemDTO = indItemApi.getInfoById(columnItem.getParamId());
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/ScheduleSampleInfoConstructor.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/ScheduleSampleInfoConstructor.java
index 6b62536..f8547d6 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/ScheduleSampleInfoConstructor.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/sample/ScheduleSampleInfoConstructor.java
@@ -1,7 +1,11 @@
 package com.iailab.module.model.mdk.sample;
 
+import com.iailab.module.data.api.point.DataPointApi;
+import com.iailab.module.data.api.point.dto.ApiPointDTO;
+import com.iailab.module.model.mcs.pre.entity.MmModelParamEntity;
 import com.iailab.module.model.mcs.sche.entity.StScheduleModelParamEntity;
 import com.iailab.module.model.mcs.sche.service.StScheduleModelParamService;
+import com.iailab.module.model.mdk.common.enums.ModelParamType;
 import com.iailab.module.model.mdk.sample.dto.ColumnItem;
 import com.iailab.module.model.mdk.sample.dto.ColumnItemPort;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -11,12 +15,18 @@
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 @Component
 public class ScheduleSampleInfoConstructor extends SampleInfoConstructor {
 
     @Autowired
     private StScheduleModelParamService stScheduleModelParamService;
+
+    @Autowired
+    private DataPointApi dataPointApi;
 
     @Override
     protected Integer getSampleColumn(String modelId) {
@@ -37,14 +47,19 @@
         int curPortOrder = modelInputParamEntityList.get(0).getModelparamportorder();
         //设置当前查询数据长度,初始值为最小端口数据长度
         int curDataLength = modelInputParamEntityList.get(0).getDatalength();
+        // 统一获取测点的信息
+        List<String> pointIds = modelInputParamEntityList.stream().filter(e -> ModelParamType.getEumByCode(e.getModelparamtype()).equals(ModelParamType.DATAPOINT)).map(StScheduleModelParamEntity::getModelparamid).collect(Collectors.toList());
+        List<ApiPointDTO> points = dataPointApi.getInfoByIds(pointIds);
+        Map<String, ApiPointDTO> pointMap = points.stream().collect(Collectors.toMap(ApiPointDTO::getId, Function.identity()));
+
         for (StScheduleModelParamEntity entry : modelInputParamEntityList) {
             columnInfo.setParamType(entry.getModelparamtype());
             columnInfo.setParamId(entry.getModelparamid());
             columnInfo.setDataLength(entry.getDatalength());
             columnInfo.setModelParamOrder(entry.getModelparamorder());
             columnInfo.setModelParamPortOrder(entry.getModelparamportorder());
-            columnInfo.setStartTime(getStartTime(columnInfo, predictTime));
-            columnInfo.setEndTime(getEndTime(columnInfo, predictTime));
+            columnInfo.setStartTime(getStartTime(columnInfo, predictTime,pointMap));
+            columnInfo.setEndTime(getEndTime(columnInfo, predictTime,pointMap));
             columnInfo.setGranularity(super.getGranularity(columnInfo));
 
             //对每一个爪进行数据项归并
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/impl/ScheduleModelHandlerImpl.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/impl/ScheduleModelHandlerImpl.java
index 26a3f6c..0282148 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/impl/ScheduleModelHandlerImpl.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/schedule/impl/ScheduleModelHandlerImpl.java
@@ -1,5 +1,6 @@
 package com.iailab.module.model.mdk.schedule.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.iail.model.IAILModel;
@@ -61,7 +62,9 @@
         String modelId = scheduleModel.getId();
         try {
             //1.根据模型id构造模型输入样本
+            long now = System.currentTimeMillis();
             List<SampleData> sampleDataList = sampleConstructor.constructSample(TypeA.Schedule.name(), modelId, scheduleTime);
+            log.info("构造模型输入样本消耗时长:" + (System.currentTimeMillis() - now) / 1000 + "秒");
             if (CollectionUtils.isEmpty(sampleDataList)) {
                 log.info("调度模型构造样本失败,schemeCode=" + schemeCode);
                 return null;
@@ -86,12 +89,12 @@
             param2Values[portLength] = settings;
 
             log.info("#######################调度模型 " + scheduleModel.getModelName() + " ##########################");
-            JSONObject jsonObjNewModelBean = new JSONObject();
-            jsonObjNewModelBean.put("newModelBean", newModelBean);
-            log.info(String.valueOf(jsonObjNewModelBean));
-            JSONObject jsonObjParam2Values = new JSONObject();
-            jsonObjParam2Values.put("param2Values", param2Values);
-            log.info(String.valueOf(jsonObjParam2Values));
+//            JSONObject jsonObjNewModelBean = new JSONObject();
+//            jsonObjNewModelBean.put("newModelBean", newModelBean);
+//            log.info(String.valueOf(jsonObjNewModelBean));
+//            JSONObject jsonObjParam2Values = new JSONObject();
+//            jsonObjParam2Values.put("param2Values", param2Values);
+            log.info("参数: " + JSON.toJSONString(param2Values));
 
             //IAILMDK.run
             HashMap<String, Object> modelResult = DllUtils.run(newModelBean, param2Values, scheduleScheme.getMpkprojectid());
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/vo/PredictResultVO.java b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/vo/PredictResultVO.java
index be560fe..67dbf8d 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/vo/PredictResultVO.java
+++ b/iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mdk/vo/PredictResultVO.java
@@ -38,6 +38,11 @@
     private Map<MmItemOutputEntity, double[]> predictMatrixs;
 
     /**
+     * double类型的模型输出
+     */
+    private Map<MmItemOutputEntity, Double> predictDoubleValues;
+
+    /**
      * 时间间隔 (当前预测时间 与 上一次预测时间 相差的分钟数;系统计算得出)
      */
     private int t;
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/resources/application-dev_rec.yaml b/iailab-module-model/iailab-module-model-biz/src/main/resources/application-dev_rec.yaml
deleted file mode 100644
index dfd9856..0000000
--- a/iailab-module-model/iailab-module-model-biz/src/main/resources/application-dev_rec.yaml
+++ /dev/null
@@ -1,51 +0,0 @@
-spring:
-  # 数据源配置项
-  autoconfigure:
-    exclude:
-      - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
-  datasource:
-    druid: # Druid 【监控】相关的全局配置
-      web-stat-filter:
-        enabled: true
-      stat-view-servlet:
-        enabled: true
-        allow: # 设置白名单,不填则允许所有访问
-        url-pattern: /druid/*
-        login-username: # 控制台管理用户名和密码
-        login-password:
-      filter:
-        stat:
-          enabled: true
-          log-slow-sql: true # 慢 SQL 记录
-          slow-sql-millis: 100
-          merge-sql: true
-        wall:
-          config:
-            multi-statement-allow: true
-    dynamic: # 多数据源配置
-      druid: # Druid 【连接池】相关的全局配置
-        initial-size: 1 # 初始连接数
-        min-idle: 1 # 最小连接池数量
-        max-active: 20 # 最大连接池数量
-        max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
-        time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
-        min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
-        max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
-        validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
-        test-while-idle: true
-        test-on-borrow: false
-        test-on-return: false
-      primary: master
-      datasource:
-        master:
-          url: jdbc:mysql://127.0.0.1:3306/iailab_expert_master?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
-          username: root
-          password: 123456
-
-  # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
-  redis:
-    host: 172.16.8.100 # 地址
-    port: 6379 # 端口
-    database: 0 # 数据库索引
-    password: 123456 # 密码,建议生产环境开启
-
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/resources/application-test_bak.yml b/iailab-module-model/iailab-module-model-biz/src/main/resources/application-test_bak.yml
deleted file mode 100644
index 39218cb..0000000
--- a/iailab-module-model/iailab-module-model-biz/src/main/resources/application-test_bak.yml
+++ /dev/null
@@ -1,54 +0,0 @@
-spring:
-  autoconfigure:
-    exclude:
-      - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
-  datasource:
-    druid:
-      web-stat-filter:
-        enabled: true
-      stat-view-servlet:
-        enabled: true
-        allow:
-        url-pattern: /druid/*
-        login-username:
-        login-password:
-      filter:
-        stat:
-          enabled: true
-          log-slow-sql: true
-          slow-sql-millis: 100
-          merge-sql: true
-        wall:
-          config:
-            multi-statement-allow: true
-    dynamic:
-      druid:
-        initial-size: 1
-        min-idle: 1
-        max-active: 20
-        max-wait: 600000
-        time-between-eviction-runs-millis: 60000
-        min-evictable-idle-time-millis: 300000
-        max-evictable-idle-time-millis: 900000
-        validation-query: SELECT 1 FROM DUAL
-        test-while-idle: true
-        test-on-borrow: false
-        test-on-return: false
-      primary: master
-      datasource:
-        master:
-          #url: jdbc:mysql://127.0.0.1:3306/iailab_expert_tenant_zjgt?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
-          url: jdbc:mysql://172.16.8.100:3306/iailab_expert_master?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
-          username: root
-          password: 123456
-
-  redis:
-    host: 172.16.8.100
-    port: 6379
-    database: 0
-    password: 123456
-
-mpk:
-  bak-file-path: D:\DLUT\mpkBakFile
-  bak-resources: D:\DLUT\mpkResources
-  model-file-path: D:\DLUT\MDK\Model\miail\
\ No newline at end of file
diff --git a/iailab-module-model/iailab-module-model-biz/src/main/resources/logback-spring.xml b/iailab-module-model/iailab-module-model-biz/src/main/resources/logback-spring.xml
index 3ac202f..328482a 100644
--- a/iailab-module-model/iailab-module-model-biz/src/main/resources/logback-spring.xml
+++ b/iailab-module-model/iailab-module-model-biz/src/main/resources/logback-spring.xml
@@ -1,86 +1,76 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration scan="true">
-    <property name="LOG_TEMP" value="./logs"/>
+<configuration>
+    <!-- 引用 Spring Boot 的 logback 基础配置 -->
     <include resource="org/springframework/boot/logging/logback/defaults.xml" />
-    <!-- <include resource="org/springframework/boot/logging/logback/base.xml" /> -->
-    <logger name="org.springframework.web" level="INFO"/>
-    <logger name="org.springboot.sample" level="TRACE" />
+    <!-- 变量 iailab.info.base-package,基础业务包 -->
+    <springProperty scope="context" name="iailab.info.base-package" source="iailab.info.base-package"/>
+    <!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level:级别从左显示 5 个字符宽度,%msg:日志消息,%n是换行符 -->
+    <property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} | %highlight(${LOG_LEVEL_PATTERN:-%5p} ${PID:- }) | %boldYellow(%thread [%tid]) %boldGreen(%-40.40logger{39}) | %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
 
-    <!-- 开发、测试环境 -->
-    <springProfile name="dev,test,prod">
-        <logger name="org.springframework.web" level="INFO"/>
-        <logger name="org.springboot.sample" level="INFO" />
-        <logger name="com.iailab" level="DEBUG" />
+    <!-- 控制台 Appender -->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">     
+        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
+                <pattern>${PATTERN_DEFAULT}</pattern>
+            </layout>
+        </encoder>
+    </appender>
+
+    <!-- 文件 Appender -->
+    <!-- 参考 Spring Boot 的 file-appender.xml 编写 -->
+    <appender name="FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
+                <pattern>${PATTERN_DEFAULT}</pattern>
+            </layout>
+        </encoder>
+        <!-- 日志文件名 -->
+        <file>${LOG_FILE}</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- 滚动后的日志文件名 -->
+            <fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
+            <!-- 启动服务时,是否清理历史日志,一般不建议清理 -->
+            <cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
+            <!-- 日志文件,到达多少容量,进行滚动 -->
+            <maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
+            <!-- 日志文件的总大小,0 表示不限制 -->
+            <totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
+            <!-- 日志文件的保留天数 -->
+            <maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
+        </rollingPolicy>
+    </appender>
+    <!-- 异步写入日志,提升性能 -->
+    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
+        <!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
+        <discardingThreshold>0</discardingThreshold>
+        <!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
+        <queueSize>256</queueSize>
+        <appender-ref ref="FILE"/>
+    </appender>
+
+    <!-- SkyWalking GRPC 日志收集,实现日志中心。注意:SkyWalking 8.4.0 版本开始支持 -->
+    <appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
+        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
+                <pattern>${PATTERN_DEFAULT}</pattern>
+            </layout>
+        </encoder>
+    </appender>
+
+    <!-- 本地环境 -->
+    <springProfile name="local">
+        <root level="INFO">
+            <appender-ref ref="STDOUT"/>
+            <appender-ref ref="GRPC"/> <!-- 本地环境下,如果不想接入 SkyWalking 日志服务,可以注释掉本行 -->
+            <appender-ref ref="ASYNC"/>  <!-- 本地环境下,如果不想打印日志,可以注释掉本行 -->
+        </root>
+    </springProfile>
+    <!-- 其它环境 -->
+    <springProfile name="dev,test,stage,prod,default">
+        <root level="INFO">
+            <appender-ref ref="STDOUT"/>
+            <appender-ref ref="ASYNC"/>
+            <appender-ref ref="GRPC"/>
+        </root>
     </springProfile>
 
-    <!-- 生产环境 -->
-    <!--<springProfile name="prod">-->
-    <!--<logger name="org.springframework.web" level="ERROR"/>-->
-    <!--<logger name="org.springboot.sample" level="ERROR" />-->
-    <!--<logger name="io.renren" level="ERROR" />-->
-    <!--</springProfile>-->
-
-    <!-- 日志文件存放路径 -->
-    <property name="log_home" value="./logs" />
-    <!-- 日志输出格式 -->
-    <!--生产用-->
-    <property name="log.pattern" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] | [%thread][%-5level] | [%logger{20}.%method,line : %line] %msg%n" />
-    <!--本地测试使用-->
-    <!--<property name="log.pattern" value="[%boldGreen(%d{yyyy-MM-dd HH:mm:ss.SSS})] | [%highlight(%thread][%-5level)] | [%boldYellow(%logger{20}.%method,%line)] %msg%n" />-->
-    <!-- 日志输出格式【控制台】 -->
-    <!--<property name="log.pattern" value="%date{yyyy-MM-dd HH:mm:ss} | [ line: %line ] | %boldGreen(%thread) | %highlight(%-5level) | %boldYellow(%logger).%method | %msg%n"/>-->
-
-    <!-- 控制台输出 -->
-    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
-        <encoder>
-            <!--<pattern>${logPatternConsoleLog}</pattern>-->
-            <pattern>${log.pattern}</pattern>
-        </encoder>
-    </appender>
-
-    <logger name="m-shop-mybatis-sql" level="debug"></logger>
-
-    <!-- debug级别设置 -->
-    <appender name="file_debug"  class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <prudent>true</prudent>
-        <filter class="ch.qos.logback.classic.filter.LevelFilter">
-            <!--过滤 DEBUG-->
-            <level>DEBUG</level>
-            <!--匹配到就禁止-->
-            <!--<onMatch>ACCEPT</onMatch>-->
-            <!--没有匹配到就允许-->
-            <!--<onMismatch>DENY</onMismatch>-->
-        </filter>
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <!--<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">-->
-            <!--日志文件输出的文件名-->
-            <!--<FileNamePattern>${log_home}/log-info.%d{yyyy-MM-dd}.%i.log</FileNamePattern>-->
-            <FileNamePattern>${log_home}/log-debug.%d{yyyy-MM-dd}.log</FileNamePattern>
-            <!--<maxFileSize>100MB</maxFileSize>-->
-            <!-- 日志最大的历史 7天 -->
-            <maxHistory>7</maxHistory>
-            <totalSizeCap>2GB</totalSizeCap>
-            <cleanHistoryOnStart>true</cleanHistoryOnStart>
-        </rollingPolicy>
-        <!--<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">-->
-        <!--&lt;!&ndash; 单文件最大50MB &ndash;&gt;-->
-        <!--<maxFileSize>50MB</maxFileSize>-->
-        <!--</triggeringPolicy>-->
-        <encoder>
-            <pattern>${log.pattern}</pattern>
-        </encoder>
-    </appender>
-
-    <!-- 系统模块日志级别控制  -->
-    <!--<logger name="com.btrh" level="info" />-->
-
-    <!-- Spring日志级别控制  -->
-    <!--<logger name="org.springframework" level="info" />-->
-
-    <!--系统操作日志-->
-    <root level="INFO">
-        <appender-ref ref="console" />
-        <appender-ref ref="file_debug" />
-    </root>
-
-</configuration>
+</configuration>
\ No newline at end of file
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/user/AdminUserApiImpl.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/user/AdminUserApiImpl.java
index e951bd2..7eb1058 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/user/AdminUserApiImpl.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/api/user/AdminUserApiImpl.java
@@ -5,6 +5,7 @@
 import com.iailab.framework.common.pojo.CommonResult;
 import com.iailab.framework.common.util.object.BeanUtils;
 import com.iailab.framework.common.util.object.ConvertUtils;
+import com.iailab.framework.datapermission.core.annotation.DataPermission;
 import com.iailab.module.system.api.user.dto.AdminUserRespDTO;
 import com.iailab.module.system.controller.admin.user.vo.user.UserSaveReqVO;
 import com.iailab.module.system.dal.dataobject.dept.DeptDO;
@@ -34,6 +35,7 @@
     private PermissionService permissionService;
 
     @Override
+    @DataPermission(enable = false) // 关闭数据权限,避免只查看自己时,查询不到部门。
     public CommonResult<AdminUserRespDTO> getUser(Long id) {
         AdminUserDO user = userService.getUser(id);
         return success(BeanUtils.toBean(user, AdminUserRespDTO.class));
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/auth/AuthController.java b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/auth/AuthController.java
index 2de4f9c..d2a3342 100644
--- a/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/auth/AuthController.java
+++ b/iailab-module-system/iailab-module-system-biz/src/main/java/com/iailab/module/system/controller/admin/auth/AuthController.java
@@ -136,7 +136,7 @@
         Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId));
         List<MenuDO> menuList = menuService.getMenuList(menuIds);
         menuList = menuService.filterDisableMenus(menuList);
-//        menuList = menuService.filterMenus(menuList, "system");
+        menuList = menuService.filterMenus(menuList, "system");
 
         // 2. 拼接结果返回
         return success(AuthConvert.INSTANCE.convert(user, roles, menuList));
@@ -239,7 +239,7 @@
         }
         children.retainAll(menuList);
         List<MenuDO> tempChildren = new LinkedList<>();
-        //为每一个二级菜单增加一个隐藏父级目录
+        //为每一个二级菜单(非外链菜单)增加一个隐藏父级目录
         children.stream().forEach(menu -> {
             if (menu.getParentId().equals(menuDO.getId())) {
                 if(menu.getType().equals(MenuTypeEnum.MENU.getType())) {
@@ -254,7 +254,9 @@
                     tempChildren.add(parentMenu);
                 } else if(menu.getType().equals(MenuTypeEnum.DIR.getType())) {
                     // 为应用菜单二级目录前增加“/”
-                    menu.setPath("/" + menu.getPath());
+                    if(!menu.getPath().contains("http:") && !menu.getPath().contains("https:")) {
+                        menu.setPath("/" + menu.getPath());
+                    }
                 }
             }
             tempChildren.add(menu);
diff --git a/iailab-module-system/iailab-module-system-biz/src/main/resources/application-local.yaml b/iailab-module-system/iailab-module-system-biz/src/main/resources/application-local.yaml
deleted file mode 100644
index 2fe59e7..0000000
--- a/iailab-module-system/iailab-module-system-biz/src/main/resources/application-local.yaml
+++ /dev/null
@@ -1,205 +0,0 @@
---- #################### 注册中心 + 配置中心相关配置 ####################
-
-#spring:
-#  cloud:
-#    nacos:
-#      server-addr: @nacos.server@ # Nacos 服务器地址
-#      username: @nacos.username@
-#      password: @nacos.password@
-#      discovery: # 【配置中心】配置项
-#        namespace: @profiles.active@ # 命名空间。这里使用 dev 开发环境
-#        group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
-#        metadata:
-#          version: @nacos.metadata.version@ # 服务实例的版本号,可用于灰度发布
-#      config: # 【注册中心】配置项
-#        namespace: @profiles.active@ # 命名空间。这里使用 dev 开发环境
-#        group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
-
---- #################### 数据库相关配置 ####################
-spring:
-  # 数据源配置项
-  autoconfigure:
-    exclude:
-      - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
-      - de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration # 禁用 Spring Boot Admin 的 Client 的自动配置
-  datasource:
-    druid: # Druid 【监控】相关的全局配置
-      web-stat-filter:
-        enabled: true
-      stat-view-servlet:
-        enabled: true
-        allow: # 设置白名单,不填则允许所有访问
-        url-pattern: /druid/*
-        login-username: # 控制台管理用户名和密码
-        login-password:
-      filter:
-        stat:
-          enabled: true
-          log-slow-sql: true # 慢 SQL 记录
-          slow-sql-millis: 100
-          merge-sql: true
-        wall:
-          config:
-            multi-statement-allow: true
-    dynamic: # 多数据源配置
-      druid: # Druid 【连接池】相关的全局配置
-        initial-size: 1 # 初始连接数
-        min-idle: 1 # 最小连接池数量
-        max-active: 20 # 最大连接池数量
-        max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
-        time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
-        min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
-        max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
-        validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
-        test-while-idle: true
-        test-on-borrow: false
-        test-on-return: false
-      primary: master
-      datasource:
-        master:
-          url: jdbc:mysql://172.16.8.100:3306/iailab-plat?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
-          #          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai # MySQL Connector/J 5.X 连接的示例
-          #          url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例
-          #          url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
-          #          url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro # SQLServer 连接的示例
-          #          url: jdbc:dm://10.211.55.4:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
-          username: root
-          password: 123456
-        #          username: sa # SQL Server 连接的示例
-        #          password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W # SQL Server 连接的示例
-        #          username: SYSDBA # DM 连接的示例
-        #          password: SYSDBA # DM 连接的示例
-        slave: # 模拟从库,可根据自己需要修改
-          lazy: true # 开启懒加载,保证启动速度
-          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
-          username: root
-          password: 123456
-
-  # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
-  redis:
-    host: 127.0.0.1 # 地址
-    port: 6379 # 端口
-    database: 0 # 数据库索引
-    password: 123456 # 密码,建议生产环境开启
-
---- #################### MQ 消息队列相关配置 ####################
-
-# rocketmq 配置项,对应 RocketMQProperties 配置类
-rocketmq:
-  name-server: 127.0.0.1:9876 # RocketMQ Namesrv
-
-spring:
-  # RabbitMQ 配置项,对应 RabbitProperties 配置类
-  rabbitmq:
-    host: 127.0.0.1 # RabbitMQ 服务的地址
-    port: 5672 # RabbitMQ 服务的端口
-    username: guest # RabbitMQ 服务的账号
-    password: guest # RabbitMQ 服务的密码
-  # Kafka 配置项,对应 KafkaProperties 配置类
-  kafka:
-    bootstrap-servers: 172.16.8.100:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
-
---- #################### 定时任务相关配置 ####################
-
-xxl:
-  job:
-    enabled: true # 是否开启调度中心,默认为 true 开启
-    admin:
-      addresses: http://172.16.8.100:9090/xxl-job-admin # 调度中心部署跟地址
-
---- #################### 服务保障相关配置 ####################
-
-# Lock4j 配置项
-lock4j:
-  acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
-  expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
-
---- #################### 监控相关配置 ####################
-
-# Actuator 监控端点的配置项
-management:
-  endpoints:
-    web:
-      base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
-      exposure:
-        include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
-
-# Spring Boot Admin 配置项
-spring:
-  boot:
-    admin:
-      # Spring Boot Admin Client 客户端的相关配置
-      client:
-        instance:
-          service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
-
-# 日志文件配置
-logging:
-  level:
-    # 配置自己写的 MyBatis Mapper 打印日志
-    com.iailab.module.system.dal.mysql: debug
-    com.iailab.module.system.dal.mysql.sensitiveword.SensitiveWordMapper: INFO # 配置 SensitiveWordMapper 的日志级别为 info
-    com.iailab.module.system.dal.mysql.sms.SmsChannelMapper: INFO # 配置 SmsChannelMapper 的日志级别为 info
-    #org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿:先禁用,Spring Boot 3.X 存在部分错误的 WARN 提示
-
---- #################### 微信公众号、小程序相关配置 ####################
-wx:
-  mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
-    #    app-id: wx041349c6f39b268b
-    #    secret: 5abee519483bc9f8cb37ce280e814bd0
-    app-id: wx5b23ba7a5589ecbb # 测试号
-    secret: 2a7b3b20c537e52e74afd395eb85f61f
-    # 存储配置,解决 AccessToken 的跨节点的共享
-    config-storage:
-      type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
-      key-prefix: wx # Redis Key 的前缀
-      http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
-  miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
-    #    appid: wx62056c0d5e8db250
-    #    secret: 333ae72f41552af1e998fe1f54e1584a
-    appid: wx63c280fe3248a3e7 # wenhualian的接口测试号
-    secret: 6f270509224a7ae1296bbf1c8cb97aed
-    config-storage:
-      type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
-      key-prefix: wa # Redis Key 的前缀
-      http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
-
---- #################### 平台相关配置 ####################
-
-# 平台配置项,设置当前项目所有自定义的配置
-iailab:
-  env: # 多环境的配置项
-    tag: ${HOSTNAME}
-  captcha:
-    enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试
-  security:
-    mock-enable: true
-  access-log: # 访问日志的配置项
-    enable: false
-
-justauth:
-  enabled: true
-  type:
-    DINGTALK: # 钉钉
-      client-id: dingvrnreaje3yqvzhxg
-      client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI
-      ignore-check-redirect-uri: true
-    WECHAT_ENTERPRISE: # 企业微信
-      client-id: wwd411c69a39ad2e54
-      client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw
-      agent-id: 1000004
-      ignore-check-redirect-uri: true
-    # noinspection SpringBootApplicationYaml
-    WECHAT_MINI_APP: # 微信小程序
-      client-id: ${wx.miniapp.appid}
-      client-secret: ${wx.miniapp.secret}
-      ignore-check-redirect-uri: true
-      ignore-check-state: true # 微信小程序,不会使用到 state,所以不进行校验
-    WECHAT_MP: # 微信公众号
-      client-id: ${wx.mp.app-id}
-      client-secret: ${wx.mp.secret}
-      ignore-check-redirect-uri: true
-  cache:
-    type: REDIS
-    prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
-    timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟

--
Gitblit v1.9.3