You've already forked FrameTour-BE
feat(puzzle): 添加免费拼图通知任务功能
- 在MemberPuzzleMapper中新增listFreeUnpurchased方法用于查询指定时间范围内生成且未购买的免费拼图记录 - 新增FreePuzzleNotificationTask定时任务类,每天晚7点执行免费拼图通知 - 添加SQL映射配置实现免费拼图记录的查询逻辑 - 实现微信订阅通知触发机制,向符合条件的用户发送免费拼图领取通知 - 集成景区信息查询和会员信息获取功能用于通知内容构造
This commit is contained in:
@@ -46,4 +46,9 @@ public interface MemberPuzzleMapper {
|
||||
* 根据人脸ID和记录ID查询
|
||||
*/
|
||||
MemberPuzzleEntity getByFaceAndRecord(@Param("faceId") Long faceId, @Param("recordId") Long recordId);
|
||||
|
||||
/**
|
||||
* 查询指定时间范围内生成且未购买的免费拼图记录
|
||||
*/
|
||||
List<MemberPuzzleEntity> listFreeUnpurchased(@Param("startTime") java.util.Date startTime, @Param("endTime") java.util.Date endTime);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.ycwl.basic.task;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
|
||||
import com.ycwl.basic.mapper.MemberMapper;
|
||||
import com.ycwl.basic.model.pc.member.resp.MemberRespVO;
|
||||
import com.ycwl.basic.model.pc.notify.req.WechatSubscribeNotifyTriggerRequest;
|
||||
import com.ycwl.basic.puzzle.mapper.MemberPuzzleMapper;
|
||||
import com.ycwl.basic.repository.ScenicRepository;
|
||||
import com.ycwl.basic.service.notify.WechatSubscribeNotifyTriggerService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 免费拼图通知任务
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class FreePuzzleNotificationTask {
|
||||
|
||||
@Autowired
|
||||
private MemberPuzzleMapper memberPuzzleMapper;
|
||||
@Autowired
|
||||
private MemberMapper memberMapper;
|
||||
@Autowired
|
||||
private ScenicRepository scenicRepository;
|
||||
@Autowired
|
||||
private WechatSubscribeNotifyTriggerService notifyTriggerService;
|
||||
|
||||
/**
|
||||
* 每天晚7点执行
|
||||
* 查找昨天生成的,未购买的且is_free字段等于1的member,触发“FREE_PUZZLE”通知
|
||||
*/
|
||||
@Scheduled(cron = "0 0 19 * * ?")
|
||||
public void sendFreePuzzleNotification() {
|
||||
log.info("开始执行免费拼图通知任务");
|
||||
// 昨天开始时间
|
||||
Date startTime = DateUtil.beginOfDay(DateUtil.yesterday());
|
||||
// 昨天结束时间
|
||||
Date endTime = DateUtil.endOfDay(DateUtil.yesterday());
|
||||
|
||||
// 查询符合条件的记录
|
||||
var list = memberPuzzleMapper.listFreeUnpurchased(startTime, endTime);
|
||||
log.info("查询到需发送免费拼图通知记录数: {}", list.size());
|
||||
|
||||
Set<Long> sentMemberIds = ConcurrentHashMap.newKeySet();
|
||||
|
||||
list.parallelStream().forEach(item -> {
|
||||
if (!sentMemberIds.add(item.getMemberId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
MemberRespVO member = memberMapper.getById(item.getMemberId());
|
||||
if (member == null || member.getOpenId() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 构造参数
|
||||
HashMap<String, Object> variables = new HashMap<>();
|
||||
ScenicV2DTO scenic = scenicRepository.getScenicBasic(item.getScenicId());
|
||||
variables.put("activityName", "免费领取三拼图");
|
||||
variables.put("scenicName", scenic.getName());
|
||||
|
||||
WechatSubscribeNotifyTriggerRequest request = WechatSubscribeNotifyTriggerRequest.builder()
|
||||
.scenicId(item.getScenicId())
|
||||
.memberId(item.getMemberId())
|
||||
.openId(member.getOpenId())
|
||||
.bizId(String.valueOf(item.getId()))
|
||||
.variables(variables)
|
||||
.build();
|
||||
|
||||
notifyTriggerService.trigger("FREE_PUZZLE", request);
|
||||
} catch (Exception e) {
|
||||
log.error("发送免费拼图通知失败: memberId={}", item.getMemberId(), e);
|
||||
}
|
||||
});
|
||||
log.info("免费拼图通知任务执行结束");
|
||||
}
|
||||
}
|
||||
@@ -67,4 +67,13 @@
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="listFreeUnpurchased" resultMap="BaseResultMap">
|
||||
SELECT mp.*
|
||||
FROM member_puzzle mp
|
||||
LEFT JOIN puzzle_generation_record pgr ON mp.record_id = pgr.id
|
||||
WHERE mp.is_free = 1
|
||||
AND (mp.is_buy = 0 OR mp.is_buy IS NULL)
|
||||
AND pgr.create_time BETWEEN #{startTime} AND #{endTime}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user