package org.springblade.mdm.flow.service; 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.tool.api.IResultCode; import org.springblade.core.tool.utils.Func; import org.springblade.mdm.flow.entity.FlowProgramFile; import org.springblade.mdm.flow.mapper.FlowProgramFileMapper; import org.springblade.mdm.flow.vo.ProgramUploadVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; 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 RuntimeService runtimeService; @Autowired private FlowCommonService flowCommonService; /** * 上传程序徐文件(编制节点调用) * @param uploadVO 上传对象 */ public void uploadFlowProgramFile(ProgramUploadVO uploadVO) { FlowProgramProperties progProps= flowCommonService.getProgramProperties(uploadVO.getProcessInstanceId()); MultipartFile file = uploadVO.getFile(); checkFilename(file.getOriginalFilename(),progProps); String programName = getProgramName(progProps); BladeFile bfile = ossTemplate.putFile(file); FlowProgramFile progFile = new FlowProgramFile(); progFile.setName(file.getOriginalFilename()); progFile.setOssName(bfile.getName()); progFile.setProcessInstanceId(uploadVO.getProcessInstanceId()); progFile.setIsCured(0); progFile.setProgramName(programName); save(progFile); } /** * 获取程序名称 * @param progProps * @return */ String getProgramName(FlowProgramProperties progProps){ return progProps.getDrawingNo()+"-"+progProps.getProcessNo(); } /** * 检查文件名合法性 * @param filename 文件名 * @param programProperties 程序属性,发起时填写的 */ void checkFilename(String filename,FlowProgramProperties programProperties){ //程序名称:零件号加工序号,文件名应该以此开头 String expectedProgramName = programProperties.getDrawingNo()+"-"+programProperties.getProcessNo(); if(!StringUtils.startsWith(filename,expectedProgramName)){ IResultCode rc = new IResultCode() { @Override public String getMessage() { return "程序文件名不合法,应为:"+expectedProgramName+"-"+programProperties.getCraftEdition()+"-[段数]-[段号].[文件扩展名]"; } @Override public int getCode() { return 1; } }; throw new ServiceException(rc); //throw new ServiceException("程序文件名不合法,应为:"+expectedProgramName+"-"+programProperties.getCraftEdition()+"-[段数]-[段号].[文件扩展名]"); } //截取后面的段数和第几段 String endPart = StringUtils.removeStart(filename,expectedProgramName+"-"+programProperties.getCraftEdition()+"-"); //去掉扩展名 if(endPart.contains(".")){ endPart = endPart.substring(0,endPart.indexOf(".")); } int sepCount = StringUtils.countMatches(endPart,"-"); if(sepCount != 1){//- 号应该是1个 IResultCode rc = new IResultCode() { @Override public String getMessage() { return "程序文件名不合法,应为:"+expectedProgramName+"-"+programProperties.getCraftEdition()+"-[段数]-[段号].[文件扩展名]"; } @Override public int getCode() { return 2; } }; throw new ServiceException(rc); //throw new ServiceException("程序文件名不合法,应为:"+expectedProgramName+"-"+programProperties.getCraftEdition()+"-[段数]-[段号].[文件扩展名]"); } String[] arr = StringUtils.split(endPart,"-"); if(!StringUtils.isNumeric(arr[0]) || Func.toInt(arr[0]) >99 || Func.toInt(arr[0]) < 1){ IResultCode rc = new IResultCode() { @Override public String getMessage() { return "程序段数不合法,应为两位以内整数"; } @Override public int getCode() { return 3; } }; throw new ServiceException(rc); } int segCount = Func.toInt(arr[0]); if(!StringUtils.isNumeric(arr[1]) || Func.toInt(arr[1]) < 1 || Func.toInt(arr[1]) > segCount){ IResultCode rc = new IResultCode() { @Override public String getMessage() { return "程序段号不合法,应为两位以内整数且小于等于段数。"; } @Override public int getCode() { return 4; } }; throw new ServiceException(rc); } } /** * 获取文件内容 * @param id * @return */ public String getFileContent(Long id) { String result =""; FlowProgramFile programFile = this.getById(id); //if(prog.getIsTextFile()!=null && programFile.getIsTextFile()){ String fileName = programFile.getOssName(); try (InputStream inputStream = ossTemplate.statFileStream(fileName)) { result = IOUtils.toString(inputStream, StandardCharsets.UTF_8); } catch (IOException e) { throw new RuntimeException(e); } //}else{ // result = "非文本格式文件"; //} return result; } /** * 验证程序文件的完整性,仅在编制节点使用 * @param processInstanceId 流程实例id */ public void checkProgramFiles(String processInstanceId,boolean isPass) { List flowPrograms = this.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId, processInstanceId).orderByAsc(FlowProgramFile::getCreateTime).list(); if(isPass && flowPrograms.isEmpty()){ throw new ServiceException("请上传程序文件"); } int totalSeg = 0; if(!flowPrograms.isEmpty()){ FlowProgramFile progFile = flowPrograms.get(0); totalSeg = getProgramSegCount(progFile.getName()); } if(totalSeg != flowPrograms.size()){ throw new ServiceException("应上传"+totalSeg+"段程序,实际上传"+flowPrograms.size()+"段"); } } /** * 根据文件名获取程序总段树 * @param filename 文件名 * @return */ int getProgramSegCount(String filename){ int idx = filename.lastIndexOf("."); String tempstr = filename.substring(0,idx);//去掉扩展名 //System.out.println(tempstr); idx = tempstr.lastIndexOf("-"); tempstr = tempstr.substring(0,idx); //System.out.println(tempstr); idx = tempstr.lastIndexOf("-"); tempstr = tempstr.substring(idx+1); //System.out.println(tempstr); return Func.toInt(tempstr); } }