ludc
2024-07-26 696c68a9f7645bc35a9382a4e2271910b222f7b5
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
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
package com.vci.web.service.impl;
 
import com.alibaba.fastjson.JSON;
import com.vci.corba.common.PLException;
import com.vci.corba.omd.data.BusinessObject;
import com.vci.corba.omd.etm.EnumItem;
import com.vci.corba.omd.etm.EnumType;
import com.vci.dto.OsEnumDTO;
import com.vci.dto.OsEnumItemDTO;
import com.vci.omd.utils.ObjectTool;
import com.vci.pagemodel.*;
import com.vci.po.OsEnumPO;
import com.vci.starter.poi.bo.ReadExcelOption;
import com.vci.starter.poi.bo.WriteExcelData;
import com.vci.starter.poi.bo.WriteExcelOption;
import com.vci.starter.poi.constant.ExcelLangCodeConstant;
import com.vci.starter.poi.util.ExcelUtil;
import com.vci.starter.web.annotation.log.VciUnLog;
import com.vci.starter.web.enumpck.UserSecretEnum;
import com.vci.starter.web.exception.VciBaseException;
import com.vci.starter.web.pagemodel.BaseResult;
import com.vci.starter.web.pagemodel.DataGrid;
import com.vci.starter.web.pagemodel.PageHelper;
import com.vci.starter.web.util.*;
import com.vci.constant.EnumIdConstant;
import com.vci.web.service.OsEnumServiceI;
import com.vci.web.service.OsLifeCycleServiceI;
import com.vci.web.service.WebBoServiceI;
import com.vci.web.util.Func;
import com.vci.web.util.PlatformClientUtil;
import com.vci.web.util.WebUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.util.HSSFColor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.util.HtmlUtils;
 
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
 
import static com.vci.constant.EnumIdConstant.LC_STATUS_SUBFIX;
 
/**
 * 枚举服务--已经调用平台底层了,不再提供dao层
 * @author weidy@2018-03-06
 *
 */
@Service
public class OsEnumServiceImpl implements OsEnumServiceI {
 
    /**
     * 平台调用客户端
     */
    @Autowired
    private PlatformClientUtil platformClientUtil;
 
    /**
     * 生命周期
     */
    @Autowired
    private OsLifeCycleServiceI lifeCycleService;
 
    /**
     * 用户新增数据的时候可以查看的密级
     */
    public static final String MY_DATA_SECRET = "myDataSecret";
 
    /**
     * 业务数据
     */
    @Autowired
    private WebBoServiceI boService;
 
    /**
     * 加载自身
     */
    @Autowired(required = false)
    @Lazy
    private OsEnumServiceI self;
 
    /**
     * 必填列
     */
    private List<Integer> ColumnNameisRed = new ArrayList<Integer>();
 
    /**
     * 日志
     */
    private Logger logger = LoggerFactory.getLogger(getClass());
 
    /**
     * 使用编号获取枚举明细
     * @param enumCode 编号
     * @return 明细
     * @throws VciBaseException 调用服务端出错的时候会抛出异常
     */
    private List<OsEnumItemVO> getEnumItemById(String enumCode)  throws VciBaseException{
        if(StringUtils.isBlank(enumCode)){
            return  null;
        }
        Map<String, OsEnumVO> enumVOMap = self.selectAllEnumMap();
        if(MY_DATA_SECRET.equalsIgnoreCase(enumCode)){
            //当前用户
            OsEnumVO enumVO = enumVOMap.getOrDefault(EnumIdConstant.DATASECRET_ENUMNAME, null);
            int userSecret = WebUtil.getInt(WebUtil.getCurrentUserSessionInfoNotException().getUserSecret());
            List<OsEnumItemVO> itemVOS = new ArrayList<>();
            if(enumVO!=null && !CollectionUtils.isEmpty(enumVO.getItems())){
                itemVOS = enumVO.getItems().stream().filter(item->WebUtil.getInt(item.getValue()) <= userSecret).collect(Collectors.toList());
            }
            return itemVOS;
        }else{
            return enumVOMap.getOrDefault(enumCode.toLowerCase(),new OsEnumVO()).getItems();
        }
    }
 
    /**
     * 获取枚举的内容
     * @param enumCode 枚举的编号(英文名称)
     * @return key是英文值,value是中文文本
     */
    @Override
    public List<KeyValue> getEnum(String enumCode) throws VciBaseException {
        if(StringUtils.isEmpty(enumCode)){
            return null;
        }
        enumCode = HtmlUtils.htmlUnescape(enumCode);
        if(enumCode.endsWith(LC_STATUS_SUBFIX)){
            List<OsStatusVO> statusVOS = lifeCycleService.listStatusById(enumCode.replace(LC_STATUS_SUBFIX, ""));
            if(CollectionUtils.isEmpty(statusVOS)){
                return new ArrayList<>();
            }
            List<KeyValue> keyValueList = new ArrayList<>();
            statusVOS.stream().forEach(statusVO->{
                KeyValue kv = new KeyValue();
                kv.setKey(statusVO.getId());
                kv.setValue(statusVO.getName());
                kv.setAttributes(VciBaseUtil.objectToMap(statusVO));
                keyValueList.add(kv);
            });
            return keyValueList;
        }
        return enumItem2KV(getEnumItemById(enumCode));
    }
 
