b488bf4b5ed42686d6df50207dbff37bd735359b..f5ec1f3326f75e18222859a534ed5a249f5e2cc3
2025-06-04 dongyukun
Merge remote-tracking branch 'origin/master'
f5ec1f 对比 | 目录
2025-06-04 dongyukun
问题模版配置
38cfd3 对比 | 目录
2025-06-04 dengzedong
Merge remote-tracking branch 'origin/master'
f590dc 对比 | 目录
2025-06-04 dengzedong
建议快照 getChartData 调度时间
2cc456 对比 | 目录
2025-06-04 Jay
Merge remote-tracking branch 'origin/master'
21d0aa 对比 | 目录
2025-06-04 Jay
增加取消采纳建议接口
05116c 对比 | 目录
2025-06-04 dongyukun
问题模版配置
822a20 对比 | 目录
2025-06-04 dengzedong
建议快照 getChartData bug
7652e1 对比 | 目录
2025-06-04 dongyukun
问题模版配置
df7558 对比 | 目录
2025-06-04 dongyukun
问题模版配置
b42a37 对比 | 目录
2025-06-04 dengzedong
建议快照逻辑调整
f9e4ec 对比 | 目录
2025-06-04 dengzedong
Merge remote-tracking branch 'origin/master'
ac80ce 对比 | 目录
2025-06-04 dengzedong
建议快照逻辑调整
e7b38b 对比 | 目录
2025-06-04 dongyukun
问题模版配置
9974f7 对比 | 目录
2025-06-04 dongyukun
问题模版配置
c1a3de 对比 | 目录
2025-06-04 dongyukun
Merge remote-tracking branch 'origin/master'
9495db 对比 | 目录
2025-06-04 dongyukun
问题模版配置
8dcfba 对比 | 目录
2025-06-04 dongyukun
问题模版配置
a5c11d 对比 | 目录
2025-06-04 潘志宝
测试再次计算
d29376 对比 | 目录
2025-06-03 潘志宝
Merge remote-tracking branch 'origin/master'
0f0155 对比 | 目录
2025-06-03 潘志宝
计算点
3d1530 对比 | 目录
2025-06-03 潘志宝
计算点前缀C
d293b3 对比 | 目录
2025-06-03 dongyukun
问题模版配置
8003c1 对比 | 目录
2025-06-03 dongyukun
问题模版配置
1a67d3 对比 | 目录
2025-06-03 dongyukun
Merge remote-tracking branch 'origin/master'
88c781 对比 | 目录
2025-06-03 dongyukun
问题模版配置
a705d6 对比 | 目录
2025-06-03 潘志宝
Merge remote-tracking branch 'origin/master'
e83cc1 对比 | 目录
2025-06-03 潘志宝
计算点递归查询
5bffdf 对比 | 目录
2025-06-03 潘志宝
handPending
d247a0 对比 | 目录
已修改25个文件
已添加6个文件
已重命名1个文件
1157 ■■■■ 文件已修改
iailab-module-ai/iailab-module-ai-api/pom.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/questionTemplate/QuestiontemplateApi.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/questionTemplate/dto/AiModelDto.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/questionTemplate/dto/QuestionParamSettingDO.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/questionTemplate/dto/QuestionTemplateDto.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-biz/db/增量sql/2025.sql 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/QuestionTemplateApiImpl.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/controller/admin/questiontemplate/QuestionTemplateController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/controller/admin/questiontemplate/vo/QuestionTemplateRespVO.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/controller/admin/questiontemplate/vo/QuestionTemplateSaveReqVO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/dal/dataobject/questionparamsetting/QuestionParamSettingDO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/dal/dataobject/questiontemplate/QuestionTemplateDO.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/dal/mysql/questionparamsetting/QuestionParamSettingMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/service/questiontemplate/QuestionTemplateService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/service/questiontemplate/QuestionTemplateServiceImpl.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-biz/src/main/resources/application.yaml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/point/collection/handler/CalculateHandle.java 114 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/McsApi.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/StSuggestSnapshotRecordRespVO.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/db/增量SQL/2025.sql 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/McsApiImpl.java 146 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/controller/admin/McsApiController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/MmItemResultService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmItemResultServiceImpl.java 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/controller/admin/StSuggestSnapshotRecordController.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/entity/StSuggestSnapshotRecordEntity.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/StScheduleSuggestService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/StSuggestSnapshotRecordService.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/impl/StScheduleSuggestServiceImpl.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/impl/StSuggestOperationRecordServiceImpl.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/impl/StSuggestSnapshotRecordServiceImpl.java 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/vo/StSuggestSnapshotConfMainRespVO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-ai/iailab-module-ai-api/pom.xml
@@ -40,5 +40,15 @@
            <artifactId>spring-boot-starter-validation</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-openfeign-core</artifactId>
        </dependency>
        <dependency>
            <groupId>io.swagger.core.v3</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>2.2.25</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>
iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/questionTemplate/QuestiontemplateApi.java
对比新文件
@@ -0,0 +1,27 @@
package com.iailab.module.ai.api.questionTemplate;
import com.iailab.framework.common.enums.RpcConstants;
import com.iailab.module.ai.api.questionTemplate.dto.AiModelDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
/**
 * @author DongYukun
 * @Description
 * @createTime 2025年06月04日
 */
