diff --git a/sql/optional/mall/coupon.sql b/sql/optional/mall/coupon.sql
new file mode 100644
index 000000000..4ab7b1ff9
--- /dev/null
+++ b/sql/optional/mall/coupon.sql
@@ -0,0 +1,85 @@
+DROP TABLE IF EXISTS `coupon`;
+CREATE TABLE `coupon`
+(
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
+ `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '优惠券类型 reward-满减 discount-折扣 random-随机',
+ `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '优惠券名称',
+ `coupon_type_id` bigint UNSIGNED DEFAULT 0 COMMENT '优惠券类型id',
+ `coupon_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '优惠券编码',
+ `member_id` bigint UNSIGNED NOT NULL DEFAULT 0 COMMENT '领用人',
+ `use_order_id` bigint UNSIGNED NOT NULL DEFAULT 0 COMMENT '优惠券使用订单id',
+ `goods_type` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用',
+ `goods_ids` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '适用商品id',
+ `at_least` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最小金额',
+ `money` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '面额',
+ `discount` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '1 =< 折扣 <= 9.9 当type为discount时需要添加',
+ `discount_limit` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最多折扣金额 当type为discount时可选择性添加',
+ `whether_forbid_preference` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用',
+ `whether_expire_notice` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否开启过期提醒0-不开启 1-开启',
+ `expire_notice_fixed_term` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '过期前N天提醒',
+ `whether_noticed` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否已提醒',
+ `state` tinyint(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '优惠券状态 1已领用(未使用) 2已使用 3已过期',
+ `get_type` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取',
+ `fetch_time` datetime NOT NULL DEFAULT 0 COMMENT '领取时间',
+ `use_time` datetime NOT NULL DEFAULT 0 COMMENT '使用时间',
+ `start_time` datetime NOT NULL DEFAULT 0 COMMENT '可使用的开始时间',
+ `end_time` datetime NOT NULL DEFAULT 0 COMMENT '有效期结束时间',
+ `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 119
+ CHARACTER SET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT = '优惠券';
+
+DROP TABLE IF EXISTS `coupon_templete`;
+CREATE TABLE `coupon_templete`
+(
+ `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
+ `type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '优惠券类型 reward-满减 discount-折扣 random-随机',
+ `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '优惠券名称',
+ `coupon_name_remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '名称备注',
+ `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '优惠券图片',
+ `count` int(11) NOT NULL DEFAULT 0 COMMENT '发放数量',
+ `lead_count` int(11) NOT NULL DEFAULT 0 COMMENT '已领取数量',
+ `used_count` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '已使用数量',
+ `goods_type` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用',
+ `product_ids` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '适用商品id',
+ `has_use_limit` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用门槛0-无门槛 1-有门槛',
+ `at_least` decimal(10, 2) NOT NULL DEFAULT 0 COMMENT '满多少元使用 0代表无限制',
+ `money` decimal(10, 2) NOT NULL DEFAULT 0 COMMENT '发放面额 当type为reward时需要添加',
+ `discount` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '1 =< 折扣 <= 9.9 当type为discount时需要添加',
+ `discount_limit` decimal(10, 2) NOT NULL DEFAULT 0 COMMENT '最多折扣金额 当type为discount时可选择性添加',
+ `min_money` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最低金额 当type为radom时需要添加',
+ `max_money` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最大金额 当type为radom时需要添加',
+ `validity_type` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期',
+ `start_use_time` datetime COMMENT '使用开始日期 过期类型1时必填',
+ `end_use_time` datetime COMMENT '使用结束日期 过期类型1时必填',
+ `fixed_term` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效',
+ `whether_limitless` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否无限制0-否 1是',
+ `max_fetch` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '每人最大领取个数',
+ `whether_expire_notice` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否开启过期提醒0-不开启 1-开启',
+ `expire_notice_fixed_term` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '过期前N天提醒',
+ `whether_forbid_preference` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用',
+ `whether_show` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否显示',
+ `discount_order_money` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '订单的优惠总金额',
+ `order_money` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '用券总成交额',
+ `whether_forbidden` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否禁止发放0-否 1-是',
+ `order_goods_num` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用优惠券购买的商品数量',
+ `status` tinyint(11) NOT NULL DEFAULT 0 COMMENT '状态(1进行中2已结束-1已关闭)',
+ `end_time` datetime COMMENT '有效日期结束时间',
+ `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+ `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 119
+ CHARACTER SET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT = '优惠券模板';
\ No newline at end of file
diff --git a/yudao-module-mall/pom.xml b/yudao-module-mall/pom.xml
index 29d5d2d2b..23812b4cc 100644
--- a/yudao-module-mall/pom.xml
+++ b/yudao-module-mall/pom.xml
@@ -24,6 +24,8 @@
yudao-module-product-biz
yudao-module-trade-api
yudao-module-trade-biz
+ yudao-module-coupon-api
+ yudao-module-coupon-biz
diff --git a/yudao-module-mall/yudao-module-coupon-api/pom.xml b/yudao-module-mall/yudao-module-coupon-api/pom.xml
new file mode 100644
index 000000000..e98526f9c
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-api/pom.xml
@@ -0,0 +1,28 @@
+
+
+
+ cn.iocoder.boot
+ yudao-module-mall
+ ${revision}
+
+
+ 4.0.0
+ yudao-module-coupon-api
+ jar
+
+
+ ${project.artifactId}
+
+ coupon 模块 API,暴露给其它模块调用
+
+
+
+
+ cn.iocoder.boot
+ yudao-common
+
+
+
+
\ No newline at end of file
diff --git a/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/ErrorCodeConstants.java
new file mode 100644
index 000000000..331824466
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/ErrorCodeConstants.java
@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.CouponTemplete.enums;
+
+import cn.iocoder.yudao.framework.common.exception.ErrorCode;
+
+/**
+ * coupon 优惠券错误码枚举类
+ *
+ * coupon 优惠券系统,使用 1-010-000-000 段
+ */
+public interface ErrorCodeConstants {
+ // ========== COUPON分类相关 1010001000 ============
+
+ ErrorCode COUPON_TEMPLETE_NOT_EXISTS = new ErrorCode(1010001000, "优惠券模板不存在");
+
+ // ========== COUPON分类相关 1010002000 ============
+ ErrorCode COUPON_NOT_EXISTS = new ErrorCode(1010001000, "优惠券模板不存在");
+
+
+}
+
diff --git a/yudao-module-mall/yudao-module-coupon-biz/pom.xml b/yudao-module-mall/yudao-module-coupon-biz/pom.xml
new file mode 100644
index 000000000..735d5180d
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/pom.xml
@@ -0,0 +1,63 @@
+
+
+
+ yudao-module-mall
+ cn.iocoder.boot
+ ${revision}
+
+ 4.0.0
+ yudao-module-coupon-biz
+ jar
+
+
+ ${project.artifactId}
+
+ trade 模块,主要实现交易相关功能
+ 例如:订单、退款、购物车等功能。
+
+
+
+
+
+ cn.iocoder.boot
+ yudao-module-coupon-api
+ ${revision}
+
+
+
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-biz-operatelog
+
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-biz-tenant
+
+
+
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-web
+
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-excel
+
+
+
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-mybatis
+
+
+
+
+ cn.iocoder.boot
+ yudao-spring-boot-starter-test
+
+
+
+
+
\ No newline at end of file
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/CouponController.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/CouponController.java
new file mode 100644
index 000000000..21a91e4b5
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/CouponController.java
@@ -0,0 +1,100 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupon;
+
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import io.swagger.annotations.*;
+
+import javax.validation.constraints.*;
+import javax.validation.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.IOException;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+
+import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
+import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
+
+import cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo.*;
+import cn.iocoder.yudao.module.coupon.dal.dataobject.coupon.CouponDO;
+import cn.iocoder.yudao.module.coupon.convert.coupon.CouponConvert;
+import cn.iocoder.yudao.module.coupon.service.coupon.CouponService;
+
+@Api(tags = "管理后台 - 优惠券")
+@RestController
+@RequestMapping("/coupon/")
+@Validated
+public class CouponController {
+
+ @Resource
+ private CouponService Service;
+
+ @PostMapping("/create")
+ @ApiOperation("创建优惠券")
+ @PreAuthorize("@ss.hasPermission('coupon::create')")
+ public CommonResult create(@Valid @RequestBody CouponCreateReqVO createReqVO) {
+ return success(Service.create(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @ApiOperation("更新优惠券")
+ @PreAuthorize("@ss.hasPermission('coupon::update')")
+ public CommonResult update(@Valid @RequestBody CouponUpdateReqVO updateReqVO) {
+ Service.update(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @ApiOperation("删除优惠券")
+ @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
+ @PreAuthorize("@ss.hasPermission('coupon::delete')")
+ public CommonResult delete(@RequestParam("id") Long id) {
+ Service.delete(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @ApiOperation("获得优惠券")
+ @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
+ @PreAuthorize("@ss.hasPermission('coupon::query')")
+ public CommonResult get(@RequestParam("id") Long id) {
+ CouponDO couponDO = Service.get(id);
+ return success(CouponConvert.INSTANCE.convert(couponDO));
+ }
+
+ @GetMapping("/list")
+ @ApiOperation("获得优惠券列表")
+ @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
+ @PreAuthorize("@ss.hasPermission('coupon::query')")
+ public CommonResult> getList(@RequestParam("ids") Collection ids) {
+ List list = Service.getList(ids);
+ return success(CouponConvert.INSTANCE.convertList(list));
+ }
+
+ @GetMapping("/page")
+ @ApiOperation("获得优惠券分页")
+ @PreAuthorize("@ss.hasPermission('coupon::query')")
+ public CommonResult> getPage(@Valid CouponPageReqVO pageVO) {
+ PageResult pageResult = Service.getPage(pageVO);
+ return success(CouponConvert.INSTANCE.convertPage(pageResult));
+ }
+
+ @GetMapping("/export-excel")
+ @ApiOperation("导出优惠券 Excel")
+ @PreAuthorize("@ss.hasPermission('coupon::export')")
+ @OperateLog(type = EXPORT)
+ public void exportExcel(@Valid CouponExportReqVO exportReqVO,
+ HttpServletResponse response) throws IOException {
+ List list = Service.getList(exportReqVO);
+ // 导出 Excel
+ List datas = CouponConvert.INSTANCE.convertList02(list);
+ ExcelUtils.write(response, "优惠券.xls", "数据", CouponExcelVO.class, datas);
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponBaseVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponBaseVO.java
new file mode 100644
index 000000000..20dba42d8
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponBaseVO.java
@@ -0,0 +1,110 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
+
+import lombok.*;
+import java.util.*;
+import java.math.BigDecimal;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+/**
+* 优惠券 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class CouponBaseVO {
+
+ @ApiModelProperty(value = "优惠券类型 reward-满减 discount-折扣 random-随机", required = true)
+ @NotNull(message = "优惠券类型 reward-满减 discount-折扣 random-随机不能为空")
+ private String type;
+
+ @ApiModelProperty(value = "优惠券名称", required = true)
+ @NotNull(message = "优惠券名称不能为空")
+ private String name;
+
+ @ApiModelProperty(value = "优惠券类型id")
+ private Long couponTypeId;
+
+ @ApiModelProperty(value = "优惠券编码", required = true)
+ @NotNull(message = "优惠券编码不能为空")
+ private String couponCode;
+
+ @ApiModelProperty(value = "领用人", required = true)
+ @NotNull(message = "领用人不能为空")
+ private Long memberId;
+
+ @ApiModelProperty(value = "优惠券使用订单id", required = true)
+ @NotNull(message = "优惠券使用订单id不能为空")
+ private Long useOrderId;
+
+ @ApiModelProperty(value = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用", required = true)
+ @NotNull(message = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用不能为空")
+ private Boolean goodsType;
+
+ @ApiModelProperty(value = "适用商品id", required = true)
+ @NotNull(message = "适用商品id不能为空")
+ private String goodsIds;
+
+ @ApiModelProperty(value = "最小金额", required = true)
+ @NotNull(message = "最小金额不能为空")
+ private BigDecimal atLeast;
+
+ @ApiModelProperty(value = "面额", required = true)
+ @NotNull(message = "面额不能为空")
+ private BigDecimal money;
+
+ @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加", required = true)
+ @NotNull(message = "1 =< 折扣 <= 9.9 当type为discount时需要添加不能为空")
+ private BigDecimal discount;
+
+ @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加", required = true)
+ @NotNull(message = "最多折扣金额 当type为discount时可选择性添加不能为空")
+ private BigDecimal discountLimit;
+
+ @ApiModelProperty(value = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用", required = true)
+ @NotNull(message = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用不能为空")
+ private Boolean whetherForbidPreference;
+
+ @ApiModelProperty(value = "是否开启过期提醒0-不开启 1-开启", required = true)
+ @NotNull(message = "是否开启过期提醒0-不开启 1-开启不能为空")
+ private Boolean whetherExpireNotice;
+
+ @ApiModelProperty(value = "过期前N天提醒", required = true)
+ @NotNull(message = "过期前N天提醒不能为空")
+ private Integer expireNoticeFixedTerm;
+
+ @ApiModelProperty(value = "是否已提醒", required = true)
+ @NotNull(message = "是否已提醒不能为空")
+ private Boolean whetherNoticed;
+
+ @ApiModelProperty(value = "优惠券状态 1已领用(未使用) 2已使用 3已过期", required = true)
+ @NotNull(message = "优惠券状态 1已领用(未使用) 2已使用 3已过期不能为空")
+ private Integer state;
+
+ @ApiModelProperty(value = "获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取", required = true)
+ @NotNull(message = "获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取不能为空")
+ private Boolean getType;
+
+ @ApiModelProperty(value = "领取时间", required = true)
+ @NotNull(message = "领取时间不能为空")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date fetchTime;
+
+ @ApiModelProperty(value = "使用时间", required = true)
+ @NotNull(message = "使用时间不能为空")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date useTime;
+
+ @ApiModelProperty(value = "可使用的开始时间", required = true)
+ @NotNull(message = "可使用的开始时间不能为空")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date startTime;
+
+ @ApiModelProperty(value = "有效期结束时间", required = true)
+ @NotNull(message = "有效期结束时间不能为空")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date endTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponCreateReqVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponCreateReqVO.java
new file mode 100644
index 000000000..2cd3cb419
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponCreateReqVO.java
@@ -0,0 +1,14 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("管理后台 - 优惠券创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class CouponCreateReqVO extends CouponBaseVO {
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponExcelVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponExcelVO.java
new file mode 100644
index 000000000..f7d1d1d6f
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponExcelVO.java
@@ -0,0 +1,90 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
+
+import lombok.*;
+import java.util.*;
+import java.math.BigDecimal;
+import io.swagger.annotations.*;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+
+/**
+ * 优惠券 Excel VO
+ *
+ * @author wxr
+ */
+@Data
+public class CouponExcelVO {
+
+ @ExcelProperty("用户ID")
+ private Long id;
+
+ @ExcelProperty("优惠券类型 reward-满减 discount-折扣 random-随机")
+ private String type;
+
+ @ExcelProperty("优惠券名称")
+ private String name;
+
+ @ExcelProperty("优惠券类型id")
+ private Long couponTypeId;
+
+ @ExcelProperty("优惠券编码")
+ private String couponCode;
+
+ @ExcelProperty("领用人")
+ private Long memberId;
+
+ @ExcelProperty("优惠券使用订单id")
+ private Long useOrderId;
+
+ @ExcelProperty("适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用")
+ private Boolean goodsType;
+
+ @ExcelProperty("适用商品id")
+ private String goodsIds;
+
+ @ExcelProperty("最小金额")
+ private BigDecimal atLeast;
+
+ @ExcelProperty("面额")
+ private BigDecimal money;
+
+ @ExcelProperty("1 =< 折扣 <= 9.9 当type为discount时需要添加")
+ private BigDecimal discount;
+
+ @ExcelProperty("最多折扣金额 当type为discount时可选择性添加")
+ private BigDecimal discountLimit;
+
+ @ExcelProperty("优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用")
+ private Boolean whetherForbidPreference;
+
+ @ExcelProperty("是否开启过期提醒0-不开启 1-开启")
+ private Boolean whetherExpireNotice;
+
+ @ExcelProperty("过期前N天提醒")
+ private Integer expireNoticeFixedTerm;
+
+ @ExcelProperty("是否已提醒")
+ private Boolean whetherNoticed;
+
+ @ExcelProperty("优惠券状态 1已领用(未使用) 2已使用 3已过期")
+ private Integer state;
+
+ @ExcelProperty("获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取")
+ private Boolean getType;
+
+ @ExcelProperty("领取时间")
+ private Date fetchTime;
+
+ @ExcelProperty("使用时间")
+ private Date useTime;
+
+ @ExcelProperty("可使用的开始时间")
+ private Date startTime;
+
+ @ExcelProperty("有效期结束时间")
+ private Date endTime;
+
+ @ExcelProperty("创建时间")
+ private Date createTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponExportReqVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponExportReqVO.java
new file mode 100644
index 000000000..a195a61de
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponExportReqVO.java
@@ -0,0 +1,91 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
+
+import lombok.*;
+
+import java.math.BigDecimal;
+import java.util.*;
+import io.swagger.annotations.*;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel(value = "管理后台 - 优惠券 Excel 导出 Request VO", description = "参数和 CouponPageReqVO 是一致的")
+@Data
+public class CouponExportReqVO {
+
+ @ApiModelProperty(value = "优惠券类型 reward-满减 discount-折扣 random-随机")
+ private String type;
+
+ @ApiModelProperty(value = "优惠券名称")
+ private String name;
+
+ @ApiModelProperty(value = "优惠券类型id")
+ private Long couponTypeId;
+
+ @ApiModelProperty(value = "优惠券编码")
+ private String couponCode;
+
+ @ApiModelProperty(value = "领用人")
+ private Long memberId;
+
+ @ApiModelProperty(value = "优惠券使用订单id")
+ private Long useOrderId;
+
+ @ApiModelProperty(value = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用")
+ private Boolean goodsType;
+
+ @ApiModelProperty(value = "适用商品id")
+ private String goodsIds;
+
+ @ApiModelProperty(value = "最小金额")
+ private BigDecimal atLeast;
+
+ @ApiModelProperty(value = "面额")
+ private BigDecimal money;
+
+ @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加")
+ private BigDecimal discount;
+
+ @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加")
+ private BigDecimal discountLimit;
+
+ @ApiModelProperty(value = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用")
+ private Boolean whetherForbidPreference;
+
+ @ApiModelProperty(value = "是否开启过期提醒0-不开启 1-开启")
+ private Boolean whetherExpireNotice;
+
+ @ApiModelProperty(value = "过期前N天提醒")
+ private Integer expireNoticeFixedTerm;
+
+ @ApiModelProperty(value = "是否已提醒")
+ private Boolean whetherNoticed;
+
+ @ApiModelProperty(value = "优惠券状态 1已领用(未使用) 2已使用 3已过期")
+ private Integer state;
+
+ @ApiModelProperty(value = "获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取")
+ private Boolean getType;
+
+ @ApiModelProperty(value = "领取时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] fetchTime;
+
+ @ApiModelProperty(value = "使用时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] useTime;
+
+ @ApiModelProperty(value = "可使用的开始时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] startTime;
+
+ @ApiModelProperty(value = "有效期结束时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] endTime;
+
+ @ApiModelProperty(value = "创建时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] createTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponPageReqVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponPageReqVO.java
new file mode 100644
index 000000000..9573200a5
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponPageReqVO.java
@@ -0,0 +1,93 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
+
+import lombok.*;
+
+import java.math.BigDecimal;
+import java.util.*;
+import io.swagger.annotations.*;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel("管理后台 - 优惠券分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class CouponPageReqVO extends PageParam {
+
+ @ApiModelProperty(value = "优惠券类型 reward-满减 discount-折扣 random-随机")
+ private String type;
+
+ @ApiModelProperty(value = "优惠券名称")
+ private String name;
+
+ @ApiModelProperty(value = "优惠券类型id")
+ private Long couponTypeId;
+
+ @ApiModelProperty(value = "优惠券编码")
+ private String couponCode;
+
+ @ApiModelProperty(value = "领用人")
+ private Long memberId;
+
+ @ApiModelProperty(value = "优惠券使用订单id")
+ private Long useOrderId;
+
+ @ApiModelProperty(value = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用")
+ private Boolean goodsType;
+
+ @ApiModelProperty(value = "适用商品id")
+ private String goodsIds;
+
+ @ApiModelProperty(value = "最小金额")
+ private BigDecimal atLeast;
+
+ @ApiModelProperty(value = "面额")
+ private BigDecimal money;
+
+ @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加")
+ private BigDecimal discount;
+
+ @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加")
+ private BigDecimal discountLimit;
+
+ @ApiModelProperty(value = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用")
+ private Boolean whetherForbidPreference;
+
+ @ApiModelProperty(value = "是否开启过期提醒0-不开启 1-开启")
+ private Boolean whetherExpireNotice;
+
+ @ApiModelProperty(value = "过期前N天提醒")
+ private Integer expireNoticeFixedTerm;
+
+ @ApiModelProperty(value = "是否已提醒")
+ private Boolean whetherNoticed;
+
+ @ApiModelProperty(value = "优惠券状态 1已领用(未使用) 2已使用 3已过期")
+ private Integer state;
+
+ @ApiModelProperty(value = "获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取")
+ private Boolean getType;
+
+ @ApiModelProperty(value = "领取时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] fetchTime;
+
+ @ApiModelProperty(value = "使用时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] useTime;
+
+ @ApiModelProperty(value = "可使用的开始时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] startTime;
+
+ @ApiModelProperty(value = "有效期结束时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] endTime;
+
+ @ApiModelProperty(value = "创建时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] createTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponRespVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponRespVO.java
new file mode 100644
index 000000000..9055a36a0
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponRespVO.java
@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+
+@ApiModel("管理后台 - 优惠券 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class CouponRespVO extends CouponBaseVO {
+
+ @ApiModelProperty(value = "用户ID", required = true)
+ private Long id;
+
+ @ApiModelProperty(value = "创建时间", required = true)
+ private Date createTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponUpdateReqVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponUpdateReqVO.java
new file mode 100644
index 000000000..0c1a741ca
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponUpdateReqVO.java
@@ -0,0 +1,18 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("管理后台 - 优惠券更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class CouponUpdateReqVO extends CouponBaseVO {
+
+ @ApiModelProperty(value = "用户ID", required = true)
+ @NotNull(message = "用户ID不能为空")
+ private Long id;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/CouponTempleteController.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/CouponTempleteController.java
new file mode 100644
index 000000000..d60ed45aa
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/CouponTempleteController.java
@@ -0,0 +1,100 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete;
+
+import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.*;
+import cn.iocoder.yudao.module.coupon.convert.CouponTemplete.CouponTempleteConvert;
+import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
+import cn.iocoder.yudao.module.coupon.service.CouponTemplete.CouponTempleteService;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import io.swagger.annotations.*;
+
+import javax.validation.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.IOException;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+
+import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
+import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
+
+
+
+@Api(tags = "管理后台 - 优惠券模板")
+@RestController
+@RequestMapping("/CouponTemplete/")
+@Validated
+public class CouponTempleteController {
+
+ @Resource
+ private CouponTempleteService Service;
+
+ @PostMapping("/create")
+ @ApiOperation("创建优惠券模板")
+ @PreAuthorize("@ss.hasPermission('CouponTemplete::create')")
+ public CommonResult create(@Valid @RequestBody CouponTempleteCreateReqVO createReqVO) {
+ return success(Service.create(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @ApiOperation("更新优惠券模板")
+ @PreAuthorize("@ss.hasPermission('CouponTemplete::update')")
+ public CommonResult update(@Valid @RequestBody CouponTempleteUpdateReqVO updateReqVO) {
+ Service.update(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @ApiOperation("删除优惠券模板")
+ @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
+ @PreAuthorize("@ss.hasPermission('CouponTemplete::delete')")
+ public CommonResult delete(@RequestParam("id") Long id) {
+ Service.delete(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @ApiOperation("获得优惠券模板")
+ @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
+ @PreAuthorize("@ss.hasPermission('CouponTemplete::query')")
+ public CommonResult get(@RequestParam("id") Long id) {
+ CouponTempleteDO couponTempleteDO = Service.get(id);
+ return success(CouponTempleteConvert.INSTANCE.convert(couponTempleteDO));
+ }
+
+ @GetMapping("/list")
+ @ApiOperation("获得优惠券模板列表")
+ @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
+ @PreAuthorize("@ss.hasPermission('CouponTemplete::query')")
+ public CommonResult> getList(@RequestParam("ids") Collection ids) {
+ List list = Service.getList(ids);
+ return success(CouponTempleteConvert.INSTANCE.convertList(list));
+ }
+
+ @GetMapping("/page")
+ @ApiOperation("获得优惠券模板分页")
+ @PreAuthorize("@ss.hasPermission('CouponTemplete::query')")
+ public CommonResult> getPage(@Valid CouponTempletePageReqVO pageVO) {
+ PageResult pageResult = Service.getPage(pageVO);
+ return success(CouponTempleteConvert.INSTANCE.convertPage(pageResult));
+ }
+
+ @GetMapping("/export-excel")
+ @ApiOperation("导出优惠券模板 Excel")
+ @PreAuthorize("@ss.hasPermission('CouponTemplete::export')")
+ @OperateLog(type = EXPORT)
+ public void exportExcel(@Valid CouponTempleteExportReqVO exportReqVO,
+ HttpServletResponse response) throws IOException {
+ List list = Service.getList(exportReqVO);
+ // 导出 Excel
+ List datas = CouponTempleteConvert.INSTANCE.convertList02(list);
+ ExcelUtils.write(response, "优惠券模板.xls", "数据", CouponTempleteExcelVO.class, datas);
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteBaseVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteBaseVO.java
new file mode 100644
index 000000000..f43339f0f
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteBaseVO.java
@@ -0,0 +1,144 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo;
+
+import lombok.*;
+import java.util.*;
+import java.math.BigDecimal;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+/**
+* 优惠券模板 Base VO,提供给添加、修改、详细的子 VO 使用
+* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+*/
+@Data
+public class CouponTempleteBaseVO {
+
+ @ApiModelProperty(value = "优惠券类型 reward-满减 discount-折扣 random-随机", required = true)
+ @NotNull(message = "优惠券类型 reward-满减 discount-折扣 random-随机不能为空")
+ private String type;
+
+ @ApiModelProperty(value = "优惠券名称", required = true)
+ @NotNull(message = "优惠券名称不能为空")
+ private String name;
+
+ @ApiModelProperty(value = "名称备注")
+ private String couponNameRemark;
+
+ @ApiModelProperty(value = "优惠券图片")
+ private String image;
+
+ @ApiModelProperty(value = "发放数量", required = true)
+ @NotNull(message = "发放数量不能为空")
+ private Integer count;
+
+ @ApiModelProperty(value = "已领取数量", required = true)
+ @NotNull(message = "已领取数量不能为空")
+ private Integer leadCount;
+
+ @ApiModelProperty(value = "已使用数量", required = true)
+ @NotNull(message = "已使用数量不能为空")
+ private Integer usedCount;
+
+ @ApiModelProperty(value = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用", required = true)
+ @NotNull(message = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用不能为空")
+ private Boolean goodsType;
+
+ @ApiModelProperty(value = "适用商品id")
+ private String productIds;
+
+ @ApiModelProperty(value = "使用门槛0-无门槛 1-有门槛", required = true)
+ @NotNull(message = "使用门槛0-无门槛 1-有门槛不能为空")
+ private Boolean hasUseLimit;
+
+ @ApiModelProperty(value = "满多少元使用 0代表无限制", required = true)
+ @NotNull(message = "满多少元使用 0代表无限制不能为空")
+ private BigDecimal atLeast;
+
+ @ApiModelProperty(value = "发放面额 当type为reward时需要添加", required = true)
+ @NotNull(message = "发放面额 当type为reward时需要添加不能为空")
+ private BigDecimal money;
+
+ @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加", required = true)
+ @NotNull(message = "1 =< 折扣 <= 9.9 当type为discount时需要添加不能为空")
+ private BigDecimal discount;
+
+ @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加", required = true)
+ @NotNull(message = "最多折扣金额 当type为discount时可选择性添加不能为空")
+ private BigDecimal discountLimit;
+
+ @ApiModelProperty(value = "最低金额 当type为radom时需要添加", required = true)
+ @NotNull(message = "最低金额 当type为radom时需要添加不能为空")
+ private BigDecimal minMoney;
+
+ @ApiModelProperty(value = "最大金额 当type为radom时需要添加", required = true)
+ @NotNull(message = "最大金额 当type为radom时需要添加不能为空")
+ private BigDecimal maxMoney;
+
+ @ApiModelProperty(value = "过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期", required = true)
+ @NotNull(message = "过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期不能为空")
+ private Boolean validityType;
+
+ @ApiModelProperty(value = "使用开始日期 过期类型1时必填")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date startUseTime;
+
+ @ApiModelProperty(value = "使用结束日期 过期类型1时必填")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date endUseTime;
+
+ @ApiModelProperty(value = "当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效", required = true)
+ @NotNull(message = "当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效不能为空")
+ private Integer fixedTerm;
+
+ @ApiModelProperty(value = "是否无限制0-否 1是", required = true)
+ @NotNull(message = "是否无限制0-否 1是不能为空")
+ private Boolean whetherLimitless;
+
+ @ApiModelProperty(value = "每人最大领取个数", required = true)
+ @NotNull(message = "每人最大领取个数不能为空")
+ private Integer maxFetch;
+
+ @ApiModelProperty(value = "是否开启过期提醒0-不开启 1-开启", required = true)
+ @NotNull(message = "是否开启过期提醒0-不开启 1-开启不能为空")
+ private Boolean whetherExpireNotice;
+
+ @ApiModelProperty(value = "过期前N天提醒", required = true)
+ @NotNull(message = "过期前N天提醒不能为空")
+ private Integer expireNoticeFixedTerm;
+
+ @ApiModelProperty(value = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用", required = true)
+ @NotNull(message = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用不能为空")
+ private Boolean whetherForbidPreference;
+
+ @ApiModelProperty(value = "是否显示", required = true)
+ @NotNull(message = "是否显示不能为空")
+ private Integer whetherShow;
+
+ @ApiModelProperty(value = "订单的优惠总金额", required = true)
+ @NotNull(message = "订单的优惠总金额不能为空")
+ private BigDecimal discountOrderMoney;
+
+ @ApiModelProperty(value = "用券总成交额", required = true)
+ @NotNull(message = "用券总成交额不能为空")
+ private BigDecimal orderMoney;
+
+ @ApiModelProperty(value = "是否禁止发放0-否 1-是", required = true)
+ @NotNull(message = "是否禁止发放0-否 1-是不能为空")
+ private Boolean whetherForbidden;
+
+ @ApiModelProperty(value = "使用优惠券购买的商品数量", required = true)
+ @NotNull(message = "使用优惠券购买的商品数量不能为空")
+ private Integer orderGoodsNum;
+
+ @ApiModelProperty(value = "状态(1进行中2已结束-1已关闭)", required = true)
+ @NotNull(message = "状态(1进行中2已结束-1已关闭)不能为空")
+ private Integer status;
+
+ @ApiModelProperty(value = "有效日期结束时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date endTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteCreateReqVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteCreateReqVO.java
new file mode 100644
index 000000000..fa13b77a5
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteCreateReqVO.java
@@ -0,0 +1,12 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo;
+
+import lombok.*;
+import io.swagger.annotations.*;
+
+@ApiModel("管理后台 - 优惠券模板创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class CouponTempleteCreateReqVO extends CouponTempleteBaseVO {
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteExcelVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteExcelVO.java
new file mode 100644
index 000000000..a09b3ff71
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteExcelVO.java
@@ -0,0 +1,119 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo;
+
+import lombok.*;
+import java.util.*;
+import java.math.BigDecimal;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+
+/**
+ * 优惠券模板 Excel VO
+ *
+ * @author wxr
+ */
+@Data
+public class CouponTempleteExcelVO {
+
+ @ExcelProperty("用户ID")
+ private Long id;
+
+ @ExcelProperty("优惠券类型 reward-满减 discount-折扣 random-随机")
+ private String type;
+
+ @ExcelProperty("优惠券名称")
+ private String name;
+
+ @ExcelProperty("名称备注")
+ private String couponNameRemark;
+
+ @ExcelProperty("优惠券图片")
+ private String image;
+
+ @ExcelProperty("发放数量")
+ private Integer count;
+
+ @ExcelProperty("已领取数量")
+ private Integer leadCount;
+
+ @ExcelProperty("已使用数量")
+ private Integer usedCount;
+
+ @ExcelProperty("适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用")
+ private Boolean goodsType;
+
+ @ExcelProperty("适用商品id")
+ private String productIds;
+
+ @ExcelProperty("使用门槛0-无门槛 1-有门槛")
+ private Boolean hasUseLimit;
+
+ @ExcelProperty("满多少元使用 0代表无限制")
+ private BigDecimal atLeast;
+
+ @ExcelProperty("发放面额 当type为reward时需要添加")
+ private BigDecimal money;
+
+ @ExcelProperty("1 =< 折扣 <= 9.9 当type为discount时需要添加")
+ private BigDecimal discount;
+
+ @ExcelProperty("最多折扣金额 当type为discount时可选择性添加")
+ private BigDecimal discountLimit;
+
+ @ExcelProperty("最低金额 当type为radom时需要添加")
+ private BigDecimal minMoney;
+
+ @ExcelProperty("最大金额 当type为radom时需要添加")
+ private BigDecimal maxMoney;
+
+ @ExcelProperty("过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期")
+ private Boolean validityType;
+
+ @ExcelProperty("使用开始日期 过期类型1时必填")
+ private Date startUseTime;
+
+ @ExcelProperty("使用结束日期 过期类型1时必填")
+ private Date endUseTime;
+
+ @ExcelProperty("当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效")
+ private Integer fixedTerm;
+
+ @ExcelProperty("是否无限制0-否 1是")
+ private Boolean whetherLimitless;
+
+ @ExcelProperty("每人最大领取个数")
+ private Integer maxFetch;
+
+ @ExcelProperty("是否开启过期提醒0-不开启 1-开启")
+ private Boolean whetherExpireNotice;
+
+ @ExcelProperty("过期前N天提醒")
+ private Integer expireNoticeFixedTerm;
+
+ @ExcelProperty("优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用")
+ private Boolean whetherForbidPreference;
+
+ @ExcelProperty("是否显示")
+ private Integer whetherShow;
+
+ @ExcelProperty("订单的优惠总金额")
+ private BigDecimal discountOrderMoney;
+
+ @ExcelProperty("用券总成交额")
+ private BigDecimal orderMoney;
+
+ @ExcelProperty("是否禁止发放0-否 1-是")
+ private Boolean whetherForbidden;
+
+ @ExcelProperty("使用优惠券购买的商品数量")
+ private Integer orderGoodsNum;
+
+ @ExcelProperty("状态(1进行中2已结束-1已关闭)")
+ private Integer status;
+
+ @ExcelProperty("有效日期结束时间")
+ private Date endTime;
+
+ @ExcelProperty("创建时间")
+ private Date createTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteExportReqVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteExportReqVO.java
new file mode 100644
index 000000000..b8b8fced1
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteExportReqVO.java
@@ -0,0 +1,119 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo;
+
+import lombok.*;
+
+import java.math.BigDecimal;
+import java.util.*;
+import io.swagger.annotations.*;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel(value = "管理后台 - 优惠券模板 Excel 导出 Request VO", description = "参数和 CouponTempletePageReqVO 是一致的")
+@Data
+public class CouponTempleteExportReqVO {
+
+ @ApiModelProperty(value = "优惠券类型 reward-满减 discount-折扣 random-随机")
+ private String type;
+
+ @ApiModelProperty(value = "优惠券名称")
+ private String name;
+
+ @ApiModelProperty(value = "名称备注")
+ private String couponNameRemark;
+
+ @ApiModelProperty(value = "优惠券图片")
+ private String image;
+
+ @ApiModelProperty(value = "发放数量")
+ private Integer count;
+
+ @ApiModelProperty(value = "已领取数量")
+ private Integer leadCount;
+
+ @ApiModelProperty(value = "已使用数量")
+ private Integer usedCount;
+
+ @ApiModelProperty(value = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用")
+ private Boolean goodsType;
+
+ @ApiModelProperty(value = "适用商品id")
+ private String productIds;
+
+ @ApiModelProperty(value = "使用门槛0-无门槛 1-有门槛")
+ private Boolean hasUseLimit;
+
+ @ApiModelProperty(value = "满多少元使用 0代表无限制")
+ private BigDecimal atLeast;
+
+ @ApiModelProperty(value = "发放面额 当type为reward时需要添加")
+ private BigDecimal money;
+
+ @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加")
+ private BigDecimal discount;
+
+ @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加")
+ private BigDecimal discountLimit;
+
+ @ApiModelProperty(value = "最低金额 当type为radom时需要添加")
+ private BigDecimal minMoney;
+
+ @ApiModelProperty(value = "最大金额 当type为radom时需要添加")
+ private BigDecimal maxMoney;
+
+ @ApiModelProperty(value = "过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期")
+ private Boolean validityType;
+
+ @ApiModelProperty(value = "使用开始日期 过期类型1时必填")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] startUseTime;
+
+ @ApiModelProperty(value = "使用结束日期 过期类型1时必填")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] endUseTime;
+
+ @ApiModelProperty(value = "当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效")
+ private Integer fixedTerm;
+
+ @ApiModelProperty(value = "是否无限制0-否 1是")
+ private Boolean whetherLimitless;
+
+ @ApiModelProperty(value = "每人最大领取个数")
+ private Integer maxFetch;
+
+ @ApiModelProperty(value = "是否开启过期提醒0-不开启 1-开启")
+ private Boolean whetherExpireNotice;
+
+ @ApiModelProperty(value = "过期前N天提醒")
+ private Integer expireNoticeFixedTerm;
+
+ @ApiModelProperty(value = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用")
+ private Boolean whetherForbidPreference;
+
+ @ApiModelProperty(value = "是否显示")
+ private Integer whetherShow;
+
+ @ApiModelProperty(value = "订单的优惠总金额")
+ private BigDecimal discountOrderMoney;
+
+ @ApiModelProperty(value = "用券总成交额")
+ private BigDecimal orderMoney;
+
+ @ApiModelProperty(value = "是否禁止发放0-否 1-是")
+ private Boolean whetherForbidden;
+
+ @ApiModelProperty(value = "使用优惠券购买的商品数量")
+ private Integer orderGoodsNum;
+
+ @ApiModelProperty(value = "状态(1进行中2已结束-1已关闭)")
+ private Integer status;
+
+ @ApiModelProperty(value = "有效日期结束时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] endTime;
+
+ @ApiModelProperty(value = "创建时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] createTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempletePageReqVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempletePageReqVO.java
new file mode 100644
index 000000000..92622d793
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempletePageReqVO.java
@@ -0,0 +1,122 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo;
+
+import lombok.*;
+
+import java.math.BigDecimal;
+import java.util.*;
+import io.swagger.annotations.*;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@ApiModel("管理后台 - 优惠券模板分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class CouponTempletePageReqVO extends PageParam {
+
+ @ApiModelProperty(value = "优惠券类型 reward-满减 discount-折扣 random-随机")
+ private String type;
+
+ @ApiModelProperty(value = "优惠券名称")
+ private String name;
+
+ @ApiModelProperty(value = "名称备注")
+ private String couponNameRemark;
+
+ @ApiModelProperty(value = "优惠券图片")
+ private String image;
+
+ @ApiModelProperty(value = "发放数量")
+ private Integer count;
+
+ @ApiModelProperty(value = "已领取数量")
+ private Integer leadCount;
+
+ @ApiModelProperty(value = "已使用数量")
+ private Integer usedCount;
+
+ @ApiModelProperty(value = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用")
+ private Boolean goodsType;
+
+ @ApiModelProperty(value = "适用商品id")
+ private String productIds;
+
+ @ApiModelProperty(value = "使用门槛0-无门槛 1-有门槛")
+ private Boolean hasUseLimit;
+
+ @ApiModelProperty(value = "满多少元使用 0代表无限制")
+ private BigDecimal atLeast;
+
+ @ApiModelProperty(value = "发放面额 当type为reward时需要添加")
+ private BigDecimal money;
+
+ @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加")
+ private BigDecimal discount;
+
+ @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加")
+ private BigDecimal discountLimit;
+
+ @ApiModelProperty(value = "最低金额 当type为radom时需要添加")
+ private BigDecimal minMoney;
+
+ @ApiModelProperty(value = "最大金额 当type为radom时需要添加")
+ private BigDecimal maxMoney;
+
+ @ApiModelProperty(value = "过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期")
+ private Boolean validityType;
+
+ @ApiModelProperty(value = "使用开始日期 过期类型1时必填")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] startUseTime;
+
+ @ApiModelProperty(value = "使用结束日期 过期类型1时必填")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] endUseTime;
+
+ @ApiModelProperty(value = "当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效")
+ private Integer fixedTerm;
+
+ @ApiModelProperty(value = "是否无限制0-否 1是")
+ private Boolean whetherLimitless;
+
+ @ApiModelProperty(value = "每人最大领取个数")
+ private Integer maxFetch;
+
+ @ApiModelProperty(value = "是否开启过期提醒0-不开启 1-开启")
+ private Boolean whetherExpireNotice;
+
+ @ApiModelProperty(value = "过期前N天提醒")
+ private Integer expireNoticeFixedTerm;
+
+ @ApiModelProperty(value = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用")
+ private Boolean whetherForbidPreference;
+
+ @ApiModelProperty(value = "是否显示")
+ private Integer whetherShow;
+
+ @ApiModelProperty(value = "订单的优惠总金额")
+ private BigDecimal discountOrderMoney;
+
+ @ApiModelProperty(value = "用券总成交额")
+ private BigDecimal orderMoney;
+
+ @ApiModelProperty(value = "是否禁止发放0-否 1-是")
+ private Boolean whetherForbidden;
+
+ @ApiModelProperty(value = "使用优惠券购买的商品数量")
+ private Integer orderGoodsNum;
+
+ @ApiModelProperty(value = "状态(1进行中2已结束-1已关闭)")
+ private Integer status;
+
+ @ApiModelProperty(value = "有效日期结束时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] endTime;
+
+ @ApiModelProperty(value = "创建时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date[] createTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteRespVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteRespVO.java
new file mode 100644
index 000000000..318492a24
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteRespVO.java
@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.annotations.*;
+
+@ApiModel("管理后台 - 优惠券模板 Response VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class CouponTempleteRespVO extends CouponTempleteBaseVO {
+
+ @ApiModelProperty(value = "用户ID", required = true)
+ private Long id;
+
+ @ApiModelProperty(value = "创建时间", required = true)
+ private Date createTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteUpdateReqVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteUpdateReqVO.java
new file mode 100644
index 000000000..7d0fb7544
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupontemplete/vo/CouponTempleteUpdateReqVO.java
@@ -0,0 +1,17 @@
+package cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo;
+
+import lombok.*;
+import io.swagger.annotations.*;
+import javax.validation.constraints.*;
+
+@ApiModel("管理后台 - 优惠券模板更新 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class CouponTempleteUpdateReqVO extends CouponTempleteBaseVO {
+
+ @ApiModelProperty(value = "用户ID", required = true)
+ @NotNull(message = "用户ID不能为空")
+ private Long id;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/convert/CouponTemplete/CouponTempleteConvert.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/convert/CouponTemplete/CouponTempleteConvert.java
new file mode 100644
index 000000000..ddd774053
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/convert/CouponTemplete/CouponTempleteConvert.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.coupon.convert.CouponTemplete;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteCreateReqVO;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteExcelVO;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteRespVO;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteUpdateReqVO;
+import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+
+/**
+ * 优惠券模板 Convert
+ *
+ * @author wxr
+ */
+@Mapper
+public interface CouponTempleteConvert {
+
+ CouponTempleteConvert INSTANCE = Mappers.getMapper(CouponTempleteConvert.class);
+
+ CouponTempleteDO convert(CouponTempleteCreateReqVO bean);
+
+ CouponTempleteDO convert(CouponTempleteUpdateReqVO bean);
+
+ CouponTempleteRespVO convert(CouponTempleteDO bean);
+
+ List convertList(List list);
+
+ PageResult convertPage(PageResult page);
+
+ List convertList02(List list);
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/convert/coupon/CouponConvert.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/convert/coupon/CouponConvert.java
new file mode 100644
index 000000000..e4dab938b
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/convert/coupon/CouponConvert.java
@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.module.coupon.convert.coupon;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo.*;
+import cn.iocoder.yudao.module.coupon.dal.dataobject.coupon.CouponDO;
+
+/**
+ * 优惠券 Convert
+ *
+ * @author wxr
+ */
+@Mapper
+public interface CouponConvert {
+
+ CouponConvert INSTANCE = Mappers.getMapper(CouponConvert.class);
+
+ CouponDO convert(CouponCreateReqVO bean);
+
+ CouponDO convert(CouponUpdateReqVO bean);
+
+ CouponRespVO convert(CouponDO bean);
+
+ List convertList(List list);
+
+ PageResult convertPage(PageResult page);
+
+ List convertList02(List list);
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/dataobject/CouponTemplete/CouponTempleteDO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/dataobject/CouponTemplete/CouponTempleteDO.java
new file mode 100644
index 000000000..106c459a1
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/dataobject/CouponTemplete/CouponTempleteDO.java
@@ -0,0 +1,158 @@
+package cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete;
+
+import lombok.*;
+import java.util.*;
+import java.math.BigDecimal;
+import com.baomidou.mybatisplus.annotation.*;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+
+/**
+ * 优惠券模板 DO
+ *
+ * @author wxr
+ */
+@TableName("coupon_templete")
+@KeySequence("coupon_templete_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class CouponTempleteDO extends BaseDO {
+
+ /**
+ * 用户ID
+ */
+ @TableId
+ private Long id;
+ /**
+ * 优惠券类型 reward-满减 discount-折扣 random-随机
+ */
+ private String type;
+ /**
+ * 优惠券名称
+ */
+ private String name;
+ /**
+ * 名称备注
+ */
+ private String couponNameRemark;
+ /**
+ * 优惠券图片
+ */
+ private String image;
+ /**
+ * 发放数量
+ */
+ private Integer count;
+ /**
+ * 已领取数量
+ */
+ private Integer leadCount;
+ /**
+ * 已使用数量
+ */
+ private Integer usedCount;
+ /**
+ * 适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用
+ */
+ private Boolean goodsType;
+ /**
+ * 适用商品id
+ */
+ private String productIds;
+ /**
+ * 使用门槛0-无门槛 1-有门槛
+ */
+ private Boolean hasUseLimit;
+ /**
+ * 满多少元使用 0代表无限制
+ */
+ private BigDecimal atLeast;
+ /**
+ * 发放面额 当type为reward时需要添加
+ */
+ private BigDecimal money;
+ /**
+ * 1 =< 折扣 <= 9.9 当type为discount时需要添加
+ */
+ private BigDecimal discount;
+ /**
+ * 最多折扣金额 当type为discount时可选择性添加
+ */
+ private BigDecimal discountLimit;
+ /**
+ * 最低金额 当type为radom时需要添加
+ */
+ private BigDecimal minMoney;
+ /**
+ * 最大金额 当type为radom时需要添加
+ */
+ private BigDecimal maxMoney;
+ /**
+ * 过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期
+ */
+ private Boolean validityType;
+ /**
+ * 使用开始日期 过期类型1时必填
+ */
+ private Date startUseTime;
+ /**
+ * 使用结束日期 过期类型1时必填
+ */
+ private Date endUseTime;
+ /**
+ * 当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效
+ */
+ private Integer fixedTerm;
+ /**
+ * 是否无限制0-否 1是
+ */
+ private Boolean whetherLimitless;
+ /**
+ * 每人最大领取个数
+ */
+ private Integer maxFetch;
+ /**
+ * 是否开启过期提醒0-不开启 1-开启
+ */
+ private Boolean whetherExpireNotice;
+ /**
+ * 过期前N天提醒
+ */
+ private Integer expireNoticeFixedTerm;
+ /**
+ * 优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用
+ */
+ private Boolean whetherForbidPreference;
+ /**
+ * 是否显示
+ */
+ private Integer whetherShow;
+ /**
+ * 订单的优惠总金额
+ */
+ private BigDecimal discountOrderMoney;
+ /**
+ * 用券总成交额
+ */
+ private BigDecimal orderMoney;
+ /**
+ * 是否禁止发放0-否 1-是
+ */
+ private Boolean whetherForbidden;
+ /**
+ * 使用优惠券购买的商品数量
+ */
+ private Integer orderGoodsNum;
+ /**
+ * 状态(1进行中2已结束-1已关闭)
+ */
+ private Integer status;
+ /**
+ * 有效日期结束时间
+ */
+ private Date endTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/dataobject/coupon/CouponDO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/dataobject/coupon/CouponDO.java
new file mode 100644
index 000000000..70e3aae20
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/dataobject/coupon/CouponDO.java
@@ -0,0 +1,118 @@
+package cn.iocoder.yudao.module.coupon.dal.dataobject.coupon;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import lombok.*;
+import java.util.*;
+import java.math.BigDecimal;
+import com.baomidou.mybatisplus.annotation.*;
+
+/**
+ * 优惠券 DO
+ *
+ * @author wxr
+ */
+@TableName("coupon")
+@KeySequence("coupon_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class CouponDO extends BaseDO {
+
+ /**
+ * 用户ID
+ */
+ @TableId
+ private Long id;
+ /**
+ * 优惠券类型 reward-满减 discount-折扣 random-随机
+ */
+ private String type;
+ /**
+ * 优惠券名称
+ */
+ private String name;
+ /**
+ * 优惠券类型id
+ */
+ private Long couponTypeId;
+ /**
+ * 优惠券编码
+ */
+ private String couponCode;
+ /**
+ * 领用人
+ */
+ private Long memberId;
+ /**
+ * 优惠券使用订单id
+ */
+ private Long useOrderId;
+ /**
+ * 适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用
+ */
+ private Boolean goodsType;
+ /**
+ * 适用商品id
+ */
+ private String goodsIds;
+ /**
+ * 最小金额
+ */
+ private BigDecimal atLeast;
+ /**
+ * 面额
+ */
+ private BigDecimal money;
+ /**
+ * 1 =< 折扣 <= 9.9 当type为discount时需要添加
+ */
+ private BigDecimal discount;
+ /**
+ * 最多折扣金额 当type为discount时可选择性添加
+ */
+ private BigDecimal discountLimit;
+ /**
+ * 优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用
+ */
+ private Boolean whetherForbidPreference;
+ /**
+ * 是否开启过期提醒0-不开启 1-开启
+ */
+ private Boolean whetherExpireNotice;
+ /**
+ * 过期前N天提醒
+ */
+ private Integer expireNoticeFixedTerm;
+ /**
+ * 是否已提醒
+ */
+ private Boolean whetherNoticed;
+ /**
+ * 优惠券状态 1已领用(未使用) 2已使用 3已过期
+ */
+ private Integer state;
+ /**
+ * 获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取
+ */
+ private Boolean getType;
+ /**
+ * 领取时间
+ */
+ private Date fetchTime;
+ /**
+ * 使用时间
+ */
+ private Date useTime;
+ /**
+ * 可使用的开始时间
+ */
+ private Date startTime;
+ /**
+ * 有效期结束时间
+ */
+ private Date endTime;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/mysql/CouponTemplete/CouponTempleteMapper.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/mysql/CouponTemplete/CouponTempleteMapper.java
new file mode 100644
index 000000000..b930f113f
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/mysql/CouponTemplete/CouponTempleteMapper.java
@@ -0,0 +1,98 @@
+package cn.iocoder.yudao.module.coupon.dal.mysql.CouponTemplete;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteExportReqVO;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempletePageReqVO;
+import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
+import org.apache.ibatis.annotations.Mapper;
+
+
+/**
+ * 优惠券模板 Mapper
+ *
+ * @author wxr
+ */
+@Mapper
+public interface CouponTempleteMapper extends BaseMapperX {
+
+ default PageResult selectPage(CouponTempletePageReqVO reqVO) {
+ return selectPage(reqVO, new LambdaQueryWrapperX()
+ .eqIfPresent(CouponTempleteDO::getType, reqVO.getType())
+ .likeIfPresent(CouponTempleteDO::getName, reqVO.getName())
+ .eqIfPresent(CouponTempleteDO::getCouponNameRemark, reqVO.getCouponNameRemark())
+ .eqIfPresent(CouponTempleteDO::getImage, reqVO.getImage())
+ .eqIfPresent(CouponTempleteDO::getCount, reqVO.getCount())
+ .eqIfPresent(CouponTempleteDO::getLeadCount, reqVO.getLeadCount())
+ .eqIfPresent(CouponTempleteDO::getUsedCount, reqVO.getUsedCount())
+ .eqIfPresent(CouponTempleteDO::getGoodsType, reqVO.getGoodsType())
+ .eqIfPresent(CouponTempleteDO::getProductIds, reqVO.getProductIds())
+ .eqIfPresent(CouponTempleteDO::getHasUseLimit, reqVO.getHasUseLimit())
+ .eqIfPresent(CouponTempleteDO::getAtLeast, reqVO.getAtLeast())
+ .eqIfPresent(CouponTempleteDO::getMoney, reqVO.getMoney())
+ .eqIfPresent(CouponTempleteDO::getDiscount, reqVO.getDiscount())
+ .eqIfPresent(CouponTempleteDO::getDiscountLimit, reqVO.getDiscountLimit())
+ .eqIfPresent(CouponTempleteDO::getMinMoney, reqVO.getMinMoney())
+ .eqIfPresent(CouponTempleteDO::getMaxMoney, reqVO.getMaxMoney())
+ .eqIfPresent(CouponTempleteDO::getValidityType, reqVO.getValidityType())
+ .betweenIfPresent(CouponTempleteDO::getStartUseTime, reqVO.getStartUseTime())
+ .betweenIfPresent(CouponTempleteDO::getEndUseTime, reqVO.getEndUseTime())
+ .eqIfPresent(CouponTempleteDO::getFixedTerm, reqVO.getFixedTerm())
+ .eqIfPresent(CouponTempleteDO::getWhetherLimitless, reqVO.getWhetherLimitless())
+ .eqIfPresent(CouponTempleteDO::getMaxFetch, reqVO.getMaxFetch())
+ .eqIfPresent(CouponTempleteDO::getWhetherExpireNotice, reqVO.getWhetherExpireNotice())
+ .eqIfPresent(CouponTempleteDO::getExpireNoticeFixedTerm, reqVO.getExpireNoticeFixedTerm())
+ .eqIfPresent(CouponTempleteDO::getWhetherForbidPreference, reqVO.getWhetherForbidPreference())
+ .eqIfPresent(CouponTempleteDO::getWhetherShow, reqVO.getWhetherShow())
+ .eqIfPresent(CouponTempleteDO::getDiscountOrderMoney, reqVO.getDiscountOrderMoney())
+ .eqIfPresent(CouponTempleteDO::getOrderMoney, reqVO.getOrderMoney())
+ .eqIfPresent(CouponTempleteDO::getWhetherForbidden, reqVO.getWhetherForbidden())
+ .eqIfPresent(CouponTempleteDO::getOrderGoodsNum, reqVO.getOrderGoodsNum())
+ .eqIfPresent(CouponTempleteDO::getStatus, reqVO.getStatus())
+ .betweenIfPresent(CouponTempleteDO::getEndTime, reqVO.getEndTime())
+ .betweenIfPresent(CouponTempleteDO::getCreateTime, reqVO.getCreateTime())
+ .orderByDesc(CouponTempleteDO::getId));
+ }
+
+ default List selectList(CouponTempleteExportReqVO reqVO) {
+ return selectList(new LambdaQueryWrapperX()
+ .eqIfPresent(CouponTempleteDO::getType, reqVO.getType())
+ .likeIfPresent(CouponTempleteDO::getName, reqVO.getName())
+ .eqIfPresent(CouponTempleteDO::getCouponNameRemark, reqVO.getCouponNameRemark())
+ .eqIfPresent(CouponTempleteDO::getImage, reqVO.getImage())
+ .eqIfPresent(CouponTempleteDO::getCount, reqVO.getCount())
+ .eqIfPresent(CouponTempleteDO::getLeadCount, reqVO.getLeadCount())
+ .eqIfPresent(CouponTempleteDO::getUsedCount, reqVO.getUsedCount())
+ .eqIfPresent(CouponTempleteDO::getGoodsType, reqVO.getGoodsType())
+ .eqIfPresent(CouponTempleteDO::getProductIds, reqVO.getProductIds())
+ .eqIfPresent(CouponTempleteDO::getHasUseLimit, reqVO.getHasUseLimit())
+ .eqIfPresent(CouponTempleteDO::getAtLeast, reqVO.getAtLeast())
+ .eqIfPresent(CouponTempleteDO::getMoney, reqVO.getMoney())
+ .eqIfPresent(CouponTempleteDO::getDiscount, reqVO.getDiscount())
+ .eqIfPresent(CouponTempleteDO::getDiscountLimit, reqVO.getDiscountLimit())
+ .eqIfPresent(CouponTempleteDO::getMinMoney, reqVO.getMinMoney())
+ .eqIfPresent(CouponTempleteDO::getMaxMoney, reqVO.getMaxMoney())
+ .eqIfPresent(CouponTempleteDO::getValidityType, reqVO.getValidityType())
+ .betweenIfPresent(CouponTempleteDO::getStartUseTime, reqVO.getStartUseTime())
+ .betweenIfPresent(CouponTempleteDO::getEndUseTime, reqVO.getEndUseTime())
+ .eqIfPresent(CouponTempleteDO::getFixedTerm, reqVO.getFixedTerm())
+ .eqIfPresent(CouponTempleteDO::getWhetherLimitless, reqVO.getWhetherLimitless())
+ .eqIfPresent(CouponTempleteDO::getMaxFetch, reqVO.getMaxFetch())
+ .eqIfPresent(CouponTempleteDO::getWhetherExpireNotice, reqVO.getWhetherExpireNotice())
+ .eqIfPresent(CouponTempleteDO::getExpireNoticeFixedTerm, reqVO.getExpireNoticeFixedTerm())
+ .eqIfPresent(CouponTempleteDO::getWhetherForbidPreference, reqVO.getWhetherForbidPreference())
+ .eqIfPresent(CouponTempleteDO::getWhetherShow, reqVO.getWhetherShow())
+ .eqIfPresent(CouponTempleteDO::getDiscountOrderMoney, reqVO.getDiscountOrderMoney())
+ .eqIfPresent(CouponTempleteDO::getOrderMoney, reqVO.getOrderMoney())
+ .eqIfPresent(CouponTempleteDO::getWhetherForbidden, reqVO.getWhetherForbidden())
+ .eqIfPresent(CouponTempleteDO::getOrderGoodsNum, reqVO.getOrderGoodsNum())
+ .eqIfPresent(CouponTempleteDO::getStatus, reqVO.getStatus())
+ .betweenIfPresent(CouponTempleteDO::getEndTime, reqVO.getEndTime())
+ .betweenIfPresent(CouponTempleteDO::getCreateTime, reqVO.getCreateTime())
+ .orderByDesc(CouponTempleteDO::getId));
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/mysql/coupon/CouponMapper.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/mysql/coupon/CouponMapper.java
new file mode 100644
index 000000000..8c9014694
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/mysql/coupon/CouponMapper.java
@@ -0,0 +1,76 @@
+package cn.iocoder.yudao.module.coupon.dal.mysql.coupon;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.coupon.dal.dataobject.coupon.CouponDO;
+import org.apache.ibatis.annotations.Mapper;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo.*;
+
+/**
+ * 优惠券 Mapper
+ *
+ * @author wxr
+ */
+@Mapper
+public interface CouponMapper extends BaseMapperX {
+
+ default PageResult selectPage(CouponPageReqVO reqVO) {
+ return selectPage(reqVO, new LambdaQueryWrapperX()
+ .eqIfPresent(CouponDO::getType, reqVO.getType())
+ .likeIfPresent(CouponDO::getName, reqVO.getName())
+ .eqIfPresent(CouponDO::getCouponTypeId, reqVO.getCouponTypeId())
+ .eqIfPresent(CouponDO::getCouponCode, reqVO.getCouponCode())
+ .eqIfPresent(CouponDO::getMemberId, reqVO.getMemberId())
+ .eqIfPresent(CouponDO::getUseOrderId, reqVO.getUseOrderId())
+ .eqIfPresent(CouponDO::getGoodsType, reqVO.getGoodsType())
+ .eqIfPresent(CouponDO::getGoodsIds, reqVO.getGoodsIds())
+ .eqIfPresent(CouponDO::getAtLeast, reqVO.getAtLeast())
+ .eqIfPresent(CouponDO::getMoney, reqVO.getMoney())
+ .eqIfPresent(CouponDO::getDiscount, reqVO.getDiscount())
+ .eqIfPresent(CouponDO::getDiscountLimit, reqVO.getDiscountLimit())
+ .eqIfPresent(CouponDO::getWhetherForbidPreference, reqVO.getWhetherForbidPreference())
+ .eqIfPresent(CouponDO::getWhetherExpireNotice, reqVO.getWhetherExpireNotice())
+ .eqIfPresent(CouponDO::getExpireNoticeFixedTerm, reqVO.getExpireNoticeFixedTerm())
+ .eqIfPresent(CouponDO::getWhetherNoticed, reqVO.getWhetherNoticed())
+ .eqIfPresent(CouponDO::getState, reqVO.getState())
+ .eqIfPresent(CouponDO::getGetType, reqVO.getGetType())
+ .betweenIfPresent(CouponDO::getFetchTime, reqVO.getFetchTime())
+ .betweenIfPresent(CouponDO::getUseTime, reqVO.getUseTime())
+ .betweenIfPresent(CouponDO::getStartTime, reqVO.getStartTime())
+ .betweenIfPresent(CouponDO::getEndTime, reqVO.getEndTime())
+ .betweenIfPresent(CouponDO::getCreateTime, reqVO.getCreateTime())
+ .orderByDesc(CouponDO::getId));
+ }
+
+ default List selectList(CouponExportReqVO reqVO) {
+ return selectList(new LambdaQueryWrapperX()
+ .eqIfPresent(CouponDO::getType, reqVO.getType())
+ .likeIfPresent(CouponDO::getName, reqVO.getName())
+ .eqIfPresent(CouponDO::getCouponTypeId, reqVO.getCouponTypeId())
+ .eqIfPresent(CouponDO::getCouponCode, reqVO.getCouponCode())
+ .eqIfPresent(CouponDO::getMemberId, reqVO.getMemberId())
+ .eqIfPresent(CouponDO::getUseOrderId, reqVO.getUseOrderId())
+ .eqIfPresent(CouponDO::getGoodsType, reqVO.getGoodsType())
+ .eqIfPresent(CouponDO::getGoodsIds, reqVO.getGoodsIds())
+ .eqIfPresent(CouponDO::getAtLeast, reqVO.getAtLeast())
+ .eqIfPresent(CouponDO::getMoney, reqVO.getMoney())
+ .eqIfPresent(CouponDO::getDiscount, reqVO.getDiscount())
+ .eqIfPresent(CouponDO::getDiscountLimit, reqVO.getDiscountLimit())
+ .eqIfPresent(CouponDO::getWhetherForbidPreference, reqVO.getWhetherForbidPreference())
+ .eqIfPresent(CouponDO::getWhetherExpireNotice, reqVO.getWhetherExpireNotice())
+ .eqIfPresent(CouponDO::getExpireNoticeFixedTerm, reqVO.getExpireNoticeFixedTerm())
+ .eqIfPresent(CouponDO::getWhetherNoticed, reqVO.getWhetherNoticed())
+ .eqIfPresent(CouponDO::getState, reqVO.getState())
+ .eqIfPresent(CouponDO::getGetType, reqVO.getGetType())
+ .betweenIfPresent(CouponDO::getFetchTime, reqVO.getFetchTime())
+ .betweenIfPresent(CouponDO::getUseTime, reqVO.getUseTime())
+ .betweenIfPresent(CouponDO::getStartTime, reqVO.getStartTime())
+ .betweenIfPresent(CouponDO::getEndTime, reqVO.getEndTime())
+ .betweenIfPresent(CouponDO::getCreateTime, reqVO.getCreateTime())
+ .orderByDesc(CouponDO::getId));
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/CouponTemplete/CouponTempleteService.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/CouponTemplete/CouponTempleteService.java
new file mode 100644
index 000000000..f0ad215c8
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/CouponTemplete/CouponTempleteService.java
@@ -0,0 +1,70 @@
+package cn.iocoder.yudao.module.coupon.service.CouponTemplete;
+
+import java.util.*;
+import javax.validation.*;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.*;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
+
+/**
+ * 优惠券模板 Service 接口
+ *
+ * @author wxr
+ */
+public interface CouponTempleteService {
+
+ /**
+ * 创建优惠券模板
+ *
+ * @param createReqVO 创建信息
+ * @return 编号
+ */
+ Long create(@Valid CouponTempleteCreateReqVO createReqVO);
+
+ /**
+ * 更新优惠券模板
+ *
+ * @param updateReqVO 更新信息
+ */
+ void update(@Valid CouponTempleteUpdateReqVO updateReqVO);
+
+ /**
+ * 删除优惠券模板
+ *
+ * @param id 编号
+ */
+ void delete(Long id);
+
+ /**
+ * 获得优惠券模板
+ *
+ * @param id 编号
+ * @return 优惠券模板
+ */
+ CouponTempleteDO get(Long id);
+
+ /**
+ * 获得优惠券模板列表
+ *
+ * @param ids 编号
+ * @return 优惠券模板列表
+ */
+ List getList(Collection ids);
+
+ /**
+ * 获得优惠券模板分页
+ *
+ * @param pageReqVO 分页查询
+ * @return 优惠券模板分页
+ */
+ PageResult getPage(CouponTempletePageReqVO pageReqVO);
+
+ /**
+ * 获得优惠券模板列表, 用于 Excel 导出
+ *
+ * @param exportReqVO 查询条件
+ * @return 优惠券模板列表
+ */
+ List getList(CouponTempleteExportReqVO exportReqVO);
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/CouponTemplete/CouponTempleteServiceImpl.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/CouponTemplete/CouponTempleteServiceImpl.java
new file mode 100644
index 000000000..982b2f1b2
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/CouponTemplete/CouponTempleteServiceImpl.java
@@ -0,0 +1,87 @@
+package cn.iocoder.yudao.module.coupon.service.CouponTemplete;
+
+import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteCreateReqVO;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteExportReqVO;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempletePageReqVO;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupontemplete.vo.CouponTempleteUpdateReqVO;
+import cn.iocoder.yudao.module.coupon.convert.CouponTemplete.CouponTempleteConvert;
+import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
+import cn.iocoder.yudao.module.coupon.dal.mysql.CouponTemplete.CouponTempleteMapper;
+import cn.iocoder.yudao.module.coupon.service.CouponTemplete.CouponTempleteService;
+import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+
+import java.util.*;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.CouponTemplete.enums.ErrorCodeConstants.COUPON_TEMPLETE_NOT_EXISTS;
+
+/**
+ * 优惠券模板 Service 实现类
+ *
+ * @author wxr
+ */
+@Service
+@Validated
+public class CouponTempleteServiceImpl implements CouponTempleteService {
+
+ @Resource
+ private CouponTempleteMapper couponTempleteMapper;
+
+ @Override
+ public Long create(CouponTempleteCreateReqVO createReqVO) {
+ // 插入
+ CouponTempleteDO couponTempleteDO = CouponTempleteConvert.INSTANCE.convert(createReqVO);
+ couponTempleteMapper.insert(couponTempleteDO);
+ // 返回
+ return couponTempleteDO.getId();
+ }
+
+ @Override
+ public void update(CouponTempleteUpdateReqVO updateReqVO) {
+ // 校验存在
+ this.validateExists(updateReqVO.getId());
+ // 更新
+ CouponTempleteDO updateObj = CouponTempleteConvert.INSTANCE.convert(updateReqVO);
+ couponTempleteMapper.updateById(updateObj);
+ }
+
+ @Override
+ public void delete(Long id) {
+ // 校验存在
+ this.validateExists(id);
+ // 删除
+ couponTempleteMapper.deleteById(id);
+ }
+
+ private void validateExists(Long id) {
+ if (couponTempleteMapper.selectById(id) == null) {
+ throw exception(COUPON_TEMPLETE_NOT_EXISTS);
+ }
+ }
+
+ @Override
+ public CouponTempleteDO get(Long id) {
+ return couponTempleteMapper.selectById(id);
+ }
+
+ @Override
+ public List getList(Collection ids) {
+ return couponTempleteMapper.selectBatchIds(ids);
+ }
+
+ @Override
+ public PageResult getPage(CouponTempletePageReqVO pageReqVO) {
+ return couponTempleteMapper.selectPage(pageReqVO);
+ }
+
+ @Override
+ public List getList(CouponTempleteExportReqVO exportReqVO) {
+ return couponTempleteMapper.selectList(exportReqVO);
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/coupon/CouponService.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/coupon/CouponService.java
new file mode 100644
index 000000000..a3ca66611
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/coupon/CouponService.java
@@ -0,0 +1,70 @@
+package cn.iocoder.yudao.module.coupon.service.coupon;
+
+import java.util.*;
+import javax.validation.*;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo.*;
+import cn.iocoder.yudao.module.coupon.dal.dataobject.coupon.CouponDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+/**
+ * 优惠券 Service 接口
+ *
+ * @author wxr
+ */
+public interface CouponService {
+
+ /**
+ * 创建优惠券
+ *
+ * @param createReqVO 创建信息
+ * @return 编号
+ */
+ Long create(@Valid CouponCreateReqVO createReqVO);
+
+ /**
+ * 更新优惠券
+ *
+ * @param updateReqVO 更新信息
+ */
+ void update(@Valid CouponUpdateReqVO updateReqVO);
+
+ /**
+ * 删除优惠券
+ *
+ * @param id 编号
+ */
+ void delete(Long id);
+
+ /**
+ * 获得优惠券
+ *
+ * @param id 编号
+ * @return 优惠券
+ */
+ CouponDO get(Long id);
+
+ /**
+ * 获得优惠券列表
+ *
+ * @param ids 编号
+ * @return 优惠券列表
+ */
+ List getList(Collection ids);
+
+ /**
+ * 获得优惠券分页
+ *
+ * @param pageReqVO 分页查询
+ * @return 优惠券分页
+ */
+ PageResult getPage(CouponPageReqVO pageReqVO);
+
+ /**
+ * 获得优惠券列表, 用于 Excel 导出
+ *
+ * @param exportReqVO 查询条件
+ * @return 优惠券列表
+ */
+ List getList(CouponExportReqVO exportReqVO);
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/coupon/CouponServiceImpl.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/coupon/CouponServiceImpl.java
new file mode 100644
index 000000000..99f87ecfc
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/coupon/CouponServiceImpl.java
@@ -0,0 +1,82 @@
+package cn.iocoder.yudao.module.coupon.service.coupon;
+
+import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+
+import java.util.*;
+import cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo.*;
+import cn.iocoder.yudao.module.coupon.dal.dataobject.coupon.CouponDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import cn.iocoder.yudao.module.coupon.convert.coupon.CouponConvert;
+import cn.iocoder.yudao.module.coupon.dal.mysql.coupon.CouponMapper;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.CouponTemplete.enums.ErrorCodeConstants.COUPON_NOT_EXISTS;
+
+/**
+ * 优惠券 Service 实现类
+ *
+ * @author wxr
+ */
+@Service
+@Validated
+public class CouponServiceImpl implements CouponService {
+
+ @Resource
+ private CouponMapper couponMapper;
+
+ @Override
+ public Long create(CouponCreateReqVO createReqVO) {
+ // 插入
+ CouponDO couponDO = CouponConvert.INSTANCE.convert(createReqVO);
+ couponMapper.insert(couponDO);
+ // 返回
+ return couponDO.getId();
+ }
+
+ @Override
+ public void update(CouponUpdateReqVO updateReqVO) {
+ // 校验存在
+ this.validateExists(updateReqVO.getId());
+ // 更新
+ CouponDO updateObj = CouponConvert.INSTANCE.convert(updateReqVO);
+ couponMapper.updateById(updateObj);
+ }
+
+ @Override
+ public void delete(Long id) {
+ // 校验存在
+ this.validateExists(id);
+ // 删除
+ couponMapper.deleteById(id);
+ }
+
+ private void validateExists(Long id) {
+ if (couponMapper.selectById(id) == null) {
+ throw exception(COUPON_NOT_EXISTS);
+ }
+ }
+
+ @Override
+ public CouponDO get(Long id) {
+ return couponMapper.selectById(id);
+ }
+
+ @Override
+ public List getList(Collection ids) {
+ return couponMapper.selectBatchIds(ids);
+ }
+
+ @Override
+ public PageResult getPage(CouponPageReqVO pageReqVO) {
+ return couponMapper.selectPage(pageReqVO);
+ }
+
+ @Override
+ public List getList(CouponExportReqVO exportReqVO) {
+ return couponMapper.selectList(exportReqVO);
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/resources/mapper/CouponTemplete/CouponTempleteMapper.xml b/yudao-module-mall/yudao-module-coupon-biz/src/main/resources/mapper/CouponTemplete/CouponTempleteMapper.xml
new file mode 100644
index 000000000..b7db75a77
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/resources/mapper/CouponTemplete/CouponTempleteMapper.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/yudao-module-mall/yudao-module-coupon-biz/src/main/resources/mapper/coupon/CouponMapper.xml b/yudao-module-mall/yudao-module-coupon-biz/src/main/resources/mapper/coupon/CouponMapper.xml
new file mode 100644
index 000000000..a5e70cf5d
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/resources/mapper/coupon/CouponMapper.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+