xiangpei
2024-08-19 70dfa087a9f61ecc33f3b5bc618202c2023e38f3
ycl-server/src/main/java/com/ycl/platform/service/impl/WorkOrderServiceImpl.java
@@ -8,23 +8,31 @@
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.query.*;
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.domain.vo.screen.ScreenWorkOrderVO;
import com.ycl.platform.domain.vo.screen.WorkOrderRegionVO;
import com.ycl.platform.domain.vo.screen.WorkOrderTotalVO;
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.platform.service.YwPointService;
import com.ycl.system.Result;
import com.ycl.system.domain.SysConfig;
import com.ycl.system.mapper.SysConfigMapper;
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 enumeration.general.*;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ArrayUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -35,10 +43,7 @@
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.*;
import java.util.stream.Collectors;
/**
@@ -47,23 +52,122 @@
 * @author xp
 * @since 2024-03-05
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WorkOrderServiceImpl extends ServiceImpl<WorkOrderMapper, WorkOrder> implements WorkOrderService {
    private final WorkOrderMapper workOrderMapper;
    private final YwUnitMapper ywUnitMapper;
    private final YwPeopleMapper ywPeopleMapper;
    private final YwPointService ywPointService;
    private final WorkOrderAuditingRecordMapper workOrderAuditingRecordMapper;
    private final WorkOrderAuditingRecordService workOrderAuditingRecordService;
    private final WorkOrderYwConditionRecordMapper workOrderYwConditionRecordMapper;
    private final NotifyService notifyService;
    private final WorkOrderDistributeRecordMapper workOrderDistributeRecordMapper;
    private final TMonitorMapper monitorMapper;
    private final SysConfigMapper configMapper;
    private final String DISTRIBUTE_LOCK_KEY = "distributeLock";
    private final static String IMPORTANT = "important";
    @Autowired
    private RedisCache redisCache;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean innerAddWorkOrder(List<WorkOrder> workOrderList) {
        int total = workOrderList.size();
        workOrderList.stream().filter(item -> {
            return StringUtils.hasText(item.getSerialNumber()) && Objects.nonNull(item.getStatus()) && StringUtils.hasText(item.getErrorType());
        });
        if (CollectionUtils.isEmpty(workOrderList)) {
            return Boolean.TRUE;
        }
        List<String> serialNumberList = workOrderList.stream().map(WorkOrder::getSerialNumber).collect(Collectors.toList());
        // 查出数据库中国标码对应的未完成的工单
        List<WorkOrder> inDatabaseWorkOrderList = new LambdaQueryChainWrapper<>(baseMapper)
                .select(WorkOrder::getId, WorkOrder::getSerialNumber, WorkOrder::getStatus, WorkOrder::getErrorType)
                .in(WorkOrder::getSerialNumber, serialNumberList)
                .ne(WorkOrder::getStatus, WorkOrderStatusEnum.AUDITING_SUCCESS)
                .list();
        Map<String, WorkOrder> mapping = inDatabaseWorkOrderList.stream().collect((Collectors.toMap(WorkOrder::getSerialNumber, workOrder -> workOrder)));
        List<WorkOrder> waitAddList = new ArrayList<>(48);
        Integer updateNum = 0;
        // TODO 查询是否报备过,更新故障类型
        for (WorkOrder workOrder : workOrderList) {
            WorkOrder databaseWorkOrder = mapping.get(workOrder.getSerialNumber());
            if (Objects.nonNull(databaseWorkOrder)) {
                String errorType = databaseWorkOrder.getErrorType();
                if (workOrder.getErrorType().equals(errorType)) {
                    // 如果,国标码、故障类型都一样,则跳过不处理
                    continue;
                } else {
                    // 错误类型不一样,就更新错误类型,并且重置工单状态为待处理
                    errorType = errorType + "," + workOrder.getErrorType();
                    databaseWorkOrder.setErrorType(errorType);
                    databaseWorkOrder.setStatus(WorkOrderStatusEnum.DISTRIBUTED);
                    Date now = new Date();
                    databaseWorkOrder.setUpdateTime(now);
                    baseMapper.updateById(databaseWorkOrder);
                    updateNum++;
                    // 同时新增一个运维处理信息,表明此工单被调整 TODO
                }
            } else {
                workOrder.setCreateTime(new Date());
                workOrder.setUpdateTime(new Date());
                waitAddList.add(workOrder);
            }
        }
        if (CollectionUtils.isEmpty(waitAddList)) {
            return Boolean.TRUE;
        }
        List<String> willAddSerialNumber = waitAddList.stream().map(WorkOrder::getSerialNumber).collect(Collectors.toList());
        List<YwPoint> pointList = new LambdaQueryChainWrapper<>(ywPointService.getBaseMapper())
                .select(YwPoint::getUnitId, YwPoint::getSerialNumber, YwPoint::getImportantTag, YwPoint::getImportantTag, YwPoint::getProvinceTag, YwPoint::getImportantCommandImageTag)
                .in(YwPoint::getSerialNumber, willAddSerialNumber)
                .list();
        Map<String, YwPoint> pointMapping = pointList.stream().collect(Collectors.toMap(YwPoint::getSerialNumber, point -> point));
        // 查出重点点位、普通点位的处理时间
        SysConfig important = configMapper.checkConfigKeyUnique("important.wordkorder.time");
        SysConfig normal = configMapper.checkConfigKeyUnique("normal.wordkorder.alarm.time");
        // 如果即将生成工单,但是设备国标码查不到点位,则不添加?
        List<WorkOrder> notAddList = new ArrayList<>();
        for (WorkOrder workOrder : waitAddList) {
            YwPoint point = pointMapping.get(workOrder.getSerialNumber());
            if (Objects.isNull(point)) {
                notAddList.add(workOrder);
                continue;
            }
            workOrder.setWorkOrderNo(IdUtils.timeAddRandomNO(5));
            workOrder.setUnitId(Math.toIntExact(point.getUnitId()));
            if (point.getImportantTag() || point.getImportantCommandImageTag()) {
                workOrder.setProcessingPeriod(Integer.valueOf(important.getConfigValue()));
            } else {
                workOrder.setProcessingPeriod(Integer.valueOf(normal.getConfigValue()));
            }
        }
        waitAddList.removeAll(notAddList);
        if (CollectionUtils.isEmpty(waitAddList)) {
            return Boolean.TRUE;
        }
        this.saveBatch(waitAddList);
        // 如果是直接下发,添加下发记录
        if (WorkOrderStatusEnum.DISTRIBUTED.equals(waitAddList.get(0).getStatus())) {
            List<WorkOrderDistributeRecord> distributedRecordList = waitAddList.stream().map(item -> {
                WorkOrderDistributeRecord workOrderDistributeRecord = new WorkOrderDistributeRecord();
                workOrderDistributeRecord.setWorkOrderId(item.getId());
                workOrderDistributeRecord.setDistributeWay(WorkOrderDistributeWayEnum.DIRECT_DISTRIBUTE);
                workOrderDistributeRecord.setUserId(1L);
                Date now = new Date();
                workOrderDistributeRecord.setCreateTime(now);
                workOrderDistributeRecord.setUpdateTime(now);
                return workOrderDistributeRecord;
            }).collect(Collectors.toList());
            workOrderDistributeRecordMapper.insertBatch(distributedRecordList);
        }
        log.info("传入工单总数: {},实际添加工单数:{}, 实际修改工单数:{}", total, waitAddList.size(), updateNum);
        return Boolean.TRUE;
    }
    /**
     * 添加
@@ -73,10 +177,12 @@
    @Override
    public Result add(WorkOrderForm form) {
        WorkOrder entity = WorkOrderForm.getEntityByForm(form, null);
        entity.setWorkOrderNo(DateUtils.dateTimeNow());
        entity.setWorkOrderNo(IdUtils.timeAddRandomNO(5));
        entity.setCreateTime(DateUtils.getNowDate());
        entity.setStatus(WorkOrderStatusEnum.WAIT_DISTRIBUTE);
        entity.setDeleted("0");
        Date now = new Date();
        entity.setCreateTime(now);
        entity.setUpdateTime(now);
        if(baseMapper.insert(entity) > 0) {
            return Result.ok("添加成功");
        }
@@ -92,10 +198,11 @@
    public Result update(WorkOrderForm form) {
        WorkOrder entity = baseMapper.selectById(form.getId());
        // 为空抛IllegalArgumentException,做全局异常处理
        Assert.notNull(entity, "记录不存在");
        BeanUtils.copyProperties(form, entity);
        Date now = new Date();
        entity.setUpdateTime(now);
        if (baseMapper.updateById(entity) > 0) {
            return Result.ok("修改成功");
        }
@@ -123,6 +230,10 @@
                UrgentLevelEnum.WARNING,
                workOrder.getWorkOrderNo());
        notifyService.save(notify);
        // 同步点位状态
        if (form.getAuditingResult() == WorkOrderStatusEnum.AUDITING_SUCCESS) {
            ywPointService.updateRecovery(Arrays.asList(workOrder.getSerialNumber()), 0);
        }
        return Result.ok("操作成功");
    }
@@ -132,7 +243,7 @@
        // 根据故障类型获取列表
        List<WorkOrder> list = new LambdaQueryChainWrapper<>(baseMapper)
                .in(WorkOrder::getStatus, WorkOrderStatusEnum.YW_HANDLE.getValue())
                .eq(WorkOrder::getErrorType, form.getErrorType())
                .in(WorkOrder::getErrorType, form.getErrorTypes())
                .select(WorkOrder::getId, WorkOrder::getUnitId, WorkOrder::getWorkOrderNo)
                .list();
        if (list.isEmpty()) {
@@ -191,21 +302,9 @@
    }
    @Override
    public Result selectYwConditionByYwId(String id) {
        return Result.ok().data(
                new LambdaQueryChainWrapper<>(workOrderYwConditionRecordMapper)
                        .eq(WorkOrderYwConditionRecord::getWorkOrderId, id)
                        .orderByAsc(WorkOrderYwConditionRecord::getCreateTime)
                        .list());
    }
    @Override
    public Result selectYwConditionListByYwId(String id) {
        return Result.ok().data(
                new LambdaQueryChainWrapper<>(workOrderYwConditionRecordMapper)
                        .eq(WorkOrderYwConditionRecord::getWorkOrderId, id)
                        .orderByAsc(WorkOrderYwConditionRecord::getCreateTime)
                        .list());
    public Result selectYwConditionByYwId(Integer id) {
        List<WorkOrderYwConditionRecordVO> ywConditionList = workOrderYwConditionRecordMapper.selectYwConditionByYwId(id);
        return Result.ok().data(ywConditionList);
    }
    @Override
@@ -273,53 +372,49 @@
    }
    @Override
    @Transactional
    public Result distributeFast(DistributeWorkOrderVO data) {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
        data.setEnd(now);
        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<Integer> ids = new LambdaQueryChainWrapper<>(baseMapper)
        List<WorkOrder> list = new LambdaQueryChainWrapper<>(baseMapper)
                .select(WorkOrder::getSerialNumber, WorkOrder::getSerialNumber)
                .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();
                .list();
        List<Integer> ids = list.stream().map(WorkOrder::getId).toList();
        List<String> serialNumberList = list.stream().map(WorkOrder::getSerialNumber).toList();
        if (ids.isEmpty()) {
            return Result.error("没有符合条件的工单");
        }
        if (!getDistributeLock()) {
            return Result.error("此刻有人下发中,为避免冲突,请稍后重试");
        }
        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);
            // 同步点位状态
            ywPointService.updateRecovery(serialNumberList, 1);
            return Result.ok("成功下发" + ids.size() + "条工单");
        } catch (Exception e) {
            return Result.error("操作失败");
@@ -329,11 +424,10 @@
    }
    @Override
    @Transactional
    public Result selectedIdsDistribute(DistributeWorkOrderQuery query) {
        WorkOrderDistributeWayEnum distributeWayEnum = WorkOrderDistributeWayEnum.SELECTED_DISTRIBUTE;
        if (!getDistributeLock()) {
            return Result.error("此刻有人下发中,为避免冲突,请稍后重试");
        }
        if (!getDistributeLock()) { return Result.error("此刻有人下发中,为避免冲突,请稍后重试"); }
        try {
            if (query.getIds().isEmpty()) {
                query.setIds(new LambdaQueryChainWrapper<>(baseMapper)
@@ -346,14 +440,15 @@
                        .collect(Collectors.toList()));
                distributeWayEnum = WorkOrderDistributeWayEnum.ALL_DISTRIBUTE;
            }
            if (query.getIds().isEmpty()) {
                return Result.error("没有工单待下发");
            }
            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);
            // 同步点位状态
            List<String> serialNumberList = new LambdaQueryChainWrapper<>(baseMapper).select(WorkOrder::getSerialNumber).in(WorkOrder::getId, query.getIds()).list().stream().map(WorkOrder::getSerialNumber).toList();
            ywPointService.updateRecovery(serialNumberList, 1);
            return Result.ok("成功下发" + query.getIds().size() + "条工单");
        } catch (Exception e) {
            return Result.error("操作失败");
@@ -423,4 +518,43 @@
                .collect(Collectors.toList());
        return Result.ok().data(vos);
    }
    @Override
    public Result screenWorkOrder(ScreenQuery query) {
        ScreenWorkOrderVO screen = baseMapper.screenWorkOrder(query);
        return Result.ok().data(screen);
    }
    @Override
    public Map<String, Object> home(HomeQuery monitorQuery) {
        Map<String, Object> dataMap = new HashMap<>();
        Map<String, Object> data1 = new HashMap<>();
        Map<String, Object> data2 = new HashMap<>();
        Map<String, Object> data3 = new HashMap<>();
        List<Map<String, Object>> home = baseMapper.home(monitorQuery);
        if (ObjectUtils.isNotEmpty(home)) {
            for (Map<String, Object> map : home) {
                if (Objects.nonNull(map.get("dateType")) && StringUtils.hasText(map.get("dateType").toString())) {
                    data1.put(map.get("dateType").toString(), map.get("num1"));
                    data2.put(map.get("dateType").toString(), map.get("num2"));
                    data3.put(map.get("dateType").toString(), map.get("num3"));
                }
            }
            dataMap.put("name", home.get(0).get("name"));
        }
        dataMap.put("complete", data1);
        dataMap.put("waiting", data2);
        dataMap.put("pending", data3);
        return dataMap;
    }
    @Override
    public WorkOrderTotalVO workOrderTotal(DashboardQuery dashboardQuery) {
        return baseMapper.workOrderTotal(dashboardQuery);
    }
    @Override
    public List<WorkOrderRegionVO> workOrderRegion(DashboardQuery dashboardQuery) {
        return baseMapper.workOrderRegion(dashboardQuery);
    }
}