|
|
@@ -18,6 +18,7 @@ import com.fs.sop.service.impl.QwSopServiceImpl;
|
|
|
import com.fs.sop.vo.QwSopLogsDoSendListTVO;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.scheduling.annotation.Async;
|
|
|
import org.springframework.scheduling.annotation.Scheduled;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
@@ -108,6 +109,13 @@ public class qwTask {
|
|
|
@Autowired
|
|
|
private SyncQwExternalContactService syncQwExternalContactService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private TenantTaskRunner tenantTaskRunner;
|
|
|
+
|
|
|
+ /** SaaS 模式:为 true 时各定时任务按租户遍历执行;为 false 时保持原单库执行(私有化部署) */
|
|
|
+ @Value("${saas.task.enabled:false}")
|
|
|
+ private boolean saasTaskEnabled;
|
|
|
+
|
|
|
/**
|
|
|
* 定时任务:检查SOP规则时间
|
|
|
* 执行时间:每天凌晨 1:10:00
|
|
|
@@ -115,7 +123,11 @@ public class qwTask {
|
|
|
*/
|
|
|
@Scheduled(cron = "0 10 1 * * ?")
|
|
|
public void qwCheckSopRuleTime() {
|
|
|
- qwSopService.checkSopRuleTime();
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> qwSopService.checkSopRuleTime());
|
|
|
+ } else {
|
|
|
+ qwSopService.checkSopRuleTime();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -125,7 +137,11 @@ public class qwTask {
|
|
|
*/
|
|
|
@Scheduled(cron = "0 0/20 * * * ?")
|
|
|
public void addTag() {
|
|
|
- qwSopTagService.addTag();
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> qwSopTagService.addTag());
|
|
|
+ } else {
|
|
|
+ qwSopTagService.addTag();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -138,13 +154,19 @@ public class qwTask {
|
|
|
@Scheduled(cron = "0 5 * * * ?") // 每小时的第5分钟触发
|
|
|
@Async
|
|
|
public void selectSopUserLogsListByTime() throws Exception {
|
|
|
- // 获取当前时间,精确到小时
|
|
|
LocalDateTime currentTime = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0);
|
|
|
- // 打印日志,确认任务执行时间
|
|
|
log.info("任务实际执行时间: {}", currentTime);
|
|
|
-
|
|
|
- // 调用服务方法处理SOP用户日志
|
|
|
- sopLogsTaskService.selectSopUserLogsListByTime(currentTime, null);
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> {
|
|
|
+ try {
|
|
|
+ sopLogsTaskService.selectSopUserLogsListByTime(currentTime, null);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ sopLogsTaskService.selectSopUserLogsListByTime(currentTime, null);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -156,13 +178,19 @@ public class qwTask {
|
|
|
*/
|
|
|
@Scheduled(cron = "0 5 * * * ?") // 每小时的第5分钟触发
|
|
|
public void wxSop() throws Exception {
|
|
|
- // 获取当前时间,精确到小时
|
|
|
LocalDateTime currentTime = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0);
|
|
|
- // 打印日志,确认任务执行时间
|
|
|
log.info("任务实际执行时间: {}", currentTime);
|
|
|
-
|
|
|
- // 调用服务方法处理微信SOP日志
|
|
|
- sopWxLogsService.wxSopLogsByTime(currentTime);
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> {
|
|
|
+ try {
|
|
|
+ sopWxLogsService.wxSopLogsByTime(currentTime);
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ sopWxLogsService.wxSopLogsByTime(currentTime);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -187,11 +215,13 @@ public class qwTask {
|
|
|
@Scheduled(cron = "0 20 1 * * ?")
|
|
|
public void SendQwApiSopLogTimer(){
|
|
|
log.info("zyp \n【企微官方接口群发开始-单链】");
|
|
|
-// qwSopLogsService.checkQwSopLogs();
|
|
|
LocalDate localDate = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0).toLocalDate();
|
|
|
String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
|
|
-
|
|
|
- qwSopLogsService.createCorpMassSending(date);
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> qwSopLogsService.createCorpMassSending(date));
|
|
|
+ } else {
|
|
|
+ qwSopLogsService.createCorpMassSending(date);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -199,29 +229,30 @@ public class qwTask {
|
|
|
*/
|
|
|
@Scheduled(cron = "0 10 0,1 * * ?")
|
|
|
public void SendQwApiSopLogTimerNew(){
|
|
|
-
|
|
|
log.info("zyp \n【企微官方接口群发开始】");
|
|
|
-// qwSopLogsService.checkQwSopLogs();
|
|
|
-// LocalDate localDate = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0).toLocalDate();
|
|
|
-// String date = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
|
|
-
|
|
|
int currentHour = LocalDateTime.now().getHour();
|
|
|
String taskStartTime = LocalDate.now().atTime(currentHour, 0, 0)
|
|
|
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
|
|
String taskEndTime = LocalDate.now().atTime(currentHour, 59, 59)
|
|
|
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
|
|
-
|
|
|
- qwSopLogsService.createCorpMassSendingByUserLogs(taskStartTime,taskEndTime);
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> qwSopLogsService.createCorpMassSendingByUserLogs(taskStartTime, taskEndTime));
|
|
|
+ } else {
|
|
|
+ qwSopLogsService.createCorpMassSendingByUserLogs(taskStartTime, taskEndTime);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- *
|
|
|
* 执行时间:每天上午 8:00:00
|
|
|
* 功能:获取通过企业微信接口发送的SOP客户群发消息的反馈结果
|
|
|
*/
|
|
|
@Scheduled(cron = "0 0 8 * * ?")
|
|
|
public void GetQwApiSopLogResultTimerNew() {
|
|
|
- qwSopLogsService.qwSopLogsResultNew();
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> qwSopLogsService.qwSopLogsResultNew());
|
|
|
+ } else {
|
|
|
+ qwSopLogsService.qwSopLogsResultNew();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -231,7 +262,11 @@ public class qwTask {
|
|
|
*/
|
|
|
@Scheduled(cron = "0 0/10 * * * ?")
|
|
|
public void sendQwGroupMsgTask() {
|
|
|
- qwGroupMsgService.qwGroupMsgTask();
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> qwGroupMsgService.qwGroupMsgTask());
|
|
|
+ } else {
|
|
|
+ qwGroupMsgService.qwGroupMsgTask();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -240,9 +275,12 @@ public class qwTask {
|
|
|
* 功能:根据SOP规则发送转换消息
|
|
|
*/
|
|
|
@Scheduled(cron = "0 0 8 * * ?")
|
|
|
-// @Scheduled(cron = "0/10 * * * * ?") // 测试用:每10秒执行一次
|
|
|
public void sendQwBySop() {
|
|
|
- sopUserLogsService.sendQwBySop();
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> sopUserLogsService.sendQwBySop());
|
|
|
+ } else {
|
|
|
+ sopUserLogsService.sendQwBySop();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -253,7 +291,11 @@ public class qwTask {
|
|
|
@Scheduled(cron = "0 0/3 * * * ?")
|
|
|
public void qwExternalErrRetryTimer() {
|
|
|
log.info("补偿机制开始");
|
|
|
- errRetryService.qwExternalErrRetryTimer();
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> errRetryService.qwExternalErrRetryTimer());
|
|
|
+ } else {
|
|
|
+ errRetryService.qwExternalErrRetryTimer();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -261,14 +303,24 @@ public class qwTask {
|
|
|
* 执行时间:每小时的第0分钟执行
|
|
|
* 功能:补发已过期但未发送的完课消息
|
|
|
*/
|
|
|
- @Scheduled(cron = "0 0 * * * ?") // 每小时的第0分钟0秒执行
|
|
|
+ @Scheduled(cron = "0 0 * * * ?")
|
|
|
public void updateQwSopLogsByCancel() {
|
|
|
log.info("补发过期完课消息 - 定时任务开始");
|
|
|
- try {
|
|
|
- sopLogsTaskService.updateSopLogsByCancel();
|
|
|
- log.info("补发过期完课消息 - 定时任务成功完成");
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("补发过期完课消息 - 定时任务执行失败", e);
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> {
|
|
|
+ try {
|
|
|
+ sopLogsTaskService.updateSopLogsByCancel();
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ sopLogsTaskService.updateSopLogsByCancel();
|
|
|
+ log.info("补发过期完课消息 - 定时任务成功完成");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("补发过期完课消息 - 定时任务执行失败", e);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -280,11 +332,17 @@ public class qwTask {
|
|
|
@Scheduled(cron = "0 0/8 * * * ?")
|
|
|
public void batchProcessingExpiredMessages() {
|
|
|
log.info("批量处理sop待发送记录中已过期的消息");
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(this::doBatchProcessingExpiredMessages);
|
|
|
+ } else {
|
|
|
+ doBatchProcessingExpiredMessages();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void doBatchProcessingExpiredMessages() {
|
|
|
try {
|
|
|
- // 步骤1:批量获取已过期的记录
|
|
|
List<QwSopLogsDoSendListTVO> expireded = iQwSopLogsService.expiredMessagesByQwSopLogs();
|
|
|
if (!expireded.isEmpty()) {
|
|
|
- // 步骤2:批量处理并插入记录
|
|
|
processAndInsertQwSopLogs(expireded);
|
|
|
}
|
|
|
log.info("处理已过期 - 定时任务成功完成");
|
|
|
@@ -326,7 +384,11 @@ public class qwTask {
|
|
|
*/
|
|
|
@Scheduled(cron = "0 10 0 * * ?")
|
|
|
public void deleteQwSopLogsByDate() {
|
|
|
- qwSopLogsMapper.deleteQwSopLogsByDate();
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> qwSopLogsMapper.deleteQwSopLogsByDate());
|
|
|
+ } else {
|
|
|
+ qwSopLogsMapper.deleteQwSopLogsByDate();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -336,10 +398,13 @@ public class qwTask {
|
|
|
*/
|
|
|
@Scheduled(cron = "0 30 0/3 * * ? ")
|
|
|
public void processRepairQwSopLogsTimer() {
|
|
|
- sopUserLogsService.repairSopUserLogsTimer();
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> sopUserLogsService.repairSopUserLogsTimer());
|
|
|
+ } else {
|
|
|
+ sopUserLogsService.repairSopUserLogsTimer();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* 凌晨 2点35开始,将营期小于7天中标记为 是否7天未看课的(E级) 客户的 但是看课了的恢复一下
|
|
|
*/
|
|
|
@@ -348,9 +413,11 @@ public class qwTask {
|
|
|
public void processSopUserLogsInfoByIsDaysNotStudy() {
|
|
|
long startTimeMillis = System.currentTimeMillis();
|
|
|
log.info("====== 开始选择和处理 是否7天未看课的(E级) 客户的 恢复一下 ======");
|
|
|
-
|
|
|
- logsInfoByIsDaysNotStudy.restoreByIsDaysNotStudy();
|
|
|
-
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> logsInfoByIsDaysNotStudy.restoreByIsDaysNotStudy());
|
|
|
+ } else {
|
|
|
+ logsInfoByIsDaysNotStudy.restoreByIsDaysNotStudy();
|
|
|
+ }
|
|
|
long endTimeMillis = System.currentTimeMillis();
|
|
|
log.info("====== 用户E级恢复处理完成,耗时 {} 毫秒 ======", (endTimeMillis - startTimeMillis));
|
|
|
}
|
|
|
@@ -359,19 +426,17 @@ public class qwTask {
|
|
|
* 定时任务:客户评级处理
|
|
|
* 执行时间:每天凌晨 3:45:00
|
|
|
* 功能:对SOP营期用户进行分级评级
|
|
|
- * 备注:异步执行,避免阻塞其他任务
|
|
|
*/
|
|
|
@Scheduled(cron = "0 45 3 * * ?")
|
|
|
@Async
|
|
|
public void processQwSopExternalContactRatingTimer() {
|
|
|
- // 记录任务开始时间
|
|
|
long startTimeMillis = System.currentTimeMillis();
|
|
|
log.info("====== 开始选择和处理 sop营期-用户分级 ======");
|
|
|
-
|
|
|
- // 执行用户分级评级
|
|
|
- qwExternalContactRatingService.ratingUserLogs();
|
|
|
-
|
|
|
- // 计算并记录任务执行耗时
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> qwExternalContactRatingService.ratingUserLogs());
|
|
|
+ } else {
|
|
|
+ qwExternalContactRatingService.ratingUserLogs();
|
|
|
+ }
|
|
|
long endTimeMillis = System.currentTimeMillis();
|
|
|
log.info("====== sop营期-用户分级处理完成,耗时 {} 毫秒 ======", (endTimeMillis - startTimeMillis));
|
|
|
}
|
|
|
@@ -384,14 +449,15 @@ public class qwTask {
|
|
|
public void processQwSopExternalContactRatingMoreSevenDaysTimer() {
|
|
|
long startTimeMillis = System.currentTimeMillis();
|
|
|
log.info("====== 开始选择和处理 sop营期-用户超7天的看课情况 ======");
|
|
|
-
|
|
|
- qwExternalContactRatingMoreSevenDaysService.ratingMoreSevenDaysUserLogs();
|
|
|
-
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> qwExternalContactRatingMoreSevenDaysService.ratingMoreSevenDaysUserLogs());
|
|
|
+ } else {
|
|
|
+ qwExternalContactRatingMoreSevenDaysService.ratingMoreSevenDaysUserLogs();
|
|
|
+ }
|
|
|
long endTimeMillis = System.currentTimeMillis();
|
|
|
log.info("====== sop营期-用户超7天处理完成,耗时 {} 毫秒 ======", (endTimeMillis - startTimeMillis));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* 更新掉所有前一天的所有待发送
|
|
|
*/
|
|
|
@@ -399,8 +465,11 @@ public class qwTask {
|
|
|
public void updateQwSopLogsDayBefore() {
|
|
|
long startTimeMillis = System.currentTimeMillis();
|
|
|
log.info("====== 更新掉所有前一天的所有待发送 ======");
|
|
|
- qwSopLogsMapper.updateQwSopLogsByDayBefore();
|
|
|
-
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> qwSopLogsMapper.updateQwSopLogsByDayBefore());
|
|
|
+ } else {
|
|
|
+ qwSopLogsMapper.updateQwSopLogsByDayBefore();
|
|
|
+ }
|
|
|
long endTimeMillis = System.currentTimeMillis();
|
|
|
log.info("====== 更新掉所有前一天的所有待发送,耗时 {} 毫秒 ======", (endTimeMillis - startTimeMillis));
|
|
|
}
|
|
|
@@ -409,8 +478,11 @@ public class qwTask {
|
|
|
public void updateQwExternalContactUnionid() {
|
|
|
long startTimeMillis = System.currentTimeMillis();
|
|
|
log.info("====== 同步外部联系人的UnionId ======");
|
|
|
- syncQwExternalContactService.syncQwExternalContactUnionid();
|
|
|
-
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(() -> syncQwExternalContactService.syncQwExternalContactUnionid());
|
|
|
+ } else {
|
|
|
+ syncQwExternalContactService.syncQwExternalContactUnionid();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -418,28 +490,26 @@ public class qwTask {
|
|
|
*/
|
|
|
@Scheduled(cron = "0 0 16 * * ?")
|
|
|
public void autoPullGroup(){
|
|
|
- // 拉群 ,①保持群号 ②每日拉群 ③创建建群记录
|
|
|
- // 计算每个人最大拉人数量
|
|
|
+ if (saasTaskEnabled) {
|
|
|
+ tenantTaskRunner.runForEachTenant(this::doAutoPullGroup);
|
|
|
+ } else {
|
|
|
+ doAutoPullGroup();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void doAutoPullGroup() {
|
|
|
long maxNum = (long) MAX_GROUP_NUM * MAX_GROUP_USER_NUM;
|
|
|
- // 获取当前时间
|
|
|
LocalDate now = LocalDate.now();
|
|
|
- // 获取需要自动拉群的SOP任务
|
|
|
List<QwSop> list = qwSopMapper.selectGroup(now);
|
|
|
if(list == null || list.isEmpty()) return;
|
|
|
list.forEach(sop -> {
|
|
|
- // 获取这个SOP下面的企微ID
|
|
|
List<Long> qwUserIdList = Arrays.stream(sop.getQwUserIds().split(",")).map(Long::parseLong).distinct().collect(Collectors.toList());
|
|
|
- // 获取企微ID下面的所有用户
|
|
|
List<QwExternalContact> qwExternalContactList = qwExternalContactService.selectQwUserAndLevel(qwUserIdList, Arrays.asList(sop.getAutoGroupLevel().split(",")), sop.getAutoUserReg() == 1);
|
|
|
- // 根据企微ID进行分组
|
|
|
Map<Long, List<QwExternalContact>> qwUserMap = PubFun.listToMapByGroupList(qwExternalContactList, QwExternalContact::getQwUserId);
|
|
|
- // 获取企微列表
|
|
|
List<QwUser> qwUserList = qwUserService.selectQwUserByIds(qwUserIdList);
|
|
|
try {
|
|
|
- // 每个企微都拉人
|
|
|
qwUserList.stream().filter(qwUser -> qwUserMap.containsKey(qwUser.getId())).forEach(qwUser -> {
|
|
|
List<QwExternalContact> userList = qwUserMap.get(qwUser.getId()).stream().limit(maxNum).collect(Collectors.toList());
|
|
|
- // 创建群 如果没人或者人数没达到满群的要求,不进行建群
|
|
|
if(userList.isEmpty() || userList.size() < MAX_GROUP_USER_NUM) return;
|
|
|
List<QwGroupChat> chatList = qwGroupChatService.selectSopAndQwUser(qwUser.getQwUserId(), sop.getId());
|
|
|
int groupNum = 0;
|
|
|
@@ -447,7 +517,6 @@ public class qwTask {
|
|
|
groupNum = extractLastNumber(chatList.get(0).getName()) == null ? 0 : extractLastNumber(chatList.get(0).getName());
|
|
|
}
|
|
|
try {
|
|
|
- // 建群
|
|
|
ipadSendUtils.createRoom(sop, sop.getGroupName(), qwUser, userList, MAX_GROUP_NUM, MAX_GROUP_USER_NUM,groupNum);
|
|
|
}catch (Exception e){
|
|
|
log.error("群聊拉人进群错误:{},企微ID:{},企微名称:{},外部联系人:{}", e.getMessage(), qwUser.getId(), qwUser.getQwUserName(), PubFun.listToNewList(userList, QwExternalContact::getId));
|