package org.springblade.mdm.flow.service; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletResponse; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.flowable.engine.RuntimeService; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.mp.base.BizServiceImpl; import org.springblade.core.oss.OssTemplate; import org.springblade.core.oss.model.BladeFile; import org.springblade.core.secure.utils.AuthUtil; import org.springblade.core.tool.api.IResultCode; import org.springblade.core.tool.utils.Func; import org.springblade.core.tool.utils.UrlUtil; import org.springblade.mdm.commons.service.OssFileCommonService; import org.springblade.mdm.flow.entity.FlowProgramFile; import org.springblade.mdm.flow.mapper.FlowProgramFileMapper; import org.springblade.mdm.flow.vo.ProgramUploadVO; import org.springblade.mdm.program.service.NcNodeService; import org.springblade.mdm.utils.FileContentUtil; import org.springblade.mdm.utils.ProgramFileNameCheckUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.List; /** * 流程程序处理,包括上传,查询展示 * * @author yangys */ @Slf4j @Service public class FlowProgramFileService extends BizServiceImpl { @Autowired private OssTemplate ossTemplate; @Autowired private OssFileCommonService ossFileCommonService; @Autowired private FlowCommonService flowCommonService; /** * 上传程序徐文件(编制节点调用) * @param uploadVO 上传对象 */ public void uploadFlowProgramFile(ProgramUploadVO uploadVO) { FlowProgramProperties progProps= flowCommonService.getProgramProperties(uploadVO.getProcessInstanceId()); MultipartFile file = uploadVO.getFile(); if(file.getSize() == 0){ throw new ServiceException("程序文件不可为空文件"); } if(exists(file.getOriginalFilename(),uploadVO.getProcessInstanceId())){ throw new ServiceException("同名文件已存在:"+file.getOriginalFilename()); } if(FlowProgramFile.TYPE_PROGRAM.equals(uploadVO.getFileType())) { ProgramFileNameCheckUtil.checkFilename(file.getOriginalFilename(), progProps); } BladeFile bfile = ossTemplate.putFile(file); FlowProgramFile progFile = new FlowProgramFile(); progFile.setName(file.getOriginalFilename()); progFile.setOssName(bfile.getName()); progFile.setProcessInstanceId(uploadVO.getProcessInstanceId()); progFile.setProgramName(NcNodeService.genProgramName(progProps.getDrawingNo(),progProps.getProcessNo(),progProps.getProcessEdition())); progFile.setFileType(uploadVO.getFileType()); save(progFile); } /** * 判断那流程下是否有同名问题 * @param filename 文件名 * @param processInstanceId 流程实例id * @return 是否 */ boolean exists(String filename,String processInstanceId){ return lambdaQuery().eq(FlowProgramFile::getName, filename).eq(FlowProgramFile::getProcessInstanceId, processInstanceId).count()>0; } /** * 获取文件内容 * @param id 文件id * @return 文件内容文本 */ public String getFileContent(Long id) { String result =""; FlowProgramFile programFile = this.getById(id); String fileName = programFile.getOssName(); try (InputStream inputStream = ossTemplate.statFileStream(fileName)) { ByteArrayInputStream bos = new ByteArrayInputStream(inputStream.readAllBytes()); boolean isText = StringUtils.endsWithIgnoreCase(fileName,".txt") || StringUtils.endsWithIgnoreCase(fileName,".nc")|| StringUtils.endsWithIgnoreCase(fileName,".xml"); if(!isText){ isText= FileContentUtil.isTextFile(bos); } if(isText){ bos.reset(); result = FileContentUtil.getContentFromStream(bos); }else{ result = "<非文本文件>"; } } catch (IOException e) { throw new RuntimeException(e); } return result; } /** * 验证程序文件的完整性,仅在编制节点使用 * @param processInstanceId 流程实例id */ public void checkProgramFiles(String processInstanceId,boolean isPass) { List flowPrograms = this.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId, processInstanceId).orderByAsc(FlowProgramFile::getCreateTime).list(); List purePrograms = flowPrograms.stream().filter(FlowProgramFile::isProgram).toList(); if(isPass && purePrograms.isEmpty()){ throw new ServiceException("请上传程序文件"); } int totalSeg = 0; if(!purePrograms.isEmpty()){ FlowProgramFile progFile = purePrograms.get(0); totalSeg = ProgramFileNameCheckUtil.getProgramSegCount(progFile.getName()); } if(totalSeg != purePrograms.size()){ throw new ServiceException("应上传"+totalSeg+"段程序,实际上传"+flowPrograms.size()+"段"); } } /** * 流程文件下载 * @param id 流程文件id * @param response http响应 * @throws IOException 文件操作异常 */ public void download(Long id, HttpServletResponse response) throws IOException { FlowProgramFile flowFile = this.getById(id); ossFileCommonService.download(flowFile.getOssName(),flowFile.getName(),response); /* response.setHeader("Content-Disposition", "attachment; filename="+ UrlUtil.encode(flowFile.getName())); response.setContentType("application/octet-stream"); try(InputStream ins = ossTemplate.statFileStream(flowFile.getOssName());){ IOUtils.copy(ins,response.getOutputStream()); }*/ } /** * 获取关于流程的所有文件 * @param processInstanceId 流程实例id * @return 流程关联的文件列表 */ public List listByProcessInstanceId(String processInstanceId){ return lambdaQuery() .eq(FlowProgramFile::getProcessInstanceId, processInstanceId).list(); } }