SalaryPoolFundShopTask.java 6.9 KB
package cn.fw.morax.server.task;

import cn.fw.common.cache.locker.DistributedLocker;
import cn.fw.ehr.sdk.api.enums.StaffShopTypeEnum;
import cn.fw.morax.common.constant.TimeTaskConstant;
import cn.fw.morax.common.utils.PublicUtil;
import cn.fw.morax.domain.db.salary.SalaryPool;
import cn.fw.morax.rpc.ehr.EhrRpcService;
import cn.fw.morax.rpc.ehr.dto.StaffBaseInfoDTO;
import cn.fw.morax.rpc.ehr.dto.StaffShopInfoDTO;
import cn.fw.morax.service.data.salary.SalaryPoolService;
import com.google.common.base.Functions;
import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.YearMonth;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;

/**
 * @author : jiangchao
 * @className : SalaryGroupTask
 * @description : 薪酬池写入社保公积金门店
 * @date : 2022-04-07 15:29
 */
@Component
@Slf4j
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "task", name = "switch", havingValue = "on")
public class SalaryPoolFundShopTask {

    private final DistributedLocker distributedLocker;
    private final SalaryPoolService salaryPoolService;
    private final EhrRpcService ehrRpcService;

    @Value("${spring.cache.custom.global-prefix}:salary:pool:fund")
    @Getter
    private String salaryPoolFundKey;

    /**
     * 每月第一天凌晨执行,薪酬池写入社保公积金门店
     * 1. 处理员工有多条绩效池的数据
     * 2. 处理员工只有一条绩效池的数据
     */
    @Scheduled(cron = TimeTaskConstant.SALARY_POOL_FUND_SHOP)
    @Transactional(rollbackFor = Exception.class)
    public void dealSalaryPoolFundShop() {
        Lock lock = distributedLocker.lock(getSalaryPoolFundKey());
        if (((RLock) lock).isLocked()) {
            try {
                log.info("定时任务【酬池写入社保公积金门店】开始执行");
                //查找待生效数据
                YearMonth yearMonth = YearMonth.now();
                List<SalaryPool> updatePools = Lists.newArrayListWithCapacity(1000);
                this.dealStaffMultiPools(updatePools, yearMonth);
                this.dealStaffPools(updatePools, yearMonth);
                salaryPoolService.updateBatchById(updatePools);
                log.info("薪酬池写入社保公积金门店定时任务结束");
            } catch (Exception e){
                log.error(e.getMessage(), e);
            } finally {
                lock.unlock();
            }
        }
    }

    /**
     * 处理一个员工多条绩效池的数据
     *
     * @param updatePools
     * @param yearMonth
     */
    @Transactional(rollbackFor = Exception.class)
    public void dealStaffMultiPools(List<SalaryPool> updatePools, YearMonth yearMonth) {
        List<SalaryPool> staffMultiPools = salaryPoolService.queryStaffMultiPools(yearMonth);
        if (PublicUtil.isEmpty(staffMultiPools)) {
            return;
        }
        Set<Long> staffMultiIds = staffMultiPools.stream().map(SalaryPool::getUserId).collect(Collectors.toSet());
        List<Long> staffIds = new ArrayList<>(staffMultiIds);
        Map<Long, List<SalaryPool>> staffMultiPoolMap = staffMultiPools.stream().collect(Collectors.groupingBy(SalaryPool::getUserId));
        List<StaffBaseInfoDTO> multiStaffBaseInfoDTOS = ehrRpcService.queryStaffBaseInfo(staffIds);
        Integer fundShopType = StaffShopTypeEnum.FUND_SHOP.getValue();

        for (StaffBaseInfoDTO staff : multiStaffBaseInfoDTOS) {
            List<SalaryPool> pools = staffMultiPoolMap.get(staff.getId());
            if (PublicUtil.isEmpty(pools)) {
                continue;
            }
            List<StaffShopInfoDTO> staffShops = staff.getStaffShopList();
            StaffShopInfoDTO fundShop = staffShops.stream()
                    .filter(shop -> fundShopType.equals(shop.getType()))
                    .findFirst()
                    .orElse(null);
            if (PublicUtil.isEmpty(fundShop)) {
                continue;
            }
            for (SalaryPool pool : pools) {
                pool.setFundShopId(fundShop.getShopId());
                pool.setFundShopName(fundShop.getShopName());
                updatePools.add(pool);
            }
        }
    }

    /**
     * 处理一个员工一条绩效池的数据
     *
     * @param updatePools
     * @param yearMonth
     */
    @Transactional(rollbackFor = Exception.class)
    public void dealStaffPools(List<SalaryPool> updatePools, YearMonth yearMonth) {
        List<SalaryPool> staffPools = salaryPoolService.queryStaffPools(yearMonth);
        if (PublicUtil.isEmpty(staffPools)) {
            return;
        }
        List<Long> staffIds = staffPools.stream().map(SalaryPool::getUserId).collect(Collectors.toList());
        Map<Long, SalaryPool> staffPoolMap = staffPools.stream()
                .collect(Collectors.toMap(SalaryPool::getUserId, Functions.identity(), (v1, v2) -> {
                    log.error("出现员工多条绩效池 " + v1.getUserId());
                    return v2;
                }));
        List<StaffBaseInfoDTO> multiStaffBaseInfoDTOS = ehrRpcService.queryStaffBaseInfo(staffIds);
        Integer fundShopType = StaffShopTypeEnum.FUND_SHOP.getValue();

        for (StaffBaseInfoDTO staff : multiStaffBaseInfoDTOS) {
            SalaryPool pool = staffPoolMap.get(staff.getId());
            if (PublicUtil.isEmpty(pool)) {
                continue;
            }
            List<StaffShopInfoDTO> staffShops = staff.getStaffShopList();
            StaffShopInfoDTO fundShop = staffShops.stream()
                    .filter(shop -> fundShopType.equals(shop.getType()))
                    .findFirst()
                    .orElse(null);
            if (PublicUtil.isEmpty(fundShop)) {
                continue;
            }
            pool.setFundShopId(fundShop.getShopId());
            pool.setFundShopName(fundShop.getShopName());
            updatePools.add(pool);
        }
    }

    /**
     * 截取list
     *
     * @param list
     * @param skip
     * @param pageSize
     * @param <T>
     * @return
     */
    public static <T> List<T> getSubListPage(List<T> list, int skip, int pageSize) {
        if (list == null || list.isEmpty()) {
            return null;
        }
        int startIndex = skip;
        int endIndex = skip + pageSize;
        if (startIndex > endIndex || startIndex > list.size()) {
            return null;
        }
        if (endIndex > list.size()) {
            endIndex = list.size();
        }
        return list.subList(startIndex, endIndex);
    }

}