ludc
2023-03-30 1dc8a3226e9ccb8b35567a0a55495d53b6352703
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
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
package com.vci.ubcs.code.service.impl;
 
 
import com.alibaba.fastjson.JSONObject;
import com.vci.ubcs.code.constant.MdmBtmTypeConstant;
import com.vci.ubcs.code.dao.CodeBasicSecDaoI;
import com.vci.ubcs.code.mapper.CodeClassifyValueMapper;
import com.vci.ubcs.code.mapper.CodeFixedValueMapper;
import com.vci.ubcs.code.enumpack.CodeSecTypeEnum;
import com.vci.ubcs.code.lifecycle.CodeRuleLC;
import com.vci.ubcs.code.entity.CodeBasicSecDO;
import com.vci.ubcs.code.entity.CodeClassifyValueDO;
import com.vci.ubcs.code.entity.CodeFixedValueDO;
import com.vci.ubcs.code.service.CodeBasicSecServiceI;
import com.vci.ubcs.code.service.CodeClassifyValueServiceI;
import com.vci.ubcs.code.service.CodeFixedValueServiceI;
import com.vci.ubcs.code.service.CodeRuleServiceI;
import com.vci.frameworkcore.lcstatuspck.FrameworkDataLCStatus;
import com.vci.starter.revision.bo.TreeWrapperOptions;
import com.vci.starter.revision.service.RevisionModelUtil;
import com.vci.starter.web.constant.QueryOptionConstant;
import com.vci.starter.web.exception.VciBaseException;
import com.vci.starter.web.pagemodel.*;
import com.vci.starter.web.util.BeanUtilForVCI;
import com.vci.starter.web.util.VciBaseUtil;
import com.vci.starter.web.wrapper.VciParentQueryOption;
import com.vci.starter.web.wrapper.VciQueryWrapperForDO;
import com.vci.web.enumpck.OsCodeFillTypeEnum;
import com.vci.web.pageModel.BatchCBO;
import com.vci.web.pageModel.UIFormReferVO;
import com.vci.web.service.BdSelectInputCharServiceI;
import com.vci.web.service.WebBoServiceI;
import com.vci.web.util.WebUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vci.ubcs.code.dto.CodeBasicSecDTO;
import com.vci.ubcs.code.vo.pagemodel.CodeBasicSecVO;
import com.vci.ubcs.code.vo.pagemodel.CodeClassifyValueVO;
import com.vci.ubcs.code.vo.pagemodel.CodeFixedValueVO;
import com.vci.ubcs.code.vo.pagemodel.CodeRuleVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import plm.bs.bom.clientobject.ClientBusinessObject;
 
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
 
import static com.vci.frameworkcore.constant.FrameWorkLangCodeConstant.*;
 
/**
 * 码段基础信息服务
 *
 * @author weidy
 * @date 2022-01-24
 */
@Service
public class CodeBasicSecServiceImpl implements CodeBasicSecServiceI {
 
    /**
     * 日志
     */
    private Logger logger = LoggerFactory.getLogger(getClass());
 
    /**
     * 数据操作层
     */
    @Resource
    private CodeBasicSecDaoI codeBasicSecMapper;
 
    /**
     * 业务类型操作的服务
     */
    @Autowired
    @Lazy
    private WebBoServiceI boService;
 
    /**
     * 对象的操作
     */
    @Autowired
    private RevisionModelUtil revisionModelUtil;
 
    /**
     * 主数据编码规则服务
     */
    @Autowired
    @Lazy
    private CodeRuleServiceI codeRuleService;
 
    /**
     * 分类码段的码值服务
     */
    @Autowired
    private CodeClassifyValueServiceI codeClassifyValueService;
 
    /**
     * 分类码段的码值数据操作层
     */
    @Autowired
    private CodeClassifyValueMapper codeClassifyValueMapper;
 
    /**
     * 固定码段的码值的服务
     */
    @Autowired
    private CodeFixedValueServiceI fixedValueService;
 
    /**
     * 固定码段的码值数据操作层
     */
    @Autowired
    private CodeFixedValueMapper fixedValueMapper;
    /**
     * 上层分类码段的属性名称
     */
    private static  final String PARENT_FIELD_NAME = "parentclassifysecoid";
 
    /**
     * 上级分类码值的属性名称
     */
    private static final String PARENT_CLASSIFY_VALUE_FIELD_NAME = "parentClassifyValueOid";
 
    /**
     * 可选可输服务
     */
    @Autowired
    private BdSelectInputCharServiceI charService;
 
