package org.springblade.mdm.program.service; import com.baomidou.mybatisplus.core.metadata.IPage; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.flowable.engine.HistoryService; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.mp.base.BizServiceImpl; import org.springblade.core.mp.support.Condition; import org.springblade.core.oss.OssTemplate; import org.springblade.core.tool.utils.FileUtil; import org.springblade.mdm.flow.service.FlowBusinessService; import org.springblade.mdm.program.entity.DncBackFile; import org.springblade.mdm.program.entity.NcNode; import org.springblade.mdm.program.entity.NcNodeHis; import org.springblade.mdm.program.mapper.DncBackFileMapper; import org.springblade.mdm.program.vo.DncBackFileQueryVO; import org.springblade.mdm.program.vo.DncBackFileVO; import org.springblade.mdm.program.vo.DncSendBackFile; import org.springblade.mdm.utils.ZipTextFileContentUtil; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; /** * DNC回传文件处理服务 * * @author yangys */ @Slf4j @Service @AllArgsConstructor public class DncBackFileService extends BizServiceImpl { private final NcNodeService ncNodeService; private final NcNodeHisService nodeHisService; private final OssTemplate ossTemplate; private final HistoryService historyService; private final FlowBusinessService businessService; public IPage pageQuery(DncBackFileQueryVO query) { IPage page= this.baseMapper.pageQuery(Condition.getPage(query),query); page.getRecords().forEach(item->{ item.setProcessExecuted(isProcessExecuted(item.getProcessInstanceId())); }); return page; } /** * 检查流程实例是否被执行过(通过历史记录) */ public boolean isProcessExecuted(String processInstanceId) { if(StringUtils.isBlank(processInstanceId)){ //空流程实例id,说明节点已经没有了 return true; } // 检查是否有历史任务记录 long taskCount = historyService.createHistoricTaskInstanceQuery() .processInstanceId(processInstanceId) .count(); //多于一个任务被处理,说明至少流转到第二个节点了 return taskCount > 1; } /** * 取消流程 * @param id 回传记录id */ @Transactional public void cancelProcess(long id) { DncBackFile backFIle = this.getById(id); NcNode packageNode = ncNodeService.getById(backFIle.getNcNodeId()); //多于一个任务被处理,说明至少流转到第二个节点了 if(isProcessExecuted(packageNode.getProcessInstanceId())){ throw new ServiceException("流程已经开始处理,不可取消"); } businessService.deleteProcessInstance(packageNode.getProcessInstanceId()); this.baseMapper.deleteById(id); } /** * 获取回传记录的文件列表 * @param id 回传记录id * @return */ public List filesById(long id) throws IOException { List fileList = new ArrayList<>(); DncBackFile backFIle = this.getById(id); InputStream inputStream = this.ossTemplate.statFileStream(backFIle.getOssName()); Path tempZipFile = createTempFile(inputStream); NcNodeHis packageNode = nodeHisService.getById(backFIle.getNcNodeId()); //String targetFolder = packageNode.getName()+"-"+packageNode.getProcessEdition()+"/"; String targetFolder = packageNode.getName()+"/"; ZipEntry entry; try (java.util.zip.ZipFile zipFile = new java.util.zip.ZipFile(tempZipFile.toFile())) { Enumeration entries = zipFile.entries(); while(entries.hasMoreElements()) { entry = entries.nextElement(); if(!entry.isDirectory() && entry.getName().startsWith(targetFolder)){ //这里面之前时入库的文件 DncSendBackFile file = new DncSendBackFile(); file.setName(entry.getName().substring(targetFolder.length())); file.setEntryName(entry.getName()); fileList.add(file); } } } return fileList; } Path createTempFile(InputStream inputStream) throws IOException { byte[] zipData = FileUtil.copyToByteArray(inputStream); Path tempFile = Files.createTempFile("tempzip"+System.currentTimeMillis(), ".zip"); // 写入字节数据到临时文件 Files.write(tempFile, zipData, StandardOpenOption.WRITE); return tempFile; } /** * 从文件夹名解析出程序包名和和工序版次 * @param folderName 文件夹名 * @return 结构数据 */ PackageAndProcessEdition parseProgramPackageFromFolderName(String folderName){ int index = StringUtils.lastIndexOf(folderName,'-'); String processEditon = ""; String temp; String packageName = ""; if(index != -1){ processEditon = folderName.substring(index+1); packageName = folderName.substring(0,index); } PackageAndProcessEdition result = new PackageAndProcessEdition();; result.setProgramPackageName(packageName); result.setProcessEdition(processEditon); return result; } /** * 获取历史记录中的文件内容 * @param id 回传历史记录id * @param entryName 压缩包文件路径 * @return */ public String getEntryFileContent(long id, String entryName) throws IOException { DncBackFile backFIle = this.getById(id); return ZipTextFileContentUtil.getTextContent(this.ossTemplate.statFileStream(backFIle.getOssName()),entryName); } }