whycxzp
6 天以前 4262e1fb86b1bd9f3e38430cdf02696c10d5a801
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
package com.whyc.service;
 
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whyc.constant.WorkflowEnum;
import com.whyc.constant.WorkflowProcessEnum;
import com.whyc.constant.WorkflowTypeEnum;
import com.whyc.dto.Response;
import com.whyc.mapper.WorkflowMainMapper;
import com.whyc.pojo.db_user.User;
import com.whyc.pojo.web_site.WorkflowDevice;
import com.whyc.pojo.web_site.WorkflowLink;
import com.whyc.pojo.web_site.WorkflowMain;
import com.whyc.util.ActionUtil;
import com.whyc.util.CommonUtil;
import com.whyc.util.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import javax.annotation.Resource;
import javax.servlet.ServletContext;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
 
@Service
public class WorkflowMainService {
 
    @Resource
    private WorkflowMainMapper mapper;
 
    @Autowired(required = false)
    private WorkflowLinkService linkService;
 
    @Autowired
    private WorkflowDeviceService deviceService;
 
 
    /**
     * 分派单号:
     * */
    public String getNextOrderId(String typeName) {
        ServletContext application = ActionUtil.getApplication();
        List<String> orderIdList = (List) application.getAttribute("orderIdList");
        if(orderIdList == null){
            orderIdList = new LinkedList<>();
        }
        String nextSequence = "";
        QueryWrapper<WorkflowMain> wrapper = Wrappers.query();
 
        String orderId = typeName+"-";
        String ymd = new SimpleDateFormat("yyyyMMdd").format(new Date());
        orderId = orderId+ymd+"-";
        //先查询是否缓存中是否存在前缀相同的单号,有的话存起来
        List<Integer> sequenceList = new LinkedList<>();
        sequenceList.add(0);
        for (String item : orderIdList) {
            if(item.startsWith(orderId)){
                String sequence = item.split("-")[3];
                sequenceList.add(Integer.parseInt(sequence));
            }
        }
        wrapper.likeRight("order_id",orderId).orderByDesc("order_id").last(" limit 1");
        WorkflowMain workflowMain = mapper.selectOne(wrapper);
        if(workflowMain != null){
            String sequence = workflowMain.getOrderId().split("-")[3];
            sequenceList.add(Integer.parseInt(sequence));
        }
        Integer maxSequence = sequenceList.stream().max(Comparator.comparing(Integer::intValue)).get();
        nextSequence = String.format("%05d", maxSequence+1);
        String nextOrderId = orderId + nextSequence;
        //加入缓存中
        orderIdList.add(nextOrderId);
        application.setAttribute("orderIdList",orderIdList);
        return nextOrderId;
    }
 
    public void add(WorkflowMain main) {
        mapper.insert(main);
    }
 
    public void addBatch(List<WorkflowMain> workflowMainList) {
        mapper.insertBatchSomeColumn(workflowMainList);
    }
 
 
    public WorkflowMain getBaseInfo(Integer mainId) {
        //根据mainId查询是哪种类型
        QueryWrapper<WorkflowMain> query = Wrappers.query();
        query.eq("id",mainId).last(" limit 1");
        WorkflowMain workflowMain = mapper.selectOne(query);
        Integer type = workflowMain.getType();
        if(type ==1){
            //List<BattDischargePlanTemp> tempList = tempService.getListByMainId(mainId);
            //workflowMain.setTempList(tempList);
        }
        List<WorkflowLink> linkList = linkService.getWorkflowInfo(mainId);
        workflowMain.setLinkList(linkList);
 
        return workflowMain;
    }
 
    public List<WorkflowLink> getAssignReply(Integer mainId) {
        QueryWrapper<WorkflowLink> wrapper = Wrappers.query();
        //wrapper.eq("main_id",mainId)
        //return linkMapper.
        return null;
    }
 
    public void updateById(WorkflowMain main) {
        mapper.updateById(main);
    }
 