    /**
     * 查询所有的码段基础信息
     *
     * @param conditionMap 查询条件
     * @param pageHelper   分页和排序
     * @return 执行结果
     * @throws VciBaseException 查询条件和分页出错的时候会抛出异常
     */
    @Override
    public DataGrid<CodeBasicSecVO> gridCodeBasicSec(Map<String, String> conditionMap, PageHelper pageHelper) throws VciBaseException {
        if (pageHelper == null) {
            pageHelper = new PageHelper(-1);
        }
        pageHelper.addDefaultAsc("ordernum");
        if(!conditionMap.containsKey("pkCodeRule") || StringUtils.isBlank(conditionMap.get("pkCodeRule"))){
            return new DataGrid<>();
        }
        List<CodeBasicSecDO> doList = codeBasicSecMapper.selectByCondition(conditionMap, pageHelper);
        DataGrid<CodeBasicSecVO> dataGrid = new DataGrid<CodeBasicSecVO>();
        if (!CollectionUtils.isEmpty(doList)) {
            dataGrid.setData(codeBasicSecDO2VOs(doList));
            dataGrid.setTotal(VciBaseUtil.getInt(String.valueOf(codeBasicSecMapper.countByCondition(conditionMap))));
        }
        return dataGrid;
    }
 
    /**
     * 批量数据对象转换为显示对象
     *
     * @param codeBasicSecDOs 数据对象列表
     * @return 显示对象
     * @throws VciBaseException 参数为空或者不存在的时候会抛出异常
     */
    @Override
    public List<CodeBasicSecVO> codeBasicSecDO2VOs(Collection<CodeBasicSecDO> codeBasicSecDOs) throws VciBaseException {
        List<CodeBasicSecVO> voList = new ArrayList<CodeBasicSecVO>();
        if (!CollectionUtils.isEmpty(codeBasicSecDOs)) {
            for (CodeBasicSecDO s : codeBasicSecDOs) {
                CodeBasicSecVO vo = codeBasicSecDO2VO(s);
                if (vo != null) {
                    voList.add(vo);
                }
            }
        }
        return voList;
    }
 
    /**
     * 批量数据对象转换为显示对象
     *
     * @param codeBasicSecDOs 数据对象列表
     * @param hasFixedValue 是否有固定值
     * @return 显示对象
     * @throws VciBaseException 参数为空或者不存在的时候会抛出异常
     */
    @Override
    public List<CodeBasicSecVO> codeBasicSecDO2VOs(Collection<CodeBasicSecDO> codeBasicSecDOs, boolean hasFixedValue) throws VciBaseException {
        List<CodeBasicSecVO> voList = new ArrayList<CodeBasicSecVO>();
        if (!CollectionUtils.isEmpty(codeBasicSecDOs)) {
            for (CodeBasicSecDO s : codeBasicSecDOs) {
                CodeBasicSecVO vo = codeBasicSecDO2VO(s);
                if (vo != null) {
                    voList.add(vo);
                }
            }
        }
        if(hasFixedValue && !CollectionUtils.isEmpty(voList)){
            List<CodeBasicSecVO> fixedSecVOList = voList.stream().filter(s -> CodeSecTypeEnum.CODE_FIXED_SEC.getValue().equalsIgnoreCase(s.getSectype())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(fixedSecVOList)){
                //查询固定码的码值
                Map<String, List<CodeFixedValueVO>> secValueMap = fixedValueService.listCodeFixedValueBySecOids(fixedSecVOList.stream().map(CodeBasicSecVO::getOid).collect(Collectors.toList()));
                voList.stream().forEach(vo->{
                    vo.setFixedValueVOList(secValueMap.getOrDefault(vo.getOid(),null));
                });
            }
        }
        return voList;
    }
 
    /**
     * 数据对象转换为显示对象
     *
     * @param codeBasicSecDO 数据对象
     * @return 显示对象
     * @throws VciBaseException 拷贝属性出错的时候会抛出异常
     */
    @Override
    public CodeBasicSecVO codeBasicSecDO2VO(CodeBasicSecDO codeBasicSecDO) throws VciBaseException {
        CodeBasicSecVO vo = new CodeBasicSecVO();
        if (codeBasicSecDO != null) {
            BeanUtilForVCI.copyPropertiesIgnoreCase(codeBasicSecDO, vo);
            //如果有lcstatus的类的话
            if (true) {
                //vo.setLcStatusText({lcStatusFullClassName}.getTextByValue(vo.getLcStatus()));
            }
        }
        return vo;
    }
 
