lihang
2023-06-15 b48356e1b39f8e812f85d1627c0fc18e1f4d58ba
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
package com.vci.ubcs.omd.service.impl;
 
import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vci.ubcs.omd.constant.BtmTypeConstant;
import com.vci.ubcs.omd.entity.Status;
import com.vci.ubcs.omd.mapper.StatusMapper;
import com.vci.ubcs.omd.service.IStatusService;
import com.vci.ubcs.omd.vo.StatusVO;
import com.vci.ubcs.omd.wrapper.StatusWrapper;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.web.util.BeanUtil;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
 
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
 
/**
 * Description: 状态池的实现类
 *
 * @author LiHang
 * @date 2023/5/23
 */
@Service
public class StatusServiceImpl extends ServiceImpl<StatusMapper, Status> implements IStatusService {
 
    private final String REGEXP = "^[A-Za-z]+$";
 
    /**
     * 获取状态列表
     *
     * @param conditionMap 查询条件
     * @param pageHelper   分页信息和排序信息,默认使用id排序
     * @return 状态对象列表
     * @throws VciBaseException 查询出错时会抛出异常
     */
    @Override
    public IPage<StatusVO> listStatus(Map<String, Object> conditionMap, Query pageHelper) throws VciBaseException {
        return StatusWrapper.build().pageVO(baseMapper.selectPage(Condition.getPage(pageHelper), Condition.getQueryWrapper(conditionMap,Status.class).lambda().orderByAsc(Status::getId)));
    }
 
    /**
     * 获取状态列表
     *
     * @param conditionMap 查询条件
     * @return 状态对象列表
     * @throws VciBaseException 查询出错时会抛出异常
     */
    @Override
    public List<StatusVO> listStatusNoPage(Map<String, String> conditionMap) throws VciBaseException {
        Status queryVO = new Status();
        BeanMap.create(queryVO).putAll(conditionMap);
        return StatusWrapper.build().listEntityVO(baseMapper.selectList(Condition.getQueryWrapper(queryVO).lambda().orderByAsc(Status::getId)));
    }
 
    /**
     * 根据主键获取状态
     *
     * @param pkStatus 状态主键
     * @return 状态,如果不存在会返回null
     * @throws VciBaseException 参数为空或者查询出错时会抛出错误
     */
    @Override
    public StatusVO getStatusByOid(String pkStatus) throws VciBaseException {
        List<StatusVO> statusVOList = listStatusByOids(pkStatus);
        if (!CollectionUtils.isEmpty(statusVOList)){
            return statusVOList.get(0);
        }
        return null;
    }
 
    /**
     * 根据主键批量获取状态
     *
     * @param primaryKeys 状态主键,用逗号分隔
     * @return 状态列表,如果有不存在的不会返回,全部不存在的则返回空列表
     * @throws VciBaseException 参数为空或者查询出错时会抛出错误
     */
    @Override
    public List<StatusVO> listStatusByOids(String primaryKeys) throws VciBaseException {
        VciBaseUtil.alertNotNull(primaryKeys,"状态的主键");
        List<String> pkList = Func.toStrList(",", primaryKeys);
        return listStatusByOidCollection(pkList);
    }
 
    /**
     * 批量根据主键获取状态
     *
     * @param pkStatusCollection 状态主键集合
     * @return 状态列表,如果有不存在的不会返回,全部不存在的则返回空列表
     * @throws VciBaseException 参数为空或者查询出错时会抛出错误
     */
    @Override
    public List<StatusVO> listStatusByOidCollection(Collection<String> pkStatusCollection) throws VciBaseException {
        if(!CollectionUtils.isEmpty(pkStatusCollection)){
            List<Status> statusDOList = listStatusByOidCollectionDO(pkStatusCollection);
            if(!CollectionUtils.isEmpty(statusDOList)) {
                return StatusWrapper.build().listEntityVO(statusDOList);
            }
        }
        return null;
    }
 
    /**
     * 根据主键集合获取数据对象
     * @param oidCollection 主键集合
     * @return 查询出来的数据对象
     * @throws VciBaseException mybatis执行出错时会抛出异常
     */
    private List<Status> listStatusByOidCollectionDO(Collection<String> oidCollection) throws VciBaseException{
        if(!CollectionUtils.isEmpty(oidCollection)){
            List<Status> statusDOList = new ArrayList<>();
            Collection<Collection<String>> pksCollections = VciBaseUtil.switchCollectionForOracleIn(oidCollection);
            if(!CollectionUtils.isEmpty(pksCollections)) {
                pksCollections.forEach(s -> {
                    List<Status> queryResult = baseMapper.selectList(Wrappers.<Status>query().lambda().in(Status::getOid,s));
                    if(!CollectionUtils.isEmpty(queryResult)){
                        statusDOList.addAll(queryResult);
                    }
                });
            }
            return statusDOList;
        }
        return null;
    }
 
