houzhongjian
2024-12-04 a82313d17b2b5d1c02e880122efc1b701c401dcf
iailab-module-model/iailab-module-model-biz/src/main/java/com/iailab/module/model/mpk/service/impl/MpkFileServiceImpl.java
@@ -20,9 +20,9 @@
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;
import com.iailab.module.model.mpk.dto.MethodSettingDTO;
import com.iailab.module.model.mpk.dto.ModelMethodDTO;
import com.iailab.module.model.mpk.dto.MpkFileDTO;
import com.iailab.module.model.mpk.dto.ProjectPackageHistoryDTO;
import com.iailab.module.model.mpk.entity.GeneratorCodeHistoryEntity;
import com.iailab.module.model.mpk.entity.MpkFileEntity;
import com.iailab.module.model.mpk.entity.ProjectPackageHistoryEntity;
@@ -99,7 +99,7 @@
        String label = (String) params.get("label");
        QueryWrapper<MpkFileEntity> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(pyName), "py_name", pyName)
        wrapper.like(StringUtils.isNotBlank(pyName), "py_chinese_name", pyName)
                .eq(StringUtils.isNotBlank(pyType), "py_type", pyType)
                .like(StringUtils.isNotBlank(remark), "remark", remark);
@@ -129,30 +129,82 @@
        entity.setCreator(SecurityFrameworkUtils.getLoginUserId());
        entity.setCreateDate(new Date());
        insert(entity);
        modelMethodService.insertList(dto.getModelMethods(), entity.getId());
        // 替换环境变量MDK_PKGS下的py文件
//        String mdkPkgs = System.getenv("MDK_PKGS");
//        String pyFilePath = mdkPkgs + File.separator + entity.getPyModule().replace(".", File.separator) + File.separator + entity.getPyName() + ".pyd";
//        FileUtil.mkParentDirs(pyFilePath);
//        FileUtil.copy(entity.getFilePath(), pyFilePath, true);
        // 将备份的pyd文件,转移到MDK_PKGS环境变量下,并添加方法的默认参数(pyFile,模型路径)
        String mdkPkgs = System.getenv("MDK_PKGS");
        String fileName = entity.getFilePath().substring(entity.getFilePath().lastIndexOf("\\") + 1,entity.getFilePath().lastIndexOf(".pyd"));
        String pyFilePath = mdkPkgs + File.separator + entity.getPyModule().replace(".", File.separator) + File.separator + fileName + ".pyd";
        FileUtil.mkParentDirs(pyFilePath);
        FileUtil.copy(entity.getFilePath(), pyFilePath, true);
        // 添加参数
        for (ModelMethodDTO method : dto.getModelMethods()) {
            List<MethodSettingDTO> methodSettings = method.getMethodSettings();
            if (methodSettings.stream().anyMatch(e -> e.getSettingKey().equals(MdkConstant.PY_FILE_KEY))) {
                methodSettings.forEach(e -> {
                    if (e.getSettingKey().equals(MdkConstant.PY_FILE_KEY)) {
                        e.setValue(entity.getPyModule() + "." + fileName);
                    }
                });
            }else {
                MethodSettingDTO setting = new MethodSettingDTO();
                setting.setId(UUID.randomUUID().toString());
                setting.setMethodId(method.getId());
                setting.setSettingKey(MdkConstant.PY_FILE_KEY);
                setting.setValue(entity.getPyModule() + "." + fileName);
                setting.setName("模型路径");
                setting.setType("input");
                setting.setValueType("string");
                methodSettings.add(setting);
            }
        }
        modelMethodService.insertList(dto.getModelMethods(), entity.getId());
    }
    @Override
    @DSTransactional(rollbackFor = Exception.class)
    public void update(MpkFileDTO dto) {
        // 添加方法的默认参数(pyFile,模型路径)
        String mdkPkgs = System.getenv("MDK_PKGS");
        String fileName = dto.getFilePath().substring(dto.getFilePath().lastIndexOf("\\") + 1,dto.getFilePath().lastIndexOf(".pyd"));
        String pyFilePath = mdkPkgs + File.separator + dto.getPyModule().replace(".", File.separator) + File.separator + fileName + ".pyd";
        // 判断文件是否存在,不存在的话将备份的pyd文件,转移到MDK_PKGS环境变量下
        File pyFile = new File(pyFilePath);
        if (!pyFile.exists()) {
            FileUtil.mkParentDirs(pyFilePath);
            FileUtil.copy(dto.getFilePath(), pyFilePath, true);
        }
        // 添加/修改参数
        for (ModelMethodDTO method : dto.getModelMethods()) {
            List<MethodSettingDTO> methodSettings = method.getMethodSettings();
            if (methodSettings.stream().anyMatch(e -> e.getSettingKey().equals(MdkConstant.PY_FILE_KEY))) {
                methodSettings.forEach(e -> {
                    if (e.getSettingKey().equals(MdkConstant.PY_FILE_KEY)) {
                        e.setValue(dto.getPyModule() + "." + fileName);
                    }
                });
            }else {
                MethodSettingDTO setting = new MethodSettingDTO();
                setting.setId(UUID.randomUUID().toString());
                setting.setMethodId(method.getId());
                setting.setSettingKey(MdkConstant.PY_FILE_KEY);
                setting.setValue(dto.getPyModule() + "." + fileName);
                setting.setName("模型路径");
                setting.setType("input");
                setting.setValueType("string");
                methodSettings.add(setting);
            }
        }
        MpkFileEntity entity = ConvertUtils.sourceToTarget(dto, MpkFileEntity.class);
        entity.setUpdater(SecurityFrameworkUtils.getLoginUserId());
        entity.setUpdateDate(new Date());
        updateById(entity);
        modelMethodService.deleteModelMethod(entity.getId());
        modelMethodService.insertList(dto.getModelMethods(), entity.getId());
        // 替换环境变量MDK_PKGS下的py文件
//        String mdkPkgs = System.getenv("MDK_PKGS");
//        String pyFilePath = mdkPkgs + File.separator + entity.getPyModule().replace(".", File.separator) + File.separator + entity.getPyName() + ".pyd";
//        FileUtil.mkParentDirs(pyFilePath);
//        FileUtil.copy(entity.getFilePath(), pyFilePath, true);
    }
    @Override