    /**
     * 增加码段基础信息
     *
     * @param codeBasicSecDTO 码段基础信息数据传输对象
     * @return 执行结果
     * @throws VciBaseException 参数为空,唯一项,必输项不通过时会抛出异常
     */
    @Override
    public CodeBasicSecVO addSave(CodeBasicSecDTO codeBasicSecDTO) throws VciBaseException {
        VciBaseUtil.alertNotNull(codeBasicSecDTO, "需要添加的数据对象",codeBasicSecDTO.getPkCodeRule(),"编码规则的主键");
        CodeRuleVO ruleVO = codeRuleService.getObjectByOid(codeBasicSecDTO.getPkCodeRule());
        if(!CodeRuleLC.EDITING.getValue().equalsIgnoreCase(ruleVO.getLcStatus())){
            throw new VciBaseException("编码规则的状态不是【" + CodeRuleLC.EDITING.getText() + "】!不允许修改");
        }
        KeyValue attrKv = checkAttrNullableBySecType(codeBasicSecDTO);
        if (! "success".equals(attrKv.getKey())){
            throw new VciBaseException(attrKv.getValue() + "不能为空");
        }
 
 
 
        //将DTO转换为DO
        CodeBasicSecDO codeBasicSecDO = new CodeBasicSecDO();
        BeanUtilForVCI.copyPropertiesIgnoreCase(codeBasicSecDTO, codeBasicSecDO);
        //排序号,默认等于当前已有的数量加1
        Map<String,String> conditionMap = new HashMap<>();
        conditionMap.put("pkCodeRule",ruleVO.getOid());
        Long total = codeBasicSecMapper.countByCondition(conditionMap);
        if(total == null){
            total = 0L;
        }
        codeBasicSecDO.setOrderNum(total.intValue() + 1);
 
        //补位的时候,要控制补位字符
        if((OsCodeFillTypeEnum.LEFT.getValue().equalsIgnoreCase(codeBasicSecDO.getCodeFillType())
         || OsCodeFillTypeEnum.RIGHT.getValue().equalsIgnoreCase(codeBasicSecDO.getCodeFillType()))
                && StringUtils.isBlank(codeBasicSecDO.getCodeFillSeparator())){
            throw new VciBaseException("当补位方式为左补位或者右补位的时候,补位字符不能为空");
        }
        //引用码段的时候,需要判断参照的信息是否正确
        if(CodeSecTypeEnum.CODE_REFER_SEC.getValue().equalsIgnoreCase(codeBasicSecDO.getSecType())){
            if(StringUtils.isBlank(codeBasicSecDO.getReferConfig())){
                throw new VciBaseException("引用码段的时候,需要填写 参照配置 的内容");
            }
            try{
                JSONObject.parseObject(codeBasicSecDO.getReferConfig(), UIFormReferVO.class);
            }catch (Throwable e){
                throw new VciBaseException("引用码段的时候,参照配置的内容的格式不正确,",new String[0],e);
            }
        }
        codeBasicSecMapper.insert(codeBasicSecDO);
        SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo();
        if(StringUtils.isNotBlank(codeBasicSecDO.getCodeFillSeparator())){
            charService.save(MdmBtmTypeConstant.CODE_BASIC_SEC,"codefileseparator",codeBasicSecDO.getCodeFillSeparator(),sessionInfo);
        }
        return codeBasicSecDO2VO(codeBasicSecDO);
    }
 
    /**
     * 修改码段基础信息
     *
     * @param codeBasicSecDTO 码段基础信息数据传输对象
     * @return 执行结果
     * @throws VciBaseException 参数为空,唯一项,必输项不通过时会抛出异常
     */
    @Override
    public CodeBasicSecVO editSave(CodeBasicSecDTO codeBasicSecDTO) throws VciBaseException {
        VciBaseUtil.alertNotNull(codeBasicSecDTO, "需要添加的数据对象");
        KeyValue attrKv = checkAttrNullableBySecType(codeBasicSecDTO);
        if (! "success".equals(attrKv.getKey())){
            throw new VciBaseException(attrKv.getValue() + "不能为空");
        }
        //将DTO转换为DO
        CodeBasicSecDO codeBasicSecDO = selectByOid(codeBasicSecDTO.getOid());
        boolean status = codeRuleService.checkEditDelStatus(codeRuleService.getObjectByOid(codeBasicSecDO.getPkCodeRule()).getLcStatus());
        if (!status){
            //返回错误信息
            throw new VciBaseException("编码规则不允许编辑或删除!");
        } else {
            //补位的时候,要控制补位字符
            if((OsCodeFillTypeEnum.LEFT.getValue().equalsIgnoreCase(codeBasicSecDO.getCodeFillType())
                    || OsCodeFillTypeEnum.RIGHT.getValue().equalsIgnoreCase(codeBasicSecDO.getCodeFillType()))
                    && StringUtils.isBlank(codeBasicSecDO.getCodeFillSeparator())){
                throw new VciBaseException("当补位方式为左补位或者右补位的时候,补位字符不能为空");
            }
            //引用码段的时候,需要判断参照的信息是否正确
            if(CodeSecTypeEnum.CODE_REFER_SEC.getValue().equalsIgnoreCase(codeBasicSecDO.getSecType())){
                if(StringUtils.isBlank(codeBasicSecDO.getReferConfig())){
                    throw new VciBaseException("引用码段的时候,需要填写 参照配置 的内容");
                }
                try{
                    JSONObject.parseObject(codeBasicSecDO.getReferConfig(), UIFormReferVO.class);
                }catch (Throwable e){
                    throw new VciBaseException("引用码段的时候,参照配置的内容的格式不正确,",new String[0],e);
                }
            }
            revisionModelUtil.copyFromDTOIgnore(codeBasicSecDTO, codeBasicSecDO);
            codeBasicSecMapper.updateByPrimaryKey(codeBasicSecDO);
            SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo();
            if(StringUtils.isNotBlank(codeBasicSecDO.getCodeFillSeparator())){
                charService.save(MdmBtmTypeConstant.CODE_BASIC_SEC,"codefileseparator",codeBasicSecDO.getCodeFillSeparator(),sessionInfo);
            }
        }
        return codeBasicSecDO2VO(codeBasicSecDO);
    }
 
 
    /**
     * 校验是否可以删除,如果存在下级,并且下级有数据引用则不能删除
     *
     * @param codeBasicSecDTO 数据传输对象
     * @param codeBasicSecDO  数据库中的数据对象
     * @return success为true为可以删除,false表示有数据引用,obj为true表示有下级
     */
    private BaseResult checkIsCanDeleteForDO(CodeBasicSecDTO codeBasicSecDTO, CodeBasicSecDO codeBasicSecDO) {
        boService.checkTs(codeBasicSecDTO);
        if (!checkIsLinked(null, codeBasicSecDO.getOid())) {
            return BaseResult.success();
        } else {
            return BaseResult.fail(DATA_LINKED_NOT_DELETE, new String[]{""});
        }
    }
 