@FeignClient(name = "ai-server")
@Tag(name = "问题模板")
public interface QuestiontemplateApi {
    String PREFIX = RpcConstants.RPC_API_PREFIX +  "/ai/questiontemplate";
    @PostMapping(PREFIX + "/modelList")
    @Operation(summary = "Ai大模型级联问题模版")
    List<AiModelDto> queryModelList();
}
iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/questionTemplate/dto/AiModelDto.java
对比新文件
@@ -0,0 +1,46 @@
package com.iailab.module.ai.api.questionTemplate.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class AiModelDto implements Serializable {
    @Schema(description = "编号", example = "2630")
    private Long id;
    @Schema(description = "API 秘钥编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22042")
    private Long keyId;
    @Schema(description = "模型名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
    private String name;
    @Schema(description = "模型标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "gpt-3.5-turbo-0125")
    private String model;
    @Schema(description = "模型平台", requiredMode = Schema.RequiredMode.REQUIRED, example = "OpenAI")
    private String platform;
    @Schema(description = "模型类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    private Integer type;
    @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    private Integer sort;
    @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
    private Integer status;
    @Schema(description = "温度参数", example = "1")
    private Double temperature;
    @Schema(description = "单条回复的最大 Token 数量", example = "4096")
    private Integer maxTokens;
    @Schema(description = "上下文的最大 Message 数量", example = "8192")
    private Integer maxContexts;
    private List<QuestionTemplateDto> children;
}
iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/questionTemplate/dto/QuestionParamSettingDO.java
对比新文件
@@ -0,0 +1,35 @@
package com.iailab.module.ai.api.questionTemplate.dto;
import lombok.*;
import java.io.Serializable;
@Data
public class QuestionParamSettingDO implements Serializable {
    /**
     * id
     */
    private String id;
    /**
     * 问题模板id
     */
    private String templateId;
    /**
     * key
     */
    private String settingKey;
    /**
     * 参数名称
     */
    private String settingName;
    /**
     * 参数默认值
     */
    private String settingValue;
    /**
     * 排序
     */
    private Integer sort;
}
iailab-module-ai/iailab-module-ai-api/src/main/java/com/iailab/module/ai/api/questionTemplate/dto/QuestionTemplateDto.java
对比新文件
@@ -0,0 +1,52 @@
package com.iailab.module.ai.api.questionTemplate.dto;
import lombok.*;
import java.io.Serializable;
import java.util.List;
/**
 * 大模型问题模板 DO
 *
 * @author 超级管理员
 */
@Data
public class QuestionTemplateDto implements Serializable {
    /**
     * id
     */
    private String id;
    /**
     * 模型id
     */
    private String modelId;
    /**
     * 问题编号
     */
    private String questionCode;
    /**
     * 问题名称
     */
    private String questionName;
    /**
     * 问题内容
     */
    private String questionContent;
    /**
     * 输入个数
     */
    private Integer dataLength;
    /**
     * 是否启用(0禁用 1启用)
     */
    private Integer isEnable;
    /**
     * 备注
     */
    private String remark;
    private List<QuestionParamSettingDO> settingList;
    public String modelName;
}
iailab-module-ai/iailab-module-ai-biz/db/增量sql/2025.sql
对比新文件
@@ -0,0 +1,9 @@
ALTER TABLE ai_question_template
    ADD COLUMN deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除';
ALTER TABLE ai_question_param_setting
    ADD COLUMN deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除';
ALTER TABLE ai_question_param_setting
    ADD COLUMN `creator` varchar(64) DEFAULT NULL COMMENT '创建者',
    ADD COLUMN `create_time` datetime DEFAULT NULL COMMENT '创建时间',
    ADD COLUMN `updater` varchar(64) DEFAULT NULL COMMENT '更新者',
    ADD COLUMN `update_time` datetime DEFAULT NULL COMMENT '更新时间';
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/api/QuestionTemplateApiImpl.java
对比新文件
@@ -0,0 +1,40 @@
package com.iailab.module.ai.api;
import com.iailab.framework.common.util.object.BeanUtils;
import com.iailab.module.ai.api.questionTemplate.QuestiontemplateApi;
import com.iailab.module.ai.api.questionTemplate.dto.AiModelDto;
import com.iailab.module.ai.api.questionTemplate.dto.QuestionTemplateDto;
import com.iailab.module.ai.controller.admin.questiontemplate.vo.QuestionTemplateRespVO;
import com.iailab.module.ai.service.model.AiModelService;
import com.iailab.module.ai.service.questiontemplate.QuestionTemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
 * @description:
 * @author: dongyukun
 * @date: 2025/6/4 14:50
 **/
@RestController // 提供 RESTful API 接口,给 Feign 调用
@Validated
public class QuestionTemplateApiImpl implements QuestiontemplateApi {
    @Autowired
    private QuestionTemplateService questionTemplateService;
    @Autowired
    private AiModelService aiModelService;
    @Override
    public List<AiModelDto> queryModelList() {
        List<AiModelDto> list = BeanUtils.toBean(aiModelService.getModelListByStatusAndType(0, 1, null), AiModelDto.class);
        list.forEach(item->{
            item.setChildren(
                    BeanUtils.toBean(questionTemplateService.getQuestionTemplateList(item.getId()), QuestionTemplateDto.class));
        });
        return list;
    }
}
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/controller/admin/questiontemplate/QuestionTemplateController.java
@@ -1,5 +1,6 @@
package com.iailab.module.ai.controller.admin.questiontemplate;
import com.iailab.module.ai.service.model.AiModelService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
@@ -13,6 +14,7 @@
import com.iailab.framework.common.pojo.PageResult;
import com.iailab.framework.common.pojo.CommonResult;
import com.iailab.framework.common.util.object.BeanUtils;
import static com.iailab.framework.common.pojo.CommonResult.success;
@@ -28,6 +30,9 @@
    @Resource
    private QuestionTemplateService questionTemplateService;
    @Resource
    private AiModelService aiModelService;
    @PostMapping("/create")
    @Operation(summary = "创建大模型问题模板")
@@ -59,6 +64,7 @@
    @PreAuthorize("@ss.hasPermission('ai:question-template:query')")
    public CommonResult<QuestionTemplateRespVO> getQuestionTemplate(@RequestParam("id") String id) {
        QuestionTemplateDO questionTemplate = questionTemplateService.getQuestionTemplate(id);
        questionTemplate.setModelName( aiModelService.getModel(Long.valueOf((questionTemplate.getModelId()))).getName());
        return success(BeanUtils.toBean(questionTemplate, QuestionTemplateRespVO.class));
    }
@@ -67,6 +73,11 @@
    @PreAuthorize("@ss.hasPermission('ai:question-template:query')")
    public CommonResult<PageResult<QuestionTemplateRespVO>> getQuestionTemplatePage(@Valid QuestionTemplatePageReqVO pageReqVO) {
        PageResult<QuestionTemplateDO> pageResult = questionTemplateService.getQuestionTemplatePage(pageReqVO);
        pageResult.getList().forEach(questionTemplateDO ->
                questionTemplateDO.setModelName(
                        aiModelService.getModel(Long.valueOf((questionTemplateDO.getModelId()))).getName()
                )
        );
        return success(BeanUtils.toBean(pageResult, QuestionTemplateRespVO.class));
    }
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/controller/admin/questiontemplate/vo/QuestionTemplateRespVO.java
@@ -1,8 +1,11 @@
package com.iailab.module.ai.controller.admin.questiontemplate.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.iailab.module.ai.controller.admin.questionparamsetting.vo.QuestionParamSettingRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 大模型问题模板 Response VO")
@Data
@@ -13,6 +16,9 @@
    @Schema(description = "模型id", requiredMode = Schema.RequiredMode.REQUIRED, example = "11609")
    private String modelId;
    @Schema(description = "模型名称")
    public String modelName;
    @Schema(description = "问题编号", requiredMode = Schema.RequiredMode.REQUIRED)
    private String questionCode;
@@ -35,4 +41,5 @@
    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
    private LocalDateTime createTime;
    private List<QuestionParamSettingRespVO> settingList;
}
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/controller/admin/questiontemplate/vo/QuestionTemplateSaveReqVO.java
@@ -1,9 +1,11 @@
package com.iailab.module.ai.controller.admin.questiontemplate.vo;
import com.iailab.module.ai.controller.admin.questionparamsetting.vo.QuestionParamSettingSaveReqVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import javax.validation.constraints.*;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 大模型问题模板新增/修改 Request VO")
@Data
@@ -35,4 +37,6 @@
    @Schema(description = "备注", example = "随便")
    private String remark;
    @Schema(description = "问题模版列表")
    private List<QuestionParamSettingSaveReqVO> settingList;
}
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/dal/dataobject/questionparamsetting/QuestionParamSettingDO.java
@@ -23,7 +23,7 @@
    /**
     * id
     */
    @TableId(type = IdType.INPUT)
    @TableId(type = IdType.ASSIGN_ID)
    private String id;
    /**
     * 问题模板id
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/dal/dataobject/questiontemplate/QuestionTemplateDO.java
@@ -1,8 +1,13 @@
package com.iailab.module.ai.dal.dataobject.questiontemplate;
import com.iailab.module.ai.controller.admin.questionparamsetting.vo.QuestionParamSettingRespVO;
import com.iailab.module.ai.controller.admin.questiontemplate.vo.QuestionTemplateSaveReqVO;
import com.iailab.module.ai.dal.dataobject.model.AiModelDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
import java.util.List;
import com.baomidou.mybatisplus.annotation.*;
import com.iailab.framework.mybatis.core.dataobject.BaseDO;
@@ -56,4 +61,9 @@
     */
    private String remark;
    @TableField(exist = false)
    private List<QuestionParamSettingRespVO> settingList;
    @TableField(exist = false)
    public String modelName;
}
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/dal/mysql/questionparamsetting/QuestionParamSettingMapper.java
@@ -1,5 +1,7 @@
package com.iailab.module.ai.dal.mysql.questionparamsetting;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.iailab.framework.common.pojo.PageResult;
import com.iailab.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.iailab.framework.mybatis.core.mapper.BaseMapperX;
@@ -25,4 +27,7 @@
                .orderByDesc(QuestionParamSettingDO::getId));
    }
    default int deleteByTemplateId(String templateId) {
        return delete("template_id",templateId);
    }
}
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/service/questiontemplate/QuestionTemplateService.java
@@ -4,6 +4,9 @@
import com.iailab.module.ai.controller.admin.questiontemplate.vo.*;
import com.iailab.module.ai.dal.dataobject.questiontemplate.QuestionTemplateDO;
import com.iailab.framework.common.pojo.PageResult;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 大模型问题模板 Service 接口
@@ -50,4 +53,12 @@
     */
    PageResult<QuestionTemplateDO> getQuestionTemplatePage(QuestionTemplatePageReqVO pageReqVO);
    /**
     * 根据模型id获得大模型问题模板列表
     *
     * @param modelId 模型id
     * @return 大模型问题模板列表
     */
    List<QuestionTemplateDO> getQuestionTemplateList(@Param("modelId") Long modelId );
}
iailab-module-ai/iailab-module-ai-biz/src/main/java/com/iailab/module/ai/service/questiontemplate/QuestionTemplateServiceImpl.java
@@ -1,5 +1,8 @@
package com.iailab.module.ai.service.questiontemplate;
import com.iailab.module.ai.controller.admin.questionparamsetting.vo.QuestionParamSettingRespVO;
import com.iailab.module.ai.dal.dataobject.questionparamsetting.QuestionParamSettingDO;
import com.iailab.module.ai.dal.mysql.questionparamsetting.QuestionParamSettingMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -10,6 +13,9 @@
import com.iailab.framework.common.util.object.BeanUtils;
import com.iailab.module.ai.dal.mysql.questiontemplate.QuestionTemplateMapper;
import java.util.List;
import java.util.UUID;
import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.iailab.module.ai.enums.ErrorCodeConstants.*;
@@ -26,10 +32,20 @@
    @Resource
    private QuestionTemplateMapper questionTemplateMapper;
    @Resource
    private QuestionParamSettingMapper questionParamSettingMapper;
    @Override
    public String createQuestionTemplate(QuestionTemplateSaveReqVO createReqVO) {
        // 插入
        QuestionTemplateDO questionTemplate = BeanUtils.toBean(createReqVO, QuestionTemplateDO.class);
        String id = UUID.randomUUID().toString();
        questionTemplate.setId(id);
        // 插入设置列表
        createReqVO.getSettingList().forEach(setting -> {
            setting.setTemplateId(id);
            questionParamSettingMapper.insert(BeanUtils.toBean(setting, QuestionParamSettingDO.class));
        });
        questionTemplateMapper.insert(questionTemplate);
        // 返回
        return questionTemplate.getId();
@@ -41,6 +57,14 @@
        validateQuestionTemplateExists(updateReqVO.getId());
        // 更新
        QuestionTemplateDO updateObj = BeanUtils.toBean(updateReqVO, QuestionTemplateDO.class);
        // 删除设置列表
        questionParamSettingMapper.deleteByTemplateId(updateReqVO.getId());
        // 更新设置列表
        updateReqVO.getSettingList().forEach(setting -> {
            setting.setTemplateId(updateReqVO.getId());
            setting.setId(null);
            questionParamSettingMapper.insert(BeanUtils.toBean(setting, QuestionParamSettingDO.class));
        });
        questionTemplateMapper.updateById(updateObj);
    }
@@ -50,6 +74,8 @@
        validateQuestionTemplateExists(id);
        // 删除
        questionTemplateMapper.deleteById(id);
        // 删除设置列表
        questionParamSettingMapper.deleteByTemplateId(id);
    }
    private void validateQuestionTemplateExists(String id) {
@@ -60,7 +86,9 @@
    @Override
    public QuestionTemplateDO getQuestionTemplate(String id) {
        return questionTemplateMapper.selectById(id);
        QuestionTemplateDO questionTemplateDO = questionTemplateMapper.selectById(id);
        questionTemplateDO.setSettingList(BeanUtils.toBean(questionParamSettingMapper.selectList("template_id",id), QuestionParamSettingRespVO.class));
        return questionTemplateDO;
    }
    @Override
@@ -68,4 +96,13 @@
        return questionTemplateMapper.selectPage(pageReqVO);
    }
    @Override
    public List<QuestionTemplateDO> getQuestionTemplateList(Long modelId) {
        List<QuestionTemplateDO> questionTemplateDOList = questionTemplateMapper.selectList("model_id",modelId);
        questionTemplateDOList.forEach(DO -> {
            DO.setSettingList(BeanUtils.toBean(questionParamSettingMapper.selectList("template_id",DO.getId()), QuestionParamSettingRespVO.class));
        });
        return questionTemplateDOList;
    }
}
iailab-module-ai/iailab-module-ai-biz/src/main/resources/application.yaml
@@ -220,5 +220,7 @@
    ignore-tables:
      - ai_api_key
      - ai_model
      - ai_question_template
      - ai_question_param_setting
