package com.ycl.platform.service.impl; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ycl.exception.ServiceException; import com.ycl.platform.domain.entity.*; import com.ycl.platform.domain.form.*; import com.ycl.platform.domain.query.DistributeWorkOrderQuery; import com.ycl.platform.domain.query.WorkOrderQuery; import com.ycl.platform.domain.vo.DistributeWorkOrderVO; import com.ycl.platform.domain.vo.WorkOrderVO; import com.ycl.platform.domain.vo.WorkOrderYwConditionRecordVO; import com.ycl.platform.mapper.*; import com.ycl.platform.service.NotifyService; import com.ycl.platform.service.WorkOrderAuditingRecordService; import com.ycl.platform.service.WorkOrderService; import com.ycl.system.Result; import com.ycl.system.model.LoginUser; import com.ycl.system.page.PageUtil; import com.ycl.utils.DateUtils; import com.ycl.utils.SecurityUtils; import com.ycl.utils.redis.RedisCache; import com.ycl.utils.uuid.IdUtils; import constant.PointConfigConstants; import enumeration.general.*; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.ArrayUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** * 工单 服务实现类 * * @author xp * @since 2024-03-05 */ @Service @RequiredArgsConstructor public class WorkOrderServiceImpl extends ServiceImpl implements WorkOrderService { private final WorkOrderMapper workOrderMapper; private final YwUnitMapper ywUnitMapper; private final YwPeopleMapper ywPeopleMapper; private final WorkOrderAuditingRecordMapper workOrderAuditingRecordMapper; private final WorkOrderAuditingRecordService workOrderAuditingRecordService; private final WorkOrderYwConditionRecordMapper workOrderYwConditionRecordMapper; private final NotifyService notifyService; private final WorkOrderDistributeRecordMapper workOrderDistributeRecordMapper; private final String DISTRIBUTE_LOCK_KEY = "distributeLock"; private final static String IMPORTANT = "important"; @Autowired private RedisCache redisCache; /** * 添加 * @param form * @return */ @Override public Result add(WorkOrderForm form) { WorkOrder entity = WorkOrderForm.getEntityByForm(form, null); entity.setWorkOrderNo(IdUtils.timeAddRandomNO(5)); entity.setCreateTime(DateUtils.getNowDate()); entity.setStatus(WorkOrderStatusEnum.WAIT_DISTRIBUTE); if(baseMapper.insert(entity) > 0) { return Result.ok("添加成功"); } return Result.error("添加失败"); } /** * 修改 * @param form * @return */ @Override public Result update(WorkOrderForm form) { WorkOrder entity = baseMapper.selectById(form.getId()); // 为空抛IllegalArgumentException,做全局异常处理 Assert.notNull(entity, "记录不存在"); BeanUtils.copyProperties(form, entity); if (baseMapper.updateById(entity) > 0) { return Result.ok("修改成功"); } return Result.error("修改失败"); } @Override @Transactional(rollbackFor = Exception.class) public Result auditing(WorkOrderAuditingForm form) { WorkOrder workOrder = baseMapper.selectById(form.getId()); // 工单状态 workOrder.setStatus(form.getAuditingResult()); baseMapper.updateById(workOrder); // 添加一条审核记录 WorkOrderAuditingRecord workOrderAuditingRecord = new WorkOrderAuditingRecord(); workOrderAuditingRecord.setWorkOrderId(workOrder.getId()); workOrderAuditingRecord.setAuditingUser(SecurityUtils.getLoginUser().getUserId().intValue()); workOrderAuditingRecord.setResult(form.getAuditingResult().getDesc()); workOrderAuditingRecord.setRemark(form.getAuditingRemark()); workOrderAuditingRecordMapper.insert(workOrderAuditingRecord); // 添加新通知 Notify notify = Notify.genEntityByUnit(NotifyTypeEnum.WORK_ORDER, form.getAuditingResult().getDesc(), workOrder.getUnitId(), UrgentLevelEnum.WARNING, workOrder.getWorkOrderNo()); notifyService.save(notify); return Result.ok("操作成功"); } @Override @Transactional(rollbackFor = Exception.class) public Result batchAuditing(WorkOrderBatchAuditingForm form) { // 根据故障类型获取列表 List list = new LambdaQueryChainWrapper<>(baseMapper) .in(WorkOrder::getStatus, WorkOrderStatusEnum.YW_HANDLE.getValue()) .in(WorkOrder::getErrorType, form.getErrorTypes()) .select(WorkOrder::getId, WorkOrder::getUnitId, WorkOrder::getWorkOrderNo) .list(); if (list.isEmpty()) { return Result.error("没有工单可以审核"); } List ids = list.stream().map(WorkOrder::getId).collect(Collectors.toList()); // 工单状态 LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper<>(); lambdaUpdateWrapper.in(WorkOrder::getId, ids); lambdaUpdateWrapper.set(WorkOrder::getStatus, form.getAuditingResult()); baseMapper.update(lambdaUpdateWrapper); // 添加多条审核记录 List workOrderAuditingRecords = new ArrayList<>(); for (Integer id : ids) { WorkOrderAuditingRecord workOrderAuditingRecord = new WorkOrderAuditingRecord(); workOrderAuditingRecord.setWorkOrderId(id); workOrderAuditingRecord.setAuditingUser(SecurityUtils.getLoginUser().getUserId().intValue()); workOrderAuditingRecord.setResult(form.getAuditingResult().getDesc()); workOrderAuditingRecord.setRemark(form.getAuditingRemark()); workOrderAuditingRecords.add(workOrderAuditingRecord); } workOrderAuditingRecordService.saveBatch(workOrderAuditingRecords); // 添加新通知 List notifies = new ArrayList<>(); for (WorkOrder workOrder : list) { Notify notify = Notify.genEntityByUnit(NotifyTypeEnum.WORK_ORDER, form.getAuditingResult().getDesc(), workOrder.getUnitId(), UrgentLevelEnum.WARNING, workOrder.getWorkOrderNo()); notifies.add(notify); } notifyService.saveBatch(notifies); return Result.ok("操作成功"); } @Override @Transactional(rollbackFor = Exception.class) public Result ywCondition(WorkOrderYWConditionForm form) { WorkOrder workOrder = baseMapper.selectById(form.getId()); if (Objects.isNull(workOrder)) { throw new ServiceException("工单不存在"); } // 工单状态 workOrder.setStatus(WorkOrderStatusEnum.YW_HANDLE); workOrder.setYwHandleTime(LocalDateTime.now()); baseMapper.updateById(workOrder); // 添加一条运维情况记录 WorkOrderYwConditionRecord workOrderYwConditionRecord = new WorkOrderYwConditionRecord(); workOrderYwConditionRecord.setWorkOrderId(workOrder.getId()); workOrderYwConditionRecord.setCommitUser(SecurityUtils.getLoginUser().getUserId().intValue()); workOrderYwConditionRecord.setYwCondition(form.getYwCondition()); workOrderYwConditionRecord.setYwProofMaterials(form.getYwProofMaterials()); workOrderYwConditionRecordMapper.insert(workOrderYwConditionRecord); return Result.ok("操作成功"); } @Override public Result selectYwConditionByYwId(Integer id) { List ywConditionList = workOrderYwConditionRecordMapper.selectYwConditionByYwId(id); return Result.ok().data(ywConditionList); } @Override public Result selectYwAuditingListByYwId(String id) { return Result.ok().data( new LambdaQueryChainWrapper<>(workOrderAuditingRecordMapper) .eq(WorkOrderAuditingRecord::getWorkOrderId, id) .orderByAsc(WorkOrderAuditingRecord::getCreateTime) .list()); } @Override public Result ywResult(WorkOrderYWResultForm form) { return null; } @Override public Result checkResult(WorkOrderCheckResultForm form) { return null; } /** * 批量删除 * @param ids * @return */ @Override public Result remove(List ids) { if(baseMapper.deleteBatchIds(ids) > 0) { return Result.ok("删除成功"); } return Result.error("删除失败"); } /** * id删除 * @param id * @return */ @Override public Result removeById(String id) { if(baseMapper.deleteById(id) > 0) { return Result.ok("删除成功"); } return Result.error("删除失败"); } /** * 分页查询 * @param query * @return */ @Override public Result page(WorkOrderQuery query) { IPage page = PageUtil.getPage(query, WorkOrderVO.class); baseMapper.page(page, query); return Result.ok().data(page.getRecords()).total(page.getTotal()); } @Override public Result distributePage(DistributeWorkOrderQuery query) { IPage page = PageUtil.getPage(query, WorkOrderVO.class); baseMapper.distributePage(page, query); page.getRecords().stream().forEach(workOrder -> { if (StringUtils.hasText(workOrder.getPointTag()) && workOrder.getPointTag().contains(IMPORTANT)) { workOrder.setImportant(Boolean.TRUE); } }); return Result.ok().data(page).total(page.getTotal()); } @Override public Result distributeFast(DistributeWorkOrderVO data) { // 获取当前时间 LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault()); switch (data.getFastWay()) { case LAST_HALF_HOUR: data.setStart(now.minusMinutes(30)); data.setEnd(now); break; case LAST_HOUR: data.setStart(now.minusHours(1)); data.setEnd(now); break; case LAST_TWO_HOUR: data.setStart(now.minusHours(2)); data.setEnd(now); break; case LAST_DAY: data.setStart(now.minusDays(1)); data.setEnd(now); break; } // 查询符合条件的工单 List ids = new LambdaQueryChainWrapper<>(baseMapper) .eq(WorkOrder::getStatus, WorkOrderStatusEnum.WAIT_DISTRIBUTE) .eq(Objects.nonNull(data.getUnitId()), WorkOrder::getUnitId, data.getUnitId()) .eq(WorkOrder::getErrorType, data.getErrorType()) .between(WorkOrder::getCreateTime, data.getStart(), data.getEnd()) .orderByDesc(WorkOrder::getCreateTime) .last("limit " + data.getFastNumLimit()) .list() .stream() .map(WorkOrder::getId) .toList(); if (ids.isEmpty()) { return Result.error("没有符合条件的工单"); } if (!getDistributeLock()) { return Result.error("此刻有人下发中,为避免冲突,请稍后重试"); } try { new LambdaUpdateChainWrapper<>(baseMapper) .set(WorkOrder::getStatus, WorkOrderStatusEnum.DISTRIBUTED) .in(WorkOrder::getId, ids) .update(); addDistributeRecord(ids, WorkOrderDistributeWayEnum.FAST_DISTRIBUTE); return Result.ok("成功下发" + ids.size() + "条工单"); } catch (Exception e) { return Result.error("操作失败"); } finally { distributeUnLock(); } } @Override public Result selectedIdsDistribute(DistributeWorkOrderQuery query) { WorkOrderDistributeWayEnum distributeWayEnum = WorkOrderDistributeWayEnum.SELECTED_DISTRIBUTE; if (!getDistributeLock()) { return Result.error("此刻有人下发中,为避免冲突,请稍后重试"); } try { if (query.getIds().isEmpty()) { query.setIds(new LambdaQueryChainWrapper<>(baseMapper) .eq(WorkOrder::getStatus, WorkOrderStatusEnum.WAIT_DISTRIBUTE) .eq(Objects.nonNull(query.getUnitId()), WorkOrder::getUnitId, query.getUnitId()) .select(WorkOrder::getId) .list() .stream() .map(WorkOrder::getId) .collect(Collectors.toList())); distributeWayEnum = WorkOrderDistributeWayEnum.ALL_DISTRIBUTE; } if (query.getIds().isEmpty()) { return Result.error("没有工单待下发"); } new LambdaUpdateChainWrapper<>(baseMapper) .set(WorkOrder::getStatus, WorkOrderStatusEnum.DISTRIBUTED) .in(WorkOrder::getId, query.getIds()) .update(); addDistributeRecord(query.getIds(), distributeWayEnum); return Result.ok("成功下发" + query.getIds().size() + "条工单"); } catch (Exception e) { return Result.error("操作失败"); } finally { distributeUnLock(); } } /** * 申请工单下发锁 * @return 工单下发锁申请结果 */ public synchronized Boolean getDistributeLock() { if (Objects.isNull(redisCache.getCacheObject(DISTRIBUTE_LOCK_KEY))) { redisCache.setCacheObject(DISTRIBUTE_LOCK_KEY, "1"); return true; } else { return false; } } /** * 工单下发锁释放 */ public synchronized void distributeUnLock() { redisCache.deleteObject(DISTRIBUTE_LOCK_KEY); } /** * 添加工单下发记录 * @param ids 工单id */ private void addDistributeRecord(List ids, WorkOrderDistributeWayEnum distributeWay) { LoginUser loginUser = SecurityUtils.getLoginUser(); workOrderDistributeRecordMapper.insertBatch( ids.stream() .map(id -> new WorkOrderDistributeRecord(id, loginUser.getUserId(), distributeWay)) .toList() ); } /** * 根据id查找 * @param id * @return */ @Override public Result detail(String id) { WorkOrder entity = baseMapper.selectById(id); Assert.notNull(entity, "记录不存在"); WorkOrderVO vo = WorkOrderVO.getVoByEntity(entity, null); return Result.ok().data(vo); } /** * 列表 * @return */ @Override public Result all() { List entities = baseMapper.selectList(null); List vos = entities.stream() .map( entity -> WorkOrderVO.getVoByEntity(entity, null) ) .collect(Collectors.toList()); return Result.ok().data(vos); } }