    /**
     * 校验是否被引用
     *
     * @param codeRuleOid     编码规则主键
     * @param codeBasicSecOid 编码基础信息主键
     * @return true表示已被引用,false表示未被引用
     * @throws VciBaseException 被引用的时候会抛出异常
     */
    private boolean checkIsLinked(String codeRuleOid, String codeBasicSecOid) throws VciBaseException {
        boolean flag = true;
        if (StringUtils.isNotBlank(codeRuleOid)) {
            boolean status = codeRuleService.checkEditDelStatus(codeRuleService.getObjectByOid(codeRuleOid).getLcStatus());
            if (!status){
                return true;
            }
            boolean alreadyInUse = codeRuleService.isAlreadyInUse(codeRuleOid);
            if (!alreadyInUse){
               flag = false;
            }
        } else {
            boolean status = codeRuleService.checkEditDelStatus(codeRuleService.getObjectByOid(codeBasicSecMapper.selectByPrimaryKey(codeBasicSecOid).getPkCodeRule()).getLcStatus());
            if (!status){
                return true;
            }
            boolean alreadyInUse = codeRuleService.isAlreadyInUse(codeBasicSecMapper.selectByPrimaryKey(codeBasicSecOid).getPkCodeRule());
            if (!alreadyInUse){
                flag = false;
            }
        }
        return flag;
    }
 
    /**
     * 删除码段基础信息
     *
     * @param codeBasicSecDTO 码段基础信息数据传输对象,oid和ts需要传输
     * @return 删除结果反馈::success:成功,fail:失败
     * @throws VciBaseException 参数为空,被引用时抛出异常
     */
    @Override
    public BaseResult deleteCodeBasicSec(CodeBasicSecDTO codeBasicSecDTO) throws VciBaseException {
        VciBaseUtil.alertNotNull(codeBasicSecDTO, "码段基础信息数据对象", codeBasicSecDTO.getOid(), "码段基础信息的主键");
        return deleteCodeBasicSecByPrimaryKey(codeBasicSecDTO.getOid());
    }
 
    /**
     * 主键删除码段基础信息
     *
     * @param oid 码段基础信息主键
     * @return 删除结果反馈::success:成功,fail:失败
     * @throws VciBaseException 参数为空,被引用时抛出异常
     */
    @Override
    public BaseResult deleteCodeBasicSecByPrimaryKey(String oid) throws VciBaseException {
        CodeBasicSecDO codeBasicSecDO = selectByOid(oid);
        boolean isLinked = checkIsLinked(codeBasicSecDO.getPkCodeRule(), oid);
        if (isLinked) {
            return BaseResult.fail("编码规则已被引用,不允许编辑或删除");
        }
        Map<String,String> conditionMap = new HashMap<>();
        //执行删除操作
        WebUtil.setPersistence(false);
        BatchCBO batchCBO = codeBasicSecMapper.deleteByPrimaryKey(oid);
        Set<ClientBusinessObject> deleteSet = new HashSet<>();
        deleteSet.addAll(batchCBO.getDeleteCbos());
        if (CodeSecTypeEnum.CODE_FIXED_SEC.getValue().equals(codeBasicSecDO.getSecType())){
            conditionMap.put("codefixedsecoid",codeBasicSecDO.getOid());
            VciQueryWrapperForDO wrapper = new VciQueryWrapperForDO(conditionMap, CodeFixedValueDO.class);
            List<CodeFixedValueDO> fixedValueDOS = fixedValueMapper.selectByWrapper(wrapper);
            BatchCBO valueCBO = fixedValueMapper.batchDeleteByOids(fixedValueDOS.stream().map(CodeFixedValueDO::getOid).collect(Collectors.toSet()));
            deleteSet.addAll(valueCBO.getDeleteCbos());
        }
        if (CodeSecTypeEnum.CODE_CLASSIFY_SEC.getValue().equals(codeBasicSecDO.getSecType())){
            conditionMap.put("codeclassifysecoid",codeBasicSecDO.getOid());
            VciQueryWrapperForDO wrapper = new VciQueryWrapperForDO(conditionMap, CodeClassifyValueDO.class);
            List<CodeClassifyValueDO> classifyValueDOS = codeClassifyValueMapper.selectByWrapper(wrapper);
            if(!CollectionUtils.isEmpty(classifyValueDOS)) {
                BatchCBO valueCBO = codeClassifyValueMapper.batchDeleteByOids(classifyValueDOS.stream().map(CodeClassifyValueDO::getOid).collect(Collectors.toSet()));
                deleteSet.addAll(valueCBO.getDeleteCbos());
            }
        }
        batchCBO.setDeleteCbos(deleteSet);
        WebUtil.setPersistence(true);
        boService.persistenceBatch(batchCBO);
        return (batchCBO != null && batchCBO.getDeleteCbos() != null && batchCBO.getDeleteCbos().size() > 0) ? BaseResult.successMsg(DELETE_SUCCESS) : BaseResult.fail(DELETE_FAIL);
    }
 
