yangys
2025-09-15 7bc1d0f521c1d59246f29bcadcc4343f88ceef1c
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
package org.springblade.mdm.flow.excution.cure;
 
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.oss.OssTemplate;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.commons.contants.ParamConstants;
import org.springblade.mdm.flow.entity.FlowProgramFile;
import org.springblade.mdm.flow.excution.dispatch.FinishDataHandler;
import org.springblade.mdm.flow.service.FlowProgramFileService;
import org.springblade.mdm.flow.service.FlowProgramProperties;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.service.NcNodeAutoCreateService;
import org.springblade.mdm.program.service.NcNodeHisService;
import org.springblade.mdm.program.service.NcNodeService;
import org.springblade.mdm.program.service.ProgramAnnotationService;
import org.springblade.mdm.program.service.programannotation.AnnotationProperties;
import org.springblade.mdm.program.service.programannotation.AnnotationUtil;
import org.springblade.mdm.program.service.programannotation.MachineAnnotationConfig;
import org.springblade.mdm.utils.EntityUtil;
import org.springblade.system.feign.ISysClient;
import org.springblade.system.pojo.entity.DictBiz;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Optional;
 
/**
 * 普通派工完成数据处理器,功能:插入审批表数据,DispatchFinishListener调用
 */
@Slf4j
@Component("normalCureFinishDataHandler")
public class NormalCureFinishDataHandler implements FinishDataHandler {
    @Autowired
    private MachineAnnotationConfig config;
 
    @Autowired
    private FlowProgramFileService flowProgramFileService;
    @Autowired
    private NcNodeService nodeService;
 
    @Autowired
    private NcNodeAutoCreateService ncNodeAutoCreateService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private ISysClient sysClient;
    @Autowired
    private ProgramAnnotationService programAnnotationService;
    /**
     * 默认有效期间(月数),2年
     */
    private static final int DEFAULT_VALID_MONTH = 24;
 
    /**
     * DispatchFinishListener中调用
     * @param flowProps 流程属性
     */
    public void handleData(FlowProgramProperties flowProps) {
 
        //需要固化的节点
        NcNode pkgNode = nodeService.lambdaQuery().eq(NcNode::getProcessInstanceId,  flowProps.getProcessInstanceId()).one();
        //原节点保留不动,置为老版本
        pkgNode.setIsLastEdition(0);
        pkgNode.setIsLocked(1);
        nodeService.updateById(pkgNode);
 
        nodeService.getBaseMapper().deleteById(pkgNode.getParentId());//删除机床组节点
        //List<NcNode> historyProgramPackageNodes = nodeService.getTryNodeHistory(pkgNode);
        try {
            moveNodeToCuredTree(pkgNode, flowProps);//, historyProgramPackageNodes
        }catch(Exception e) {
            log.error("固化流程完成异常",e);
            throw new ServiceException("普通固化执行异常"+e.getMessage());
        }
 
    }
 
 
    /**
     * 将节点和历史节点挪动到固化的同级节点下
     * @param pkgNode1 要固化的节点
     * @param programProperties 流程属性
     */
    void moveNodeToCuredTree(NcNode pkgNode1, FlowProgramProperties programProperties) throws IOException {
 
        //创建节点到机床级别.(固化树)
        NcNode machineGroupNode = ncNodeAutoCreateService.createNodeTreeToMachineGroup(programProperties);
 
        //新建一个节点,作为固化节点,
        this.nodeService.lambdaUpdate().likeRight(NcNode::getParentIds, machineGroupNode.subNodeParentIds())
            .in(NcNode::getNodeType, Arrays.asList(NcNode.TYPE_PROGRAM_PACKAGE,NcNode.TYPE_PROGRAM_FILE))
            .set(NcNode::getIsLastEdition,0).set(NcNode::getIsLocked,1).update();
 
        List<NcNode> programNodes = nodeService.getProgramFilesByPackageId(pkgNode1.getId());
        boolean tryPkgNodeHasChild = !programNodes.isEmpty();
 
        //新建固化节点
        NcNode cureNode = createNewCureNodeByTargetNode(pkgNode1,tryPkgNodeHasChild);
        cureNode.setParentId(machineGroupNode.getId());
        cureNode.setParentIds(machineGroupNode.subNodeParentIds());
        nodeService.save(cureNode);
 
        this.copyNonProgramNodes(pkgNode1,cureNode);
        /*
        List<NcNode> oriProgramNodes = nodeService.lambdaQuery().eq(NcNode::getParentId,pkgNode1.getId()).list();
        FlowProgramFile pfile;
        for(NcNode oldProgramNode : oriProgramNodes){
            oldProgramNode.setParentIds(pkgNode1.subNodeParentIds());
            oldProgramNode.setIsLastEdition(0);
            //当前固化程序包名下的“其他文件”非程序文件。不设置为老版本,直接挪到固化树下,两个网络之间只交换程序文件,其他文件只能保留
            //其他文件,需要复制到新建的固化节点下(程序文件不复制)
            pfile = flowProgramFileService.getById(oldProgramNode.getFlowProgramFileId());
            if(!pfile.isProgram()) {
                NcNode newFileNode = new NcNode();
                BeanUtils.copyProperties(oldProgramNode, newFileNode);
                EntityUtil.clearBaseProperties(newFileNode);
                newFileNode.setParentId(cureNode.getId());
                newFileNode.setParentIds(cureNode.subNodeParentIds());
                newFileNode.setIsLastEdition(1);
                nodeService.save(newFileNode);
            }
 
        }
        nodeService.updateBatchById(oriProgramNodes);
        */
 
        this.addNewProgramNode(cureNode,pkgNode1.getProcessInstanceId());
 
    }
 
