فهرست منبع

定时发放优惠券逻辑

xdd 1 ماه پیش
والد
کامیت
a450e5eecc

+ 31 - 27
fs-service-system/src/main/java/com/fs/store/domain/FsCouponSchedule.java

@@ -2,9 +2,14 @@ package com.fs.store.domain;
 
 import java.time.LocalDateTime;
 import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import cn.hutool.core.util.ObjectUtil;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fs.common.annotation.Excel;
 import com.fs.common.core.domain.BaseEntity;
+import com.hc.openapi.tool.util.StringUtils;
 import lombok.Data;
 
 /**
@@ -41,7 +46,7 @@ public class FsCouponSchedule extends BaseEntity
      * 套餐名称
      */
     @Excel(name = "套餐名称")
-    private Long setmealTitle;
+    private String setmealTitle;
 
     /** 总月数 */
     @Excel(name = "总月数")
@@ -53,37 +58,45 @@ public class FsCouponSchedule extends BaseEntity
 
     /** 0待处理, 1正在处理, 2成功, -1失败, 3用户拒签或者退货 */
     @Excel(name = "0待处理, 1正在处理, 2成功, -1失败, 3用户拒签或者退货")
-    private Long status;
+    private Integer status;
 
     /** 下单时间 */
     @JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "下单时间", width = 30, dateFormat = "yyyy-MM-dd")
     private LocalDateTime orderTime;
 
-    /** 执行时间 */
-//    @JsonFormat(pattern = "yyyy-MM-dd")
-//    @Excel(name = "执行时间", width = 30, dateFormat = "yyyy-MM-dd")
-//    private Date executeTime;
-
     /** 优惠券ID */
     @Excel(name = "优惠券ID")
-    private Long couponId;
+    private Set<Long> couponId;
     /**
-     * 优惠券名称
+     * 优惠券id列表
      */
-    @Excel(name = "优惠券名称")
-    private String couponName;
-
-    /** 优惠券批次ID */
-    @Excel(name = "优惠券批次ID")
-    private Long couponBatchId;
+    private String couponIds;
+
+    public Set<Long> getCouponId() {
+        if(StringUtils.isNotBlank(couponIds)){
+            String[] split = couponIds.split(",");
+            HashSet<Long> longs = new HashSet<>();
+            for (String e : split) {
+                longs.add(Long.valueOf(e.trim()));
+            }
+            couponId=longs;
+        }
+        return couponId;
+    }
+
+    public String getCouponIds() {
+        if(ObjectUtil.isNotNull(couponId)){
+            couponIds=String.join(",", couponId.toString());
+        }
+        return couponIds;
+    }
 
     /** 预计发送时间 */
     @JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "预计发送时间", width = 30, dateFormat = "yyyy-MM-dd")
     private LocalDateTime sendTime;
 
-
     /** 实际发送时间 */
     @JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "实际发送时间", width = 30, dateFormat = "yyyy-MM-dd")
@@ -95,19 +108,10 @@ public class FsCouponSchedule extends BaseEntity
 
     /** 重试次数 */
     @Excel(name = "重试次数")
-    private Long retryCount;
+    private Integer retryCount;
 
     /** 最大重试次数 */
     @Excel(name = "最大重试次数")
-    private Long maxRetries = 3L;
-
-    /** 下次重试时间 */
-    @JsonFormat(pattern = "yyyy-MM-dd")
-    @Excel(name = "下次重试时间", width = 30, dateFormat = "yyyy-MM-dd")
-    private LocalDateTime nextRetryTime;
-
-    /** 订单来源 */
-    @Excel(name = "订单来源")
-    private String sourceType;
+    private Integer maxRetries = 3;
 
 }

+ 94 - 0
fs-service-system/src/main/java/com/fs/store/domain/FsCouponScheduleLog.java

