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 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 updatePools, YearMonth yearMonth) { List staffMultiPools = salaryPoolService.queryStaffMultiPools(yearMonth); if (PublicUtil.isEmpty(staffMultiPools)) { return; } Set staffMultiIds = staffMultiPools.stream().map(SalaryPool::getUserId).collect(Collectors.toSet()); List staffIds = new ArrayList<>(staffMultiIds); Map> staffMultiPoolMap = staffMultiPools.stream().collect(Collectors.groupingBy(SalaryPool::getUserId)); List multiStaffBaseInfoDTOS = ehrRpcService.queryStaffBaseInfo(staffIds); Integer fundShopType = StaffShopTypeEnum.FUND_SHOP.getValue(); for (StaffBaseInfoDTO staff : multiStaffBaseInfoDTOS) { List pools = staffMultiPoolMap.get(staff.getId()); if (PublicUtil.isEmpty(pools)) { continue; } List 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 updatePools, YearMonth yearMonth) { List staffPools = salaryPoolService.queryStaffPools(yearMonth); if (PublicUtil.isEmpty(staffPools)) { return; } List staffIds = staffPools.stream().map(SalaryPool::getUserId).collect(Collectors.toList()); Map staffPoolMap = staffPools.stream() .collect(Collectors.toMap(SalaryPool::getUserId, Functions.identity(), (v1, v2) -> { log.error("出现员工多条绩效池 " + v1.getUserId()); return v2; })); List 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 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 * @return */ public static List getSubListPage(List 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); } }