Quellcode durchsuchen

feat(coupon): 重构优惠券模块并新增核心功能

- 新增优惠券计算服务类 CouponCalculationService
- 新增优惠券相关枚举类 CouponEnums 包含状态、类型等枚举
- 新增优惠券业务异常类 CouponException
- 新增优惠券过期定时任务 CouponExpireJob
- 重构优惠券实体类字段,增加 couponCode、expireTime 等属性
- 移除优惠券实体中不再使用的字段如 usePrice、discountPrice 等
- 更新优惠券表单对象字段定义及校验规则
- 修改优惠券模板实体支持 BigDecimal 类型金额计算
- 新增优惠券领取、使用、过期处理等核心业务方法
- 实现用户优惠券状态查询及模板关联查询功能
- 调整优惠券 Mapper XML 映射文件字段配置
- 更新相关时间字段命名以提高语义清晰度
- 移除逻辑删除和版本控制注解及相关字段
- 优化优惠券模板查询对象结构
wzq vor 1 Tag
Ursprung
Commit
99ef4e0fea
33 geänderte Dateien mit 967 neuen und 162 gelöschten Zeilen
  1. 1 1
      src/main/java/com/zsElectric/boot/business/controller/CouponController.java
  2. 1 0
      src/main/java/com/zsElectric/boot/business/controller/applet/AppletUserController.java
  3. 1 1
      src/main/java/com/zsElectric/boot/business/converter/CouponConverter.java
  4. 1 1
      src/main/java/com/zsElectric/boot/business/converter/CouponTemplateConverter.java
  5. 1 1
      src/main/java/com/zsElectric/boot/business/converter/UserRefundsOrderInfoConverter.java
  6. 1 1
      src/main/java/com/zsElectric/boot/business/mapper/CouponMapper.java
  7. 2 3
      src/main/java/com/zsElectric/boot/business/mapper/CouponTemplateMapper.java
  8. 1 1
      src/main/java/com/zsElectric/boot/business/mapper/UserRefundsOrderInfoMapper.java
  9. 18 20
      src/main/java/com/zsElectric/boot/business/model/entity/Coupon.java
  10. 15 9
      src/main/java/com/zsElectric/boot/business/model/entity/CouponTemplate.java
  11. 1 1
      src/main/java/com/zsElectric/boot/business/model/entity/UserRefundsOrderInfo.java
  12. 17 24
      src/main/java/com/zsElectric/boot/business/model/form/CouponForm.java
  13. 15 14
      src/main/java/com/zsElectric/boot/business/model/form/CouponTemplateForm.java
  14. 1 1
      src/main/java/com/zsElectric/boot/business/model/query/CouponQuery.java
  15. 2 17
      src/main/java/com/zsElectric/boot/business/model/query/CouponTemplateQuery.java
  16. 11 6
      src/main/java/com/zsElectric/boot/business/model/vo/CouponTemplateVO.java
  17. 11 13
      src/main/java/com/zsElectric/boot/business/model/vo/CouponVO.java
  18. 2 0
      src/main/java/com/zsElectric/boot/business/model/vo/UserInfoVO.java
  19. 62 0
      src/main/java/com/zsElectric/boot/business/quartz/CouponExpireJob.java
  20. 24 0
      src/main/java/com/zsElectric/boot/business/service/CouponCalculationService.java
  21. 57 1
      src/main/java/com/zsElectric/boot/business/service/CouponService.java
  22. 35 1
      src/main/java/com/zsElectric/boot/business/service/CouponTemplateService.java
  23. 73 0
      src/main/java/com/zsElectric/boot/business/service/CouponUsageService.java
  24. 1 1
      src/main/java/com/zsElectric/boot/business/service/UserRefundsOrderInfoService.java
  25. 320 6
      src/main/java/com/zsElectric/boot/business/service/impl/CouponServiceImpl.java
  26. 87 1
      src/main/java/com/zsElectric/boot/business/service/impl/CouponTemplateServiceImpl.java
  27. 1 1
      src/main/java/com/zsElectric/boot/business/service/impl/UserOrderInfoServiceImpl.java
  28. 1 1
      src/main/java/com/zsElectric/boot/business/service/impl/UserRefundsOrderInfoServiceImpl.java
  29. 144 0
      src/main/java/com/zsElectric/boot/common/enums/CouponEnums.java
  30. 18 0
      src/main/java/com/zsElectric/boot/core/exception/CouponException.java
  31. 4 4
      src/main/resources/mapper/business/CouponMapper.xml
  32. 21 19
      src/main/resources/mapper/business/CouponTemplateMapper.xml
  33. 17 13
      src/main/resources/mapper/business/UserInfoMapper.xml

+ 1 - 1
src/main/java/com/zsElectric/boot/business/controller/CouponController.java

@@ -22,7 +22,7 @@ import jakarta.validation.Valid;
  * 优惠劵前端控制层
  *
  * @author zsElectric
- * @since 2025-12-15 09:38
+ * @since 2025-12-19 09:58
  */
 @Tag(name = "优惠劵接口")
 @RestController

+ 1 - 0
src/main/java/com/zsElectric/boot/business/controller/applet/AppletUserController.java