    /**
     *
     * @param userId
     * @param type
     * @see WorkflowEnum
     *
     * @return
     */
    public Response<Map<Integer,Integer>> getOwnStatistics(int userId, int type) {
        Map<Integer,Integer> statistics = new HashMap<>();
        statistics.put(1,0);
        statistics.put(2,0);
        statistics.put(3,0);
        QueryWrapper<WorkflowMain> query = Wrappers.query();
        query.eq("create_user_id",userId).eq("type",type);
        List<WorkflowMain> mains = mapper.selectList(query);
        Map<Integer, List<WorkflowMain>> statusListMap = mains.stream().collect(Collectors.groupingBy(WorkflowMain::getStatus));
        Set<Integer> statusSet = statusListMap.keySet();
        for (Integer status : statusSet) {
            statistics.put(status,statusListMap.get(status).size());
        }
        return new Response<Map<Integer,Integer>>().set(1,statistics);
    }
 
    /**
     * 二次核容和故障隐患的统计
     *
     * 增加了全部 key=0
     * @param type ={0,2,3} 0代表二次核容和故障隐患一起
     * @see WorkflowEnum
     *
     * @return
     */
    public Response<Map<Integer,Integer>> getOwnStatistics2(int userId, int type) {
        Map<Integer,Integer> statistics = new HashMap<>();
        statistics.put(0,0);
        statistics.put(1,0);
        statistics.put(2,0);
        statistics.put(3,0);
        QueryWrapper<WorkflowMain> query = Wrappers.query();
        query.eq("create_user_id", userId);
        if(type == 0){
            query.in("type",2,3);
        }else {
            query.eq("type", type);
        }
        List<WorkflowMain> mains = mapper.selectList(query);
        Map<Integer, List<WorkflowMain>> statusListMap = mains.stream().collect(Collectors.groupingBy(WorkflowMain::getStatus));
        Set<Integer> statusSet = statusListMap.keySet();
        int sum = 0;
        for (Integer status : statusSet) {
            int size = statusListMap.get(status).size();
            statistics.put(status, size);
            sum+=size;
        }
        statistics.put(0,sum);
        return new Response<Map<Integer,Integer>>().set(1,statistics);
    }
 
    public Response<PageInfo<WorkflowMain>> ownListPage(int userId, int type, int status, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<WorkflowMain> mains = getOwnListByUserAndType(userId,type,status);
        if(type == 1) {
            for (WorkflowMain main : mains) {
                Integer id = main.getId();
                //List<BattDischargePlanTemp> tempList = tempService.getListByMainId(id);
                //main.setTempList(tempList);
            }
        }
        PageInfo<WorkflowMain> pageInfo = new PageInfo<>(mains);
        return new Response<PageInfo<WorkflowMain>>().set(1,pageInfo);
    }
 
    private List<WorkflowMain> getOwnListByUserAndType(int userId, int type, int status) {
        QueryWrapper<WorkflowMain> query = Wrappers.query();
        if(status == 0){
            query.eq("create_user_id",userId).eq("type",type).orderByDesc("id");
        }else {
            query.eq("create_user_id", userId).eq("type", type).eq("status", status).orderByDesc("id");
        }
        return mapper.selectList(query);
    }
 
    public Response<Map<Integer,Integer>> getReceivedStatistics(int type, User user) {
        Map<Integer,Integer> statisticsMap = linkService.getReceivedStatistics(type,user);
        return new Response<Map<Integer,Integer>>().set(1,statisticsMap);
    }
 
    public Response<PageInfo<WorkflowMain>> getReceivedListPage(int type, int status, User user, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<WorkflowMain> mains = getReceivedListByUserAndType(user,type,status);
        if (type == 1) {
            for (WorkflowMain main : mains) {
                Integer id = main.getId();
                //List<BattDischargePlanTemp> tempList = tempService.getListByMainId(id);
                //main.setTempList(tempList);
            }
        }
        PageInfo<WorkflowMain> pageInfo = new PageInfo<>(mains);
        return new Response<PageInfo<WorkflowMain>>().set(1, pageInfo);
    }
 
    private List<WorkflowMain> getReceivedListByUserAndType(User user, int type, int status) {
        return mapper.getReceivedListByUserAndType(user, type, status);
    }
 
    public WorkflowMain getById(Integer mainId) {
        return mapper.selectById(mainId);
    }
 
    //查询表单编号
    public int getMaxId() {
        Integer id = mapper.getMaxId();
        if (id == null) {
            id = 1;
        } else {
            id = id + 1;
        }
        return id;
    }
 
    /**
     * 通用提交方法,提交给角色-角色层
     * 如果related_id不为空,则需要特殊处理. 证明会影响到关联单据
     *
     * 涉及到新的问题需要解决,现场故障后,设备维修申请 或 报废申请 是多个,并存入工单设备表中. 并不只是单纯的数量. TODO ?自动化处理怎么更新
     */
 
