ludc
2024-09-13 8c9f15cc8a3c3e6f4a4404574d39732b624289a6
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
package com.vci.web.service.impl;
 
import com.vci.corba.omd.data.LinkObject;
import com.vci.dto.ProcessTemplateVO;
import com.vci.frameworkcore.compatibility.OrgDeptQueryServiceI;
import com.vci.frameworkcore.compatibility.SmRoleQueryServiceI;
import com.vci.frameworkcore.compatibility.SmUserQueryServiceI;
import com.vci.pagemodel.*;
import com.vci.starter.web.enumpck.DataSecretEnum;
import com.vci.starter.web.enumpck.UserSecretEnum;
import com.vci.starter.web.exception.VciBaseException;
import com.vci.starter.web.pagemodel.*;
import com.vci.starter.web.util.Md5;
import com.vci.starter.web.util.VciBaseUtil;
import com.vci.starter.web.wrapper.VciQueryWrapperForDO;
import com.vci.constant.FileTypeConstants;
import com.vci.constant.WFVariablesKeyConstant;
import com.vci.web.dao.WebProcessDaoI;
import com.vci.model.WFProcessClassifyDO;
import com.vci.web.properties.WebProperties;
import com.vci.web.service.*;
import com.vci.web.util.PlatformClientUtil;
import com.vci.web.util.WebUtil;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
 
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
import java.util.stream.Collectors;
 
/**
 * 流程相关查询服务
 * @author weidy@2018-04-24
 *
 */
@Service
public class WebProcessDefineServiceImpl implements WebProcessDefineServiceI{
    
    @Autowired
    private WebProcessDaoI processDao;
    
 
 
    @Autowired
    private WebProperties webProperties;
    
    @Autowired
    private WebProcessCommandServiceI proCmdService;
 
    @Autowired
    private PlatformClientUtil platformClientUtil;
 
    /**
     * 业务数据服务
     */
    @Autowired
    private WebBoServiceI boService;
 
 
    /**
     * 角色服务
     */
    @Autowired
    private SmRoleQueryServiceI roleQueryService;
    @Autowired
    private OrgDeptQueryServiceI deptQueryServiceI;
    @Autowired
    private SmUserQueryServiceI userQueryServiceI;
    @Autowired
    private WebSecretServiceI secretService;
 
    /**
     * 文件的对象服务
     */
    @Autowired
    private VciFileObjectServiceI fileObjectService;
 
 
    @Autowired
    private OsEnumServiceI enumService;
 
    
    private final String msgCodePrefix = "com.vci.web.flow.";
 
    private Logger logger = LoggerFactory.getLogger(getClass());
 
 
    /**
     * 查询当前用户可以使用的type分类下的流程模板--目前暂时不根据用户过滤流程模板
     * @param type 流程分类
     * @param filterTemplate 指定模板
     * @param showAll 是否显示所有的版本
     */
    @Override
    public List<ProcessTemplateVO> getMyTemplates(String type, String filterTemplate,
                                                  boolean showAll) throws VciBaseException {
        //现在没有添加用户的过滤
        return processDao.getTemplatesByType(type,filterTemplate,showAll);
    }
 
    /**
     * 获取某个流程分类下的所有流程模板
     * @param type 流程模板
     */
    @Override
    public List<ProcessTemplateVO> getAllTemplates(String type)
            throws VciBaseException {
        return processDao.getTemplatesByType(type,null,true);
    }
 
    /**
     * 获取流程模板中所有的任务节点
     * @param processOid 流程模板的主键
     * @param isQueryUser 是否查询节点的用户
     * @param maxSecret 数据中的最大密级值
     */
    @Override
    public List<ProcessNodeVO> getAllProcessNode(String processOid, boolean isQueryUser, int maxSecret)
            throws VciBaseException {
        List<ProcessNodeVO> allProcessNodeVO = processDao.getAllProcessNode(processOid);
        if(allProcessNodeVO !=null&& allProcessNodeVO.size()>0 && isQueryUser){
            for(ProcessNodeVO pn : allProcessNodeVO){
                pn.setProcessUserVO(getProcessUsersByNode(pn,maxSecret));
            }
        }
        return allProcessNodeVO;
    }
    
    /**
     * 获取流程模板中所有的任务节点名称
     * @param processOid 流程模板的主键
     */
    @Override
    public List<String> getAllProcessNodeName(String processOid)
            throws VciBaseException {
        String[] allTaskName = processDao.getAllProcessNodeName(processOid);
        if(allTaskName !=null){
            return Arrays.asList(allTaskName);
        }else{
            return new ArrayList<String>();
        }
    }
 