    /**
     * 获取枚举的中文文本
     * @param enumCode 枚举的编号(英文名称)
     * @param enumKey 枚举的英文值,区分大小写
     */
    @Override
    public String getValue(String enumCode, String enumKey) throws VciBaseException {
        List<KeyValue> allKV = getEnum(enumCode);
        if(allKV.size()>0){
            for(KeyValue kv : allKV){
                if(kv.getKey().equalsIgnoreCase(enumKey)){
                    return kv.getValue();
                }
            }
        }
        return "";
    }
 
    /**
     * 获取枚举的英文值
     * @param enumCode 枚举的编号(英文名称)
     * @param enumValue 枚举的中文文本,区分大小写 
     */
    @Override
    public String getKey(String enumCode, String enumValue) throws VciBaseException {
        List<KeyValue> allKV = getEnum(enumCode);
        if(allKV.size()>0){
            for(KeyValue kv : allKV){
                if(kv.getValue().equalsIgnoreCase(enumValue)){
                    return kv.getKey();
                }
            }
        }
        return "";
    }
 
    /**
     * 获取枚举的映射
     *
     * @param enumCode 枚举的=编号
     * @return 枚举的值映射
     */
    @Override
    public Map<String, String> getEnumValueMap(String enumCode) throws VciBaseException {
        if(StringUtils.isBlank(enumCode)){
            return  null;
        }
        Map<String, OsEnumVO> enumVOMap = self.selectAllEnumMap();
        if(MY_DATA_SECRET.equalsIgnoreCase(enumCode)){
            //当前用户
            OsEnumVO enumVO = enumVOMap.getOrDefault(EnumIdConstant.DATASECRET_ENUMNAME, null);
            int userSecret = WebUtil.getInt(WebUtil.getCurrentUserSessionInfoNotException().getUserSecret());
            Map<String,String> itemVOMap = new HashMap<>();
            if(enumVO!=null && !CollectionUtils.isEmpty(enumVO.getItemMaps())){
                enumVO.getItemMaps().forEach((key,value)->{
                    if(WebUtil.getInt(key) <= userSecret){
                        itemVOMap.put(key,value);
                    }
                });
            }
            return itemVOMap;
        }else{
            return enumVOMap.getOrDefault(enumCode.toLowerCase(),new OsEnumVO()).getItemMaps();
        }
    }
 
    /**
     * 查询所有的枚举
     *
     * @return 枚举的显示对象
     */
    @Override
    @VciUnLog
    public List<OsEnumVO> selectAllEnum() {
        //后面两个参数居然完全没有作用
        try {
            return enumDO2VOs(Arrays.stream(platformClientUtil.getEnumService().getEnumTypes("",1,1)).collect(Collectors.toList()));
        } catch (PLException vciError) {
            throw WebUtil.getVciBaseException(vciError);
        }
    }
 
    /**
     * 枚举定义列表查询(缓存里面找且带name查询条件)
     * @param enumName
     * @return 枚举的显示对象
     */
    @Override
    public List<OsEnumVO> getEnumTypeList(String enumName) throws PLException {
        return enumDO2VOs(Arrays.stream(platformClientUtil.getEnumService().getEnumTypes(enumName,1,1)).collect(Collectors.toList()));
    }
 
    /**
     * 查看枚举的使用范围
     * @param enumName 枚举名称
     * @return
     * @throws PLException
     */
    @Override
    public List<Map<String,String>> getUsedEnumList(String enumName) throws PLException {
        if(Func.isBlank(enumName)){
            throw new PLException("500",new String[]{"请选择要查询应用范围的枚举!"});
        }
        String[] attrubuteNames = platformClientUtil.getAttributeService().getAttrubyteNamesByEMName(enumName);
        if(Func.isEmpty(attrubuteNames)){
            return new ArrayList<>();
        }
        List<Map<String,String>> attrubuteMapList = new ArrayList<>();
        Arrays.stream(attrubuteNames).forEach(attrName->{
            Map<String, String> itemMap = new HashMap<>();
            itemMap.put("enumName",enumName);
            itemMap.put("source",attrName);
            attrubuteMapList.add(itemMap);
        });
        return attrubuteMapList;
    }
 
    /**
     * 根据枚举英文名称获取枚举类型
     * @param id
     * @return
     */
    @Override
    public OsEnumVO getEnumTypeById(String id) throws PLException {
        if (Func.isBlank(id)) {
            return null;
        }
        EnumType enumType = platformClientUtil.getEnumService().getEnumTypeByName(id);
        return enumDO2VO(enumType);
    }
 
    /**
     * 新增枚举类型
     * @param osEnumDTO
     * @return
     */
    @Override
    public boolean addEnumType(OsEnumDTO osEnumDTO) throws PLException {
        //1、枚举值判空
        VciBaseUtil.alertNotNull(
        osEnumDTO,"枚举类型对象",
            osEnumDTO.getId(),"枚举名称",
            osEnumDTO.getEnumValueDataType(),"枚举的类型",
            osEnumDTO.getLength(),"枚举长度"
        );
        //2、枚举类型名称正则校验和查重
        if(!osEnumDTO.getId().matches("^[A-Za-z]+$")){
            throw new PLException("500", new String[] { "枚举名称只能为英文字母!"});
        }
        OsEnumVO osEnumVO = this.getEnumTypeById(osEnumDTO.getId());
        if(Func.isNotEmpty(osEnumVO) && Func.isNotBlank(osEnumVO.getOid())){
            throw new PLException("500", new String[] { "枚举名称已存在,请修改枚举名称!"});
        }
        //枚举项名称判重等操作
        checkOsEnumItem(osEnumDTO);
        //默认值处理
        String userId = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId();
        osEnumDTO.setCreator(userId);
        //手动设置主键,否则平台直接用没有主键的枚举放进了缓存中,导致后续查询的数据没有oid
        osEnumDTO.setOid(VciBaseUtil.getPk().toUpperCase(Locale.ROOT));
        osEnumDTO.setLastModifier(userId);
        return platformClientUtil.getEnumService().addEnumType(this.osEnumDTO2EnumType(osEnumDTO));
    }
 
