package com.ycwl.basic.task; import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; 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.pricing.entity.PriceCouponClaimRecord; import com.ycwl.basic.pricing.entity.PriceCouponConfig; import com.ycwl.basic.pricing.enums.CouponStatus; import com.ycwl.basic.pricing.mapper.PriceCouponClaimRecordMapper; import com.ycwl.basic.pricing.mapper.PriceCouponConfigMapper; import com.ycwl.basic.service.notify.WechatSubscribeNotifyTriggerService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.Date; import java.util.HashMap; import java.util.List; @Component @EnableScheduling @Slf4j @Profile("prod") public class CouponExpireNotificationTask { @Autowired private PriceCouponClaimRecordMapper couponClaimRecordMapper; @Autowired private MemberMapper memberMapper; @Autowired private WechatSubscribeNotifyTriggerService notifyTriggerService; @Autowired private PriceCouponConfigMapper priceCouponConfigMapper; @Scheduled(cron = "0 0 20 * * *") public void sendCouponExpireNotification() { log.info("开始执行优惠券过期提醒定时任务"); processNotification("COUPON_EXPIRE", -2); log.info("优惠券过期提醒定时任务执行结束"); } @Scheduled(cron = "0 0 8 * * *") public void sendCouponPreExpireNotification() { log.info("开始执行优惠券临期提醒定时任务"); processNotification("COUPON_PRE_EXPIRE", -2); log.info("优惠券临期提醒定时任务执行结束"); } private void processNotification(String notifyType, int offsetDays) { // 获取指定偏移天数(例如-2 days)的开始和结束时间 Date date = DateUtil.offsetDay(new Date(), offsetDays); Date beginTime = DateUtil.beginOfDay(date); Date endTime = DateUtil.endOfDay(date); log.info("查询时间范围: {} - {}", beginTime, endTime); // 查询该时间段内创建的优惠券记录 LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); queryWrapper.between(PriceCouponClaimRecord::getCreateTime, beginTime, endTime); queryWrapper.eq(PriceCouponClaimRecord::getStatus, CouponStatus.CLAIMED); List couponRecords = couponClaimRecordMapper.selectList(queryWrapper); if (couponRecords == null || couponRecords.isEmpty()) { log.info("未找到符合条件的优惠券记录"); return; } log.info("找到 {} 条优惠券记录", couponRecords.size()); for (PriceCouponClaimRecord record : couponRecords) { try { MemberRespVO member = memberMapper.getById(record.getUserId()); if (member == null || member.getOpenId() == null) { continue; } PriceCouponConfig coupon = priceCouponConfigMapper.selectValidCouponById(record.getCouponId()); HashMap variables = new HashMap<>(); variables.put("couponName", coupon.getCouponName()); variables.put("couponValue", coupon.getDiscountValue()); variables.put("couponType", coupon.getCouponType().getDescription()); // 优惠券有效期到第二天的结束,从领取开始的时候算 variables.put("couponStartTime", DateUtil.format(record.getCreateTime(), "yyyy-MM-dd HH:mm")); variables.put("couponExpireTime", DateUtil.format(DateUtil.endOfDay(DateUtil.offsetDay(record.getCreateTime(), 2)), "yyyy-MM-dd HH:mm")); WechatSubscribeNotifyTriggerRequest request = WechatSubscribeNotifyTriggerRequest.builder() .memberId(record.getUserId()) .openId(member.getOpenId()) .bizId(String.valueOf(record.getId())) .variables(variables) .build(); // 触发消息 notifyTriggerService.trigger(notifyType, request); } catch (Exception e) { log.error("发送通知失败, type: {}, recordId: {}", notifyType, record.getId(), e); } } } }