dengzedong
2024-10-14 558ffc4bcaf7aa5c683e7c9ce01e971feb9e4d95
提交 | 用户 | 时间
449017 1 package com.iailab.module.model.mpk.service.impl;
D 2
3 import cn.hutool.core.io.FileUtil;
4 import cn.hutool.core.util.RuntimeUtil;
5 import cn.hutool.core.util.ZipUtil;
6 import com.alibaba.fastjson.JSON;
8b3ee3 7 import com.baomidou.dynamic.datasource.annotation.DSTransactional;
449017 8 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
D 9 import com.baomidou.mybatisplus.core.metadata.IPage;
10 import com.iailab.framework.common.page.PageData;
c12dae 11 import com.iailab.framework.common.pojo.CommonResult;
449017 12 import com.iailab.framework.common.service.impl.BaseServiceImpl;
D 13 import com.iailab.framework.common.util.date.DateUtils;
14 import com.iailab.framework.common.util.object.ConvertUtils;
15 import com.iailab.framework.security.core.util.SecurityFrameworkUtils;
558ffc 16 import com.iailab.framework.tenant.core.context.TenantContextHolder;
449017 17 import com.iailab.module.infra.api.config.ConfigApi;
D 18 import com.iailab.module.model.mpk.common.MdkConstant;
c12dae 19 import com.iailab.module.model.mpk.common.utils.DllUtils;
449017 20 import com.iailab.module.model.mpk.common.utils.GenUtils;
D 21 import com.iailab.module.model.mpk.dao.MpkFileDao;
1fea3e 22 import com.iailab.module.model.mpk.dto.GeneratorCodeHistoryDTO;
D 23 import com.iailab.module.model.mpk.dto.ModelMethodDTO;
24 import com.iailab.module.model.mpk.dto.MpkFileDTO;
25 import com.iailab.module.model.mpk.dto.ProjectPackageHistoryDTO;
26 import com.iailab.module.model.mpk.entity.GeneratorCodeHistoryEntity;
27 import com.iailab.module.model.mpk.entity.MpkFileEntity;
558ffc 28 import com.iailab.module.model.mpk.entity.ProjectPackageHistoryEntity;
1fea3e 29 import com.iailab.module.model.mpk.entity.ProjectPackageHistoryModelEntity;
449017 30 import com.iailab.module.model.mpk.service.*;
D 31 import lombok.extern.slf4j.Slf4j;
32 import org.apache.commons.io.FileUtils;
33 import org.apache.commons.lang3.StringUtils;
34 import org.apache.velocity.VelocityContext;
35 import org.apache.velocity.app.Velocity;
36 import org.springframework.beans.factory.annotation.Autowired;
a27351 37 import org.springframework.beans.factory.annotation.Value;
449017 38 import org.springframework.stereotype.Service;
D 39 import org.springframework.util.CollectionUtils;
40 import org.springframework.web.multipart.MultipartFile;
41
f7932f 42 import java.io.*;
c12dae 43 import java.net.URLClassLoader;
912a1e 44 import java.nio.file.Files;
449017 45 import java.util.*;
D 46 import java.util.stream.Collectors;
47
48 /**
49  * @author PanZhibao
50  * @Description
51  * @createTime 2024年08月14日
52  */
53 @Slf4j
54 @Service
0255ea 55 public class MpkFileServiceImpl extends BaseServiceImpl<MpkFileDao, MpkFileEntity> implements MpkFileService {
449017 56
D 57     @Autowired
58     private GeneratorCodeHistoryService generatorCodeHistoryService;
8b3ee3 59
449017 60     @Autowired
D 61     private ProjectPackageHistoryService projectPackageHistoryService;
8b3ee3 62
449017 63     @Autowired
D 64     private ModelMethodService modelMethodService;
8b3ee3 65
449017 66     @Autowired
D 67     private ProjectPackageHistoryModelService projectPackageHistoryModelService;
68
69     @Autowired
70     private ConfigApi configApi;
71
1fea3e 72     @Value("${mpk.bak-file-path}")
a27351 73     private String mpkBakFilePath;
1fea3e 74
D 75     @Value("${mpk.bak-resources}")
76     private String mpkResources;
449017 77
D 78     @Override
79     public PageData<MpkFileDTO> page(Map<String, Object> params) {
80         IPage<MpkFileEntity> page = baseDao.selectPage(
81                 getPage(params, "create_date", false),
82                 getWrapper(params)
83         );
84
85         return getPageData(page, MpkFileDTO.class);
86     }
87
88     @Override
89     public List<MpkFileDTO> list(Map<String, Object> params) {
90         List<MpkFileEntity> entityList = baseDao.selectList(getWrapper(params).orderByDesc("create_date"));
91
92         return ConvertUtils.sourceToTarget(entityList, MpkFileDTO.class);
93     }
94
8b3ee3 95     private QueryWrapper<MpkFileEntity> getWrapper(Map<String, Object> params) {
449017 96         String pyName = (String) params.get("pyName");
D 97         String pyType = (String) params.get("pyType");
98         String remark = (String) params.get("remark");
d8db4b 99         String label = (String) params.get("label");
449017 100
D 101         QueryWrapper<MpkFileEntity> wrapper = new QueryWrapper<>();
102         wrapper.like(StringUtils.isNotBlank(pyName), "py_name", pyName)
103                 .eq(StringUtils.isNotBlank(pyType), "py_type", pyType)
104                 .like(StringUtils.isNotBlank(remark), "remark", remark);
d8db4b 105
106         if (StringUtils.isNotBlank(label)) {
107             wrapper.and(w -> {
108                 w.eq(StringUtils.isNotBlank(label),"menu_name", label)
109                         .or().eq(StringUtils.isNotBlank(label),"group_name", label);
110             });
111         }
449017 112         return wrapper;
D 113     }
114
115     @Override
116     public MpkFileDTO get(String id) {
117         MpkFileDTO entity = baseDao.get(id);
118
119         return entity;
120     }
121
122     @Override
8b3ee3 123     @DSTransactional(rollbackFor = Exception.class)
449017 124     public void save(MpkFileDTO dto) {
D 125         MpkFileEntity entity = ConvertUtils.sourceToTarget(dto, MpkFileEntity.class);
8b3ee3 126         entity.setId(UUID.randomUUID().toString());
ed8ba3 127         entity.setPkgName(dto.getPkgName().trim());
128         entity.setFilePath(dto.getFilePath().trim());
449017 129         entity.setCreator(SecurityFrameworkUtils.getLoginUserId());
D 130         entity.setCreateDate(new Date());
131         insert(entity);
8b3ee3 132         modelMethodService.insertList(dto.getModelMethods(), entity.getId());
449017 133     }
D 134
135     @Override
8b3ee3 136     @DSTransactional(rollbackFor = Exception.class)
449017 137     public void update(MpkFileDTO dto) {
D 138         MpkFileEntity entity = ConvertUtils.sourceToTarget(dto, MpkFileEntity.class);
139         entity.setUpdater(SecurityFrameworkUtils.getLoginUserId());
140         entity.setUpdateDate(new Date());
141         updateById(entity);
8b3ee3 142         modelMethodService.deleteModelMethod(entity.getId());
143         modelMethodService.insertList(dto.getModelMethods(), entity.getId());
449017 144     }
D 145
146     @Override
8b3ee3 147     @DSTransactional(rollbackFor = Exception.class)
449017 148     public void delete(String id) {
D 149
150         //删除源文件
151         MpkFileEntity mpkFileEntity = selectById(id);
152         if (StringUtils.isNoneBlank(mpkFileEntity.getFilePath())) {
153             File mpkFile = new File(mpkFileEntity.getFilePath());
154             if (mpkFile.exists()) {
155                 mpkFile.delete();
156                 log.info("删除源文件备份文件:" + mpkFileEntity.getFilePath());
157             }
158         }
159
160         //删除备份文件
8b3ee3 161         Map<String, Object> map1 = new HashMap<>();
162         map1.put("mdkId", id);
449017 163         List<GeneratorCodeHistoryDTO> list = generatorCodeHistoryService.list(map1);
D 164         list.forEach(e -> {
165             File file = new File(e.getFilePath());
166             if (file.exists()) {
167                 file.delete();
168                 log.info("删除生成代码备份文件:" + e.getFilePath());
169             }
170         });
171
0255ea 172         //删除 会级联删除掉关联表
D 173         deleteById(id);
449017 174     }
D 175
176     @Override
177     public byte[] generatorCode(String id, String remark, String zipFileName) {
558ffc 178         Long tenantId = TenantContextHolder.getTenantId();
D 179         // 备份文件 租户隔离
180         String mpkTenantBakFilePath = mpkBakFilePath + File.separator + tenantId;
181
449017 182         MpkFileDTO entity = baseDao.get(id);
D 183         //生成代码
1fea3e 184         //设置velocity资源加载器
D 185         Properties prop = new Properties();
186         prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
187         Velocity.init(prop);
449017 188
1fea3e 189         //封装模板数据
D 190         Map<String, Object> map = new HashMap<>();
191         map.put("pkgName",entity.getPkgName());
192         map.put("modelMethods",entity.getModelMethods());
193         map.put("pyName",entity.getPyName());
194         map.put("pyModule",entity.getPyModule());
195
196         VelocityContext dataContext = new VelocityContext(map);
197
198         //临时文件夹
912a1e 199         File dirPath = null;
D 200         try {
201             dirPath = Files.createTempDirectory("generatorCodeTmp").toFile();
202             log.info("生成临时文件夹," + dirPath.getAbsolutePath());
203         } catch (IOException e) {
204             throw new RuntimeException("创建临时文件夹异常",e);
205         }
1fea3e 206
D 207         List<String> javaFilePaths = new ArrayList<>();
208         List<String> cppFilePaths = new ArrayList<>();
209
210         //生成java文件
211         File javaFile = new File(dirPath.getAbsolutePath() + File.separator + "IAILMDK" + File.separator + entity.getPkgName().replace(".", File.separator) + File.separator + entity.getPyName() + ".java");
212         GenUtils.drawTemplate("abstract.java.vm", dataContext, javaFile);
213         javaFilePaths.add(javaFile.getAbsolutePath());
214
215         //生成Impl.java文件
216         File implJavaFile = new File(dirPath.getAbsolutePath() + File.separator + "IAILMDK" + File.separator + entity.getPkgName().replace(".", File.separator) + File.separator + MdkConstant.IMPL + File.separator + entity.getPyName() + "Impl.java");
217         GenUtils.drawTemplate("impl.java.vm", dataContext, implJavaFile);
218         javaFilePaths.add(implJavaFile.getAbsolutePath());
219
220         //生成.cpp文件
221         File cppFile = new File(dirPath.getAbsolutePath() + File.separator + MdkConstant.C + File.separator + entity.getPyName() + ".cpp");
222         GenUtils.drawTemplate("cpp.vm", dataContext, cppFile);
223         cppFilePaths.add(cppFile.getAbsolutePath());
224
225         //生成Jni.cpp文件
226         File jniCppFile = new File(dirPath.getAbsolutePath() + File.separator + MdkConstant.C + File.separator + entity.getPyName() + "Jni.cpp");
227         GenUtils.drawTemplate("Jni.cpp.vm", dataContext, jniCppFile);
228         cppFilePaths.add(jniCppFile.getAbsolutePath());
229
230         //生成.h文件
231         File hFile = new File(dirPath.getAbsolutePath() + File.separator + MdkConstant.C + File.separator + entity.getPyName() + ".h");
232         GenUtils.drawTemplate("h.vm", dataContext, hFile);
233
234         //生成Jni.h文件
235         File jniHFile = new File(dirPath.getAbsolutePath() + File.separator + MdkConstant.C + File.separator + entity.getPyName() + "Jni.h");
236         GenUtils.drawTemplate("Jni.h.vm", dataContext, jniHFile);
237
238         // 资源文件
239         FileUtil.copy(mpkResources + File.separator + "libs", dirPath.getAbsolutePath(), true);
240
241         //生成dll文件
242         String dllSavePath = dirPath.getAbsolutePath() + File.separator + MdkConstant.LIBS + File.separator + "IAIL.MDK.Mid.Jni.dll";
243         createDllFile(dirPath.getAbsolutePath(),cppFilePaths,dllSavePath);
244         //备份dll文件,用于后续运行
558ffc 245         String dllBakPath = mpkTenantBakFilePath + File.separator + MdkConstant.DLL + File.separator + entity.getPyName() + ".dll";
1fea3e 246         FileUtil.mkParentDirs(dllBakPath);
D 247         FileUtil.copy(dllSavePath, dllBakPath, true);
248
249         //utils + env java文件
250         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");
251         FileUtil.mkParentDirs(utilsJavaFile);
252         FileUtil.copy(mpkResources + File.separator +"IAILMDK/utils/AlgsUtils.java", utilsJavaFile.getAbsolutePath(), true);
253         javaFilePaths.add(utilsJavaFile.getAbsolutePath());
254         File envJavaFile = new File(dirPath.getAbsolutePath() + File.separator + "IAILMDK" + File.separator + "iail" + File.separator + "mdk" + File.separator + "model" + File.separator + "common" + File.separator + "Environment.java");
255         FileUtil.mkParentDirs(envJavaFile);
256         FileUtil.copy(mpkResources + File.separator +"IAILMDK/common/Environment.java", envJavaFile.getAbsolutePath(), true);
257         javaFilePaths.add(envJavaFile.getAbsolutePath());
258         // 生成class文件
259         createClassFile(javaFilePaths);
260         // 删除java源文件
261         deleteJavaFile(javaFilePaths);
262         // 打jar包
263         String jarSavePath = pkgJar(dirPath.getAbsolutePath());
264         //备份jar文件,用于后续运行
558ffc 265         String jarBakPath = mpkTenantBakFilePath + File.separator + MdkConstant.JAR + File.separator + entity.getPyName() + ".jar";
1fea3e 266         FileUtil.mkParentDirs(dllBakPath);
D 267         FileUtil.copy(jarSavePath, jarBakPath, true);
268         // 打zip包
558ffc 269         String zipPath = mpkTenantBakFilePath + File.separator + zipFileName;
1fea3e 270         ZipUtil.zip(dirPath.getAbsolutePath(), zipPath);
D 271         byte[] bytes = FileUtil.readBytes(zipPath);
449017 272
D 273         //代码生成历史记录
274         GeneratorCodeHistoryEntity historyEntity = new GeneratorCodeHistoryEntity();
275         historyEntity.setId(UUID.randomUUID().toString());
276         historyEntity.setMdkId(id);
1fea3e 277         historyEntity.setFileName(zipFileName);
D 278         historyEntity.setFilePath(zipPath);
449017 279         historyEntity.setRemark(remark);
D 280         historyEntity.setCreateTime(new Date());
281         generatorCodeHistoryService.insert(historyEntity);
282
1fea3e 283         // 删除临时文件
3009e2 284         try {
D 285             FileUtils.deleteDirectory(dirPath);
286         } catch (IOException e) {
912a1e 287             throw new RuntimeException("删除临时文件异常",e);
3009e2 288         }
1fea3e 289         return bytes;
449017 290     }
D 291
292     @Override
8b3ee3 293     @DSTransactional(rollbackFor = Exception.class)
f7932f 294     public byte[] packageModel(List<String> ids, String projectId, String projectName, String zipFileName, String logs, String version) throws IOException, InterruptedException {
558ffc 295         Long tenantId = TenantContextHolder.getTenantId();
D 296         // 备份文件 租户隔离
297         String mpkTenantBakFilePath = mpkBakFilePath + File.separator + tenantId;
298
449017 299         List<MpkFileDTO> entities = baseDao.selectByIds(ids);
D 300
301         //模板数据
1fea3e 302 //        Map<String, Object> map = new HashMap<>();
D 303 //        map.put("entities", entities);
304 //        VelocityContext context = new VelocityContext(map);
449017 305
D 306         //临时文件夹
912a1e 307         File dirPath = null;
D 308         try {
309             dirPath = Files.createTempDirectory("packageModelTmp").toFile();
310             log.info("生成临时文件夹," + dirPath.getAbsolutePath());
311         } catch (IOException e) {
312             throw new RuntimeException("创建临时文件夹异常",e);
313         }
449017 314
D 315         //设置velocity资源加载器
316         Properties prop = new Properties();
317         prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
318         Velocity.init(prop);
319
a27351 320         //生成menu.xml文件
2cc235 321         LinkedHashMap<String, LinkedHashMap<String, List<MpkFileDTO>>> collect = entities.stream().collect(Collectors.groupingBy(MpkFileDTO::getMenuName, LinkedHashMap::new, Collectors.groupingBy(e -> StringUtils.isNotBlank(e.getGroupName()) ? e.getGroupName() : "default_group",LinkedHashMap::new,Collectors.toList())));
a27351 322         Map<String, Object> map1 = new HashMap<>();
8b3ee3 323         map1.put("collects", collect);
c7009e 324         File xmlFile = new File(dirPath.getAbsolutePath() + File.separator + MdkConstant.LIBS + File.separator + "menu.xml");
8b3ee3 325         GenUtils.drawTemplate("menu.xml.vm", new VelocityContext(map1), xmlFile);
449017 326
D 327         List<String> javaFilePaths = new ArrayList<>();
f7932f 328         List<String> cppFilePaths = new ArrayList<>();
449017 329
D 330         //生成java文件
331         for (MpkFileDTO entity : entities) {
332             //封装模板数据
333             Map<String, Object> data = new HashMap<>();
8b3ee3 334             data.put("pkgName", entity.getPkgName());
335             data.put("modelMethods", entity.getModelMethods());
336             data.put("pyName", entity.getPyName());
337             data.put("pyModule", entity.getPyModule());
449017 338             VelocityContext dataContext = new VelocityContext(data);
D 339             //生成java文件
340             File javaFile = new File(dirPath.getAbsolutePath() + File.separator + "IAILMDK" + File.separator + entity.getPkgName().replace(".", File.separator) + File.separator + entity.getPyName() + ".java");
8b3ee3 341             GenUtils.drawTemplate("abstract.java.vm", dataContext, javaFile);
449017 342             javaFilePaths.add(javaFile.getAbsolutePath());
D 343
344             //生成Impl.java文件
345             File implJavaFile = new File(dirPath.getAbsolutePath() + File.separator + "IAILMDK" + File.separator + entity.getPkgName().replace(".", File.separator) + File.separator + MdkConstant.IMPL + File.separator + entity.getPyName() + "Impl.java");
8b3ee3 346             GenUtils.drawTemplate("impl.java.vm", dataContext, implJavaFile);
449017 347             javaFilePaths.add(implJavaFile.getAbsolutePath());
D 348
f7932f 349             //生成.cpp文件
D 350             File cppFile = new File(dirPath.getAbsolutePath() + File.separator + MdkConstant.C + File.separator + entity.getPyName() + ".cpp");
351             GenUtils.drawTemplate("cpp.vm", dataContext, cppFile);
352             cppFilePaths.add(cppFile.getAbsolutePath());
353
354             //生成Jni.cpp文件
355             File jniCppFile = new File(dirPath.getAbsolutePath() + File.separator + MdkConstant.C + File.separator + entity.getPyName() + "Jni.cpp");
356             GenUtils.drawTemplate("Jni.cpp.vm", dataContext, jniCppFile);
357             cppFilePaths.add(jniCppFile.getAbsolutePath());
358
359             //生成.h文件
360             File hFile = new File(dirPath.getAbsolutePath() + File.separator + MdkConstant.C + File.separator + entity.getPyName() + ".h");
361             GenUtils.drawTemplate("h.vm", dataContext, hFile);
362
363             //生成Jni.h文件
364             File jniHFile = new File(dirPath.getAbsolutePath() + File.separator + MdkConstant.C + File.separator + entity.getPyName() + "Jni.h");
365             GenUtils.drawTemplate("Jni.h.vm", dataContext, jniHFile);
366
449017 367             // 添加python源文件
c7009e 368             String pyFilePath = dirPath.getAbsolutePath() + File.separator + MdkConstant.ALGS + File.separator + entity.getPyModule().replace(".", File.separator) + File.separator + entity.getPyName() + ".pyd";
449017 369             FileUtil.mkParentDirs(pyFilePath);
8b3ee3 370             FileUtil.copy(entity.getFilePath(), pyFilePath, true);
449017 371         }
D 372
1fea3e 373         // 资源文件
D 374         FileUtil.copy(mpkResources + File.separator + "libs", dirPath.getAbsolutePath(), true);
c7009e 375
f7932f 376         //生成dll文件
c7009e 377         String dllSavePath = dirPath.getAbsolutePath() + File.separator + MdkConstant.LIBS + File.separator + "IAIL.MDK.Mid.Jni.dll";
f7932f 378         createDllFile(dirPath.getAbsolutePath(),cppFilePaths,dllSavePath);
c12dae 379         // 打包历史id
D 380         String historyId = UUID.randomUUID().toString();
381         //备份dll,发布时使用
382         File dllFile = new File(dllSavePath);
383         if (dllFile.exists()) {
558ffc 384             File dllBakFile = new File(mpkBakFilePath + File.separator + MdkConstant.PROJECT_UNPUBLISH + File.separator + projectId + MdkConstant.SPLIT + historyId + ".dll");
c12dae 385             FileUtil.copy(dllFile, dllBakFile, true);
D 386         }else {
387             log.error("dll文件不存在,无法备份。" + dllSavePath);
388         }
f7932f 389
449017 390         //utils + env java文件
c7009e 391         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");
449017 392         FileUtil.mkParentDirs(utilsJavaFile);
1fea3e 393         FileUtil.copy(mpkResources + File.separator +"IAILMDK/utils/AlgsUtils.java", utilsJavaFile.getAbsolutePath(), true);
449017 394         javaFilePaths.add(utilsJavaFile.getAbsolutePath());
c7009e 395         File envJavaFile = new File(dirPath.getAbsolutePath() + File.separator + "IAILMDK" + File.separator + "iail" + File.separator + "mdk" + File.separator + "model" + File.separator + "common" + File.separator + "Environment.java");
449017 396         FileUtil.mkParentDirs(envJavaFile);
1fea3e 397         FileUtil.copy(mpkResources + File.separator +"IAILMDK/common/Environment.java", envJavaFile.getAbsolutePath(), true);
449017 398         javaFilePaths.add(envJavaFile.getAbsolutePath());
D 399         // 生成class文件
400         createClassFile(javaFilePaths);
401         // 删除java源文件
402         deleteJavaFile(javaFilePaths);
403         // 打jar包
c12dae 404         String jarSavePath = pkgJar(dirPath.getAbsolutePath());
D 405         //备份jar包,发布时使用
406         File jarFile = new File(jarSavePath);
407         if (jarFile.exists()) {
558ffc 408             File jarBakFile = new File(mpkBakFilePath + File.separator + MdkConstant.PROJECT_UNPUBLISH + File.separator + projectId + MdkConstant.SPLIT + historyId + ".jar");
c12dae 409             FileUtil.copy(jarFile, jarBakFile, true);
D 410         }else {
411             log.error("jar文件不存在,无法备份。" + jarSavePath);
412         }
413
449017 414         // 本次更新日志
558ffc 415         ProjectPackageHistoryEntity projectPackageHistoryEntity = new ProjectPackageHistoryEntity();
D 416         projectPackageHistoryEntity.setId(historyId);
417         projectPackageHistoryEntity.setProjectId(projectId);
418         projectPackageHistoryEntity.setFileName(zipFileName);
419         projectPackageHistoryEntity.setLog(logs);
420         projectPackageHistoryEntity.setVersion(version);
421         projectPackageHistoryEntity.setModelNames(entities.stream().map(MpkFileDTO::getPyName).collect(Collectors.joining(",")));
422         projectPackageHistoryEntity.setCreateTime(new Date());
449017 423         // 生成更新日志
558ffc 424         createLog(projectId, projectName, dirPath.getAbsolutePath(), projectPackageHistoryEntity, version);
449017 425         // 打zip包
558ffc 426         String zipPath = mpkTenantBakFilePath + File.separator + zipFileName;
8b3ee3 427         ZipUtil.zip(dirPath.getAbsolutePath(), zipPath);
449017 428         byte[] bytes = FileUtil.readBytes(zipPath);
D 429         // 记录打包日志
558ffc 430         projectPackageHistoryEntity.setFilePath(zipPath);
D 431         projectPackageHistoryService.insert(projectPackageHistoryEntity);
449017 432         // 插入打包历史-模型关联表
D 433         List<ProjectPackageHistoryModelEntity> historyModelList = new ArrayList<>(entities.size());
434         entities.forEach(e -> {
435             ProjectPackageHistoryModelEntity entity = new ProjectPackageHistoryModelEntity();
436             entity.setId(UUID.randomUUID().toString());
437             entity.setProjectId(projectId);
438             entity.setPackageHistoryId(historyId);
439             entity.setPyName(e.getPyName());
067d7a 440             entity.setPyChineseName(e.getPyChineseName());
449017 441             entity.setPkgName(e.getPkgName());
D 442             entity.setPyModule(e.getPyModule());
443             entity.setRemark(e.getRemark());
0255ea 444             List<ModelMethodDTO> methods = e.getModelMethods();
449017 445             if (!CollectionUtils.isEmpty(methods)) {
D 446                 entity.setMethodInfo(JSON.toJSONString(methods));
447             }
448             historyModelList.add(entity);
449         });
558ffc 450         projectPackageHistoryModelService.insertList(historyModelList);
449017 451         // 删除临时文件
D 452         FileUtils.deleteDirectory(dirPath);
453         return bytes;
454     }
455
1fea3e 456     private void createDllFile(String dirPath, List<String> cppFilePaths, String dllSavePath) {
D 457         try {
458             String paths = cppFilePaths.stream().collect(Collectors.joining(" "));
459             String command = "cl /LD " + paths + " /EHsc /o " + dllSavePath + " /link " + "IAIL.MDK.Mid.Windows.lib";
460             log.info("执行cmd命令生成dll:" + command);
461             ProcessBuilder builder = new ProcessBuilder("cmd", "/c", command);
462             builder.directory(new File(dirPath + File.separator + MdkConstant.LIBS));
463             Process process = builder.start();
464             // 获取命令输出结果
465             InputStream inputStream = process.getInputStream();
466             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "GBK")); // 设置编码为GBK
467             String line;
468             while ((line = reader.readLine()) != null) {
469                 log.info(line);
470             }
471             // 等待命令执行完成
472             process.waitFor();
473         } catch (Exception e) {
912a1e 474             throw new RuntimeException("执行cmd命令生成dll异常",e);
f7932f 475         }
D 476     }
477
449017 478     @Override
8b3ee3 479     public Map<String, String> savePyFile(MultipartFile file) throws IOException {
558ffc 480         Long tenantId = TenantContextHolder.getTenantId();
D 481         // 备份文件 租户隔离
482         String mpkTenantBakFilePath = mpkBakFilePath + File.separator + tenantId;
483
484         File dir = new File(mpkTenantBakFilePath);
449017 485         if (!dir.exists()) {
D 486             dir.mkdirs();
487         }
488         String fileName = file.getOriginalFilename();
1fea3e 489         String fileSuffix = fileName.substring(fileName.lastIndexOf("."));
D 490         File saveFile = new File(dir.getAbsolutePath() + File.separator + UUID.randomUUID() + fileSuffix);
491
449017 492         saveFile.createNewFile();
D 493         // 保存
494         file.transferTo(saveFile);
495
8b3ee3 496         Map<String, String> result = new HashMap<>(2);
497         result.put("filePath", saveFile.getAbsolutePath());
449017 498         result.put("fileName", fileName);
D 499
500         return result;
501     }
502
c12dae 503     @Override
D 504     public CommonResult<String> publish(Map<String, Object> params) {
505         String historyId = (String) params.get("historyId");
506         String projectId = (String) params.get("projectId");
507
508         // 判断新的dll和jar文件是否存在
558ffc 509         String jarFileBakPath = mpkBakFilePath + File.separator + MdkConstant.PROJECT_UNPUBLISH + File.separator + projectId + MdkConstant.SPLIT + historyId + ".jar";
D 510         String dllFileBakPath = mpkBakFilePath + File.separator + MdkConstant.PROJECT_UNPUBLISH + File.separator + projectId + MdkConstant.SPLIT + historyId + ".dll";
c12dae 511         if (!FileUtil.exist(jarFileBakPath)) {
D 512             throw new RuntimeException("jar文件不存在," + jarFileBakPath);
513         }
514         if (!FileUtil.exist(dllFileBakPath)) {
515             throw new RuntimeException("dll文件不存在" + dllFileBakPath);
516         }
517
518         try {
519             // 卸载之前的dll和jar
520             DllUtils.removeClassLoaderCache(projectId);
521             // 删除之前的dll和jar备份文件
522             DllUtils.removeOldFile(mpkBakFilePath + File.separator + MdkConstant.PROJECT_PUBLISH,projectId);
523         } catch (Exception e) {
524             throw new RuntimeException("卸载之前的dll和jar异常",e);
525         }
526
527         // 备份新的dll和jar
528         String jarFilePath = mpkBakFilePath + File.separator + MdkConstant.PROJECT_PUBLISH + File.separator + projectId + MdkConstant.SPLIT + historyId + ".jar";
529         String dllFilePath = mpkBakFilePath + File.separator + MdkConstant.PROJECT_PUBLISH + File.separator + projectId + MdkConstant.SPLIT + historyId + ".dll";
530         FileUtil.copy(jarFileBakPath,jarFilePath,true);
531         FileUtil.copy(dllFileBakPath,dllFilePath,true);
532
533         URLClassLoader urlClassLoader = null;
534         try {
535             // 加载新的jar
536             urlClassLoader = DllUtils.loadJar(jarFilePath);
537         } catch (Exception e) {
538             throw new RuntimeException("加载新的jar异常",e);
539         }
540
541         try {
542             // 加载新的dll
543             DllUtils.loadDll(urlClassLoader.loadClass("iail.mdk.model.common.Environment"),dllFilePath);
544         } catch (Exception e) {
545             DllUtils.unloadJar(urlClassLoader);
546             throw new RuntimeException("加载新的dll异常",e);
547         }
548         // 都加载成功后加入缓存
549         DllUtils.addClassLoaderCache(projectId,urlClassLoader);
550
551         return CommonResult.success();
552     }
553
558ffc 554     private void createLog(String projectId, String projectName, String dirPath, ProjectPackageHistoryEntity projectPackageHistoryEntity, String version) {
8b3ee3 555         Map<String, Object> map = new HashMap<>();
556         map.put("projectId", projectId);
558ffc 557         List<ProjectPackageHistoryEntity> list = projectPackageHistoryService.list(map);
D 558         list.add(projectPackageHistoryEntity);
449017 559         // 按照日期分组再排序
558ffc 560         HashMap<String, List<ProjectPackageHistoryEntity>> dataMap = list.stream().collect(
449017 561                 Collectors.groupingBy(e -> DateUtils.format(e.getCreateTime(), DateUtils.DATE_PATTERN_POINT),
8b3ee3 562                         LinkedHashMap::new,
558ffc 563                         Collectors.collectingAndThen(Collectors.toList(), e -> e.stream().sorted(Comparator.comparing(ProjectPackageHistoryEntity::getCreateTime)).collect(Collectors.toList()))));
449017 564
D 565         Map<String, Object> data = new HashMap<>();
8b3ee3 566         data.put("dataMap", dataMap);
567         data.put("projectName", projectName);
568         data.put("version", version);
569         data.put("now", DateUtils.format(new Date(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
449017 570
D 571         File logFile = new File(dirPath + File.separator + "更新日志.txt");
8b3ee3 572         GenUtils.drawTemplate("log.txt.vm", data, logFile);
449017 573     }
D 574
3009e2 575     private String pkgJar(String dirPath) {
D 576         try {
577             String jarSavePath = dirPath + File.separator + MdkConstant.LIBS + File.separator + "IAILMDK.jar";
578             StringBuilder sb = new StringBuilder();
579             sb.append("jar -cvf");
580             sb.append(" ").append(jarSavePath);
581             sb.append(" -C ").append(dirPath).append(File.separator).append("IAILMDK").append(File.separator).append(" .");
582             log.info("执行cmd命令打jar包:" + sb);
583             Process process = RuntimeUtil.exec(sb.toString());
584             process.waitFor();
585             return jarSavePath;
586         } catch (InterruptedException e) {
912a1e 587             throw new RuntimeException("执行cmd命令打jar包异常",e);
3009e2 588         }
449017 589     }
D 590
591     private void deleteJavaFile(List<String> javaFilePaths) {
592         for (String javaFilePath : javaFilePaths) {
593             FileUtil.del(javaFilePath);
594         }
595     }
596
3009e2 597     private void createClassFile(List<String> javaFilePaths){
D 598         try {
599             StringBuilder sb = new StringBuilder();
600             sb.append("javac -encoding utf-8");
601             for (String path : javaFilePaths) {
602                 sb.append(" ").append(path);
603             }
604             log.info("执行cmd命令生成class:" + sb);
605             Process process = RuntimeUtil.exec(sb.toString());
606             process.waitFor();
607         } catch (InterruptedException e) {
912a1e 608             throw new RuntimeException("执行cmd命令生成class异常",e);
449017 609         }
D 610     }
611 }