    /**
     * 修改枚举类型
     * @param osEnumDTO
     * @return
     */
    @Override
    public boolean updateEnumType(OsEnumDTO osEnumDTO) throws PLException {
        //1、枚举值判空
        VciBaseUtil.alertNotNull(
                osEnumDTO,"枚举类型对象",
                osEnumDTO.getOid(),"枚举的主键",
                osEnumDTO.getId(),"枚举名称",
                osEnumDTO.getEnumValueDataType(),"枚举的类型",
                osEnumDTO.getLength(),"枚举长度"
        );
        //2、枚举类型名称(名称不允许修改)所以可以用名称查询是否存在
        OsEnumVO osEnumVO = this.getEnumTypeById(osEnumDTO.getId());
        if(Func.isEmpty(osEnumVO) || Func.isBlank(osEnumVO.getOid())){
            throw new PLException("500", new String[] { "当前修改枚举对象不存在,请刷新后重试!"});
        }
        //3、枚举项判重,和长度等校验
        checkOsEnumItem(osEnumDTO);
        //将osEnumVO中的默认值赋值给osEnumDTO对象
        String userId = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId();
        osEnumDTO.setLastModifier(userId);
        osEnumDTO.setCreator(osEnumVO.getCreator());
        osEnumDTO.setCreateTime(osEnumVO.getCreateTime());
        //修改和删除时ts参数为前端必传参数
        return platformClientUtil.getEnumService().modifyEnumType(osEnumDTO2EnumType(osEnumDTO));
    }
 
    /**
     * 删除枚举类型(包含删除枚举项功能)
     * @param osEnumDTOS
     * @return
     */
    @Override
    public boolean deleteEnumTypes(List<OsEnumDTO> osEnumDTOS) throws PLException {
        VciBaseUtil.alertNotNull(osEnumDTOS,"待删除的枚举列表");
        //平台的deleteEnumTypes方法必传三个参数,oid、name和ts
        List<EnumType> enumTypes = new ArrayList<>();
        for(OsEnumDTO osEnumDTO : osEnumDTOS){
            //oid和ts判空
            String oid = osEnumDTO.getOid();
            //name主要用来对缓存数据删除
            String name = osEnumDTO.getName();
            Date ts = osEnumDTO.getTs();
            if(Func.isBlank(oid) || Func.isBlank(name) || Func.isEmpty(ts)){
                throw new PLException("500",new String[]{"待删除的枚举列表中主键【oid】、调整时间【ts】、属性名【name】不能为空!"});
            }
            //判断枚举是否有被引用
            List<Map<String, String>> usedEnumList = this.getUsedEnumList(name);
            if(Func.isNotEmpty(usedEnumList)){
                throw new PLException("500",new String[]{"删除的枚举中,枚举名称为:【" + name + "】,已被引用!"});
            }
            EnumType enumType = new EnumType();
            enumType.oid = oid;
            enumType.name = name;
            enumType.ts = Func.format(ts,VciDateUtil.DateTimeMillFormat);
            enumTypes.add(enumType);
        }
        if(Func.isEmpty(enumTypes)){
            return false;
        }
        return platformClientUtil.getEnumService().deleteEnumTypes(enumTypes.toArray(new EnumType[enumTypes.size()]));
    }
 
