package com.tcm.training.admin.member.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
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.member.entity.AppUser;
|
import com.tcm.training.admin.member.mapper.UserMapper;
|
import com.tcm.training.admin.system.entity.SystemSettings;
|
import com.tcm.training.admin.system.mapper.SystemSettingsMapper;
|
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.stereotype.Service;
|
|
import java.time.LocalDateTime;
|
import java.time.temporal.ChronoUnit;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* 会员到期提醒分发服务。
|
*/
|
@Service
|
public class MemberExpireRemindDispatchService {
|
|
private final UserMapper userMapper;
|
private final SystemSettingsMapper systemSettingsMapper;
|
private final AppSystemNoticeDispatchService appSystemNoticeDispatchService;
|
|
/**
|
* 注入会员到期提醒分发所需依赖。
|
*/
|
public MemberExpireRemindDispatchService(UserMapper userMapper,
|
SystemSettingsMapper systemSettingsMapper,
|
AppSystemNoticeDispatchService appSystemNoticeDispatchService) {
|
this.userMapper = userMapper;
|
this.systemSettingsMapper = systemSettingsMapper;
|
this.appSystemNoticeDispatchService = appSystemNoticeDispatchService;
|
}
|
|
/**
|
* 定时扫描即将到期的会员,并按系统设置发放提醒通知。
|
*/
|
@Scheduled(fixedDelayString = "${app.member.expire-remind-interval-ms:3600000}")
|
public void dispatchMemberExpireReminds() {
|
Integer remindDays = resolveRemindDays();
|
if (remindDays == null || remindDays.intValue() < 0) {
|
return;
|
}
|
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime deadline = now.plusDays(remindDays.longValue());
|
List<AppUser> users = userMapper.selectList(new LambdaQueryWrapper<AppUser>()
|
.eq(AppUser::getDeleted, 0)
|
.eq(AppUser::getStatus, 1)
|
.isNotNull(AppUser::getMemberExpireAt)
|
.ge(AppUser::getMemberExpireAt, now)
|
.le(AppUser::getMemberExpireAt, deadline)
|
.orderByAsc(AppUser::getMemberExpireAt)
|
.orderByAsc(AppUser::getId));
|
for (AppUser user : users) {
|
dispatchMemberExpireNotice(user, now);
|
}
|
}
|
|
/**
|
* 为单个即将到期会员发放系统通知。
|
*/
|
private void dispatchMemberExpireNotice(AppUser user, LocalDateTime now) {
|
if (user == null || user.getId() == null || user.getMemberExpireAt() == null) {
|
return;
|
}
|
long days = ChronoUnit.DAYS.between(now.toLocalDate(), user.getMemberExpireAt().toLocalDate());
|
AppSystemNoticeDispatchCommand command = new AppSystemNoticeDispatchCommand();
|
command.setAppUserId(user.getId());
|
command.setNoticeTypeCode(AppSystemNoticeType.MEMBER_EXPIRE_REMIND);
|
command.setTitle("会员到期提醒");
|
command.setContent("您的会员有效期将于" + user.getMemberExpireAt().toLocalDate() + "到期");
|
// 这里把到期时间编码进引用类型,保证同一到期批次只提醒一次。
|
command.setReferenceType("MEMBER_EXPIRE_" + user.getMemberExpireAt().toLocalDate());
|
command.setReferenceId(user.getId());
|
command.setRequireUserSetting(Boolean.FALSE);
|
Map<String, String> payload = new LinkedHashMap<String, String>();
|
payload.put("expireAt", String.valueOf(user.getMemberExpireAt()));
|
payload.put("remainingDays", String.valueOf(days));
|
command.setPayload(payload);
|
appSystemNoticeDispatchService.createAndPush(command);
|
}
|
|
/**
|
* 获取系统配置的会员到期提醒天数。
|
*/
|
private Integer resolveRemindDays() {
|
SystemSettings settings = systemSettingsMapper.selectOne(new LambdaQueryWrapper<SystemSettings>()
|
.eq(SystemSettings::getDeleted, 0)
|
.orderByDesc(SystemSettings::getId)
|
.last("limit 1"));
|
return settings == null ? null : settings.getMemberExpireRemindDays();
|
}
|
}
|