    /**
     * 获取流程节点中可以选择的用户
     * @param  node 流程模版的主键
     * @param maxSecret 数据中的最大密级值
     * @return
     * @throws VciBaseException
     */
    @Override
    public List<ProcessUserVO> getProcessUsersByNode(ProcessNodeVO node, int maxSecret) throws VciBaseException{
        if(!webProperties.isCheckSecretOnProcessStart()){
            maxSecret = -1;//不校验的时候就不需要对比密级了
        }
        List<ProcessUserVO> allUsers = new ArrayList<ProcessUserVO>();
        if(node!=null){
            //先处理角色和部门
            boolean isHasRoleOrDept = false;
            if(StringUtils.isNotEmpty(node.getRoles())){
                isHasRoleOrDept = true;
                List<String> roleOids = VciBaseUtil.str2List(node.getRoles().replace("role:", ""));
                List<SmRoleVO> roles = roleQueryService.listRoleByRoleOids(roleOids);
                Map<String,List<SmUserVO>> userRoleMap = userQueryServiceI.batchListUserByRoleOids(roleOids);
                if(roles!=null && roles.size() > 0){
                    for(SmRoleVO role : roles){
                        ProcessUserVO pu = new ProcessUserVO();
                        BeanUtils.copyProperties(role, pu);
                        pu.setType("role");
                        //找角色下的用户
                        List<SmUserVO> users = userRoleMap.getOrDefault(role.getOid(),new ArrayList<>());
                        if(users!=null&& users.size()>0){
                            List<ProcessUserVO> pul = copyUsersToProcessNode(users,maxSecret);
                            if(pul.size()>0) {
                                pu.setChildren(pul);
                            }
                        }
                        allUsers.add(pu);
                    }
                }
            }
            if(StringUtils.isNotEmpty(node.getDepts())){
                isHasRoleOrDept = true;
                List<String> deptOids = VciBaseUtil.str2List(node.getDepts().replace("dept:", ""));
                List<OrgDepartmentVO> depts = deptQueryServiceI.listDeptByDeptOids(deptOids);
                Map<String, List<SmUserVO>> userDeptMap = userQueryServiceI.batchListUserByDeptOids(deptOids);
                if(depts!=null && depts.size() > 0){
                    for(OrgDepartmentVO dept : depts){
                        ProcessUserVO pu = new ProcessUserVO();
                        BeanUtils.copyProperties(dept, pu);
                        pu.setType("dept");
                        //找角色下的用户
                        List<SmUserVO> users = userDeptMap.getOrDefault(dept.getOid(),new ArrayList<>());
                        if(users!=null&& users.size()>0){
                            List<ProcessUserVO> pul = copyUsersToProcessNode(users,maxSecret);
                            if(pul.size()>0) {
                                pu.setChildren(pul);
                            }
                        }
                        allUsers.add(pu);
                    }
                }
            }
            if(StringUtils.isNotEmpty(node.getUsers())){
                //处理用户,用户是存储的用户名
                String userids = node.getUsers().replace("user:", "");
                boolean isHasCurrentUser = false;
                String[] useridsArr = userids.split(",");//因为要找#CURRENTUSER#,所以直接分隔后,后面直接加上要查询的单引号
                if(useridsArr!=null&& useridsArr.length>0){
                    userids = "";
                    for(String userid : useridsArr){
                        if("#CURRENTUSER#".equalsIgnoreCase(userid)){
                            isHasCurrentUser = true;
                        }else if(StringUtils.isNotEmpty(userid)){
                            userids += userid + ",";
                        }
                    }
                }
                userids = WebUtil.removeComma(userids);
                List<SmUserVO> users = null;
                if(StringUtils.isNotBlank(userids)){
                    users = userQueryServiceI.listUserByUserIds(VciBaseUtil.str2List(userids));
                }
                List<ProcessUserVO> pul = copyUsersToProcessNode(users,maxSecret);
                if(isHasCurrentUser){//当前用户放在前面
                    ProcessUserVO pu = new ProcessUserVO();
                    SessionInfo si = WebUtil.getCurrentUserSessionInfo();
                    pu.setOid(si.getUserOid());
                    pu.setId(si.getUserId());
                    pu.setName(si.getUserName());
                    pu.setType("user");
                    pu.setLeaf(true);
                    int userSecret = WebUtil.getInt(si.getUserSecret());
                    if(maxSecret == -1 || secretService.checkDataSecret(maxSecret,userSecret)) {
                        if(maxSecret>-1){
                            pu.setSecret(userSecret);
                            pu.setSecretText(UserSecretEnum.getSecretText(userSecret));
                        }
                        pul.add(pu);
                    }
                }
 
                if(isHasRoleOrDept){//已经有角色或者部门了,那么就加一个用户的节点
                    ProcessUserVO pu = new ProcessUserVO();
                    pu.setOid("userfolder");
                    pu.setId("");
                    pu.setName("用户");
                    pu.setType("userfolder");
                    pu.setChildren(pul);
                    allUsers.add(pu);
                }else{
                    allUsers.addAll(pul);
                }
            }
        }
        return allUsers;
    }
 