    @Transactional
    public Response submit(WorkflowMain main){
        //1.提交到单据审批流程
        //如果存在关联单据id,首先校验提交的数量
        Date now = new Date();
        List<WorkflowDevice>  deviceListRelatedInDB = deviceService.getByMainId(main.getRelatedId());
        List<WorkflowDevice> deviceList = main.getDeviceList();
        if(main.getRelatedId() != null) {
            //遍历deviceList,如果deviceList内的对象的quantity值大于 deviceListRelatedInDB内对象列表中的对象所有字段相同的记录的quantityUnprocessed值,则返回错误
            for (int i = 0; i < deviceList.size(); i++) {
                WorkflowDevice device = deviceList.get(i);
                for (int j = 0; j < deviceListRelatedInDB.size(); j++) {
                    WorkflowDevice deviceInDB = deviceListRelatedInDB.get(j);
                    if (device.getName().equals(deviceInDB.getName())
                            && device.getModel().equals(deviceInDB.getModel())
                            && device.getVersion().equals(deviceInDB.getVersion())
                            && device.getBrand().equals(deviceInDB.getBrand())
                            && device.getType().equals(deviceInDB.getType())
                            && device.getSupplier().equals(deviceInDB.getSupplier())
                    ) {
                        if (device.getQuantity() > deviceInDB.getQuantityUnprocessed()) {
                            return new Response().setII(1, "入库数量不能大于维修申请关联单据的未处理数量");
                        }else{
                            //当前设备的校验结束,进入下一个设备校验
                            break;
                        }
                    }
 
                }
            }
        }
        //主表插入
        //初始化相关字段
        WorkflowTypeEnum typeEnum = WorkflowTypeEnum.getByType(main.getType());
        String name = typeEnum.getName();
        String namingPrefix = typeEnum.getNamingPrefix();
        String orderId = getNextOrderId(namingPrefix);
        //String title = mainTypeCN+"审批单-"+ DateUtil.YYYY_MM_DD_HH_MM_SS.format(now);
 
        String title = name + ThreadLocalUtil.format(ThreadLocalUtil.TIME_YYYY_MM_DD_HH_MM_SS, now);
        Integer mainStatus = WorkflowEnum.MAIN_STATUS_DEALING.getValue();
        User user = CommonUtil.getUser();
        WorkflowProcessEnum process = getProcessLevel(main.getType(),user.getRole());
        main.setOrderId(orderId);
        main.setTitle(title);
        main.setCreateUserId(user.getId());
        main.setCreateUserName(user.getName());
        main.setCreateTime(now);
        main.setBeginTime(now);
        main.setStatus(mainStatus);
        main.setProcessStage(process.getStage());
        if(main.getType() == WorkflowTypeEnum.DEVICE_REPAIR.getType().intValue()){ //维修申请单,需填入
            for (int i = 0; i < deviceList.size(); i++) {
                deviceList.get(i).setQuantityUnprocessed(deviceList.get(i).getQuantity());
            }
        }
        add(main);
        //主表关联的物料插入
        for (WorkflowDevice device : deviceList) {
            device.setMainId(main.getId());
        }
        deviceService.addBatch(deviceList);
 
        //内存中去除已插入数据库的单号
        ServletContext application = ActionUtil.getApplication();
        List<String> orderIdList = (List<String>) application.getAttribute("orderIdList");
        //校验是否去除
        boolean remove = orderIdList.remove(orderId);
        if(!remove){
            System.err.println("没有去除掉!!!!!!!!!!!!!");
        }
        application.setAttribute("orderIdList",orderIdList);
 
        //节点表插入
        WorkflowLink link = new WorkflowLink();
        link.setMainId(main.getId());
        link.setParentId(0);
        link.setProcessStage(process.getStage());
        link.setProcessName(process.getName());
        link.setCreateTime(now);
        link.setDealRoleId(getNextDealRoleId(process.getName()));
        link.setDealType(WorkflowEnum.TYPE_DELIVER.getValue());
        link.setDealDesc(main.getTaskDesc());
        link.setStatus(WorkflowEnum.LINK_STATUS_TAKING.getValue());
 
        linkService.add(link);
 
        //如果存在关联单据id,处理关联单据及自动生成新单据
        checkRelatedAndDone(main, now, deviceListRelatedInDB, user);
        return new Response().setII(1,"提交完成");
    }
 
