|
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.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.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.IOException;
|
import java.io.InputStream;
|
import java.nio.charset.StandardCharsets;
|
import java.util.List;
|
|
/**
|
* 流程程序处理,包括上传,查询展示
|
*
|
* @author yangys
|
*/
|
@Slf4j
|
@Service
|
public class FlowProgramFileService extends BizServiceImpl<FlowProgramFileMapper, FlowProgramFile> {
|
@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();
|
if(file.getSize() == 0){
|
throw new ServiceException("程序文件不可为空文件");
|
}
|
ProgramFileNameCheckUtil.checkFilename(file.getOriginalFilename(),progProps);
|
|
String programName = NcNodeService.genProgramName(progProps.getDrawingNo(),progProps.getProcessNo());
|
|
BladeFile bfile = ossTemplate.putFile(file);
|
|
FlowProgramFile progFile = new FlowProgramFile();
|
progFile.setName(file.getOriginalFilename());
|
progFile.setOssName(bfile.getName());
|
progFile.setProcessInstanceId(uploadVO.getProcessInstanceId());
|
progFile.setProgramName(programName);
|
progFile.setFileType(uploadVO.getFileType());
|
save(progFile);
|
|
}
|
|
|
/**
|
* 检查文件名合法性
|
* @param filename 文件名
|
* @param programProperties 程序属性,发起时填写的
|
*/
|
/*
|
void checkFilename(String filename,FlowProgramProperties programProperties){
|
//程序名称:零件号加工序号,文件名应该以此开头
|
String programNamePrefix = NcNodeService.genProgramName(programProperties.getDrawingNo(),programProperties.getProcessNo()) + "-"+programProperties.getProcessEdition();
|
if(!StringUtils.startsWith(filename,programNamePrefix)){
|
|
IResultCode rc = new IResultCode() {
|
@Override
|
public String getMessage() {
|
return "程序文件名不合法,应为:"+programNamePrefix+"-[段数]-[段号].[文件扩展名]";
|
}
|
|
@Override
|
public int getCode() {
|
return 1;
|
}
|
};
|
throw new ServiceException(rc);
|
}
|
|
//截取后面的段数和第几段
|
String endPart = StringUtils.removeStart(filename,programNamePrefix+"-");
|
|
//去掉扩展名
|
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 "程序文件名不合法,应为:"+programNamePrefix+"-[段数]-[段号].[文件扩展名]";
|
}
|
|
@Override
|
public int getCode() {
|
return 2;
|
}
|
};
|
throw new ServiceException(rc);
|
}
|
|
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 文件id
|
* @return 文件内容文本
|
*/
|
public String getFileContent(Long id) {
|
String result ="";
|
|
FlowProgramFile programFile = this.getById(id);
|
/*
|
String fileName = programFile.getOssName();
|
try (InputStream inputStream = ossTemplate.statFileStream(fileName)) {
|
result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
|
} catch (IOException e) {
|
throw new RuntimeException(e);
|
}
|
*/
|
|
String fileName = programFile.getOssName();
|
try (InputStream inputStream = ossTemplate.statFileStream(fileName)) {
|
result = FileContentUtil.getContentFromStream(inputStream);
|
} catch (IOException e) {
|
throw new RuntimeException(e);
|
}
|
|
return result;
|
}
|
|
/**
|
* 验证程序文件的完整性,仅在编制节点使用
|
* @param processInstanceId 流程实例id
|
*/
|
public void checkProgramFiles(String processInstanceId,boolean isPass) {
|
List<FlowProgramFile> 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 = ProgramFileNameCheckUtil.getProgramSegCount(progFile.getName());
|
}
|
|
if(totalSeg != flowPrograms.size()){
|
throw new ServiceException("应上传"+totalSeg+"段程序,实际上传"+flowPrograms.size()+"段");
|
}
|
|
}
|
|
public void download(Long id, HttpServletResponse response) throws IOException {
|
FlowProgramFile flowFile = this.getById(id);
|
response.setHeader("Content-Disposition", "attachment; filename="+flowFile.getName());
|
response.setContentType("application/octet-stream");
|
try(InputStream ins = ossTemplate.statFileStream(flowFile.getOssName());){
|
IOUtils.copy(ins,response.getOutputStream());
|
}
|
}
|
}
|