    private List<ProcessUserVO> copyUsersToProcessNode(List<SmUserVO> users, int maxSecret) throws VciBaseException{
        List<ProcessUserVO> pul = new ArrayList<ProcessUserVO>();
        if(users!=null&& users.size()>0){
            for(SmUserVO user : users){
                ProcessUserVO puc = new ProcessUserVO();
                BeanUtils.copyProperties(user, puc);
                puc.setType("user");
                puc.setLeaf(true);
                if(maxSecret == -1 || secretService.checkDataSecret(maxSecret,user.getSecretGrade())) {
                    if(maxSecret>-1){
                        puc.setSecret(user.getSecretGrade());
                        puc.setSecretText(UserSecretEnum.getSecretText(user.getSecretGrade()));
                    }
                    pul.add(puc);
                }
            }
        }
        return pul;
    }
 
    /**
     * 获取流程模板中某个节点的所有的处理用户
     * @param processTemplateOid 流程模板
     * @param nodeName 节点名称
     * @return
     * @throws VciBaseException
     */
    @Override
    public List<ProcessUserVO> getAllProcessUsersInProcess(String processTemplateOid,
                                                           String nodeName) throws VciBaseException {
        //先获取流程节点
        ProcessNodeVO pn = processDao.getNodePresideUsers(processTemplateOid, nodeName);
        return getProcessUsersByNode(pn,-1);
    }
 
    /**
     * 获取部署id
     * @param executionId 执行主键
     * @return
     * @throws VciBaseException
     */
    @Override
    public String getDeployIdByExecutionId(String executionId) throws VciBaseException {
        return processDao.getJbpmDeploymentIdByExecutionId(executionId);
    }
 
    /**
     * 获取任务中设置的当前处理人
     * @param taskOid 任务主键
     * @return
     * @throws VciBaseException
     */
    @Override
    public List<ProcessUserVO> getProcessUserByTask(String taskOid) throws VciBaseException{
        List<ProcessTaskVO> task = processDao.getTaskByOid(taskOid);
        if(task!=null && task.size()>0){
            return processDao.getNodePresideUsersByTask(task.get(0).getExecutionId(),task.get(0).getName());
        }else{
            throw new VciBaseException(msgCodePrefix + "taskNotFound",new String[]{taskOid}) ;
        }
    }
 
    /**
     * 获取我的待办事项--平台不支持查询数据总条数,不清楚在这种情况下,start和pagesize是用来做什么用的
     * @param conditionMap 条件查询
     * @param ph 分页和排序
     * @return
     * @throws VciBaseException
     */
    @Override
    public DataGrid getMyUndoProcessTask(
            Map<String, String> conditionMap, PageHelper ph) throws VciBaseException {
        if(conditionMap == null ) {
            conditionMap = new HashMap<String, String>();
        }
        return processDao.getUndoTask(conditionMap,ph,WebUtil.getCurrentUserId());
    }
 
    /**
     * 获取我处理了的任务
     * @param conditionMap 查询条件
     * @param ph 分页信息
     * @return
     * @throws VciBaseException
     */
    @Override
    public DataGrid getMyDoneProcessTask(Map<String, String> conditionMap,
            PageHelper ph) throws VciBaseException {
        if(conditionMap == null) {
            conditionMap = new HashMap<String, String>();
        }
        return processDao.getDoneProcess(conditionMap,ph,WebUtil.getCurrentUserId());
    }
 
    @Override
    public DataGrid getMyCompletedProcess(Map<String, String> conditionMap,
            PageHelper ph) throws VciBaseException{
        return processDao.getCompletedProcess(conditionMap,ph,WebUtil.getCurrentUserId());
    }
    
    @Override
    public DataGrid getAllCompletedProcess(Map<String, String> conditionMap,
            PageHelper ph) throws VciBaseException {
        return processDao.getCompletedProcess(conditionMap,ph,"");
    }
 