@@ -0,0 +1,94 @@
+package com.fs.store.domain;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * 优惠券发放计划日志表实体类
+ *
+ * @author example
+ */
+@Data
+public class FsCouponScheduleLog {
+    /**
+     * 日志ID
+     */
+    private Long logId;
+
+    /**
+     * fs_coupon_schedule 表的主键ID
+     */
+    private Long scheduleId;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 订单ID
+     */
+    private Long orderId;
+
+    /**
+     * 操作前状态
+     */
+    private Integer statusBefore;
+
+    /**
+     * 操作后状态
+     */
+    private Integer statusAfter;
+
+    /**
+     * 操作前预计发送时间
+     */
+    private LocalDateTime sendTimeBefore;
+
+    /**
+     * 操作后预计发送时间
+     */
+    private LocalDateTime sendTimeAfter;
+
+    /**
+     * 实际发送时间
+     */
+    private LocalDateTime actualSendTime;
+
+    /**
+     * 错误信息
+     */
+    private String errorMessage;
+
+    /**
+     * 操作前重试次数
+     */
+    private Integer retryCountBefore;
+
+    /**
+     * 操作后重试次数
+     */
+    private Integer retryCountAfter;
+
+    /**
+     * 操作类型,如:INSERT, ERROR, RETRY
+     */
+    private String operationType;
+
+    /**
+     * 操作时间
+     */
+    private LocalDateTime operationTime;
+
+    /**
+     * 操作人
+     */
+    private String operator;
+
+    /**
+     * 备注
+     */
+    private String remark;
+}

+ 32 - 0
fs-service-system/src/main/java/com/fs/store/enums/IcgProcessStatusEnum.java

@@ -0,0 +1,32 @@
+package com.fs.store.enums;
+
+import lombok.Getter;
+
+/**
+ * 定时发放优惠券处理枚举类
+ */
+@Getter
+public enum IcgProcessStatusEnum {
+    PENDING(0, "待处理"),
+    PROCESSING(1, "正在处理"),
+    SUCCESS(2, "成功"),
+    FAILED(-1, "失败"),
+    REJECTED_OR_RETURNED(3, "用户拒签或者退货");
+
+    private final Integer code;
+    private final String description;
+
+    IcgProcessStatusEnum(Integer code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    public static IcgProcessStatusEnum fromCode(Integer code) {
+        for (IcgProcessStatusEnum status : IcgProcessStatusEnum.values()) {
+            if (status.getCode().equals(code)) {
+                return status;
+            }
+        }
+        return null;
+    }
+}

+ 30 - 0
fs-service-system/src/main/java/com/fs/store/enums/IcgScheduleOperationTypeEnum.java

@@ -0,0 +1,30 @@
+package com.fs.store.enums;
+
+import lombok.Getter;
+
+@Getter
+public enum IcgScheduleOperationTypeEnum {
+    NORMAL("NORMAL"),
+    ERROR("ERROR"),
+    RETRY("RETRY");
+    private final String code;
+
+    IcgScheduleOperationTypeEnum(String code) {
+        this.code = code;
+    }
+
+
+    public static IcgScheduleOperationTypeEnum fromCode(String code) {
+        for (IcgScheduleOperationTypeEnum type : IcgScheduleOperationTypeEnum.values()) {
+            if (type.getCode().equalsIgnoreCase(code)) {
+                return type;
+            }
+        }
+        return null;
+    }
+
+     @Override
+    public String toString() {
+        return code;
+    }
+}

+ 60 - 0
fs-service-system/src/main/java/com/fs/store/mapper/FsCouponScheduleLogMapper.java

@@ -0,0 +1,60 @@
+package com.fs.store.mapper;
+
+import com.fs.store.domain.FsCouponScheduleLog;
+import org.apache.ibatis.annotations.*;
+
+import java.util.List;
+
+/**
+ * 优惠券发放计划日志表Mapper接口
+ *
+ * @author example
+ */
+@Mapper
+public interface FsCouponScheduleLogMapper {
+
+    /**
+     * 根据日志ID查询日志信息
+     *
+     * @param logId 日志ID
+     * @return 日志信息
+     */
+    @Select("SELECT * FROM fs_coupon_schedule_log WHERE log_id = #{logId}")
+    FsCouponScheduleLog selectByLogId(@Param("logId") Integer logId);
+
+    /**
+     * 插入一条日志记录
+     *
+     * @param log 日志信息
+     * @return 插入的行数
+     */
+    @Insert("INSERT INTO fs_coupon_schedule_log (schedule_id, user_id, order_id, status_before, status_after, send_time_before, send_time_after, actual_send_time, error_message, retry_count_before, retry_count_after, operation_type, operation_time, operator, remark) " +
+            "VALUES (#{scheduleId}, #{userId}, #{orderId}, #{statusBefore}, #{statusAfter}, #{sendTimeBefore}, #{sendTimeAfter}, #{actualSendTime}, #{errorMessage}, #{retryCountBefore}, #{retryCountAfter}, #{operationType}, #{operationTime}, #{operator}, #{remark})")
+    int insert(FsCouponScheduleLog log);
+
+    /**
+     * 更新日志信息
+     *
+     * @param log 日志信息
+     * @return 更新的行数
+     */
+    @Update("UPDATE fs_coupon_schedule_log SET schedule_id = #{scheduleId}, user_id = #{userId}, order_id = #{orderId}, status_before = #{statusBefore}, status_after = #{statusAfter}, send_time_before = #{sendTimeBefore}, send_time_after = #{sendTimeAfter}, actual_send_time = #{actualSendTime}, error_message = #{errorMessage}, retry_count_before = #{retryCountBefore}, retry_count_after = #{retryCountAfter}, operation_type = #{operationType}, operation_time = #{operationTime}, operator = #{operator}, remark = #{remark} WHERE log_id = #{logId}")
+    int update(FsCouponScheduleLog log);
+
+    /**
+     * 根据schedule_id查询日志列表
+     *
+     * @param scheduleId fs_coupon_schedule 表的主键ID
+     * @return 日志列表
+     */
+    @Select("SELECT * FROM fs_coupon_schedule_log WHERE schedule_id = #{scheduleId}")
+    List<FsCouponScheduleLog> selectByScheduleId(@Param("scheduleId") Integer scheduleId);
+
+    /**
+     * 批量插入日志记录
+     *
+     * @param logs 日志信息列表
+     * @return 插入的行数
+     */
+    int batchInsert(@Param("logs") List<FsCouponScheduleLog> logs);
+}

+ 15 - 1
fs-service-system/src/main/java/com/fs/store/mapper/FsCouponScheduleMapper.java

@@ -2,6 +2,7 @@ package com.fs.store.mapper;
 
 import com.fs.store.domain.FsCouponSchedule;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -45,7 +46,13 @@ public interface FsCouponScheduleMapper
      * @return 结果
      */
     public int updateFsCouponSchedule(FsCouponSchedule fsCouponSchedule);
-
+    /**
+     * 批量修改定时发放优惠券队列
+     *
+     * @param fsCouponSchedule 定时发放优惠券队列
+     * @return 结果
+     */
+    public int updateBatchFsCouponSchedule(@Param("list") List<FsCouponSchedule> fsCouponSchedule);
     /**
      * 删除定时发放优惠券队列
      *
@@ -66,4 +73,11 @@ public interface FsCouponScheduleMapper
      * 查询待发送优惠券
      */
     List<FsCouponSchedule> selectPendingCouponList();
+
+    /**
+     * 查询待发送优惠券通过订单id
+     * @param orderId
+     * @return
+     */
+    FsCouponSchedule selectFsCouponScheduleByOrderId(@Param("orderId") String orderId);
 }

