已修改12个文件
已重命名2个文件
已添加5个文件
500 ■■■■ 文件已修改
iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/api/controller/DataController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/api/controller/IndItemController.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/McsApi.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/AlarmMessageReqDTO.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/AlarmMessageRespDTO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/PredictModelSettingReqDTO.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/ScheduleModelSettingReqDTO.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/ScheduleSuggestReqDTO.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/ScheduleSuggestRespDTO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/MdkApi.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkPredictReqDTO.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/ModelServiceApplication.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/common/MdkConstant.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/common/utils/DllUtils.java 112 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/controller/admin/MdkController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/controller/admin/MpkFileController.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/service/MpkFileService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/service/impl/MpkFileServiceImpl.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/api/controller/DataController.java
@@ -22,6 +22,7 @@
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
@@ -56,6 +57,7 @@
    @Resource
    private PointCollector pointCollector;
    @PermitAll
    @PostMapping("/point/history")
    @Operation(summary = "point历史数据")
    public CommonResult<Map<String, List<Map<String, Object>>>> pointHistory(HttpServletResponse response, HttpServletRequest
iailab-module-data/iailab-module-data-biz/src/main/java/com/iailab/module/data/api/controller/IndItemController.java
对比新文件
@@ -0,0 +1,53 @@
package com.iailab.module.data.api.controller;
import com.iailab.framework.common.pojo.CommonResult;
import com.iailab.framework.common.util.object.ConvertUtils;
import com.iailab.module.data.api.ind.dto.ApiIndItemQueryDTO;
import com.iailab.module.data.api.ind.dto.ApiIndItemValueDTO;
import com.iailab.module.data.ind.collection.IndItemCollector;
import com.iailab.module.data.ind.item.vo.IndItemValueVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.security.PermitAll;
import java.util.List;
import static com.iailab.framework.common.pojo.CommonResult.success;
/**
 * @author PanZhibao
 * @Description
 * @createTime 2024年10月10日
 */
@Slf4j
@RestController
@RequestMapping("/api/data/ind-item")
@Tag(name = "指标")
public class IndItemController {
    @Autowired
    private IndItemCollector indItemCollector;
    @PermitAll
    @GetMapping("/query-ind/default-value")
    @Operation(summary = "查询指标默认值")
    public CommonResult<List<ApiIndItemValueDTO>> queryIndItemDefaultValue(@RequestParam String itemNo) {
        List<IndItemValueVO> list = indItemCollector.queryValue(itemNo);
        return success(ConvertUtils.sourceToTarget(list, ApiIndItemValueDTO.class));
    }
    @PermitAll
    @GetMapping("/query-ind/history-value")
    @Operation(summary = "查询指标历史值")
    public CommonResult<List<ApiIndItemValueDTO>> queryIndItemHistoryValue(@RequestParam ApiIndItemQueryDTO dto) {
        List<IndItemValueVO> list = indItemCollector.queryValue(dto.getItemNo(), dto.getStart(), dto.getEnd());
        return success(ConvertUtils.sourceToTarget(list, ApiIndItemValueDTO.class));
    }
}
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/McsApi.java
@@ -1,10 +1,7 @@
package com.iailab.module.model.api.mcs;
import com.iailab.framework.common.pojo.CommonResult;
import com.iailab.module.model.api.mcs.dto.AlarmMessageDTO;
import com.iailab.module.model.api.mcs.dto.PredictItemInfoDTO;
import com.iailab.module.model.api.mcs.dto.PredictItemTreeDTO;
import com.iailab.module.model.api.mcs.dto.ScheduleSuggestDTO;
import com.iailab.module.model.api.mcs.dto.*;
import com.iailab.module.model.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -23,7 +20,7 @@
 * @createTime 2024年08月26日
 */
@FeignClient(name = ApiConstants.NAME)
@Tag(name = "RPC 服务 - MCS")
@Tag(name = "RPC 服务 - 模型配置接口")
public interface McsApi {
    String PREFIX = ApiConstants.PREFIX + "/mcs";
@@ -38,18 +35,25 @@
    @PostMapping(PREFIX + "/alarm-message/create")
    @Operation(summary = "添加预警信息")
    CommonResult<Boolean> createAlarmMessage(@RequestBody AlarmMessageDTO dto);
    CommonResult<Boolean> createAlarmMessage(@RequestBody AlarmMessageRespDTO dto);
    @GetMapping(PREFIX + "/alarm-message/list")
    @Operation(summary = "获取预警信息")
    CommonResult<AlarmMessageDTO> listAlarmMessage(@RequestParam Map<String, Object> params);
    @Operation(summary = "获取预警信息列表")
    CommonResult<AlarmMessageRespDTO> listAlarmMessage(@RequestParam Map<String, Object> params);
    @PostMapping(PREFIX + "/schedule-suggest/create")
    @Operation(summary = "添加调度建议")
    CommonResult<Boolean> createScheduleSuggest(@RequestBody ScheduleSuggestDTO dto);
    CommonResult<Boolean> createScheduleSuggest(@RequestBody ScheduleSuggestRespDTO dto);
    @GetMapping(PREFIX + "/alarm-message/list")
    @Operation(summary = "获取调度建议")
    CommonResult<ScheduleSuggestDTO> listScheduleSuggest(@RequestParam Map<String, Object> params);
    @Operation(summary = "获取调度建议列表")
    CommonResult<ScheduleSuggestRespDTO> listScheduleSuggest(@RequestParam ScheduleSuggestReqDTO params);
    @PostMapping(PREFIX + "/predict-model-setting/modify")
    @Operation(summary = "修改预测模型设置参数")
    CommonResult<Boolean> modifyPredictModelSetting(@RequestBody List<PredictModelSettingReqDTO> dtos);
    @PostMapping(PREFIX + "/schedule-model-setting/modify")
    @Operation(summary = "修改调度模型设置参数")
    CommonResult<Boolean> modifyScheduleModelSetting(@RequestBody List<ScheduleModelSettingReqDTO> dtos);
}
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/AlarmMessageReqDTO.java
对比新文件
@@ -0,0 +1,36 @@
package com.iailab.module.model.api.mcs.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 * @author PanZhibao
 * @Description
 * @createTime 2024年10月10日
 */
@Schema(description = "RPC 模型 - 预警消息 DTO")
@Data
public class AlarmMessageReqDTO implements Serializable {
    private static final long serialVersionUID = 1L;
    @Schema(description = "监控对象")
    private String alarmObj;
    @Schema(description = "监控点位ID")
    private String pointId;
    @Schema(description = "预测项ID")
    private String itemId;
    @Schema(description = "预警时间")
    private Date alarmTime;
    @Schema(description = "开始时间")
    private Date startTime;
    @Schema(description = "结束时间")
    private Date endTime;
}
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/AlarmMessageRespDTO.java
文件名从 iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/AlarmMessageDTO.java 修改
@@ -20,7 +20,7 @@
 */
@Schema(description = "RPC 模型 - 预警消息 DTO")
@Data
public class AlarmMessageDTO implements Serializable {
public class AlarmMessageRespDTO implements Serializable {
    private static final long serialVersionUID = 1L;
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/PredictModelSettingReqDTO.java
对比新文件
@@ -0,0 +1,30 @@
package com.iailab.module.model.api.mcs.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
 * @author PanZhibao
 * @Description
 * @createTime 2024年10月10日
 */
@Schema(description = "RPC 模型 - 调度建议 DTO")
@Data
public class PredictModelSettingReqDTO implements Serializable {
    private static final long serialVersionUID = 1L;
    private String modelid;
    /**
     * 键
     */
    private String key;
    /**
     * 值
     */
    private String value;
}
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/ScheduleModelSettingReqDTO.java
对比新文件
@@ -0,0 +1,24 @@
package com.iailab.module.model.api.mcs.dto;
import java.io.Serializable;
/**
 * @author PanZhibao
 * @Description
 * @createTime 2024年10月10日
 */
public class ScheduleModelSettingReqDTO implements Serializable {
    private static final long serialVersionUID = 1L;
    private String modelid;
    /**
     * 键
     */
    private String key;
    /**
     * 值
     */
    private String value;
}
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/ScheduleSuggestReqDTO.java
对比新文件
@@ -0,0 +1,34 @@
package com.iailab.module.model.api.mcs.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
 * @author PanZhibao
 * @Description
 * @createTime 2024年10月10日
 */
@Schema(description = "RPC 模型 - 调度建议req DTO")
@Data
public class ScheduleSuggestReqDTO implements Serializable {
    private static final long serialVersionUID = 1L;
    @Schema(description = "预测项ID")
    private String itemId;
    @Schema(description = "模型ID")
    private String modelId;
    @Schema(description = "调整对象")
    private String adjustObj;
    @Schema(description = "开始时间")
    private Date startTime;
    @Schema(description = "结束时间")
    private Date endTime;
}
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/ScheduleSuggestRespDTO.java
文件名从 iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mcs/dto/ScheduleSuggestDTO.java 修改
@@ -14,7 +14,7 @@
 */
@Schema(description = "RPC 模型 - 调度建议 DTO")
@Data
public class ScheduleSuggestDTO implements Serializable {
public class ScheduleSuggestRespDTO implements Serializable {
    private static final long serialVersionUID = 1L;
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/MdkApi.java
@@ -2,11 +2,10 @@
import com.iailab.module.model.api.mdk.dto.*;
import com.iailab.module.model.enums.ApiConstants;
import com.iailab.framework.common.pojo.CommonResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
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 javax.validation.Valid;
@@ -17,25 +16,24 @@
 * @createTime 2024年08月26日
 */
@FeignClient(name = ApiConstants.NAME)
@Tag(name = "RPC 服务 - MDK")
@Tag(name = "RPC 服务 - 模型调用接口")
public interface MdkApi {
    String PREFIX = ApiConstants.PREFIX + "/mdk";
    @GetMapping(PREFIX + "/predict-module")
    @Operation(summary = "模块预测")
    CommonResult<MdkPredictModuleRespDTO> predictModule(@Valid @RequestBody MdkPredictReqDTO reqDTO);
    @PostMapping(PREFIX + "/predict-module")
    @Operation(summary = "执行模块预测")
    MdkPredictModuleRespDTO predictModule(@Valid @RequestBody MdkPredictReqDTO reqDTO);
    @GetMapping(PREFIX + "/predict-item")
    @Operation(summary = "单独预测")
    CommonResult<MdkPredictItemRespDTO> predictItem(@Valid @RequestBody MdkPredictReqDTO reqDTO);
    @PostMapping(PREFIX + "/predict-item")
    @Operation(summary = "执行单独预测")
    MdkPredictItemRespDTO predictItem(@Valid @RequestBody MdkPredictReqDTO reqDTO);
    @GetMapping(PREFIX + "/predict-auto-adjust")
    @PostMapping(PREFIX + "/predict-adjust")
    @Operation(summary = "预测自动调整")
    CommonResult<Boolean> predictAutoAdjust(@Valid @RequestBody MdkPredictReqDTO reqDTO);
    Boolean predictAutoAdjust(@Valid @RequestBody MdkPredictReqDTO reqDTO);
    @GetMapping(PREFIX + "/schedule")
    @Operation(summary = "执行调度")
    CommonResult<MdkScheduleRespDTO> doSchedule(@Valid @RequestBody MdkScheduleReqDTO reqDTO);
    @PostMapping(PREFIX + "/schedule-scheme")
    @Operation(summary = "执行调度方案")
    MdkScheduleRespDTO doSchedule(@Valid @RequestBody MdkScheduleReqDTO reqDTO);
}
iailab-module-model/iailab-module-model-api/src/main/java/com/iailab/module/model/api/mdk/dto/MdkPredictReqDTO.java
@@ -3,6 +3,7 @@
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
@@ -14,9 +15,13 @@
@Data
public class MdkPredictReqDTO {
    @Schema(description = "预测时间")
    @NotNull(message="预测时间不能为空")
    private Date predictTime;
    @Schema(description = "预测模块")
    private String moduleType;
    @Schema(description = "预测项编号")
    private String itemNo;
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/ModelServiceApplication.java
@@ -1,27 +1,37 @@
package com.iailab;
import com.iailab.module.model.mpk.common.MdkConstant;
import com.iailab.module.model.mpk.common.utils.DllUtils;
import iail.mdk.model.common.Environment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.InputStream;
import java.util.Properties;
@EnableAsync
@SpringBootApplication
@Slf4j
public class ModelServiceApplication implements CommandLineRunner {
    static {
    @Value("${mpk.bak-file-path}")
    private String mpkBakFilePath;
    @PostConstruct
    void init() {
        //加载动态链接库
        try {
            Properties properties = new Properties();
            InputStream in = ModelServiceApplication.class.getClassLoader().getResourceAsStream("iailmdk.properties");
            properties.load(in);
            String mdkInitPath = properties.getProperty("mdk-init-path");
            System.out.println("mdkInitPath=" + mdkInitPath);
            log.info("mdkInitPath=" + mdkInitPath);
            File file = new File(mdkInitPath + File.separator + "IAIL.MDK.Mid.Windows.dll");
            if (!file.exists()) {
                throw new RuntimeException("动态链接库IAIL.MDK.Mid.Windows.dll文件不存在," + file.getAbsolutePath());
@@ -31,9 +41,16 @@
            env.init();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("动态链接库IAIL.MDK.Mid.Windows.dll初始化失败");
            log.error("动态链接库IAIL.MDK.Mid.Windows.dll初始化失败");
        }
        //加载项目已发布的dll和jar
        try {
            DllUtils.loadProjectPublish(mpkBakFilePath + File.separator + MdkConstant.PROJECT_PUBLISH);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("加载项目已发布的dll和jar失败");
        }
    }
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/api/MdkApiImpl.java
@@ -22,10 +22,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
@@ -74,7 +71,7 @@
     * @return
     */
    @Override
    public CommonResult<MdkPredictModuleRespDTO> predictModule(MdkPredictReqDTO reqDTO) {
    public MdkPredictModuleRespDTO predictModule(MdkPredictReqDTO reqDTO) {
        MdkPredictModuleRespDTO resp = new MdkPredictModuleRespDTO();
        Map<String, MdkPredictItemRespDTO> predictItemRespMap = new HashMap<>();
        try {
@@ -112,10 +109,11 @@
            }
            log.info("预测计算结束: " + System.currentTimeMillis());
        } catch (Exception ex) {
            return error(999, ex.getMessage());
            ex.printStackTrace();
            return resp;
        }
        resp.setPredictItemRespMap(predictItemRespMap);
        return success(resp);
        return resp;
    }
    /**
@@ -125,7 +123,7 @@
     * @return
     */
    @Override
    public CommonResult<MdkPredictItemRespDTO> predictItem(@Valid @RequestBody MdkPredictReqDTO reqDTO) {
    public MdkPredictItemRespDTO predictItem(MdkPredictReqDTO reqDTO) {
        MdkPredictItemRespDTO resp = new MdkPredictItemRespDTO();
        try {
@@ -146,10 +144,10 @@
            log.info("预测计算结束: " + System.currentTimeMillis());
        } catch (Exception ex) {
            log.info("预测计算异常: " + System.currentTimeMillis());
            ex.printStackTrace();
            return resp;
        }
        return success(resp);
        return resp;
    }
    /**
@@ -159,10 +157,10 @@
     * @return
     */
    @Override
    public CommonResult<Boolean> predictAutoAdjust(@Valid @RequestBody MdkPredictReqDTO reqDTO) {
    public Boolean predictAutoAdjust(MdkPredictReqDTO reqDTO) {
        return success(true);
        return true;
    }
    /**
@@ -172,7 +170,7 @@
     * @return
     */
    @Override
    public CommonResult<MdkScheduleRespDTO> doSchedule(@Valid @RequestBody MdkScheduleReqDTO reqDTO) {
    public MdkScheduleRespDTO doSchedule(MdkScheduleReqDTO reqDTO) {
        MdkScheduleRespDTO resp = new MdkScheduleRespDTO();
        resp.setScheduleCode(reqDTO.getScheduleCode());
        resp.setScheduleTime(reqDTO.getScheduleTime());
@@ -184,7 +182,8 @@
        } catch (Exception ex) {
            log.info("调度计算异常: " + System.currentTimeMillis());
            ex.printStackTrace();
            return resp;
        }
        return success(resp);
        return resp;
    }
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/common/MdkConstant.java
@@ -34,4 +34,12 @@
     * jar
     */
    String JAR = "jar";
    /**
     * 分隔符 dll、jar文件名
     */
    String SPLIT = "__";
    /**
     * 项目发布dll和jar目录
     */
    String PROJECT_PUBLISH = "projectPublish";
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/common/utils/DllUtils.java
@@ -1,19 +1,23 @@
package com.iailab.module.model.mpk.common.utils;
import cn.hutool.core.io.FileUtil;
import com.iailab.module.model.mpk.common.MdkConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import sun.misc.URLClassPath;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
@Slf4j
public class DllUtils {
    private static HashMap<String, URLClassLoader> classLoaderCache = new HashMap<>();
    /**
     * @description: 加载dll到指定class下
@@ -22,14 +26,14 @@
     **/
    public static void loadDll(Class<?> clazz, String dllPath) {
        try {
            Method method = Runtime.class.getDeclaredMethod("load0", Class.class,String.class);
            Method method = Runtime.class.getDeclaredMethod("load0", Class.class, String.class);
            boolean accessible = method.isAccessible();
            method.setAccessible(true);
            method.invoke(Runtime.getRuntime(), clazz,dllPath);
            method.invoke(Runtime.getRuntime(), clazz, dllPath);
            method.setAccessible(accessible);
            log.info("成功加载dll:"+ dllPath);
            log.info("成功加载dll:" + dllPath);
        } catch (Exception e) {
            throw new RuntimeException("加载dll异常",e);
            throw new RuntimeException("加载dll异常", e);
        }
    }
@@ -38,7 +42,7 @@
     * @author: dzd
     * @date: 2024/9/30 14:31
     **/
    public static synchronized void uploadDll(URLClassLoader classLoader) {
    public static synchronized void unloadDll(URLClassLoader classLoader) {
        try {
            Field field = ClassLoader.class.getDeclaredField("nativeLibraries");
            field.setAccessible(true);
@@ -60,7 +64,7 @@
                log.info("成功卸载dll:" + name);
            }
        } catch (Exception e) {
            throw new RuntimeException("卸载dll异常",e);
            throw new RuntimeException("卸载dll异常", e);
        }
    }
@@ -69,7 +73,7 @@
     * @author: dzd
     * @date: 2024/9/30 14:52
     **/
    public static synchronized void uploadDllName(URLClassLoader classLoader,String dllName) {
    public static synchronized void unloadDllName(URLClassLoader classLoader, String dllName) {
        try {
            Field field = ClassLoader.class.getDeclaredField("nativeLibraries");
            field.setAccessible(true);
@@ -93,7 +97,7 @@
                log.info("成功卸载dll:" + name);
            }
        } catch (Exception e) {
            throw new RuntimeException("卸载dll异常",e);
            throw new RuntimeException("卸载dll异常", e);
        }
    }
@@ -105,24 +109,102 @@
    public static synchronized URLClassLoader loadJar(String jarPath) {
        File jarFile = new File(jarPath);
        if (!jarFile.exists()) {
            throw new RuntimeException("jar沒有找到!");
            throw new RuntimeException("jar沒有找到!"+jarPath);
        } else {
            try {
                URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{jarFile.toURI().toURL()});
                log.info("成功加载jar包:"+ jarFile.getAbsolutePath());
                // 设置classloader的patent为null,限制使用双亲委派,防止其他classloader找到class,导致dll加载到其他classloader
                URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{jarFile.toURI().toURL()},null,null);
                log.info("成功加载jar包:" + jarFile.getAbsolutePath());
                return urlClassLoader;
            } catch (Exception e) {
                throw new RuntimeException("加载jar异常",e);
                throw new RuntimeException("加载jar异常", e);
            }
        }
    }
    public static synchronized void uploadJar(URLClassLoader urlClassLoader) {
    public static synchronized void unloadJar(URLClassLoader urlClassLoader) {
        try {
            urlClassLoader.close();
            log.info("成功卸载jar包。");
        } catch (Exception e) {
            throw new RuntimeException("卸载jar异常",e);
            throw new RuntimeException("卸载jar异常", e);
        }
    }
    public static synchronized void addClassLoaderCache(String projectId, URLClassLoader urlClassLoader) {
        classLoaderCache.put(projectId, urlClassLoader);
    }
    public static synchronized URLClassLoader getClassLoader(String projectId) {
        return classLoaderCache.get(projectId);
    }
    public static synchronized void removeClassLoaderCache(String projectId) {
        if (classLoaderCache.containsKey(projectId)) {
            URLClassLoader urlClassLoader = classLoaderCache.get(projectId);
            unloadDll(urlClassLoader);
            unloadJar(urlClassLoader);
            classLoaderCache.remove(projectId);
        }
    }
    public static void removeOldFile(String bakPath,String projectId) {
        File dir = new File(bakPath);
        if (dir.exists() && dir.isDirectory()) {
            File[] files = dir.listFiles();
            if (null != files && files.length > 0) {
                for (File file : files) {
                    if (file.getName().startsWith(projectId)) {
                        file.delete();
                    }
                }
            }
        }
    }
    /**
     * @description: 项目启动加载已发布的dll和jar
     * @author: dzd
     * @date: 2024/10/10 11:58
     **/
    public static void loadProjectPublish(String bakPath) {
        File dir = new File(bakPath);
        if (dir.exists() && dir.isDirectory()) {
            File[] files = dir.listFiles();
            if (null != files && files.length > 0) {
                for (File file : files) {
                    String fileName = file.getName();
                    if (fileName.endsWith(".jar")) {
                        String[] split = fileName.substring(0,fileName.length() - 4).split(MdkConstant.SPLIT);
                        String projectId = split[0];
                        String historyId = split[1];
                        String jarFilePath = bakPath + File.separator + projectId + MdkConstant.SPLIT + historyId + ".jar";
                        String dllFilePath = bakPath + File.separator + projectId + MdkConstant.SPLIT + historyId + ".dll";
                        if (FileUtil.exist(jarFilePath) && FileUtil.exist(dllFilePath)) {
                            URLClassLoader urlClassLoader = null;
                            try {
                                // 加载新的jar
                                urlClassLoader = loadJar(jarFilePath);
                            } catch (Exception e) {
                                throw new RuntimeException("加载jar异常",e);
                            }
                            try {
                                // 加载新的dll
                                loadDll(urlClassLoader.loadClass("iail.mdk.model.common.Environment"),dllFilePath);
                            } catch (Exception e) {
                                unloadJar(urlClassLoader);
                                throw new RuntimeException("加载dll异常",e);
                            }
                            // 都加载成功后加入缓存
                            addClassLoaderCache(projectId,urlClassLoader);
                        }
                    }
                }
            }
        }
    }
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/controller/admin/MdkController.java
@@ -104,8 +104,8 @@
            return error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"运行异常");
        } finally {
            if (classLoader != null) {
                DllUtils.uploadDll(classLoader);
                DllUtils.uploadJar(classLoader);
                DllUtils.unloadDll(classLoader);
                DllUtils.unloadJar(classLoader);
            }
            System.gc();
        }
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/controller/admin/MpkFileController.java
@@ -125,8 +125,13 @@
    @PostMapping("/upload")
    @Operation(summary = "python文件上传")
    public CommonResult<Map<String,String>> importExcel(@RequestParam("file") MultipartFile file) throws Exception {
    public CommonResult<Map<String,String>> upload(@RequestParam("file") MultipartFile file) throws Exception {
        Map<String,String> result = mpkFileService.savePyFile(file);
        return success(result);
    }
    @PostMapping("/publish")
    public CommonResult<String> publish(@RequestBody Map<String, Object> params) {
        return mpkFileService.publish(params);
    }
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/service/MpkFileService.java
@@ -1,6 +1,7 @@
package com.iailab.module.model.mpk.service;
import com.iailab.framework.common.page.PageData;
import com.iailab.framework.common.pojo.CommonResult;
import com.iailab.framework.common.service.BaseService;
import com.iailab.module.model.mpk.dto.MpkFileDTO;
import com.iailab.module.model.mpk.entity.MpkFileEntity;
@@ -34,4 +35,6 @@
    byte[] packageModel(List<String> ids,String projectId,String projectName,String fileName,String log,String version) throws IOException, InterruptedException;
    Map<String,String> savePyFile(MultipartFile file) throws IOException;
    CommonResult<String> publish(Map<String, Object> params);
}
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/service/impl/MpkFileServiceImpl.java
@@ -8,12 +8,14 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.iailab.framework.common.page.PageData;
import com.iailab.framework.common.pojo.CommonResult;
import com.iailab.framework.common.service.impl.BaseServiceImpl;
import com.iailab.framework.common.util.date.DateUtils;
import com.iailab.framework.common.util.object.ConvertUtils;
import com.iailab.framework.security.core.util.SecurityFrameworkUtils;
import com.iailab.module.infra.api.config.ConfigApi;
import com.iailab.module.model.mpk.common.MdkConstant;
import com.iailab.module.model.mpk.common.utils.DllUtils;
import com.iailab.module.model.mpk.common.utils.GenUtils;
import com.iailab.module.model.mpk.dao.MpkFileDao;
import com.iailab.module.model.mpk.dto.GeneratorCodeHistoryDTO;
@@ -36,6 +38,7 @@
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.Collectors;
@@ -368,6 +371,16 @@
        //生成dll文件
        String dllSavePath = dirPath.getAbsolutePath() + File.separator + MdkConstant.LIBS + File.separator + "IAIL.MDK.Mid.Jni.dll";
        createDllFile(dirPath.getAbsolutePath(),cppFilePaths,dllSavePath);
        // 打包历史id
        String historyId = UUID.randomUUID().toString();
        //备份dll,发布时使用
        File dllFile = new File(dllSavePath);
        if (dllFile.exists()) {
            File dllBakFile = new File(mpkBakFilePath + File.separator + projectId + MdkConstant.SPLIT + historyId + ".dll");
            FileUtil.copy(dllFile, dllBakFile, true);
        }else {
            log.error("dll文件不存在,无法备份。" + dllSavePath);
        }
        //utils + env java文件
        File utilsJavaFile = new File(dirPath.getAbsolutePath() + File.separator + "IAILMDK" + File.separator + "iail" + File.separator + "mdk" + File.separator + "model" + File.separator + "utils" + File.separator + "AlgsUtils.java");
@@ -383,10 +396,18 @@
        // 删除java源文件
        deleteJavaFile(javaFilePaths);
        // 打jar包
        pkgJar(dirPath.getAbsolutePath());
        String jarSavePath = pkgJar(dirPath.getAbsolutePath());
        //备份jar包,发布时使用
        File jarFile = new File(jarSavePath);
        if (jarFile.exists()) {
            File jarBakFile = new File(mpkBakFilePath + File.separator + projectId + MdkConstant.SPLIT + historyId + ".jar");
            FileUtil.copy(jarFile, jarBakFile, true);
        }else {
            log.error("jar文件不存在,无法备份。" + jarSavePath);
        }
        // 本次更新日志
        ProjectPackageHistoryDTO dto = new ProjectPackageHistoryDTO();
        String historyId = UUID.randomUUID().toString();
        dto.setId(historyId);
        dto.setProjectId(projectId);
        dto.setFileName(zipFileName);
@@ -470,6 +491,57 @@
        return result;
    }
    @Override
    public CommonResult<String> publish(Map<String, Object> params) {
        String historyId = (String) params.get("historyId");
        String projectId = (String) params.get("projectId");
        // 判断新的dll和jar文件是否存在
        String jarFileBakPath = mpkBakFilePath + File.separator + projectId + MdkConstant.SPLIT + historyId + ".jar";
        String dllFileBakPath = mpkBakFilePath + File.separator + projectId + MdkConstant.SPLIT + historyId + ".dll";
        if (!FileUtil.exist(jarFileBakPath)) {
            throw new RuntimeException("jar文件不存在," + jarFileBakPath);
        }
        if (!FileUtil.exist(dllFileBakPath)) {
            throw new RuntimeException("dll文件不存在" + dllFileBakPath);
        }
        try {
            // 卸载之前的dll和jar
            DllUtils.removeClassLoaderCache(projectId);
            // 删除之前的dll和jar备份文件
            DllUtils.removeOldFile(mpkBakFilePath + File.separator + MdkConstant.PROJECT_PUBLISH,projectId);
        } catch (Exception e) {
            throw new RuntimeException("卸载之前的dll和jar异常",e);
        }
        // 备份新的dll和jar
        String jarFilePath = mpkBakFilePath + File.separator + MdkConstant.PROJECT_PUBLISH + File.separator + projectId + MdkConstant.SPLIT + historyId + ".jar";
        String dllFilePath = mpkBakFilePath + File.separator + MdkConstant.PROJECT_PUBLISH + File.separator + projectId + MdkConstant.SPLIT + historyId + ".dll";
        FileUtil.copy(jarFileBakPath,jarFilePath,true);
        FileUtil.copy(dllFileBakPath,dllFilePath,true);
        URLClassLoader urlClassLoader = null;
        try {
            // 加载新的jar
            urlClassLoader = DllUtils.loadJar(jarFilePath);
        } catch (Exception e) {
            throw new RuntimeException("加载新的jar异常",e);
        }
        try {
            // 加载新的dll
            DllUtils.loadDll(urlClassLoader.loadClass("iail.mdk.model.common.Environment"),dllFilePath);
        } catch (Exception e) {
            DllUtils.unloadJar(urlClassLoader);
            throw new RuntimeException("加载新的dll异常",e);
        }
        // 都加载成功后加入缓存
        DllUtils.addClassLoaderCache(projectId,urlClassLoader);
        return CommonResult.success();
    }
    private void createLog(String projectId, String projectName, String dirPath, ProjectPackageHistoryDTO dto, String version) throws IOException {
        Map<String, Object> map = new HashMap<>();
        map.put("projectId", projectId);