    /**
     * 导出枚举类型
     * @param exportFileName 导出的文件名
     * @param enumNames 需要导出的枚举名称
     * @return
     */
    @Override
    public String exportEnumTypes(String exportFileName,String enumNames) throws PLException {
        if(Func.isBlank(enumNames)){
            throw new PLException("500",new String[]{"请勾选要导出的枚举!"});
        }
        //界面没传名称,使用默认导出名称
        exportFileName = Func.isBlank(exportFileName) ?  "枚举类型导出_" + Func.format(new Date(),"yyyy-MM-dd HHmmss.sss"):exportFileName;
        //设置列名
        List<String> columns = new ArrayList<>(Arrays.asList("枚举名称", "标签", "返回类型", "长度","创建时间", "枚举项名称", "枚举值", "描述"));
 
        //写excel
        String excelPath = LocalFileUtil.getDefaultTempFolder() + File.separator + exportFileName +  ".xls";
        try {
            new File(excelPath).createNewFile();
        } catch (Throwable e) {
            throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelPath}, e);
        }
        //设置列
        List<WriteExcelData> excelDataList = new ArrayList<>();
        //设置列头
        for (int index = 0; index < columns.size(); index++) {
            excelDataList.add(new WriteExcelData(0,index, columns.get(index)));
        }
        //按照枚举名查询枚举,然后处理枚举导出
        List<String> enumNameList = Func.toStrList(enumNames);
        int startRow = 1;
        for (int i = 0; i < enumNameList.size(); i++) {
            //根据枚举名称查询枚举和枚举项
            OsEnumVO osEnumVO = this.getEnumTypeById(enumNameList.get(i));
            //OsEnumVO osEnumVO = getTestJson(i);
            //查询结果不应该为空
            if(Func.isEmpty(osEnumVO) && Func.isBlank(osEnumVO.getOid())){
                throw new PLException("500",new String[]{"未查询到枚举名为【" + enumNameList.get(i) + "】的枚举,请刷新后重新导出!"});
            }
            //枚举项不为空时需要考虑合并行问题
            List<OsEnumItemVO> enumVOItems = osEnumVO.getItems();
            //枚举项不为空时需要进行合并行处理
            if(Func.isNotEmpty(enumVOItems) || enumVOItems.size() > 1){
                //excelDataList.add(new WriteExcelData(startRow,(enumVOItems.size()+startRow)-1,true,true,0, osEnumVO.getOid()));
                excelDataList.add(new WriteExcelData(startRow,(enumVOItems.size()+startRow)-1,true,true,0, osEnumVO.getId()));
                excelDataList.add(new WriteExcelData(startRow,(enumVOItems.size()+startRow)-1,true,true,1, osEnumVO.getName()));
                excelDataList.add(new WriteExcelData(startRow,(enumVOItems.size()+startRow)-1,true,true,2, osEnumVO.getEnumValueDataType()+"("+osEnumVO.getEnumValueDataTypeText()+")"));
                excelDataList.add(new WriteExcelData(startRow,(enumVOItems.size()+startRow)-1,true,true,3, osEnumVO.getLength()));
                //excelDataList.add(new WriteExcelData(startRow,(enumVOItems.size()+startRow)-1,true,true,5, osEnumVO.getCreator()));
                excelDataList.add(new WriteExcelData(startRow,(enumVOItems.size()+startRow)-1,true,true,4, Func.format(osEnumVO.getCreateTime(),"yyyy年MM月dd日 hh:mm:ss")));
 
                //处理枚举项写入
                for (int j = 0; j < enumVOItems.size(); j++) {
                    OsEnumItemVO osEnumItemVO = enumVOItems.get(j);
                    excelDataList.add(new WriteExcelData(startRow+j,5, true,osEnumItemVO.getName()));
                    excelDataList.add(new WriteExcelData(startRow+j,6, true, osEnumItemVO.getValue()));
                    excelDataList.add(new WriteExcelData(startRow+j,7, true, osEnumItemVO.getDescription()));
                }
 
                startRow += enumVOItems.size();
            }else{
                //枚举项为空时就不需要合并行
                //excelDataList.add(new WriteExcelData(startRow,0, true,osEnumVO.getOid()));
                excelDataList.add(new WriteExcelData(startRow,0, true, osEnumVO.getId()));
                excelDataList.add(new WriteExcelData(startRow,1, true, osEnumVO.getName()));
                excelDataList.add(new WriteExcelData(startRow,1, true, osEnumVO.getEnumValueDataType()+"("+osEnumVO.getEnumValueDataTypeText()+")"));
                excelDataList.add(new WriteExcelData(startRow,3, true, osEnumVO.getLength()));
                //excelDataList.add(new WriteExcelData(startRow,5, true, osEnumVO.getCreator()));
                excelDataList.add(new WriteExcelData(startRow,4, true, Func.format(osEnumVO.getCreateTime(),"yyyy年MM月dd日 hh:mm:ss")));
            }
            //记录下上一组数据结束时的行号,方便用做合并行的起始行
            startRow += 1;
        }
        WriteExcelOption excelOption = new WriteExcelOption(excelDataList);
        ExcelUtil.writeDataToFile(excelPath, excelOption);
        return excelPath;
    }
 
    /**
     * 下载导入模板
     * @param exportFileName
     * @return
     */
    @Override
    public String downloadEnumTemplate(String exportFileName) {
        //界面没传名称,使用默认导出名称
        exportFileName = Func.isBlank(exportFileName) ?  "枚举导入模板_" + Func.format(new Date(),"yyyy-MM-dd HHmmss.sss"):exportFileName;
        //设置列名
        List<String> columns = new ArrayList<>(Arrays.asList("枚举名称", "标签", "返回类型", "长度", "枚举项名称(当前枚举下有枚举项时必填)", "枚举值(当前枚举下有枚举项时必填)", "描述","*注意*:第二行开始的数据为示例数据,导入前请将其删除,当导入的枚举下具备多个枚举项时,应按照示例enum2的写法"));
        //写excel
        String excelPath = LocalFileUtil.getDefaultTempFolder() + File.separator + exportFileName +  ".xls";
        //设置必填列
        ColumnNameisRed.clear();
        ColumnNameisRed.add(0);
        ColumnNameisRed.add(2);
        ColumnNameisRed.add(3);
        ColumnNameisRed.add(4);
        ColumnNameisRed.add(5);
        try {
            new File(excelPath).createNewFile();
        } catch (Throwable e) {
            throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelPath}, e);
        }
        //设置列
        List<WriteExcelData> excelDataList = new ArrayList<>();
        //设置列头
        for (int index = 0; index < columns.size(); index++) {
            //判断是否为必填列,给必填列设置颜色
            if(ColumnNameisRed.contains(index)){
                WriteExcelData excelData = new WriteExcelData(0, index, columns.get(index));
                excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
                excelDataList.add(excelData);
            }else{
                excelDataList.add(new WriteExcelData(0,index, columns.get(index)));
            }
        }
        List<OsEnumVO> exportEnumTempExample = this.getExportEnumTempExample();
        for (int i = 0; i < exportEnumTempExample.size(); i++) {
            OsEnumVO osEnumVO = exportEnumTempExample.get(i);
            List<OsEnumItemVO> enumVOItems = osEnumVO.getItems();
            for (int j = 0; j < enumVOItems.size(); j++) {
                OsEnumItemVO osEnumItemVO = enumVOItems.get(j);
                excelDataList.add(new WriteExcelData(i+j+1,0, osEnumVO.getId()));
                excelDataList.add(new WriteExcelData(i+j+1,1, osEnumVO.getName()));
                excelDataList.add(new WriteExcelData(i+j+1,2, osEnumVO.getEnumValueDataType()));
                excelDataList.add(new WriteExcelData(i+j+1,3, osEnumVO.getLength()));
 
                excelDataList.add(new WriteExcelData(i+j+1,4,osEnumItemVO.getName()));
                excelDataList.add(new WriteExcelData(i+j+1,5, osEnumItemVO.getValue()));
                excelDataList.add(new WriteExcelData(i+j+1,6, osEnumItemVO.getDescription()));
            }
        }
        WriteExcelOption excelOption = new WriteExcelOption(excelDataList);
        ExcelUtil.writeDataToFile(excelPath, excelOption);
        return excelPath;
    }
 
    /**
     * 导入枚举
     * @param file
     * @return
     * @throws Exception
     */
    @Override
    public BaseResult importEnumTypes(File file) throws Exception {
        VciBaseUtil.alertNotNull(file,"excel文件");
        if(!file.exists()){
            throw new VciBaseException("导入的excel文件不存在,{0}",new String[]{file.getPath()});
        }
        try{
            //1、读取excel中的数据,组成对象
            ReadExcelOption excelOption = new ReadExcelOption();
            List<OsEnumPO> poList = ExcelUtil.readDataObjectFromExcel(file, OsEnumPO.class,excelOption,(value, po, fieldName)->{});
            //去除都是空的情况
            if(CollectionUtils.isEmpty(poList)){
                return BaseResult.fail(ExcelLangCodeConstant.IMPORT_CONTENT_NULL,new String[]{});
            }
            //将枚举和枚举项处理成一对多关系的对象
            Map<String, OsEnumPO> groupPOMap = new HashMap<>();
            for (OsEnumPO po : poList) {
                //拼接用来作为分组的key
                String key = po.getId() + "_" + po.getName() + "_" + po.getEnumValueDataType() + "_" + po.getLength();
                OsEnumPO group = groupPOMap.get(key);
                if (group == null) {
                    group = new OsEnumPO();
                    //拿出现的首行做后续的提示行
                    group.setRowIndex(po.getRowIndex());
                    group.setId(po.getId());
                    group.setName(po.getName());
                    group.setEnumValueDataType(po.getEnumValueDataType());
                    group.setLength(po.getLength());
                    groupPOMap.put(key, group);
                }
 
                OsEnumItemDTO itemDTO = new OsEnumItemDTO();
                itemDTO.setName(po.getEnumItemName());
                itemDTO.setValue(po.getValue());
                itemDTO.setDescription(po.getDescription());
 
                group.getItems().add(itemDTO);
            }
            Collection<OsEnumPO> newPOList = groupPOMap.values();
            //数据库查询是否有已存在的枚举名,方便后续做判重处理
            List<OsEnumVO> osEnumVOList = this.listEnumByIdCollection(poList.stream().map(OsEnumPO::getId).collect(Collectors.toSet()));
            List<String> repeatEnumId = new ArrayList<>();
            if(Func.isNotEmpty(osEnumVOList)){
                repeatEnumId = osEnumVOList.stream().map(OsEnumVO::getId).collect(Collectors.toList());
            }
            //当前excel中是否重复用的判重Map:(key:判重属性,value:行号)
            Map<String, String> excelReapeat = new HashMap<>();
            //判断必填属性是否为空,用户是否已存在,以及部门是否填错等校验逻辑
            List<String> finalRepeatEnumId = repeatEnumId;
            newPOList.stream().forEach(osEnumPO -> {
                if(Func.isBlank(osEnumPO.getId())){//枚举名
                    throw new VciBaseException("第【"+osEnumPO.getRowIndex()+"】行,enumnameerror");
                }else if(Func.isBlank(osEnumPO.getEnumValueDataType())){
                    throw new VciBaseException("第【"+osEnumPO.getRowIndex()+"】行,typeerror");
                }else if(Func.isEmpty(osEnumPO.getLength())){
                    throw new VciBaseException("第【"+osEnumPO.getRowIndex()+"】行,lengtherror");
                }else if(!osEnumPO.getId().matches("^[A-Za-z]+$")){
                    throw new VciBaseException("第【"+osEnumPO.getRowIndex()+"】行数据,枚举名称只能为英文字母");
                }else if(excelReapeat.containsKey(osEnumPO.getId())){//枚举名表格中判重
                    throw new VciBaseException("第【"+excelReapeat.get(osEnumPO.getId())+"】行和第【"+osEnumPO.getRowIndex()+"】行数据,枚举名重复");
                }else if (Func.isNotEmpty(osEnumVOList) && finalRepeatEnumId.contains(osEnumPO.getId())){//2、判断枚举名是否与系统中重复
                    throw new VciBaseException("第【"+osEnumPO.getRowIndex()+"】行,枚举名在系统中已经存在,请修改!");
                }
                //先对枚举名excel中需要判重处理
                excelReapeat.put(osEnumPO.getId(),osEnumPO.getRowIndex());
            });
            //保存逻辑
            for (OsEnumPO osEnumPO : newPOList) {
                OsEnumDTO osEnumDTO = new OsEnumDTO();
                //生成存储的DTO对象
                osEnumDTO.setId(osEnumPO.getId());
                osEnumDTO.setName(osEnumPO.getName());
                osEnumDTO.setEnumValueDataType(osEnumPO.getEnumValueDataType());
                osEnumDTO.setLength(osEnumPO.getLength());
                osEnumDTO.setItems(osEnumPO.getItems());
 
                //调用新增枚举方法
                boolean addBoolean = this.addEnumType(osEnumDTO);
                if(!addBoolean){
                    throw new PLException("500",new String[]{"保存枚举名为【" + osEnumDTO.getId() + "】的数据时出现错误!"});
                }
            }
        }catch (Exception e){
            if(logger.isErrorEnabled()){
                logger.error("读取excel内容时或保存用户信息时出现了错误,具体原因:",VciBaseUtil.getExceptionMessage(e));
            }
            e.printStackTrace();
            return BaseResult.fail(VciBaseUtil.getExceptionMessage(e),new String[]{},e);
        }
        return BaseResult.success("枚举导入成功!");
    }
 
    /**
     * 获取导入模板的示例数据
     * @return
     */
    private List<OsEnumVO> getExportEnumTempExample(){
        String testJosn = "[{\"enumValueDataType\":\"String\",\"id\":\"enum1\",\"items\":[{\"description\":\"enumitem1.1\",\"name\":\"enumitem1.1\",\"value\":\"1\"},{\"description\":\"enumitem1.2\",\"name\":\"enumitem1.2\",\"value\":\"2\"}],\"length\":2,\"name\":\"enum1\"},{\"enumValueDataType\":\"String\",\"id\":\"enum2\",\"items\":[{\"description\":\"enumitem2.1\",\"name\":\"enumitem2.1\",\"value\":\"1\"},{\"description\":\"enumitem2.2\",\"name\":\"enumitem2.2\",\"value\":\"2\"},{\"description\":\"enumitem2.3\",\"name\":\"enumitem2.3\",\"value\":\"3\"}],\"length\":6,\"name\":\"enum2\"}]";
        List<OsEnumVO> OsEnumVOs = JSON.parseArray(testJosn,OsEnumVO.class);
        return OsEnumVOs;
    }
 
    /**
     * 枚举项校验
     * @param osEnumDTO
     * @return 校验失败直接抛出异常,否则不会做任何返回
     */
    private void checkOsEnumItem(OsEnumDTO osEnumDTO) throws PLException {
        List<OsEnumItemDTO> items = osEnumDTO.getItems();
        if (Func.isNotEmpty(items)) {
            //获取正则,主要是针对Integer类型的时候
            String regular = "Integer".equals(osEnumDTO.getEnumValueDataType()) ? "^-?\\d+$" : "";
            //利用set的add返回值进行name判重
            Set<String> uniqueNames = new HashSet<>();
            for (OsEnumItemDTO item : items) {
                // 判断name属性是否有重复的值
                if (!uniqueNames.add(item.getName())) {
                    throw new PLException("500", new String[] {"以下枚举项名称: 【" + item.getName()+ "】重复,请修改枚举项名后重试!"});
                }
                //判断枚举值是否超过设定长度
                if (item.getValue().length() > osEnumDTO.getLength()) {
                    throw new PLException("500", new String[] {"枚举项名称为:【" + item.getName() + "】的枚举值长度,超过限定长度【" + osEnumDTO.getLength() + "】"});
                }
                //枚举类型正则校验
                if(Func.isNotBlank(regular) && !item.getValue().matches(regular)){
                    throw new PLException("500", new String[] { "枚举值只能为【" +
                            ("String".equals(osEnumDTO.getEnumValueDataType()) ? "字符串":"整型") + "】类型!"});
                }
            }
        }
    }
 
    /**
     * 新平台枚举DTO对象转平台EnumType对象
     * @param osEnumDTO
     * @return
     */
    private EnumType osEnumDTO2EnumType(OsEnumDTO osEnumDTO){
        EnumType enumType = new EnumType();
        enumType.oid = osEnumDTO.getOid();
        //枚举名统一转成小写,避免后期出现其他问题
        enumType.name = osEnumDTO.getId().toLowerCase(Locale.ROOT);
        enumType.label = osEnumDTO.getName();
        enumType.length = osEnumDTO.getLength();
        enumType.creator = osEnumDTO.getCreator();
        enumType.ts = Func.format((Func.isNotEmpty(osEnumDTO.getTs()) ? osEnumDTO.getTs():new Date()),VciDateUtil.DateTimeMillFormat);
        enumType.createTime = Func.isNotEmpty(osEnumDTO.getCreateTime()) ? osEnumDTO.getCreateTime().getTime():System.currentTimeMillis();
        enumType.modifier = osEnumDTO.getLastModifier();
        enumType.modifyTime = System.currentTimeMillis();
        enumType.type = osEnumDTO.getEnumValueDataType();
        //处理枚举项
        List<EnumItem> enumItems = new ArrayList<>();
        List<OsEnumItemDTO> items = osEnumDTO.getItems();
        if(Func.isNotEmpty(items)){
            items.stream().forEach(item->{
                EnumItem enumItem = new EnumItem();
                enumItem.name = item.getName();
                enumItem.value = item.getValue();
                enumItem.description = item.getDescription();
                enumItems.add(enumItem);
            });
        }
        enumType.items = enumItems.toArray(new EnumItem[enumItems.size()]);
        return enumType;
    }
 
    /**
     * 查询所有的枚举映射
     *
     * @return key是枚举的英文名称
     */
    @Override
    @VciUnLog
    public Map<String, OsEnumVO> selectAllEnumMap() {
        return Optional.ofNullable(self.selectAllEnum()).orElseGet(()->new ArrayList<>()).stream().collect(Collectors.toMap(s->s.getId().toLowerCase(),t->t,(o1,o2)->o1));
    }
 
    /**
     * 枚举的数据对象转换为显示对象
     *
     * @param enumItems 枚举的对象
     * @return 显示对象
     */
    @Override
    public List<OsEnumVO> enumDO2VOs(Collection<EnumType> enumItems) {
        List<OsEnumVO> enumVOS = new ArrayList<>();
        Optional.ofNullable(enumItems).orElseGet(()->new ArrayList<>()).stream().forEach(enumItem -> {
            OsEnumVO enumVO = enumDO2VO(enumItem);
            enumVOS.add(enumVO);
        });
        return enumVOS;
    }
 
    /**
     * 枚举的数据对象转换为显示对象
     *
     * @param enumType 数据对象
     * @return 显示对象
     */
    @Override
    public OsEnumVO enumDO2VO(EnumType enumType) {
        OsEnumVO enumVO = new OsEnumVO();
        if(enumType!=null){
            enumVO.setOid(enumType.oid);
            enumVO.setCreator(enumType.creator);
            enumVO.setLastModifier(enumType.modifier);
            enumVO.setId(enumType.name);
            enumVO.setName(enumType.label);
            enumVO.setEnumValueDataType(enumType.type);
            enumVO.setEnumValueDataTypeText("String".equalsIgnoreCase(enumType.type) ? "字符串":"整型");
            enumVO.setLength((int) enumType.length);
 
            try {
                enumVO.setLastModifyTime(new Date(enumType.createTime));
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                enumVO.setCreateTime(new Date(enumType.createTime));
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                enumVO.setTs(VciDateUtil.str2Date(enumType.ts,VciDateUtil.DateTimeMillFormat));
            } catch (Exception e) {
                e.printStackTrace();
            }
            //枚举项处理
            List<OsEnumItemVO> itemVOS = new ArrayList<>();
            Map<String,String> itemVOMap = new HashMap<>();
            if(enumType.items!=null && enumType.items.length > 0){
                for(int i = 0 ; i < enumType.items.length ; i ++){
                    OsEnumItemVO enumItemVO = new OsEnumItemVO();
                    EnumItem enumChild = enumType.items[i];
                    enumItemVO.setValue(enumChild.value);
                    enumItemVO.setName(enumChild.name);
                    enumItemVO.setDescription(enumChild.description);
                    itemVOS.add(enumItemVO);
                    itemVOMap.put(enumChild.value,enumChild.name);
                }
            }
            enumVO.setItems(itemVOS);
            enumVO.setItemMaps(itemVOMap);
        }
        return enumVO;
    }
 
    /**
     * 枚举明细转换为KV
     *
     * @param enumItemVO 枚举明细显示对象
     * @return KV
     */
    @Override
    public List<KeyValue> enumItem2KV(Collection<OsEnumItemVO> enumItemVO) {
        List<KeyValue> keyValueList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(enumItemVO)){
            enumItemVO.forEach(itemVO->{
                KeyValue keyValue = new KeyValue();
                keyValue.setKey(itemVO.getValue());
                keyValue.setValue(itemVO.getName());
                keyValueList.add(keyValue);
            });
        }
        return keyValueList;
    }
 
    /**
     * 获取数据的密级,并且会用当前用户的密级再校验一下
     *
     * @param oid     主键
     * @param btmname 业务类型
     * @return 数据的密级
     */
    @Override
    public List<KeyValue> getDataEnum(String oid, String btmname) {
        VciBaseUtil.alertNotNull(oid,"业务数据的主键",btmname,"业务类型");
        BusinessObject cbo = boService.selectCBOByOid(oid, btmname);
        String secret = ObjectTool.getBOAttributeValue(cbo,"secretGrade");
        if(StringUtils.isBlank(secret)){
            return new ArrayList<>();
        }else{
            int dataSecret = VciBaseUtil.getInt(secret);
            List<KeyValue> values = getEnum(EnumIdConstant.DATASECRET_ENUMNAME);
            Integer userSecret = VciBaseUtil.getCurrentUserSecret();
            if(userSecret == null || userSecret < UserSecretEnum.NONE.getValue()){
                userSecret = UserSecretEnum.NONE.getValue();
            }
            if(CollectionUtils.isEmpty(values)){
                return new ArrayList<>();
            }
            Integer finalUserSecret = userSecret;
            return values.stream().filter(s-> {
                int thisDataSecret = VciBaseUtil.getInt(s.getKey());
                if(dataSecret >= thisDataSecret && finalUserSecret >=thisDataSecret){
                    return true;
                }
                return false;
            }).collect(Collectors.toList());
        }
    }
 
    /**
     * 批量添加内容
     *
     * @param enumItemList 枚举的内容
     */
    @Override
    public void batchAddEnum(List<EnumType> enumItemList) {
        if(!CollectionUtils.isEmpty(enumItemList)){
            enumItemList.stream().forEach(enumItem -> {
                try {
                    platformClientUtil.getEnumService().addEnumType(enumItem);
                } catch (PLException e) {
                    throw WebUtil.getVciBaseException(e);
                }
            });
        }
    }
 
    /**
     * 批量修改内容
     *
     * @param enumItemList 枚举的内容
     */
    @Override
    public void batchEditEnum(List<EnumType> enumItemList) {
        if(!CollectionUtils.isEmpty(enumItemList)){
            enumItemList.stream().forEach(enumItem -> {
                try {
                    platformClientUtil.getEnumService().modifyEnumType(enumItem);
                } catch (PLException e) {
                    throw WebUtil.getVciBaseException(e);
                }
            });
        }
    }
 
    /**
     * 使用编号获取枚举的名称
     *
     * @param id 编号
     * @return 枚举的中文名称
     */
    @Override
    public String getNameById(String id) {
        VciBaseUtil.alertNotNull(id,"枚举的英文编号");
        Map<String, OsEnumVO> enumVOMap = self.selectAllEnumMap();
        if(!enumVOMap.containsKey(id.toLowerCase())){
            throw new VciBaseException("枚举[{0}]在系统中不存在",new String[]{id});
        }
        return enumVOMap.get(id.toLowerCase()).getName();
    }
 
    /**
     * 使用枚举的英文名称集合获取对象
     *
     * @param enumIdCollection 英文名称集合,不区分大小写
     * @return 枚举的对象
     */
    @Override
    public List<OsEnumVO> listEnumByIdCollection(Collection<String> enumIdCollection) {
        Map<String, OsEnumVO> enumVOMap = self.selectAllEnumMap();
        List<OsEnumVO> enumVOList = new ArrayList<>();
        enumIdCollection.stream().forEach(enumId->{
            if(enumVOMap.containsKey(enumId.toLowerCase())){
                enumVOList.add(enumVOMap.get(enumId.toLowerCase()));
            }
        });
        return enumVOList;
    }
 
    /**
     * 参照枚举的信息 不建议使用这个方法,因为是sql拼接做的查询
     *
     * @param conditionMap 查询条件
     * @param pageHelper   分页
     * @return 枚举的信息
     */
    @Override
    public DataGrid<OsEnumVO> referDataGrid(Map<String, String> conditionMap, PageHelper pageHelper) {
        DataGrid<OsEnumVO> dataGrid = queryObjectServiceInfoBySql(conditionMap, pageHelper, "plenumtype",OsEnumVO.class,null);
        return dataGrid;
    }
 
    /**
     * 枚举选项列表
     *
     * @param pkEnum 枚举的主键
     * @return 枚举选项
     */
    @Override
    public DataGrid<OsEnumItemVO> gridEnumItemByOid(String pkEnum) {
        if(StringUtils.isBlank(pkEnum)){
            return new DataGrid<>("没有选择枚举");
        }
        //先查询出来
        OsEnumVO enumVO = self.selectAllEnumMap().values().stream().filter(s -> s.getOid().equalsIgnoreCase(pkEnum)).findFirst().orElseGet(() -> new OsEnumVO());
        DataGrid<OsEnumItemVO> dataGrid = new DataGrid<>();
        if(enumVO!=null && enumVO.getItems()!=null){
            dataGrid.setData(enumVO.getItems());
            dataGrid.setTotal(enumVO.getItems().size());
        }
        return dataGrid;
    }
 
    /**
     * 根据枚举类型查询枚举:枚举名 , 枚举
     * @param enumType:String, Integer
     * @return
     */
    public List<Map<String,List<String>>> getEnumMapByType(String enumType){
        List<Map<String,List<String>>> enumMapList = new ArrayList<>();
        EnumType[] emArray = null;
        try {
            emArray = platformClientUtil.getEnumService().getEnumTypesByType(enumType);
        } catch (PLException e) {
            e.printStackTrace();
        }
        if(emArray == null || emArray.length == 0){
            return null;
        }
        EnumType emItem;
        for(int i = 0; i < emArray.length; i++){
            emItem = emArray[i];
            EnumItem[] emChildren = emItem.items;
            ArrayList<String> valueList = new ArrayList<String>();
            for(int k = 0; k < emChildren.length; k++){
                EnumItem emChild = emChildren[k];
                String value = emChild.value;
                valueList.add(value);
            }
            Map<String, List<String>> enumMap = new HashMap<>();
            enumMap.put(emItem.name, valueList);
            enumMapList.add(enumMap);
        }
        return enumMapList;
    }
 
    /**
     * 清除缓存
     */
    @Override
    public void clearCache() {
 
    }
 
}