+ 14 - 0
fs-service-system/src/main/java/com/fs/store/service/IFsCouponScheduleService.java

@@ -21,6 +21,18 @@ public interface IFsCouponScheduleService
      */
     public FsCouponSchedule selectFsCouponScheduleById(Long id);
 
+    /**
+     * 查询定时发放优惠券队列通过订单id
+     * @param orderId 订单id
+     * @return FsCouponSchedule
+     */
+    FsCouponSchedule selectFsCouponScheduleByOrderId(String orderId);
+
+    /**
+     * 退款将定时发放优惠券的状态设置为已退款
+     * @param orderCode 订单号码
+     */
+    void setScheduleCouponRefund(String orderCode);
     /**
      * 查询定时发放优惠券队列列表
      *
@@ -65,4 +77,6 @@ public interface IFsCouponScheduleService
      * 发放优惠券
      */
     void issueCoupon();
+
+
 }

+ 1 - 4
fs-service-system/src/main/java/com/fs/store/service/IFsStoreCouponIssueService.java

@@ -73,9 +73,6 @@ public interface IFsStoreCouponIssueService
     FsStoreCouponIssueVO selectFsStoreCouponIssueVOById(Long id);
 
     List<FsStoreCouponIssueVO> selectFsStoreCouponIssueListVO(FsStoreCouponIssue fsStoreCouponIssue);
-    /**
-     * 返回所有可用套餐优惠券
-     * @return List<FsStoreCouponIssueVO>
-     */
+
     List<FsStoreCouponIssueVO> listAllAvailable();
 }