    /**
     * 从待固化节点复制非程序文件节点到固化节点下
     * @param oriPkgNode 待固化节点
     * @param cureNode 固化节点
     */
    void copyNonProgramNodes(NcNode oriPkgNode,NcNode cureNode){
        List<NcNode> oriProgramNodes = nodeService.lambdaQuery().eq(NcNode::getParentId,oriPkgNode.getId()).list();
        FlowProgramFile pfile;
        for(NcNode oldProgramNode : oriProgramNodes){
            oldProgramNode.setParentIds(oriPkgNode.subNodeParentIds());
            oldProgramNode.setIsLastEdition(0);
            //当前固化程序包名下的“其他文件”非程序文件。不设置为老版本,直接挪到固化树下,两个网络之间只交换程序文件,其他文件只能保留
            //其他文件,需要复制到新建的固化节点下(程序文件不复制)
            pfile = flowProgramFileService.getById(oldProgramNode.getFlowProgramFileId());
            if(!pfile.isProgram()) {
                NcNode newFileNode = new NcNode();
                BeanUtils.copyProperties(oldProgramNode, newFileNode);
                EntityUtil.clearBaseProperties(newFileNode);
                newFileNode.setParentId(cureNode.getId());
                newFileNode.setParentIds(cureNode.subNodeParentIds());
                newFileNode.setIsLastEdition(1);
                nodeService.save(newFileNode);
            }
 
        }
        nodeService.updateBatchById(oriProgramNodes);
    }
 