    private void checkRelatedAndDone(WorkflowMain main, Date now, List<WorkflowDevice> deviceListRelatedInDB, User user) {
        if(main.getRelatedId() != null){
            //申请的数量<关联单据的未处理数量,则说明有剩余. 需要自动生成对立工单
            List<WorkflowDevice> deviceList = main.getDeviceList();
            //计算deviceListn内quantity属性值的和
            int sumQuantity = 0;
            for (WorkflowDevice device : deviceList) {
                sumQuantity += device.getQuantity();
            }
            //计算deviceListRelatedInDBn内quantityUnprocessed属性值的和
            int sumQuantityUnprocessedInDB = 0;
            for (WorkflowDevice device : deviceListRelatedInDB) {
                sumQuantityUnprocessedInDB += device.getQuantityUnprocessed();
            }
            if (sumQuantity < sumQuantityUnprocessedInDB){ //说明需要自动生成入库或者报废单据
                //需要自动生成报废的申请
                WorkflowMain mainAuto = new WorkflowMain();
                WorkflowTypeEnum typeEnumAuto;
 
                Integer statusAuto = WorkflowEnum.MAIN_STATUS_DEALING.getValue();
                WorkflowProcessEnum processAuto = WorkflowProcessEnum.PROCESS_MANAGER1SIGN;
                mainAuto.setCreateUserId(user.getId());
                mainAuto.setCreateTime(now);
                mainAuto.setBeginTime(now);
                mainAuto.setProcessStage(processAuto.getStage());
                mainAuto.setStatus(statusAuto);
                mainAuto.setRelatedId(main.getRelatedId());
                //整理主表的设备附表
                List<WorkflowDevice> deviceListAuto = new ArrayList<>();
                //遍历deviceListRelatedInDB,减去deviceList中申请的数量
                for (WorkflowDevice deviceInDB : deviceListRelatedInDB) {
                    boolean deviceExists = false;
                    for (WorkflowDevice device : deviceList) {
                        if (device.getName().equals(deviceInDB.getName())
                                && device.getModel().equals(deviceInDB.getModel())
                                && device.getVersion().equals(deviceInDB.getVersion())
                                && device.getBrand().equals(deviceInDB.getBrand())
                                && device.getType().equals(deviceInDB.getType())
                                && device.getSupplier().equals(deviceInDB.getSupplier())
                        ){
                            deviceExists = true;
                            if (deviceInDB.getQuantityUnprocessed()-device.getQuantity() > 0){
                                WorkflowDevice deviceAuto = new WorkflowDevice();
                                deviceAuto.setName(deviceInDB.getName());
                                deviceAuto.setModel(deviceInDB.getModel());
                                deviceAuto.setVersion(deviceInDB.getVersion());
                                deviceAuto.setQuantity(deviceInDB.getQuantityUnprocessed()-device.getQuantity());
                                deviceAuto.setBrand(deviceInDB.getBrand());
                                deviceAuto.setType(deviceInDB.getType());
                                deviceAuto.setSupplier(deviceInDB.getSupplier());
 
                                deviceListAuto.add(deviceAuto);
                            }else{
                                break;
                            }
                        }
                    }
                    if (!deviceExists){
                        WorkflowDevice deviceAuto = new WorkflowDevice();
                        deviceAuto.setName(deviceInDB.getName());
                        deviceAuto.setModel(deviceInDB.getModel());
                        deviceAuto.setVersion(deviceInDB.getVersion());
                        deviceAuto.setQuantity(deviceInDB.getQuantityUnprocessed());
                        deviceAuto.setBrand(deviceInDB.getBrand());
                        deviceAuto.setType(deviceInDB.getType());
                        deviceAuto.setSupplier(deviceInDB.getSupplier());
 
                        deviceListAuto.add(deviceAuto);
                    }
                }
 
                if(main.getType() == WorkflowTypeEnum.DEVICE_IN.getType().intValue()) { //申请的入库
                    mainAuto.setTaskDesc("提交了维修后的入库申请,系统自动生成剩余数量的报废申请");
                    typeEnumAuto = WorkflowTypeEnum.DEVICE_SCRAP;
                }else { //申请的报废
                    mainAuto.setTaskDesc("提交了维修后的报废申请,系统自动生成剩余数量的入库申请");
                    typeEnumAuto = WorkflowTypeEnum.DEVICE_IN;
                }
                mainAuto.setOrderId(getNextOrderId(typeEnumAuto.getNamingPrefix()));
                String titleAuto = typeEnumAuto.getName() + ThreadLocalUtil.format(ThreadLocalUtil.TIME_YYYY_MM_DD_HH_MM_SS, now);
                mainAuto.setTitle(titleAuto);
                mainAuto.setType(typeEnumAuto.getType());
                add(mainAuto);
                deviceListAuto.forEach(device -> {
                    device.setMainId(mainAuto.getId());
                });
                //插入主表的设备附表
                deviceService.addBatch(deviceListAuto);
 
                //自动节点生成
                WorkflowLink linkAuto = new WorkflowLink();
                linkAuto.setParentId(0);
                linkAuto.setProcessStage(processAuto.getStage());
                linkAuto.setProcessName(processAuto.getName());
                linkAuto.setCreateTime(now);
                linkAuto.setDealRoleId(getNextDealRoleId(processAuto.getName()));
                linkAuto.setDealType(WorkflowEnum.TYPE_DELIVER.getValue());
                linkAuto.setStatus(WorkflowEnum.LINK_STATUS_TAKING.getValue());
                linkAuto.setMainId(mainAuto.getId());
                linkAuto.setDealDesc(mainAuto.getTaskDesc());
                linkService.add(linkAuto);
 
            }
            //关闭关联单据的状态
            WorkflowMain relatedMain = new WorkflowMain();
            relatedMain.setId(main.getRelatedId());
            relatedMain.setStatus(WorkflowEnum.MAIN_STATUS_END_DEALT.getValue());
            relatedMain.setEndTime(now);
            if(main.getType() == WorkflowTypeEnum.DEVICE_IN.getType().intValue()) {
                relatedMain.setEndReason("用户提交维修申请后的入库申请,维修流程结束");
            }else{
                relatedMain.setEndReason("用户提交维修申请后的报废申请,维修流程结束");
            }
            updateById(relatedMain);
            //更新关联单据的设备剩余未处理数量为0
            deviceService.setQuantityUnprocessedZero(main.getRelatedId());
        }
    }
 
