BigViewServiceV1Impl.java 9.23 KB
package com.ruoyi.service.impl;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.SignStatusEnum;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.domain.DriverScheduling;
import com.ruoyi.driver.domain.Driver;
import com.ruoyi.in.domain.SignIn;
import com.ruoyi.in.domain.SignInV1;
import com.ruoyi.pojo.vo.bigViewVo.FleetInfoVo;
import com.ruoyi.pojo.vo.bigViewVo.FleetState;
import com.ruoyi.pojo.vo.bigViewVo.LineInfo;
import com.ruoyi.service.BigViewServiceV1;
import com.ruoyi.template.domain.FleetLineTemplate;
import com.ruoyi.template.service.IFleetLineTemplateService;
import com.ruoyi.utils.ConstDateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.ruoyi.common.ConstSignInConstSignInProperties.SIGN_IN_ERROR_COUNT;
import static com.ruoyi.common.ErrorTypeProperties.SIGN_IN_ERROR;
import static com.ruoyi.common.redispre.GlobalRedisPreName.REDIS_SIGN_IN_DRIVER_ALCOHOL_OVERFLOW;

/**
 * @author liujun
 * @date 2024年09月25日 14:38
 */
@Slf4j
@Service
@EnableAsync
public class BigViewServiceV1Impl implements BigViewServiceV1 {
    @Autowired
    private IFleetLineTemplateService fleetLineTemplateService;
    @Autowired
    private RedisCache redisCache;

    private static final String DRIVER_SIGN_KEY = "sign:driver:{0}:{1}";

    private static final String LINE_SIGN_KEY = "sign:line:{0}:{1}";

    private static final String LOCK_LINE_SIGN_KEY = "sign:lock:{0}:{1}";

    private static final String SIGN_REPORT_LIST = "sign:report:list:{0}";

    @Override
    public void asyncRefreshRedisValue(SignIn signIn, Driver driver, DriverScheduling driverScheduling, String dateStr) throws InterruptedException {
        String key = MessageFormat.format(SIGN_REPORT_LIST, dateStr);

        refreshRedisDriver(signIn, driver);
        refreshRedisLine(signIn, driverScheduling);
    }

    @Override
    public AjaxResult queryBigViewQueryLineInfo(Date date) {
        return null;
    }


    @Override
    public LineInfo.PersonInfoVo refreshRedisDriver(SignIn signIn, Driver driver) {
        LineInfo.PersonInfoVo personInfoVo = new LineInfo.PersonInfoVo();
        personInfoVo.setName(driver.getPersonnelName());

        if (isSignStatusZoneEnum(signIn)) {
            personInfoVo.setSignStatus(SignStatusEnum.SIGN_STATUS_ZONE_ENUM);
        } else if (isSignStatusWineEnum(signIn)) {
            personInfoVo.setSignStatus(SignStatusEnum.SIGN_STATUS_WINE_ENUM);
        } else if (isSignStatusDelayEnum(signIn)) {
            personInfoVo.setSignStatus(SignStatusEnum.SIGN_STATUS_DELAY_ENUM);
        }
        personInfoVo.setPosts(driver.getPosts());

        String dateStr = ConstDateUtil.formatDate(signIn.getCreateTime());

        String key = MessageFormat.format(DRIVER_SIGN_KEY, dateStr, driver.getJobCode());
        redisCache.setCacheObject(key, JSON.toJSONString(personInfoVo), 25, TimeUnit.HOURS);

        return personInfoVo;
    }


    @Override
    public FleetState refreshRedisLine(SignIn signIn, DriverScheduling driverScheduling) throws InterruptedException {
        String dateStr = ConstDateUtil.formatDate(signIn.getCreateTime());
        String key = MessageFormat.format(LINE_SIGN_KEY, dateStr, driverScheduling.getLineName());
        FleetState source = redisCache.getCacheObject(key);

        FleetState fleetState = new FleetState();
        fleetState.setLineName(driverScheduling.getLineName());

        if (isSignStatusWineEnum(signIn)) {
            fleetState.setState(SignStatusEnum.SIGN_STATUS_WINE_ENUM.getStatus());
        } else if (isSignStatusDelayEnum(signIn)) {
            fleetState.setState(SignStatusEnum.SIGN_STATUS_DELAY_ENUM.getStatus());
        } else {
            fleetState.setState(SignStatusEnum.SIGN_STATUS_ZONE_ENUM.getStatus());
        }

        if (Objects.isNull(source) || Objects.isNull(source.getState()) || (fleetState.getState() > source.getState())) {
            boolean flag = true;
            String lockKey = MessageFormat.format(LOCK_LINE_SIGN_KEY, dateStr, driverScheduling.getLineName());
            for (int i = 0; i < 10000; i++) {
                if (redisCache.setNx(lockKey, fleetState, 10L, TimeUnit.SECONDS)) {
                    try {
                        redisCache.setCacheObject(key, JSON.toJSONString(fleetState), 25, TimeUnit.HOURS);
                    } finally {
                        redisCache.deleteObject(lockKey);
                    }

                    flag = false;
                    break;
                }
                log.info("redis的[{}]锁已经被占用,1秒钟后再试", key);
                Thread.sleep(1000);
            }

            if (flag) {
                log.warn("redis的[{}]数据没有刷新成功[{}]", key, fleetState);
            }
        }
        return fleetState;
    }