    @Override
    public DataGrid getMyObsoledtedProcess(Map<String, String> conditionMap,
            PageHelper ph) throws VciBaseException {
        return processDao.getObsoledtedProcess(conditionMap,ph,WebUtil.getCurrentUserId());
    }
    
    @Override
    public DataGrid getAllObsoledtedProcess(Map<String, String> conditionMap,
            PageHelper ph) throws VciBaseException {
        return processDao.getObsoledtedProcess(conditionMap,ph,"");
    }
 
    @Override
    public DataGrid getMySuspendedProcess(Map<String, String> conditionMap,
            PageHelper ph) throws VciBaseException {
        return processDao.getSuspendedProcess(conditionMap,ph,WebUtil.getCurrentUserId());
    }
    
    @Override
    public DataGrid getAllSuspendedProcess(Map<String, String> conditionMap,
            PageHelper ph) throws VciBaseException {
        return processDao.getSuspendedProcess(conditionMap,ph,"");
    }
 
    @Override
    public DataGrid getMyExecutingProcess(Map<String, String> conditionMap,
            PageHelper ph) throws VciBaseException{
        return processDao.getExecutingProcess(conditionMap,ph,WebUtil.getCurrentUserId());
    }
    
    @Override
    public DataGrid getAllExecutingProcess(Map<String, String> conditionMap,
            PageHelper ph) throws VciBaseException {
        return processDao.getExecutingProcess(conditionMap,ph,"");
    }
 
