AccidentPoolBizService.java 6.53 KB
package cn.fw.valhalla.service.bus.cust;

import cn.fw.common.cache.locker.DistributedLocker;
import cn.fw.common.web.auth.LoginAuthBean;
import cn.fw.valhalla.common.constant.RoleCode;
import cn.fw.valhalla.common.utils.DateUtil;
import cn.fw.valhalla.domain.db.customer.AccidentPool;
import cn.fw.valhalla.domain.db.follow.FollowTask;
import cn.fw.valhalla.domain.dto.AccidentPoolDTO;
import cn.fw.valhalla.domain.enums.FollowTypeEnum;
import cn.fw.valhalla.domain.enums.SettingTypeEnum;
import cn.fw.valhalla.domain.enums.SettingUnitEnum;
import cn.fw.valhalla.domain.enums.TaskStateEnum;
import cn.fw.valhalla.rpc.erp.UserService;
import cn.fw.valhalla.rpc.erp.dto.PostUserDTO;
import cn.fw.valhalla.rpc.oop.OopService;
import cn.fw.valhalla.rpc.oop.dto.ShopDTO;
import cn.fw.valhalla.service.bus.setting.SettingBizService;
import cn.fw.valhalla.service.data.AccidentPoolService;
import cn.fw.valhalla.service.data.FollowTaskService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static cn.fw.common.businessvalidator.Validator.BV;
import static cn.fw.valhalla.common.utils.DateUtil.getNowExpiredDay;
import static cn.fw.valhalla.service.bus.follow.strategy.AbstractFollowStrategy.getCalendarType;

/**
 * @author : kurisu
 * @className : AccidentPoolBizService
 * @description : 事故池
 * @date: 2020-08-15 15:20
 */
@Service
@Slf4j
public class AccidentPoolBizService {
    private final DistributedLocker distributedLocker;
    private final AccidentPoolService accidentPoolService;
    private final FollowTaskService followTaskService;
    private final UserService userService;
    private final OopService oopService;
    private final SettingBizService settingBizService;


    @Value("${spring.cache.custom.global-prefix}:AccidentPool")
    @Getter
    private String keyPrefix;

    @Autowired
    public AccidentPoolBizService(final DistributedLocker distributedLocker,
                                  final AccidentPoolService accidentPoolService,
                                  final FollowTaskService followTaskService,
                                  final UserService userService,
                                  final OopService oopService,
                                  final SettingBizService settingBizService) {
        this.distributedLocker = distributedLocker;
        this.accidentPoolService = accidentPoolService;
        this.followTaskService = followTaskService;
        this.userService = userService;
        this.oopService = oopService;
        this.settingBizService = settingBizService;
    }

    @Transactional(rollbackFor = Exception.class)
    public void add2Pool(LoginAuthBean currentUser, AccidentPoolDTO poolDTO) {
        final String lockKey = getLockKey(poolDTO.getPlateNo(), currentUser.getGroupId());
        Pair<Boolean, RLock> pair = distributedLocker.tryLock(lockKey, TimeUnit.SECONDS, 0, 15);
        BV.isTrue(Boolean.TRUE.equals(pair.getKey()), () -> "请勿重复提交");
        try {
            BV.isTrue(Boolean.TRUE.equals(pair.getKey()), () -> "请勿重复提交");
            boolean repetition = isRepetition(currentUser.getGroupId(), poolDTO.getPlateNo());
            BV.isFalse(repetition, () -> "该记录已存在,请勿重复添加");
            AccidentPool pool = conversion2db(poolDTO, currentUser);
            pool.setShopId(poolDTO.getShopId());
            pool.setShopName(poolDTO.getName());
            accidentPoolService.save(pool);
            createAccPoolTask(pool);
        } catch (Exception e) {
            distributedLocker.unlock(lockKey);
            throw e;
        }
    }

    private String getLockKey(String plateNo, Long groupId) {
        BV.isNotBlank(plateNo, "plateNo cannot be null");
        BV.notNull(groupId, "groupId cannot be null");

        return String.format("%s:lock:%s:%s", getKeyPrefix(), groupId, plateNo);
    }


    private void createAccPoolTask(final AccidentPool pool) {
        if (Objects.isNull(pool)) {
            return;
        }
        final FollowTask followTask = new FollowTask();
        followTask.setCustomerId(pool.getId());
        followTask.setType(FollowTypeEnum.AC);
        followTask.setOriginTime(pool.getCreateTime());
        followTask.setState(TaskStateEnum.WAITING);
        followTask.setBeginTime(DateUtil.localDateTime2Date(LocalDateTime.now()));
        followTask.setDeadline(DateUtil.getCurrentDayEndTime());
        followTask.setFinished(Boolean.FALSE);
        followTask.setGroupId(pool.getGroupId());
        followTask.setOriginShop(pool.getShopId());
        ShopDTO shop = oopService.shop(pool.getShopId());
        BV.notNull(shop, () -> "门店信息有误");
        List<PostUserDTO> userByRole = userService.getUserByRole(pool.getShopId(), RoleCode.SGCGJ);
        BV.isFalse(CollectionUtils.isEmpty(userByRole), () -> "该门店没有事故车跟进人员");
        Collections.shuffle(userByRole);
        Long userId = userByRole.get(0).getUserId();
        followTask.setOriginUser(userId);
        followTask.setFollowUser(userId);
        followTask.setFollowShop(shop.getId());
        followTask.setDealerId(shop.getDealerId());
        followTask.setCreateTime(DateUtil.localDateTime2Date(LocalDateTime.now()));
        followTaskService.save(followTask);
    }

    private AccidentPool conversion2db(AccidentPoolDTO dto, LoginAuthBean currentUser) {
        AccidentPool pool = new AccidentPool();
        BeanUtils.copyProperties(dto, pool);
        pool.setCreateTime(new Date());
        pool.setUpdateTime(new Date());
        pool.setGroupId(currentUser.getGroupId());
        return pool;
    }

    private boolean isRepetition(Long groupId, String plateNo) {
        int count = accidentPoolService.count(Wrappers.<AccidentPool>lambdaQuery()
                .eq(AccidentPool::getPlateNo, plateNo)
                .eq(AccidentPool::getGroupId, groupId)
                .ge(AccidentPool::getCreateTime, DateUtil.startDate(getNowExpiredDay(-1)))
        );
        return count > 0;
    }
}