@@ -246,6 +298,11 @@
        //生成Jni.h文件
        File jniHFile = new File(dirPath.getAbsolutePath() + File.separator + MdkConstant.C + File.separator + entity.getPyName() + "Jni.h");
        GenUtils.drawTemplate("Jni.h.vm", dataContext, jniHFile);
        // 添加python源文件
        String pyFilePath = dirPath.getAbsolutePath() + File.separator + MdkConstant.ALGS + File.separator + entity.getPyModule().replace(".", File.separator) + File.separator + entity.getFilePath().substring(entity.getFilePath().lastIndexOf("\\"));
        FileUtil.mkParentDirs(pyFilePath);
        FileUtil.copy(entity.getFilePath(), pyFilePath, true);
        // 资源文件
        FileUtil.copy(mpkResources + File.separator + "libs", dirPath.getAbsolutePath(), true);
@@ -377,7 +434,7 @@
            GenUtils.drawTemplate("Jni.h.vm", dataContext, jniHFile);
            // 添加python源文件
            String pyFilePath = dirPath.getAbsolutePath() + File.separator + MdkConstant.ALGS + File.separator + entity.getPyModule().replace(".", File.separator) + File.separator + entity.getPyName() + ".pyd";
            String pyFilePath = dirPath.getAbsolutePath() + File.separator + MdkConstant.ALGS + File.separator + entity.getPyModule().replace(".", File.separator) + File.separator + entity.getFilePath().substring(entity.getFilePath().lastIndexOf("\\"));
            FileUtil.mkParentDirs(pyFilePath);
            FileUtil.copy(entity.getFilePath(), pyFilePath, true);
        }