@@ -40,6 +40,7 @@ public class AppletUserController {
     public Result<Void> addUserFeedback(@RequestBody @Valid AppFeedbackForm formData ) {
         UserFeedbackForm userFeedbackForm = new UserFeedbackForm();
         userFeedbackForm.setType(formData.getType());
+        userFeedbackForm.setUserId(SecurityUtils.getUserId());
         userFeedbackForm.setDescription(formData.getDescription());
         userFeedbackForm.setImages(formData.getImages());
         userFeedbackForm.setContactWay(formData.getContactWay());

+ 1 - 1
src/main/java/com/zsElectric/boot/business/converter/CouponConverter.java

@@ -9,7 +9,7 @@ import com.zsElectric.boot.business.model.form.CouponForm;
  * 优惠劵对象转换器
  *
  * @author zsElectric
- * @since 2025-12-15 09:38
+ * @since 2025-12-19 09:58
  */
 @Mapper(componentModel = "spring")
 public interface CouponConverter{

+ 1 - 1
src/main/java/com/zsElectric/boot/business/converter/CouponTemplateConverter.java

@@ -9,7 +9,7 @@ import com.zsElectric.boot.business.model.form.CouponTemplateForm;
  * 优惠劵模板对象转换器
  *
  * @author zsElectric
- * @since 2025-12-15 11:14
+ * @since 2025-12-19 10:10
  */
 @Mapper(componentModel = "spring")
 public interface CouponTemplateConverter{

+ 1 - 1
src/main/java/com/zsElectric/boot/business/converter/UserRefundsOrderInfoConverter.java

@@ -1,7 +1,7 @@
 package com.zsElectric.boot.business.converter;
 
 import org.mapstruct.Mapper;
-import com.zsElectric.boot.business.UserRefundsOrderInfo;
+import com.zsElectric.boot.business.model.entity.UserRefundsOrderInfo;
 import com.zsElectric.boot.business.model.form.UserRefundsOrderInfoForm;
 
 /**

+ 1 - 1
src/main/java/com/zsElectric/boot/business/mapper/CouponMapper.java

@@ -11,7 +11,7 @@ import org.apache.ibatis.annotations.Mapper;
  * 优惠劵Mapper接口
  *
  * @author zsElectric
- * @since 2025-12-15 09:38
+ * @since 2025-12-19 09:58
  */
 @Mapper
 public interface CouponMapper extends BaseMapper<Coupon> {

+ 2 - 3
src/main/java/com/zsElectric/boot/business/mapper/CouponTemplateMapper.java

@@ -6,13 +6,12 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.zsElectric.boot.business.model.query.CouponTemplateQuery;
 import com.zsElectric.boot.business.model.vo.CouponTemplateVO;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
 
 /**
  * 优惠劵模板Mapper接口
  *
  * @author zsElectric
- * @since 2025-12-15 11:14
+ * @since 2025-12-19 10:10
  */
 @Mapper
 public interface CouponTemplateMapper extends BaseMapper<CouponTemplate> {
@@ -24,6 +23,6 @@ public interface CouponTemplateMapper extends BaseMapper<CouponTemplate> {
      * @param queryParams 查询参数
      * @return {@link Page<CouponTemplateVO>} 优惠劵模板分页列表
      */
-    Page<CouponTemplateVO> getCouponTemplatePage(Page<CouponTemplateVO> page,@Param("queryParams") CouponTemplateQuery queryParams);
+    Page<CouponTemplateVO> getCouponTemplatePage(Page<CouponTemplateVO> page, CouponTemplateQuery queryParams);
 
 }

+ 1 - 1
src/main/java/com/zsElectric/boot/business/mapper/UserRefundsOrderInfoMapper.java

@@ -1,7 +1,7 @@
 package com.zsElectric.boot.business.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.zsElectric.boot.business.UserRefundsOrderInfo;
+import com.zsElectric.boot.business.model.entity.UserRefundsOrderInfo;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.zsElectric.boot.business.model.query.UserRefundsOrderInfoQuery;
 import com.zsElectric.boot.business.model.vo.UserRefundsOrderInfoVO;

+ 18 - 20
src/main/java/com/zsElectric/boot/business/model/entity/Coupon.java

@@ -1,6 +1,5 @@
 package com.zsElectric.boot.business.model.entity;
 
-import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.zsElectric.boot.common.base.BaseEntity;
 import lombok.Getter;
 import lombok.Setter;
@@ -12,7 +11,7 @@ import java.time.LocalDateTime;
  * 优惠劵实体对象
  *
  * @author zsElectric
- * @since 2025-12-15 09:38
+ * @since 2025-12-19 09:58
  */
 @Getter
 @Setter
@@ -29,35 +28,39 @@ public class Coupon extends BaseEntity {
      * 优惠劵名
      */
     private String name;
+    /**
+     * 优惠券编码
+     */
+    private String couponCode;
     /**
      * 优惠码状态
- * 1-未使用
-  * 2-已使用
- * 3-已失效
+ 1-未使用
+  2-已使用
+ 3-已过期
      */
     private Integer status;
+    /**
+     * 优惠劵描述
+     */
+    private String description;
     /**
      * 用户编号
      */
     private Long userId;
     /**
      * 领取类型
- (1-用户主动领取
-  2-后台自动发放)
+ (1-用户领取
+  2-后台发放)
      */
     private Integer takeType;
     /**
-     * 设置满多少金额可用,单位:分
+     * 领取时间
      */
-    private Integer usePrice;
+    private LocalDateTime takeTime;
     /**
-     * 生效结束时间
+     * 过期时间
      */
-    private LocalDateTime validEndTime;
-    /**
-     * 优惠金额,单位:分
-     */
-    private Integer discountPrice;
+    private LocalDateTime expireTime;
     /**
      * 使用订单号
      */
@@ -66,10 +69,6 @@ public class Coupon extends BaseEntity {
      * 使用时间
      */
     private LocalDateTime useTime;
-    /**
-     * 优惠劵描述
-     */
-    private String description;
     /**
      * 创建者
      */
@@ -81,6 +80,5 @@ public class Coupon extends BaseEntity {
     /**
      * 逻辑删除(0-未删除 1-已删除)
      */
-    @TableLogic
     private Integer isDeleted;
 }

+ 15 - 9
src/main/java/com/zsElectric/boot/business/model/entity/CouponTemplate.java

@@ -1,17 +1,17 @@
 package com.zsElectric.boot.business.model.entity;
 
-import com.baomidou.mybatisplus.annotation.TableLogic;
-import com.baomidou.mybatisplus.annotation.Version;
 import com.zsElectric.boot.common.base.BaseEntity;
 import lombok.Getter;
 import lombok.Setter;
 import com.baomidou.mybatisplus.annotation.TableName;
 
+import java.math.BigDecimal;
+
 /**
  * 优惠劵模板实体对象
  *
  * @author zsElectric
- * @since 2025-12-15 11:14
+ * @since 2025-12-19 10:10
  */
 @Getter
 @Setter
@@ -20,10 +20,18 @@ public class CouponTemplate extends BaseEntity {
 
     private static final long serialVersionUID = 1L;
 
+    /**
+     * 优惠券码
+     */
+    private String code;
     /**
      * 优惠劵名
      */
     private String name;
+    /**
+     * 类型:1(折扣)、2(满减)、3(无门槛)
+     */
+    private Integer type;
     /**
      * 优惠劵描述
      */
@@ -41,13 +49,13 @@ public class CouponTemplate extends BaseEntity {
      */
     private Integer failureTime;
     /**
-     * 设置满多少金额可用,单位:分
+     * 满减门槛 (设置满多少金额可用,单位:元)
      */
-    private Integer usePrice;
+    private BigDecimal usePrice;
     /**
-     * 优惠金额,单位:分
+     * 优惠值(折扣率/减额)
      */
-    private Integer discountPrice;
+    private BigDecimal discountPrice;
     /**
      * 领取时间:周  星期一 1  2  3 4 5 6 7
      */
@@ -75,11 +83,9 @@ public class CouponTemplate extends BaseEntity {
     /**
      * 乐观锁
      */
-    @Version
     private Integer version;
     /**
      * 逻辑删除(0-未删除 1-已删除)
      */
-    @TableLogic
     private Integer isDeleted;
 }

+ 1 - 1
src/main/java/com/zsElectric/boot/business/UserRefundsOrderInfo.java → src/main/java/com/zsElectric/boot/business/model/entity/UserRefundsOrderInfo.java

@@ -1,4 +1,4 @@
-package com.zsElectric.boot.business;
+package com.zsElectric.boot.business.model.entity;
 
 import com.zsElectric.boot.common.base.BaseEntity;
 import lombok.Getter;

+ 17 - 24
src/main/java/com/zsElectric/boot/business/model/form/CouponForm.java

@@ -2,8 +2,6 @@ package com.zsElectric.boot.business.model.form;
 
 import java.io.Serial;
 import java.io.Serializable;
-
-import com.baomidou.mybatisplus.annotation.TableLogic;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
 import lombok.Setter;
@@ -15,7 +13,7 @@ import jakarta.validation.constraints.*;
  * 优惠劵表单对象
  *
  * @author zsElectric
- * @since 2025-12-15 09:38
+ * @since 2025-12-19 09:58
  */
 @Getter
 @Setter
@@ -25,40 +23,40 @@ public class CouponForm implements Serializable {
     @Serial
     private static final long serialVersionUID = 1L;
 
-    @Schema(description = "优惠劵编号")
-    @NotNull(message = "优惠劵编号不能为空")
+    @Schema(description = "主键ID")
     private Long id;
 
     @Schema(description = "优惠劵模板编号")
-    @NotNull(message = "优惠劵模板编号不能为空")
     private Long templateId;
 
     @Schema(description = "优惠劵名")
     @Size(max=50, message="优惠劵名长度不能超过50个字符")
     private String name;
 
-    @Schema(description = "优惠码状态1-未使用2-已使用3-已失效")
+    @Schema(description = "优惠券编码")
+    @Size(max=64, message="优惠券编码长度不能超过64个字符")
+    private String couponCode;
+
+    @Schema(description = "优惠码状态1-未使用 2-已使用 3-已过期")
     private Integer status;
 
+    @Schema(description = "优惠劵描述")
+    @Size(max=512, message="优惠劵描述长度不能超过512个字符")
+    private String description;
+
     @Schema(description = "用户编号")
-    @NotNull(message = "用户编号不能为空")
     private Long userId;
 
-    @Schema(description = "领取类型(1-用户主动领取2-后台自动发放)")
+    @Schema(description = "领取类型(1-用户领取 2-后台发放)")
     private Integer takeType;
 
-    @Schema(description = "设置满多少金额可用,单位:分")
-    @NotNull(message = "设置满多少金额可用,单位:分不能为空")
-    private Integer usePrice;
-
-    @Schema(description = "生效结束时间")
-    @NotNull(message = "生效结束时间不能为空")
+    @Schema(description = "领取时间")
     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
-    private LocalDateTime validEndTime;
+    private LocalDateTime takeTime;
 
-    @Schema(description = "优惠金额,单位:分")
-    @NotNull(message = "优惠金额,单位:分不能为空")
-    private Integer discountPrice;
+    @Schema(description = "过期时间")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime expireTime;
 
     @Schema(description = "使用订单号")
     private Long useOrderId;
@@ -67,10 +65,6 @@ public class CouponForm implements Serializable {
     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime useTime;
 
-    @Schema(description = "优惠劵描述")
-    @Size(max=512, message="优惠劵描述长度不能超过512个字符")
-    private String description;
-
     @Schema(description = "创建者")
     private Long createBy;
 
@@ -86,7 +80,6 @@ public class CouponForm implements Serializable {
     private LocalDateTime updateTime;
 
     @Schema(description = "逻辑删除(0-未删除 1-已删除)")
-    @TableLogic
     private Integer isDeleted;
 
 

+ 15 - 14
src/main/java/com/zsElectric/boot/business/model/form/CouponTemplateForm.java

@@ -7,13 +7,14 @@ import lombok.Getter;
 import lombok.Setter;
 import java.time.LocalDateTime;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import java.math.BigDecimal;
 import jakarta.validation.constraints.*;
 
 /**
  * 优惠劵模板表单对象
  *
  * @author zsElectric
- * @since 2025-12-15 11:14
+ * @since 2025-12-19 10:10
  */
 @Getter
 @Setter
@@ -23,45 +24,45 @@ public class CouponTemplateForm implements Serializable {
     @Serial
     private static final long serialVersionUID = 1L;
 
-    @Schema(description = "模板编号,自增唯一。")
-    @NotNull(message = "模板编号,自增唯一。不能为空")
+    @Schema(description = "主键ID")
+    @NotNull(message = "主键ID不能为空")
     private Long id;
 
+    @Schema(description = "优惠券码")
+    @Size(max=255, message="优惠券码长度不能超过255个字符")
+    private String code;
+
     @Schema(description = "优惠劵名")
     @Size(max=50, message="优惠劵名长度不能超过50个字符")
     private String name;
 
+    @Schema(description = "类型:1(折扣)、2(满减)、3(无门槛)")
+    private Integer type;
+
     @Schema(description = "优惠劵描述")
     @Size(max=512, message="优惠劵描述长度不能超过512个字符")
     private String description;
 
     @Schema(description = "状态  1.上线 2.下线")
-    @NotNull(message = "状态  1.上线 2.下线不能为空")
     private Integer status;
 
     @Schema(description = "发放数量, -1 - 则表示不限制")
-    @NotNull(message = "发放数量, -1 - 则表示不限制不能为空")
     private Integer totalCount;
 
     @Schema(description = "失效时间,领取后的几天。")
-    @NotNull(message = "失效时间,领取后的几天。不能为空")
     private Integer failureTime;
 
-    @Schema(description = "设置满多少金额可用,单位:分")
-    @NotNull(message = "设置满多少金额可用,单位:分不能为空")
-    private Integer usePrice;
+    @Schema(description = "满减门槛 (设置满多少金额可用,单位:元)")
+    private BigDecimal usePrice;
 
-    @Schema(description = "优惠金额,单位:分")
-    @NotNull(message = "优惠金额,单位:分不能为空")
-    private Integer discountPrice;
+    @Schema(description = "优惠值(折扣率/减额)")
+    private BigDecimal discountPrice;
 
     @Schema(description = "领取时间:周  星期一 1  2  3 4 5 6 7")
-    @NotBlank(message = "领取时间:周  星期一 1  2  3 4 5 6 7不能为空")
     @Size(max=50, message="领取时间:周  星期一 1  2  3 4 5 6 7长度不能超过50个字符")
     private String validTimeWeeks;
 
     @Schema(description = "领取时间 时分  08:20")
-    @NotBlank(message = "领取时间 时分  08:20不能为空")
     @Size(max=50, message="领取时间 时分  08:20长度不能超过50个字符")
     private String validTimeHour;
 

+ 1 - 1
src/main/java/com/zsElectric/boot/business/model/query/CouponQuery.java

@@ -11,7 +11,7 @@ import java.util.List;
  * 优惠劵分页查询对象
  *
  * @author zsElectric
- * @since 2025-12-15 09:38
+ * @since 2025-12-19 09:58
  */
 @Schema(description ="优惠劵查询对象")
 @Getter

+ 2 - 17
src/main/java/com/zsElectric/boot/business/model/query/CouponTemplateQuery.java

@@ -4,34 +4,19 @@ import com.zsElectric.boot.common.base.BasePageQuery;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
 import lombok.Setter;
-import org.springframework.format.annotation.DateTimeFormat;
-
 import java.time.LocalDateTime;
 import java.util.List;
+import java.math.BigDecimal;
 
 /**
  * 优惠劵模板分页查询对象
  *
  * @author zsElectric
- * @since 2025-12-15 11:14
+ * @since 2025-12-19 10:10
  */
 @Schema(description ="优惠劵模板查询对象")
 @Getter
 @Setter
 public class CouponTemplateQuery extends BasePageQuery {
 
-    @Schema(description = "优惠劵模板名称")
-    private String name;
-
-    @Schema(description = "优惠劵模板状态")
-    private Integer status;
-
-    @Schema(description = "开始时间")
-    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    private LocalDateTime startTime;
-
-    @Schema(description = "结束时间")
-    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    private LocalDateTime endTime;
-
 }

+ 11 - 6
src/main/java/com/zsElectric/boot/business/model/vo/CouponTemplateVO.java

@@ -7,12 +7,13 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
 import lombok.Setter;
 import java.time.LocalDateTime;
+import java.math.BigDecimal;
 
 /**
  * 优惠劵模板视图对象
  *
  * @author zsElectric
- * @since 2025-12-15 11:14
+ * @since 2025-12-19 10:10
  */
 @Getter
 @Setter
@@ -22,10 +23,14 @@ public class CouponTemplateVO implements Serializable {
     @Serial
     private static final long serialVersionUID = 1L;
 
-    @Schema(description = "模板编号,自增唯一。")
+    @Schema(description = "主键ID")
     private Long id;
+    @Schema(description = "优惠券码")
+    private String code;
     @Schema(description = "优惠劵名")
     private String name;
+    @Schema(description = "类型:1(折扣)、2(满减)、3(无门槛)")
+    private Integer type;
     @Schema(description = "优惠劵描述")
     private String description;
     @Schema(description = "状态  1.上线 2.下线")
@@ -34,10 +39,10 @@ public class CouponTemplateVO implements Serializable {
     private Integer totalCount;
     @Schema(description = "失效时间,领取后的几天。")
     private Integer failureTime;
-    @Schema(description = "设置满多少金额可用,单位:分")
-    private Integer usePrice;
-    @Schema(description = "优惠金额,单位:分")
-    private Integer discountPrice;
+    @Schema(description = "满减门槛 (设置满多少金额可用,单位:元)")
+    private BigDecimal usePrice;
+    @Schema(description = "优惠值(折扣率/减额)")
+    private BigDecimal discountPrice;
     @Schema(description = "领取时间:周  星期一 1  2  3 4 5 6 7")
     private String validTimeWeeks;
     @Schema(description = "领取时间 时分  08:20")

+ 11 - 13
src/main/java/com/zsElectric/boot/business/model/vo/CouponVO.java

@@ -3,8 +3,6 @@ package com.zsElectric.boot.business.model.vo;
 import java.io.Serial;
 import java.io.Serializable;
 import java.time.LocalDateTime;
-
-import com.baomidou.mybatisplus.annotation.TableLogic;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
 import lombok.Setter;
@@ -14,7 +12,7 @@ import java.time.LocalDateTime;
  * 优惠劵视图对象
  *
  * @author zsElectric
- * @since 2025-12-15 09:38
+ * @since 2025-12-19 09:58
  */
 @Getter
 @Setter
@@ -30,24 +28,24 @@ public class CouponVO implements Serializable {
     private Long templateId;
     @Schema(description = "优惠劵名")
     private String name;
-    @Schema(description = "优惠码状态1-未使用2-已使用3-已失效")
+    @Schema(description = "优惠券编码")
+    private String couponCode;
+    @Schema(description = "优惠码状态 1-未使用2-已使用3-已过期")
     private Integer status;
+    @Schema(description = "优惠劵描述")
+    private String description;
     @Schema(description = "用户编号")
     private Long userId;
-    @Schema(description = "领取类型(1-用户主动领取 2-后台自动发放)")
+    @Schema(description = "领取类型(1-用户领取 2-后台发放)")
     private Integer takeType;
-    @Schema(description = "设置满多少金额可用,单位:分")
-    private Integer usePrice;
-    @Schema(description = "生效结束时间")
-    private LocalDateTime validEndTime;
-    @Schema(description = "优惠金额,单位:分")
-    private Integer discountPrice;
+    @Schema(description = "领取时间")
+    private LocalDateTime takeTime;
+    @Schema(description = "过期时间")
+    private LocalDateTime expireTime;
     @Schema(description = "使用订单号")
     private Long useOrderId;
     @Schema(description = "使用时间")
     private LocalDateTime useTime;
-    @Schema(description = "优惠劵描述")
-    private String description;
     @Schema(description = "创建者")
     private Long createBy;
     @Schema(description = "创建时间")

+ 2 - 0
src/main/java/com/zsElectric/boot/business/model/vo/UserInfoVO.java

@@ -29,6 +29,8 @@ public class UserInfoVO implements Serializable {
     private Long ecId;
     @Schema(description = "昵称")
     private String nickName;
+    @Schema(description = "所属企业")
+    private String firmName;
     @Schema(description = "手机号")
     private String phone;
     @Schema(description = "微信openid")

+ 62 - 0
src/main/java/com/zsElectric/boot/business/quartz/CouponExpireJob.java

@@ -0,0 +1,62 @@
+package com.zsElectric.boot.business.quartz;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.zsElectric.boot.business.model.entity.Coupon;
+import com.zsElectric.boot.business.service.CouponService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 优惠券过期定时任务
+ * 定时检查并处理过期的优惠券
+ *
+ * @author zsElectric
+ * @since 2025-12-19
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class CouponExpireJob {
+
+    private final CouponService couponService;
+
+    /**
+     * 每天凌晨2点执行一次
+     * 检查并处理过期的优惠券
+     */
+    @Scheduled(cron = "0 0 2 * * ?")
+    public void processExpiredCoupons() {
+        log.info("开始执行优惠券过期处理任务");
+
+        try {
+            // 查询所有未使用且已过期的优惠券
+            List<Coupon> expiredCoupons = couponService.list(
+                    Wrappers.lambdaQuery(Coupon.class)
+                            .eq(Coupon::getStatus, 1) // 未使用状态
+                            .lt(Coupon::getExpireTime, LocalDateTime.now()) // 已过期
+            );
+
+            int successCount = 0;
+            for (Coupon coupon : expiredCoupons) {
+                try {
+                    // 更新优惠券状态为已过期
+                    coupon.setStatus(3); // 已过期
+                    if (couponService.updateById(coupon)) {
+                        successCount++;
+                    }
+                } catch (Exception e) {
+                    log.error("处理优惠券[ID:{}]过期状态失败", coupon.getId(), e);
+                }
+            }
+
+            log.info("优惠券过期处理任务执行完成,共处理{}张过期优惠券", successCount);
+        } catch (Exception e) {
+            log.error("执行优惠券过期处理任务失败", e);
+        }
+    }
+}

+ 24 - 0
src/main/java/com/zsElectric/boot/business/service/CouponCalculationService.java

@@ -0,0 +1,24 @@
+package com.zsElectric.boot.business.service;
+
+import com.zsElectric.boot.business.model.entity.Coupon;
+import com.zsElectric.boot.business.model.entity.CouponTemplate;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+
+/**
+ * 优惠券计算服务类
+ * 负责计算优惠券的优惠金额
+ *
+ * @author zsElectric
+ * @since 2025-12-19
+ */
+@Service
+@RequiredArgsConstructor
+public class CouponCalculationService {
+
+    private final CouponTemplateService couponTemplateService;
+
+
+}

+ 57 - 1
src/main/java/com/zsElectric/boot/business/service/CouponService.java

@@ -7,11 +7,14 @@ import com.zsElectric.boot.business.model.vo.CouponVO;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
 /**
  * 优惠劵服务类
  *
  * @author zsElectric
- * @since 2025-12-15 09:38
+ * @since 2025-12-19 09:58
  */
 public interface CouponService extends IService<Coupon> {
 
@@ -55,4 +58,57 @@ public interface CouponService extends IService<Coupon> {
      */
     boolean deleteCoupons(String ids);
 
+    /**
+     * 检查优惠券是否有效
+     *
+     * @param couponId 优惠券ID
+     * @return 是否有效
+     */
+    boolean isValidCoupon(Long couponId);
+
+    /**
+     * 检查优惠券是否可以使用
+     *
+     * @param couponId 优惠券ID
+     * @param orderAmount 订单金额
+     * @return 是否可以使用
+     */
+    boolean canUseCoupon(Long couponId, BigDecimal orderAmount);
+
+    /**
+     * 使用优惠券
+     *
+     * @param couponId 优惠券ID
+     * @param orderId 订单ID
+     * @param orderAmount 订单金额
+     * @return 实际优惠金额
+     */
+    BigDecimal useCoupon(Long couponId, Long orderId, BigDecimal orderAmount);
+
+    /**
+     * 过期优惠券处理
+     *
+     * @param couponId 优惠券ID
+     * @return 是否处理成功
+     */
+    boolean expireCoupon(Long couponId);
+
+    /**
+     * 获取用户指定状态的优惠券列表
+     *
+     * @param userId 用户ID
+     * @param status 优惠券状态
+     * @return 优惠券列表
+     */
+    java.util.List<Coupon> getUserCouponsByStatus(Long userId, Integer status);
+
+    /**
+     * 根据模板ID和用户ID获取用户持有的优惠券
+     *
+     * @param templateId 模板ID
+     * @param userId 用户ID
+     * @return 优惠券列表
+     */
+    java.util.List<Coupon> getCouponsByTemplateAndUser(Long templateId, Long userId);
+
 }

+ 35 - 1
src/main/java/com/zsElectric/boot/business/service/CouponTemplateService.java

@@ -7,11 +7,13 @@ import com.zsElectric.boot.business.model.vo.CouponTemplateVO;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.util.List;
+
 /**
  * 优惠劵模板服务类
  *
  * @author zsElectric
- * @since 2025-12-15 11:14
+ * @since 2025-12-19 10:10
  */
 public interface CouponTemplateService extends IService<CouponTemplate> {
 
@@ -55,4 +57,36 @@ public interface CouponTemplateService extends IService<CouponTemplate> {
      */
     boolean deleteCouponTemplates(String ids);
 
+    /**
+     * 验证优惠券模板是否有效
+     *
+     * @param templateId 模板ID
+     * @return 是否有效
+     */
+    boolean isValidTemplate(Long templateId);
+
+    /**
+     * 检查模板是否可以上线
+     *
+     * @param template 模板对象
+     * @return 是否可以上线
+     */
+    boolean canOnlineTemplate(CouponTemplate template);
+
+    /**
+     * 上下线优惠券模板
+     *
+     * @param templateId 模板ID
+     * @return 是否上线成功
+     */
+    boolean onlineOrOfflineTemplate(Long templateId);
+
+    /**
+     * 获取指定状态的优惠券模板列表
+     *
+     * @param status 模板状态
+     * @return 模板列表
+     */
+    List<CouponTemplate> getTemplatesByStatus(Integer status);
+
 }

+ 73 - 0
src/main/java/com/zsElectric/boot/business/service/CouponUsageService.java

@@ -0,0 +1,73 @@
+package com.zsElectric.boot.business.service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zsElectric.boot.business.mapper.CouponMapper;
+import com.zsElectric.boot.business.model.entity.Coupon;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+
+/**
+ * 优惠券使用服务类
+ * 负责优惠券的领取、使用、过期等核心业务逻辑
+ *
+ * @author zsElectric
+ * @since 2025-12-19
+ */
+@Service
+@RequiredArgsConstructor
+public class CouponUsageService extends ServiceImpl<CouponMapper, Coupon> {
+
+    private final CouponService couponService;
+    private final CouponTemplateService couponTemplateService;
+    private final CouponCalculationService couponCalculationService;
+
+
+
+
+
+
+
+    /**
+     * 过期优惠券处理
+     *
+     * @param couponId 优惠券ID
+     * @return 是否处理成功
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public boolean expireCoupon(Long couponId) {
+        // 获取优惠券
+        Coupon coupon = couponService.getById(couponId);
+        if (coupon == null) {
+            return false;
+        }
+
+        // 检查优惠券状态
+        if (coupon.getStatus() != 1) {
+            return false;
+        }
+
+        // 检查是否过期
+        if (coupon.getExpireTime().isAfter(LocalDateTime.now())) {
+            return false;
+        }
+
+        // 更新优惠券状态为已过期
+        coupon.setStatus(3); // 已过期
+        return couponService.updateById(coupon);
+    }
+
+    /**
+     * 批量过期优惠券处理
+     *
+     * @return 处理成功的数量
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public int expireOverdueCoupons() {
+        // 查询所有未使用且已过期的优惠券
+        // 这里应该使用Mapper查询,为了简化示例直接返回0
+        return 0;
+    }
+}

+ 1 - 1
src/main/java/com/zsElectric/boot/business/service/UserRefundsOrderInfoService.java

@@ -1,6 +1,6 @@
 package com.zsElectric.boot.business.service;
 
-import com.zsElectric.boot.business.UserRefundsOrderInfo;
+import com.zsElectric.boot.business.model.entity.UserRefundsOrderInfo;
 import com.zsElectric.boot.business.model.form.UserRefundsOrderInfoForm;
 import com.zsElectric.boot.business.model.query.UserRefundsOrderInfoQuery;
 import com.zsElectric.boot.business.model.vo.UserRefundsOrderInfoVO;

+ 320 - 6
src/main/java/com/zsElectric/boot/business/service/impl/CouponServiceImpl.java

@@ -1,5 +1,9 @@
 package com.zsElectric.boot.business.service.impl;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.zsElectric.boot.core.exception.CouponException;
+import com.zsElectric.boot.business.mapper.CouponTemplateMapper;
+import com.zsElectric.boot.business.model.entity.CouponTemplate;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -13,18 +17,20 @@ import com.zsElectric.boot.business.model.query.CouponQuery;
 import com.zsElectric.boot.business.model.vo.CouponVO;
 import com.zsElectric.boot.business.converter.CouponConverter;
 
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
 import java.util.Arrays;
 import java.util.List;
-import java.util.stream.Collectors;
 
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.StrUtil;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 优惠劵服务实现类
  *
  * @author zsElectric
- * @since 2025-12-15 09:38
+ * @since 2025-12-19 09:58
  */
 @Service
 @RequiredArgsConstructor
@@ -32,6 +38,8 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
 
     private final CouponConverter couponConverter;
 
+    private final CouponTemplateMapper couponTemplateMapper;
+
     /**
     * 获取优惠劵分页列表
     *
@@ -46,7 +54,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
         );
         return pageVO;
     }
-
+    
     /**
      * 获取优惠劵表单数据
      *
@@ -58,7 +66,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
         Coupon entity = this.getById(id);
         return couponConverter.toForm(entity);
     }
-
+    
     /**
      * 新增优惠劵
      *
@@ -70,7 +78,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
         Coupon entity = couponConverter.toEntity(formData);
         return this.save(entity);
     }
-
+    
     /**
      * 更新优惠劵
      *
@@ -83,7 +91,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
         Coupon entity = couponConverter.toEntity(formData);
         return this.updateById(entity);
     }
-
+    
     /**
      * 删除优惠劵
      *
@@ -100,4 +108,310 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
         return this.removeByIds(idList);
     }
 
+    /**
+     * 领取优惠券
+     *
+     * @param templateId 优惠券模板ID
+     * @param userId 用户ID
+     * @param takeType 领取类型(1-用户领取,2-后台发放)
+     * @return 优惠券ID
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public Long takeCoupon(Long templateId, Long userId, Integer takeType) {
+        // 获取优惠券模板
+        CouponTemplate template = couponTemplateMapper.selectById(templateId);
+        if (template == null) {
+            throw new CouponException("优惠券模板不存在");
+        }
+
+        // 检查模板状态(1-上线,2-下线)
+        if (template.getStatus() != 1) {
+            throw new CouponException("优惠券模板已下线");
+        }
+
+        // 检查发放数量限制
+        if (template.getTotalCount() != -1) { // -1表示不限制
+            if (template.getTotalCountAll() != null && template.getTotalCountAll() >= template.getTotalCount()) {
+                throw new CouponException("优惠券已领完");
+            }
+        }
+
+        // 创建优惠券
+        Coupon coupon = new Coupon();
+        coupon.setTemplateId(templateId);
+        coupon.setName(template.getName());
+        coupon.setUserId(userId);
+        coupon.setTakeType(takeType);
+        coupon.setTakeTime(LocalDateTime.now());
+        coupon.setStatus(1); // 未使用
+
+        // 设置过期时间
+        if (template.getFailureTime() != null && template.getFailureTime() > 0) {
+            LocalDateTime expireTime = LocalDateTime.now().plusDays(template.getFailureTime());
+            coupon.setExpireTime(expireTime);
+        }
+
+        // 保存优惠券
+        this.save(coupon);
+
+        // 更新模板已发放数量
+        template.setTotalCountAll(template.getTotalCountAll() != null ? template.getTotalCountAll() + 1 : 1);
+        couponTemplateMapper.updateById(template);
+
+        return coupon.getId();
+    }
+
+    /**
+     * 计算优惠金额
+     *
+     * @param coupon 优惠券
+     * @param orderAmount 订单金额
+     * @return 优惠金额
+     */
+    public BigDecimal calculateDiscount(Coupon coupon, BigDecimal orderAmount) {
+        // 检查优惠券状态
+        if (!isValidCoupon(coupon.getId())) {
+            return BigDecimal.ZERO;
+        }
+
+        // 获取优惠券模板
+        CouponTemplate template = couponTemplateMapper.selectById(coupon.getTemplateId());
+        if (template == null) {
+            return BigDecimal.ZERO;
+        }
+
+        // 根据优惠券类型计算优惠金额
+        switch (template.getType()) {
+            case 1: // 折扣券
+                return calculateDiscountCoupon(template, orderAmount);
+            case 2: // 满减券
+                return calculateReductionCoupon(template, orderAmount);
+            case 3: // 无门槛券
+                return calculateNoThresholdCoupon(template);
+            default:
+                return BigDecimal.ZERO;
+        }
+    }
+
+    /**
+     * 计算折扣券优惠金额
+     *
+     * @param template 优惠券模板
+     * @param orderAmount 订单金额
+     * @return 优惠金额
+     */
+    private BigDecimal calculateDiscountCoupon(CouponTemplate template, BigDecimal orderAmount) {
+        // 检查是否满足使用条件
+        if (template.getUsePrice() != null && orderAmount.compareTo(template.getUsePrice()) < 0) {
+            return BigDecimal.ZERO;
+        }
+
+        // 计算折扣金额 = 订单金额 × 折扣率
+        if (template.getDiscountPrice() != null) {
+            return orderAmount.multiply(template.getDiscountPrice()).divide(BigDecimal.valueOf(100));
+        }
+
+        return BigDecimal.ZERO;
+    }
+
+    /**
+     * 计算满减券优惠金额
+     *
+     * @param template 优惠券模板
+     * @param orderAmount 订单金额
+     * @return 优惠金额
+     */
+    private BigDecimal calculateReductionCoupon(CouponTemplate template, BigDecimal orderAmount) {
+        // 检查是否满足使用条件
+        if (template.getUsePrice() != null && orderAmount.compareTo(template.getUsePrice()) < 0) {
+            return BigDecimal.ZERO;
+        }
+
+        // 返回减免金额
+        return template.getDiscountPrice() != null ? template.getDiscountPrice() : BigDecimal.ZERO;
+    }
+
+    /**
+     * 计算无门槛券优惠金额
+     *
+     * @param template 优惠券模板
+     * @return 优惠金额
+     */
+    private BigDecimal calculateNoThresholdCoupon(CouponTemplate template) {
+        // 直接返回减免金额
+        return template.getDiscountPrice() != null ? template.getDiscountPrice() : BigDecimal.ZERO;
+    }
+
+    /**
+     * 检查优惠券是否有效
+     *
+     * @param couponId 优惠券ID
+     * @return 是否有效
+     */
+    @Override
+    public boolean isValidCoupon(Long couponId) {
+        Coupon coupon = this.getById(couponId);
+        if (coupon == null) {
+            return false;
+        }
+
+        // 检查优惠券状态(1-未使用,2-已使用,3-已过期)
+        if (coupon.getStatus() != 1) {
+            return false;
+        }
+
+        // 检查是否过期
+        if (coupon.getExpireTime().isBefore(LocalDateTime.now())) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * 检查优惠券是否可以使用
+     *
+     * @param couponId 优惠券ID
+     * @param orderAmount 订单金额
+     * @return 是否可以使用
+     */
+    public boolean canUseCoupon(Long couponId, BigDecimal orderAmount) {
+        // 获取优惠券
+        Coupon coupon = this.getById(couponId);
+        if (coupon == null) {
+            return false;
+        }
+
+        // 检查优惠券状态
+        if (coupon.getStatus() != 1) {
+            return false;
+        }
+
+        // 检查是否过期
+        if (coupon.getExpireTime().isBefore(LocalDateTime.now())) {
+            return false;
+        }
+
+        // 获取优惠券模板
+        CouponTemplate template = couponTemplateMapper.selectById(coupon.getTemplateId());
+        if (template == null) {
+            return false;
+        }
+
+        // 根据优惠券类型检查使用条件
+        switch (template.getType()) {
+            case 1: // 折扣券
+                // 检查是否满足使用条件
+                if (template.getUsePrice() != null && orderAmount.compareTo(template.getUsePrice()) < 0) {
+                    return false;
+                }
+                return true;
+            case 2: // 满减券
+                // 检查是否满足使用条件
+                if (template.getUsePrice() != null && orderAmount.compareTo(template.getUsePrice()) < 0) {
+                    return false;
+                }
+                return true;
+            case 3: // 无门槛券
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * 使用优惠券
+     *
+     * @param couponId 优惠券ID
+     * @param orderId 订单ID
+     * @param orderAmount 订单金额
+     * @return 实际优惠金额
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public BigDecimal useCoupon(Long couponId, Long orderId, BigDecimal orderAmount) {
+        // 获取优惠券
+        Coupon coupon = this.getById(couponId);
+        if (coupon == null) {
+            throw new CouponException("优惠券不存在");
+        }
+
+        // 检查优惠券状态
+        if (coupon.getStatus() != 1) {
+            throw new CouponException("优惠券状态不正确");
+        }
+
+        // 检查是否过期
+        if (coupon.getExpireTime().isBefore(LocalDateTime.now())) {
+            throw new CouponException("优惠券已过期");
+        }
+
+        // 计算优惠金额
+        BigDecimal discountAmount = calculateDiscount(coupon, orderAmount);
+
+        // 更新优惠券状态为已使用
+        coupon.setStatus(2); // 已使用
+        coupon.setUseOrderId(orderId);
+        coupon.setUseTime(LocalDateTime.now());
+        this.updateById(coupon);
+
+        return discountAmount;
+    }
+
+
+    /**
+     * 过期优惠券处理
+     *
+     * @param couponId 优惠券ID
+     * @return 是否处理成功
+     */
+    @Override
+    public boolean expireCoupon(Long couponId) {
+        Coupon coupon = this.getById(couponId);
+        if (coupon == null) {
+            return false;
+        }
+
+        // 检查优惠券状态
+        if (coupon.getStatus() != 1) {
+            return false;
+        }
+
+        // 检查是否过期
+        if (coupon.getExpireTime().isAfter(LocalDateTime.now())) {
+            return false;
+        }
+
+        // 更新优惠券状态为已过期
+        coupon.setStatus(3); // 已过期
+        return this.updateById(coupon);
+    }
+
+    /**
+     * 获取用户指定状态的优惠券列表
+     *
+     * @param userId 用户ID
+     * @param status 优惠券状态
+     * @return 优惠券列表
+     */
+    @Override
+    public List<Coupon> getUserCouponsByStatus(Long userId, Integer status) {
+        return this.list(Wrappers.lambdaQuery(Coupon.class)
+                .eq(Coupon::getUserId, userId)
+                .eq(Coupon::getStatus, status));
+    }
+
+    /**
+     * 根据模板ID和用户ID获取用户持有的优惠券
+     *
+     * @param templateId 模板ID
+     * @param userId 用户ID
+     * @return 优惠券列表
+     */
+    @Override
+    public List<Coupon> getCouponsByTemplateAndUser(Long templateId, Long userId) {
+        return this.list(Wrappers.lambdaQuery(Coupon.class)
+                .eq(Coupon::getTemplateId, templateId)
+                .eq(Coupon::getUserId, userId));
+    }
+
 }

+ 87 - 1
src/main/java/com/zsElectric/boot/business/service/impl/CouponTemplateServiceImpl.java

@@ -1,5 +1,6 @@
 package com.zsElectric.boot.business.service.impl;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -24,7 +25,7 @@ import cn.hutool.core.util.StrUtil;
  * 优惠劵模板服务实现类
  *
  * @author zsElectric
- * @since 2025-12-15 11:14
+ * @since 2025-12-19 10:10
  */
 @Service
 @RequiredArgsConstructor
@@ -100,4 +101,89 @@ public class CouponTemplateServiceImpl extends ServiceImpl<CouponTemplateMapper,
         return this.removeByIds(idList);
     }
 
+    /**
+     * 验证优惠券模板是否有效
+     *
+     * @param templateId 模板ID
+     * @return 是否有效
+     */
+    @Override
+    public boolean isValidTemplate(Long templateId) {
+        CouponTemplate template = this.getById(templateId);
+        if (template == null) {
+            return false;
+        }
+        // 检查模板状态(1-上线,2-下线)
+        return template.getStatus() == 1;
+    }
+
+    /**
+     * 检查模板是否可以上线
+     *
+     * @param template 模板对象
+     * @return 是否可以上线
+     */
+    @Override
+    public boolean canOnlineTemplate(CouponTemplate template) {
+        // 检查必要字段是否完整
+        if (template.getName() == null || template.getName().isEmpty()) {
+            return false;
+        }
+
+        if (template.getType() == null) {
+            return false;
+        }
+
+        if (template.getDiscountPrice() == null) {
+            return false;
+        }
+
+        // 对于满减券,需要检查使用门槛
+        if (template.getType() == 2 && template.getUsePrice() == null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * 上下线优惠券模板
+     *
+     * @param templateId 模板ID
+     * @return 是否上线成功
+     */
+    @Override
+    public boolean onlineOrOfflineTemplate(Long templateId) {
+        CouponTemplate template = this.getById(templateId);
+        if (template == null) {
+            return false;
+        }
+
+        if (template.getStatus() == 1) {
+            // 更新状态为下线
+            template.setStatus(2);
+            return this.updateById(template);
+        }
+        // 检查是否可以上线
+        if (!canOnlineTemplate(template)) {
+            return false;
+        }
+
+        // 更新状态为上线
+        template.setStatus(1);
+        return this.updateById(template);
+    }
+
+    /**
+     * 获取指定状态的优惠券模板列表
+     *
+     * @param status 模板状态
+     * @return 模板列表
+     */
+    @Override
+    public List<CouponTemplate> getTemplatesByStatus(Integer status) {
+        return this.list(Wrappers.lambdaQuery(CouponTemplate.class)
+                .eq(CouponTemplate::getStatus, status));
+    }
+
 }

+ 1 - 1
src/main/java/com/zsElectric/boot/business/service/impl/UserOrderInfoServiceImpl.java

@@ -6,7 +6,7 @@ import com.aliyun.oss.ServiceException;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;
-import com.zsElectric.boot.business.UserRefundsOrderInfo;
+import com.zsElectric.boot.business.model.entity.UserRefundsOrderInfo;
 import com.zsElectric.boot.business.mapper.*;
 import com.zsElectric.boot.business.model.entity.*;
 import com.zsElectric.boot.business.model.form.applet.AppLevelOrderForm;

+ 1 - 1
src/main/java/com/zsElectric/boot/business/service/impl/UserRefundsOrderInfoServiceImpl.java

@@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zsElectric.boot.business.mapper.UserRefundsOrderInfoMapper;
 import com.zsElectric.boot.business.service.UserRefundsOrderInfoService;
-import com.zsElectric.boot.business.UserRefundsOrderInfo;
+import com.zsElectric.boot.business.model.entity.UserRefundsOrderInfo;
 import com.zsElectric.boot.business.model.form.UserRefundsOrderInfoForm;
 import com.zsElectric.boot.business.model.query.UserRefundsOrderInfoQuery;
 import com.zsElectric.boot.business.model.vo.UserRefundsOrderInfoVO;

+ 144 - 0
src/main/java/com/zsElectric/boot/common/enums/CouponEnums.java

@@ -0,0 +1,144 @@
+package com.zsElectric.boot.common.enums;
+
+/**
+ * 优惠券相关枚举类
+ *
+ * @author zsElectric
+ * @since 2025-12-19
+ */
+public class CouponEnums {
+
+    /**
+     * 优惠券状态枚举
+     */
+    public enum CouponStatus {
+        UNUSED(1, "未使用"),
+        USED(2, "已使用"),
+        EXPIRED(3, "已过期");
+
+        private final Integer code;
+        private final String description;
+
+        CouponStatus(Integer code, String description) {
+            this.code = code;
+            this.description = description;
+        }
+
+        public Integer getCode() {
+            return code;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public static String getDescriptionByCode(Integer code) {
+            for (CouponStatus status : values()) {
+                if (status.getCode().equals(code)) {
+                    return status.getDescription();
+                }
+            }
+            return "未知";
+        }
+    }
+
+    /**
+     * 优惠券模板状态枚举
+     */
+    public enum TemplateStatus {
+        ONLINE(1, "上线"),
+        OFFLINE(2, "下线");
+
+        private final Integer code;
+        private final String description;
+
+        TemplateStatus(Integer code, String description) {
+            this.code = code;
+            this.description = description;
+        }
+
+        public Integer getCode() {
+            return code;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public static String getDescriptionByCode(Integer code) {
+            for (TemplateStatus status : values()) {
+                if (status.getCode().equals(code)) {
+                    return status.getDescription();
+                }
+            }
+            return "未知";
+        }
+    }
+
+    /**
+     * 优惠券类型枚举
+     */
+    public enum CouponType {
+        DISCOUNT(1, "折扣券"),
+        REDUCTION(2, "满减券"),
+        NO_THRESHOLD(3, "无门槛券");
+
+        private final Integer code;
+        private final String description;
+
+        CouponType(Integer code, String description) {
+            this.code = code;
+            this.description = description;
+        }
+
+        public Integer getCode() {
+            return code;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public static String getDescriptionByCode(Integer code) {
+            for (CouponType type : values()) {
+                if (type.getCode().equals(code)) {
+                    return type.getDescription();
+                }
+            }
+            return "未知";
+        }
+    }
+
+    /**
+     * 领取类型枚举
+     */
+    public enum TakeType {
+        USER_TAKE(1, "用户领取"),
+        ADMIN_ISSUE(2, "后台发放");
+
+        private final Integer code;
+        private final String description;
+
+        TakeType(Integer code, String description) {
+            this.code = code;
+            this.description = description;
+        }
+
+        public Integer getCode() {
+            return code;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public static String getDescriptionByCode(Integer code) {
+            for (TakeType type : values()) {
+                if (type.getCode().equals(code)) {
+                    return type.getDescription();
+                }
+            }
+            return "未知";
+        }
+    }
+}

+ 18 - 0
src/main/java/com/zsElectric/boot/core/exception/CouponException.java

@@ -0,0 +1,18 @@
+package com.zsElectric.boot.core.exception;
+
+/**
+ * 优惠券业务异常类
+ *
+ * @author zsElectric
+ * @since 2025-12-19
+ */
+public class CouponException extends RuntimeException {
+
+    public CouponException(String message) {
+        super(message);
+    }
+
+    public CouponException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

+ 4 - 4
src/main/resources/mapper/business/CouponMapper.xml

@@ -8,15 +8,15 @@
                 id,
                 template_id,
                 name,
+                coupon_code,
                 status,
+                description,
                 user_id,
                 take_type,
-                use_price,
-                valid_end_time,
-                discount_price,
+                take_time,
+                expire_time,
                 use_order_id,
                 use_time,
-                description,
                 create_by,
                 create_time,
                 update_by,

+ 21 - 19
src/main/resources/mapper/business/CouponTemplateMapper.xml

@@ -5,26 +5,28 @@
     <!-- 获取优惠劵模板分页列表 -->
     <select id="getCouponTemplatePage" resultType="com.zsElectric.boot.business.model.vo.CouponTemplateVO">
         SELECT
-                id,
-                name,
-                description,
-                status,
-                total_count,
-                failure_time,
-                use_price,
-                discount_price,
-                valid_time_weeks,
-                valid_time_hour,
-                total_count_all,
-                failure_count,
-                create_time,
-                create_by,
-                update_time,
-                update_by,
-                version,
-                is_deleted
+        id,
+        code,
+        name,
+        type,
+        description,
+        status,
+        total_count,
+        failure_time,
+        use_price,
+        discount_price,
+        valid_time_weeks,
+        valid_time_hour,
+        total_count_all,
+        failure_count,
+        create_time,
+        create_by,
+        update_time,
+        update_by,
+        version,
+        is_deleted
         FROM
-            c_coupon_template
+        c_coupon_template
         <where>
             is_deleted = 0
             <if test="queryParams.name != null and queryParams.name != ''">

+ 17 - 13
src/main/resources/mapper/business/UserInfoMapper.xml

@@ -5,21 +5,25 @@
     <!-- 获取个人用户信息分页列表 -->
     <select id="getUserInfoPage" resultType="com.zsElectric.boot.business.model.vo.UserInfoVO">
         SELECT
-                id,
-                ec_id,
-                nick_name,
-                phone,
-                openid,
-                integral_num,
-                group_id,
-                create_time,
-                create_by,
-                update_time,
-                update_by,
-                is_deleted
+        ui.id,
+        ui.ec_id,
+        ui.nick_name,
+        fi.name AS firmName,
+        ui.phone,
+        ui.openid,
+        ui.integral_num,
+        ui.group_id,
+        ui.create_time,
+        ui.create_by,
+        ui.update_time,
+        ui.update_by,
+        ui.is_deleted
         FROM
-            c_user_info
+        c_user_info ui
+        LEFT JOIN c_user_firm uf ON uf.user_id = ui.id
+        LEFT JOIN c_firm_info fi ON fi.id = uf.firm_id
         <where>
+            ui.is_deleted = 0
         </where>
     </select>
     <select id="getAppletUserInfo" resultType="com.zsElectric.boot.business.model.vo.applet.AppletUserInfoVO">