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