    /**
     * 根据英文名称获取状态
     *
     * @param id 英文名称
     * @return 状态,如果不存在会返回null
     * @throws VciBaseException 查询出错抛出异常
     */
    @Override
    public StatusVO getStatusById(String id) throws VciBaseException {
        List<StatusVO> statusVOList = listStatusByIds(id);
        if(!CollectionUtils.isEmpty(statusVOList)){
            return statusVOList.get(0);
        }
        return null;
    }
 
    /**
     * 根据英文名称批量获取状态
     *
     * @param ids 英文名称,使用逗号分隔
     * @return 状态列表,如果有不存在的不会返回,全部不存在的则返回空列表
     * @throws VciBaseException 参数为空或者查询出错时会抛出错误
     */
    @Override
    public List<StatusVO> listStatusByIds(String ids) throws VciBaseException {
        VciBaseUtil.alertNotNull(ids,"状态的英文名称");
        List<String> idList = Func.toStrList(",", ids);
        return listStatusByIdCollection(idList);
    }
 
    /**
     * 根据英文名称集合批量获取状态
     *
     * @param idCollection 英文名称集合
     * @return 状态列表,如果有不存在的不会返回,全部不存在的则返回空列表
     * @throws VciBaseException 参数为空或者查询出错时会抛出错误
     */
    @Override
    public List<StatusVO> listStatusByIdCollection(Collection<String> idCollection) throws VciBaseException {
        if(!CollectionUtils.isEmpty(idCollection)){
            List<Status> statusDOList = listStatusByIdCollectionDO(idCollection);
            if(!CollectionUtils.isEmpty(statusDOList)) {
                return StatusWrapper.build().listEntityVO(statusDOList);
            }
        }
        return null;
    }
 
    /**
     * 根据英文名称集合获取数据对象
     * @param idCollection 英文名称集合
     * @return 数据对象列表,如果有不存在的不会返回,全部不存在的则返回空列表
     * @throws VciBaseException mybatis查询出错的时候会抛出异常
     */
    private List<Status> listStatusByIdCollectionDO(Collection<String> idCollection) throws VciBaseException {
        if(CollectionUtils.isEmpty(idCollection)) {
            return null;
        }
        List<Status> statusDOList = new ArrayList<>();
        Collection<Collection<String>> idCollections = VciBaseUtil.switchCollectionForOracleIn(idCollection);
        if(!CollectionUtils.isEmpty(idCollections)) {
            idCollections.forEach(s -> {
                List<Status> queryResult = baseMapper.selectByIdIgnoreCase(s);
                if(!CollectionUtils.isEmpty(queryResult)){
                    statusDOList.addAll(queryResult);
                }
            });
        }
        return statusDOList;
    }
 
    /**
     * 根据状态主键获取中文名称
     *
     * @param oid 状态主键,多个使用逗号分隔
     * @return 中文名称,如果不存在会返回null
     * @throws VciBaseException 参数为空或者查询出错时会抛出错误
     */
    @Override
    public String getNameByOid(String oid) throws VciBaseException {
        VciBaseUtil.alertNotNull(oid,"状态对象主键");
        return Optional.ofNullable(getStatusByOid(oid)).orElseGet(StatusVO::new).getName();
    }
 
    /**
     * 根据状态英文名称获取中文名称
     *
     * @param id 状态英文名称
     * @return 中文名称,如果不存在会返回null
     * @throws VciBaseException 参数为空或者查询出错时会抛出错误
     */
    @Override
    public String getNameById(String id) throws VciBaseException {
        VciBaseUtil.alertNotNull(id,"状态对象主键");
        return Optional.ofNullable(getStatusById(id)).orElseGet(StatusVO::new).getName();
    }
 
    /**
     * 添加状态
     *
     * @param statusVO 状态显示对象(和DTO共用)
     * @return 添加后的状态
     * @throws VciBaseException 添加出错的时候会抛出异常
     */
    @Override
    public StatusVO addSave(StatusVO statusVO) throws VciBaseException {
        VciBaseUtil.alertNotNull(statusVO,"要添加的状态",statusVO.getId(),"状态英文名称",statusVO.getName(),"状态中文名称");
        List<StatusVO> statusVOS = new ArrayList<>();
        statusVOS.add(statusVO);
        List<StatusVO> statusVOList = batchAddSave(statusVOS);
        if(CollectionUtils.isEmpty(statusVOList)){
            return null;
        }
        return statusVOList.get(0);
    }
 