    @Override
    public DataGrid getMyCreateProcess(Map<String, String> conditionMap,
            PageHelper ph) throws VciBaseException {
        return processDao.getCreateProcess(conditionMap,ph,WebUtil.getCurrentUserId());
    }
 
 
    /**
     * 查询流程对于表格相关的定义
     * @param executionid 执行实例的主键
     * @param taskOid 任务的主键
     * @return
     * @throws VciBaseException
     */
    @Override
    public Map<String,Object> getDataTableDefine(String executionid,String taskOid)
            throws VciBaseException{
        //获取具体的任务
        WebUtil.alertNotNull(executionid,msgCodePrefix + "executionidIsNotFound");
        if(StringUtils.isBlank(executionid) ){
            throw new VciBaseException(msgCodePrefix + "executionidIsNotFound",new String[]{executionid});
        }
        List<ProcessTaskVO> tasks = null;
        if(StringUtils.isNotBlank(taskOid)) {
            tasks =processDao.getTaskByOid(taskOid);
            WebUtil.alertNotNull(tasks,"流程任务");
        }
        //找一下变量里有没有设置显示的内容
        while (StringUtils.countMatches(executionid,".") >1){
            //说明有两个以上的点,说明这个是子流程,我们需要使用父流程来查询
            executionid = executionid.substring(0,executionid.lastIndexOf("."));
        }
        //无需获取获取流程的对象,因为也只能拿到executionId
        //找一下变量里有没有设置显示的内容
        String btmType = processDao.getVariablesInProcess(executionid, WFVariablesKeyConstant.BTMTYPE_OLD);
        String displayTable = processDao.getVariablesInProcess(executionid, WFVariablesKeyConstant.UI_TABLE_CODE);
        String detailUrl =  processDao.getVariablesInProcess(executionid, WFVariablesKeyConstant.UI_DETAIL_URL);
        String UIContent = processDao.getVariablesInProcess(executionid,WFVariablesKeyConstant.UI_CONTENT_CODE);
        String UIType = processDao.getVariablesInProcess(executionid,WFVariablesKeyConstant.UI_TYPE);
 
        if(StringUtils.isBlank(detailUrl) && StringUtils.isBlank(UIContent) && StringUtils.isBlank(displayTable)){
            //说明取默认的
            UIType = btmType;
            UIContent = "processTaskUI";
        }else{
            if(StringUtils.isBlank(UIType)){
                UIType = btmType;
            }
        }
        Map<String, Object> map = new HashMap<String,Object>();
        map.put("btmType", btmType);
        map.put("UIType", UIType);
        map.put("tableCode", displayTable);
        map.put("detailUrl",detailUrl== null?"":detailUrl);
        map.put("UIContentCode",UIContent);
        //增加查询关联的业务数据
        List<LinkObject> linkObjects = processDao.getDataCloInTask("",executionid);
        StringBuilder sb = new StringBuilder();
        String thisBusinessOid = "";
        if(linkObjects!=null && linkObjects.size()>0){
            Set<String> oidSet = new HashSet<String>();
            //去除重复
            for(LinkObject clo : linkObjects){
                oidSet.add(clo.toOid);
            }
            for(String oidString : oidSet) {
                sb.append(oidString).append(",");
            }
            thisBusinessOid = sb.substring(0,sb.length() -1 );
            map.put("businessOids", sb.substring(0,sb.length() -1 ));
        }
        String executionidOnlyNumber = "";
        if(executionid.indexOf(".")>-1){
            executionidOnlyNumber = executionid.substring(executionid.indexOf(".") + 1);
        }
        String viewProcessLinkBusinessToken = Md5.md5(executionidOnlyNumber + "${executionsplit}" + thisBusinessOid);
        map.put("viewProcessLinkBusinessToken",viewProcessLinkBusinessToken);
        map.put("executionidno",executionidOnlyNumber);
        //需要去查询这个流程任务节点上有什么自定义的按钮
        if(tasks != null) {
 
            String jbpmDeploymentId = processDao.getJbpmDeploymentIdByExecutionId(executionid);
            if(StringUtils.isNotBlank(jbpmDeploymentId)) {
                try {
                    byte[] processXml = processDao.getProcessXmlContent(jbpmDeploymentId);
                    InputStream in = new ByteArrayInputStream(processXml);
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in, "utf-8"));
                    SAXReader saxr = new SAXReader();
                    Document doc = saxr.read(reader);
                    Element root = doc.getRootElement();
                    String name = tasks.get(0).getName();
                    if(name.contains("-")){
                        name = name.substring(name.lastIndexOf("-") + 1);
                    }
                    for (Iterator<?> a = root.elementIterator(); a.hasNext();) {
                        Element next = (Element) a.next();
                        //todo FlowConstants此占无法引用,后续会进行调整,再进行引用
//                        String cellName = next.attributeValue(FlowConstants.XMLNAME);
//                        if(cellName != null && cellName.equals(name)) {
//                            map.put("customerbuttoninfo",next.attributeValue(FlowConstants.URL_PATH));
//                            break;
//                        }
                    }
                }catch (Exception e) {
                    throw new VciBaseException("读取流程的xml内容出现了错误");
                }
            }
        }
        return map;
    }
 
    /**
     * 获取流程任务关联的业务数据
     * @param taskOid 任务主键
     * @param processOid 流程主键
     * @param referColumns 要显示的参照的列
     * @return
     * @throws VciBaseException
     */
    @Override
    public DataGrid getDataInProcess(String taskOid,String processOid,String referColumns)
            throws VciBaseException {
        if(StringUtils.isBlank(taskOid) && StringUtils.isBlank(processOid)){
            throw new VciBaseException(msgCodePrefix + "taskOidOrProcessOidNotNull");
        }
        return processDao.getDataByTask(taskOid,processOid,referColumns);
    }
 
    @Override
    public DataGrid getHistory(String executionId,
            boolean showCurrentNode) throws VciBaseException {
        List<ProcessHistoryVO> allHisTask = processDao.getHistory(executionId);
        List<ProcessHistoryVO> data = null;
        if(!showCurrentNode){
            data = new ArrayList<ProcessHistoryVO>();
            for(ProcessHistoryVO his : allHisTask){
                if(StringUtils.isNotEmpty(his.getEndTime())){
                    data.add(his);
                }
            }
        }else{
            data = allHisTask;
        }
        DataGrid dg = new DataGrid();
        dg.setData(data);
        dg.setTotal(data.size());
        dg.setLimit(-1);
        dg.setPage(1);
        //不支持分页
        return dg;
    }
 
    @Override
    public byte[] getProcessPicture(String executionId, String taskOid)
            throws VciBaseException{
        List<ProcessTaskVO> task = null;
        if(StringUtils.isNotBlank(taskOid)){
            task = processDao.getTaskByOid(taskOid);
        }
        if(task!=null && task.size()>0){
            return processDao.getProcessPicture(task.get(0).getExecutionId(),task.get(0).getName().substring(task.get(0).getName().lastIndexOf("-") + 1));
        }else{
            return getProcessTemplatePicture(executionId);
        }
    }
 
    @Override
    public byte[] getProcessTemplatePicture(String executionId)
            throws VciBaseException{
        return processDao.getProcessTemplatePicture(executionId);
    }
    
    @Override
    public List<ProcessTaskVO> getTaskByOid(String taskOid) throws VciBaseException {
        return processDao.getTaskByOid(taskOid);
    }
 
    @Override
    public List<ProcessOutcomeVO> getOutCome(String taskOid,
                                             boolean isQueryNextNode) throws VciBaseException{
        List<ProcessTaskVO> taskList = processDao.getTaskByOid(taskOid);
        List<ProcessOutcomeVO> allComes = new ArrayList<ProcessOutcomeVO>();
        if(taskList!=null && taskList.size()>0){
            ProcessTaskVO task = taskList.get(0);
            String[] allOutComes = processDao.getAllOutComes(task.getTaskOid());
            String tureTaskName = task.getName().substring(task.getName().lastIndexOf("-") + 1);//////////////平台使用这种方式存储太不稳定了,数据容易被弄乱
            for(String oc : allOutComes){
                ProcessOutcomeVO po = new ProcessOutcomeVO();
                po.setName(oc);
                String nextTaskName = processDao.getNextTaskName(task.getExecutionId(),tureTaskName,oc);
                if(StringUtils.isEmpty(oc)){
                    po.setName("未命名路由");
                }
                if(StringUtils.isNotEmpty(nextTaskName)){
                    po.setNextTaskName(nextTaskName);
                    if(isQueryNextNode && !"结束".equalsIgnoreCase(po.getNextTaskName())){
                        po.setProcessUserVO(processDao.getNodePresideUsersByTask(task.getExecutionId(), po.getNextTaskName()));
                        if(po.getProcessUserVO() == null || po.getProcessUserVO().size()==0){
                            //说明没有设置候选人
                            ProcessNodeVO processNodeVO = processDao.getNodePresideUsersByDeploy(processDao.getJbpmDeploymentIdByExecutionId(task.getExecutionId()), po.getNextTaskName());
                            if(processNodeVO !=null){
                                String maxSecretString = processDao.getVariablesInProcess(task.getExecutionId(),WFVariablesKeyConstant.DATA_MAX_SECRET);
                                int maxSecret = WebUtil.getInt(maxSecretString);
                                if(maxSecret ==0){
                                    maxSecret = -1;
                                }
                                //需要查看业务数据中是否有密级,在发起流程的时候已经添加
                                po.setNextNodeUser(getProcessUsersByNode(processNodeVO,maxSecret));
                            }
                        }
                    }
                }
                allComes.add(po);
            }
        }
        return allComes;
    }
 
    @Override
    public String getNameFromRule(String btmtype, Map<String, String> data)
            throws VciBaseException {
        // TODO Auto-generated method stub
        return null;
    }
 
    /**
     * 校验任务是否相同的流程模板和同一个任务
     */
    @Override
    public boolean checkUseSameTemplate(String taskOids) throws VciBaseException {
        List<ProcessTaskVO> allTask = getTaskByOid(taskOids);
        String depolyId = "";
        String taskName = "";
        if(allTask!=null){
            for(ProcessTaskVO task : allTask){
                String tureTaskName = task.getName().substring(task.getName().lastIndexOf("-") + 1).trim();//////////////平台使用这种方式存储太不稳定了,数据容易被弄乱
                String thisDepolyId = processDao.getJbpmDeploymentIdByExecutionId(task.getExecutionId()).trim();
                if(StringUtils.isEmpty(taskName)){
                    taskName = tureTaskName;
                    depolyId = thisDepolyId;
                }else if(!tureTaskName.equals(taskName) || !thisDepolyId.equals(depolyId)){
                    throw new VciBaseException("[{0}]与其他任务不是使用相同的流程模板或者不是同一个任务节点,{1}",new String[]{task.getName(),depolyId});
                }else if(StringUtils.isEmpty(task.getPrincipal())){
                    throw new VciBaseException("[{0}没有设置负责人,不能被批量执行",new String[]{task.getName()});
                }
            }
        }
        return true;
    }
 
    /**
     * 获取流程中关联的数据关联的文件
     *
     * @param conditionMap 查询条件
     * @param taskOid      任务主键
     * @param executionId 流程执行主键
     * @param pageHelper   分页信息
     * @return
     */
    @Override
    public DataGrid getFilesInProcess(Map<String, String> conditionMap, String taskOid, String executionId,PageHelper pageHelper) throws VciBaseException{
        List<LinkObject> cloByTask = processDao.getDataCloInTask(taskOid,executionId);
        if(cloByTask == null || cloByTask.size() == 0){
            throw new VciBaseException("没有关联的业务数据");
        }
        Map<String,List<String>> busOid_btmMap = new HashMap<String, List<String>>();
        Set<String> fileOidSet = new HashSet();
        for(LinkObject clo:cloByTask){
            if(FileTypeConstants.FILE_DATA_TABLE.equals(clo.toBTName)){
                fileOidSet.add(clo.toOid);
            }else {
                List<String> thisBtmOids = busOid_btmMap.getOrDefault(clo.toBTName,new ArrayList<>());
                thisBtmOids.add(clo.toOid);
                busOid_btmMap.put(clo.toBTName, thisBtmOids);
            }
        }
        DataGrid dg = new DataGrid();
        List<VciFileObjectVO> fileVOS = new ArrayList<VciFileObjectVO>();
 
        if(busOid_btmMap.size()>0){
            List<VciFileObjectVO> finalFileVOS = fileVOS;
            busOid_btmMap.forEach((btm, oids)->{
                finalFileVOS.addAll(fileObjectService.batchListFilesByOwnbizs(oids,btm,null));
            });
            fileVOS = finalFileVOS;
        }
        if(fileOidSet.size()>0){
            fileVOS.addAll(fileObjectService.listVciFileObjectByOids(fileOidSet));
        }
        if(!CollectionUtils.isEmpty(fileVOS)) {
            Integer userSecret = VciBaseUtil.getCurrentUserSecret();
            if(userSecret == null){
                userSecret = UserSecretEnum.NONE.getValue();
            }
            if(webProperties.isSecretRight()){
                Integer finalUserSecret = userSecret;
                fileVOS = fileVOS.stream().filter(s->{
                    Integer secretGrade = s.getSecretGrade();
                    if(secretGrade == null){
                        secretGrade = DataSecretEnum.NONE.getValue();
                    }
                    return secretGrade >= finalUserSecret;
                }).collect(Collectors.toList());
            }
 
            dg.setData(fileVOS);
            dg.setTotal(fileVOS.size());
        }
        return dg;
    }
 
    /**
     * 批量获取流程中的变量信息
     *
     * @param executionId 流程标识
     * @param keys        流程变量
     * @return
     * @throws VciBaseException
     */
    @Override
    public Map<String, String> getVariablesInProcess(String executionId, String keys) throws VciBaseException {
        WebUtil.alertNotNull(executionId,"流程标识",keys,"要查询的变量名称");
        String[] keyArray = keys.split(",");
        Map<String,String> variableInfoMap = new HashMap<String, String>();
        for(String key : keyArray){//平台不能批量获取,
            String value = processDao.getVariablesInProcess(executionId,key);
            if(value == null){
                value = "";
            }
            variableInfoMap.put(key,value);
        }
        return variableInfoMap;
    }
 
    /**
     * 根据业务数据,获取正在执行的流程
     *
     * @param bussinessOid 业务类型数据
     * @param btmName      业务类型名
     * @return 流程的执行oid
     * @throws VciBaseException
     */
    @Override
    public List<String> listExecutingProcessByBussinessOid(String bussinessOid, String btmName) throws VciBaseException {
        WebUtil.alertNotNull(bussinessOid,"业务类型数据",btmName,"业务类型名称");
        List<ProcessInstanceVO> processInstanceList = processDao.listExecutingProcessByBussinessOid(bussinessOid,btmName);
        List<String> processExecutionIdList = new ArrayList<String>();
        if(processInstanceList!=null && processInstanceList.size()>0){
            for(ProcessInstanceVO instance : processInstanceList){
                processExecutionIdList.add(instance.getExecutionId());
            }
        }
        return processExecutionIdList;
    }
 
    /**
     * 获取审批意见文件
     *
     * @param taskOids 任务的主键
     * @return 文件的信息
     */
    @Override
    public DataGrid<VciFileObjectVO> listAuditSuggestFile(String taskOids) {
        WebUtil.alertNotNull(taskOids,"流程任务主键");
        DataGrid dataGrid = getDataInProcess(taskOids,null,"");
        if(dataGrid == null || CollectionUtils.isEmpty(dataGrid.getData())){
            throw new VciBaseException("流程的业务数据是空的,数据错误");
        }
        String btwName = "";
        List<String> businessDataOidList = new ArrayList<String>();
        List<Map> businessDataList = (List<Map>)dataGrid.getData();
        for(Map businessData : businessDataList){
            if(StringUtils.isBlank(btwName)){
                btwName = (String)businessData.get("btmname");
            }
            businessDataOidList.add((String)businessData.get("oid"));
        }
        List<VciFileObjectVO> fileObjectVOS = new ArrayList<>();
        for(String oid : businessDataOidList){
            List<VciFileObjectVO> tempFileVOS = fileObjectService.listFilesByOwnbiz(oid, btwName, "processAuditSuggest");
            if(!CollectionUtils.isEmpty(tempFileVOS)){
                fileObjectVOS.addAll(tempFileVOS);
            }
        }
        dataGrid = new DataGrid();
        dataGrid.setData(fileObjectVOS);
        dataGrid.setTotal(fileObjectVOS.size());
        return dataGrid;
    }
 
    /**
     * 参照流程分类
     *
     * @param conditionMap 查询条件
     * @param pageHelper   分页对象
     * @return 分类的信息
     */
    @Override
    public DataGrid<ProcessClassifyVO> referGridProcessClassify(Map<String, String> conditionMap, PageHelper pageHelper) {
        if (pageHelper == null) {
            pageHelper = new PageHelper(-1);
        }
        //有需要转换的属性
        pageHelper.addDefaultAsc("plname");
        VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(conditionMap, WFProcessClassifyDO.class,pageHelper);
        queryWrapperForDO.setConditionMap(queryWrapperForDO.switchConditionMap());
        queryWrapperForDO.wrapperSql();
        List<WFProcessClassifyDO> doList = boService.selectByQueryWrapper(queryWrapperForDO,WFProcessClassifyDO.class);
        DataGrid<ProcessClassifyVO> dataGrid=new DataGrid<ProcessClassifyVO>();
        if (!CollectionUtils.isEmpty(doList)) {
            dataGrid.setData(processDao.processClassifyDO2VOs(doList));
            dataGrid.setTotal(VciBaseUtil.getInt(String.valueOf(boService.countByQueryWrapper(queryWrapperForDO,WFProcessClassifyDO.class))));
        }
        return dataGrid;
    }
 
    /**
     * 参照流程的模板
     * @param processClassifyId 流程分类的名称
     * @param name 模板的名称
     * @return 模板的显示对象
     */
    @Override
    public DataGrid<ProcessTemplateVO> referGridProcessTemplate(String processClassifyId, String name){
        if(StringUtils.isBlank(processClassifyId)){
            return new DataGrid<>();
        }
        List<ProcessTemplateVO> templateVOS = processDao.getTemplatesByType(processClassifyId, name, false);
        DataGrid<ProcessTemplateVO> dataGrid = new DataGrid<>();
        dataGrid.setData(templateVOS);
        dataGrid.setTotal(templateVOS ==null?0:templateVOS.size());
        return dataGrid;
    }
 
    /**
     * 参照流程分类树
     *
     * @param queryObject 查询对象
     * @return 树的信息
     */
    @Override
    public List<Tree> referTreeProcessClassify(TreeQueryObject queryObject) {
        PageHelper pageHelper = new PageHelper(-1);
        //有需要转换的属性
        pageHelper.addDefaultAsc("plname");
        VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(queryObject.getConditionMap(), WFProcessClassifyDO.class,pageHelper);
        queryWrapperForDO.setConditionMap(queryWrapperForDO.switchConditionMap());
        queryWrapperForDO.wrapperSql();
        List<WFProcessClassifyDO> doList = boService.selectByQueryWrapper(queryWrapperForDO,WFProcessClassifyDO.class);
        List<Tree> treeList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(doList)){
            doList.stream().forEach(classifyDO->{
                Tree tree = new Tree();
                tree.setOid(classifyDO.getOid());
                tree.setText(classifyDO.getName());
                Map<String,String> attributeMap = WebUtil.objectToMapString(classifyDO);
                tree.setAttributes(attributeMap);
                tree.setLeaf(true);
                treeList.add(tree);
            });
        }
        return treeList;
    }
 
    /**
     * 使用模板的主键获取
     *
     * @param id 模板的key
     * @param revisionValue 版本的值
     * @return 模板的显示对象
     */
    @Override
    public ProcessTemplateVO getTemplateById(String id,String revisionValue) {
        VciBaseUtil.alertNotNull(id,"模板的key",revisionValue,"版本的值");
        String deploymentId = processDao.getJbpmDeploymentId(id + "-" + revisionValue);
        if(StringUtils.isBlank(deploymentId)){
            throw new VciBaseException("流程模板在系统里不存在,{0}-{1}",new String[]{id,revisionValue});
        }
        return processDao.getTemplateByDeployId(deploymentId);
    }
 
    /**
     * 获取某个用户的待办任务个数
     *
     * @param username 用户的编号
     * @return 总数
     */
    @Override
    public int getUndoTaskCount(String username) {
        return processDao.countUndoTaskByUsername(username);
    }
 
 
}