    /**
     * 主键获取码段基础信息
     *
     * @param oid 主键
     * @return 码段基础信息显示对象
     * @throws VciBaseException 参数为空,数据不存在时会抛出异常
     */
    @Override
    public CodeBasicSecVO getObjectByOid(String oid) throws VciBaseException {
        return codeBasicSecDO2VO(selectByOid(oid));
    }
 
    /**
     * 主键查询数据对象
     *
     * @param oid 主键
     * @return 数据对象
     * @throws VciBaseException 参数为空,并且数据不存在的时候会抛出异常
     */
    private CodeBasicSecDO selectByOid(String oid) throws VciBaseException {
        VciBaseUtil.alertNotNull(oid, "主键");
        CodeBasicSecDO codeBasicSecDO = codeBasicSecMapper.selectByPrimaryKey(oid.trim());
        if (codeBasicSecDO == null || StringUtils.isBlank(codeBasicSecDO.getOid())) {
            throw new VciBaseException(DATA_OID_NOT_EXIST);
        }
        return codeBasicSecDO;
    }
 
    /**
     * 主键批量获取码段基础信息
     *
     * @param oidCollections 主键集合,但是受性能影响,建议一次查询不超过10000个
     * @return 码段基础信息显示对象
     * @throws VciBaseException 查询出现异常时会抛出
     */
    @Override
    public Collection<CodeBasicSecVO> listCodeBasicSecByOids(Collection<String> oidCollections) throws VciBaseException {
        VciBaseUtil.alertNotNull(oidCollections, "数据对象主键集合");
        List<CodeBasicSecDO> codeBasicSecDOList = listCodeBasicSecDOByOidCollections(oidCollections);
        return codeBasicSecDO2VOs(codeBasicSecDOList);
    }
 
    /**
     * 使用主键集合查询数据对象
     *
     * @param oidCollections 主键的集合
     * @return 数据对象列表
     */
    private List<CodeBasicSecDO> listCodeBasicSecDOByOidCollections(Collection<String> oidCollections) {
        List<CodeBasicSecDO> codeBasicSecDOList = new ArrayList<CodeBasicSecDO>();
        if (!CollectionUtils.isEmpty(oidCollections)) {
            Collection<Collection<String>> oidCollectionsList = VciBaseUtil.switchCollectionForOracleIn(oidCollections);
            for (Collection<String> oids : oidCollectionsList) {
                List<CodeBasicSecDO> tempDOList = codeBasicSecMapper.selectByPrimaryKeyCollection(oids);
                if (!CollectionUtils.isEmpty(tempDOList)) {
                    codeBasicSecDOList.addAll(tempDOList);
                }
            }
        }
        return codeBasicSecDOList;
    }
 
 
    /**
     * 参照码段基础信息列表
     *
     * @param conditionMap 查询条件
     * @param pageHelper   分页和排序
     * @return 码段基础信息显示对象列表,生效的内容
     * @throws VciBaseException 查询条件和分页出错的时候会抛出异常
     */
    @Override
    public DataGrid<CodeBasicSecVO> refDataGridCodeBasicSec(Map<String, String> conditionMap, PageHelper pageHelper) throws VciBaseException {
        if (conditionMap == null) {
            conditionMap = new HashMap<String, String>();
        }
        return gridCodeBasicSec(conditionMap, pageHelper);
    }
 
    /**
     * 克隆码段信息
     *
     * @param oidList 源码段信息主键集合
     * @param pkCodeRule 目标编码规则
     * @return 克隆结果反馈::success:成功,fail:失败
     */
    @Override
    public BaseResult cloneCodeBasicSec(List<String> oidList, String pkCodeRule) {
        boolean isLinked = checkIsLinked(pkCodeRule,null);
        if (isLinked) {
            return BaseResult.fail("编码规则已被引用,不允许编辑或删除");
        }
        List<CodeBasicSecDO> createList = new ArrayList<>();
        List<CodeBasicSecDO> basicSecDOS = codeBasicSecMapper.selectByPrimaryKeyCollection(oidList);
        basicSecDOS.forEach(sec -> {
            CodeBasicSecDO newSecDO = new CodeBasicSecDO();
            BeanUtilForVCI.copyPropertiesIgnoreCase(sec,newSecDO);
            newSecDO.setOid("");
            newSecDO.setNameOid("");
            newSecDO.setRevisionOid("");
            newSecDO.setId(newSecDO.getId() + "_copy");
            newSecDO.setName(newSecDO.getName() + "_copy");
            newSecDO.setPkCodeRule(pkCodeRule);
            createList.add(newSecDO);
        });
        codeBasicSecMapper.batchInsert(createList);
        return BaseResult.success();
    }
 