    void addNewProgramNode(NcNode cureNode,String processInstanceId) throws IOException {
        Machine machine = machineService.getByCode(cureNode.getMachineCode());
        List<DictBiz> annoDicts = programAnnotationService.getAnnotionDictList();
        //新的流程文件,需要在包节点下新建,不能用老的包节点
        List<FlowProgramFile> files = flowProgramFileService.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId,processInstanceId).list();
        for(FlowProgramFile flowProgramFile : files){
            NcNode newProgNode = new NcNode();
 
            BeanUtils.copyProperties(cureNode,newProgNode);
            EntityUtil.clearBaseProperties(newProgNode);
 
            newProgNode.setName(flowProgramFile.getName());
            newProgNode.setNodeType(NcNode.TYPE_PROGRAM_FILE);
            newProgNode.setParentId(cureNode.getId());
            newProgNode.setParentIds(cureNode.subNodeParentIds());
            newProgNode.setIsLastEdition(1);
            newProgNode.setFlowProgramFileId(flowProgramFile.getId());
            newProgNode.setIsCured(1);
 
            setGhAnnotation(flowProgramFile,machine.getControlSystem(),annoDicts);
 
            nodeService.save(newProgNode);
        }
    }
 
    /**
     * 复制待固化节点数据,创建一个新的固化节点
     * @param waitingCureNode 待固化节点
     * @param tryPkgNodeHasProgramFiles 是否有程序文件
     * @return 固化节点
     */
    NcNode createNewCureNodeByTargetNode(NcNode waitingCureNode,boolean tryPkgNodeHasProgramFiles){
        //新建一个节点,作为固化节点,老节点保留不动
        NcNode cureNode = new NcNode();
        BeanUtils.copyProperties(waitingCureNode, cureNode);
        EntityUtil.clearBaseProperties(cureNode);
        cureNode.setIsCured(1);
        cureNode.setIsLocked(NcNode.UNLOCK);
        cureNode.setIsLastEdition(1);
        cureNode.setExpireDate(calculateExpireDate());//设置过期日期
 
        cureNode.setHisSerial(nodeService.calculateHistorySerial(cureNode));
 
        Optional<NcNode> optOldCuredPackageNode = nodeService.lambdaQuery().eq(NcNode::getName,waitingCureNode.getName())
            .eq(NcNode::getProcessNo,waitingCureNode.getProcessNo())
            .eq(NcNode::getProcessEdition,waitingCureNode.getProcessEdition())
            .eq(NcNode::getIsLastEdition,1).eq(NcNode::getIsCured,1).oneOpt();
 
        if(optOldCuredPackageNode.isEmpty() && tryPkgNodeHasProgramFiles){
            //之前 没有已固化的程序包名,则直接更新版本号,如果有,那就使用node现在的版本号,因为不可用转为试切,审批完成已经升级version
            //tryPkdNodeHasProgramFiles 试切程序包下有程序文件才需要升级版本(没有文件的是车床,无文件,直接等待回传)
            cureNode.upgradeVersionNumber();
        }
 
        //nodeService.save(cureNode);
 
        return cureNode;
    }
    /**
     * 设置固化注释,实现方式,获取文件字节下,修改后替换文件
     * @param flowProgramFile oss 文件
     *
     */
    void setGhAnnotation(FlowProgramFile flowProgramFile,String controlSystem,List<DictBiz> annoDicts) throws IOException {
        String ossName = flowProgramFile.getOssName();
        //
        try(InputStream ins = ossTemplate.statFileStream(ossName);){
            byte[] bytes = IOUtils.toByteArray(ins);
            ByteArrayInputStream byteInputStream =  new ByteArrayInputStream(bytes);
 
            //InputStream finishedStream = programAnnotationService.setGHAnnotation(byteInputStream,controlSystem,annoDicts);
            List<DictBiz> annoDictList = programAnnotationService.getAnnotionDictList();
            AnnotationProperties annoProps = config.getConfigMap().get(controlSystem);
            if(annoProps == null){
                annoProps = AnnotationProperties.getDefault();
            }
            InputStream finishedStream =AnnotationUtil.setAnnotationAndGetInputStream(byteInputStream, "GH", annoProps.getStatusLineIndex(), controlSystem, annoDictList);
            try(finishedStream) {
                finishedStream.reset();
                BladeFile bfile = ossTemplate.putFile(flowProgramFile.getName(), finishedStream);
                //替换原有的文件地址
                flowProgramFile.setOssName(bfile.getName());
 
                flowProgramFileService.updateById(flowProgramFile);
            }
        }
    }
 
 
    /**
     * 计算有效期
     * @return 过期日
     */
    private Date calculateExpireDate() {
        R<String> validMonResult = sysClient.getParamValue(ParamConstants.CURE_VALID_MONTH_KEY);
 
        int month = DEFAULT_VALID_MONTH;
        if(validMonResult.isSuccess() && validMonResult.getData()!=null){
            month = Integer.parseInt(validMonResult.getData());
        }
 
        LocalDate now = LocalDate.now();
        return DateUtil.toDate(now.plusMonths(month));
    }
 
}