@@ -492,26 +549,87 @@
        Long tenantId = TenantContextHolder.getTenantId();
        // 备份文件 租户隔离
        String mpkTenantBakFilePath = mpkBakFilePath + File.separator + tenantId;
        File dir = new File(mpkTenantBakFilePath);
        if (!dir.exists()) {
            dir.mkdirs();
        File bakDir = new File(mpkTenantBakFilePath);
        if (!bakDir.exists()) {
            bakDir.mkdirs();
        }
        //临时文件夹
        File tempDir = null;
        try {
            tempDir = Files.createTempDirectory("pyFileTmp").toFile();
            log.info("生成临时文件夹," + tempDir.getAbsolutePath());
        } catch (IOException e) {
            throw new RuntimeException("创建临时文件夹异常",e);
        }
        String fileName = file.getOriginalFilename();
        String fileSuffix = fileName.substring(fileName.lastIndexOf("."));
        File saveFile = new File(dir.getAbsolutePath() + File.separator + UUID.randomUUID() + fileSuffix);
        String pyName = fileName.substring(0, fileName.lastIndexOf("."));
        String pyName_uuTime = pyName + "_" + new Date().getTime();
        saveFile.createNewFile();
        // 保存
        file.transferTo(saveFile);
        File pydBakFile = new File(bakDir.getAbsolutePath() + File.separator + pyName_uuTime + ".pyd");
        try {
            // py文件存入临时文件夹
            File saveFile = new File(tempDir.getAbsolutePath() + File.separator + fileName);
            saveFile.createNewFile();
            file.transferTo(saveFile);
            // 临时文件夹中生成pyd文件
            // 生成setup.py文件
            createSetUpFile(tempDir.getAbsolutePath(),fileName,pyName_uuTime);
            // 执行cmd命令编译pyd文件
            createPydFile(tempDir.getAbsolutePath());
            // 临时文件夹中pyd文件移到dir下,修改为uuid.pyd
            File pydFile = new File(tempDir.getAbsolutePath() + File.separator + pyName_uuTime + MdkConstant.PYD_SUFFIX);
            if (!pydFile.exists()) {
                throw new RuntimeException("编译pyd文件失败!");
            }
            log.info("备份pyd文件," + pydBakFile.getAbsolutePath());
            FileUtil.copy(pydFile,pydBakFile,true);
        } catch (Exception e) {
            throw new RuntimeException("编译pyd文件异常");
        } finally {
            if (tempDir.exists()) {
                tempDir.delete();
            }
        }
        Map<String, String> result = new HashMap<>(2);
        result.put("filePath", saveFile.getAbsolutePath());
        result.put("fileName", fileName);
        result.put("filePath", pydBakFile.getAbsolutePath());
        result.put("fileName", pyName);
        return result;
    }
    private void createPydFile(String dir) {
        try {
            String command = "python setup.py build_ext --inplace";
            log.info("执行cmd命令编译pyd:" + command);
            ProcessBuilder builder = new ProcessBuilder("cmd", "/c", command);
            builder.directory(new File(dir));  // 设置工作目录
            builder.redirectErrorStream(true);  // 将错误输出和标准输出合并
            Process process = builder.start();
            // 获取命令输出结果
            InputStream inputStream = process.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "GBK")); // 设置编码为GBK
            String line;
            while ((line = reader.readLine()) != null) {
                log.info(line);
            }
            // 等待命令执行完成
            process.waitFor();
        } catch (Exception e) {
            throw new RuntimeException("执行cmd命令生成dll异常", e);
        }
    }
    private void createSetUpFile(String dir, String pyFileName, String pyName) {
        // 生成setup.py文件
        HashMap<String,Object> map = new HashMap<>();
        map.put("fileName",pyFileName);
        map.put("pyName",pyName);
        GenUtils.drawTemplate("setup.py.vm",map,new File(dir + File.separator + MdkConstant.SETUP_PY));
    }
    @Override
    public CommonResult<String> publish(Map<String, Object> params) {
        String historyId = (String) params.get("historyId");