SalaryGroupTask.java
6.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package cn.fw.morax.server.task;
import cn.fw.common.cache.locker.DistributedLocker;
import cn.fw.morax.common.constant.TimeTaskConstant;
import cn.fw.morax.common.utils.DateUtil;
import cn.fw.morax.common.utils.PublicUtil;
import cn.fw.morax.domain.db.salary.SalaryGroup;
import cn.fw.morax.domain.dto.query.SalaryGroupRepeatQueryDTO;
import cn.fw.morax.domain.enums.SettingStatusEnum;
import cn.fw.morax.service.biz.salary.SalaryGroupDataService;
import cn.fw.morax.service.biz.salary.SalaryGroupUserBizService;
import cn.fw.morax.service.data.salary.SalaryGroupService;
import cn.hutool.core.date.StopWatch;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
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.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
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 SalaryGroupTask {
private final SalaryGroupUserBizService salaryGroupUserBizService;
private final SalaryGroupDataService salaryGroupDataService;
private final SalaryGroupService salaryGroupService;
private final DistributedLocker distributedLocker;
@Value("${spring.cache.custom.global-prefix}:salary:group")
@Getter
private String salaryGroupKey;
/**
* 每个月1号凌晨3点执行
* 1. 将待生效数据改为生效中
* 2. 将之前的配置设置为失效
* 3. 处理重复数据,合并、拆分门店的绩效组配置需要把其他的重复配置失效
*/
@Scheduled(cron = TimeTaskConstant.SALARY_GROUP)
@Transactional(rollbackFor = Exception.class)
public void processCurMonthEffectSalaryGroup() {
Lock lock = distributedLocker.lock(getSalaryGroupKey());
if (((RLock) lock).isLocked()) {
try {
log.info("定时任务【每月薪酬组配置状态改变】开始执行");
//查找待生效数据
LocalDate currentTime = LocalDate.now();
List<SalaryGroup> beEffectiveSalaryGroups = salaryGroupService.list(Wrappers.<SalaryGroup>lambdaQuery()
.eq(SalaryGroup::getStatus, SettingStatusEnum.BE_EFFECTIVE)
.eq(SalaryGroup::getBeginTime, currentTime)
);
if (PublicUtil.isEmpty(beEffectiveSalaryGroups)) {
log.info("绩效组定时器:暂无即将生效的绩效组配置");
return;
}
//之前配置都设置为无效(之前配置一定被使用过)
List<Long> preIds = beEffectiveSalaryGroups.stream()
.filter(kpiGroup -> PublicUtil.isNotEmpty(kpiGroup.getPreId()))
.map(SalaryGroup::getPreId).collect(Collectors.toList());
salaryGroupDataService.modifyStatusByIds(preIds, SettingStatusEnum.INEFFECTIVE);
//以岗位、门店的维度,出现重复的配置,将创建时间最早的设置为失效
this.processEffectiveRepeatGroup(beEffectiveSalaryGroups);
//生效的配置
salaryGroupDataService.modifyStatusBySalaryGroups(beEffectiveSalaryGroups, SettingStatusEnum.EFFECTIVE);
} catch (Exception e){
log.error(e.getMessage(), e);
} finally {
lock.unlock();
}
}
}
/**
* 处理当月之前的重复生效数据
*
* @param beEffectiveSalaryGroups
*/
@Transactional(rollbackFor = Exception.class)
public void processEffectiveRepeatGroup(List<SalaryGroup> beEffectiveSalaryGroups) {
Map<Long, List<SalaryGroup>> groupKpiMap = beEffectiveSalaryGroups.stream().collect(Collectors.groupingBy(SalaryGroup::getGroupId));
Long groupId = null;
Long postId = null;
List<SalaryGroup> kpis = null;
Set<Long> shopIds = null;
List<SalaryGroup> beEffectiveKpis = null;
Map<Long, List<SalaryGroup>> postKpiMap = null;
for (Map.Entry<Long, List<SalaryGroup>> entry : groupKpiMap.entrySet()) {
groupId = entry.getKey();
beEffectiveKpis = entry.getValue();
postKpiMap = beEffectiveKpis.stream().collect(Collectors.groupingBy(SalaryGroup::getPostId));
for (Map.Entry<Long, List<SalaryGroup>> postKpi : postKpiMap.entrySet()) {
postId = postKpi.getKey();
kpis = postKpi.getValue();
shopIds = new HashSet<>();
for (SalaryGroup salaryGroup : kpis) {
shopIds.addAll(salaryGroup.getShopIds());
}
SalaryGroupRepeatQueryDTO repeatQueryDTO = SalaryGroupRepeatQueryDTO.builder()
.shopIds(new ArrayList<>(shopIds))
.status(SettingStatusEnum.EFFECTIVE)
.groupId(groupId)
.postId(postId)
.build();
List<SalaryGroup> effectSalaryGroups = salaryGroupService.queryRepeatSalaryGroup(repeatQueryDTO);
salaryGroupDataService.modifyStatusBySalaryGroups(effectSalaryGroups, SettingStatusEnum.INEFFECTIVE);
}
}
}
/**
* 生成昨日薪酬组人员
*/
@Scheduled(cron = TimeTaskConstant.SALARY_GROUP_USER)
public void asyncSalaryGroupUser() {
final String lockKey = ":asyncSalaryGroupUser";
Lock lock = distributedLocker.lock(lockKey);
if (((RLock) lock).isLocked()) {
log.info("薪酬组人员更新定时任务");
StopWatch stopWatch = new StopWatch();
stopWatch.start("薪酬组人员更新定时任务");
LocalDateTime queryTime = LocalDateTime.now().minusDays(1);
List<SalaryGroup> list = salaryGroupService.getAllEffectGroups(DateUtil.localDateTime2Date(queryTime));
for (SalaryGroup salaryGroup : list) {
salaryGroupUserBizService.asyncSalaryGroupUser(salaryGroup, queryTime.toLocalDate());
}
stopWatch.stop();
log.info(stopWatch.prettyPrint(TimeUnit.SECONDS));
lock.unlock();
}
}
}