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
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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
 
package org.springblade.mdm.program.service;
 
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.base.BizServiceImpl;
import org.springblade.core.tool.utils.Func;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.mapper.NcNodeMapper;
import org.springblade.mdm.program.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
 
/**
 * 程序节点
 *
 * @author yangys
 */
@Slf4j
@Service
@AllArgsConstructor
public class NcNodeService extends BizServiceImpl<NcNodeMapper, NcNode> {
 
    private final MachineService machineService;
 
    public void saveNcCode(NcNodeVO vo) {
        NcNode ncNode = new NcNode();
 
        BeanUtils.copyProperties(vo, ncNode);
        ncNode.setId(null);
        ncNode.setParentIds(buildParentIds(vo.getParentId()));
 
        this.save(ncNode);
    }
 
    /**
     * 构建父id节点
     * @param nodeId 节点id
     * @return
     */
    String buildParentIds(long nodeId){
        if(nodeId == 0L){
            return "0";
        }
        NcNode pNode = this.baseMapper.selectById(nodeId);
 
        return pNode.getParentIds()+","+pNode.getId();
    }
    /**
     * 更新节点
     * @param vo
     */
    public void updateNcNode(NcNodeVO vo) {
        NcNode ncNode = this.getById(vo.getId());
        ncNode.setName(vo.getName());
        ncNode.setNodeType(vo.getNodeType());
        ncNode.setDescription(vo.getDescription());
        ncNode.setRemark(vo.getRemark());
        ncNode.setMachineCode(vo.getMachineCode());
        ncNode.setParentIds(buildParentIds(vo.getParentId()));
 
        this.updateById(ncNode);
    }
 
    /**
     * 懒加载列表
     * @param parentId 父节点ID
     * @return
     */
    public List<NcNodeVO> lazyList(Long parentId) {
        // 判断点击搜索但是没有查询条件的情况
        if (Func.isEmpty(parentId)) {
            parentId = 0L;
        }
 
        return baseMapper.lazyList(parentId);
    }
 
 
    /**
     * 查询现有固化的程序,暂定条件:零组件号相同,且是同一机床组
     *      * @param name 程序名称
     * @param name
     * @return
     */
    public NcNode getLastProgramNode(String name) {
        return this.getBaseMapper().getLastProgramNode(name);
    }
 
    /**
     * 首页树查询
     * @param queryVO
     * @return
     */
    public List<NcNodeVO> searchList(NcNodeOldQueryVO queryVO) {
        //1.根据关进字和节点类型查询初始列表,查询的原始列表,需要hasChild字段,所以使用mapper.xml
        List<NcNodeVO> oriList = this.getBaseMapper().searchList(queryVO);
        if ("10".equals(queryVO.getNodeType())) {
            //搜索的根级别,直接返回
            return oriList;
        }
 
        List<NcNodeVO> allVos = new ArrayList<NcNodeVO>();//已经加入过的节点,用于去重
        List<NcNodeVO> rootVos = new ArrayList<NcNodeVO>();
 
        for(NcNodeVO vo : oriList){
            allVos.add(vo);
            //上级各级的节点
            List<NcNodeVO> parents = this.getBaseMapper().searchListInIds(Func.toLongList(vo.getParentIds()));
 
            for(NcNodeVO pvo : parents){
                if(pvo.getParentId() == 0L){
                    rootVos.add(pvo);
                }
                allVos.add(pvo);
            }
        }
        for(NcNodeVO root : rootVos){
            addNodeChildren(root, allVos);
 
        }
        return rootVos;
    }
 