+ 89 - 13
fs-service-system/src/main/java/com/fs/store/service/impl/FsCouponScheduleServiceImpl.java

@@ -1,14 +1,26 @@
 package com.fs.store.service.impl;
 
-import java.util.List;
+import java.time.LocalDateTime;
+import java.util.*;
 
 import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSON;
+import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
 import com.fs.store.domain.FsCouponSchedule;
+import com.fs.store.domain.FsCouponScheduleLog;
+import com.fs.store.enums.IcgProcessStatusEnum;
+import com.fs.store.enums.IcgScheduleOperationTypeEnum;
+import com.fs.store.mapper.FsCouponScheduleLogMapper;
 import com.fs.store.mapper.FsCouponScheduleMapper;
+import com.fs.store.param.FsStoreCouponReceiveParam;
 import com.fs.store.service.IFsCouponScheduleService;
-import org.springframework.beans.factory.annotation.Autowired;
+import com.fs.store.service.IFsStoreCouponIssueService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 定时发放优惠券队列Service业务层处理
@@ -16,12 +28,14 @@ import org.springframework.stereotype.Service;
  * @author fs
  * @date 2025-03-08
  */
+@Slf4j
 @Service
+@RequiredArgsConstructor
 public class FsCouponScheduleServiceImpl implements IFsCouponScheduleService
 {
-    @Autowired
-    private FsCouponScheduleMapper fsCouponScheduleMapper;
-
+    private final FsCouponScheduleMapper fsCouponScheduleMapper;
+    private final IFsStoreCouponIssueService fsStoreCouponIssueService;
+    private final FsCouponScheduleLogMapper fsCouponScheduleLogMapper;
     /**
      * 查询定时发放优惠券队列
      *
@@ -34,6 +48,21 @@ public class FsCouponScheduleServiceImpl implements IFsCouponScheduleService
         return fsCouponScheduleMapper.selectFsCouponScheduleById(id);
     }
 
+    @Override
+    public FsCouponSchedule selectFsCouponScheduleByOrderId(String orderId) {
+        return fsCouponScheduleMapper.selectFsCouponScheduleByOrderId(orderId);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
+    public void setScheduleCouponRefund(String orderCode) {
+        FsCouponSchedule fsCouponSchedule = fsCouponScheduleMapper.selectFsCouponScheduleByOrderId(orderCode);
+        if(ObjectUtil.isNotNull(fsCouponSchedule)){
+            fsCouponSchedule.setStatus(IcgProcessStatusEnum.REJECTED_OR_RETURNED.getCode());
+            fsCouponScheduleMapper.updateFsCouponSchedule(fsCouponSchedule);
+        }
+    }
+
     /**
      * 查询定时发放优惠券队列列表
      *
@@ -56,13 +85,6 @@ public class FsCouponScheduleServiceImpl implements IFsCouponScheduleService
     public int insertFsCouponSchedule(FsCouponSchedule fsCouponSchedule)
     {
         fsCouponSchedule.setCreateTime(DateUtils.getNowDate());
-        // 如果上次发送时间为空,那么预计发送时间等于=下单时间+1月
-        if(ObjectUtil.isNull(fsCouponSchedule.getActualSendTime())){
-            fsCouponSchedule.setSendTime(fsCouponSchedule.getOrderTime().plusMonths(1L));
-        } else {
-            // 否则等于上次发送时间+1月
-            fsCouponSchedule.setSendTime(fsCouponSchedule.getActualSendTime().plusMonths(1L));
-        }
         return fsCouponScheduleMapper.insertFsCouponSchedule(fsCouponSchedule);
     }
 
@@ -108,6 +130,60 @@ public class FsCouponScheduleServiceImpl implements IFsCouponScheduleService
      */
     @Override
     public void issueCoupon() {
-        fsCouponScheduleMapper.selectPendingCouponList();
+        List<FsCouponSchedule> fsCouponSchedules = fsCouponScheduleMapper.selectPendingCouponList();
+        List<FsCouponScheduleLog> logList = new ArrayList<>();
+        for (FsCouponSchedule fsCouponSchedule : fsCouponSchedules) {
+
+            FsCouponScheduleLog log = 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());
+
+            FsStoreCouponReceiveParam param = new FsStoreCouponReceiveParam();
+            Long userId = fsCouponSchedule.getUserId();
+            // 领取优惠券
+            R receive = fsStoreCouponIssueService.receive(String.valueOf(userId), param);
+            Set<String> operationTypeSet = new HashSet<>();
+            if(fsCouponSchedule.getRetryCount()>0) {
+                operationTypeSet.add(IcgScheduleOperationTypeEnum.RETRY.getCode());
+            }
+            // 如果不等于200表示失败了
+            if(ObjectUtil.equal(200,receive.get("code"))){
+                fsCouponSchedule.setErrorMessage(JSON.toJSONString(receive));
+                fsCouponSchedule.setStatus(IcgProcessStatusEnum.FAILED.getCode());
+                fsCouponSchedule.setRetryCount(fsCouponSchedule.getRetryCount()+1);
+
+                log.setStatusAfter(IcgProcessStatusEnum.FAILED.getCode());
+                log.setErrorMessage(fsCouponSchedule.getErrorMessage());
+
+                operationTypeSet.add(IcgScheduleOperationTypeEnum.ERROR.getCode());
+            } else {
+                fsCouponSchedule.setStatus(IcgProcessStatusEnum.SUCCESS.getCode());
+                fsCouponSchedule.setActualSendTime(LocalDateTime.now());
+                fsCouponSchedule.setSendTime(fsCouponSchedule.getActualSendTime().plusMonths(1));
+                fsCouponSchedule.setCount(fsCouponSchedule.getCount()+1);
+
+                log.setStatusAfter(IcgProcessStatusEnum.SUCCESS.getCode());
+                log.setActualSendTime(fsCouponSchedule.getActualSendTime());
+                log.setSendTimeAfter(fsCouponSchedule.getSendTime());
+                operationTypeSet.add(IcgScheduleOperationTypeEnum.NORMAL.getCode());
+            }
+            fsCouponSchedule.setUpdateTime(new Date());
+
+            log.setOperationType(String.join(",",operationTypeSet));
+            logList.add(log);
+        }
+        // 批量更新发放优惠券队列表
+        fsCouponScheduleMapper.updateBatchFsCouponSchedule(fsCouponSchedules);
+        // 批量添加执行日志
+        fsCouponScheduleLogMapper.batchInsert(logList);
+        // 批量进行微信公众号消息通知
+
     }
 }