    /**
     * TODO 每次新增流程时,需要持续维护
     * 如果后续存在会签,则需要追加一个多type类型的同名方法
     * @param processLevelName 流程阶段名
     * @return 流程处理的下一个角色
     */
    private Integer getNextDealRoleId(String processLevelName) {
        WorkflowProcessEnum processEnum = WorkflowProcessEnum.getByName(processLevelName);
        switch (processEnum){
            //角色:1普通用户,2管理层,3领导层,4运维班组
            case PROCESS_MANAGER1SIGN:
                return 2;
            default:
                return 2;
        }
    }
 
    /**
     * TODO 每次新增流程时,需要持续维护
     * @param type 流程的类型
     * @param roleId 现在的角色
     * @return 流程处理的下一个角色
     */
    private WorkflowProcessEnum getProcessLevel(Integer type,Integer roleId) {
        WorkflowTypeEnum typeEnum = WorkflowTypeEnum.getByType(type);
        String name = typeEnum.getName();
        //角色:1普通用户,2管理层,3领导层,4运维班组
        switch (name){
            //审批顺序为 普通用户->管理员 ->普通用户(进行完结)
            case "设备维修申请单":
            case "设备入库申请单":
            case "设备报废申请单":
            case "设备出库申请单":
                if (roleId == 1) {
                    return WorkflowProcessEnum.PROCESS_MANAGER1SIGN;
                }
            default:
                return WorkflowProcessEnum.PROCESS_SPECIALIST;
        }
    }
 
    public void updateProcessLevel(String processLevel, Integer mainId) {
        UpdateWrapper<WorkflowMain> update = Wrappers.update();
        update.set("process_level",processLevel).eq("id",mainId);
        mapper.update((WorkflowMain) ActionUtil.objeNull,update);
    }
 
    public void resetRepairStatus(Integer relatedId) {
        UpdateWrapper<WorkflowMain> update = Wrappers.update();
        update.set("status",WorkflowEnum.MAIN_STATUS_WAIT_FOR_DEALING.getValue())
                .set("end_time",null)
                .set("end_reason",null)
                .eq("id",relatedId);
        mapper.update((WorkflowMain) ActionUtil.objeNull,update);
    }
}