feat(puzzle): 添加免费拼图通知任务功能

- 在MemberPuzzleMapper中新增listFreeUnpurchased方法用于查询指定时间范围内生成且未购买的免费拼图记录
- 新增FreePuzzleNotificationTask定时任务类,每天晚7点执行免费拼图通知
- 添加SQL映射配置实现免费拼图记录的查询逻辑
- 实现微信订阅通知触发机制,向符合条件的用户发送免费拼图领取通知
- 集成景区信息查询和会员信息获取功能用于通知内容构造
This commit is contained in:
2026-01-20 18:35:57 +08:00
parent ce48bd00c9
commit a8156976be
3 changed files with 101 additions and 0 deletions

View File

@@ -46,4 +46,9 @@ public interface MemberPuzzleMapper {
* 根据人脸ID和记录ID查询 * 根据人脸ID和记录ID查询
*/ */
MemberPuzzleEntity getByFaceAndRecord(@Param("faceId") Long faceId, @Param("recordId") Long recordId); 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);
} }

View File

@@ -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("免费拼图通知任务执行结束");
}
}

View File

@@ -67,4 +67,13 @@
LIMIT 1 LIMIT 1
</select> </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> </mapper>