yangys
2025-09-22 12f2fafc574afb4c534ab59244f2b954d1876e9f
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
162
163
164
165
166
167
168
169
170
171
172
173
 
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.flowable.engine.ProcessEngine;
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.oss.model.BladeFile;
import org.springblade.core.tool.utils.FileUtil;
import org.springblade.mdm.flow.entity.FlowProgramFile;
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.FileContentUtil;
import org.springblade.mdm.utils.ZipTextFileContentUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.io.ByteArrayInputStream;
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.Optional;
import java.util.zip.ZipEntry;
 
/**
 * DNC回传文件处理服务
 *
 * @author yangys
 */
@Slf4j
@Service
@AllArgsConstructor
public class DncBackFileService extends BizServiceImpl<DncBackFileMapper, DncBackFile> {
    private final NcNodeService ncNodeService;
    private final NcNodeHisService nodeHisService;
    private final OssTemplate ossTemplate;
    private final HistoryService historyService;
    private final FlowBusinessService businessService;
    public IPage<DncBackFileVO> pageQuery(DncBackFileQueryVO query) {
        IPage<DncBackFileVO> 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<DncSendBackFile> filesById(long id) throws IOException {
        List<DncSendBackFile> 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<? extends ZipEntry> 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);
    }
}