    /**
     * 首页搜索 新的
     * @param queryVO 查询参数
     * @return
     */
    public List<NcNodeVO> searchList2(NcNodeQueryVO queryVO) {
        //1.根据零组件号和创建时间查询初始列表,查询的原始列表,需要hasChild字段,所以使用mapper.xml
        if(queryVO.getCreateTimeEnd()!=null){
            queryVO.setCreateTimeEnd(queryVO.getCreateTimeEnd().plusDays(1));
        }
        List<NcNodeVO> oriList = this.getBaseMapper().searchList2(queryVO);
 
        List<NcNodeVO> allVos = new ArrayList<>();//已经加入过的节点,用于去重
        List<NcNodeVO> rootVos = new ArrayList<>();
 
        for(NcNodeVO vo : oriList){
            allVos.add(vo);
            //上级各级的节点
            List<NcNodeVO> parents = this.getBaseMapper().searchListInIds(Func.toLongList(vo.getParentIds()));
 
            for(NcNodeVO pvo : parents){
                if(pvo.getParentId() == 0L && !rootVos.contains(pvo)){
                    rootVos.add(pvo);
                }
                if(!allVos.contains(pvo)){
                    allVos.add(pvo);
                }
 
            }
        }
        for(NcNodeVO root : rootVos){
            addNodeChildren(root, allVos);
        }
        return rootVos;
    }
 
    void addNodeChildren(NcNodeVO node, List<NcNodeVO> allNodes) {
        for(NcNodeVO vo : allNodes){
            if(Objects.equals(vo.getParentId(), node.getId())){
                node.addChildren(vo);
            }
        }
 
        if(node.getChildren()!=null && !node.getChildren().isEmpty()){
            for(NcNodeVO child : node.getChildren()){
                addNodeChildren(child, allNodes);
            }
        }
    }
 
 
 
    /**
     * 获取“程序包名”试切的最新版本
     * @param name 节点名称
     * @return 最新版本程序报名节点
     */
    public NcNode getLastEditionTryingProgramPackage(String name){
        //.or(NcNode::getIsCured,0)
        List<NcNode> pkgList = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
            .eq(NcNode::getName, name).and(i->{
                i.eq(NcNode::getIsCured, 0).or().isNull(NcNode::getIsCured);
            }).likeRight(NcNode::getParentIds,"0,1,")
            .eq(NcNode::getIsLastEdition,1).orderByDesc(NcNode::getCreateTime).list();//.eq(NcNode::getProcessEdition,processEdition)
 
        if(pkgList.isEmpty()){
            return null;
        }else{
            return pkgList.get(0);
        }
    }
 
