yangys
2025-09-29 4c7296d45efe849dc70a3b2e2240c905481a91c9
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
 
package org.springblade.mdm.machinefile.service;
 
import jakarta.servlet.ServletOutputStream;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springblade.core.mp.base.BizServiceImpl;
import org.springblade.core.oss.OssTemplate;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.gkw.task.entity.MachineBackTask;
import org.springblade.mdm.gkw.task.service.MachineBackTaskService;
import org.springblade.mdm.machinefile.entity.MachineAcceptedFile;
import org.springblade.mdm.machinefile.entity.MachineFile;
import org.springblade.mdm.machinefile.events.ExportedToInnerEvent;
import org.springblade.mdm.program.entity.NcProgramExchange;
import org.springblade.mdm.program.mapper.NcProgramExchangeMapper;
import org.springblade.mdm.program.service.ProgramAnnotationService;
import org.springblade.mdm.program.service.programannotation.*;
import org.springblade.mdm.utils.FileContentUtil;
import org.springblade.mdm.utils.ProgramFileNameParser;
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.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
 
/**
 * 下发/回传程序统计
 *
 * @author yangys
 */
@Slf4j
@Service
@AllArgsConstructor
public class NcProgramExportInnerService extends BizServiceImpl<NcProgramExchangeMapper, NcProgramExchange> {
    private final MachineAcceptedFileService machineAcceptedService;
    private final OssTemplate ossTemplate;
    private final MachineFileService machineFileService;
    private final MachineService machineService;
    private final AnnotationProcessorHelper annotationProcessorHelper;
    private final ProgramAnnotationService programAnnotationService;
 
    private final MachineBackTaskService machineBackTaskService;
    /**
     * 导出到涉密网
     * @param acceptedFileIds 接受的文件id离了吧
     * @param os 输出流
     * @throws IOException 操作zip可能导致的IO异常
     */
    @Transactional
    public void exportToInner(List<Long> acceptedFileIds, ServletOutputStream os) throws IOException {
 
        List<MachineAcceptedFile> acceptedFiles = machineAcceptedService.lambdaQuery().in(MachineAcceptedFile::getId,acceptedFileIds).list();
        try (ZipOutputStream zipOut = new ZipOutputStream(os);) {//os
            Map<String,List<MachineAcceptedFile>> map =  acceptedFiles.stream()
                .collect(Collectors.groupingBy(s -> ProgramFileNameParser.parseProgramName(s.getName()).logicProgramName()));
 
            this.createFoldersInZip(zipOut,map.keySet());
 
            for (Map.Entry<String, List<MachineAcceptedFile>> entry : map.entrySet()) {
                String programName = entry.getKey();
                List<MachineAcceptedFile> acceptedFileList = entry.getValue();
                for (MachineAcceptedFile acceptedFile : acceptedFileList) {
                    try(InputStream ins = ossTemplate.statFileStream(acceptedFile.getOssName()) ) {
                        MachineFile machineFile = machineFileService.getById(acceptedFile.getMachineFileId());
                        addInputStreamToZip(zipOut,ins , programName + "/" + acceptedFile.getName(),acceptedFile.getName(),machineFile.getMachineCode());
                    }
                    acceptedFile.setExportTime(DateUtil.now());
                    acceptedFile.setStatus(MachineAcceptedFile.STATUS_EXPORTED);
                }
            }
 
            machineAcceptedService.updateBatchById(acceptedFiles);
 
            //更新任务状态
            List<Long> backTaskIdList = acceptedFiles.stream().map(MachineAcceptedFile::getBackTaskId).filter(Objects::nonNull).toList();
            this.finishTask(backTaskIdList);
 
            SpringUtil.publishEvent(new ExportedToInnerEvent("exportToInner",acceptedFiles));
        }
 
        os.close();
 
 
    }
 
    /**
     * 创建左右的程序包名文件夹
     * @param zipOut zip输出流
     * @param folderSet 程序报名文件夹集合
     * @throws IOException zipIO操作异常
     */
    void createFoldersInZip(ZipOutputStream zipOut,Set<String> folderSet) throws IOException {
        for(String folderName : folderSet){
            ZipEntry zipEntry = new ZipEntry(folderName+"/");// "/"结尾表示文件夹
            zipOut.putNextEntry(zipEntry);
            zipOut.closeEntry();
        }
 
 
    }
 
 
    void finishTask(List<Long> backTaskIdList){
        if(backTaskIdList.isEmpty()){
            return;
        }
        for(Long backTaskId : backTaskIdList){
            MachineBackTask backTask = machineBackTaskService.getById(backTaskId);
            List<MachineAcceptedFile> acceptedFiles = machineAcceptedService.listByBackTaskId(backTaskId);
 
            if(acceptedFiles.size() == backTask.getSegCount()) {
                backTask.setStatus(MachineBackTask.STATUS_FINISHED);
                backTask.setFinishTime(new Date());
 
                machineBackTaskService.updateById(backTask);
            }
 
        }
    }
 
    /**
     * j将输入流加入zip
     * @param zipOut zip文件输出里路
     * @param inputStream 文件的输入流
     * @param entryName entryName
     * @param filename 原始文件名
     * @param machineCode 机床代码
     * @throws IOException 异常
     */
    public void addInputStreamToZip(ZipOutputStream zipOut, InputStream inputStream, String entryName,String filename,String machineCode)
        throws IOException {
        // 创建新的 ZIP 条目
        ZipEntry zipEntry = new ZipEntry(entryName);
        zipOut.putNextEntry(zipEntry);
        InputStream insAdded = setAnnotations(inputStream,filename,machineCode);
        // 将输入流写入 ZIP 输出流
        byte[] buffer = new byte[1024];
        int length;
        while ((length = insAdded.read(buffer)) >= 0) {
            zipOut.write(buffer, 0, length);
        }
 
        // 关闭当前条目
        zipOut.closeEntry();
    }
 
    /**
     * 给导出文件增加注释,涉密网要用
     * @param inputStream 输入流
     * @param filename 文件名
     * @param machineCode 机床代码
     * @return 完成后的stream
     * @throws IOException 操作异常
     */
    InputStream setAnnotations(InputStream inputStream,String filename,String machineCode) throws IOException {
        Machine machine = this.machineService.getByCode(machineCode);
        AnnotationProcessor annoProcessor = annotationProcessorHelper.getProcessor(machine.getControlSystem());
 
        AnnotationData annoData = new AnnotationData();
        annoData.setFilename(filename);
        annoData.setSendPath(machine.getProgSendDir());
 
        AnnotationProperties annoProps = annoProcessor.getAnnotationProperties();
 
        ByteArrayInputStream byteInsStream = new ByteArrayInputStream(IOUtils.toByteArray(inputStream));
        String statusLine = FileContentUtil.readLineAt(byteInsStream,annoProps.getStatusLineIndex());
        String text = programAnnotationService.removeAnnotation(machine.getControlSystem(),statusLine);
 
        if(AnnotationUtil.isStatusContent(text)){
            //是3种状态之一
            annoData.setProgramStatus(text);
        }else{
            //没有按试切处理
            annoData.setProgramStatus(AnnotationUtil.SQ);
        }
        byteInsStream.reset();
        //
        return annoProcessor.putAnnotation(annoData,byteInsStream);
    }
}