debug: true
iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/point/collection/handler/CalculateHandle.java
@@ -1,6 +1,7 @@
package com.iailab.module.data.point.collection.handler;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iailab.framework.common.util.string.StrUtils;
import com.iailab.module.data.common.enums.CommonConstant;
import com.iailab.module.data.common.enums.DataTypeEnum;
@@ -16,6 +17,7 @@
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource;
import javax.validation.constraints.Max;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
@@ -24,6 +26,7 @@
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
/**
@@ -58,7 +61,13 @@
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    public static final String regex = "[+\\-\\*/()\\&\\|\\>\\<]";
    public final static String regex = "[+\\-\\*/()\\&\\|\\>\\<]";
    private final static String POINT_PREFIX = "C";
    private final static String PENDING_FLAG = "pending";
    private final static int MAX_RECURSION = 10;
    public List<InfluxPointValuePOJO> handle(Date collectTime, List<DaPointDTO> dtos, Map<String, Object> dataMap, List<String> listGood, List<String> listBad) {
        List<InfluxPointValuePOJO> result = new ArrayList<>();
@@ -67,33 +76,83 @@
            if (CollectionUtils.isEmpty(dtos)) {
                return result;
            }
            Map<String, DaPointDTO> pendingMap = new HashMap<>();
            log.info(JSON.toJSONString(listBad));
            dtos.forEach(dto -> {
                try {
                    Object rawValue = singleCompute(dto, dataMap, listGood, listBad);
                    BigDecimal coefficient = dto.getUnittransfactor() == null ? BigDecimal.ONE : dto.getUnittransfactor();
                    BigDecimal calValue = new BigDecimal(rawValue.toString()).multiply(coefficient);
                    if (dto.getMaxValue() != null && calValue.compareTo(dto.getMaxValue()) > 0) {
                        calValue = dto.getMaxValue();
                    } else if (dto.getMinValue() != null && calValue.compareTo(dto.getMinValue()) < 0) {
                        calValue = dto.getMinValue();
                    if (PENDING_FLAG.equals(rawValue.toString())) {
                        pendingMap.put(dto.getPointNo(), dto);
                    } else {
                        BigDecimal coefficient = dto.getUnittransfactor() == null ? BigDecimal.ONE : dto.getUnittransfactor();
                        BigDecimal calValue = new BigDecimal(rawValue.toString()).multiply(coefficient);
                        if (dto.getMaxValue() != null && calValue.compareTo(dto.getMaxValue()) > 0) {
                            calValue = dto.getMaxValue();
                        } else if (dto.getMinValue() != null && calValue.compareTo(dto.getMinValue()) < 0) {
                            calValue = dto.getMinValue();
                        }
                        dataMap.put(dto.getPointNo(), calValue);
                        InfluxPointValuePOJO pojo = GenInfluxPointValueUtils.getByPoint(dto, calValue);
                        pojo.setTimestamp(GenInfluxPointValueUtils.getByMin(collectTime, DataPointFreqEnum.getEumByCode(dto.getMinfreqid())));
                        result.add(pojo);
                    }
                    InfluxPointValuePOJO pojo = GenInfluxPointValueUtils.getByPoint(dto, calValue);
                    pojo.setTimestamp(GenInfluxPointValueUtils.getByMin(collectTime, DataPointFreqEnum.getEumByCode(dto.getMinfreqid())));
                    result.add(pojo);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    log.info("计算点异常!PointNo=" + dto.getPointNo());
                }
            });
            log.info("计算点处理结束");
            Map<DaPointDTO, Object> valueResult = new HashMap<>();
            handPending(pendingMap, dataMap, listGood, listBad, valueResult, 1);
            log.info("valueResult size=" + valueResult.size());
            valueResult.forEach((key, value) -> {
                InfluxPointValuePOJO pojo = GenInfluxPointValueUtils.getByPoint(key, value);
                pojo.setTimestamp(GenInfluxPointValueUtils.getByMin(collectTime, DataPointFreqEnum.getEumByCode(key.getMinfreqid())));
                result.add(pojo);
            });
            log.info("计算点处理结束");
        } catch (Exception ex) {
            ex.printStackTrace();
            log.info("计算点处理异常!");
        }
        return result;
    }
    private void handPending(Map<String, DaPointDTO> pendingMap, Map<String, Object> dataMap,
                                            List<String> listGood, List<String> listBad, Map<DaPointDTO, Object> valueResult, int count) {
        Map<String, DaPointDTO> tempMap = new HashMap<>();
        if (CollectionUtils.isEmpty(pendingMap)) {
            log.info("pendingMap is empty");
            return;
        }
        log.info("处理包含计算点的");
        log.info("handPending count=" + count);
        if (count > MAX_RECURSION) {
            log.info("最多递归10次");
            return;
        }
        count = count + 1;
        for(String key : pendingMap.keySet()) {
            DaPointDTO dto = pendingMap.get(key);
            Object rawValue = singleCompute(dto, dataMap, listGood, listBad);
            if (PENDING_FLAG.equals(rawValue.toString())) {
                tempMap.put(key, dto);
            } else {
                BigDecimal coefficient = dto.getUnittransfactor() == null ? BigDecimal.ONE : dto.getUnittransfactor();
                BigDecimal calValue = new BigDecimal(rawValue.toString()).multiply(coefficient);
                if (dto.getMaxValue() != null && calValue.compareTo(dto.getMaxValue()) > 0) {
                    calValue = dto.getMaxValue();
                } else if (dto.getMinValue() != null && calValue.compareTo(dto.getMinValue()) < 0) {
                    calValue = dto.getMinValue();
                }
                dataMap.put(dto.getPointNo(), calValue);
                valueResult.put(dto, calValue);
            }
        }
        if (!CollectionUtils.isEmpty(tempMap)) {
            this.handPending(tempMap, dataMap, listGood, listBad, valueResult, count);
        }
    }
    private Object singleCompute(DaPointDTO dto, Map<String, Object> dataMap, List<String> listGood, List<String> listBad) {
@@ -103,17 +162,25 @@
        // 去掉arr中的空格
        arr = Stream.of(arr).filter(StringUtils::isNotBlank).toArray(String[]::new);
        // 判断arr都在dataMap中包含
        if (!Arrays.stream(arr).allMatch(dataMap::containsKey)) {
        /*if (!Arrays.stream(arr).allMatch(dataMap::containsKey)) {
            log.info("dataMap not contains key");
            listBad.add(dto.getPointNo());
            return CommonConstant.BAD_VALUE;
        }
        }*/
        for (int i = 0; i < arr.length; i++) {
            String s = arr[i];
            if (StringUtils.isNotBlank(s) && dataMap.containsKey(s)) {
                // 对每个数加(),否则负值报错
                expression = expression.replace(s, "(" + dataMap.get(s).toString() + ")");
            } else if(StringUtils.isNotBlank(s) && s.trim().startsWith(POINT_PREFIX)) {
                log.info("包含计算点,先挂起");
                log.info("dataMap=" + JSONObject.toJSONString(dataMap));
                return PENDING_FLAG;
            }  else if(StringUtils.isNotBlank(s) && !dataMap.containsKey(s)) {
                log.info("dataMap not contains key " + s);
                listBad.add(dto.getPointNo());
                return CommonConstant.BAD_VALUE;
            }
        }
        expression = expression.replace("&", "&&");
@@ -121,6 +188,7 @@
        expression = expression.replace("False", "false");
        expression = expression.replace("True", "true");
        log.info("PointNo=" + dto.getPointNo() + ";expression=" + expression);
        String result = javaScriptHandler.eval(expression);
        log.info("result=" + result);
        if (result == null || result.contains(JsErrorCode.Infinity.name()) || result.contains(JsErrorCode.NaN.name())) {
@@ -154,7 +222,7 @@
            if (redisTemplate.hasKey(PointCollector.PV + item.getPointNo())) {
                value = redisTemplate.opsForValue().get(PointCollector.PV + item.getPointNo());
            } else {
                Object rawValue = singleCompute(item);
                Object rawValue = singleCompute(item, 1);
                BigDecimal coefficient = item.getUnittransfactor() == null ? BigDecimal.ONE : item.getUnittransfactor();
                value = new BigDecimal(rawValue.toString()).multiply(coefficient);
            }
@@ -163,7 +231,7 @@
        return data;
    }
    private Object singleCompute(DaPointDTO dto) {
    private Object singleCompute(DaPointDTO dto, int count) {
        String result = CommonConstant.BAD_VALUE.toString();
        Map<String, Object> dataMap = new HashMap<>();
        String expression = dto.getExpression();
@@ -179,6 +247,20 @@
            dataMap.putAll(constantHandle.getCurrent(pointNos));
            dataMap.putAll(cumulateHandle.getCurrent(pointNos));
            dataMap.putAll(extremalHandle.getCurrent(pointNos));
            if (s.trim().startsWith(POINT_PREFIX)) {
                log.info("计算点递归查询");
                List<DaPointDTO> pointMathList = daPointService.getMathPoint(pointNos);
                if (CollectionUtils.isEmpty(pointMathList)) {
                    return result;
                }
                log.info("count = " + count);
                if (count > MAX_RECURSION) {
                    return result;
                }
                Object v = this.singleCompute(pointMathList.get(0), count);
                dataMap.put(s, v);
                count = count + 1;
            }
            if (dataMap.get(s) == null) {
                log.info("计算点数据异常");
                log.info("pointNo=" + dto.getPointNo() + ";dataMap.key=" + s);
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/McsApi.java
@@ -156,6 +156,10 @@
    @Operation(summary = "采纳建议")
    Boolean useSuggest(@RequestBody StAlarmAndSuggestReqVO reqVO);
    @PostMapping(PREFIX + "/schedule-suggest/cancel-use-suggest")
    @Operation(summary = "取消采纳建议")
    Boolean cancelUseSuggest(@RequestBody StAlarmAndSuggestReqVO reqVO);
    @PostMapping(PREFIX + "/schedule-suggest/ignore-suggest")
    @Operation(summary = "忽略建议")
    Boolean ignoreSuggest(StAlarmAndSuggestReqVO reqVO);
@@ -176,4 +180,8 @@
    @Operation(summary = "保存建议操作记录")
    Boolean saveSuggestOperationRecord(@RequestBody SuggestOperationRecordReqVO reqVO);
    @GetMapping(PREFIX + "/suggest/snapshot/getAllChartData")
    @Operation(summary = "根据建议id获取建议快照全部图表数据")
    List<StSuggestSnapshotRecordRespVO> getSuggestSnapshotAllChartData(@RequestParam("suggestId") String suggestId);
}
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/StSuggestSnapshotRecordRespVO.java
文件名从 iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/vo/StSuggestSnapshotRecordRespVO.java 修改
@@ -1,4 +1,4 @@
package com.iailab.module.model.mcs.sche.vo;
package com.iailab.module.model.api.mcs.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -36,6 +36,10 @@
    @Schema(description = "数据名称")
    private String dataName;
    @Schema(description = "调度时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date scheduleTime;
    @Schema(description = "开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date startTime;
iailab-module-model/iailab-module-model-biz/db/增量SQL/2025.sql
@@ -53,6 +53,7 @@
    `ext4`         varchar(50) COMMENT '拓展字段1',
    `ext5`         varchar(50) COMMENT '拓展字段1',
    PRIMARY KEY (`id`) USING BTREE,
    UNIQUE KEY `conf_id_data_name_unique` (`conf_id`,`data_name`),
    KEY            `idx_conf_id` (`conf_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='调度建议快照配置详情表';
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/McsApiImpl.java
@@ -95,6 +95,9 @@
    private StScheduleSuggestService stScheduleSuggestService;
    @Autowired
    private StSuggestSnapshotRecordService stSuggestSnapshotRecordService;
    @Autowired
    private PlanItemApi planItemApi;
    @Autowired
@@ -129,8 +132,6 @@
    @Autowired
    private StSuggestOperationRecordService stSuggestOperationRecordService;
    private int HOUR_MINS = 60;
    @Override
    public List<PredictItemTreeDTO> getPredictItemTree() {
@@ -173,131 +174,7 @@
    @Override
    public PreDataBarLineRespVO getPreDataCharts(PreDataBarLineReqVO reqVO) {
        PreDataBarLineRespVO result = new PreDataBarLineRespVO();
        List<String> outIds = reqVO.getOutIds();
        List<String> legends = new ArrayList<>();
        List<PreDataViewRespDTO> dataViewList = new ArrayList<>();
        if (CollectionUtils.isEmpty(outIds)) {
            return result;
        }
        Date predictTime = reqVO.getPredictTime();
        if (predictTime == null) {
            MmItemOutputEntity output = null;
            for (String outId : outIds) {
                output = mmItemOutputService.getOutPutById(outId);
                if (output != null) {
                    break;
                }
            }
            ItemVO predictItem = mmPredictItemService.getItemById(output.getItemid());
            if (predictItem.getLastTime() != null) {
                predictTime = predictItem.getLastTime();
            } else {
                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.MILLISECOND, 0);
                calendar.set(Calendar.SECOND, 0);
                predictTime = calendar.getTime();
            }
        }
        Date startTime = reqVO.getStartTime();
        if (startTime == null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(predictTime);
            calendar.add(Calendar.HOUR_OF_DAY, -1);
            startTime = calendar.getTime();
        }
        Date endTime = reqVO.getEndTime();
        if (endTime == null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(predictTime);
            calendar.add(Calendar.HOUR_OF_DAY, 1);
            calendar.add(Calendar.MINUTE, 1);
            endTime = calendar.getTime();
        }
        for (int i = 0; i < outIds.size(); i++) {
            PreDataViewRespDTO viewDto = new PreDataViewRespDTO();
            String outId = outIds.get(i);
            MmItemOutputEntity output = mmItemOutputService.getOutPutById(outId);
            if (output == null) {
                continue;
            }
            legends.add(output.getResultName());
            viewDto.setItemId(output.getItemid());
            viewDto.setOutId(outId);
            viewDto.setResultstr(output.getResultstr());
            viewDto.setResultName(output.getResultName());
            viewDto.setRealData(getHisData(output.getPointid(), startTime, endTime, reqVO.getPrec()));
            viewDto.setPreDataN(mmItemResultService.getData(output.getId(), startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
            viewDto.setPreDataL(mmItemResultLastPointService.getData(output.getId(), startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
            viewDto.setPreDataLOriginal(mmItemResultLastPointService.getData(output.getId(), startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, DataTypeEnum.FLOAT_LAST_BAK));
            viewDto.setCurData(mmItemResultJsonService.getData(output.getId(), predictTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
            // 模拟调整曲线
            viewDto.setAdjData(stAdjustResultService.getData(output.getId(), predictTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
            List<Double> values = new ArrayList<>();
            if (!CollectionUtils.isEmpty(viewDto.getRealData())) {
                List<Double> hisValues = new ArrayList<>();
                viewDto.getRealData().forEach(item -> {
                    values.add(Double.parseDouble(item[1].toString()));
                    hisValues.add(Double.parseDouble(item[1].toString()));
                });
                viewDto.setHisMax(new BigDecimal(hisValues.stream().mapToDouble(Double::doubleValue).max().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
                viewDto.setHisMin(new BigDecimal(hisValues.stream().mapToDouble(Double::doubleValue).min().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
                viewDto.setHisAvg(new BigDecimal(hisValues.stream().mapToDouble(Double::doubleValue).average().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
                viewDto.setHisCumulant(new BigDecimal(hisValues.stream().mapToDouble(Double::doubleValue).sum())
                        .divide(new BigDecimal(HOUR_MINS), 2, BigDecimal.ROUND_HALF_UP));
            }
            if (!CollectionUtils.isEmpty(viewDto.getPreDataN())) {
                viewDto.getPreDataN().forEach(item -> {
                    values.add(Double.parseDouble(item[1].toString()));
                });
            }
            if (!CollectionUtils.isEmpty(viewDto.getPreDataL())) {
                List<Double> preValues = new ArrayList<>();
                viewDto.getPreDataL().forEach(item -> {
                    values.add(Double.parseDouble(item[1].toString()));
                    preValues.add(Double.parseDouble(item[1].toString()));
                });
                viewDto.setPreMax(new BigDecimal(preValues.stream().mapToDouble(Double::doubleValue).max().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
                viewDto.setPreMin(new BigDecimal(preValues.stream().mapToDouble(Double::doubleValue).min().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
                viewDto.setPreAvg(new BigDecimal(preValues.stream().mapToDouble(Double::doubleValue).average().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
            }
            if (!CollectionUtils.isEmpty(viewDto.getCurData())) {
                List<Double> preValues = new ArrayList<>();
                viewDto.getCurData().forEach(item -> {
                    values.add(Double.parseDouble(item[1].toString()));
                    preValues.add(Double.parseDouble(item[1].toString()));
                });
                viewDto.setPreCumulant(new BigDecimal(preValues.stream().mapToDouble(Double::doubleValue).sum())
                        .divide(new BigDecimal(HOUR_MINS), 2, BigDecimal.ROUND_HALF_UP));
            }
            if (!CollectionUtils.isEmpty(viewDto.getAdjData())) {
                viewDto.getAdjData().forEach(item -> {
                    values.add(Double.parseDouble(item[1].toString()));
                });
            }
            if (!CollectionUtils.isEmpty(values)) {
                viewDto.setMaxValue(new BigDecimal(values.stream().mapToDouble(Double::doubleValue).max().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
                viewDto.setMinValue(new BigDecimal(values.stream().mapToDouble(Double::doubleValue).min().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
            }
            //处理预测累计
            if (output.getIscumulant() == 1) {
                if (StringUtils.isNotBlank(output.getCumulpoint())) {
                    viewDto.setCumulantRealData(getHisData(output.getCumulpoint(), startTime, endTime, reqVO.getPrec()));
                }
                viewDto.setCumulantPreData(mmItemResultService.getData(output.getId() + CommonDict.CUMULANT_SUFFIX, startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
            }
            dataViewList.add(viewDto);
        }
        result.setStartTime(startTime);
        result.setEndTime(endTime);
        result.setPredictTime(predictTime);
        result.setCategories(DateUtils.getTimeScale(startTime, endTime, 60));
        result.setLegend(legends);
        result.setDataViewList(dataViewList);
        return result;
        return mmItemResultService.getPreDataCharts(reqVO);
    }
    @Override
@@ -725,7 +602,11 @@
    @Override
    public Boolean createScheduleSuggest(ScheduleSuggestRespDTO dto) {
        String suggestId = UUID.randomUUID().toString();
        dto.setId(suggestId);
        stScheduleSuggestService.create(ConvertUtils.sourceToTarget(dto, StScheduleSuggestSaveReqVO.class));
        // 根据建议产生快照
        stSuggestSnapshotRecordService.createSnapshotRecord(dto.getModelId(),dto.getScheduleObj(),dto.getScheduleTime(),suggestId);
        return true;
    }
@@ -993,6 +874,11 @@
    }
    @Override
    public Boolean cancelUseSuggest(StAlarmAndSuggestReqVO reqVO) {
        return stScheduleSuggestService.cancelUseSuggest(reqVO);
    }
    @Override
    public Boolean ignoreSuggest(StAlarmAndSuggestReqVO reqVO) {
        return stScheduleSuggestService.ignoreSuggest(reqVO);
    }
@@ -1037,6 +923,12 @@
        stSuggestOperationRecordService.create(operationRecordVo);
        return true;
    }
    @Override
    public List<StSuggestSnapshotRecordRespVO> getSuggestSnapshotAllChartData(String suggestId) {
        return stSuggestSnapshotRecordService.getAllChartData(suggestId);
    }
    private Date[] calResultTime(ItemVO predictItem, Date startTimeReq, Date endTimeReq, int lengthLeft, int lengthRight) {
        Date[] result = new Date[3];
        Date predictTime = predictItem.getLastTime();
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/controller/admin/McsApiController.java
@@ -340,6 +340,13 @@
        return success( true);
    }
    @PostMapping("/schedule-suggest/cancel-use-suggest")
    @Operation(summary = "取消采纳建议")
    public CommonResult<Boolean> cancelUseSuggest(@RequestBody StAlarmAndSuggestReqVO reqVO){
        mcsApi.cancelUseSuggest(reqVO);
        return success( true);
    }
    @PostMapping(value = "/schedule-suggest/operation_record/save",  consumes = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "保存建议操作记录")
    public CommonResult<Boolean> saveSuggestOperationRecord(@RequestBody SuggestOperationRecordReqVO reqVO){
@@ -353,4 +360,10 @@
        mcsApi.ignoreSuggest(reqVO);
        return success( true);
    }
    @GetMapping("/suggest/snapshot/getAllChartData")
    @Operation(summary = "根据建议id获取建议快照全部图表数据")
    public CommonResult<List<StSuggestSnapshotRecordRespVO>> getSuggestSnapshotAllChartData(@RequestParam("suggestId") String suggestId){
        return success( mcsApi.getSuggestSnapshotAllChartData(suggestId));
    }
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/MmItemResultService.java
@@ -1,5 +1,7 @@
package com.iailab.module.model.mcs.pre.service;
import com.iailab.module.model.api.mcs.dto.PreDataBarLineReqVO;
import com.iailab.module.model.api.mcs.dto.PreDataBarLineRespVO;
import com.iailab.module.model.mdk.vo.DataValueVO;
import java.util.Date;
@@ -21,4 +23,6 @@
    List<Object[]> getData(String outputid, Date startTime, Date endTime, String timeFormat);
    List<Object[]> getData(String outputid, Date startTime, Date endTime, String timeFormat, int decimalPlaces);
    PreDataBarLineRespVO getPreDataCharts(PreDataBarLineReqVO reqVO);
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/pre/service/impl/MmItemResultServiceImpl.java
@@ -2,6 +2,14 @@
import com.alibaba.fastjson.JSONArray;
import com.iailab.framework.common.util.date.DateUtils;
import com.iailab.module.data.api.point.DataPointApi;
import com.iailab.module.data.api.point.dto.ApiPointDTO;
import com.iailab.module.data.api.point.dto.ApiPointValueDTO;
import com.iailab.module.data.api.point.dto.ApiPointValueQueryDTO;
import com.iailab.module.model.api.mcs.dto.PreDataBarLineReqVO;
import com.iailab.module.model.api.mcs.dto.PreDataBarLineRespVO;
import com.iailab.module.model.api.mcs.dto.PreDataViewRespDTO;
import com.iailab.module.model.common.enums.CommonDict;
import com.iailab.module.model.common.enums.DataTypeEnum;
import com.iailab.module.model.influxdb.pojo.InfluxModelResultLastBakSimPOJO;
import com.iailab.module.model.influxdb.pojo.InfluxModelResultLastSimPOJO;
@@ -9,10 +17,13 @@
import com.iailab.module.model.influxdb.pojo.InfluxModelResultSimPOJO;
import com.iailab.module.model.influxdb.service.InfluxDBService;
import com.iailab.module.model.influxdb.vo.InfluxModelResultVO;
import com.iailab.module.model.mcs.pre.entity.MmItemOutputEntity;
import com.iailab.module.model.mcs.pre.entity.MmItemResultJsonEntity;
import com.iailab.module.model.mcs.pre.service.MmItemResultJsonService;
import com.iailab.module.model.mcs.pre.service.MmItemResultService;
import com.iailab.module.model.mcs.pre.service.*;
import com.iailab.module.model.mcs.sche.service.StAdjustResultService;
import com.iailab.module.model.mdk.vo.DataValueVO;
import com.iailab.module.model.mdk.vo.ItemVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -32,6 +43,19 @@
    private MmItemResultJsonService mmItemResultJsonService;
    @Autowired
    private InfluxDBService influxDBService;
    @Autowired
    private MmItemOutputService mmItemOutputService;
    @Autowired
    private MmPredictItemService mmPredictItemService;
    @Autowired
    private DataPointApi dataPointApi;
    @Autowired
    private MmItemResultService mmItemResultService;
    @Autowired
    private StAdjustResultService stAdjustResultService;
    @Autowired
    private MmItemResultLastPointService mmItemResultLastPointService;
    private int HOUR_MINS = 60;
    @Override
    public void savePredictValue(Map<String, List<DataValueVO>> predictValueMap, int t, String nIndex, Date predictTime) {
@@ -163,4 +187,163 @@
        });
        return result;
    }
    @Override
    public PreDataBarLineRespVO getPreDataCharts(PreDataBarLineReqVO reqVO) {
        PreDataBarLineRespVO result = new PreDataBarLineRespVO();
        List<String> outIds = reqVO.getOutIds();
        List<String> legends = new ArrayList<>();
        List<PreDataViewRespDTO> dataViewList = new ArrayList<>();
        if (CollectionUtils.isEmpty(outIds)) {
            return result;
        }
        Date predictTime = reqVO.getPredictTime();
        if (predictTime == null) {
            MmItemOutputEntity output = null;
            for (String outId : outIds) {
                output = mmItemOutputService.getOutPutById(outId);
                if (output != null) {
                    break;
                }
            }
            ItemVO predictItem = mmPredictItemService.getItemById(output.getItemid());
            if (predictItem.getLastTime() != null) {
                predictTime = predictItem.getLastTime();
            } else {
                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.MILLISECOND, 0);
                calendar.set(Calendar.SECOND, 0);
                predictTime = calendar.getTime();
            }
        }
        Date startTime = reqVO.getStartTime();
        if (startTime == null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(predictTime);
            calendar.add(Calendar.HOUR_OF_DAY, -1);
            startTime = calendar.getTime();
        }
        Date endTime = reqVO.getEndTime();
        if (endTime == null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(predictTime);
            calendar.add(Calendar.HOUR_OF_DAY, 1);
            calendar.add(Calendar.MINUTE, 1);
            endTime = calendar.getTime();
        }
        for (int i = 0; i < outIds.size(); i++) {
            PreDataViewRespDTO viewDto = new PreDataViewRespDTO();
            String outId = outIds.get(i);
            MmItemOutputEntity output = mmItemOutputService.getOutPutById(outId);
            if (output == null) {
                continue;
            }
            legends.add(output.getResultName());
            viewDto.setItemId(output.getItemid());
            viewDto.setOutId(outId);
            viewDto.setResultstr(output.getResultstr());
            viewDto.setResultName(output.getResultName());
            viewDto.setRealData(getHisData(output.getPointid(), startTime, endTime, reqVO.getPrec()));
            viewDto.setPreDataN(mmItemResultService.getData(output.getId(), startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
            viewDto.setPreDataL(mmItemResultLastPointService.getData(output.getId(), startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
            viewDto.setPreDataLOriginal(mmItemResultLastPointService.getData(output.getId(), startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, DataTypeEnum.FLOAT_LAST_BAK));
            viewDto.setCurData(mmItemResultJsonService.getData(output.getId(), predictTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
            // 模拟调整曲线
            viewDto.setAdjData(stAdjustResultService.getData(output.getId(), predictTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
            List<Double> values = new ArrayList<>();
            if (!CollectionUtils.isEmpty(viewDto.getRealData())) {
                List<Double> hisValues = new ArrayList<>();
                viewDto.getRealData().forEach(item -> {
                    values.add(Double.parseDouble(item[1].toString()));
                    hisValues.add(Double.parseDouble(item[1].toString()));
                });
                viewDto.setHisMax(new BigDecimal(hisValues.stream().mapToDouble(Double::doubleValue).max().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
                viewDto.setHisMin(new BigDecimal(hisValues.stream().mapToDouble(Double::doubleValue).min().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
                viewDto.setHisAvg(new BigDecimal(hisValues.stream().mapToDouble(Double::doubleValue).average().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
                viewDto.setHisCumulant(new BigDecimal(hisValues.stream().mapToDouble(Double::doubleValue).sum())
                        .divide(new BigDecimal(HOUR_MINS), 2, BigDecimal.ROUND_HALF_UP));
            }
            if (!CollectionUtils.isEmpty(viewDto.getPreDataN())) {
                viewDto.getPreDataN().forEach(item -> {
                    values.add(Double.parseDouble(item[1].toString()));
                });
            }
            if (!CollectionUtils.isEmpty(viewDto.getPreDataL())) {
                List<Double> preValues = new ArrayList<>();
                viewDto.getPreDataL().forEach(item -> {
                    values.add(Double.parseDouble(item[1].toString()));
                    preValues.add(Double.parseDouble(item[1].toString()));
                });
                viewDto.setPreMax(new BigDecimal(preValues.stream().mapToDouble(Double::doubleValue).max().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
                viewDto.setPreMin(new BigDecimal(preValues.stream().mapToDouble(Double::doubleValue).min().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
                viewDto.setPreAvg(new BigDecimal(preValues.stream().mapToDouble(Double::doubleValue).average().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
            }
            if (!CollectionUtils.isEmpty(viewDto.getCurData())) {
                List<Double> preValues = new ArrayList<>();
                viewDto.getCurData().forEach(item -> {
                    values.add(Double.parseDouble(item[1].toString()));
                    preValues.add(Double.parseDouble(item[1].toString()));
                });
                viewDto.setPreCumulant(new BigDecimal(preValues.stream().mapToDouble(Double::doubleValue).sum())
                        .divide(new BigDecimal(HOUR_MINS), 2, BigDecimal.ROUND_HALF_UP));
            }
            if (!CollectionUtils.isEmpty(viewDto.getAdjData())) {
                viewDto.getAdjData().forEach(item -> {
                    values.add(Double.parseDouble(item[1].toString()));
                });
            }
            if (!CollectionUtils.isEmpty(values)) {
                viewDto.setMaxValue(new BigDecimal(values.stream().mapToDouble(Double::doubleValue).max().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
                viewDto.setMinValue(new BigDecimal(values.stream().mapToDouble(Double::doubleValue).min().getAsDouble()).setScale(2, BigDecimal.ROUND_HALF_UP));
            }
            //处理预测累计
            if (output.getIscumulant() == 1) {
                if (StringUtils.isNotBlank(output.getCumulpoint())) {
                    viewDto.setCumulantRealData(getHisData(output.getCumulpoint(), startTime, endTime, reqVO.getPrec()));
                }
                viewDto.setCumulantPreData(mmItemResultService.getData(output.getId() + CommonDict.CUMULANT_SUFFIX, startTime, endTime, DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
            }
            dataViewList.add(viewDto);
        }
        result.setStartTime(startTime);
        result.setEndTime(endTime);
        result.setPredictTime(predictTime);
        result.setCategories(DateUtils.getTimeScale(startTime, endTime, 60));
        result.setLegend(legends);
        result.setDataViewList(dataViewList);
        return result;
    }
    private List<Object[]> getHisData(String pointId, Date startTime, Date endTime, Integer prec) {
        List<Object[]> result = new ArrayList<>();
        if (StringUtils.isBlank(pointId)) {
            return result;
        }
        ApiPointDTO pointDTO = dataPointApi.getInfoById(pointId);
        ApiPointValueQueryDTO queryPointDto = new ApiPointValueQueryDTO();
        queryPointDto.setPointNo(pointDTO.getPointNo());
        queryPointDto.setStart(startTime);
        queryPointDto.setEnd(endTime);
        List<ApiPointValueDTO> valueDTOS = dataPointApi.queryPointHistoryValue(queryPointDto);
        if (CollectionUtils.isEmpty(valueDTOS)) {
            return result;
        }
        int defaultPrec = 3;
        valueDTOS.forEach(item -> {
            Object[] values = new Object[2];
            values[0] = DateUtils.format(item.getT(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
            if (prec != null && prec < 0) {
                values[1] = item.getV();
            } else if (prec != null && prec > 0) {
                values[1] = new BigDecimal(item.getV()).setScale(prec, BigDecimal.ROUND_HALF_UP);
            } else {
                values[1] = new BigDecimal(item.getV()).setScale(defaultPrec, BigDecimal.ROUND_HALF_UP);
            }
            result.add(values);
        });
        return result;
    }
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/controller/admin/StSuggestSnapshotRecordController.java
@@ -1,35 +1,16 @@
package com.iailab.module.model.mcs.sche.controller.admin;
import com.iailab.framework.common.pojo.CommonResult;
import com.iailab.module.data.api.ind.IndItemApi;
import com.iailab.module.data.api.ind.dto.ApiIndItemQueryDTO;
import com.iailab.module.data.api.ind.dto.ApiIndItemValueDTO;
import com.iailab.module.data.api.plan.PlanItemApi;
import com.iailab.module.data.api.point.DataPointApi;
import com.iailab.module.data.api.point.dto.ApiPointValueDTO;
import com.iailab.module.data.api.point.dto.ApiPointValueQueryDTO;
import com.iailab.module.data.common.ApiDataQueryDTO;
import com.iailab.module.data.common.ApiDataValueDTO;
import com.iailab.module.model.api.mcs.McsApi;
import com.iailab.module.model.api.mcs.dto.PreDataBarLineReqVO;
import com.iailab.module.model.api.mcs.dto.PreDataBarLineRespVO;
import com.iailab.module.model.common.enums.DataCategoryEnum;
import com.iailab.module.model.common.utils.DateUtils;
import com.iailab.module.model.mcs.sche.service.StSuggestSnapshotRecordService;
import com.iailab.module.model.mcs.sche.vo.StSuggestSnapshotRecordRespVO;
import com.mysql.cj.util.TimeUtil;
import com.iailab.module.model.api.mcs.dto.StSuggestSnapshotRecordRespVO;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static com.iailab.framework.common.pojo.CommonResult.success;
import static com.iailab.module.model.common.utils.DateUtils.DATE_TIME_PATTERN;
/**
 * @author Jay
@@ -42,102 +23,19 @@
    @Autowired
    private StSuggestSnapshotRecordService stSuggestSnapshotRecordService;
    @Autowired
    private DataPointApi dataPointApi;
    @Autowired
    private IndItemApi indItemApi;
    @Autowired
    private PlanItemApi planItemApi;
    @Autowired
    private McsApi mcsApi;
    @GetMapping("/list")
    @Parameter(name = "operationId", description = "操作id", required = true, example = "1024")
    public CommonResult<List<StSuggestSnapshotRecordRespVO>> getListByOperationId(@RequestParam("operationId") String operationId) {
        return success(stSuggestSnapshotRecordService.getListByOperationId(operationId));
    public CommonResult<List<StSuggestSnapshotRecordRespVO>> getListByOperationId(@RequestParam("suggestId") String suggestId) {
        return success(stSuggestSnapshotRecordService.getListBySuggestId(suggestId));
    }
    @PostMapping("/getChartData")
    public CommonResult<List<StSuggestSnapshotRecordRespVO>> getChartData(@RequestBody List<StSuggestSnapshotRecordRespVO> reqList){
        reqList.forEach(item -> {
            List<Object[]> dataList = new ArrayList<>();
            if(DataCategoryEnum.DATAPOINT.getCode().equals(item.getDataType())){
                ApiPointValueQueryDTO queryDTO = new ApiPointValueQueryDTO();
                queryDTO.setPointNo(item.getDataNo());
                queryDTO.setStart(item.getStartTime());
                queryDTO.setEnd(item.getEndTime());
                List<ApiPointValueDTO> valueList = dataPointApi.queryPointHistoryValue(queryDTO);
                if (valueList != null && !valueList.isEmpty()){
                    for (ApiPointValueDTO apiPointValueDTO : valueList) {
                        Object[] data = new Object[2];
                        data[0] = DateUtils.format(new Date(String.valueOf(apiPointValueDTO.getT())), DATE_TIME_PATTERN);
                        data[1] = apiPointValueDTO.getV();
                        dataList.add(data);
                    }
                }
            } else if (DataCategoryEnum.IND.getCode().equals(item.getDataType())) {
                ApiIndItemQueryDTO queryDTO = new ApiIndItemQueryDTO();
                queryDTO.setItemNo(item.getDataNo());
                queryDTO.setStart(item.getStartTime());
                queryDTO.setEnd(item.getEndTime());
                List<ApiIndItemValueDTO> valueList = indItemApi.queryIndItemHistoryValue(queryDTO);
                if (valueList != null && !valueList.isEmpty()){
                    for (ApiIndItemValueDTO apiIndItemValueDTO : valueList) {
                        Object[] data = new Object[2];
                        data[0] = DateUtils.format(new Date(apiIndItemValueDTO.getDataTime()), DATE_TIME_PATTERN);
                        data[1] = apiIndItemValueDTO.getDataValue();
                        dataList.add(data);
                    }
                }
            } else if (DataCategoryEnum.PLAN.getCode().equals(item.getDataType())) {
                ApiDataQueryDTO queryDTO = new ApiDataQueryDTO();
                queryDTO.setItemNo(item.getDataNo());
                queryDTO.setStart(item.getStartTime());
                queryDTO.setEnd(item.getEndTime());
                List<ApiDataValueDTO> valueList = planItemApi.queryPlanItemHistoryValue(queryDTO);
                if (valueList != null && !valueList.isEmpty()){
                    for (ApiDataValueDTO apiDataValueDTO : valueList) {
                        Object[] data = new Object[2];
                        data[0] = DateUtils.format(apiDataValueDTO.getDataTime(), DATE_TIME_PATTERN);
                        data[1] = apiDataValueDTO.getDataValue();
                        dataList.add(data);
                    }
                }
            } else if (DataCategoryEnum.PREDICT_ITEM_N.getCode().equals(item.getDataType())) {
                dataList = getPreDataList(item, "N");
            }else if (DataCategoryEnum.PREDICT_ITEM_L.getCode().equals(item.getDataType())) {
                dataList = getPreDataList(item, "L");
            }else if (DataCategoryEnum.PREDICT_ITEM_C.getCode().equals(item.getDataType())) {
                dataList = getPreDataList(item, "C");
            }
            item.setDataList(dataList);
        });
        return success(reqList);
        return success(stSuggestSnapshotRecordService.getChartData(reqList));
    }
    private List<Object[]> getPreDataList(StSuggestSnapshotRecordRespVO resVo, String type){
        List<Object[]> dataList = new ArrayList<>();
        PreDataBarLineReqVO reqVO  = new PreDataBarLineReqVO();
        List<String> outIds = new ArrayList<>();
        outIds.add(resVo.getDataNo());
        reqVO.setOutIds(outIds);
        reqVO.setStartTime(resVo.getStartTime());
        reqVO.setEndTime(resVo.getEndTime());
        PreDataBarLineRespVO result = mcsApi.getPreDataCharts(reqVO);
        if (result == null || result.getDataViewList() == null || result.getDataViewList().isEmpty()){
            return dataList;
        }
        if ("N".equals(type) && result.getDataViewList().get(0).getPreDataN()!=null){
            dataList = result.getDataViewList().get(0).getPreDataN();
        }else if ("L".equals(type) && result.getDataViewList().get(0).getPreDataL()!=null){
            dataList = result.getDataViewList().get(0).getPreDataL();
        }else if ("C".equals(type) && result.getDataViewList().get(0).getCurData()!=null){
            dataList = result.getDataViewList().get(0).getCurData();
        }
        return dataList;
    @GetMapping("/getAllChartData")
    public CommonResult<List<StSuggestSnapshotRecordRespVO>> getAllChartData(@RequestParam("suggestId") String suggestId){
        return success(stSuggestSnapshotRecordService.getAllChartData(suggestId));
    }
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/entity/StSuggestSnapshotRecordEntity.java
@@ -54,7 +54,7 @@
    private String dataName;
    /**
     * 开始时间
     * 调度时间
     */
    private Date scheduleTime;
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/StScheduleSuggestService.java
@@ -5,7 +5,6 @@
import com.iailab.module.model.api.mcs.dto.ScheduleSuggestReqDTO;
import com.iailab.module.model.api.mcs.dto.ScheduleSuggestRespDTO;
import com.iailab.module.model.api.mcs.dto.StAlarmAndSuggestReqVO;
import com.iailab.module.model.api.mcs.dto.StAlarmAndSuggestRespVO;
import com.iailab.module.model.mcs.sche.entity.StScheduleSuggestEntity;
import com.iailab.module.model.mcs.sche.vo.StScheduleSuggestPageReqVO;
import com.iailab.module.model.mcs.sche.vo.StScheduleSuggestSaveReqVO;
@@ -41,6 +40,8 @@
    Boolean useSuggest(StAlarmAndSuggestReqVO reqVO);
    Boolean cancelUseSuggest(StAlarmAndSuggestReqVO reqVO);
    Boolean ignoreSuggest(StAlarmAndSuggestReqVO reqVO);
    List<ScheduleSuggestRespDTO> getLastSuggest(Map<String, Object> params);
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/StSuggestSnapshotRecordService.java
@@ -2,9 +2,10 @@
import com.iailab.framework.common.service.BaseService;
import com.iailab.module.model.mcs.sche.entity.StSuggestSnapshotRecordEntity;
import com.iailab.module.model.mcs.sche.vo.StSuggestSnapshotRecordRespVO;
import com.iailab.module.model.api.mcs.dto.StSuggestSnapshotRecordRespVO;
import com.iailab.module.model.mcs.sche.vo.StSuggestSnapshotRecordSaveReqVO;
import java.util.Date;
import java.util.List;
/**
@@ -18,5 +19,11 @@
    void delete(String id);
    List<StSuggestSnapshotRecordRespVO> getListByOperationId(String operationId);
    List<StSuggestSnapshotRecordRespVO> getListBySuggestId(String suggestId);
    void createSnapshotRecord(String modelId, String scheduleObj, Date scheduleTime, String suggestId);
    List<StSuggestSnapshotRecordRespVO> getChartData(List<StSuggestSnapshotRecordRespVO> reqList);
    List<StSuggestSnapshotRecordRespVO> getAllChartData(String suggestId);
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/impl/StScheduleSuggestServiceImpl.java
@@ -18,7 +18,10 @@
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * @author PanZhibao
@@ -37,7 +40,6 @@
    @Override
    public void create(StScheduleSuggestSaveReqVO createReqVO) {
        StScheduleSuggestEntity entity = BeanUtils.toBean(createReqVO, StScheduleSuggestEntity.class);
        entity.setId(UUID.randomUUID().toString());
        entity.setStatus(ScheduleSuggestStatusEnum.S0.getCode());
        baseDao.insert(entity);
    }
@@ -104,6 +106,16 @@
    }
    @Override
    public Boolean cancelUseSuggest(StAlarmAndSuggestReqVO reqVO) {
        StScheduleSuggestEntity entity = new StScheduleSuggestEntity();
        entity.setId(reqVO.getId());
        entity.setStatus(ScheduleSuggestStatusEnum.S0.getCode());
        entity.setHandleTime(new Date());
        baseDao.updateById(entity);
        return true;
    }
    @Override
    public Boolean ignoreSuggest(StAlarmAndSuggestReqVO reqVO) {
        StScheduleSuggestEntity entity = new StScheduleSuggestEntity();
        entity.setId(reqVO.getId());
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/impl/StSuggestOperationRecordServiceImpl.java
@@ -28,15 +28,6 @@
public class StSuggestOperationRecordServiceImpl extends BaseServiceImpl<StSuggestOperationRecordDao, StSuggestOperationRecordEntity>
        implements StSuggestOperationRecordService {
    @Autowired
    private StSuggestSnapshotConfMainService stSuggestSnapshotConfMainService;
    @Autowired
    private StSuggestSnapshotConfDetService stSuggestSnapshotConfDetService;
    @Autowired
    private StSuggestSnapshotRecordService stSuggestSnapshotRecordService;
    @Override
    public PageResult<StSuggestOperationRecordEntity> page(StSuggestOperationRecordPageReqVO reqVO) {
        return baseDao.selectPage(reqVO);
@@ -48,37 +39,6 @@
        entity.setId(UUID.randomUUID().toString());
        entity.setHandleTime(new Date());
        baseDao.insert(entity);
        if (!"采纳建议".equals(reqVo.getOperate())){
            return;
        }
        //获取调度建议快照配置表信息
        StSuggestSnapshotConfMainRespVO confMain = stSuggestSnapshotConfMainService.getByModelIdAndScheduleObj(reqVo.getModelId(), reqVo.getScheduleObj());
        if (confMain == null) {
            return;
        }
        List<StSuggestSnapshotConfDetRespVO> confDetList = stSuggestSnapshotConfDetService.getByConfId(confMain.getId());
        if (CollectionUtils.isAnyEmpty(confDetList)) {
            return;
        }
        confDetList.forEach(confDet -> {
            StSuggestSnapshotRecordSaveReqVO snapshotRecordSaveReqVO = new StSuggestSnapshotRecordSaveReqVO();
            snapshotRecordSaveReqVO.setSuggestId(reqVo.getSuggestId());
            snapshotRecordSaveReqVO.setModelId(entity.getModelId());
            snapshotRecordSaveReqVO.setOperationId(entity.getId());
            snapshotRecordSaveReqVO.setDataNo(confDet.getDataNo());
            snapshotRecordSaveReqVO.setDataType(confDet.getDataType());
            snapshotRecordSaveReqVO.setDataName(confDet.getDataName());
            snapshotRecordSaveReqVO.setScheduleTime(entity.getScheduleTime());
            //计算开始时间,开始时间为当前调度时间减去快照配置表配置的左侧时间长度
            LocalDateTime localStartDateTime =  entity.getScheduleTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().minusMinutes(confDet.getLeftLength() ==  null ? 60 : confDet.getLeftLength());
            Date startTime = Date.from(localStartDateTime.atZone(ZoneId.systemDefault()).toInstant());
            snapshotRecordSaveReqVO.setStartTime(startTime);
            //计算结束时间,结束时间为当前调度时间加上快照配置表配置的右侧时间长度
            LocalDateTime localEndDateTime =  entity.getScheduleTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().plusMinutes(confDet.getRightLength() ==  null ? 60 : confDet.getLeftLength());
            Date endTime = Date.from(localEndDateTime.atZone(ZoneId.systemDefault()).toInstant());
            snapshotRecordSaveReqVO.setEndTime(endTime);
            stSuggestSnapshotRecordService.create(snapshotRecordSaveReqVO);
        });
    }
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/service/impl/StSuggestSnapshotRecordServiceImpl.java
@@ -4,16 +4,42 @@
import com.iailab.framework.common.service.impl.BaseServiceImpl;
import com.iailab.framework.common.util.object.BeanUtils;
import com.iailab.framework.common.util.object.ConvertUtils;
import com.iailab.module.data.api.ind.IndItemApi;
import com.iailab.module.data.api.ind.dto.ApiIndItemQueryDTO;
import com.iailab.module.data.api.ind.dto.ApiIndItemValueDTO;
import com.iailab.module.data.api.plan.PlanItemApi;
import com.iailab.module.data.api.point.DataPointApi;
import com.iailab.module.data.api.point.dto.ApiPointValueDTO;
import com.iailab.module.data.api.point.dto.ApiPointValueQueryDTO;
import com.iailab.module.data.common.ApiDataQueryDTO;
import com.iailab.module.data.common.ApiDataValueDTO;
import com.iailab.module.model.api.mcs.dto.PreDataBarLineReqVO;
import com.iailab.module.model.api.mcs.dto.PreDataBarLineRespVO;
import com.iailab.module.model.api.mcs.dto.StSuggestSnapshotRecordRespVO;
import com.iailab.module.model.common.enums.DataCategoryEnum;
import com.iailab.module.model.common.utils.DateUtils;
import com.iailab.module.model.mcs.pre.service.MmItemResultService;
import com.iailab.module.model.mcs.sche.dao.StSuggestSnapshotRecordDao;
import com.iailab.module.model.mcs.sche.entity.StSuggestSnapshotRecordEntity;
import com.iailab.module.model.mcs.sche.service.StSuggestSnapshotConfDetService;
import com.iailab.module.model.mcs.sche.service.StSuggestSnapshotConfMainService;
import com.iailab.module.model.mcs.sche.service.StSuggestSnapshotRecordService;
import com.iailab.module.model.mcs.sche.vo.StSuggestSnapshotRecordRespVO;
import com.iailab.module.model.mcs.sche.vo.StSuggestSnapshotConfDetRespVO;
import com.iailab.module.model.mcs.sche.vo.StSuggestSnapshotConfMainRespVO;
import com.iailab.module.model.mcs.sche.vo.StSuggestSnapshotRecordSaveReqVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import static com.iailab.module.model.common.utils.DateUtils.DATE_TIME_PATTERN;
/**
@@ -22,10 +48,25 @@
@Service
public class StSuggestSnapshotRecordServiceImpl extends BaseServiceImpl<StSuggestSnapshotRecordDao, StSuggestSnapshotRecordEntity>
        implements StSuggestSnapshotRecordService {
    @Autowired
    private DataPointApi dataPointApi;
    @Autowired
    private IndItemApi indItemApi;
    @Autowired
    private PlanItemApi planItemApi;
    @Autowired
    private MmItemResultService mmItemResultService;
    @Autowired
    private StSuggestSnapshotRecordService StSuggestSnapshotRecordService;
    private StSuggestSnapshotConfMainService stSuggestSnapshotConfMainService;
    @Autowired
    private StSuggestSnapshotConfDetService stSuggestSnapshotConfDetService;
    @Override
    @DSTransactional(rollbackFor = Exception.class)
@@ -49,7 +90,134 @@
    }
    @Override
    public List<StSuggestSnapshotRecordRespVO> getListByOperationId(String operationId) {
        return ConvertUtils.sourceToTarget(baseDao.selectList("operation_id",  operationId), StSuggestSnapshotRecordRespVO.class);
    public List<StSuggestSnapshotRecordRespVO> getListBySuggestId(String suggestId) {
        return ConvertUtils.sourceToTarget(baseDao.selectList("suggest_id",  suggestId), StSuggestSnapshotRecordRespVO.class);
    }
    @Override
    public void createSnapshotRecord(String modelId, String scheduleObj,Date scheduleTime, String suggestId) {
        if (StringUtils.isBlank(modelId) || StringUtils.isBlank(scheduleObj) || StringUtils.isBlank(suggestId)) {
            log.error("生成快照失败,参数错误!modelId:" + modelId + ",scheduleObj:" + scheduleObj + ",suggestId:" + suggestId);
            return;
        }
        //获取调度建议快照配置表信息
        StSuggestSnapshotConfMainRespVO confMain = stSuggestSnapshotConfMainService.getByModelIdAndScheduleObj(modelId, scheduleObj);
        if (confMain == null) {
            log.error("生成快照失败,confMain is null!modelId:" + modelId + ",scheduleObj:" + scheduleObj);
            return;
        }
        List<StSuggestSnapshotConfDetRespVO> confDetList = stSuggestSnapshotConfDetService.getByConfId(confMain.getId());
        if (CollectionUtils.isEmpty(confDetList)) {
            log.error("生成快照失败,confDetList is empty!modelId:" + modelId + ",scheduleObj:" + scheduleObj);
            return;
        }
        confDetList.forEach(confDet -> {
            StSuggestSnapshotRecordSaveReqVO snapshotRecordSaveReqVO = new StSuggestSnapshotRecordSaveReqVO();
            snapshotRecordSaveReqVO.setSuggestId(suggestId);
            snapshotRecordSaveReqVO.setModelId(modelId);
            snapshotRecordSaveReqVO.setDataNo(confDet.getDataNo());
            snapshotRecordSaveReqVO.setDataType(confDet.getDataType());
            snapshotRecordSaveReqVO.setDataName(confDet.getDataName());
            snapshotRecordSaveReqVO.setScheduleTime(scheduleTime);
            //计算开始时间,开始时间为当前调度时间减去快照配置表配置的左侧时间长度
            LocalDateTime localStartDateTime =  scheduleTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().minusMinutes(confDet.getLeftLength() ==  null ? 60 : confDet.getLeftLength());
            Date startTime = Date.from(localStartDateTime.atZone(ZoneId.systemDefault()).toInstant());
            snapshotRecordSaveReqVO.setStartTime(startTime);
            //计算结束时间,结束时间为当前调度时间加上快照配置表配置的右侧时间长度
            LocalDateTime localEndDateTime =  scheduleTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().plusMinutes(confDet.getRightLength() ==  null ? 60 : confDet.getLeftLength());
            Date endTime = Date.from(localEndDateTime.atZone(ZoneId.systemDefault()).toInstant());
            snapshotRecordSaveReqVO.setEndTime(endTime);
            this.create(snapshotRecordSaveReqVO);
        });
    }
    @Override
    public List<StSuggestSnapshotRecordRespVO> getChartData(List<StSuggestSnapshotRecordRespVO> reqList) {
        reqList.forEach(item -> {
            List<Object[]> dataList = new ArrayList<>();
            if(DataCategoryEnum.DATAPOINT.getCode().equals(item.getDataType())){
                ApiPointValueQueryDTO queryDTO = new ApiPointValueQueryDTO();
                queryDTO.setPointNo(item.getDataNo());
                queryDTO.setStart(item.getStartTime());
                queryDTO.setEnd(item.getEndTime());
                List<ApiPointValueDTO> valueList = dataPointApi.queryPointHistoryValue(queryDTO);
                if (valueList != null && !valueList.isEmpty()){
                    for (ApiPointValueDTO apiPointValueDTO : valueList) {
                        Object[] data = new Object[2];
                        data[0] = DateUtils.format(apiPointValueDTO.getT(), DATE_TIME_PATTERN);
                        data[1] = apiPointValueDTO.getV();
                        dataList.add(data);
                    }
                }
            } else if (DataCategoryEnum.IND.getCode().equals(item.getDataType())) {
                ApiIndItemQueryDTO queryDTO = new ApiIndItemQueryDTO();
                queryDTO.setItemNo(item.getDataNo());
                queryDTO.setStart(item.getStartTime());
                queryDTO.setEnd(item.getEndTime());
                List<ApiIndItemValueDTO> valueList = indItemApi.queryIndItemHistoryValue(queryDTO);
                if (valueList != null && !valueList.isEmpty()){
                    for (ApiIndItemValueDTO apiIndItemValueDTO : valueList) {
                        Object[] data = new Object[2];
                        data[0] = apiIndItemValueDTO.getDataTime();
                        data[1] = apiIndItemValueDTO.getDataValue();
                        dataList.add(data);
                    }
                }
            } else if (DataCategoryEnum.PLAN.getCode().equals(item.getDataType())) {
                ApiDataQueryDTO queryDTO = new ApiDataQueryDTO();
                queryDTO.setItemNo(item.getDataNo());
                queryDTO.setStart(item.getStartTime());
                queryDTO.setEnd(item.getEndTime());
                List<ApiDataValueDTO> valueList = planItemApi.queryPlanItemHistoryValue(queryDTO);
                if (valueList != null && !valueList.isEmpty()){
                    for (ApiDataValueDTO apiDataValueDTO : valueList) {
                        Object[] data = new Object[2];
                        data[0] = DateUtils.format(apiDataValueDTO.getDataTime(), DATE_TIME_PATTERN);
                        data[1] = apiDataValueDTO.getDataValue();
                        dataList.add(data);
                    }
                }
            } else if (DataCategoryEnum.PREDICT_ITEM_N.getCode().equals(item.getDataType())) {
                dataList = getPreDataList(item, "N");
            }else if (DataCategoryEnum.PREDICT_ITEM_L.getCode().equals(item.getDataType())) {
                dataList = getPreDataList(item, "L");
            }else if (DataCategoryEnum.PREDICT_ITEM_C.getCode().equals(item.getDataType())) {
                dataList = getPreDataList(item, "C");
            }
            item.setDataList(dataList);
        });
        return reqList;
    }
    @Override
    public List<StSuggestSnapshotRecordRespVO> getAllChartData(String suggestId) {
        List<StSuggestSnapshotRecordRespVO> records = this.getListBySuggestId(suggestId);
        if (CollectionUtils.isEmpty(records)) {
            return new ArrayList<>();
        }
        return this.getChartData(records);
    }
    private List<Object[]> getPreDataList(StSuggestSnapshotRecordRespVO resVo, String type){
        List<Object[]> dataList = new ArrayList<>();
        PreDataBarLineReqVO reqVO  = new PreDataBarLineReqVO();
        List<String> outIds = new ArrayList<>();
        outIds.add(resVo.getDataNo());
        reqVO.setOutIds(outIds);
        reqVO.setStartTime(resVo.getStartTime());
        reqVO.setEndTime(resVo.getEndTime());
        PreDataBarLineRespVO result = mmItemResultService.getPreDataCharts(reqVO);
        if (result == null || result.getDataViewList() == null || result.getDataViewList().isEmpty()){
            return dataList;
        }
        if ("N".equals(type) && result.getDataViewList().get(0).getPreDataN()!=null){
            dataList = result.getDataViewList().get(0).getPreDataN();
        }else if ("L".equals(type) && result.getDataViewList().get(0).getPreDataL()!=null){
            dataList = result.getDataViewList().get(0).getPreDataL();
        }else if ("C".equals(type) && result.getDataViewList().get(0).getCurData()!=null){
            dataList = result.getDataViewList().get(0).getCurData();
        }
        return dataList;
    }
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mcs/sche/vo/StSuggestSnapshotConfMainRespVO.java
@@ -23,7 +23,7 @@
    @Schema(description = "模型ID")
    private String modelId;
    @Schema(description = "模型ID")
    @Schema(description = "模型名称")
    private String modelName;
    @Schema(description = "调整对象")