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查询
|
* 根据人脸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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
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>
|
||||||
|
|||||||
Reference in New Issue
Block a user