iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/common/MatlabConstant.java
对比新文件 @@ -0,0 +1,13 @@ package com.iailab.module.model.matlab.common; /** * @description: * @author: dzd * @date: 2025/2/14 10:59 **/ public interface MatlabConstant { /** * JNI */ String JNI = "JNI"; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/common/exceptions/IllegalityJarException.java
对比新文件 @@ -0,0 +1,22 @@ package com.iailab.module.model.matlab.common.exceptions; /** * @description: 非法jar包异常 * @author: dzd * @date: 2025/2/26 17:52 **/ public class IllegalityJarException extends Exception { private Throwable cause; public IllegalityJarException() { } public IllegalityJarException(String msg) { super(msg); } public IllegalityJarException(String msg, Exception cause) { super(msg, cause); this.cause = cause; } } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/common/utils/MatlabUtils.java
对比新文件 @@ -0,0 +1,405 @@ package com.iailab.module.model.matlab.common.utils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.iail.model.IAILModel; import com.iailab.module.model.matlab.common.exceptions.IllegalityJarException; import com.iailab.module.model.matlab.dto.MatlabJarFileClassInfoDTO; import com.iailab.module.model.matlab.dto.MatlabJarFileMethodInfoDTO; import com.iailab.module.model.matlab.dto.MlModelMethodSettingDTO; import com.iailab.module.model.mpk.common.MdkConstant; import com.mathworks.toolbox.javabuilder.*; import com.mathworks.toolbox.javabuilder.internal.MWFunctionSignature; import lombok.extern.slf4j.Slf4j; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.*; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.stream.Collectors; @Slf4j public class MatlabUtils { private static HashMap<String, URLClassLoader> classLoaderCache = new HashMap<>(); private static HashMap<String, Object> classCache = new HashMap<>(); private static HashMap<String, Method> classMethodCache = new HashMap<>(); /** * @description: 解析matlab jar文件 **/ public static List<MatlabJarFileClassInfoDTO> parseJarInfo(String jarFilePath, String jatName) throws IllegalityJarException { List<MatlabJarFileClassInfoDTO> classInfos = new ArrayList<>(); //加载jar用于解析内部class method URLClassLoader urlClassLoader = loadJar(null,jarFilePath); try (JarFile jarFile = new JarFile(jarFilePath)) { // 获取 JAR 文件中所有的条目 Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String entryName = entry.getName(); // 检查条目是否为类文件 if (entryName.endsWith(".class") && !entryName.endsWith("Remote.class") && !entryName.endsWith("MCRFactory.class")) { MatlabJarFileClassInfoDTO classInfo = new MatlabJarFileClassInfoDTO(); // 将类文件的路径转换为类的全限定名 String className = entryName.replace('/', '.').substring(0, entryName.lastIndexOf(".class")); // 校验包名是否和文件名一致,不一致则说明修改过jar包名,判定为非法包 if (!className.startsWith(jatName)) { throw new IllegalityJarException(); } classInfo.setClassName(className); try { // 加载类 Class<?> clazz = urlClassLoader.loadClass(className); // 获取该类的所有属性 Field[] fields = clazz.getDeclaredFields(); List<MatlabJarFileMethodInfoDTO> methodInfos = new ArrayList<>(); for (Field field : fields) { int modifiers = field.getModifiers(); if (Modifier.isPrivate(modifiers) && Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { try { // 绕过访问控制检查 field.setAccessible(true); Object value = field.get(null); // 静态字段不需要实例,传 null if (value instanceof MWFunctionSignature) { MatlabJarFileMethodInfoDTO methodInfo = new MatlabJarFileMethodInfoDTO(); methodInfo.setMethodName(value.getClass().getField("name").get(value).toString()); // 减1是为了排除最后面的setting methodInfo.setDataLength((Integer) value.getClass().getField("numInputs").get(value) - 1); methodInfo.setOutLength((Integer) value.getClass().getField("numOutputs").get(value)); methodInfos.add(methodInfo); } } catch (Exception e) { log.error("get matlab method info exception,className:" + className, e); } } } classInfo.setMethodInfos(methodInfos); } catch (Exception e) { log.error("get matlab class info exception,className:" + className, e); } classInfos.add(classInfo); } } } catch (IOException e) { log.error("get matlab jar info exception,jarFilePath:" + jarFilePath, e); } finally { unloadJar(urlClassLoader); } return classInfos; } public static synchronized URLClassLoader loadJar(String projectId, String... jarPaths) { try { URL[] urls = new URL[jarPaths.length]; for (int i = 0; i < jarPaths.length; i++) { String jarPath = jarPaths[i]; File jarFile = new File(jarPath); if (!jarFile.exists()) { throw new RuntimeException("jar沒有找到!" + jarPath); } urls[i] = new File(jarPath).toURI().toURL(); } // 不能设置classloader的patent,让它使用双亲委派去找系统classloader中javabuilder.jar中的依赖。因为javabuilder.jar只能加载一次,加载多次会报资源占用 URLClassLoader urlClassLoader = new URLClassLoader(urls); if (projectId != null) { addClassLoaderCache(projectId, urlClassLoader); } log.info("成功加载jar包:" + String.join(";",jarPaths)); return urlClassLoader; } catch (Exception e) { throw new RuntimeException("加载jar异常", e); } } public static synchronized void unloadJar(URLClassLoader urlClassLoader) { try { urlClassLoader.close(); log.info("成功卸载jar包。"); } catch (Exception 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); unloadJar(urlClassLoader); classLoaderCache.remove(projectId); removeClassCache(projectId); removeClassMethodCache(projectId); } } public static synchronized void removeClassCache(String projectId) { Iterator<String> iterator = classCache.keySet().iterator(); while (iterator.hasNext()) { String key = iterator.next(); if (key.startsWith(projectId)) { iterator.remove(); } } } public static synchronized void removeClassMethodCache(String projectId) { Iterator<String> iterator = classMethodCache.keySet().iterator(); while (iterator.hasNext()) { String key = iterator.next(); if (key.startsWith(projectId)) { iterator.remove(); } } } 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.split(MdkConstant.SPLIT); String projectId = split[0]; URLClassLoader urlClassLoader = null; try { // 加载新的jar urlClassLoader = loadJar(projectId,file.getAbsolutePath()); } catch (Exception e) { throw new RuntimeException("加载jar异常", e); } // 成功后加入缓存 addClassLoaderCache(projectId, urlClassLoader); } } } } } public static HashMap<String, Object> run(IAILModel model, Object[] paramsValueArray, String projectId) throws Exception { if (model == null) { throw new RuntimeException("模型文件不能为空!"); } else { // 上传时校验文件名和class的开头是相同的,保证className唯一,可以用 projectId_className 作为唯一key String classCacheKey = projectId + "_" + model.getClassName(); String methodParams = Arrays.stream(model.getParamsArray()).map(e -> e.getName()).collect(Collectors.joining(",")); String classMethodCacheKey = classCacheKey + "." + model.getMethodName() + "(" + methodParams + ")"; // 因为一个类下可能有多多个方法,所以这里classCacheKey 和 classMethodCacheKey 要分开判断 if (classCache.containsKey(classCacheKey)) { if (classMethodCache.containsKey(classMethodCacheKey)) { return (HashMap) classMethodCache.get(classMethodCacheKey).invoke(classCache.get(classCacheKey), paramsValueArray); } else { // 运行过这个类的其他方法,类从缓存中取,新建方法 Object o = classCache.get(classCacheKey); Class<?>[] paramsArray = new Class[2]; paramsArray[0] = int.class; paramsArray[1] = Object[].class; Method method = o.getClass().getMethod(model.getMethodName(), paramsArray); classMethodCache.put(classMethodCacheKey, method); Object[] objects = (Object[]) method.invoke(o, paramsValueArray); HashMap<String, Object> map = convertStructToMap((MWStructArray) objects[0]); return map; } } else { URLClassLoader classLoader = getClassLoader(projectId); if (null == classLoader) { throw new RuntimeException("matlab未发布,classLoader为null"); } Class<?> clazz = classLoader.loadClass(model.getClassName()); Object o = clazz.newInstance(); Class<?>[] paramsArray = new Class[2]; paramsArray[0] = int.class; paramsArray[1] = Object[].class; Method method = clazz.getMethod(model.getMethodName(), paramsArray); classCache.put(classCacheKey, o); classMethodCache.put(classMethodCacheKey, method); Object[] objects = (Object[]) method.invoke(o, paramsValueArray); HashMap<String, Object> map = convertStructToMap((MWStructArray) objects[0]); return map; } } } public static HashMap<String, Object> convertStructToMap(MWStructArray struct) { HashMap<String, Object> map; try { map = new HashMap<>(); String[] fieldNames = struct.fieldNames(); int numElements = struct.numberOfElements(); for (int i = 1; i <= numElements; i++) { for (String fieldName : fieldNames) { MWArray value = struct.getField(fieldName, i); Object javaValue = convertMWArrayToJavaObject(value); map.put(fieldName, javaValue); } } } finally { struct.dispose(); } return map; } private static Object convertMWArrayToJavaObject(MWArray mwArray) { try { if (mwArray instanceof MWNumericArray) { MWNumericArray numArray = (MWNumericArray) mwArray; if (numArray.numberOfElements() == 1) { MWClassID mwClassID = numArray.classID(); if (mwClassID.equals(MWClassID.DOUBLE)) { return numArray.getDouble(); } else if (mwClassID.equals(MWClassID.SINGLE)) { return numArray.getFloat(); } else if (mwClassID.equals(MWClassID.INT8) || mwClassID.equals(MWClassID.UINT8)) { return numArray.getByte(); } else if (mwClassID.equals(MWClassID.INT16) || mwClassID.equals(MWClassID.UINT16)) { return numArray.getShort(); } else if (mwClassID.equals(MWClassID.INT32) || mwClassID.equals(MWClassID.UINT32)) { return numArray.getInt(); } else if (mwClassID.equals(MWClassID.INT64) || mwClassID.equals(MWClassID.UINT64)) { return numArray.getLong(); } else if (mwClassID.equals(MWClassID.LOGICAL)) { return numArray.getByte(); } return null; } else { MWClassID mwClassID = numArray.classID(); if (mwClassID.equals(MWClassID.DOUBLE)) { return numArray.toDoubleArray(); } else if (mwClassID.equals(MWClassID.SINGLE)) { return numArray.toFloatArray(); } else if (mwClassID.equals(MWClassID.INT8)) { return numArray.toByteArray(); } else if (mwClassID.equals(MWClassID.INT16) || mwClassID.equals(MWClassID.UINT16)) { return numArray.toShortArray(); } else if (mwClassID.equals(MWClassID.INT32) || mwClassID.equals(MWClassID.UINT32)) { return numArray.toIntArray(); } else if (mwClassID.equals(MWClassID.INT64) || mwClassID.equals(MWClassID.UINT64)) { return numArray.toLongArray(); } else if (mwClassID.equals(MWClassID.LOGICAL)) { return numArray.toByteArray(); } return null; } } else if (mwArray instanceof MWCharArray) { MWCharArray stringArray = (MWCharArray) mwArray; if (stringArray.numberOfElements() == 1) { return stringArray.getChar(1); } else { // 不支持string,string都是用char[]返回,所以这里将char[]转为string int[] dimensions = stringArray.getDimensions(); if (dimensions[0] == 1) { //string return stringArray.toString(); } else { //String[] 暂时只考虑一维string char[][] array = (char[][]) stringArray.toArray(); String[] list = new String[dimensions[0]]; for (int i = 0; i < dimensions[0]; i++) { list[i] = (String.valueOf(array[i])); } return list; } } } else if (mwArray instanceof MWLogicalArray) { MWLogicalArray logicalArray = (MWLogicalArray) mwArray; if (logicalArray.numberOfElements() == 1) { return logicalArray.getBoolean(1); } else { int[] dimensions = logicalArray.getDimensions(); return logicalArray.toArray(); } } else if (mwArray instanceof MWStructArray) { MWStructArray structArray = (MWStructArray) mwArray; return convertStructToMap(structArray); } } finally { mwArray.dispose(); } return null; } public static HashMap<String, Object> handleModelSettings(List<MlModelMethodSettingDTO> modelSettings) { HashMap<String, Object> resultMap = null; try { resultMap = new HashMap<>(modelSettings.size()); for (MlModelMethodSettingDTO modelSetting : modelSettings) { switch (modelSetting.getValueType()) { case "int": resultMap.put(modelSetting.getSettingKey(), Integer.valueOf(modelSetting.getSettingValue())); break; case "string": resultMap.put(modelSetting.getSettingKey(), modelSetting.getSettingValue()); break; case "decimal": resultMap.put(modelSetting.getSettingKey(), Double.valueOf(modelSetting.getSettingValue())); break; case "decimalArray": JSONArray jsonArray = JSON.parseArray(modelSetting.getSettingValue()); double[] doubles = new double[jsonArray.size()]; for (int i = 0; i < jsonArray.size(); i++) { doubles[i] = Double.valueOf(String.valueOf(jsonArray.get(i))); } resultMap.put(modelSetting.getSettingKey(), doubles); break; } } } catch (NumberFormatException e) { throw new RuntimeException("模型参数有误,请检查!!!"); } return resultMap; } public static MWStructArray convertMapToStruct(Map<String, Object> map) { String[] fieldNames = map.keySet().toArray(new String[0]); MWStructArray struct = new MWStructArray(1, 1, fieldNames); for (String key : map.keySet()) { Object value = map.get(key); if (value instanceof Number) { struct.set(key, 1, ((Number) value).doubleValue()); } else if (value instanceof String) { struct.set(key, 1, value); } // 可以根据需要添加更多类型的处理 } return struct; } } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/controller/admin/MlModelController.java
对比新文件 @@ -0,0 +1,113 @@ package com.iailab.module.model.matlab.controller.admin; import com.iailab.framework.common.exception.enums.GlobalErrorCodeConstants; import com.iailab.framework.common.page.PageData; import com.iailab.framework.common.pojo.CommonResult; import com.iailab.module.model.matlab.common.exceptions.IllegalityJarException; import com.iailab.module.model.matlab.dto.MatlabJarFileInfoDTO; import com.iailab.module.model.matlab.dto.MatlabRunDTO; import com.iailab.module.model.matlab.dto.MlModelDTO; import com.iailab.module.model.matlab.service.MlModelService; import com.iailab.module.model.mpk.dto.MpkFileDTO; import io.swagger.v3.oas.annotations.Operation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.HashMap; import java.util.List; import java.util.Map; import static com.iailab.framework.common.pojo.CommonResult.success; /** * @author Dzd * @since 1.0.0 2025-02-08 */ @RestController @RequestMapping("/model/matlab/model") public class MlModelController { @Autowired private MlModelService mlModelService; @GetMapping("page") @Operation(summary = "分页") @PreAuthorize("@ss.hasPermission('ml:model:query')") public CommonResult<PageData<MlModelDTO>> page(@RequestParam Map<String, Object> params) { PageData<MlModelDTO> page = mlModelService.page(params); return success(page); } @GetMapping("{id}") @Operation(summary = "信息") @PreAuthorize("@ss.hasPermission('ml:model:query')") public CommonResult<MlModelDTO> get(@PathVariable("id") String id){ MlModelDTO data = mlModelService.get(id); return success(data); } @PreAuthorize("@ss.hasPermission('ml:model:query')") @GetMapping("list") public CommonResult<List<MlModelDTO>> list(@RequestParam Map<String, Object> params) { List<MlModelDTO> list = mlModelService.list(params); return success(list); } @PostMapping @Operation(summary = "保存") @PreAuthorize("@ss.hasPermission('ml:model:create')") public CommonResult save(@RequestBody MlModelDTO dto){ mlModelService.save(dto); return success(); } @PutMapping @Operation(summary = "修改") @PreAuthorize("@ss.hasPermission('ml:model:update')") public CommonResult update(@RequestBody MlModelDTO dto){ mlModelService.update(dto); return success(); } @DeleteMapping @Operation(summary = "删除") @PreAuthorize("@ss.hasPermission('ml:model:delete')") public CommonResult delete(String id){ mlModelService.delete(id); return success(); } @PostMapping("/upload") @Operation(summary = "算法封装jar文件上传") public CommonResult<MatlabJarFileInfoDTO> upload(@RequestParam("file") MultipartFile file){ MatlabJarFileInfoDTO result = null; try { result = mlModelService.uploadJarFile(file); } catch (IllegalityJarException e) { return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),"非法jar包"); } return success(result); } @PostMapping("/test") @Operation(summary = "Matlab测试运行") public CommonResult<String> test(@RequestBody MatlabRunDTO dto) { return mlModelService.test(dto); } @PostMapping("/importData") @Operation(summary = "导入参数") public CommonResult<List<HashMap<String,Object>>> importData(@RequestParam("file") MultipartFile file) throws Exception { List<HashMap<String,Object>> result = mlModelService.importData(file); return success(result); } } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/controller/admin/MlProjectController.java
对比新文件 @@ -0,0 +1,93 @@ package com.iailab.module.model.matlab.controller.admin; import com.iailab.framework.common.page.PageData; import com.iailab.framework.common.pojo.CommonResult; import com.iailab.module.model.matlab.dto.MlModelDTO; import com.iailab.module.model.matlab.dto.MlProjectDTO; import com.iailab.module.model.matlab.service.MlProjectService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import static com.iailab.framework.common.pojo.CommonResult.success; /** * @description: * @author: dzd * @date: 2024/8/22 14:40 **/ @RestController @RequestMapping("/model/matlab/project") public class MlProjectController { @Autowired private MlProjectService mlProjectService; @PreAuthorize("@ss.hasPermission('matlab:project:query')") @GetMapping("page") public CommonResult<PageData<MlProjectDTO>> page(@RequestParam Map<String, Object> params){ PageData<MlProjectDTO> page = mlProjectService.page(params); return success(page); } @PreAuthorize("@ss.hasPermission('matlab:project:query')") @GetMapping("list") public CommonResult<List<MlProjectDTO>> list() { List<MlProjectDTO> list = mlProjectService.list(new HashMap<>()); return success(list); } @PreAuthorize("@ss.hasPermission('matlab:project:query')") @GetMapping("{id}") public CommonResult<MlProjectDTO> get(@PathVariable("id") String id){ MlProjectDTO data = mlProjectService.get(id); return success(data); } @PreAuthorize("@ss.hasPermission('matlab:project:create')") @PostMapping public CommonResult<Boolean> save(@RequestBody MlProjectDTO dto){ mlProjectService.save(dto); return CommonResult.success(true); } @PreAuthorize("@ss.hasPermission('matlab:project:update')") @PutMapping public CommonResult<Boolean> update(@RequestBody MlProjectDTO dto){ dto.setUpdateTime(new Date()); mlProjectService.update(dto); return CommonResult.success(true); } @PreAuthorize("@ss.hasPermission('matlab:project:delete')") @DeleteMapping public CommonResult<Boolean> delete(String id){ mlProjectService.delete(id); return CommonResult.success(true); } @GetMapping("getProjectModel") public CommonResult<PageData<MlModelDTO>> getProjectModel(@RequestParam Map<String, Object> params){ PageData<MlModelDTO> page = mlProjectService.getProjectModel(params); return CommonResult.success(page); } @PostMapping("/publish") public CommonResult<String> publish(@RequestBody Map<String, Object> params) { return mlProjectService.publish(params); } } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/controller/package-info.java
对比新文件 @@ -0,0 +1 @@ package com.iailab.module.model.matlab.controller; iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dao/MlModelDao.java
对比新文件 @@ -0,0 +1,30 @@ package com.iailab.module.model.matlab.dao; import com.iailab.framework.common.dao.BaseDao; import com.iailab.framework.tenant.core.db.dynamic.TenantDS; import com.iailab.module.model.matlab.dto.MlModelDTO; import com.iailab.module.model.matlab.entity.MlModelEntity; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Map; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ @TenantDS @Mapper public interface MlModelDao extends BaseDao<MlModelEntity> { List<MlModelDTO> list(Map<String, Object> params); MlModelDTO get(String id); int getProjectModelCount(String projectId); List<MlModelDTO> getProjectModel(@Param("params") Map<String, Object> params); } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dao/MlModelMethodDao.java
对比新文件 @@ -0,0 +1,18 @@ package com.iailab.module.model.matlab.dao; import com.iailab.framework.common.dao.BaseDao; import com.iailab.framework.tenant.core.db.dynamic.TenantDS; import com.iailab.module.model.matlab.entity.MlModelMethodEntity; import org.apache.ibatis.annotations.Mapper; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ @TenantDS @Mapper public interface MlModelMethodDao extends BaseDao<MlModelMethodEntity> { } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dao/MlModelMethodSettingDao.java
对比新文件 @@ -0,0 +1,18 @@ package com.iailab.module.model.matlab.dao; import com.iailab.framework.common.dao.BaseDao; import com.iailab.framework.tenant.core.db.dynamic.TenantDS; import com.iailab.module.model.matlab.entity.MlModelMethodSettingEntity; import org.apache.ibatis.annotations.Mapper; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ @TenantDS @Mapper public interface MlModelMethodSettingDao extends BaseDao<MlModelMethodSettingEntity> { } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dao/MlProjectDao.java
对比新文件 @@ -0,0 +1,16 @@ package com.iailab.module.model.matlab.dao; import com.iailab.framework.common.dao.BaseDao; import com.iailab.framework.tenant.core.db.dynamic.TenantDS; import com.iailab.module.model.matlab.entity.MlProjectEntity; import org.apache.ibatis.annotations.Mapper; /** * @description: * @author: dzd * @date: 2025/2/25 14:11 **/ @TenantDS @Mapper public interface MlProjectDao extends BaseDao<MlProjectEntity> { } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dao/MlProjectModelDao.java
对比新文件 @@ -0,0 +1,23 @@ package com.iailab.module.model.matlab.dao; import com.iailab.framework.common.dao.BaseDao; import com.iailab.framework.tenant.core.db.dynamic.TenantDS; import com.iailab.module.model.matlab.dto.MlModelDTO; import com.iailab.module.model.matlab.entity.MlProjectModelEntity; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Map; /** * @description: * @author: dzd * @date: 2025/2/25 14:10 **/ @TenantDS @Mapper public interface MlProjectModelDao extends BaseDao<MlProjectModelEntity> { List<MlModelDTO> getProjectModel(@Param("params") Map<String, Object> params); } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dto/MatlabJarFileClassInfoDTO.java
对比新文件 @@ -0,0 +1,13 @@ package com.iailab.module.model.matlab.dto; import lombok.Data; import java.util.List; @Data public class MatlabJarFileClassInfoDTO { private String className; private List<MatlabJarFileMethodInfoDTO> methodInfos; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dto/MatlabJarFileInfoDTO.java
对比新文件 @@ -0,0 +1,16 @@ package com.iailab.module.model.matlab.dto; import lombok.Data; import java.util.HashMap; import java.util.List; @Data public class MatlabJarFileInfoDTO { private String fileName; private String filePath; private List<MatlabJarFileClassInfoDTO> classInfos; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dto/MatlabJarFileMethodInfoDTO.java
对比新文件 @@ -0,0 +1,13 @@ package com.iailab.module.model.matlab.dto; import lombok.Data; @Data public class MatlabJarFileMethodInfoDTO { private String methodName; private Integer dataLength; private Integer outLength; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dto/MatlabRunDTO.java
对比新文件 @@ -0,0 +1,28 @@ package com.iailab.module.model.matlab.dto; import lombok.Data; import java.io.Serializable; import java.util.List; /** * @description: * @author: dzd * @date: 2025/2/24 15:59 **/ @Data public class MatlabRunDTO implements Serializable { private static final long serialVersionUID = 1L; private String modelFileName; private String className; private String methodName; private Integer outLength; private List<MlModelMethodSettingDTO> modelSettings; private List<String> uuids; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dto/MlModelDTO.java
对比新文件 @@ -0,0 +1,46 @@ package com.iailab.module.model.matlab.dto; import lombok.Data; import java.io.Serializable; import java.util.Date; import java.util.List; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ @Data public class MlModelDTO implements Serializable { private static final long serialVersionUID = 1L; private String id; private String modelName; private String modelFileName; private String modelFilePath; private String modelType; private String matlabPlatform; private String matlabVersion; private String remark; private Long updater; private Date updateDate; private Long creator; private Date createDate; private List<MlModelMethodDTO> modelMethods; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dto/MlModelMethodDTO.java
对比新文件 @@ -0,0 +1,34 @@ package com.iailab.module.model.matlab.dto; import lombok.Data; import java.io.Serializable; import java.util.List; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ @Data public class MlModelMethodDTO implements Serializable { private static final long serialVersionUID = 1L; private String id; private String mlModelId; private String className; private String methodName; private Integer dataLength; private Integer outLength; private Integer sort; private List<MlModelMethodSettingDTO> methodSettings; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dto/MlModelMethodSettingDTO.java
对比新文件 @@ -0,0 +1,32 @@ package com.iailab.module.model.matlab.dto; import lombok.Data; import java.io.Serializable; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ @Data public class MlModelMethodSettingDTO implements Serializable { private static final long serialVersionUID = 1L; private String id; private String mlModelMethodId; private String name; private String settingKey; private String settingValue; private String valueType; private String sort; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dto/MlProjectDTO.java
对比新文件 @@ -0,0 +1,32 @@ package com.iailab.module.model.matlab.dto; import lombok.Data; import java.io.Serializable; import java.util.Date; import java.util.List; /** * @description: 项目表 * @author: dzd * @date: 2024/8/22 14:41 **/ @Data public class MlProjectDTO implements Serializable { private static final long serialVersionUID = 1L; private String id; private String projectName; private String projectCode; private Date createTime; private Date updateTime; private List<MlModelDTO> models; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/dto/MlProjectModelDTO.java
对比新文件 @@ -0,0 +1,24 @@ package com.iailab.module.model.matlab.dto; import lombok.Data; import java.io.Serializable; /** * @description: * @author: dzd * @date: 2025/2/25 14:39 **/ @Data public class MlProjectModelDTO implements Serializable { private static final long serialVersionUID = 1L; private String id; private String projectId; private String modelId; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/entity/MlModelEntity.java
对比新文件 @@ -0,0 +1,73 @@ package com.iailab.module.model.matlab.entity; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.util.Date; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ @Data @TableName("t_ml_model") public class MlModelEntity { /** * */ private String id; /** * 模型名称 */ private String modelName; /** * 模型文件名 */ private String modelFileName; /** * 模型文件路径 */ private String modelFilePath; /** * 模型类型 */ private String modelType; /** * matlab平台 */ private String matlabPlatform; /** * matlab版本 */ private String matlabVersion; /** * 备注 */ private String remark; /** * 更新者 */ @TableField(fill = FieldFill.INSERT_UPDATE) private Long updater; /** * 更新时间 */ @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateDate; /** * 创建者 */ @TableField(fill = FieldFill.INSERT) private Long creator; /** * 创建时间 */ @TableField(fill = FieldFill.INSERT) private Date createDate; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/entity/MlModelMethodEntity.java
对比新文件 @@ -0,0 +1,46 @@ package com.iailab.module.model.matlab.entity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.util.Date; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ @Data @TableName("t_ml_model_method") public class MlModelMethodEntity { /** * */ private String id; /** * 模型id */ private String mlModelId; /** * 全类名 */ private String className; /** * 方法名 */ private String methodName; /** * 数据长度 */ private Integer dataLength; /** * 输出长度 */ private Integer outLength; /** * 排序 */ private Integer sort; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/entity/MlModelMethodSettingEntity.java
对比新文件 @@ -0,0 +1,46 @@ package com.iailab.module.model.matlab.entity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.util.Date; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ @Data @TableName("t_ml_model_method_setting") public class MlModelMethodSettingEntity { /** * id */ private String id; /** * 模型方法id */ private String mlModelMethodId; /** * 参数名称 */ private String name; /** * 参数key */ private String settingKey; /** * 参数值 */ private String settingValue; /** * 参数类型 */ private String valueType; /** * 排序 */ private Integer sort; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/entity/MlProjectEntity.java
对比新文件 @@ -0,0 +1,37 @@ package com.iailab.module.model.matlab.entity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.util.Date; /** * @description: * @author: dzd * @date: 2025/2/25 14:10 **/ @Data @TableName("t_ml_project") public class MlProjectEntity { /** * id */ private String id; /** * 项目名称 */ private String projectName; /** * 项目编码 */ private String projectCode; /** * 创建时间 */ private Date createTime; /** * 修改时间 */ private Date updateTime; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/entity/MlProjectModelEntity.java
对比新文件 @@ -0,0 +1,27 @@ package com.iailab.module.model.matlab.entity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; /** * @description: * @author: dzd * @date: 2025/2/25 14:16 **/ @Data @TableName("t_ml_project_model") public class MlProjectModelEntity { /** * id */ private String id; /** * 项目id */ private String projectId; /** * 模型id */ private String modelId; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/service/MlModelMethodService.java
对比新文件 @@ -0,0 +1,20 @@ package com.iailab.module.model.matlab.service; import com.iailab.framework.common.service.BaseService; import com.iailab.module.model.matlab.dto.MlModelMethodDTO; import com.iailab.module.model.matlab.entity.MlModelMethodEntity; import java.util.List; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ public interface MlModelMethodService extends BaseService<MlModelMethodEntity> { void insertList(List<MlModelMethodDTO> modelMethods, String id); void deleteModelMethod(String modelId); } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/service/MlModelMethodSettingService.java
对比新文件 @@ -0,0 +1,18 @@ package com.iailab.module.model.matlab.service; import com.iailab.framework.common.service.BaseService; import com.iailab.module.model.matlab.entity.MlModelMethodSettingEntity; import java.util.List; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ public interface MlModelMethodSettingService extends BaseService<MlModelMethodSettingEntity> { void insertList(List<MlModelMethodSettingEntity> settingEntities); } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/service/MlModelService.java
对比新文件 @@ -0,0 +1,44 @@ package com.iailab.module.model.matlab.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.framework.common.service.CrudService; import com.iailab.module.model.matlab.common.exceptions.IllegalityJarException; import com.iailab.module.model.matlab.dto.MatlabJarFileInfoDTO; import com.iailab.module.model.matlab.dto.MatlabRunDTO; import com.iailab.module.model.matlab.dto.MlModelDTO; import com.iailab.module.model.matlab.entity.MlModelEntity; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ public interface MlModelService extends BaseService<MlModelEntity> { PageData<MlModelDTO> page(Map<String, Object> params); List<MlModelDTO> list(Map<String, Object> params); MlModelDTO get(String id); void save(MlModelDTO dto); void update(MlModelDTO dto); void delete(String id); MatlabJarFileInfoDTO uploadJarFile(MultipartFile file) throws IllegalityJarException; CommonResult<String> test(MatlabRunDTO dto); List<HashMap<String, Object>> importData(MultipartFile file) throws IOException; } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/service/MlProjectModelService.java
对比新文件 @@ -0,0 +1,25 @@ package com.iailab.module.model.matlab.service; import com.iailab.framework.common.service.BaseService; import com.iailab.module.model.matlab.dto.MlModelDTO; import com.iailab.module.model.matlab.dto.MlProjectModelDTO; import com.iailab.module.model.matlab.entity.MlProjectModelEntity; import java.util.List; import java.util.Map; /** * @description: * @author: dzd * @date: 2024/8/22 14:41 **/ public interface MlProjectModelService extends BaseService<MlProjectModelEntity> { List<MlProjectModelDTO> list(Map<String, Object> params); void deleteByMap(Map<String,Object> map); void create(List<MlModelDTO> models, String projectId); List<MlModelDTO> getProjectModel(Map<String, Object> params); } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/service/MlProjectService.java
对比新文件 @@ -0,0 +1,34 @@ package com.iailab.module.model.matlab.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.matlab.dto.MlModelDTO; import com.iailab.module.model.matlab.dto.MlProjectDTO; import com.iailab.module.model.matlab.entity.MlProjectEntity; import java.util.List; import java.util.Map; /** * @description: * @author: dzd * @date: 2024/8/22 14:41 **/ public interface MlProjectService extends BaseService<MlProjectEntity> { PageData<MlProjectDTO> page(Map<String, Object> params); List<MlProjectDTO> list(Map<String, Object> params); MlProjectDTO get(String id); void save(MlProjectDTO dto); void update(MlProjectDTO dto); void delete(String id); PageData<MlModelDTO> getProjectModel(Map<String, Object> params); CommonResult<String> publish(Map<String, Object> params); } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/service/impl/MlModelMethodServiceImpl.java
对比新文件 @@ -0,0 +1,60 @@ package com.iailab.module.model.matlab.service.impl; import com.iailab.framework.common.service.impl.BaseServiceImpl; import com.iailab.framework.common.util.object.ConvertUtils; import com.iailab.module.model.matlab.dao.MlModelMethodDao; import com.iailab.module.model.matlab.dto.MlModelMethodDTO; import com.iailab.module.model.matlab.entity.MlModelMethodEntity; import com.iailab.module.model.matlab.entity.MlModelMethodSettingEntity; import com.iailab.module.model.matlab.service.MlModelMethodService; import com.iailab.module.model.matlab.service.MlModelMethodSettingService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.util.*; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ @Service public class MlModelMethodServiceImpl extends BaseServiceImpl<MlModelMethodDao, MlModelMethodEntity> implements MlModelMethodService { @Autowired private MlModelMethodSettingService mlModelMethodSettingService; @Override public void insertList(List<MlModelMethodDTO> list, String modelId) { List<MlModelMethodEntity> methodEntities = new ArrayList<>(); List<MlModelMethodSettingEntity> settingEntities = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { MlModelMethodEntity entity = ConvertUtils.sourceToTarget(list.get(i), MlModelMethodEntity.class); String methodId = UUID.randomUUID().toString(); entity.setId(methodId); entity.setMlModelId(modelId); entity.setSort(i); methodEntities.add(entity); if (!CollectionUtils.isEmpty(list.get(i).getMethodSettings())) { List<MlModelMethodSettingEntity> settingEntityList = ConvertUtils.sourceToTarget(list.get(i).getMethodSettings(), MlModelMethodSettingEntity.class); for (int j = 0; j < settingEntityList.size(); j++) { MlModelMethodSettingEntity mlModelMethodSettingEntity = settingEntityList.get(j); mlModelMethodSettingEntity.setId(UUID.randomUUID().toString()); mlModelMethodSettingEntity.setMlModelMethodId(methodId); mlModelMethodSettingEntity.setSort(j); settingEntities.add(mlModelMethodSettingEntity); } } } baseDao.insert(methodEntities); mlModelMethodSettingService.insertList(settingEntities); } @Override public void deleteModelMethod(String modelId) { Map<String,Object> map = new HashMap<>(); map.put("ml_model_id", modelId); baseDao.deleteByMap(map); } } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/service/impl/MlModelMethodSettingServiceImpl.java
对比新文件 @@ -0,0 +1,25 @@ package com.iailab.module.model.matlab.service.impl; import com.iailab.framework.common.service.impl.BaseServiceImpl; import com.iailab.module.model.matlab.dao.MlModelMethodSettingDao; import com.iailab.module.model.matlab.entity.MlModelMethodSettingEntity; import com.iailab.module.model.matlab.service.MlModelMethodSettingService; import org.springframework.stereotype.Service; import java.util.List; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ @Service public class MlModelMethodSettingServiceImpl extends BaseServiceImpl<MlModelMethodSettingDao, MlModelMethodSettingEntity> implements MlModelMethodSettingService { @Override public void insertList(List<MlModelMethodSettingEntity> settingEntities) { baseDao.insert(settingEntities); } } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/service/impl/MlModelServiceImpl.java
对比新文件 @@ -0,0 +1,287 @@ package com.iailab.module.model.matlab.service.impl; import cn.hutool.cache.CacheUtil; import cn.hutool.cache.impl.FIFOCache; import cn.hutool.core.io.FileUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.baomidou.dynamic.datasource.annotation.DSTransactional; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.iailab.framework.common.exception.enums.GlobalErrorCodeConstants; 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.object.ConvertUtils; import com.iailab.framework.security.core.util.SecurityFrameworkUtils; import com.iailab.framework.tenant.core.context.TenantContextHolder; import com.iailab.module.model.common.utils.DateUtils; import com.iailab.module.model.matlab.common.exceptions.IllegalityJarException; import com.iailab.module.model.matlab.common.utils.MatlabUtils; import com.iailab.module.model.matlab.dao.MlModelDao; import com.iailab.module.model.matlab.dto.MatlabJarFileInfoDTO; import com.iailab.module.model.matlab.dto.MatlabRunDTO; import com.iailab.module.model.matlab.dto.MlModelDTO; import com.iailab.module.model.matlab.entity.MlModelEntity; import com.iailab.module.model.matlab.service.MlModelMethodService; import com.iailab.module.model.matlab.service.MlModelService; import com.iailab.module.model.mpk.common.MdkConstant; import com.iailab.module.model.mpk.common.utils.Readtxt; import com.mathworks.toolbox.javabuilder.MWStructArray; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.net.URLClassLoader; import java.util.*; import static com.iailab.framework.common.pojo.CommonResult.error; import static com.iailab.framework.common.pojo.CommonResult.success; /** * * * @author Dzd * @since 1.0.0 2025-02-08 */ @Slf4j @Service public class MlModelServiceImpl extends BaseServiceImpl<MlModelDao, MlModelEntity> implements MlModelService { @Value("${mablab.bak-file-path}") private String mablabBakFilePath; @Autowired private MlModelMethodService mlModelMethodService; // 先进先出缓存 临时保存导入的数据 private static FIFOCache<String, String> cache = CacheUtil.newFIFOCache(100); @Override public PageData<MlModelDTO> page(Map<String, Object> params) { IPage<MlModelEntity> page = baseDao.selectPage( getPage(params, "create_date", false), getWrapper(params) ); return getPageData(page, MlModelDTO.class); } @Override public List<MlModelDTO> list(Map<String, Object> params) { List<MlModelDTO> list = baseDao.list(params); return list; } private QueryWrapper<MlModelEntity> getWrapper(Map<String, Object> params) { String modelName = (String) params.get("modelName"); String modelFileName = (String) params.get("modelFileName"); QueryWrapper<MlModelEntity> wrapper = new QueryWrapper<>(); wrapper.like(StringUtils.isNotBlank(modelName), "model_name", modelName) .like(StringUtils.isNotBlank(modelFileName), "model_file_name", modelFileName); return wrapper; } @Override public MlModelDTO get(String id) { MlModelDTO entity = baseDao.get(id); return entity; } @Override @DSTransactional(rollbackFor = Exception.class) public void save(MlModelDTO dto) { MlModelEntity entity = ConvertUtils.sourceToTarget(dto, MlModelEntity.class); entity.setId(UUID.randomUUID().toString()); entity.setModelFilePath(dto.getModelFilePath().trim()); entity.setModelFileName(dto.getModelFileName().trim()); entity.setCreator(SecurityFrameworkUtils.getLoginUserId()); entity.setCreateDate(new Date()); insert(entity); mlModelMethodService.insertList(dto.getModelMethods(), entity.getId()); saveJarFile(dto.getModelFilePath(),dto.getModelFileName()); } @Override @DSTransactional(rollbackFor = Exception.class) public void update(MlModelDTO dto) { MlModelEntity entity = ConvertUtils.sourceToTarget(dto, MlModelEntity.class); entity.setUpdater(SecurityFrameworkUtils.getLoginUserId()); entity.setUpdateDate(new Date()); updateById(entity); mlModelMethodService.deleteModelMethod(entity.getId()); mlModelMethodService.insertList(dto.getModelMethods(), entity.getId()); saveJarFile(dto.getModelFilePath(),dto.getModelFileName()); } /** * @description: 保存最新jar文件,用于测试运行 * @author: dzd * @date: 2025/2/24 16:25 **/ private void saveJarFile(String modelFilePath,String modelFileName) { String matlabTenantBakFilePath = getMatlabTenantBakFilePath(); String jarBakPath = matlabTenantBakFilePath + File.separator + MdkConstant.JAR + File.separator + modelFileName + ".jar"; FileUtil.copy(modelFilePath, jarBakPath, true); } @Override @DSTransactional(rollbackFor = Exception.class) public void delete(String id) { //删除源文件 MlModelEntity MlModelEntity = selectById(id); if (StringUtils.isNoneBlank(MlModelEntity.getModelFilePath())) { File mpkFile = new File(MlModelEntity.getModelFilePath()); if (mpkFile.exists()) { mpkFile.delete(); log.info("删除源文件备份文件:" + MlModelEntity.getModelFilePath()); } } //删除 会级联删除掉关联表 deleteById(id); } @Override public MatlabJarFileInfoDTO uploadJarFile(MultipartFile file) throws IllegalityJarException { String matlabTenantBakFilePath = getMatlabTenantBakFilePath(); File bakDir = new File(matlabTenantBakFilePath); String jarName = null; File jarBakFile = null; try { String fileName = file.getOriginalFilename(); jarName = fileName.substring(0, fileName.lastIndexOf(".")); String pyName_time = jarName + "_" + DateUtils.format(new Date(),DateUtils.DATE_TIME_STRING); jarBakFile = new File(bakDir.getAbsolutePath() + File.separator + pyName_time + ".jar"); file.transferTo(jarBakFile); } catch (IOException e) { throw new RuntimeException("保存算法封装jar文件失败!"); } //解析jar info MatlabJarFileInfoDTO result = new MatlabJarFileInfoDTO(); result.setFilePath(jarBakFile.getAbsolutePath()); result.setFileName(jarName); result.setClassInfos(MatlabUtils.parseJarInfo(jarBakFile.getAbsolutePath(),jarName)); return result; } @Override public CommonResult<String> test(MatlabRunDTO dto) { String matlabTenantBakFilePath = getMatlabTenantBakFilePath(); Class<?> clazz; URLClassLoader classLoader; try { File jarFile = new File(matlabTenantBakFilePath + File.separator + MdkConstant.JAR + File.separator + dto.getModelFileName() + ".jar"); if (!jarFile.exists()) { throw new RuntimeException("jar包不存在,请检查。jarPath:" + jarFile.getAbsolutePath()); } // 加载jar包 classLoader = MatlabUtils.loadJar(null,jarFile.getAbsolutePath()); // 实现类 clazz = classLoader.loadClass(dto.getClassName()); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("加载运行环境失败。"); } try { List<String> uuids = dto.getUuids(); Object[] paramsValueArray = new Object[uuids.size() + 1]; try { for (int i = 0; i < uuids.size(); i++) { String uuid = uuids.get(i); if (!cache.containsKey(uuid)) { return error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),"请重新导入模型参数"); } JSONArray jsonArray = JSON.parseArray(cache.get(uuid)); double[][] data = new double[jsonArray.size()][jsonArray.getJSONArray(0).size()]; for (int j = 0; j < jsonArray.size(); j++) { for (int k = 0; k < jsonArray.getJSONArray(j).size(); k++) { data[j][k] = jsonArray.getJSONArray(j).getDoubleValue(k); } } paramsValueArray[i] = data; } } catch (Exception e) { e.printStackTrace(); return error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),"模型参数错误,请检查!"); } MWStructArray mwStructArraySetting; try { HashMap<String, Object> settings = MatlabUtils.handleModelSettings(dto.getModelSettings()); mwStructArraySetting = MatlabUtils.convertMapToStruct(settings); paramsValueArray[uuids.size()] = mwStructArraySetting; } catch (Exception e) { e.printStackTrace(); return error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),"模型设置错误,请检查!"); } Class<?>[] paramsArray = new Class[2]; paramsArray[0] = int.class; paramsArray[1] = Object[].class; Object[] objects = (Object[]) clazz.getDeclaredMethod(dto.getMethodName(), paramsArray).invoke(clazz.newInstance(), new Object[]{dto.getOutLength(), paramsValueArray}); mwStructArraySetting.dispose(); Map<String, Object> result = MatlabUtils.convertStructToMap((MWStructArray) objects[0]); return success(JSON.toJSONString(result)); } catch (Exception ex) { ex.printStackTrace(); return error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"运行异常"); } finally { if (classLoader != null) { MatlabUtils.unloadJar(classLoader); } } } @Override public List<HashMap<String, Object>> importData(MultipartFile file) throws IOException { List<double[][]> datas = Readtxt.readMethodExcel(file); List<HashMap<String,Object>> result = new ArrayList<>(); if (!CollectionUtils.isEmpty(datas)) { for (double[][] data : datas) { if (data.length > 0) { HashMap<String,Object> map = new HashMap<>(); String uuid = UUID.randomUUID().toString(); map.put("uuid",uuid); map.put("data", JSON.toJSONString(data)); cache.put(uuid,JSON.toJSONString(data)); result.add(map); } } } return result; } private String getMatlabTenantBakFilePath() { Long tenantId = TenantContextHolder.getTenantId(); // 备份文件夹 租户隔离 String matlabTenantBakFilePath = mablabBakFilePath + File.separator + tenantId; File bakDir = new File(matlabTenantBakFilePath); if (!bakDir.exists()) { bakDir.mkdirs(); } return matlabTenantBakFilePath; } } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/service/impl/MlProjectModelServiceImpl.java
对比新文件 @@ -0,0 +1,70 @@ package com.iailab.module.model.matlab.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.iailab.framework.common.service.impl.BaseServiceImpl; import com.iailab.framework.common.util.object.ConvertUtils; import com.iailab.module.model.matlab.dao.MlProjectModelDao; import com.iailab.module.model.matlab.dto.MlModelDTO; import com.iailab.module.model.matlab.dto.MlProjectModelDTO; import com.iailab.module.model.matlab.entity.MlProjectModelEntity; import com.iailab.module.model.matlab.service.MlProjectModelService; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; /** * @description: * @author: dzd * @date: 2024/8/22 14:41 **/ @Service public class MlProjectModelServiceImpl extends BaseServiceImpl<MlProjectModelDao, MlProjectModelEntity> implements MlProjectModelService { @Override public List<MlProjectModelDTO> list(Map<String, Object> params) { List<MlProjectModelEntity> entityList = baseDao.selectList(getWrapper(params)); return ConvertUtils.sourceToTarget(entityList, MlProjectModelDTO.class); } @Override public void deleteByMap(Map<String,Object> map) { baseDao.delete(getWrapper(map)); } @Override public void create(List<MlModelDTO> models, String projectId) { List<MlProjectModelEntity> list = new ArrayList<>(models.size()); for (MlModelDTO model : models) { MlProjectModelEntity projectModel = new MlProjectModelEntity(); projectModel.setId(UUID.randomUUID().toString()); projectModel.setProjectId(projectId); projectModel.setModelId(model.getId()); list.add(projectModel); } baseDao.insert(list); } @Override public List<MlModelDTO> getProjectModel(Map<String, Object> params) { return baseDao.getProjectModel(params); } public QueryWrapper<MlProjectModelEntity> getWrapper(Map<String, Object> params){ String id = (String)params.get("id"); String projectId = (String)params.get("projectId"); String modelId = (String)params.get("modelId"); QueryWrapper<MlProjectModelEntity> wrapper = new QueryWrapper<>(); wrapper.eq(StringUtils.isNotBlank(id), "id", id) .eq(StringUtils.isNotBlank(projectId), "project_id", projectId) .eq(StringUtils.isNotBlank(modelId),"model_id",modelId); return wrapper; } } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/matlab/service/impl/MlProjectServiceImpl.java
对比新文件 @@ -0,0 +1,192 @@ package com.iailab.module.model.matlab.service.impl; import cn.hutool.core.io.FileUtil; import com.baomidou.dynamic.datasource.annotation.DSTransactional; 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.object.ConvertUtils; import com.iailab.module.model.matlab.common.utils.MatlabUtils; import com.iailab.module.model.matlab.dao.MlModelDao; import com.iailab.module.model.matlab.dao.MlProjectDao; import com.iailab.module.model.matlab.dto.MlModelDTO; import com.iailab.module.model.matlab.dto.MlProjectDTO; import com.iailab.module.model.matlab.dto.MlProjectModelDTO; import com.iailab.module.model.matlab.entity.MlProjectEntity; import com.iailab.module.model.matlab.service.MlProjectModelService; import com.iailab.module.model.matlab.service.MlProjectService; import com.iailab.module.model.mpk.common.MdkConstant; import com.iailab.module.model.mpk.common.utils.DllUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.File; import java.net.URLClassLoader; import java.util.*; import java.util.stream.Collectors; /** * @description: * @author: dzd * @date: 2025/2/25 14:45 **/ @Service @Slf4j public class MlProjectServiceImpl extends BaseServiceImpl<MlProjectDao, MlProjectEntity> implements MlProjectService { @Autowired MlProjectModelService mlProjectModelService; @Autowired MlModelDao mlModelDao; @Value("${mablab.bak-file-path}") private String mablabBakFilePath; @Override public PageData<MlProjectDTO> page(Map<String, Object> params) { IPage<MlProjectEntity> page = baseDao.selectPage( getPage(params, null, false), getWrapper(params) ); return getPageData(page, MlProjectDTO.class); } @Override public List<MlProjectDTO> list(Map<String, Object> params) { List<MlProjectEntity> entityList = baseDao.selectList(getWrapper(params).orderByDesc("create_time")); return ConvertUtils.sourceToTarget(entityList, MlProjectDTO.class); } @Override public MlProjectDTO get(String id) { MlProjectEntity entity = baseDao.selectById(id); MlProjectDTO dto = ConvertUtils.sourceToTarget(entity, MlProjectDTO.class); Map<String,Object> map = new HashMap<>(); map.put("projectId",id); List<MlProjectModelDTO> projectModelList = mlProjectModelService.list(map); dto.setModels(projectModelList.stream().map(e -> { MlModelDTO mlModelDTO = new MlModelDTO(); mlModelDTO.setId(e.getModelId()); return mlModelDTO; }).collect(Collectors.toList())); return dto; } @Override @DSTransactional(rollbackFor = Exception.class) public void save(MlProjectDTO dto) { MlProjectEntity entity = ConvertUtils.sourceToTarget(dto, MlProjectEntity.class); String projectId = UUID.randomUUID().toString(); entity.setId(projectId); entity.setCreateTime(new Date()); insert(entity); //关联模型 List<MlModelDTO> models = dto.getModels(); if (CollectionUtils.isNotEmpty(models)) { mlProjectModelService.create(models,projectId); } } @Override @DSTransactional(rollbackFor = Exception.class) public void update(MlProjectDTO dto) { MlProjectEntity entity = ConvertUtils.sourceToTarget(dto, MlProjectEntity.class); entity.setUpdateTime(new Date()); updateById(entity); String projectId = dto.getId(); //删除关联 Map<String,Object> map = new HashMap<>(); map.put("projectId",projectId); mlProjectModelService.deleteByMap(map); //关联模型 List<MlModelDTO> models = dto.getModels(); if (CollectionUtils.isNotEmpty(models)) { mlProjectModelService.create(models,projectId); } } @Override @DSTransactional(rollbackFor = Exception.class) public void delete(String id) { //删除 (级联删除) baseDao.deleteById(id); } @Override public PageData<MlModelDTO> getProjectModel(Map<String, Object> params) { String projectId = (String) params.get("projectId"); int total = mlModelDao.getProjectModelCount(projectId); if (total == 0) { return new PageData<>(new ArrayList<>(), 0); } int page = Integer.parseInt((String) params.get("page")); int pageSize = Integer.parseInt((String) params.get("pageSize")); int offset = (page - 1)*pageSize; params.put("offset",offset); params.put("pageSize",pageSize); List<MlModelDTO> list = mlModelDao.getProjectModel(params); return new PageData<>(list,total); } @Override public CommonResult<String> publish(Map<String, Object> params) { String projectId = (String) params.get("projectId"); // 卸载上次发布的classloader 并删除发布备份文件 MatlabUtils.removeClassLoaderCache(projectId); MatlabUtils.removeOldFile(mablabBakFilePath + File.separator + MdkConstant.PROJECT_PUBLISH,projectId); // 查询关联模型 List<MlModelDTO> list = mlProjectModelService.getProjectModel(params); // 将模型文件备份到发布文件 String[] jarFilePaths = new String[list.size()]; for (int i = 0; i < list.size(); i++) { MlModelDTO mlModelDTO = list.get(i); String jarFilePath = mablabBakFilePath + File.separator + MdkConstant.PROJECT_PUBLISH + File.separator + projectId + MdkConstant.SPLIT + mlModelDTO.getId() + ".jar"; FileUtil.copy(mlModelDTO.getModelFilePath(),jarFilePath,true); jarFilePaths[i] = jarFilePath; } // 加载新的jar,将classloader存入缓存 URLClassLoader urlClassLoader = null; try { // 加载新的jar urlClassLoader = MatlabUtils.loadJar(projectId,jarFilePaths); } catch (Exception e) { throw new RuntimeException("加载新的jar异常",e); } return CommonResult.success(); } public QueryWrapper<MlProjectEntity> getWrapper(Map<String, Object> params){ String id = (String)params.get("id"); String projectName = (String)params.get("projectName"); String projectCode = (String)params.get("projectCode"); QueryWrapper<MlProjectEntity> wrapper = new QueryWrapper<>(); wrapper.eq(StringUtils.isNotBlank(id), "id", id) .like(StringUtils.isNotBlank(projectName),"project_name",projectName) .like(StringUtils.isNotBlank(projectCode),"project_code",projectCode); return wrapper; } } iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/service/impl/MpkFileServiceImpl.java
@@ -347,7 +347,7 @@ String jarSavePath = pkgJar(dirPath.getAbsolutePath()); //备份jar文件,用于后续运行 String jarBakPath = mpkTenantBakFilePath + File.separator + MdkConstant.JAR + File.separator + entity.getPyName() + ".jar"; FileUtil.mkParentDirs(dllBakPath); FileUtil.mkParentDirs(jarBakPath); FileUtil.copy(jarSavePath, jarBakPath, true); // 打zip包 String zipPath = mpkTenantBakFilePath + File.separator + zipFileName; iailab-module-model/iailab-module-model-biz/src/main/resources/mapper/matlab/MlModelDao.xml
对比新文件 @@ -0,0 +1,120 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.iailab.module.model.matlab.dao.MlModelDao"> <resultMap type="com.iailab.module.model.matlab.dto.MlModelDTO" id="mlModelMap"> <result property="id" column="id"/> <result property="modelName" column="model_name"/> <result property="modelFileName" column="model_file_name"/> <result property="modelFilePath" column="model_file_path"/> <result property="modelType" column="model_type"/> <result property="matlabPlatform" column="matlab_platform"/> <result property="matlabVersion" column="matlab_version"/> <result property="remark" column="remark"/> <result property="creator" column="creator"/> <result property="createDate" column="create_date"/> <result property="updater" column="updater"/> <result property="updateDate" column="update_date"/> <collection property="modelMethods" ofType="com.iailab.module.model.matlab.dto.MlModelMethodDTO"> <id property="id" column="method_id"/> <result property="className" column="class_name"/> <result property="methodName" column="method_name"/> <result property="dataLength" column="data_length"/> <result property="outLength" column="out_length"/> <collection property="methodSettings" ofType="com.iailab.module.model.matlab.dto.MlModelMethodSettingDTO"> <id property="id" column="setting_id"/> <result property="name" column="setting_name"/> <result property="settingKey" column="setting_key"/> <result property="settingValue" column="setting_value"/> <result property="valueType" column="value_type"/> </collection> </collection> </resultMap> <select id="list" resultMap="mlModelMap" parameterType="java.util.Map"> SELECT a.*, b.id method_id, b.class_name, b.method_name, b.data_length, b.out_length, c.id setting_id, c.NAME setting_name, c.setting_key, c.setting_value, c.value_type FROM t_ml_model a LEFT JOIN t_ml_model_method b ON a.id = b.ml_model_id LEFT JOIN t_ml_model_method_setting c ON b.id = c.ml_model_method_id <where> <if test="params.modelType != null and params.modelType != ''"> AND a.model_type = #{params.modelType} </if> </where> ORDER BY a.create_date, b.sort, c.sort </select> <select id="get" resultMap="mlModelMap" parameterType="java.lang.String"> SELECT a.*, b.id method_id, b.class_name, b.method_name, b.data_length, b.out_length, c.id setting_id, c.NAME setting_name, c.setting_key, c.setting_value, c.value_type FROM t_ml_model a LEFT JOIN t_ml_model_method b ON a.id = b.ml_model_id LEFT JOIN t_ml_model_method_setting c ON b.id = c.ml_model_method_id WHERE a.id = #{id} ORDER BY b.sort,c.sort </select> <select id="getProjectModelCount" resultType="java.lang.Integer" parameterType="java.lang.String"> SELECT count(*) FROM t_ml_project_model WHERE project_id = #{projectId} </select> <select id="getProjectModel" resultMap="mlModelMap" parameterType="java.util.Map"> SELECT t3.*, t4.id method_id, t4.class_name, t4.method_name, t4.data_length, t4.out_length, t5.id setting_id, t5.setting_key, t5.name setting_name, t5.setting_value, t5.value_type FROM ( SELECT t2.* FROM t_ml_project_model t1 LEFT JOIN t_ml_model t2 ON t1.model_id = t2.id WHERE t1.project_id = #{params.projectId} <if test="params.modelFileName != null and params.modelFileName != ''"> AND t2.model_file_name LIKE CONCAT('%',#{params.modelFileName},'%') </if> ORDER BY t2.create_date DESC LIMIT #{params.offset},#{params.pageSize} ) t3 LEFT JOIN t_ml_model_method t4 ON t3.id = t4.ml_model_id LEFT JOIN t_ml_model_method_setting t5 ON t4.id = t5.ml_model_method_id </select> </mapper> iailab-module-model/iailab-module-model-biz/src/main/resources/mapper/matlab/MlProjectModelDao.xml
对比新文件 @@ -0,0 +1,14 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.iailab.module.model.matlab.dao.MlProjectModelDao"> <select id="getProjectModel" resultType="com.iailab.module.model.matlab.dto.MlModelDTO"> SELECT t2.id, t2.model_file_path FROM t_ml_project_model t1 LEFT JOIN t_ml_model t2 ON t1.model_id = t2.id WHERE t1.project_id = #{params.projectId} </select> </mapper>