+ 19 - 14
fs-service-system/src/main/java/com/fs/store/service/impl/FsStoreOrderServiceImpl.java

@@ -6,11 +6,11 @@ import java.nio.charset.Charset;
 import java.sql.Timestamp;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
-import cn.hutool.core.date.DateTime;
 import cn.hutool.core.net.URLDecoder;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.NumberUtil;
@@ -22,7 +22,6 @@ import com.alibaba.fastjson.JSONObject;
 import com.fs.api.param.OrderListParam;
 import com.fs.api.vo.OrderListVO;
 import com.fs.api.vo.ProductListVO;
-import com.fs.common.annotation.DataScope;
 import com.fs.common.config.FSSysConfig;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.redis.RedisCache;
@@ -61,24 +60,18 @@ import com.fs.store.param.*;
 import com.fs.store.service.*;
 import com.fs.store.vo.*;
 import com.fs.pay.service.IPayService;
-import com.fs.pay.service.dto.RefundDTO;
-import com.fs.system.domain.SysConfig;
 import com.fs.system.service.ISysConfigService;
-import com.hc.openapi.tool.util.Ids;
 import lombok.Synchronized;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import com.fs.store.mapper.FsStoreOrderMapper;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
 
-import javax.swing.plaf.TableHeaderUI;
-
 import static com.fs.store.constants.StoreConstants.DELIVERY;
 
 /**
@@ -1386,12 +1379,24 @@ public class FsStoreOrderServiceImpl implements IFsStoreOrderService
 
             // 如果是套餐类型的
             if(ObjectUtil.equal(storeOrder.getIsPackage(),1)) {
-                // 如果该套餐有定时发放优惠券
-
-                FsCouponSchedule fsCouponSchedule = new FsCouponSchedule();
-                fsCouponSchedule.setOrderId(order.getId());
-
-                fsCouponScheduleService.insertFsCouponSchedule(fsCouponSchedule);
+                // 如果该套餐有定时发放优惠券,就放置到定时发放优惠券队列
+                FsStoreProductPackage fsStoreProductPackage = productPackageService.selectFsStoreProductPackageById(storeOrder.getPackageId());
+                if(ObjectUtil.equal(1,fsStoreProductPackage.getIcgEnable())){
+                    FsCouponSchedule fsCouponSchedule = new FsCouponSchedule();
+                    fsCouponSchedule.setOrderId(order.getId());
+                    fsCouponSchedule.setSetmealId(fsStoreProductPackage.getPackageId());
+                    fsCouponSchedule.setSetmealTitle(fsStoreProductPackage.getTitle());
+                    fsCouponSchedule.setMonth(fsStoreProductPackage.getIcgMonth().longValue());
+                    fsCouponSchedule.setCount(0L);
+                    fsCouponSchedule.setStatus(IcgProcessStatusEnum.PENDING.getCode());
+                    fsCouponSchedule.setOrderTime(LocalDateTime.now());
+
+                    // 如果上次发送时间为空,那么预计发送时间等于=下单时间+1月
+                    fsCouponSchedule.setSendTime(fsCouponSchedule.getOrderTime().plusMonths(1L));
+                    fsCouponSchedule.setRetryCount(0);
+
+                    fsCouponScheduleService.insertFsCouponSchedule(fsCouponSchedule);
+                }
             }
             //非处方直接提交OMS
             try {

+ 5 - 9
fs-service-system/src/main/java/com/fs/store/service/impl/FsStorePaymentServiceImpl.java

@@ -1,35 +1,30 @@
 package com.fs.store.service.impl;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.TimeUnit;
 
 import cn.hutool.core.util.IdUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.annotation.DataScope;
-import com.fs.common.config.FSConfig;
 import com.fs.common.config.FSSysConfig;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
-import com.fs.common.utils.IPUtils;
-import com.fs.common.utils.ServletUtils;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.huifuPay.domain.HuiFuCreateOrder;
 import com.fs.huifuPay.domain.HuifuCreateOrderResult;
 import com.fs.huifuPay.service.HuiFuService;
-import com.fs.pay.pay.config.PayConfig;
 import com.fs.pay.pay.domain.CreateWxOrderResult;
 import com.fs.pay.pay.dto.WxJspayDTO;
 import com.fs.pay.pay.service.PayService;
 import com.fs.store.domain.FsPayConfig;
 import com.fs.store.param.FsStoreStatisticsParam;
+import com.fs.store.service.IFsCouponScheduleService;
 import com.fs.store.vo.FsStorePaymentStatisticsVO;
 import com.fs.system.service.ISysConfigService;
 import com.fs.wx.miniapp.config.WxMaProperties;
@@ -40,9 +35,6 @@ import com.fs.store.param.FsStorePaymentParam;
 import com.fs.store.service.IFsUserService;
 import com.fs.store.vo.FsStorePaymentVO;
 import com.fs.pay.service.IPayService;
-import com.fs.pay.service.dto.CreatePayDTO;
-import com.fs.pay.service.dto.PayDTO;
-import com.fs.pay.service.dto.TradeOrder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -85,6 +77,8 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService
     private ISysConfigService configService;
     @Autowired
     HuiFuService huiFuService;
+    @Autowired
+    IFsCouponScheduleService fsCouponScheduleService;
     /**
      * 查询支付明细
      *
@@ -346,6 +340,8 @@ public class FsStorePaymentServiceImpl implements IFsStorePaymentService
         if(payment.getCompanyId()!=null&&payment.getCompanyId()>0){
             companyService.subCompanyPaymentMoney(payment);
         }
+        // 退款将定时发放优惠券的状态设置为已退款
+        fsCouponScheduleService.setScheduleCouponRefund(orderCode);
         return "success";
     }
 

+ 20 - 0
fs-service-system/src/main/resources/mapper/store/FsCouponScheduleLogMapper.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.store.mapper.FsCouponScheduleLogMapper">
+
+    <!-- 其他映射配置... -->
+
+    <insert id="batchInsert" parameterType="java.util.List">
+        INSERT INTO fs_coupon_schedule_log (schedule_id, user_id, order_id, status_before, status_after,
+        send_time_before, send_time_after, actual_send_time, error_message, retry_count_before,
+        retry_count_after, operation_type, operation_time, operator, remark)
+        VALUES
+        <foreach collection="logs" item="log" separator=",">
+            (#{log.scheduleId}, #{log.userId}, #{log.orderId}, #{log.statusBefore}, #{log.statusAfter},
+            #{log.sendTimeBefore}, #{log.sendTimeAfter}, #{log.actualSendTime}, #{log.errorMessage},
+            #{log.retryCountBefore}, #{log.retryCountAfter}, #{log.operationType}, #{log.operationTime},
+            #{log.operator}, #{log.remark})
+        </foreach>
+    </insert>
+
+</mapper>

+ 37 - 21
fs-service-system/src/main/resources/mapper/store/FsCouponScheduleMapper.xml

@@ -17,20 +17,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="updateTime"    column="update_time"    />
         <result property="updateBy"    column="update_by"    />
         <result property="orderTime"    column="order_time"    />
-        <result property="couponId"    column="coupon_id"    />
-        <result property="couponBatchId"    column="coupon_batch_id"    />
+        <result property="couponIds"    column="coupon_id"    />
         <result property="sendTime"    column="send_time"    />
         <result property="actualSendTime"    column="actual_send_time"    />
         <result property="errorMessage"    column="error_message"    />
         <result property="retryCount"    column="retry_count"    />
         <result property="maxRetries"    column="max_retries"    />
-        <result property="nextRetryTime"    column="next_retry_time"    />
-        <result property="sourceType"    column="source_type"    />
         <result property="remark"    column="remark"    />
     </resultMap>
 
     <sql id="selectFsCouponScheduleVo">
-        select id, user_id, order_id, setmeal_id, month, count, status, create_time, create_by, update_time, update_by, order_time, execute_time, coupon_id, coupon_batch_id, send_time, actual_send_time, error_message, retry_count, max_retries, next_retry_time, source_type, remark from fs_coupon_schedule
+        select id, user_id, order_id, setmeal_id, month, count, status, create_time, create_by, update_time, update_by, order_time, coupon_id, send_time, actual_send_time, error_message, retry_count, max_retries,  remark from fs_coupon_schedule
     </sql>
 
     <select id="selectFsCouponScheduleList" parameterType="FsCouponSchedule" resultMap="FsCouponScheduleResult">
@@ -43,15 +40,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="count != null "> and count = #{count}</if>
             <if test="status != null "> and status = #{status}</if>
             <if test="orderTime != null "> and order_time = #{orderTime}</if>
-            <if test="couponId != null "> and coupon_id = #{couponId}</if>
-            <if test="couponBatchId != null "> and coupon_batch_id = #{couponBatchId}</if>
+            <if test="couponIds != null "> and coupon_id = #{couponIds}</if>
             <if test="sendTime != null "> and send_time = #{sendTime}</if>
             <if test="actualSendTime != null "> and actual_send_time = #{actualSendTime}</if>
             <if test="errorMessage != null  and errorMessage != ''"> and error_message = #{errorMessage}</if>
             <if test="retryCount != null "> and retry_count = #{retryCount}</if>
             <if test="maxRetries != null "> and max_retries = #{maxRetries}</if>
-            <if test="nextRetryTime != null "> and next_retry_time = #{nextRetryTime}</if>
-            <if test="sourceType != null  and sourceType != ''"> and source_type = #{sourceType}</if>
         </where>
     </select>
 
@@ -63,6 +57,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <select id="selectPendingCouponList" resultType="com.fs.store.domain.FsCouponSchedule">
         <include refid="selectFsCouponScheduleVo"/>
         where status in (0,-1) and retry_count &lt; 3 and count &lt; month
+        limit 500
+    </select>
+    <select id="selectFsCouponScheduleByOrderId" resultType="com.fs.store.domain.FsCouponSchedule">
+        <include refid="selectFsCouponScheduleVo"/>
+        where order_id = #{orderId} limit 1
     </select>
 
     <insert id="insertFsCouponSchedule" parameterType="FsCouponSchedule" useGeneratedKeys="true" keyProperty="id">
@@ -79,15 +78,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateTime != null">update_time,</if>
             <if test="updateBy != null">update_by,</if>
             <if test="orderTime != null">order_time,</if>
-            <if test="couponId != null">coupon_id,</if>
-            <if test="couponBatchId != null">coupon_batch_id,</if>
+            <if test="couponIds != null">coupon_id,</if>
             <if test="sendTime != null">send_time,</if>
             <if test="actualSendTime != null">actual_send_time,</if>
             <if test="errorMessage != null">error_message,</if>
             <if test="retryCount != null">retry_count,</if>
             <if test="maxRetries != null">max_retries,</if>
-            <if test="nextRetryTime != null">next_retry_time,</if>
-            <if test="sourceType != null">source_type,</if>
             <if test="remark != null">remark,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
@@ -102,15 +98,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateTime != null">#{updateTime},</if>
             <if test="updateBy != null">#{updateBy},</if>
             <if test="orderTime != null">#{orderTime},</if>
-            <if test="couponId != null">#{couponId},</if>
-            <if test="couponBatchId != null">#{couponBatchId},</if>
+            <if test="couponIds != null">#{couponIds},</if>
             <if test="sendTime != null">#{sendTime},</if>
             <if test="actualSendTime != null">#{actualSendTime},</if>
             <if test="errorMessage != null">#{errorMessage},</if>
             <if test="retryCount != null">#{retryCount},</if>
             <if test="maxRetries != null">#{maxRetries},</if>
-            <if test="nextRetryTime != null">#{nextRetryTime},</if>
-            <if test="sourceType != null">#{sourceType},</if>
             <if test="remark != null">#{remark},</if>
          </trim>
     </insert>
@@ -129,19 +122,42 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateTime != null">update_time = #{updateTime},</if>
             <if test="updateBy != null">update_by = #{updateBy},</if>
             <if test="orderTime != null">order_time = #{orderTime},</if>
-            <if test="couponId != null">coupon_id = #{couponId},</if>
-            <if test="couponBatchId != null">coupon_batch_id = #{couponBatchId},</if>
+            <if test="couponIds != null">coupon_id = #{couponIds},</if>
             <if test="sendTime != null">send_time = #{sendTime},</if>
             <if test="actualSendTime != null">actual_send_time = #{actualSendTime},</if>
             <if test="errorMessage != null">error_message = #{errorMessage},</if>
             <if test="retryCount != null">retry_count = #{retryCount},</if>
             <if test="maxRetries != null">max_retries = #{maxRetries},</if>
-            <if test="nextRetryTime != null">next_retry_time = #{nextRetryTime},</if>
-            <if test="sourceType != null">source_type = #{sourceType},</if>
             <if test="remark != null">remark = #{remark},</if>
         </trim>
         where id = #{id}
     </update>
+    <update id="updateBatchFsCouponSchedule">
+        <foreach collection="list" separator=";" item="item">
+            update fs_coupon_schedule
+            <trim prefix="SET" suffixOverrides=",">
+                <if test="userId != null">user_id = #{item.userId},</if>
+                <if test="orderId != null and orderId != ''">order_id = #{item.orderId},</if>
+                <if test="setmealId != null">setmeal_id = #{item.setmealId},</if>
+                <if test="month != null">month = #{item.month},</if>
+                <if test="count != null">count = #{item.count},</if>
+                <if test="status != null">status = #{item.status},</if>
+                <if test="createTime != null">create_time = #{item.createTime},</if>
+                <if test="createBy != null">create_by = #{item.createBy},</if>
+                <if test="updateTime != null">update_time = #{item.updateTime},</if>
+                <if test="updateBy != null">update_by = #{item.updateBy},</if>
+                <if test="orderTime != null">order_time = #{item.orderTime},</if>
+                <if test="couponIds != null">coupon_id = #{item.couponIds},</if>
+                <if test="sendTime != null">send_time = #{item.sendTime},</if>
+                <if test="actualSendTime != null">actual_send_time = #{item.actualSendTime},</if>
+                <if test="errorMessage != null">error_message = #{item.errorMessage},</if>
+                <if test="retryCount != null">retry_count = #{item.retryCount},</if>
+                <if test="maxRetries != null">max_retries = #{item.maxRetries},</if>
+                <if test="remark != null">remark = #{item.remark},</if>
+            </trim>
+            where id = #{id}
+        </foreach>
+    </update>
 
     <delete id="deleteFsCouponScheduleById" parameterType="Long">
         delete from fs_coupon_schedule where id = #{id}

+ 1 - 0
fs-user-app/src/main/java/com/fs/app/controller/CouponController.java

@@ -104,6 +104,7 @@ public class CouponController extends  AppBaseController {
         FsStoreCouponIssueVO couponIssue=fsStoreCouponIssueService.selectFsStoreCouponIssueVOById(id);
         return R.ok().put("data",couponIssue).put("code",code);
     }
+
     @Login
     @ApiOperation("领取")
     @PostMapping("/companyReceive")