yangys
2025-09-17 1e2b04fabbbc4b1ae37d7951068d7ab235f5b5f9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
 
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.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<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("程序文件不可为空文件");
        }
        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<FlowProgramFile> flowPrograms = this.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId, processInstanceId).orderByAsc(FlowProgramFile::getCreateTime).list();
        List<FlowProgramFile> 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()+"段");
        }
 
    }
 
    public void download(Long id, HttpServletResponse response) throws IOException {
        FlowProgramFile flowFile = this.getById(id);
        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<FlowProgramFile> listByProcessInstanceId(String processInstanceId){
        return lambdaQuery()
        .eq(FlowProgramFile::getProcessInstanceId, processInstanceId).list();
    }
}