yangys
2025-08-16 66db2ddb74b0f1afba2ccb237ac949959501283f
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
package org.springblade.mdm.flow.task.cure;
 
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.checkerframework.checker.units.qual.N;
import org.flowable.engine.delegate.DelegateExecution;
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.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.service.FlowCommonService;
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.NcNodeService;
import org.springblade.mdm.program.service.ProgramAnnotationService;
import org.springblade.mdm.utils.FileContentUtil;
import org.springblade.system.feign.ISysClient;
import org.springblade.system.pojo.entity.Dict;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
 
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
 
@Slf4j
@Component("cureFinishOperateTask")
@AllArgsConstructor
public class CureFinishOperateTask {
    private final NcNodeService nodeService;
    private final NcNodeAutoCreateService ncNodeAutoCreateService;
    private final FlowCommonService flowCommonService;
    private final FlowProgramFileService flowProgramFileService;
    private final ISysClient sysClient;
    private final OssTemplate ossTemplate;
    private final ProgramAnnotationService programAnnotationService;
    private final MachineService machineService;
 
    public static final String GH = "GH";
 
 
    /**
     * 默认有效期间(月数),2年
     */
    private static final int DEFAULT_VALID_MONTH = 24;
    private final NcNodeService ncNodeService;
 
    /**
     * 固化审批通过处理任务,
     * @param execution 流程execution
     */
    @Transactional
    public void execute(DelegateExecution execution) throws IOException {
        log.info("执行固化程序任务服务,流程实例id={}", execution.getProcessInstanceId());
        //固化程序检查有效期,
        dealWithNode(execution.getProcessInstanceId());
    }
 
    /**
     * 处理node状态。
     * @param processInstanceId 流程实例id
     */
    void dealWithNode(String processInstanceId) throws IOException {
        //程序包节点和下属程序节点(包括历史节点非最新版本的)从试切挪到固化下面
        //程序包节点 设置未已固化
        NcNode pkgNode =  nodeService.lambdaQuery().eq(NcNode::getProcessInstanceId, processInstanceId).one();
        if(pkgNode.isDeviationProgram()){
            //偏离的程序直接锁定
            pkgNode.setIsLocked(1);
            nodeService.updateById(pkgNode);
        }else {
            //试切的
            pkgNode.setIsCured(1);
            //设置过期日期
            pkgNode.upgradeVersionNUmber();
            pkgNode.setExpireDate(calculateExpireDate());
            nodeService.updateById(pkgNode);
 
            List<NcNode> historyProgramPackageNodes = nodeService.getNodeHistory(pkgNode);
            moveNodeToCuredTree(pkgNode, historyProgramPackageNodes, flowCommonService.getProgramProperties(processInstanceId));
        }
    }
 
    /**
     * 将节点和历史节点挪动到固化的同级节点下
     * @param pkgNode 要挪动的节点
     * @param historyProgramPackageNodes 程序包名 历史节点
     */
    void moveNodeToCuredTree(NcNode pkgNode,List<NcNode> historyProgramPackageNodes, FlowProgramProperties programProperties) throws IOException {
        //创建节点到机床级别.(固化树)
        NcNode machineNode = ncNodeAutoCreateService.createNodeTreeToMachine(programProperties);
 
        //机床下现在没有文件了,程序包名升级与机床同级了,改为找到机床同级程序包名更新了
        this.nodeService.lambdaUpdate().likeRight(NcNode::getParentIds, machineNode.getParentIds())
            .in(NcNode::getNodeType, Arrays.asList(NcNode.TYPE_PROGRAM_PACKAGE,NcNode.TYPE_PROGRAM_FILE))
            .set(NcNode::getIsLastEdition,0).set(NcNode::getIsLocked,1).update();
 
        for(NcNode hisPackageNode : historyProgramPackageNodes){
            if(!hisPackageNode.getId().equals(pkgNode.getId())){
                hisPackageNode.setIsLastEdition(0);
            }
            hisPackageNode.setParentId(machineNode.getParentId());
            hisPackageNode.setParentIds(machineNode.getParentIds());//程序包与机床节点同级
 
            //处理程序包下层的程序节点
            List<NcNode> programNodes = nodeService.lambdaQuery().eq(NcNode::getParentId,hisPackageNode.getId()).list();
            for(NcNode programNode : programNodes){
                programNode.setIsLastEdition(0);
                programNode.setParentIds(hisPackageNode.getParentIds()+","+hisPackageNode.getId());
            }
            nodeService.updateBatchById(programNodes);
        }
        nodeService.updateBatchById(historyProgramPackageNodes);
 
        Machine machine = machineService.getByCode(pkgNode.getMachineCode());
        List<Dict> annoDicts = programAnnotationService.getAnnotionList();
        //新的流程文件,需要在包节点下新建,不能用老的
        List<FlowProgramFile> files = flowProgramFileService.lambdaQuery().eq(FlowProgramFile::getProcessInstanceId,pkgNode.getProcessInstanceId()).list();
        for(FlowProgramFile flowProgramFile : files){
            NcNode newProgNode = new NcNode();
            newProgNode.setName(flowProgramFile.getName());
            newProgNode.setNodeType(NcNode.TYPE_PROGRAM_FILE);
            newProgNode.setParentId(pkgNode.getId());
            newProgNode.setParentIds(pkgNode.getParentIds()+","+pkgNode.getId());
            newProgNode.setIsLastEdition(1);
            newProgNode.setVersionNumber(pkgNode.getVersionNumber());
            newProgNode.setFlowProgramFileId(flowProgramFile.getId());
            newProgNode.setIsCured(1);
            ncNodeService.save(newProgNode);
 
            //修改文件内容更新注释,并更新文件数据的地址
            ///替换注释后总是不行啊
            setGhAnnotation(flowProgramFile,machine.getMachineGroupCode(),annoDicts);
 
            flowProgramFileService.updateById(flowProgramFile);
        }
    }
 
    /**
     * 设置固化注释,实现方式,获取文件字节下,修改后替换文件
     * @param flowProgramFile oss 文件
     *
     */
    void setGhAnnotation(FlowProgramFile flowProgramFile,String machineGroup,List<Dict> annoDicts) throws IOException {
        String ossName = flowProgramFile.getOssName();
        //
        try(InputStream ins = ossTemplate.statFileStream(ossName);){
            byte[] bytes = IOUtils.toByteArray(ins);
            ByteArrayInputStream byteInputStream =  new ByteArrayInputStream(bytes);
 
            String annoTxt = programAnnotationService.generateAnnotation("GH",machineGroup,annoDicts);
            int statusLineIndex = 2;
            String line2 = FileContentUtil.readLineAt(byteInputStream,statusLineIndex);//第三行应该是状态注释
            byteInputStream.reset();
            InputStream finishedStream;
            if(programAnnotationService.isAnnotation(line2,machineGroup,annoDicts)){
                finishedStream = FileContentUtil.replaceAtLine(byteInputStream,statusLineIndex,annoTxt);
            }else{
                finishedStream = FileContentUtil.insertLine(byteInputStream,statusLineIndex,annoTxt);
            }
            try(finishedStream) {
                finishedStream.reset();
                BladeFile bfile = ossTemplate.putFile(flowProgramFile.getName(), finishedStream);
                //替换原有的文件地址
                flowProgramFile.setOssName(bfile.getName());
            }
        }
    }
 
    /**
     * 计算有效期
     * @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));
    }
 
}