    /**
     * 根据码段分类的类型判断属性是否是空的
     *
     * @param codeBasicSecDTO 码段基础信息数据传输对象
     * @return 有空的则传key-属性名 value-字段含义,没有空的则传 key-success value-true
     */
    @Override
    public KeyValue checkAttrNullableBySecType(CodeBasicSecDTO codeBasicSecDTO) {
        VciBaseUtil.alertNotNull(codeBasicSecDTO.getSectype(), "码段分类");
        String secType = codeBasicSecDTO.getSectype();
        HashMap<String, String> attrMap = JSONObject.parseObject(JSONObject.toJSONString(codeBasicSecDTO), HashMap.class);
        Map<String, String> notNullableAttr = getNotNullableAttr(secType);
        if (notNullableAttr == null) {
            throw new VciBaseException("码段分类填写出错,请查验后重试");
        }
        for (String key : notNullableAttr.keySet()) {
            if (StringUtils.isBlank(WebUtil.getStringValueFromObject(attrMap.get(key)))) {
                KeyValue kv = new KeyValue();
                kv.setKey(key);
                kv.setValue(notNullableAttr.get(key));
                return kv;
            }
        }
        KeyValue kv = new KeyValue();
        kv.setKey("success");
        kv.setValue("true");
        return kv;
    }
 
    /**
     * 使用规则的主键获取对应的码段内容
     *
     * @param ruleOid 规则的内容
     * @return 码段的内容
     */
    @Override
    public List<CodeBasicSecVO> listCodeBasicSecByRuleOid(String ruleOid) {
        if(StringUtils.isBlank(ruleOid)){
            return new ArrayList<>();
        }
        Map<String,String> conditionMap = new HashMap<>();
        conditionMap.put("pkCodeRule",ruleOid);
        PageHelper pageHelper = new PageHelper(-1);
        pageHelper.addDefaultAsc("ordernum");
        List<CodeBasicSecDO> secDOList = codeBasicSecMapper.selectByCondition(conditionMap, pageHelper);
        return codeBasicSecDO2VOs(secDOList,true);
    }
 
    /**
     * 使用规则的主键获取对应的码段的内容
     *
     * @param ruleCollection 规则主键集合
     * @return 码段的内容
     */
    @Override
    public List<CodeBasicSecVO> listCodeBasicSecByRuleOids(Collection<String> ruleCollection) {
        if(CollectionUtils.isEmpty(ruleCollection)){
            return new ArrayList<>();
        }
        List<CodeBasicSecDO> secDOList = new CopyOnWriteArrayList<>();
        SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo();
        VciBaseUtil.switchCollectionForOracleIn(ruleCollection).parallelStream().forEach(ruleOids->{
            WebUtil.setCurrentUserSessionInfo(sessionInfo);
            Map<String,String> conditionMap = new HashMap<>();
            conditionMap.put("pkcoderule", QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(ruleOids.toArray(new String[0])) + ")");
            PageHelper pageHelper = new PageHelper(-1);
            pageHelper.addDefaultAsc("ordernum");
            List<CodeBasicSecDO> tempSecDOs = codeBasicSecMapper.selectByCondition(conditionMap, pageHelper);
            if(!CollectionUtils.isEmpty(tempSecDOs)){
                secDOList.addAll(tempSecDOs);
            }
        });
        return codeBasicSecDO2VOs(secDOList);
    }
 
    /**
     * 参照分类的码段
     *
     * @param conditionMap 查询条件,必须要有pkCodeRule
     * @param pageHelper   分页的对象
     * @return 码段的内容
     */
    @Override
    public DataGrid<CodeBasicSecVO> refDataGridClassifySec(Map<String, String> conditionMap, PageHelper pageHelper) {
        if(CollectionUtils.isEmpty(conditionMap) || !conditionMap.containsKey("pkCodeRule")){
            return new DataGrid<>();
        }
        conditionMap.put("secType",CodeSecTypeEnum.CODE_CLASSIFY_SEC.getValue());
        return refDataGridCodeBasicSec(conditionMap,pageHelper);
    }
 