    @Override
    public AjaxResult getAjaxResultByDriverSignInfo(SignIn signIn) {
        String key = StringUtils.join(REDIS_SIGN_IN_DRIVER_ALCOHOL_OVERFLOW, ConstDateUtil.FAST_YYYY_MM_DD.format(new Date()), ":", signIn.getJobCode());
        // 驾驶员酒精测试连续超标两次则提示换人
        Integer count = redisCache.getCacheObject(key);
        if (Objects.isNull(count) || count.equals(0)) {
            count = 1;
            redisCache.setCacheObject(key, count, 1, TimeUnit.DAYS);
        } else {
            redisCache.setCacheObject(key, ++count, 1, TimeUnit.DAYS);
        }
        if (SIGN_IN_ERROR_COUNT.compareTo(count) <= 0) {
            SignInV1 signInV1 = new SignInV1();
            BeanUtils.copyProperties(signIn, signInV1);
            return AjaxResult.success(SIGN_IN_ERROR + ": " + (StringUtils.isEmpty(signIn.getRemark()) ? "" : signIn.getRemark()) + "酒精测试不通过" + count + "次请更换车辆驾驶员。", signIn);
        }
        return null;
    }


    @Override
    public boolean isEarly(SignIn signIn) {
        return Objects.nonNull(signIn) && signIn.getExType() >= 20 && signIn.getExType() < 30;
    }


    @Override
    public boolean isSignStatusWineEnum(SignIn signIn) {
        return Objects.equals(3, signIn.getExType()) || Objects.equals(23, signIn.getExType()) || Objects.equals(33, signIn.getExType());
    }


    @Override
    public boolean isSignStatusDelayEnum(SignIn signIn) {
        return Objects.nonNull(signIn.getExType()) && signIn.getExType() >= 30 && signIn.getExType() < 40;
    }

    @Override
    public boolean isSignStatusZoneEnum(SignIn signIn) {
        return Objects.equals(0, signIn.getExType());
    }

    private boolean chooseRedisData(String key, SignIn signIn, Driver driver, DriverScheduling driverScheduling) {
        try {
            String jsonStr = redisCache.getCacheObject(key);
            if (StringUtils.isEmpty(jsonStr)) {
                log.info("redis中没有当天的数据[{}],[{}],[{}],[{}]", key, signIn, driver, driverScheduling);
                return false;
            }

            List<FleetInfoVo> fleetInfoVos = JSON.parseArray(jsonStr, FleetInfoVo.class);
            if (CollectionUtils.isEmpty(fleetInfoVos)) {
                log.info("redis中的数据为空[{}],[{}],[{}],[{}]", key, signIn, driver, driverScheduling);
                return false;
            }


        } catch (Exception e) {
            log.error("刷新签到数据异常[{}],[{}],[{}],[{}]", key, signIn, driver, driverScheduling, e);
        }
        return false;
    }

    private List<FleetInfoVo> saveFleetLineTemp() {
        List<FleetLineTemplate> fleetLineTemplates = fleetLineTemplateService.selectFleetLineTemplateList();
        if (CollectionUtils.isEmpty(fleetLineTemplates)) {
            return null;
        }

        Map<String, List<FleetLineTemplate>> groupFleetLingTemp = fleetLineTemplates.stream().collect(Collectors.groupingBy(FleetLineTemplate::getFleetName, Collectors.toList()));

        List<FleetInfoVo> fleetInfoVos = new ArrayList<>();

        groupFleetLingTemp.forEach((key, vals) -> {
            FleetInfoVo fleetInfoVo = new FleetInfoVo();
            fleetInfoVo.setTitle(key);

            if (CollectionUtils.isNotEmpty(vals)) {
                List<FleetInfoVo.FleetInfo> fleetInfoVoFleetInfos = new ArrayList<>();
                List<FleetState> fleetStates = new ArrayList<>();
                vals.stream().forEach(fl -> {
                    FleetInfoVo.FleetInfo fleetInfo = new FleetInfoVo.FleetInfo();
                    fleetInfo.setLineName(fl.getLineName());
                    fleetInfoVoFleetInfos.add(fleetInfo);

                    FleetState fleetState = new FleetState();
                    fleetState.setLineName(fl.getLineName());
                    fleetState.setState(0);

                    fleetStates.add(fleetState);
                });
                fleetInfoVo.setFleetInfos(fleetInfoVoFleetInfos);
                fleetInfoVo.setFleetStates(fleetStates);
            }
            fleetInfoVos.add(fleetInfoVo);
        });

        return fleetInfoVos;
    }
}