package com.tcm.training.admin.system.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.tcm.training.admin.app.notice.service.AppSystemNoticeDispatchCommand;
|
import com.tcm.training.admin.app.notice.service.AppSystemNoticeDispatchService;
|
import com.tcm.training.admin.app.notice.service.AppSystemNoticeType;
|
import com.tcm.training.admin.app.notice.entity.AppUserActivityNotice;
|
import com.tcm.training.admin.app.notice.mapper.AppUserActivityNoticeMapper;
|
import com.tcm.training.admin.member.entity.AppUser;
|
import com.tcm.training.admin.member.mapper.UserMapper;
|
import com.tcm.training.admin.system.event.ActivityNoticeCreatedEvent;
|
import com.tcm.training.admin.system.entity.ActivityNotice;
|
import com.tcm.training.admin.system.mapper.ActivityNoticeMapper;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.event.TransactionalEventListener;
|
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* 活动通知分发服务。
|
*/
|
@Service
|
public class ActivityNoticeDispatchService {
|
|
private static final Logger log = LoggerFactory.getLogger(ActivityNoticeDispatchService.class);
|
|
private static final int USER_STATUS_ENABLED = 1;
|
private static final int USER_DELETED_NO = 0;
|
private static final int RECORD_DELETED_NO = 0;
|
private static final int RECORD_DELETED_YES = 1;
|
private static final long PAGE_SIZE = 500L;
|
|
private final UserMapper userMapper;
|
private final AppUserActivityNoticeMapper appUserActivityNoticeMapper;
|
private final ActivityNoticeMapper activityNoticeMapper;
|
private final AppSystemNoticeDispatchService appSystemNoticeDispatchService;
|
|
/**
|
* 注入活动通知分发所需依赖。
|
*/
|
public ActivityNoticeDispatchService(UserMapper userMapper,
|
AppUserActivityNoticeMapper appUserActivityNoticeMapper,
|
ActivityNoticeMapper activityNoticeMapper,
|
AppSystemNoticeDispatchService appSystemNoticeDispatchService) {
|
this.userMapper = userMapper;
|
this.appUserActivityNoticeMapper = appUserActivityNoticeMapper;
|
this.activityNoticeMapper = activityNoticeMapper;
|
this.appSystemNoticeDispatchService = appSystemNoticeDispatchService;
|
}
|
|
/**
|
* 在活动通知创建提交成功后异步为用户分发通知记录。
|
*/
|
@Async("activityNoticeTaskExecutor")
|
@TransactionalEventListener
|
public void handleActivityNoticeCreated(ActivityNoticeCreatedEvent event) {
|
if (event == null || event.getActivityNoticeId() == null) {
|
return;
|
}
|
ActivityNotice activityNotice = activityNoticeMapper.selectOne(new LambdaQueryWrapper<ActivityNotice>()
|
.eq(ActivityNotice::getId, event.getActivityNoticeId())
|
.eq(ActivityNotice::getDeleted, RECORD_DELETED_NO)
|
.last("limit 1"));
|
if (activityNotice == null) {
|
return;
|
}
|
long currentPage = 1L;
|
while (true) {
|
Page<AppUser> page = userMapper.selectPage(
|
new Page<AppUser>(currentPage, PAGE_SIZE),
|
new LambdaQueryWrapper<AppUser>()
|
.eq(AppUser::getDeleted, USER_DELETED_NO)
|
.eq(AppUser::getStatus, USER_STATUS_ENABLED)
|
.orderByAsc(AppUser::getId)
|
);
|
List<AppUser> users = page.getRecords();
|
if (users == null || users.isEmpty()) {
|
break;
|
}
|
for (AppUser user : users) {
|
distributeToUser(user, activityNotice);
|
}
|
if (page.getCurrent() >= page.getPages()) {
|
break;
|
}
|
currentPage++;
|
}
|
}
|
|
/**
|
* 为单个 APP 用户分发活动通知,单用户失败不影响整批分发。
|
*/
|
private void distributeToUser(AppUser user, ActivityNotice activityNotice) {
|
if (user == null || user.getId() == null || activityNotice == null || activityNotice.getId() == null) {
|
return;
|
}
|
try {
|
boolean exists = appUserActivityNoticeMapper.selectCount(new LambdaQueryWrapper<AppUserActivityNotice>()
|
.eq(AppUserActivityNotice::getAppUserId, user.getId())
|
.eq(AppUserActivityNotice::getActivityNoticeId, activityNotice.getId())
|
.eq(AppUserActivityNotice::getDeleted, RECORD_DELETED_NO)) > 0;
|
if (!exists) {
|
AppUserActivityNotice record = new AppUserActivityNotice();
|
record.setAppUserId(user.getId());
|
record.setActivityNoticeId(activityNotice.getId());
|
record.setDeleted(RECORD_DELETED_NO);
|
appUserActivityNoticeMapper.insert(record);
|
}
|
// 活动通知发布后同时写入统一系统通知表,并按双开关规则尝试极光推送。
|
appSystemNoticeDispatchService.createAndPush(buildActivityNoticeCommand(user.getId(), activityNotice));
|
} catch (Exception ex) {
|
log.error("activity notice distribute failed, activityNoticeId={}, appUserId={}",
|
activityNotice.getId(), user.getId(), ex);
|
}
|
}
|
|
/**
|
* 构建活动通知统一发放命令。
|
*/
|
private AppSystemNoticeDispatchCommand buildActivityNoticeCommand(Long appUserId, ActivityNotice activityNotice) {
|
AppSystemNoticeDispatchCommand command = new AppSystemNoticeDispatchCommand();
|
command.setAppUserId(appUserId);
|
command.setNoticeTypeCode(AppSystemNoticeType.ACTIVITY_NOTICE);
|
command.setTitle(activityNotice.getTitle());
|
command.setContent(activityNotice.getTitle());
|
command.setReferenceType("ACTIVITY_NOTICE");
|
command.setReferenceId(activityNotice.getId());
|
command.setRequireUserSetting(Boolean.TRUE);
|
Map<String, String> payload = new LinkedHashMap<String, String>();
|
payload.put("activityNoticeId", String.valueOf(activityNotice.getId()));
|
payload.put("title", activityNotice.getTitle());
|
command.setPayload(payload);
|
return command;
|
}
|
|
/**
|
* 在后台删除活动通知时同步隐藏用户侧对应记录。
|
*/
|
public void hideDistributedRecords(Long activityNoticeId) {
|
if (activityNoticeId == null) {
|
return;
|
}
|
appUserActivityNoticeMapper.update(
|
null,
|
new LambdaUpdateWrapper<AppUserActivityNotice>()
|
.eq(AppUserActivityNotice::getActivityNoticeId, activityNoticeId)
|
.eq(AppUserActivityNotice::getDeleted, RECORD_DELETED_NO)
|
.set(AppUserActivityNotice::getDeleted, RECORD_DELETED_YES)
|
);
|
}
|
}
|