    /**
     * 根据码段类型获取不可为空的字段
     *
     * @param secType 码段类型
     * @return 不可为空的字段集合
     */
    private Map<String, String> getNotNullableAttr(String secType) {
        Map<String, String> attrMap = new HashMap<>();
        if (CodeSecTypeEnum.CODE_ATTR_SEC.getValue().equalsIgnoreCase(secType)) {
            attrMap.put("name", "属性码段名称");
        } else if (CodeSecTypeEnum.CODE_DATE_SEC.getValue().equalsIgnoreCase(secType)) {
            attrMap.put("name", "日期码段名称");
            attrMap.put("codeDateFormatStr", "日期格式");
        } else if (CodeSecTypeEnum.CODE_FIXED_SEC.getValue().equalsIgnoreCase(secType)) {
            attrMap.put("name", "固定码段名称");
            attrMap.put("codeSecLengthType", "码段长度类型");
            attrMap.put("codeSecLength", "码段的长度");
        } else if (CodeSecTypeEnum.CODE_LEVEL_SEC.getValue().equalsIgnoreCase(secType)) {
            attrMap.put("name", "层级码段名称");
            attrMap.put("codeLevelType", "层级类型");
            attrMap.put("valueCutType", "字符截取类型");
        } else if (CodeSecTypeEnum.CODE_REFER_SEC.getValue().equalsIgnoreCase(secType)) {
            attrMap.put("name", "引用码段名称");
        } else if (CodeSecTypeEnum.CODE_SERIAL_SEC.getValue().equalsIgnoreCase(secType)) {
            attrMap.put("name", "流水码段名称");
            attrMap.put("codeSecLength", "码段的长度");
            attrMap.put("codeFillType", "编码补位方式");
            attrMap.put("codeFillLength", "填充长度");
            attrMap.put("codeFillLimit", "流水上限");
            attrMap.put("codeFillFlag", "流水是否补码");
        } else if (CodeSecTypeEnum.CODE_VARIABLE_SEC.getValue().equalsIgnoreCase(secType)) {
            attrMap.put("name", "可变码段名称");
            attrMap.put("codeSecLength", "码段的长度");
            attrMap.put("codeFillType", "编码补位方式");
        } else if (CodeSecTypeEnum.CODE_CLASSIFY_SEC.getValue().equalsIgnoreCase(secType)) {
            attrMap.put("name", "分类码段名称");
            attrMap.put("codeSecLengthType", "码段长度类型");
            attrMap.put("codeSecLength", "码段的长度");
        } else {
            attrMap = null;
        }
        return attrMap;
    }
 
    /**
     * 查询目标分类码段所在的树结构
     *
     * @param oid 目标分类码段主键
     * @return 分类码段树结构
     */
    @Override
    public List<Tree> gridCodeClassifySecTree(String oid) {
        VciParentQueryOption queryOption = new VciParentQueryOption(PARENT_FIELD_NAME);
        queryOption.setfOid(oid);
        queryOption.setLinkTypeFlag(false);
        queryOption.setHasSelf(true);
        VciQueryWrapperForDO wrapper = new VciQueryWrapperForDO(CodeBasicSecDO.class);
        wrapper.childQueryParent(queryOption);
        List<CodeBasicSecDO> doList = codeBasicSecMapper.selectByWrapper(wrapper);
        List<String> secOid = new ArrayList<>();
        doList.forEach(o -> secOid.add(o.getOid()));
        List<CodeClassifyValueVO> valueVOs = (List<CodeClassifyValueVO>) codeClassifyValueService.listCodeClassifyValueByOids(secOid);
        TreeQueryObject treeQueryObject = new TreeQueryObject();
        treeQueryObject.setMultipleSelect(false);
        treeQueryObject.setShowCheckBox(false);
        treeQueryObject.setQueryAllLevel(false);
        treeQueryObject.setValueField("oid");
        treeQueryObject.setTextField("name");
        treeQueryObject.setQueryAllRev(false);
        TreeWrapperOptions treeWrapperOptions = new TreeWrapperOptions(PARENT_CLASSIFY_VALUE_FIELD_NAME);
        treeWrapperOptions.copyFromTreeQuery(treeQueryObject);
        return revisionModelUtil.doList2Trees(valueVOs,treeWrapperOptions,(CodeClassifyValueVO s) ->{
            //可以在这里处理树节点的显示
            return s.getId() + " " + s.getName() + (FrameworkDataLCStatus.DISABLED.getValue().equalsIgnoreCase(s
                    .getLcStatus()) ? (" 【停用】 ") : "");
        });
    }
 