    /**
     * 批量添加状态
     *
     * @param statusVOList 状态显示对象列表(和DTO共用)
     * @return 批量添加后的状态
     * @throws VciBaseException 添加出错的时候会抛出异常
     */
    @Override
    public List<StatusVO> batchAddSave(List<StatusVO> statusVOList) throws VciBaseException {
        if(CollectionUtils.isEmpty(statusVOList)){
            throw new VciBaseException("要添加的状态对象不能为空");
        }
        //1. 判断各个属性是否必输项都输入了
        //2. 判断英文名称是否重复
        Set<String> idSet = new HashSet<>();
        String creator = AuthUtil.getUserAccount();
        Date now = new Date();
        Pattern pattern = Pattern.compile(REGEXP);
        statusVOList.forEach(s -> {
            if (!pattern.matcher(s.getId()).matches()){
                throw new VciBaseException("英文名称{0}只能是英文字母",new Object[]{s.getId()});
            }
            VciBaseUtil.alertNotNull(s.getId(),"状态英文名称",s.getName(),"状态中文名称");
            if(idSet.contains(s.getId().toLowerCase().trim())){
                throw new VciBaseException("英文名称为{0}的状态已经存在(不区分大小写)",new Object[]{s.getId()});
            }else{
                idSet.add(s.getId().toLowerCase().trim());
            }
            if(StringUtils.isBlank(s.getOid())){
                s.setOid(VciBaseUtil.getPk());
            }
            s.setBtmName(BtmTypeConstant.STATUS);
            s.setOwner(creator);
            s.setCreator(creator);
            s.setCreateTime(now);
            s.setLastModifier(creator);
            s.setLastModifyTime(now);
            s.setTs(now);
        });
        //判断是否存在
        List<Status> checkExistStatusDOList = listStatusByIdCollectionDO(idSet);
        if(!CollectionUtils.isEmpty(checkExistStatusDOList)){
            String existIds = checkExistStatusDOList.stream().map(Status::getId).collect(Collectors.joining(","));
            throw new VciBaseException("英文名称为{0}的状态的已经在系统中存在(不区分大小写),不能添加",new Object[]{existIds});
        }
        List<Status> statusDOList = StatusWrapper.build().batchCopyVO2DO(statusVOList);
        VciBaseUtil.switchCollectionForOracleIn(statusDOList,1000).forEach(this::saveBatch);
        return statusVOList;
    }
 
    /**
     * 修改状态
     *
     * @param statusVO 状态显示对象(和DTO共用)
     * @return 修改后的状态
     * @throws VciBaseException 修改出错的时候会抛出异常
     */
    @Override
    public StatusVO editSave(StatusVO statusVO) throws VciBaseException {
        VciBaseUtil.alertNotNull(statusVO,"要修改的状态对象",statusVO.getOid(),"要修改的状态对象的主键");
        List<StatusVO> needEditVOList = new ArrayList<>();
        needEditVOList.add(statusVO);
        List<StatusVO> statusVOList = batchEditSave(needEditVOList);
        if(!CollectionUtils.isEmpty(statusVOList)){
            return statusVOList.get(0);
        }
        return null;
    }
 