    /**
     * 根据父节点和名称,查询文件界节点列表
     * @param name 节点/文件名称
     * @param parentId 父节点id
     */
    public NcNode getLastEditionProgramFile(String name,Long parentId) {
        List<NcNode> nodes = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_FILE)
            .eq(NcNode::getName, name).eq(NcNode::getParentId,parentId)
            .eq(NcNode::getIsLastEdition,1).list();
        if(nodes.isEmpty()){
            return null;
        }else {
            return nodes.get(0);
        }
    }
 
    /**
     * 获取试切节点node的历史列表(零组件号,工序号,工序版本,机床组)
     * @param pkgNode node
     * @return 历史列表,报错节点本身
     */
    public List<NcNode> getTryNodeHistory(NcNode pkgNode) {
        return this.lambdaQuery().eq(NcNode::getDrawingNo,pkgNode.getDrawingNo())
            .eq(NcNode::getProcessNo,pkgNode.getProcessNo())
            .eq(NcNode::getProcessEdition,pkgNode.getProcessEdition())
            .eq(NcNode::getMachineGroupCode,pkgNode.getMachineGroupCode())
            .likeLeft(NcNode::getParentIds,"0,1,")
            .list();//.ne(NcNode::getId,pkgNode.getId())
        /*
        return this.lambdaQuery().eq(NcNode::getParentId,pkgNode.getParentId())
            .eq(NcNode::getName,pkgNode.getName()).list();//.ne(NcNode::getId,pkgNode.getId())
 
         */
    }
 
    /**
     * 计算历史序号,根据零组件号,工序号,工序版次,机床组查询,查询道则使用该历史编号,查询不到使用新生成的
     */
    public long calculateHistorySerial(NcNode pkgNode) {
        NcNode node = this.lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE).eq(NcNode::getDrawingNo,pkgNode.getDrawingNo())
            .eq(NcNode::getProcessNo,pkgNode.getProcessNo()).eq(NcNode::getProcessEdition,pkgNode.getProcessEdition())
            .eq(NcNode::getMachineGroupCode,pkgNode.getMachineGroupCode()).last("limit 1").one();
 
        if(node != null && node.getHisSerial()!=null){
            return node.getHisSerial();
        }else{
            //以往没有,生成一个新的
            return System.currentTimeMillis();//使用当前毫秒数
        }
    }
 
    public int calculateVersionNumber(NcNode pkgNode) {
        NcNode node = this.lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE).eq(NcNode::getDrawingNo,pkgNode.getDrawingNo())
            .eq(NcNode::getProcessNo,pkgNode.getProcessNo()).eq(NcNode::getProcessEdition,pkgNode.getProcessEdition())
            .eq(NcNode::getMachineGroupCode,pkgNode.getMachineGroupCode()).last("limit 1").one();
 
        if(node != null && node.getVersionNumber()!=null){
            return node.getVersionNumber()+1;
        }else{
            //以往没有,生成一个新的
            return 1;
        }
    }
    /**
     * 生成程序包名/程序名称
     * @param drawingNo 零组件号
     * @param processNo 工序版次
     * @return 程序包名/程序名称
     */
    public static String genProgramName(String drawingNo,String processNo,String processEdition){
        return drawingNo+"-"+processNo+"-"+processEdition;
    }
 
    /**
     * 获取最新版本的 已固化节点
     * @param programPkgName
     * @return
     */
    public NcNode getLastEditionCuredProgramPackage(String programPkgName) {
        List<NcNode> nodes = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
            .eq(NcNode::getName, programPkgName).likeRight(NcNode::getParentIds,"0,2,").eq(NcNode::getIsCured,1)
            //.eq(NcNode::getProcessEdition, processEdition)
            .eq(NcNode::getIsLastEdition,1).list();
 
        if(nodes.isEmpty()){
            return null;
        }else {
            return nodes.get(0);
        }
    }
 
    /**
     * 获取最新版本的 已固化节点
     * @param programPkgName 程序包名
     * @param machineCode 机床编号
     * @return
     */
    public NcNode getCuredProgramPackage(String programPkgName,String processEdition,String machineCode) {
        Machine machine = machineService.getByCode(machineCode);
        List<Machine> sameGroupMachines = machineService.lambdaQuery().eq(Machine::getMachineGroupCode,machine.getMachineGroupCode()).list();
        List<String> machineCodesInGroup = sameGroupMachines.stream().map(Machine::getCode).toList();
        List<NcNode> nodes = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
            .eq(NcNode::getName, programPkgName)
            .eq(NcNode::getProcessEdition,processEdition)
            .likeRight(NcNode::getParentIds,"0,2,").eq(NcNode::getIsCured,1)
            .in(!machineCodesInGroup.isEmpty(),NcNode::getMachineCode,machineCodesInGroup)
            .eq(NcNode::getIsLastEdition,1).list();
 
        if(nodes.isEmpty()){
            return null;
        }else {
            return nodes.get(0);
        }
    }
 
    /**
     * 获取最新的固化程序,不用工序版次匹配
     * @param drawingNo
     * @param processNo
     * @param machineCode
     * @return
     */
    public NcNode getLastCuredProgramWithoutProcessEdition(String drawingNo, String processNo, String machineCode) {
        Machine machine = machineService.getByCode(machineCode);
        List<Machine> sameGroupMachines = machineService.lambdaQuery().eq(Machine::getMachineGroupCode,machine.getMachineGroupCode()).list();
        List<String> machineCodesInGroup = sameGroupMachines.stream().map(Machine::getCode).toList();
        List<NcNode> nodes = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
            .eq(NcNode::getDrawingNo, drawingNo).eq(NcNode::getProcessNo, processNo)
            .likeRight(NcNode::getParentIds,"0,2,").eq(NcNode::getIsCured,1)
            .in(!machineCodesInGroup.isEmpty(),NcNode::getMachineCode,machineCodesInGroup)
            .eq(NcNode::getIsLastEdition,1).orderByDesc(NcNode::getCreateTime).list();
 
        if(nodes.isEmpty()){
            return null;
        }else {
            return nodes.get(0);
        }
    }
 
    /**
     * 获取最新版本的 偏离节点
     * @param programPkgName 程序包名
     * @return 偏离的程序节点
     */
    public NcNode getLastEditionDeviationProgramPackage(String programPkgName) {//,String processEdition
        List<NcNode> nodes = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
            .eq(NcNode::getName, programPkgName)
            //.eq(NcNode::getProcessEdition, processEdition)
            .likeRight(NcNode::getParentIds,"0,3,")
            .eq(NcNode::getIsLastEdition,1).list();
 
        if(nodes.isEmpty()){
            return null;
        }else {
            return nodes.get(0);
        }
    }
 
    /**
     * 根据流程实例id获取node节点,都是程序包节点
     * @param processInstanceId 流程实例id
     * @return 对应额系欸但那
     */
    public NcNode getByProcessInstanceId(String processInstanceId) {
        Optional<NcNode> nodeOpt = this.lambdaQuery().eq(NcNode::getProcessInstanceId,processInstanceId).oneOpt();
        return nodeOpt.orElse(null);
    }
 
    /**
     * 物理删除节点id下的子节点(性能考虑,否则数据太多)
     * @param nodeId 节点id
     */
    public void deleteSubNodes(Long nodeId) {
        this.baseMapper.deleteSubNodes(nodeId);
    }
 
    /**
     * 获取程序包下所有层序文件节点
     * @param packageNodeId 程序包名 节点id
     * @return 包下属的程序文件
     */
    public List<NcNode> getProgramFilesByPackageId(Long packageNodeId) {
        return this.lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_FILE)
            .eq(NcNode::getParentId,packageNodeId).eq(NcNode::getIsLastEdition,1).list();
    }
    /**
     * 升级版本号(+1)
     * @param nodeId 节点id
     */
    @Transactional
    public void upgradeVersionNumber(Long nodeId) {
        NcNode node = this.getById(nodeId);
        node.upgradeVersionNumber();
        this.updateById(node);
 
    }
 
    /**
     * 锁定节点
     * @param id 程序包节点id
     */
    @Transactional
    public void lock(Long id) {
        NcNode node = this.getById(id);
        node.lock();
        this.updateById(node);
    }
    @Transactional
    public void lock(Long id,String remark) {
        NcNode node = this.getById(id);
        node.lock(remark);
        this.updateById(node);
    }
    @Transactional
    public void unlock(Long id) {
        NcNode node = this.getById(id);
        node.unlock();
        this.updateById(node);
    }
 
    /**
     * 查询偏离单的序号
     * @param programPkgNode 偏离单的程序包名节点
     * @return 序号
     */
    /*
    public long getDeviationSerialForNode(NcNode programPkgNode) {
        return lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
            .eq(NcNode::getName,programPkgNode.getName())
 
            .eq(NcNode::getDrawingNo,programPkgNode.getDrawingNo())
            .eq(NcNode::getProcessNo,programPkgNode.getProcessNo())
            .eq(NcNode::getProcessEdition,programPkgNode.getProcessEdition())
 
            .isNotNull(NcNode::getDeviation)
            .le(NcNode::getCreateTime,programPkgNode.getCreateTime())  //时间小于等于当前节点
            .count();
    }
    */
 
    /**
     * 根据上级节点id,移动下面的加工机床节点
     * @param parentId 上级节点id
     */
    /*
    public void deleteMachineGroupNodeByParentId(Long parentId) {
        baseMapper.deleteMachineGroupNodeByParentId(parentId);
    }*/
 
    /**
     * 删除所偶非最新版本的数据(hodeHIs里面已经保存过)
     */
    public void deleteOldEditionNodeData() {
        baseMapper.deleteOldEditionNodeData();
    }
 
    /**
     * //更新已固化的,同名、不同机床组的程序为锁定状态
     * @param packageNode
     */
    public void lockSameNameOtherMachineGroupProgramPackage(NcNode packageNode) {
        lambdaUpdate().eq(NcNode::getDrawingNo,packageNode.getDrawingNo())
            .eq(NcNode::getProcessNo,packageNode.getProcessNo())
            .eq(NcNode::getName,packageNode.getName())
            .ne(NcNode::getMachineGroupCode,packageNode.getMachineGroupCode())
            .eq(NcNode::getIsCured,1)
            .eq(NcNode::getIsLastEdition,1)
            .set(NcNode::getIsLocked,NcNode.LOCKED)
            .set(NcNode::getRemark,"回传固化同名程序锁定")
            .update();
    }
}