|  | @@ -3,21 +3,24 @@ package com.fs.store.service.impl;
 | 
											
												
													
														|  |  import java.time.LocalDateTime;
 |  |  import java.time.LocalDateTime;
 | 
											
												
													
														|  |  import java.util.*;
 |  |  import java.util.*;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +import cn.hutool.core.date.DateUtil;
 | 
											
												
													
														|  |  import cn.hutool.core.util.ObjectUtil;
 |  |  import cn.hutool.core.util.ObjectUtil;
 | 
											
												
													
														|  |  import com.alibaba.fastjson.JSON;
 |  |  import com.alibaba.fastjson.JSON;
 | 
											
												
													
														|  |  import com.fs.common.core.domain.R;
 |  |  import com.fs.common.core.domain.R;
 | 
											
												
													
														|  |  import com.fs.common.utils.DateUtils;
 |  |  import com.fs.common.utils.DateUtils;
 | 
											
												
													
														|  | -import com.fs.store.domain.FsCouponSchedule;
 |  | 
 | 
											
												
													
														|  | -import com.fs.store.domain.FsCouponScheduleLog;
 |  | 
 | 
											
												
													
														|  | 
 |  | +import com.fs.store.domain.*;
 | 
											
												
													
														|  | 
 |  | +import com.fs.store.dto.TemplateMessageSendRequestDTO;
 | 
											
												
													
														|  |  import com.fs.store.enums.IcgProcessStatusEnum;
 |  |  import com.fs.store.enums.IcgProcessStatusEnum;
 | 
											
												
													
														|  |  import com.fs.store.enums.IcgScheduleOperationTypeEnum;
 |  |  import com.fs.store.enums.IcgScheduleOperationTypeEnum;
 | 
											
												
													
														|  | -import com.fs.store.mapper.FsCouponScheduleLogMapper;
 |  | 
 | 
											
												
													
														|  | -import com.fs.store.mapper.FsCouponScheduleMapper;
 |  | 
 | 
											
												
													
														|  | 
 |  | +import com.fs.store.enums.MiniAppNotifyTaskStatusEnum;
 | 
											
												
													
														|  | 
 |  | +import com.fs.store.mapper.*;
 | 
											
												
													
														|  |  import com.fs.store.param.FsStoreCouponReceiveParam;
 |  |  import com.fs.store.param.FsStoreCouponReceiveParam;
 | 
											
												
													
														|  |  import com.fs.store.service.IFsCouponScheduleService;
 |  |  import com.fs.store.service.IFsCouponScheduleService;
 | 
											
												
													
														|  |  import com.fs.store.service.IFsStoreCouponIssueService;
 |  |  import com.fs.store.service.IFsStoreCouponIssueService;
 | 
											
												
													
														|  | 
 |  | +import com.github.pagehelper.util.StringUtil;
 | 
											
												
													
														|  |  import lombok.RequiredArgsConstructor;
 |  |  import lombok.RequiredArgsConstructor;
 | 
											
												
													
														|  |  import lombok.extern.slf4j.Slf4j;
 |  |  import lombok.extern.slf4j.Slf4j;
 | 
											
												
													
														|  | 
 |  | +import org.apache.commons.collections4.CollectionUtils;
 | 
											
												
													
														|  |  import org.springframework.stereotype.Service;
 |  |  import org.springframework.stereotype.Service;
 | 
											
												
													
														|  |  import org.springframework.transaction.annotation.Propagation;
 |  |  import org.springframework.transaction.annotation.Propagation;
 | 
											
												
													
														|  |  import org.springframework.transaction.annotation.Transactional;
 |  |  import org.springframework.transaction.annotation.Transactional;
 | 
											
										
											
												
													
														|  | @@ -29,7 +32,7 @@ import org.springframework.transaction.annotation.Transactional;
 | 
											
												
													
														|  |   * @date 2025-03-08
 |  |   * @date 2025-03-08
 | 
											
												
													
														|  |   */
 |  |   */
 | 
											
												
													
														|  |  @Slf4j
 |  |  @Slf4j
 | 
											
												
													
														|  | -@Service("fsCouponScheduleService")
 |  | 
 | 
											
												
													
														|  | 
 |  | +@Service
 | 
											
												
													
														|  |  @RequiredArgsConstructor
 |  |  @RequiredArgsConstructor
 | 
											
												
													
														|  |  public class FsCouponScheduleServiceImpl implements IFsCouponScheduleService
 |  |  public class FsCouponScheduleServiceImpl implements IFsCouponScheduleService
 | 
											
												
													
														|  |  {
 |  |  {
 | 
											
										
											
												
													
														|  | @@ -45,6 +48,36 @@ public class FsCouponScheduleServiceImpl implements IFsCouponScheduleService
 | 
											
												
													
														|  |       * 优惠券发放计划日志表Mapper接口
 |  |       * 优惠券发放计划日志表Mapper接口
 | 
											
												
													
														|  |       */
 |  |       */
 | 
											
												
													
														|  |      private final FsCouponScheduleLogMapper fsCouponScheduleLogMapper;
 |  |      private final FsCouponScheduleLogMapper fsCouponScheduleLogMapper;
 | 
											
												
													
														|  | 
 |  | +    /**
 | 
											
												
													
														|  | 
 |  | +     * 优惠券表Mapper接口
 | 
											
												
													
														|  | 
 |  | +     */
 | 
											
												
													
														|  | 
 |  | +    private final FsStoreCouponMapper fsStoreCouponMapper;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /**
 | 
											
												
													
														|  | 
 |  | +     * 用户表Mapper接口
 | 
											
												
													
														|  | 
 |  | +     */
 | 
											
												
													
														|  | 
 |  | +    private final FsUserMapper fsUserMapper;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /**
 | 
											
												
													
														|  | 
 |  | +     * 优惠券发放计划日志表Mapper接口
 | 
											
												
													
														|  | 
 |  | +     */
 | 
											
												
													
														|  | 
 |  | +    private final FsMiniprogramSubNotifyTaskMapper fsMiniprogramSubNotifyTaskMapper;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /**
 | 
											
												
													
														|  | 
 |  | +     * 小程序消息通知任务名称
 | 
											
												
													
														|  | 
 |  | +     */
 | 
											
												
													
														|  | 
 |  | +    private final String WX_MINI_APP_NOTIFY_TASK_NAME = "优惠券发放";
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /**
 | 
											
												
													
														|  | 
 |  | +     * 小程序消息通知模板ID
 | 
											
												
													
														|  | 
 |  | +     */
 | 
											
												
													
														|  | 
 |  | +    private final String WX_MINI_APP_NOTIFY_TEMPLATE_ID = "5ZSzz2nPmJo9EuenZa78mQPScoOMc84LnEfEpV0-i04";
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +    /**
 | 
											
												
													
														|  | 
 |  | +     * 小程序消息通知跳转URL
 | 
											
												
													
														|  | 
 |  | +     */
 | 
											
												
													
														|  | 
 |  | +    private final String WX_MINI_APP_NOTIFY_GOTO_URL ="";
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |      /**
 |  |      /**
 | 
											
												
													
														|  |       * 查询定时发放优惠券队列
 |  |       * 查询定时发放优惠券队列
 | 
											
												
													
														|  |       *
 |  |       *
 | 
											
										
											
												
													
														|  | @@ -141,18 +174,20 @@ public class FsCouponScheduleServiceImpl implements IFsCouponScheduleService
 | 
											
												
													
														|  |      public void issueCoupon() {
 |  |      public void issueCoupon() {
 | 
											
												
													
														|  |          List<FsCouponSchedule> fsCouponSchedules = fsCouponScheduleMapper.selectPendingCouponList();
 |  |          List<FsCouponSchedule> fsCouponSchedules = fsCouponScheduleMapper.selectPendingCouponList();
 | 
											
												
													
														|  |          List<FsCouponScheduleLog> logList = new ArrayList<>();
 |  |          List<FsCouponScheduleLog> logList = new ArrayList<>();
 | 
											
												
													
														|  | 
 |  | +        List<FsMiniprogramSubNotifyTask> subNotifyTasks = new ArrayList<>();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |          for (FsCouponSchedule fsCouponSchedule : fsCouponSchedules) {
 |  |          for (FsCouponSchedule fsCouponSchedule : fsCouponSchedules) {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -            FsCouponScheduleLog log = new FsCouponScheduleLog();
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FsCouponScheduleLog scheduleLog = new FsCouponScheduleLog();
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -            log.setScheduleId(fsCouponSchedule.getId());
 |  | 
 | 
											
												
													
														|  | -            log.setOrderId(fsCouponSchedule.getOrderId());
 |  | 
 | 
											
												
													
														|  | -            log.setUserId(fsCouponSchedule.getUserId());
 |  | 
 | 
											
												
													
														|  | -            log.setStatusBefore(fsCouponSchedule.getStatus());
 |  | 
 | 
											
												
													
														|  | -            log.setSendTimeBefore(fsCouponSchedule.getSendTime());
 |  | 
 | 
											
												
													
														|  | -            log.setRetryCountBefore(fsCouponSchedule.getRetryCount());
 |  | 
 | 
											
												
													
														|  | -            log.setOperator("SYSTEM");
 |  | 
 | 
											
												
													
														|  | -            log.setOperationTime(LocalDateTime.now());
 |  | 
 | 
											
												
													
														|  | 
 |  | +            scheduleLog.setScheduleId(fsCouponSchedule.getId());
 | 
											
												
													
														|  | 
 |  | +            scheduleLog.setOrderId(fsCouponSchedule.getOrderId());
 | 
											
												
													
														|  | 
 |  | +            scheduleLog.setUserId(fsCouponSchedule.getUserId());
 | 
											
												
													
														|  | 
 |  | +            scheduleLog.setStatusBefore(fsCouponSchedule.getStatus());
 | 
											
												
													
														|  | 
 |  | +            scheduleLog.setSendTimeBefore(fsCouponSchedule.getSendTime());
 | 
											
												
													
														|  | 
 |  | +            scheduleLog.setRetryCountBefore(fsCouponSchedule.getRetryCount());
 | 
											
												
													
														|  | 
 |  | +            scheduleLog.setOperator("SYSTEM");
 | 
											
												
													
														|  | 
 |  | +            scheduleLog.setOperationTime(LocalDateTime.now());
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              FsStoreCouponReceiveParam param = new FsStoreCouponReceiveParam();
 |  |              FsStoreCouponReceiveParam param = new FsStoreCouponReceiveParam();
 | 
											
												
													
														|  |              Long userId = fsCouponSchedule.getUserId();
 |  |              Long userId = fsCouponSchedule.getUserId();
 | 
											
										
											
												
													
														|  | @@ -168,8 +203,8 @@ public class FsCouponScheduleServiceImpl implements IFsCouponScheduleService
 | 
											
												
													
														|  |                  fsCouponSchedule.setStatus(IcgProcessStatusEnum.FAILED.getCode());
 |  |                  fsCouponSchedule.setStatus(IcgProcessStatusEnum.FAILED.getCode());
 | 
											
												
													
														|  |                  fsCouponSchedule.setRetryCount(fsCouponSchedule.getRetryCount()+1);
 |  |                  fsCouponSchedule.setRetryCount(fsCouponSchedule.getRetryCount()+1);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -                log.setStatusAfter(IcgProcessStatusEnum.FAILED.getCode());
 |  | 
 | 
											
												
													
														|  | -                log.setErrorMessage(fsCouponSchedule.getErrorMessage());
 |  | 
 | 
											
												
													
														|  | 
 |  | +                scheduleLog.setStatusAfter(IcgProcessStatusEnum.FAILED.getCode());
 | 
											
												
													
														|  | 
 |  | +                scheduleLog.setErrorMessage(fsCouponSchedule.getErrorMessage());
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |                  operationTypeSet.add(IcgScheduleOperationTypeEnum.ERROR.getCode());
 |  |                  operationTypeSet.add(IcgScheduleOperationTypeEnum.ERROR.getCode());
 | 
											
												
													
														|  |              } else {
 |  |              } else {
 | 
											
										
											
												
													
														|  | @@ -178,21 +213,85 @@ public class FsCouponScheduleServiceImpl implements IFsCouponScheduleService
 | 
											
												
													
														|  |                  fsCouponSchedule.setSendTime(fsCouponSchedule.getActualSendTime().plusMonths(1));
 |  |                  fsCouponSchedule.setSendTime(fsCouponSchedule.getActualSendTime().plusMonths(1));
 | 
											
												
													
														|  |                  fsCouponSchedule.setCount(fsCouponSchedule.getCount()+1);
 |  |                  fsCouponSchedule.setCount(fsCouponSchedule.getCount()+1);
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -                log.setStatusAfter(IcgProcessStatusEnum.SUCCESS.getCode());
 |  | 
 | 
											
												
													
														|  | -                log.setActualSendTime(fsCouponSchedule.getActualSendTime());
 |  | 
 | 
											
												
													
														|  | -                log.setSendTimeAfter(fsCouponSchedule.getSendTime());
 |  | 
 | 
											
												
													
														|  | 
 |  | +                scheduleLog.setStatusAfter(IcgProcessStatusEnum.SUCCESS.getCode());
 | 
											
												
													
														|  | 
 |  | +                scheduleLog.setActualSendTime(fsCouponSchedule.getActualSendTime());
 | 
											
												
													
														|  | 
 |  | +                scheduleLog.setSendTimeAfter(fsCouponSchedule.getSendTime());
 | 
											
												
													
														|  |                  operationTypeSet.add(IcgScheduleOperationTypeEnum.NORMAL.getCode());
 |  |                  operationTypeSet.add(IcgScheduleOperationTypeEnum.NORMAL.getCode());
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +                // 小程序消息通知
 | 
											
												
													
														|  | 
 |  | +                FsMiniprogramSubNotifyTask notifyTask = new FsMiniprogramSubNotifyTask();
 | 
											
												
													
														|  | 
 |  | +                notifyTask.setTaskName(WX_MINI_APP_NOTIFY_TASK_NAME);
 | 
											
												
													
														|  | 
 |  | +                notifyTask.setTemplateId(WX_MINI_APP_NOTIFY_TEMPLATE_ID);
 | 
											
												
													
														|  | 
 |  | +                FsUser fsUser = fsUserMapper.selectFsUserById(fsCouponSchedule.getUserId());
 | 
											
												
													
														|  | 
 |  | +                String maOpenId = fsUser.getMaOpenId();
 | 
											
												
													
														|  | 
 |  | +                notifyTask.setTouser(maOpenId);
 | 
											
												
													
														|  | 
 |  | +                notifyTask.setPage(WX_MINI_APP_NOTIFY_GOTO_URL);
 | 
											
												
													
														|  | 
 |  | +                notifyTask.setCreateTime(LocalDateTime.now());
 | 
											
												
													
														|  | 
 |  | +                // 状态等待执行
 | 
											
												
													
														|  | 
 |  | +                notifyTask.setStatus(MiniAppNotifyTaskStatusEnum.WAITING.getValue());
 | 
											
												
													
														|  | 
 |  | +                notifyTask.setRetryCount(0);
 | 
											
												
													
														|  | 
 |  | +                Map<String, TemplateMessageSendRequestDTO.TemplateDataValue> data = new HashMap<>();
 | 
											
												
													
														|  | 
 |  | +                // 获取优惠券名称
 | 
											
												
													
														|  | 
 |  | +                Set<Long> couponIds = fsCouponSchedule.getCouponId();
 | 
											
												
													
														|  | 
 |  | +                if(CollectionUtils.isEmpty(couponIds)){
 | 
											
												
													
														|  | 
 |  | +                    log.info("当前优惠券没有被选择!已经跳过");
 | 
											
												
													
														|  | 
 |  | +                    continue;
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  | 
 |  | +                // 优惠券id (有多张这里只取第一张)
 | 
											
												
													
														|  | 
 |  | +                Long couponId = couponIds.stream().findFirst().get();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +                TemplateMessageSendRequestDTO.TemplateDataValue couponName = new TemplateMessageSendRequestDTO.TemplateDataValue();
 | 
											
												
													
														|  | 
 |  | +                FsStoreCoupon fsStoreCoupon = fsStoreCouponMapper.selectFsStoreCouponById(couponId);
 | 
											
												
													
														|  | 
 |  | +                if(ObjectUtil.isNotNull(fsStoreCoupon)){
 | 
											
												
													
														|  | 
 |  | +                    String couponNameById = fsStoreCoupon.getTitle();
 | 
											
												
													
														|  | 
 |  | +                    if(StringUtil.isNotEmpty(couponNameById)){
 | 
											
												
													
														|  | 
 |  | +                        couponName.setValue(couponNameById);
 | 
											
												
													
														|  | 
 |  | +                    }
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +                // 获取优惠券时间范围
 | 
											
												
													
														|  | 
 |  | +                TemplateMessageSendRequestDTO.TemplateDataValue couponValidate = new TemplateMessageSendRequestDTO.TemplateDataValue();
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +                FsStoreCouponIssue fsStoreCouponIssue = fsStoreCouponIssueService.selectFsStoreCouponIssueByCouponId(couponId);
 | 
											
												
													
														|  | 
 |  | +                if(ObjectUtil.isNotNull(fsStoreCouponIssue)){
 | 
											
												
													
														|  | 
 |  | +                    String beginTime = fsStoreCouponIssue.getBeginTime();
 | 
											
												
													
														|  | 
 |  | +                    String endTime = fsStoreCouponIssue.getEndTime();
 | 
											
												
													
														|  | 
 |  | +                    if(StringUtil.isNotEmpty(beginTime) && StringUtil.isNotEmpty(endTime)){
 | 
											
												
													
														|  | 
 |  | +                        couponValidate.setValue(beginTime + " ~ " + endTime);
 | 
											
												
													
														|  | 
 |  | +                    }
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  | 
 |  | +                // 备注消息
 | 
											
												
													
														|  | 
 |  | +                TemplateMessageSendRequestDTO.TemplateDataValue couponMark = new TemplateMessageSendRequestDTO.TemplateDataValue();
 | 
											
												
													
														|  | 
 |  | +                couponMark.setValue("");
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +                // 面值
 | 
											
												
													
														|  | 
 |  | +                TemplateMessageSendRequestDTO.TemplateDataValue couponPrice = new TemplateMessageSendRequestDTO.TemplateDataValue();
 | 
											
												
													
														|  | 
 |  | +                if(ObjectUtil.isNotNull(fsStoreCoupon)){
 | 
											
												
													
														|  | 
 |  | +                    if(ObjectUtil.isNotNull(fsStoreCoupon.getCouponPrice())){
 | 
											
												
													
														|  | 
 |  | +                        couponPrice.setValue(fsStoreCoupon.getCouponPrice().toPlainString());
 | 
											
												
													
														|  | 
 |  | +                    }
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +                data.put("thing1",couponName);
 | 
											
												
													
														|  | 
 |  | +                data.put("time2",couponValidate);
 | 
											
												
													
														|  | 
 |  | +                data.put("thing3",couponMark);
 | 
											
												
													
														|  | 
 |  | +                data.put("amount4",couponPrice);
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +                notifyTask.setData(JSON.toJSONString(data));
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +                subNotifyTasks.add(notifyTask);
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  |              fsCouponSchedule.setUpdateTime(new Date());
 |  |              fsCouponSchedule.setUpdateTime(new Date());
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -            log.setOperationType(String.join(",",operationTypeSet));
 |  | 
 | 
											
												
													
														|  | -            logList.add(log);
 |  | 
 | 
											
												
													
														|  | 
 |  | +            scheduleLog.setOperationType(String.join(",",operationTypeSet));
 | 
											
												
													
														|  | 
 |  | +            logList.add(scheduleLog);
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |          // 批量更新发放优惠券队列表
 |  |          // 批量更新发放优惠券队列表
 | 
											
												
													
														|  |          fsCouponScheduleMapper.updateBatchFsCouponSchedule(fsCouponSchedules);
 |  |          fsCouponScheduleMapper.updateBatchFsCouponSchedule(fsCouponSchedules);
 | 
											
												
													
														|  |          // 批量添加执行日志
 |  |          // 批量添加执行日志
 | 
											
												
													
														|  |          fsCouponScheduleLogMapper.batchInsert(logList);
 |  |          fsCouponScheduleLogMapper.batchInsert(logList);
 | 
											
												
													
														|  |          // 批量进行微信公众号消息通知
 |  |          // 批量进行微信公众号消息通知
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | 
 |  | +        fsMiniprogramSubNotifyTaskMapper.insertBatch(subNotifyTasks);
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  }
 |  |  }
 |