    /**
     * 根据编码规则批量删除码段基本信息
     * @param codeRuleOid 编码规则主键
     * @return 执行结果
     */
    @Override
    public BatchCBO batchDeleteSecByCodeRuleOid(String codeRuleOid) {
        VciBaseUtil.alertNotNull(codeRuleOid,"编码规则主键");
        Map<String,String> conditionMap = new HashMap<>();
        conditionMap.put("pkcoderule",codeRuleOid);
        VciQueryWrapperForDO wrapper = new VciQueryWrapperForDO(conditionMap,CodeBasicSecDO.class);
        List<CodeBasicSecDO> deleteList = codeBasicSecMapper.selectByWrapper(wrapper);
        if (CollectionUtils.isEmpty(deleteList)){
            return new BatchCBO();
        }
        BatchCBO batchCBO = codeBasicSecMapper.batchDeleteByOids(deleteList.stream().map(CodeBasicSecDO::getOid).collect(Collectors.toSet()));
        Set<ClientBusinessObject> deleteSet = new HashSet<>();
        deleteSet.addAll(batchCBO.getDeleteCbos());
        List<CodeBasicSecDO> fixedSecList = deleteList.stream().filter(sec -> {
            return CodeSecTypeEnum.CODE_FIXED_SEC.getValue().equals(sec.getSecType());
        }).collect(Collectors.toList());
        List<CodeBasicSecDO> classifySecList = deleteList.stream().filter(sec -> {
            return CodeSecTypeEnum.CODE_CLASSIFY_SEC.getValue().equals(sec.getSecType());
        }).collect(Collectors.toList());
        Set<String> fixedSecOidSet = fixedSecList.stream().map(CodeBasicSecDO::getOid).collect(Collectors.toSet());
        Set<String> classifySecOidSet = classifySecList.stream().map(CodeBasicSecDO::getOid).collect(Collectors.toSet());
        if (!CollectionUtils.isEmpty(fixedSecOidSet)){
            StringBuilder sb = new StringBuilder();
            fixedSecOidSet.stream().forEach(oid -> {
                sb.append("'").append(oid).append("',");
            });
            String inSql = sb.toString().substring(0,sb.toString().length()-1);
            VciQueryWrapperForDO wrapperForValue = new VciQueryWrapperForDO(null,CodeFixedValueDO.class);
            PageHelper ph = new PageHelper();
            ph.setLimit(-1);
            wrapperForValue.in("codefixedsecoid",inSql);
            List<CodeFixedValueDO> fixedValueDOS = fixedValueMapper.selectByWrapper(wrapperForValue);
            BatchCBO fixedCBO = fixedValueMapper.batchDeleteByOids(fixedValueDOS.stream().map(CodeFixedValueDO::getOid).collect(Collectors.toSet()));
            deleteSet.addAll(fixedCBO.getDeleteCbos());
        }
        if (!CollectionUtils.isEmpty(classifySecOidSet)){
            StringBuilder sb = new StringBuilder();
            classifySecOidSet.stream().forEach(oid -> {
                sb.append("'").append(oid).append("',");
            });
            String inSql = sb.toString().substring(0,sb.toString().length()-1);
            VciQueryWrapperForDO wrapperForValue = new VciQueryWrapperForDO(null,CodeClassifyValueDO.class);
            PageHelper ph = new PageHelper();
            ph.setLimit(-1);
            wrapperForValue.in("codeclassifysecoid",inSql);
            List<CodeClassifyValueDO> classifyValueDOS = codeClassifyValueMapper.selectByWrapper(wrapperForValue);
            BatchCBO fixedCBO = codeClassifyValueMapper.batchDeleteByOids(classifyValueDOS.stream().map(CodeClassifyValueDO::getOid).collect(Collectors.toSet()));
            deleteSet.addAll(fixedCBO.getDeleteCbos());
        }
        batchCBO.setDeleteCbos(deleteSet);
        return batchCBO;
    }
 
    /**
     * 上移
     *
     * @param oid 主键
     */
    @Override
    public void upOrderNum(String oid) {
        CodeBasicSecDO secDO = selectByOid(oid);
        BatchCBO batchCBO = new BatchCBO();
        WebUtil.setPersistence(false);
        if(secDO.getOrderNum() >1){
            //等于1的时候不能上移了
            //找比自己小的
            Map<String,String> conditionMap = new HashMap<>();
            conditionMap.put("pkCodeRule",secDO.getPkCodeRule());
            conditionMap.put("ordernum",String.valueOf(secDO.getOrderNum()-1));
            List<CodeBasicSecDO> lastSecDOs = codeBasicSecMapper.selectByCondition(conditionMap,new PageHelper(-1));
            if(!CollectionUtils.isEmpty(lastSecDOs)){
                CodeBasicSecDO lastSec = lastSecDOs.get(0);
                lastSec.setOrderNum(lastSec.getOrderNum()+1);
                batchCBO.copyFromOther(codeBasicSecMapper.updateByPrimaryKey(lastSec));
            }
            secDO.setOrderNum(secDO.getOrderNum()-1);
            batchCBO.copyFromOther(codeBasicSecMapper.updateByPrimaryKey(secDO));
        }
        WebUtil.setPersistence(true);
        boService.persistenceBatch(batchCBO);
    }
 
    /**
     * 下移
     *
     * @param oid 主键
     */
    @Override
    public void downOrderNum(String oid) {
        CodeBasicSecDO secDO = selectByOid(oid);
        BatchCBO batchCBO = new BatchCBO();
        WebUtil.setPersistence(false);
        Map<String,String> conditionMap = new HashMap<>();
        conditionMap.put("pkCodeRule",secDO.getPkCodeRule());
        Long total = codeBasicSecMapper.countByCondition(conditionMap);
        if(secDO.getOrderNum()  < total){
            //小于总数的时候才下移
            conditionMap.put("ordernum",String.valueOf(secDO.getOrderNum()+1));
            List<CodeBasicSecDO> lastSecDOs = codeBasicSecMapper.selectByCondition(conditionMap,new PageHelper(-1));
            if(!CollectionUtils.isEmpty(lastSecDOs)){
                CodeBasicSecDO lastSec = lastSecDOs.get(0);
                lastSec.setOrderNum(lastSec.getOrderNum()-1);
                batchCBO.copyFromOther(codeBasicSecMapper.updateByPrimaryKey(lastSec));
            }
            secDO.setOrderNum(secDO.getOrderNum()+1);
            batchCBO.copyFromOther(codeBasicSecMapper.updateByPrimaryKey(secDO));
        }
        WebUtil.setPersistence(true);
        boService.persistenceBatch(batchCBO);
    }
}