    /**
     * 批量修改状态
     *
     * @param statusVOList 状态显示对象列表(和DTO共用)
     * @return 批量修改后的状态
     * @throws VciBaseException 修改出错的时候会抛出异常
     */
    @Override
    public List<StatusVO> batchEditSave(List<StatusVO> statusVOList) throws VciBaseException {
        if(CollectionUtils.isEmpty(statusVOList)){
            throw new VciBaseException("要修改的状态对象不能为空");
        }
        //1. 判断各个属性是否必输项都输入了
        //2. 判断状态的英文名称是否重复
        Set<String> idSet = new HashSet<>();
        Map<String,StatusVO> oidObjectMap = new HashMap<>();
        String creator = AuthUtil.getUserAccount();
        Date now = new Date();
        statusVOList.forEach(s -> {
            //判断为空
            VciBaseUtil.alertNotNull(s.getOid(),"状态主键",s.getId(),"状态英文名称",s.getName(),"状态中文名称");
            //判断本次是否存在
            if(idSet.contains(s.getId().toLowerCase().trim())){
                throw new VciBaseException("英文名称为{0}的状态已经存在(不区分大小写)",new Object[]{s.getId()});
            }else{
                idSet.add(s.getId().toLowerCase().trim());
            }
            oidObjectMap.put(s.getOid(),s);
            s.setLastModifier(creator);
            s.setLastModifyTime(now);
            s.setTs(now);
        });
        //判断是否存在
        List<Status> statusDOList = listStatusByOidCollectionDO(oidObjectMap.keySet());
        if(CollectionUtils.isEmpty(statusDOList)){
            throw new VciBaseException("这些状态在系统中均不存在",new Object[]{});
        }
        //判断属性名称是否修改
        Set<String> oidInDbSet = new HashSet<>();
        statusDOList.forEach(s -> {
            StatusVO statusVO =  oidObjectMap.get(s.getOid());
            if(!statusVO.getId().equalsIgnoreCase(s.getId())){
                throw new VciBaseException("状态[{0}]的英文名称不允许修改,原名称{1},新名称{2}",new Object[]{s.getName(),s.getId(),statusVO.getId()});
            }
            BeanUtil.convert(statusVO,s);
            oidInDbSet.add(s.getOid());
        });
        oidObjectMap.forEach( (k,v) ->{
            if(!oidInDbSet.contains(k)){
                throw new VciBaseException("状态{0}[{1}]在系统中不存在",new Object[]{v.getId(),v.getName()});
            }
        });
        //看看是否有不在系统中存在的
        VciBaseUtil.switchCollectionForOracleIn(statusDOList).forEach(this::saveOrUpdateBatch);
        return statusVOList;
    }
 
    /**
     * 删除状态
     *
     * @param statusVO 状态显示对象
     * @throws VciBaseException 如果状态被引用,或者删除出错时会抛出异常
     */
    @Override
    public void delete(StatusVO statusVO) throws VciBaseException {
        VciBaseUtil.alertNotNull(statusVO,"要删除的状态对象",statusVO.getOid(),"要删除的状态对象的主键");
        List<StatusVO> needDeleteVOList = new ArrayList<>();
        needDeleteVOList.add(statusVO);
        batchDelete(needDeleteVOList);
    }
 
    /**
     * 批量删除状态
     *
     * @param statusVOList 要删除的状态显示对象列表
     * @throws VciBaseException 如果状态被引用,或者删除出错时会抛出异常
     */
    @Override
    public void batchDelete(List<StatusVO> statusVOList) throws VciBaseException {
        if(CollectionUtils.isEmpty(statusVOList)){
            throw new VciBaseException("要删除的状态对象不能为空");
        }
        Set<String> oidSet= new HashSet<>();
        statusVOList.stream().forEach( s -> {
            VciBaseUtil.alertNotNull(s.getOid(),"要删除的状态对象的主键");
            oidSet.add(s.getOid());
        });
        //查询
        List<Status> statusDOList = listStatusByOidCollectionDO(oidSet);
        if(CollectionUtils.isEmpty(statusDOList)){
            throw new VciBaseException("要删除的状态在系统中不存在,可能您需要刷新后再试");
        }
        Set<String> oidInDbSet = statusDOList.stream().map(Status::getOid).collect(Collectors.toSet());
        oidSet.forEach( s -> {
            if(!oidInDbSet.contains(s)){
                throw new VciBaseException("要删除的状态在系统中不存在,可能您需要刷新后再试");
            }
        });
        //检查属性是否被引用
        if(checkStatusUseds(oidSet)){
            throw new VciBaseException("要删除的状态在生命周期对象中被使用,无法删除");
        }
        Collection<Collection<String>> oidCollections = VciBaseUtil.switchCollectionForOracleIn(oidInDbSet);
        for(Collection<String> oidCollection : oidCollections){
            baseMapper.delete(Wrappers.<Status>query().lambda().in(Status::getOid,oidCollection));
        }
    }
 
    /**
     * 批量校验状态是否被使用
     *
     * @param oidCollection 主键集合
     * @return true表示被引用
     */
    @Override
    public boolean checkStatusUseds(Collection<String> oidCollection) {
        return false;
    }
 
    /**
     * 校验状态是否被引用
     *
     * @param pkStatus 状态的主键
     * @return true表示被引用, false表示没有被引用
     * @throws VciBaseException 参数为空或者查询出错时会抛出错误
     */
    @Override
    public boolean checkStatusUsed(String pkStatus) throws VciBaseException {
        return false;
    }
}