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/CouponExpireTimeTypeEnum.java b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponExpireTimeTypeEnum.java
new file mode 100644
index 000000000..be6d2a90e
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponExpireTimeTypeEnum.java
@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.CouponTemplete.enums;
+
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+
+/**
+ * 优惠券 - 是否开启过期提醒
+ *
+ * @author Sin
+ */
+@RequiredArgsConstructor
+@Getter
+public enum CouponExpireTimeTypeEnum {
+
+ OPEN(1,"不开启"),CLOSE(0,"开启"),;
+
+ /**
+ * 是否开启过期提醒
+ */
+ private final Integer type;
+ /**
+ * 是否开启过期提醒
+ */
+ private final String name;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponFetchTypeEnum.java b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponFetchTypeEnum.java
new file mode 100644
index 000000000..ffdd99c28
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponFetchTypeEnum.java
@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.CouponTemplete.enums;
+
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+
+/**
+ * 优惠券 - 领取是否无限制 0
+ *
+ * @author Sin
+ */
+@RequiredArgsConstructor
+@Getter
+public enum CouponFetchTypeEnum {
+
+ LIMIT(0,"否"),NOT_LIMIT(0,"开启"),;
+
+ /**
+ * 是否开启过期提醒
+ */
+ private final Integer type;
+ /**
+ * 是否开启过期提醒
+ */
+ private final String name;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponProductTypeEnum.java b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponProductTypeEnum.java
new file mode 100644
index 000000000..f5e6cf995
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponProductTypeEnum.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.CouponTemplete.enums;
+
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+
+/**
+ * 优惠券 - 优惠券类型
+ *
+ * @author Sin
+ */
+@RequiredArgsConstructor
+@Getter
+public enum CouponProductTypeEnum {
+
+ PROCESSING(1,"进行中"),
+ END(2,"已结束"),
+ CLOSE(3,"已关闭"),;
+
+ /**
+ * 优惠券类型
+ */
+ private final Integer type;
+ /**
+ * 优惠券类型名
+ */
+ private final String name;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponStatusTypeEnum.java b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponStatusTypeEnum.java
new file mode 100644
index 000000000..c58ce36b4
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponStatusTypeEnum.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.CouponTemplete.enums;
+
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+
+/**
+ * 优惠券 - 优惠券类型
+ *
+ * @author Sin
+ */
+@RequiredArgsConstructor
+@Getter
+public enum CouponStatusTypeEnum {
+
+ ALL(1,"全部商品可用"),
+ POINT_PRODUCT(2,"指定商品可用"),
+ POINT_PRODUCT_NOT(3,"指定商品不可用不能为空"),;
+
+ /**
+ * 优惠券类型
+ */
+ private final Integer type;
+ /**
+ * 优惠券类型名
+ */
+ private final String name;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponTypeEnum.java b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponTypeEnum.java
new file mode 100644
index 000000000..639d5080d
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponTypeEnum.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.CouponTemplete.enums;
+
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+
+/**
+ * 优惠券 - 优惠券类型
+ *
+ * @author Sin
+ */
+@RequiredArgsConstructor
+@Getter
+public enum CouponTypeEnum {
+
+ REWARD(1,"满减"),
+ DISCOUNT(2,"折扣"),
+ RANDOW(3,"随机"),;
+
+ /**
+ * 优惠券类型
+ */
+ private final Integer type;
+ /**
+ * 优惠券类型名
+ */
+ private final String name;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponUseLimitEnum.java b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponUseLimitEnum.java
new file mode 100644
index 000000000..61d2f429b
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponUseLimitEnum.java
@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.CouponTemplete.enums;
+
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+
+/**
+ * 优惠券 - 优惠券类型
+ *
+ * @author Sin
+ */
+@RequiredArgsConstructor
+@Getter
+public enum CouponUseLimitEnum {
+
+ HAS_LIMIT(1,"无门槛"),
+ NO_LIMIT(2,"有门槛"),;
+
+ /**
+ * 优惠券类型
+ */
+ private final Integer type;
+ /**
+ * 优惠券类型名
+ */
+ private final String name;
+
+}
diff --git a/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponValidityTypeEnum.java b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponValidityTypeEnum.java
new file mode 100644
index 000000000..6411ecbf9
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponValidityTypeEnum.java
@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.CouponTemplete.enums;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 过期类型 - 状态
+ *
+ * @author Sin
+ */
+@RequiredArgsConstructor
+@Getter
+public enum CouponValidityTypeEnum {
+
+ TIME_RANGE_EXPIRTED(1,"时间范围过期"),
+ EXPIRES_AFTER_FIXED_DATE(2,"领取之日固定日期后过期"),
+ EXPIRES_DATE_NEXT_FIEXD_DATE(3,"领取次日固定日期后过期不能为空"),;
+
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+}
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..fced9d140
--- /dev/null
+++ b/yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/ErrorCodeConstants.java
@@ -0,0 +1,27 @@
+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, "优惠券模板不存在");
+ ErrorCode MONEY_NOT_NULL = new ErrorCode(1010001001, "当type为reward时需要添加发放面额不能为空");
+ ErrorCode DISCOUNT_NOT_NULL = new ErrorCode(1010001001, "当type为discount时需要添加折扣不能为空");
+ ErrorCode DISCOUNT_LIMIT_NOT_NULL = new ErrorCode(1010001001, "当type为discount时可选择性添加最多折扣金额不能为空");
+ ErrorCode MIN_MAX_NOT_NULL = new ErrorCode(1010001001, "当type为radom时需要添加最低金额");
+ ErrorCode START_END_TIME_NOT_NULL = new ErrorCode(1010001001, "使用开始日期,使用结束日期不能为空");
+ ErrorCode FIXED_TERM_NOT_NULL = new ErrorCode(1010001001, "领取之日起或者次日N天内有效不能为空");
+
+
+ // ========== 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..6e099269a
--- /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,88 @@
+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.*;
+import java.util.*;
+
+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.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/coupon/")
+@Validated
+public class CouponController {
+
+ @Resource
+ private CouponService couponService;
+
+
+ //todo 用户优惠券
+ @PostMapping("/create")
+ @ApiOperation("用户领取优惠券")
+ @PreAuthorize("@ss.hasPermission('coupon::create')")
+ public CommonResult create(@RequestParam("couponTemplateId") Long couponTemplateId) {
+
+ return success(couponService.create(couponTemplateId));
+ }
+
+
+ @PutMapping("/update")
+ @ApiOperation("更新优惠券")
+ @PreAuthorize("@ss.hasPermission('coupon::update')")
+ public CommonResult update(@Valid @RequestBody CouponUpdateReqVO updateReqVO) {
+ couponService.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) {
+ couponService.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 = couponService.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 = couponService.getList(ids);
+ return success(CouponConvert.INSTANCE.convertList(list));
+ }
+
+ @GetMapping("/page")
+ @ApiOperation("获得优惠券分页")
+ @PreAuthorize("@ss.hasPermission('coupon::query')")
+ public CommonResult> getPage(@Valid CouponPageReqVO pageVO) {
+ PageResult pageResult = couponService.getPage(pageVO);
+ return success(CouponConvert.INSTANCE.convertPage(pageResult));
+ }
+
+
+}
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-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityRespVO.java b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponRespVO.java
similarity index 52%
rename from yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityRespVO.java
rename to yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponRespVO.java
index de7ca3af2..9055a36a0 100644
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityRespVO.java
+++ b/yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponRespVO.java
@@ -1,16 +1,16 @@
-package cn.iocoder.yudao.module.market.controller.admin.activity.vo;
+package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
import lombok.*;
import java.util.*;
import io.swagger.annotations.*;
-@ApiModel("管理后台 - 促销活动 Response VO")
+@ApiModel("管理后台 - 优惠券 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
-public class ActivityRespVO extends ActivityBaseVO {
+public class CouponRespVO extends CouponBaseVO {
- @ApiModelProperty(value = "活动编号", required = true)
+ @ApiModelProperty(value = "用户ID", required = true)
private Long id;
@ApiModelProperty(value = "创建时间", required = true)
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..40d9ac429
--- /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,81 @@
+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 java.util.*;
+
+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;
+
+@Api(tags = "管理后台 - 优惠券模板")
+@RestController
+@RequestMapping("/coupon/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));
+ }
+
+
+
+}
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..d9818344f
--- /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,172 @@
+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 = "优惠券名称", required = true)
+ @NotNull(message = "优惠券名称不能为空")
+ private String name;
+
+ @ApiModelProperty(value = "名称备注")
+ private String couponNameRemark;
+
+ @ApiModelProperty(value = "优惠券图片")
+ private String image;
+
+ /* ============判断适用商品——开始============= */
+
+
+ @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 = "优惠券类型 reward-满减 discount-折扣 random-随机", required = true)
+ @NotNull(message = "优惠券类型 reward-满减 discount-折扣 random-随机不能为空")
+ private String type;
+
+ @ApiModelProperty(value = "发放面额 当type为reward时需要添加")
+ @NotNull(message = "发放面额 当type为reward时需要添加不能为空")
+ private BigDecimal money;
+
+ @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加")
+ @NotNull(message = "1 =< 折扣 <= 9.9 当type为discount时需要添加不能为空")
+ private BigDecimal discount;
+
+ @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加")
+ @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 Integer 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天内有效")
+ @NotNull(message = "当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效不能为空")
+ private Integer fixedTerm;
+
+ @ApiModelProperty(value = "有效日期结束时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private Date endTime;
+
+ /* ============过期类型——结束============= */
+
+
+ @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 = "是否禁止发放0-否 1-是", required = true)
+ @NotNull(message = "是否禁止发放0-否 1-是不能为空")
+ private Boolean whetherForbidden;
+
+ /* ============汇总计算——开始============= */
+
+
+
+ @ApiModelProperty(value = "使用优惠券购买的商品数量", required = true)
+ @NotNull(message = "使用优惠券购买的商品数量不能为空")
+ private Integer orderGoodsNum;
+
+ @ApiModelProperty(value = "订单的优惠总金额", required = true)
+ @NotNull(message = "订单的优惠总金额不能为空")
+ private BigDecimal discountOrderMoney;
+
+ @ApiModelProperty(value = "用券总成交额", required = true)
+ @NotNull(message = "用券总成交额不能为空")
+ private BigDecimal orderMoney;
+
+ @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已结束-1已关闭)不能为空")
+ private Integer status;
+
+
+
+}
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..f3f826b81
--- /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,135 @@
+package cn.iocoder.yudao.module.coupon.service.CouponTemplete;
+
+import cn.iocoder.yudao.module.CouponTemplete.enums.CouponTypeEnum;
+import cn.iocoder.yudao.module.CouponTemplete.enums.CouponValidityTypeEnum;
+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.*;
+
+/**
+ * 优惠券模板 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);
+ /* 验证类型、判断必填*/
+ checkCouponType(createReqVO);
+
+ /*todo 验证过期类型、判断必填*/
+ checkValidityType(createReqVO);
+
+
+
+ couponTempleteMapper.insert(couponTempleteDO);
+ // 返回
+ return couponTempleteDO.getId();
+ }
+
+ /*确认优惠券类型*/
+ private void checkValidityType(CouponTempleteCreateReqVO createReqVO) {
+ Integer validtyType = createReqVO.getValidityType();
+
+ if(CouponValidityTypeEnum.TIME_RANGE_EXPIRTED.getStatus().equals(validtyType)){
+ if(createReqVO.getStartUseTime() == null||createReqVO.getEndUseTime() == null){
+ throw exception(START_END_TIME_NOT_NULL);
+ }
+ }else{
+ if(createReqVO.getFixedTerm() == null){
+ throw exception(FIXED_TERM_NOT_NULL);
+ }
+ }
+ }
+
+ private void checkCouponType(CouponTempleteCreateReqVO createReqVO) {
+
+ String couponType = createReqVO.getType();
+ //当type=reward时候,需要添加
+ if(couponType.equals(CouponTypeEnum.REWARD.getName())){
+ if(createReqVO.getMoney()==null){
+ throw exception(MONEY_NOT_NULL);
+ }
+ }else if(couponType.equals(CouponTypeEnum.DISCOUNT.getName())){
+ if(createReqVO.getDiscount()==null){
+ throw exception(DISCOUNT_NOT_NULL);
+ }
+ if(createReqVO.getDiscountLimit()==null){
+ throw exception(DISCOUNT_LIMIT_NOT_NULL);
+ }
+ }else if (couponType.equals(CouponTypeEnum.RANDOW.getName())){
+ //当type为radom时需要添加不能为空
+ if(createReqVO.getMinMoney()==null||createReqVO.getMaxMoney()==null){
+ throw exception(MIN_MAX_NOT_NULL);
+ }
+ }
+ }
+
+ @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..6a9d31520
--- /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 templateId 优惠券模板id
+ * @return 编号
+ */
+ Long create(Long templateId);
+
+ /**
+ * 更新优惠券
+ *
+ * @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..0a1737a31
--- /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,107 @@
+package cn.iocoder.yudao.module.coupon.service.coupon;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
+import cn.iocoder.yudao.module.coupon.dal.mysql.CouponTemplete.CouponTempleteMapper;
+import io.micrometer.core.instrument.Counter;
+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;
+
+ @Resource
+ private CouponTempleteMapper couponTempleteMapper;
+
+ public Long create(CouponCreateReqVO createReqVO) {
+ // 插入
+ CouponDO couponDO = CouponConvert.INSTANCE.convert(createReqVO);
+ couponMapper.insert(couponDO);
+ // 返回
+ return couponDO.getId();
+ }
+
+
+ /**
+ *todo 获取用户id收获优惠券
+ *@author:wxr
+ *@date:2022-08-13 3:11
+ *@Description
+ */
+ @Override
+ public Long create(Long templateId) {
+ Long userid = SecurityFrameworkUtils.getLoginUserId();
+ CouponDO couponDO = CouponDO.builder().memberId(userid).build();
+ CouponTempleteDO couponTempleteDO = couponTempleteMapper.selectById(templateId);
+ //todo 缺少判空
+ BeanUtil.copyProperties(couponTempleteDO,couponTempleteDO);
+ 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 @@
+
+
+
+
+
+
+
diff --git a/yudao-module-mall/yudao-module-market-api/pom.xml b/yudao-module-mall/yudao-module-market-api/pom.xml
index fef3428fc..9517c343f 100644
--- a/yudao-module-mall/yudao-module-market-api/pom.xml
+++ b/yudao-module-mall/yudao-module-market-api/pom.xml
@@ -21,6 +21,13 @@
cn.iocoder.boot
yudao-common
+
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+ true
+
diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApi.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApi.java
new file mode 100644
index 000000000..532a66dc2
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApi.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.market.api.price;
+
+import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO;
+import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
+
+/**
+ * 价格 API 接口
+ *
+ * @author 芋道源码
+ */
+public interface PriceApi {
+
+ /**
+ * 计算商品的价格
+ *
+ * @param calculateReqDTO 价格请求
+ * @return 价格相应
+ */
+ PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO);
+
+}
diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateReqDTO.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateReqDTO.java
new file mode 100644
index 000000000..4cc019651
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateReqDTO.java
@@ -0,0 +1,56 @@
+package cn.iocoder.yudao.module.market.api.price.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 价格计算 Request DTO
+ *
+ * @author 芋道源码
+ */
+@Data
+public class PriceCalculateReqDTO {
+
+ /**
+ * 用户编号
+ *
+ * 对应 MemberUserDO 的 id 编号
+ */
+ private Long userId;
+
+ /**
+ * 优惠劵编号
+ */
+ private Long couponId;
+
+ /**
+ * 商品 SKU 数组
+ */
+ @NotNull(message = "商品数组不能为空")
+ private List- items;
+
+ /**
+ * 商品 SKU
+ */
+ @Data
+ public static class Item {
+
+ /**
+ * SKU 编号
+ */
+ @NotNull(message = "商品 SKU 编号不能为空")
+ private Long skuId;
+
+ /**
+ * SKU 数量
+ */
+ @NotNull(message = "商品 SKU 数量不能为空")
+ @Min(value = 0L, message = "商品 SKU 数量必须大于等于 0") // 可传递 0 数量,用于购物车未选中的情况
+ private Integer count;
+
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateRespDTO.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateRespDTO.java
new file mode 100644
index 000000000..dc4f10a10
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateRespDTO.java
@@ -0,0 +1,202 @@
+package cn.iocoder.yudao.module.market.api.price.dto;
+
+import cn.iocoder.yudao.module.market.enums.common.PromotionLevelEnum;
+import cn.iocoder.yudao.module.market.enums.common.PromotionTypeEnum;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 价格计算 Response DTO
+ *
+ * @author 芋道源码
+ */
+@Data
+public class PriceCalculateRespDTO {
+
+ /**
+ * 订单
+ */
+ private Order order;
+
+ /**
+ * 商品 SKU 数组
+ */
+ private List
- items;
+
+ /**
+ * 营销活动数组
+ *
+ * 只对应 {@link #items} 商品匹配的活动
+ */
+ private List promotions;
+
+ /**
+ * 订单
+ */
+ @Data
+ public static class Order {
+
+ /**
+ * 商品原价(总),单位:分
+ *
+ * 基于 {@link Item#getTotalOriginalPrice()} 求和
+ */
+ private Integer skuOriginalPrice;
+ /**
+ * 商品优惠(总),单位:分
+ *
+ * 基于 {@link Item#getTotalPromotionPrice()} 求和
+ */
+ private Integer skuPromotionPrice;
+ /**
+ * 订单优惠(总),单位:分
+ *
+ * 例如说:满减折扣;不包括优惠劵、商品优惠
+ */
+ private Integer orderPromotionPrice;
+ /**
+ * 运费金额,单位:分
+ */
+ private Integer deliveryPrice;
+ /**
+ * 应付金额(总),单位:分
+ *
+ * = {@link #skuOriginalPrice}
+ * + {@link #deliveryPrice}
+ * - {@link #skuPromotionPrice}
+ * - {@link #orderPromotionPrice}
+ */
+ // * - {@link #couponPrice} // TODO 芋艿:靠营销表记录
+ private Integer payPrice;
+
+ // ========== 营销基本信息 ==========
+ /**
+ * 优惠劵编号
+ */
+ private Long couponId;
+// /**
+// * 优惠劵减免金额,单位:分
+// *
+// * // TODO 芋艿:靠营销表记录
+// */
+// private Integer couponPrice;
+
+ }
+
+ /**
+ * 商品 SKU
+ */
+ @Data
+ public static class Item extends PriceCalculateReqDTO.Item {
+
+ /**
+ * 商品原价(单),单位:分
+ *
+ * 对应 ProductSkuDO 的 price 字段
+ */
+ private Integer originalPrice;
+ /**
+ * 商品原价(总),单位:分
+ *
+ * = {@link #originalPrice} * {@link #getCount()}
+ */
+ private Integer totalOriginalPrice;
+ /**
+ * 商品级优惠(总),单位:分
+ *
+ * 例如说“限时折扣”:商品原价的 8 折;商品原价的减 50 元
+ */
+ private Integer totalPromotionPrice;
+ /**
+ * 最终购买金额(总),单位:分。
+ *
+ * = {@link #totalOriginalPrice}
+ * - {@link #totalPromotionPrice}
+ */
+ private Integer totalPresentPrice;
+ /**
+ * 最终购买金额(单),单位:分。
+ *
+ * = {@link #totalPresentPrice} / {@link #getCount()}
+ */
+ private Integer presentPrice;
+ /**
+ * 应付金额(总),单位:分
+ */
+ private Integer totalPayPrice;
+
+ }
+
+ /**
+ * 营销活动
+ */
+ @Data
+ public static class Promotion {
+
+ /**
+ * 营销编号
+ *
+ * 例如说:营销活动的编号、优惠劵的编号
+ */
+ private Long id;
+ /**
+ * 营销类型
+ *
+ * 枚举 {@link PromotionTypeEnum}
+ */
+ private Integer type;
+ /**
+ * 营销级别
+ *
+ * 枚举 {@link PromotionLevelEnum}
+ */
+ private Integer level;
+ /**
+ * 匹配的商品 SKU 数组
+ */
+ private List
- items;
+ /**
+ * 计算时的原价(总),单位:分
+ */
+ private Integer totalOriginalPrice;
+ /**
+ * 计算时的优惠(总),单位:分
+ */
+ private Integer totalPromotionPrice;
+ /**
+ * 是否满足优惠条件
+ */
+ private Boolean meet;
+ /**
+ * 满足条件的提示
+ *
+ * 如果 {@link #meet} = true 满足,则提示“圣诞价:省 150.00 元”
+ * 如果 {@link #meet} = false 不满足,则提示“购满 85 元,可减 40 元”
+ */
+ private String meetTip;
+
+ /**
+ * 匹配的商品 SKU
+ */
+ @Data
+ public static class Item {
+
+ /**
+ * 商品 SKU 编号
+ */
+ private Long skuId;
+ /**
+ * 计算时的原价(总),单位:分
+ */
+ private Integer totalOriginalPrice;
+ /**
+ * 计算时的优惠(总),单位:分
+ */
+ private Integer totalPromotionPrice;
+
+ }
+
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/activity/MarketActivityStatusEnum.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/activity/MarketActivityStatusEnum.java
deleted file mode 100644
index a02b0269c..000000000
--- a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/activity/MarketActivityStatusEnum.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package cn.iocoder.yudao.module.market.enums.activity;
-
-import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
-
-import java.util.Arrays;
-
-/**
- * 促销活动状态枚举
- */
-public enum MarketActivityStatusEnum implements IntArrayValuable {
-
- WAIT(10, "未开始"),
- RUN(20, "进行中"),
- END(30, "已结束"),
- /**
- * 1. WAIT、RUN、END 可以转换成 INVALID 状态。
- * 2. INVALID 只可以转换成 DELETED 状态。
- */
- INVALID(40, "已撤销"),
- DELETED(50, "已删除"),
- ;
-
- public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MarketActivityStatusEnum::getValue).toArray();
-
- /**
- * 状态值
- */
- private final Integer value;
- /**
- * 状态名
- */
- private final String name;
-
- MarketActivityStatusEnum(Integer value, String name) {
- this.value = value;
- this.name = name;
- }
-
- public Integer getValue() {
- return value;
- }
-
- public String getName() {
- return name;
- }
-
- @Override
- public int[] array() {
- return ARRAYS;
- }
-}
diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/activity/MarketActivityTypeEnum.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/activity/MarketActivityTypeEnum.java
deleted file mode 100644
index 0413dba66..000000000
--- a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/activity/MarketActivityTypeEnum.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package cn.iocoder.yudao.module.market.enums.activity;
-
-import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
-
-import java.util.Arrays;
-
-/**
- * 促销活动类型枚举
- */
-public enum MarketActivityTypeEnum implements IntArrayValuable {
-
- TIME_LIMITED_DISCOUNT(1, "限时折扣"),
- FULL_PRIVILEGE(2, "满减送"),
- ;
-
- public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MarketActivityTypeEnum::getValue).toArray();
-
- /**
- * 类型值
- */
- private final Integer value;
- /**
- * 类型名
- */
- private final String name;
-
- MarketActivityTypeEnum(Integer value, String name) {
- this.value = value;
- this.name = name;
- }
-
- public Integer getValue() {
- return value;
- }
-
- public String getName() {
- return name;
- }
-
- @Override
- public int[] array() {
- return ARRAYS;
- }
-}
diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionActivityStatusEnum.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionActivityStatusEnum.java
new file mode 100644
index 000000000..9577841aa
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionActivityStatusEnum.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.market.enums.common;
+
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * 促销活动的状态枚举
+ *
+ * @author 芋道源码
+ */
+@AllArgsConstructor
+@Getter
+public enum PromotionActivityStatusEnum implements IntArrayValuable {
+
+ WAIT(10, "未开始"),
+ RUN(20, "进行中"),
+ END(30, "已结束"),
+ CLOSE(40, "已关闭");
+
+ public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionActivityStatusEnum::getStatus).toArray();
+
+ /**
+ * 状态值
+ */
+ private final Integer status;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ @Override
+ public int[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionConditionTypeEnum.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionConditionTypeEnum.java
new file mode 100644
index 000000000..4df0e6957
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionConditionTypeEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.market.enums.common;
+
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * 营销的条件类型枚举
+ *
+ * @author 芋道源码
+ */
+@AllArgsConstructor
+@Getter
+public enum PromotionConditionTypeEnum implements IntArrayValuable {
+
+ PRICE(10, "满 N 元"),
+ COUNT(20, "满 N 件");
+
+ public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionConditionTypeEnum::getType).toArray();
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public int[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionLevelEnum.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionLevelEnum.java
new file mode 100644
index 000000000..25e3f33c2
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionLevelEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.market.enums.common;
+
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * 营销的级别枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum PromotionLevelEnum implements IntArrayValuable {
+
+ ORDER(1, "订单级"),
+ SKU(2, "商品级"),
+ ;
+
+ public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionLevelEnum::getLevel).toArray();
+
+ /**
+ * 级别值
+ */
+ private final Integer level;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public int[] array() {
+ return ARRAYS;
+ }
+}
diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionProductScopeEnum.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionProductScopeEnum.java
new file mode 100644
index 000000000..e1792ee67
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionProductScopeEnum.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.market.enums.common;
+
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * 营销的商品范围枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum PromotionProductScopeEnum implements IntArrayValuable {
+
+ ALL(1, "全部商品参与"),
+ SPU(2, "指定商品参与"),
+ ;
+
+ public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionProductScopeEnum::getScope).toArray();
+
+ /**
+ * 范围值
+ */
+ private final Integer scope;
+ /**
+ * 范围名
+ */
+ private final String name;
+
+ @Override
+ public int[] array() {
+ return ARRAYS;
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionTypeEnum.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionTypeEnum.java
new file mode 100644
index 000000000..f3f5cc882
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionTypeEnum.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.market.enums.common;
+
+import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * 营销类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum PromotionTypeEnum implements IntArrayValuable {
+
+ DISCOUNT(1, "限时折扣"),
+ REWARD(2, "满减送"),
+ ;
+
+ public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionTypeEnum::getType).toArray();
+
+ /**
+ * 类型值
+ */
+ private final Integer type;
+ /**
+ * 类型名
+ */
+ private final String name;
+
+ @Override
+ public int[] array() {
+ return ARRAYS;
+ }
+}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/MarketTestController.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/MarketTestController.java
deleted file mode 100644
index 49b83b6c9..000000000
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/MarketTestController.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package cn.iocoder.yudao.module.market.controller.admin;
-
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-
-@Api(tags = "管理后台 - 营销")
-@RestController
-@RequestMapping("/market/test")
-@Validated
-public class MarketTestController {
-
- @GetMapping("/get")
- @ApiOperation("获取 market 信息")
- public CommonResult get() {
- return success("true");
- }
-
-}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/ActivityController.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/ActivityController.java
deleted file mode 100644
index dac4211a6..000000000
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/ActivityController.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package cn.iocoder.yudao.module.market.controller.admin.activity;
-
-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 java.util.*;
-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.module.market.controller.admin.activity.vo.*;
-import cn.iocoder.yudao.module.market.dal.dataobject.activity.ActivityDO;
-import cn.iocoder.yudao.module.market.convert.activity.ActivityConvert;
-import cn.iocoder.yudao.module.market.service.activity.ActivityService;
-
-@Api(tags = "管理后台 - 促销活动")
-@RestController
-@RequestMapping("/market/activity")
-@Validated
-public class ActivityController {
-
- @Resource
- private ActivityService activityService;
-
- @PostMapping("/create")
- @ApiOperation("创建促销活动")
- @PreAuthorize("@ss.hasPermission('market:activity:create')")
- public CommonResult createActivity(@Valid @RequestBody ActivityCreateReqVO createReqVO) {
- return success(activityService.createActivity(createReqVO));
- }
-
- @PutMapping("/update")
- @ApiOperation("更新促销活动")
- @PreAuthorize("@ss.hasPermission('market:activity:update')")
- public CommonResult updateActivity(@Valid @RequestBody ActivityUpdateReqVO updateReqVO) {
- activityService.updateActivity(updateReqVO);
- return success(true);
- }
-
- @DeleteMapping("/delete")
- @ApiOperation("删除促销活动")
- @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
- @PreAuthorize("@ss.hasPermission('market:activity:delete')")
- public CommonResult deleteActivity(@RequestParam("id") Long id) {
- activityService.deleteActivity(id);
- return success(true);
- }
-
- @GetMapping("/get")
- @ApiOperation("获得促销活动")
- @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
- @PreAuthorize("@ss.hasPermission('market:activity:query')")
- public CommonResult getActivity(@RequestParam("id") Long id) {
- ActivityDO activity = activityService.getActivity(id);
- return success(ActivityConvert.INSTANCE.convert(activity));
- }
-
- @GetMapping("/list")
- @ApiOperation("获得促销活动列表")
- @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
- @PreAuthorize("@ss.hasPermission('market:activity:query')")
- public CommonResult
> getActivityList(@RequestParam("ids") Collection ids) {
- List list = activityService.getActivityList(ids);
- return success(ActivityConvert.INSTANCE.convertList(list));
- }
-
- @GetMapping("/page")
- @ApiOperation("获得促销活动分页")
- @PreAuthorize("@ss.hasPermission('market:activity:query')")
- public CommonResult> getActivityPage(@Valid ActivityPageReqVO pageVO) {
- PageResult pageResult = activityService.getActivityPage(pageVO);
- return success(ActivityConvert.INSTANCE.convertPage(pageResult));
- }
-
-}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityBaseVO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityBaseVO.java
deleted file mode 100644
index 3ae5cd679..000000000
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityBaseVO.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package cn.iocoder.yudao.module.market.controller.admin.activity.vo;
-
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.market.enums.activity.MarketActivityStatusEnum;
-import cn.iocoder.yudao.module.market.enums.activity.MarketActivityTypeEnum;
-import lombok.*;
-import java.util.*;
-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 ActivityBaseVO {
-
- @ApiModelProperty(value = "活动标题", required = true)
- @NotNull(message = "活动标题不能为空")
- private String title;
-
- @ApiModelProperty(value = "活动类型", required = true)
- @NotNull(message = "活动类型不能为空")
- @InEnum(MarketActivityTypeEnum.class)
- private Integer activityType;
-
- @ApiModelProperty(value = "活动状态", required = true)
- @NotNull(message = "活动状态不能为空")
- @InEnum(MarketActivityStatusEnum.class)
- private Integer status;
-
- @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;
-
- @ApiModelProperty(value = "失效时间")
- @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
- private Date invalidTime;
-
- @ApiModelProperty(value = "删除时间")
- @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
- private Date deleteTime;
-
- @ApiModelProperty(value = "限制折扣字符串,使用 JSON 序列化成字符串存储")
- private String timeLimitedDiscount;
-
- @ApiModelProperty(value = "限制折扣字符串,使用 JSON 序列化成字符串存储")
- private String fullPrivilege;
-
-}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityCreateReqVO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityCreateReqVO.java
deleted file mode 100644
index 0ca112709..000000000
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityCreateReqVO.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package cn.iocoder.yudao.module.market.controller.admin.activity.vo;
-
-import lombok.*;
-import java.util.*;
-import io.swagger.annotations.*;
-import javax.validation.constraints.*;
-
-/**
- * @author xia
- */
-@ApiModel("管理后台 - 促销活动创建 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class ActivityCreateReqVO extends ActivityBaseVO {
-
-}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityPageReqVO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityPageReqVO.java
deleted file mode 100644
index 9543d8fee..000000000
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityPageReqVO.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package cn.iocoder.yudao.module.market.controller.admin.activity.vo;
-
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.market.enums.activity.MarketActivityStatusEnum;
-import cn.iocoder.yudao.module.market.enums.activity.MarketActivityTypeEnum;
-import lombok.*;
-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 ActivityPageReqVO extends PageParam {
-
- @ApiModelProperty(value = "活动标题")
- private String title;
-
- @ApiModelProperty(value = "活动类型")
- @InEnum(MarketActivityTypeEnum.class)
- private Integer activityType;
-
- @ApiModelProperty(value = "活动状态")
- @InEnum(MarketActivityStatusEnum.class)
- private Integer status;
-
- @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
- @ApiModelProperty(value = "开始时间")
- private Date[] startTime;
-
- @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
- @ApiModelProperty(value = "结束时间")
- private Date[] endTime;
-
- @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
- @ApiModelProperty(value = "失效时间")
- private Date[] invalidTime;
-
- @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
- @ApiModelProperty(value = "删除时间")
- private Date[] deleteTime;
-
- @ApiModelProperty(value = "限制折扣字符串,使用 JSON 序列化成字符串存储")
- private String timeLimitedDiscount;
-
- @ApiModelProperty(value = "限制折扣字符串,使用 JSON 序列化成字符串存储")
- private String fullPrivilege;
-
- @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
- @ApiModelProperty(value = "创建时间")
- private Date[] createTime;
-
-}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityUpdateReqVO.java
deleted file mode 100644
index 1db24f259..000000000
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityUpdateReqVO.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package cn.iocoder.yudao.module.market.controller.admin.activity.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 ActivityUpdateReqVO extends ActivityBaseVO {
-
- @ApiModelProperty(value = "活动编号", required = true)
- @NotNull(message = "活动编号不能为空")
- private Long id;
-
-}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/discount/package-info.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/discount/package-info.java
new file mode 100644
index 000000000..a3f145f26
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/discount/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * TODO 占位
+ */
+package cn.iocoder.yudao.module.market.controller.admin.discount;
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/activity/ActivityConvert.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/activity/ActivityConvert.java
deleted file mode 100644
index 64ba73975..000000000
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/activity/ActivityConvert.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package cn.iocoder.yudao.module.market.convert.activity;
-
-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.market.controller.admin.activity.vo.*;
-import cn.iocoder.yudao.module.market.dal.dataobject.activity.ActivityDO;
-
-/**
- * 促销活动 Convert
- *
- * @author 芋道源码
- */
-@Mapper
-public interface ActivityConvert {
-
- ActivityConvert INSTANCE = Mappers.getMapper(ActivityConvert.class);
-
- ActivityDO convert(ActivityCreateReqVO bean);
-
- ActivityDO convert(ActivityUpdateReqVO bean);
-
- ActivityRespVO convert(ActivityDO bean);
-
- List convertList(List list);
-
- PageResult convertPage(PageResult page);
-
-}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/discount/package-info.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/discount/package-info.java
new file mode 100644
index 000000000..787492406
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/discount/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * TODO 占位
+ */
+package cn.iocoder.yudao.module.market.convert.discount;
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/activity/ActivityDO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/activity/ActivityDO.java
deleted file mode 100644
index 13dcbf67c..000000000
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/activity/ActivityDO.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package cn.iocoder.yudao.module.market.dal.dataobject.activity;
-
-import lombok.*;
-import java.util.*;
-import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-
-/**
- * 促销活动 DO
- *
- * @author 芋道源码
- */
-@TableName("market_activity")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class ActivityDO extends BaseDO {
-
- /**
- * 活动编号
- */
- @TableId
- private Long id;
- /**
- * 活动标题
- */
- private String title;
- /**
- * 活动类型MarketActivityTypeEnum
- */
- private Integer activityType;
- /**
- * 活动状态MarketActivityStatusEnum
- */
- private Integer status;
- /**
- * 开始时间
- */
- private Date startTime;
- /**
- * 结束时间
- */
- private Date endTime;
- /**
- * 失效时间
- */
- private Date invalidTime;
- /**
- * 删除时间
- */
- private Date deleteTime;
- /**
- * 限制折扣字符串,使用 JSON 序列化成字符串存储
- */
- private String timeLimitedDiscount;
- /**
- * 限制折扣字符串,使用 JSON 序列化成字符串存储
- */
- private String fullPrivilege;
-
-}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountActivityDO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountActivityDO.java
new file mode 100644
index 000000000..8780546f6
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountActivityDO.java
@@ -0,0 +1,55 @@
+package cn.iocoder.yudao.module.market.dal.dataobject.discount;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.market.enums.common.PromotionActivityStatusEnum;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 限时折扣活动 DO
+ *
+ * 一个活动下,可以有 {@link DiscountProductDO} 商品;
+ * 一个商品,在指定时间段内,只能属于一个活动;
+ *
+ * @author 芋道源码
+ */
+@TableName(value = "promotion_discount_activity", autoResultMap = true)
+@KeySequence("promotion_discount_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class DiscountActivityDO extends BaseDO {
+
+ /**
+ * 活动编号,主键自增
+ */
+ @TableId
+ private Long id;
+ /**
+ * 活动标题
+ */
+ private String name;
+ /**
+ * 状态
+ *
+ * 枚举 {@link PromotionActivityStatusEnum}
+ */
+ private Integer status;
+ /**
+ * 开始时间
+ */
+ private Date startTime;
+ /**
+ * 结束时间
+ */
+ private Date endTime;
+ /**
+ * 备注
+ */
+ private String remark;
+
+}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountProductDO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountProductDO.java
new file mode 100644
index 000000000..cd73a19a5
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountProductDO.java
@@ -0,0 +1,65 @@
+package cn.iocoder.yudao.module.market.dal.dataobject.discount;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 限时折扣商品 DO
+ *
+ * @author 芋道源码
+ */
+@TableName(value = "promotion_discount_product", autoResultMap = true)
+@KeySequence("promotion_discount_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class DiscountProductDO extends BaseDO {
+
+ /**
+ * 编号,主键自增
+ */
+ @TableId
+ private Long id;
+ /**
+ * 限时折扣活动的编号
+ *
+ * 关联 {@link DiscountActivityDO#getId()}
+ */
+ private Long activityId;
+ /**
+ * 商品 SPU 编号
+ *
+ * 关联 ProductSpuDO 的 id 编号
+ */
+ private Long spuId;
+ /**
+ * 商品 SKU 编号
+ *
+ * 关联 ProductSkuDO 的 id 编号
+ */
+ private Long skuId;
+ /**
+ * 开始时间
+ */
+ private Date startTime;
+ /**
+ * 结束时间
+ */
+ private Date endTime;
+ /**
+ * 销售价格,单位:分
+ *
+ * 冗余 ProductSkuDO 的 price 字段
+ */
+ private Integer originalPrice;
+ /**
+ * 优惠价格,单位:分
+ */
+ private Integer promotionPrice;
+
+}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/reward/RewardActivityDO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/reward/RewardActivityDO.java
new file mode 100644
index 000000000..85cd8c955
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/reward/RewardActivityDO.java
@@ -0,0 +1,116 @@
+package cn.iocoder.yudao.module.market.dal.dataobject.reward;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.market.enums.common.PromotionActivityStatusEnum;
+import cn.iocoder.yudao.module.market.enums.common.PromotionConditionTypeEnum;
+import cn.iocoder.yudao.module.market.enums.common.PromotionProductScopeEnum;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 满减送活动 DO
+ *
+ * @author 芋道源码
+ */
+@TableName(value = "promotion_reward_activity", autoResultMap = true)
+@KeySequence("promotion_reward_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class RewardActivityDO extends BaseDO {
+
+ /**
+ * 活动编号,主键自增
+ */
+ @TableId
+ private Long id;
+ /**
+ * 活动标题
+ */
+ private String name;
+ /**
+ * 状态
+ *
+ * 枚举 {@link PromotionActivityStatusEnum}
+ */
+ private Integer status;
+ /**
+ * 开始时间
+ */
+ private Date startTime;
+ /**
+ * 结束时间
+ */
+ private Date endTime;
+ /**
+ * 备注
+ */
+ private String remark;
+ /**
+ * 条件类型
+ *
+ * 枚举 {@link PromotionConditionTypeEnum}
+ */
+ private Integer conditionType;
+ /**
+ * 商品范围
+ *
+ * 枚举 {@link PromotionProductScopeEnum}
+ */
+ private Integer productScope;
+ /**
+ * 商品 SPU 编号的数组
+ */
+ @TableField(typeHandler = JacksonTypeHandler.class)
+ private List spuIds;
+ /**
+ * 优惠规则的数组
+ */
+ @TableField(typeHandler = JacksonTypeHandler.class)
+ private List rules;
+
+ /**
+ * 优惠规则
+ */
+ @Data
+ public static class Rule {
+
+ /**
+ * 优惠门槛
+ *
+ * 1. 满 N 元,单位:分
+ * 2. 满 N 件
+ */
+ private Integer limit;
+ /**
+ * 优惠价格,单位:分
+ */
+ private Integer promotionPrice;
+ /**
+ * 是否包邮
+ */
+ private Boolean freeDelivery;
+ /**
+ * 赠送的积分
+ */
+ private Integer integral;
+ /**
+ * 赠送的优惠劵编号的数组
+ */
+ private List couponIds;
+ /**
+ * 赠送的优惠卷数量的数组
+ */
+ private List couponCounts;
+
+ }
+
+
+}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/activity/ActivityMapper.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/activity/ActivityMapper.java
deleted file mode 100644
index feb3fb122..000000000
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/activity/ActivityMapper.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package cn.iocoder.yudao.module.market.dal.mysql.activity;
-
-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.market.dal.dataobject.activity.ActivityDO;
-import org.apache.ibatis.annotations.Mapper;
-import cn.iocoder.yudao.module.market.controller.admin.activity.vo.*;
-
-/**
- * 促销活动 Mapper
- *
- * @author 芋道源码
- */
-@Mapper
-public interface ActivityMapper extends BaseMapperX {
-
- default PageResult selectPage(ActivityPageReqVO reqVO) {
- return selectPage(reqVO, new LambdaQueryWrapperX()
- .eqIfPresent(ActivityDO::getTitle, reqVO.getTitle())
- .eqIfPresent(ActivityDO::getActivityType, reqVO.getActivityType())
- .eqIfPresent(ActivityDO::getStatus, reqVO.getStatus())
- .betweenIfPresent(ActivityDO::getStartTime, reqVO.getStartTime())
- .betweenIfPresent(ActivityDO::getEndTime, reqVO.getEndTime())
- .betweenIfPresent(ActivityDO::getInvalidTime, reqVO.getInvalidTime())
- .betweenIfPresent(ActivityDO::getDeleteTime, reqVO.getDeleteTime())
- .eqIfPresent(ActivityDO::getTimeLimitedDiscount, reqVO.getTimeLimitedDiscount())
- .eqIfPresent(ActivityDO::getFullPrivilege, reqVO.getFullPrivilege())
- .betweenIfPresent(ActivityDO::getCreateTime, reqVO.getCreateTime())
- .orderByDesc(ActivityDO::getId));
- }
-
-}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/discount/package-info.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/discount/package-info.java
new file mode 100644
index 000000000..f8de42cd9
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/discount/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * TODO 占位
+ */
+package cn.iocoder.yudao.module.market.dal.mysql.discount;
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/package-info.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/package-info.java
index 2efde4ec7..92b9c698d 100644
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/package-info.java
+++ b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/package-info.java
@@ -1,8 +1,8 @@
/**
- * market 模块,我们放营销业务。
+ * promotion 模块,我们放营销业务。
* 例如说:营销活动、banner、优惠券等等
*
- * 1. Controller URL:以 /market/ 开头,避免和其它 Module 冲突
- * 2. DataObject 表名:以 market_ 开头,方便在数据库中区分
+ * 1. Controller URL:以 /promotion/ 开头,避免和其它 Module 冲突
+ * 2. DataObject 表名:以 promotion_ 开头,方便在数据库中区分
*/
package cn.iocoder.yudao.module.market;
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/activity/ActivityService.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/activity/ActivityService.java
deleted file mode 100644
index 1d5e27857..000000000
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/activity/ActivityService.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package cn.iocoder.yudao.module.market.service.activity;
-
-import java.util.*;
-import javax.validation.*;
-import cn.iocoder.yudao.module.market.controller.admin.activity.vo.*;
-import cn.iocoder.yudao.module.market.dal.dataobject.activity.ActivityDO;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
-/**
- * 促销活动 Service 接口
- *
- * @author 芋道源码
- */
-public interface ActivityService {
-
- /**
- * 创建促销活动
- *
- * @param createReqVO 创建信息
- * @return 编号
- */
- Long createActivity(@Valid ActivityCreateReqVO createReqVO);
-
- /**
- * 更新促销活动
- *
- * @param updateReqVO 更新信息
- */
- void updateActivity(@Valid ActivityUpdateReqVO updateReqVO);
-
- /**
- * 删除促销活动
- *
- * @param id 编号
- */
- void deleteActivity(Long id);
-
- /**
- * 获得促销活动
- *
- * @param id 编号
- * @return 促销活动
- */
- ActivityDO getActivity(Long id);
-
- /**
- * 获得促销活动列表
- *
- * @param ids 编号
- * @return 促销活动列表
- */
- List getActivityList(Collection ids);
-
- /**
- * 获得促销活动分页
- *
- * @param pageReqVO 分页查询
- * @return 促销活动分页
- */
- PageResult getActivityPage(ActivityPageReqVO pageReqVO);
-
-}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/activity/ActivityServiceImpl.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/activity/ActivityServiceImpl.java
deleted file mode 100644
index 57bb9af53..000000000
--- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/activity/ActivityServiceImpl.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package cn.iocoder.yudao.module.market.service.activity;
-
-import org.springframework.stereotype.Service;
-import javax.annotation.Resource;
-import org.springframework.validation.annotation.Validated;
-
-import java.util.*;
-import cn.iocoder.yudao.module.market.controller.admin.activity.vo.*;
-import cn.iocoder.yudao.module.market.dal.dataobject.activity.ActivityDO;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
-import cn.iocoder.yudao.module.market.convert.activity.ActivityConvert;
-import cn.iocoder.yudao.module.market.dal.mysql.activity.ActivityMapper;
-
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.market.enums.ErrorCodeConstants.*;
-
-/**
- * 促销活动 Service 实现类
- *
- * @author 芋道源码
- */
-@Service
-@Validated
-public class ActivityServiceImpl implements ActivityService {
-
- @Resource
- private ActivityMapper activityMapper;
-
- @Override
- public Long createActivity(ActivityCreateReqVO createReqVO) {
- // 插入
- ActivityDO activity = ActivityConvert.INSTANCE.convert(createReqVO);
- activityMapper.insert(activity);
- // 返回
- return activity.getId();
- }
-
- @Override
- public void updateActivity(ActivityUpdateReqVO updateReqVO) {
- // 校验存在
- this.validateActivityExists(updateReqVO.getId());
- // 更新
- ActivityDO updateObj = ActivityConvert.INSTANCE.convert(updateReqVO);
- activityMapper.updateById(updateObj);
- }
-
- @Override
- public void deleteActivity(Long id) {
- // 校验存在
- this.validateActivityExists(id);
- // 删除
- activityMapper.deleteById(id);
- }
-
- private void validateActivityExists(Long id) {
- if (activityMapper.selectById(id) == null) {
- throw exception(ACTIVITY_NOT_EXISTS);
- }
- }
-
- @Override
- public ActivityDO getActivity(Long id) {
- return activityMapper.selectById(id);
- }
-
- @Override
- public List getActivityList(Collection ids) {
- return activityMapper.selectBatchIds(ids);
- }
-
- @Override
- public PageResult getActivityPage(ActivityPageReqVO pageReqVO) {
- return activityMapper.selectPage(pageReqVO);
- }
-
-}
diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/package-info.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/package-info.java
new file mode 100644
index 000000000..f52febd44
--- /dev/null
+++ b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * TODO 占位
+ */
+package cn.iocoder.yudao.module.market.service.discount;
diff --git a/yudao-module-mall/yudao-module-market-biz/src/test/java/cn/iocoder/yudao/module/market/service/activity/ActivityServiceImplTest.java b/yudao-module-mall/yudao-module-market-biz/src/test/java/cn/iocoder/yudao/module/market/service/activity/ActivityServiceImplTest.java
deleted file mode 100644
index b292251a4..000000000
--- a/yudao-module-mall/yudao-module-market-biz/src/test/java/cn/iocoder/yudao/module/market/service/activity/ActivityServiceImplTest.java
+++ /dev/null
@@ -1,197 +0,0 @@
-package cn.iocoder.yudao.module.market.service.activity;
-
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-
-import javax.annotation.Resource;
-
-import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
-
-import cn.iocoder.yudao.module.market.controller.admin.activity.vo.*;
-import cn.iocoder.yudao.module.market.dal.dataobject.activity.ActivityDO;
-import cn.iocoder.yudao.module.market.dal.mysql.activity.ActivityMapper;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
-import org.springframework.context.annotation.Import;
-
-import static cn.iocoder.yudao.module.market.enums.ErrorCodeConstants.*;
-import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
-import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
-import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
-import static org.junit.jupiter.api.Assertions.*;
-
-/**
-* {@link ActivityServiceImpl} 的单元测试类
-*
-* @author 芋道源码
-*/
-@Import(ActivityServiceImpl.class)
-public class ActivityServiceImplTest extends BaseDbUnitTest {
-
- @Resource
- private ActivityServiceImpl activityService;
-
- @Resource
- private ActivityMapper activityMapper;
-
- @Test
- public void testCreateActivity_success() {
- // 准备参数
- ActivityCreateReqVO reqVO = randomPojo(ActivityCreateReqVO.class);
-
- // 调用
- Long activityId = activityService.createActivity(reqVO);
- // 断言
- assertNotNull(activityId);
- // 校验记录的属性是否正确
- ActivityDO activity = activityMapper.selectById(activityId);
- assertPojoEquals(reqVO, activity);
- }
-
- @Test
- public void testUpdateActivity_success() {
- // mock 数据
- ActivityDO dbActivity = randomPojo(ActivityDO.class);
- activityMapper.insert(dbActivity);// @Sql: 先插入出一条存在的数据
- // 准备参数
- ActivityUpdateReqVO reqVO = randomPojo(ActivityUpdateReqVO.class, o -> {
- o.setId(dbActivity.getId()); // 设置更新的 ID
- });
-
- // 调用
- activityService.updateActivity(reqVO);
- // 校验是否更新正确
- ActivityDO activity = activityMapper.selectById(reqVO.getId()); // 获取最新的
- assertPojoEquals(reqVO, activity);
- }
-
- @Test
- public void testUpdateActivity_notExists() {
- // 准备参数
- ActivityUpdateReqVO reqVO = randomPojo(ActivityUpdateReqVO.class);
-
- // 调用, 并断言异常
- assertServiceException(() -> activityService.updateActivity(reqVO), ACTIVITY_NOT_EXISTS);
- }
-
- @Test
- public void testDeleteActivity_success() {
- // mock 数据
- ActivityDO dbActivity = randomPojo(ActivityDO.class);
- activityMapper.insert(dbActivity);// @Sql: 先插入出一条存在的数据
- // 准备参数
- Long id = dbActivity.getId();
-
- // 调用
- activityService.deleteActivity(id);
- // 校验数据不存在了
- assertNull(activityMapper.selectById(id));
- }
-
- @Test
- public void testDeleteActivity_notExists() {
- // 准备参数
- Long id = randomLongId();
-
- // 调用, 并断言异常
- assertServiceException(() -> activityService.deleteActivity(id), ACTIVITY_NOT_EXISTS);
- }
-
- @Test
- @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
- public void testGetActivityPage() {
- // mock 数据
- ActivityDO dbActivity = randomPojo(ActivityDO.class, o -> { // 等会查询到
- o.setTitle(null);
- o.setActivityType(null);
- o.setStatus(null);
- o.setStartTime(null);
- o.setEndTime(null);
- o.setInvalidTime(null);
- o.setDeleteTime(null);
- o.setTimeLimitedDiscount(null);
- o.setFullPrivilege(null);
- o.setCreateTime(null);
- });
- activityMapper.insert(dbActivity);
- // 测试 title 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setTitle(null)));
- // 测试 activityType 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setActivityType(null)));
- // 测试 status 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setStatus(null)));
- // 测试 startTime 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setStartTime(null)));
- // 测试 endTime 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setEndTime(null)));
- // 测试 invalidTime 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setInvalidTime(null)));
- // 测试 deleteTime 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setDeleteTime(null)));
- // 测试 timeLimitedDiscount 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setTimeLimitedDiscount(null)));
- // 测试 fullPrivilege 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setFullPrivilege(null)));
- // 测试 createTime 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setCreateTime(null)));
- // 准备参数
- ActivityPageReqVO reqVO = new ActivityPageReqVO();
- reqVO.setTitle(null);
- reqVO.setActivityType(null);
- reqVO.setStatus(null);
- reqVO.setStartTime(null);
- reqVO.setEndTime(null);
- reqVO.setInvalidTime(null);
- reqVO.setDeleteTime(null);
- reqVO.setTimeLimitedDiscount(null);
- reqVO.setFullPrivilege(null);
- reqVO.setCreateTime(null);
-
- // 调用
- PageResult pageResult = activityService.getActivityPage(reqVO);
- // 断言
- assertEquals(1, pageResult.getTotal());
- assertEquals(1, pageResult.getList().size());
- assertPojoEquals(dbActivity, pageResult.getList().get(0));
- }
-
- @Test
- @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
- public void testGetActivityList() {
- // mock 数据
- ActivityDO dbActivity = randomPojo(ActivityDO.class, o -> { // 等会查询到
- o.setTitle(null);
- o.setActivityType(null);
- o.setStatus(null);
- o.setStartTime(null);
- o.setEndTime(null);
- o.setInvalidTime(null);
- o.setDeleteTime(null);
- o.setTimeLimitedDiscount(null);
- o.setFullPrivilege(null);
- o.setCreateTime(null);
- });
- activityMapper.insert(dbActivity);
- // 测试 title 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setTitle(null)));
- // 测试 activityType 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setActivityType(null)));
- // 测试 status 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setStatus(null)));
- // 测试 startTime 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setStartTime(null)));
- // 测试 endTime 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setEndTime(null)));
- // 测试 invalidTime 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setInvalidTime(null)));
- // 测试 deleteTime 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setDeleteTime(null)));
- // 测试 timeLimitedDiscount 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setTimeLimitedDiscount(null)));
- // 测试 fullPrivilege 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setFullPrivilege(null)));
- // 测试 createTime 不匹配
- activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setCreateTime(null)));
- }
-
-}
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java
index 427bf3136..6671e9b44 100644
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java
@@ -38,12 +38,6 @@ public class ProductCategoryDO extends BaseDO {
* 父分类编号
*/
private Long parentId;
-// /**
-// * 店铺编号
-// *
-// * 关联 {@link ShopDO#getId()} TODO 芋艿:多店铺,暂不考虑
-// */
-// private Long shopId;
/**
* 分类名称
*/
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java
index 209a7085c..2e3b63e59 100644
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java
@@ -27,12 +27,6 @@ public class ProductGroupBindDO extends BaseDO {
*/
@TableId
private Long id;
-// /**
-// * 店铺编号
-// *
-// * 关联 {@link ShopDO#getId()} TODO 芋艿:多店铺,暂不考虑
-// */
-// private Long shopId;
/**
* 商品分组编号
*
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java
index e942b957c..605e8c38a 100644
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.product.dal.dataobject.group;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.module.product.dal.dataobject.shop.ShopDO;
import cn.iocoder.yudao.module.product.enums.group.ProductGroupStyleEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -29,12 +28,6 @@ public class ProductGroupDO extends BaseDO {
*/
@TableId
private Long id;
-// /**
-// * 店铺编号
-// *
-// * 关联 {@link ShopDO#getId()} TODO 芋艿:多店铺,暂不考虑
-// */
-// private Long shopId;
/**
* 分组名称
*/
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java
index 94bfc808c..608b248fe 100644
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java
@@ -27,12 +27,6 @@ public class ProductPropertyDO extends BaseDO {
*/
@TableId
private Long id;
-// /**
-// * 店铺编号
-// *
-// * 关联 {@link ShopDO#getId()} TODO 芋艿:多店铺,暂不考虑
-// */
-// private Long shopId;
/**
* 规格名称
*/
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java
index c53f01aca..3d5cf9101 100644
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java
@@ -34,11 +34,5 @@ public class ProductHotSearchDO extends BaseDO {
* 内容
*/
private String content;
-// /**
-// * 店铺编号
-// *
-// * 关联 {@link ShopDO#getId()} TODO 芋艿:多店铺,暂不考虑
-// */
-// private Long shopId;
}
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
index 34f7a9d02..456b231b8 100755
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
@@ -36,13 +36,6 @@ public class ProductSpuDO extends BaseDO {
@TableId
private Long id;
-// /**
-// * 店铺编号
-// *
-// * 关联 {@link ShopDO#getId()} TODO 芋艿:多店铺,暂不考虑
-// */
-// private Long shopId;
-
// ========== 基本信息 =========
/**
@@ -215,4 +208,9 @@ public class ProductSpuDO extends BaseDO {
// TODO poster:商品自定义海报
+ // TODO ========== 待定字段:laoji =========
+ // TODO productType 1 - 普通商品 2 - 预售商品;可能和 type 合并不错
+ // TODO productUnit 商品单位
+ // TODO extJson 扩展信息;例如说,预售商品的信息
+
}
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java
index 756636687..eff999be0 100755
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java
@@ -22,7 +22,7 @@ public interface ProductSkuMapper extends BaseMapperX {
.eqIfPresent(ProductSkuDO::getSpuId, reqVO.getSpuId())
.eqIfPresent(ProductSkuDO::getProperties, reqVO.getProperties())
.eqIfPresent(ProductSkuDO::getPrice, reqVO.getPrice())
- .eqIfPresent(ProductSkuDO::getOriginalPrice, reqVO.getOriginalPrice())
+// .eqIfPresent(ProductSkuDO::getOriginalPrice, reqVO.getOriginalPrice())
// .eqIfPresent(ProductSkuDO::getCostPrice, reqVO.getCostPrice())
.eqIfPresent(ProductSkuDO::getBarCode, reqVO.getBarCode())
.eqIfPresent(ProductSkuDO::getPicUrl, reqVO.getPicUrl())
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
index 7487dd60c..a1d919ef2 100755
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
@@ -24,7 +24,7 @@ public interface ProductSpuMapper extends BaseMapperX {
.eqIfPresent(ProductSpuDO::getPicUrls, reqVO.getPicUrls())
.eqIfPresent(ProductSpuDO::getSort, reqVO.getSort())
// .eqIfPresent(ProductSpuDO::getLikeCount, reqVO.getLikeCount())
- .eqIfPresent(ProductSpuDO::getPrice, reqVO.getPrice())
+// .eqIfPresent(ProductSpuDO::getPrice, reqVO.getPrice())
// .eqIfPresent(ProductSpuDO::getQuantity, reqVO.getQuantity())
.eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus())
.betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime())
diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/SkuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/SkuServiceImplTest.java
index 8cd086e81..2902121e7 100755
--- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/SkuServiceImplTest.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/SkuServiceImplTest.java
@@ -105,7 +105,7 @@ public class SkuServiceImplTest extends BaseDbUnitTest {
o.setSpuId(null);
o.setProperties(null);
o.setPrice(null);
- o.setOriginalPrice(null);
+// o.setOriginalPrice(null);
// o.setCostPrice(null);
o.setBarCode(null);
o.setPicUrl(null);
@@ -120,7 +120,7 @@ public class SkuServiceImplTest extends BaseDbUnitTest {
// 测试 price 不匹配
ProductSkuMapper.insert(cloneIgnoreId(dbSku, o -> o.setPrice(null)));
// 测试 originalPrice 不匹配
- ProductSkuMapper.insert(cloneIgnoreId(dbSku, o -> o.setOriginalPrice(null)));
+// ProductSkuMapper.insert(cloneIgnoreId(dbSku, o -> o.setOriginalPrice(null)));
// 测试 costPrice 不匹配
// ProductSkuMapper.insert(cloneIgnoreId(dbSku, o -> o.setCostPrice(null)));
// 测试 barCode 不匹配
diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java
index ef2372ac9..4aa0c0e68 100755
--- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java
@@ -110,7 +110,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
o.setPicUrls(null);
o.setSort(null);
// o.setLikeCount(null);
- o.setPrice(null);
+// o.setPrice(null);
// o.setQuantity(null);
o.setStatus(null);
o.setCreateTime(null);
@@ -131,7 +131,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
// 测试 likeCount 不匹配
// ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setLikeCount(null)));
// 测试 price 不匹配
- ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setPrice(null)));
+// ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setPrice(null)));
// 测试 quantity 不匹配
// ProductSpuMapper.insert(cloneIgnoreId(dbSpu, o -> o.setQuantity(null)));
// 测试 status 不匹配
diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCloseTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java
similarity index 93%
rename from yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCloseTypeEnum.java
rename to yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java
index 4fdaf9298..670651d4e 100644
--- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCloseTypeEnum.java
+++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java
@@ -10,7 +10,7 @@ import lombok.RequiredArgsConstructor;
*/
@RequiredArgsConstructor
@Getter
-public enum TradeOrderCloseTypeEnum {
+public enum TradeOrderCancelTypeEnum {
PAY_TIMEOUT(10, "超时未支付"),
REFUND_CLOSE(20, "退款关闭"),
diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java
index 6510e26cb..fe0a85f3d 100644
--- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java
+++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java
@@ -15,8 +15,8 @@ public enum TradeOrderStatusEnum {
WAITING_PAYMENT(0, "待付款"),
WAIT_SHIPMENT(1, "待发货"),
ALREADY_SHIPMENT(2, "待收货"),
- COMPLETED(3, "成功"),
- CLOSED(4, "失败");
+ COMPLETED(3, "已完成"),
+ CANCEL(4, "已关闭");
/**
* 状态值
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/CartController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/CartController.java
new file mode 100644
index 000000000..91e51dfd5
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/CartController.java
@@ -0,0 +1,71 @@
+package cn.iocoder.yudao.module.trade.controller.app.cart;
+
+import io.swagger.annotations.Api;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Api(tags = "购物车 API")
+@RestController
+@RequestMapping("/cart")
+@Validated
+public class CartController {
+
+// @Autowired
+// private CartManager cartManager;
+//
+// @PostMapping("add")
+// @ApiOperation("添加商品到购物车")
+// @ApiImplicitParams({
+// @ApiImplicitParam(name = "skuId", value = "商品 SKU 编号", required = true, example = "1"),
+// @ApiImplicitParam(name = "quantity", value = "增加数量", required = true, example = "1024")
+// })
+// @RequiresAuthenticate
+// public CommonResult addCartItem(@RequestParam("skuId") Integer skuId,
+// @RequestParam("quantity") Integer quantity) {
+// cartManager.addCartItem(UserSecurityContextHolder.getUserId(), skuId, quantity);
+// return success(true);
+// }
+//
+// @GetMapping("sum-quantity")
+// @ApiOperation("查询用户在购物车中的商品数量")
+// @RequiresAuthenticate
+// public CommonResult sumCartItemQuantity() {
+// return success(cartManager.sumCartItemQuantity(UserSecurityContextHolder.getUserId()));
+// }
+//
+// @GetMapping("/get-detail")
+// @ApiOperation("查询用户的购物车的商品列表")
+// @RequiresAuthenticate
+// public CommonResult getCartDetail() {
+// return success(cartManager.getCartDetail(UserSecurityContextHolder.getUserId()));
+// }
+//
+// @PostMapping("update-quantity")
+// @ApiOperation("更新购物车商品数量")
+// @ApiImplicitParams({
+// @ApiImplicitParam(name = "skuId", value = "商品 SKU 编号", required = true, example = "1"),
+// @ApiImplicitParam(name = "quantity", value = "增加数量", required = true, example = "1024")
+// })
+// @RequiresAuthenticate
+// public CommonResult updateCartItemQuantity(@RequestParam("skuId") Integer skuId,
+// @RequestParam("quantity") Integer quantity) {
+// cartManager.updateCartItemQuantity(UserSecurityContextHolder.getUserId(), skuId, quantity);
+// return success(true);
+// }
+//
+// @PostMapping("update-selected")
+// @ApiOperation("更新购物车商品是否选中")
+// @ApiImplicitParams({
+// @ApiImplicitParam(name = "skuIds", value = "商品 SKU 编号数组", required = true, example = "1,3"),
+// @ApiImplicitParam(name = "selected", value = "是否选中", required = true, example = "true")
+// })
+// @RequiresAuthenticate
+// public CommonResult updateCartItemSelected(@RequestParam("skuIds") Set skuIds,
+// @RequestParam("selected") Boolean selected) {
+// cartManager.updateCartItemSelected(UserSecurityContextHolder.getUserId(), skuIds, selected);
+// // 获得目前购物车明细
+// return success(true);
+// }
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/CartDetailVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/CartDetailVO.java
new file mode 100644
index 000000000..403efbebe
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/CartDetailVO.java
@@ -0,0 +1,211 @@
+package cn.iocoder.yudao.module.trade.controller.app.cart.vo;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+@ApiModel(value = "用户的购物车明细 Response VO") // TODO 芋艿:swagger 文档完善
+@Data
+@Accessors(chain = true)
+public class CartDetailVO {
+
+ /**
+ * 商品分组数组
+ */
+ private List itemGroups;
+ /**
+ * 费用
+ */
+ private Fee fee;
+
+ /**
+ * 商品分组
+ *
+ * 多个商品,参加同一个活动,从而形成分组。
+ */
+ @Data
+ @Accessors(chain = true)
+ public static class ItemGroup {
+
+// /**
+// * 优惠活动
+// */
+// private PromotionActivityRespDTO activity; // TODO 芋艿,偷懒
+ /**
+ * 促销减少的金额
+ *
+ * 1. 若未参与促销活动,或不满足促销条件,返回 null
+ * 2. 该金额,已经分摊到每个 Item 的 discountTotal ,需要注意。
+ */
+ private Integer activityDiscountTotal;
+ /**
+ * 商品数组
+ */
+ private List items;
+
+ }
+
+ @Data
+ @Accessors(chain = true)
+ public static class Sku {
+
+ // SKU 自带信息
+ /**
+ * sku 编号
+ */
+ private Integer id;
+ /**
+ * SPU 信息
+ */
+ private Spu spu;
+ /**
+ * 图片地址
+ */
+ private String picURL;
+// /**
+// * 规格值数组
+// */
+// private List attrs; // TODO 后面改下
+ /**
+ * 价格,单位:分
+ */
+ private Integer price;
+ /**
+ * 库存数量
+ */
+ private Integer quantity;
+
+ // 非 SKU 自带信息
+
+ /**
+ * 购买数量
+ */
+ private Integer buyQuantity;
+ /**
+ * 是否选中
+ */
+ private Boolean selected;
+// /**
+// * 优惠活动
+// */
+// private PromotionActivityRespDTO activity; // TODO 芋艿,偷懒
+ /**
+ * 原始单价,单位:分。
+ */
+ private Integer originPrice;
+ /**
+ * 购买单价,单位:分
+ */
+ private Integer buyPrice;
+ /**
+ * 最终价格,单位:分。
+ */
+ private Integer presentPrice;
+ /**
+ * 购买总金额,单位:分
+ *
+ * 用途类似 {@link #presentTotal}
+ */
+ private Integer buyTotal;
+ /**
+ * 优惠总金额,单位:分。
+ */
+ private Integer discountTotal;
+ /**
+ * 最终总金额,单位:分。
+ *
+ * 注意,presentPrice * quantity 不一定等于 presentTotal 。
+ * 因为,存在无法整除的情况。
+ * 举个例子,presentPrice = 8.33 ,quantity = 3 的情况,presentTotal 有可能是 24.99 ,也可能是 25 。
+ * 所以,需要存储一个该字段。
+ */
+ private Integer presentTotal;
+
+ }
+
+ @Data
+ @Accessors(chain = true)
+ public static class Spu {
+
+ /**
+ * SPU 编号
+ */
+ private Integer id;
+
+ // ========== 基本信息 =========
+ /**
+ * SPU 名字
+ */
+ private String name;
+ /**
+ * 分类编号
+ */
+ private Integer cid;
+ /**
+ * 商品主图地址
+ *
+ * 数组,以逗号分隔
+ *
+ * 建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张
+ */
+ private List picUrls;
+
+ }
+
+ /**
+ * 费用(合计)
+ */
+ @Data
+ @Accessors(chain = true)
+ public static class Fee {
+
+ /**
+ * 购买总价
+ */
+ private Integer buyTotal;
+ /**
+ * 优惠总价
+ *
+ * 注意,满多少元包邮,不算在优惠中。
+ */
+ private Integer discountTotal;
+ /**
+ * 邮费
+ */
+ private Integer postageTotal;
+ /**
+ * 最终价格
+ *
+ * 计算公式 = 总价 - 优惠总价 + 邮费
+ */
+ private Integer presentTotal;
+
+ public Fee() {
+ }
+
+ public Fee(Integer buyTotal, Integer discountTotal, Integer postageTotal, Integer presentTotal) {
+ this.buyTotal = buyTotal;
+ this.discountTotal = discountTotal;
+ this.postageTotal = postageTotal;
+ this.presentTotal = presentTotal;
+ }
+
+ }
+
+ /**
+ * 邮费信息 TODO 芋艿,未完成
+ */
+ @Data
+ @Accessors(chain = true)
+ public static class Postage {
+
+ /**
+ * 需要满足多少钱,可以包邮。单位:分
+ */
+ private Integer threshold;
+
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http
new file mode 100644
index 000000000..778e99029
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http
@@ -0,0 +1,31 @@
+### /trade-order/confirm-create-order-info 基于商品,确认创建订单
+GET {{appApi}}/trade/order/get-create-info?items[0].skuId=1&items[0].count=1
+Authorization: Bearer {{user-access-token}}
+tenant-id: {{appTenentId}}
+
+### /trade-order/confirm-create-order-info-from-cart 基于购物车,确认创建订单
+GET {{shop-api-base-url}}/trade-order/confirm-create-order-info-from-cart
+Content-Type: application/x-www-form-urlencoded
+Authorization: Bearer {{user-access-token}}
+
+### /trade-order/confirm-create-order-info-from-cart 基于商品,创建订单
+POST {{shop-api-base-url}}/trade-order/create
+Content-Type: application/json
+Authorization: Bearer {{user-access-token}}
+
+{
+ "userAddressId": 19,
+ "remark": "我是备注",
+ "orderItems": [
+ {
+ "skuId": 3,
+ "quantity": 1
+ }
+ ]
+}
+
+### /trade-order/page 获得订单交易分页
+GET {{shop-api-base-url}}/trade-order/page?status=1&pageNo=1&pageSize=10
+Content-Type: application/x-www-form-urlencoded
+
+###
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
new file mode 100644
index 000000000..da027e1fa
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
@@ -0,0 +1,61 @@
+package cn.iocoder.yudao.module.trade.controller.app.order;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
+import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderGetCreateInfoRespVO;
+import cn.iocoder.yudao.module.trade.controller.app.order.vo.TradeOrderPageReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.order.vo.TradeOrderRespVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+@Api(tags = "用户 App - 交易订单")
+@RestController
+@RequestMapping("/trade/order")
+@Validated
+@Slf4j
+public class AppTradeOrderController {
+
+ // TODO 在思考下;
+
+ @GetMapping("/get-create-info")
+ @ApiOperation("基于商品,确认创建订单")
+ @PreAuthenticated
+ public CommonResult getTradeOrderCreateInfo(AppTradeOrderCreateReqVO createReqVO) {
+// return success(tradeOrderService.getOrderConfirmCreateInfo(UserSecurityContextHolder.getUserId(), skuId, quantity, couponCardId));
+ return null;
+ }
+
+ @PostMapping("/create")
+ @ApiOperation("创建订单")
+ @PreAuthenticated
+ public CommonResult createTradeOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO,
+ HttpServletRequest servletRequest) {
+// return success(tradeOrderService.createTradeOrder(UserSecurityContextHolder.getUserId(),
+// HttpUtil.getIp(servletRequest), createReqVO));
+ return null;
+ }
+
+ @GetMapping("/get")
+ @ApiOperation("获得交易订单")
+ @ApiImplicitParam(name = "tradeOrderId", value = "交易订单编号", required = true)
+ public CommonResult getTradeOrder(@RequestParam("tradeOrderId") Integer tradeOrderId) {
+// return success(tradeOrderService.getTradeOrder(tradeOrderId));
+ return null;
+ }
+
+ @GetMapping("/page")
+ @ApiOperation("获得订单交易分页")
+ public CommonResult> pageTradeOrder(TradeOrderPageReqVO pageVO) {
+// return success(tradeOrderService.pageTradeOrder(UserSecurityContextHolder.getUserId(), pageVO));
+ return null;
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java
new file mode 100644
index 000000000..85edde55d
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java
@@ -0,0 +1,50 @@
+package cn.iocoder.yudao.module.trade.controller.app.order.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@ApiModel(value = "用户 App - 交易订单创建 Request VO")
+@Data
+public class AppTradeOrderCreateReqVO {
+
+ @ApiModelProperty(name = "收件地址编号", required = true, example = "1")
+ @NotNull(message = "收件地址不能为空")
+ private Integer addressId;
+
+ @ApiModelProperty(name = "优惠劵编号", example = "1024")
+ private Integer couponId;
+
+ @ApiModelProperty(name = "备注", example = "1024")
+ private String remark;
+
+ @ApiModelProperty(name = "是否来自购物车", required = true, example = "true", notes = "true - 来自购物车;false - 立即购买")
+ @NotNull(message = "是否来自购物车不能为空")
+ private Boolean fromCart;
+
+ /**
+ * 订单商品项列表
+ */
+ @NotNull(message = "必须选择购买的商品")
+ private List- items;
+
+ @ApiModel(value = "订单商品项")
+ @Data
+ public static class Item {
+
+ @ApiModelProperty(name = "商品 SKU 编号", required = true, example = "111")
+ @NotNull(message = "商品 SKU 编号不能为空")
+ private Integer skuId;
+
+ @ApiModelProperty(name = "商品 SKU 购买数量", required = true, example = "1024")
+ @NotNull(message = "商品 SKU 购买数量不能为空")
+ @Min(value = 1, message = "商品 SKU 购买数量必须大于 0")
+ private Integer count;
+
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java
new file mode 100644
index 000000000..d0bf595f6
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java
@@ -0,0 +1,169 @@
+package cn.iocoder.yudao.module.trade.controller.app.order.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.List;
+
+@ApiModel(value = "用户 App - 订单获得创建信息 Response VO")
+@Data
+public class AppTradeOrderGetCreateInfoRespVO {
+
+ /**
+ * 商品分组数组
+ */
+ private List itemGroups;
+ /**
+ * 费用
+ */
+ private Fee fee;
+
+// /**
+// * 优惠劵列表 TODO 芋艿,后续改改
+// */
+// private List coupons;
+
+ @ApiModel(value = "商品分组", description = "多个商品,参加同一个活动,从而形成分组")
+ @Data
+ public static class ItemGroup {
+
+// /**
+// * 优惠活动
+// */
+// private PromotionActivityRespDTO activity; // TODO 芋艿,偷懒
+ /**
+ * 商品 SKU 数组
+ */
+ private List items;
+
+ }
+
+ @ApiModel("商品 SKU")
+ @Data
+ public static class Sku {
+
+ // SKU 自带信息
+ @ApiModelProperty(value = "SKU 编号", required = true, example = "1024")
+ private Integer id;
+ /**
+ * SPU 信息
+ */
+ private Spu spu;
+ /**
+ * 图片地址
+ */
+ private String picURL;
+// /**
+// * 规格值数组
+// */
+// private List attrs; // TODO 后面改下
+ /**
+ * 价格,单位:分
+ */
+ private Integer price;
+ /**
+ * 库存数量
+ */
+ private Integer stock;
+
+ // 非 SKU 自带信息
+
+ /**
+ * 购买数量
+ */
+ private Integer buyQuantity;
+// /**
+// * 优惠活动
+// */
+// private PromotionActivityRespDTO activity; // TODO 芋艿,偷懒
+ /**
+ * 原始单价,单位:分。
+ */
+ private Integer originPrice;
+ /**
+ * 购买单价,单位:分
+ */
+ private Integer buyPrice;
+ /**
+ * 最终价格,单位:分。
+ */
+ private Integer presentPrice;
+ /**
+ * 购买总金额,单位:分
+ *
+ * 用途类似 {@link #presentTotal}
+ */
+ private Integer buyTotal;
+ /**
+ * 优惠总金额,单位:分。
+ */
+ private Integer discountTotal;
+ /**
+ * 最终总金额,单位:分。
+ *
+ * 注意,presentPrice * quantity 不一定等于 presentTotal 。
+ * 因为,存在无法整除的情况。
+ * 举个例子,presentPrice = 8.33 ,quantity = 3 的情况,presentTotal 有可能是 24.99 ,也可能是 25 。
+ * 所以,需要存储一个该字段。
+ */
+ private Integer presentTotal;
+
+ }
+
+ @Data
+ public static class Spu {
+
+ /**
+ * SPU 编号
+ */
+ private Integer id;
+
+ // ========== 基本信息 =========
+ /**
+ * SPU 名字
+ */
+ private String name;
+ /**
+ * 分类编号
+ */
+ private Integer cid;
+ /**
+ * 商品主图地址
+ *
+ * 数组,以逗号分隔
+ *
+ * 建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张
+ */
+ private List picUrls;
+
+ }
+
+ @ApiModel("费用(合计)")
+ @Data
+ @AllArgsConstructor
+ public static class Fee {
+
+ @ApiModelProperty(value = "购买总价", required = true, example = "1024")
+ private Integer buyPrice;
+ /**
+ * 优惠总价
+ *
+ * 注意,满多少元包邮,不算在优惠中。
+ */
+ private Integer discountTotal;
+ /**
+ * 邮费
+ */
+ private Integer postageTotal;
+ /**
+ * 最终价格
+ *
+ * 计算公式 = 总价 - 优惠总价 + 邮费
+ */
+ private Integer presentTotal;
+
+ }
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java
new file mode 100644
index 000000000..195f7330f
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java
@@ -0,0 +1,53 @@
+package cn.iocoder.yudao.module.trade.controller.app.order.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+@ApiModel("交易订单项 Response VO")
+@Data
+public class TradeOrderItemRespVO {
+
+ @ApiModelProperty(value = "id自增长", required = true)
+ private Integer id;
+ @ApiModelProperty(value = "订单编号", required = true)
+ private Integer orderId;
+ @ApiModelProperty(value = "订单项状态", required = true)
+ private Integer status;
+ @ApiModelProperty(value = "商品 SKU 编号", required = true)
+ private Integer skuId;
+ @ApiModelProperty(value = "商品 SPU 编号", required = true)
+ private Integer spuId;
+ @ApiModelProperty(value = "商品名字", required = true)
+ private String skuName;
+ @ApiModelProperty(value = "图片名字", required = true)
+ private String skuImage;
+ @ApiModelProperty(value = "商品数量", required = true)
+ private Integer quantity;
+ @ApiModelProperty(value = "原始单价,单位:分", required = true)
+ private Integer originPrice;
+ @ApiModelProperty(value = "购买单价,单位:分", required = true)
+ private Integer buyPrice;
+ @ApiModelProperty(value = "最终价格,单位:分", required = true)
+ private Integer presentPrice;
+ @ApiModelProperty(value = "购买总金额,单位:分", required = true)
+ private Integer buyTotal;
+ @ApiModelProperty(value = "优惠总金额,单位:分", required = true)
+ private Integer discountTotal;
+ @ApiModelProperty(value = "最终总金额,单位:分", required = true)
+ private Integer presentTotal;
+ @ApiModelProperty(value = "退款总金额,单位:分", required = true)
+ private Integer refundTotal;
+ @ApiModelProperty(value = "物流id")
+ private Integer logisticsId;
+ @ApiModelProperty(value = "售后状态", required = true)
+ private Integer afterSaleStatus;
+ @ApiModelProperty(value = "售后订单编号")
+ private Integer afterSaleOrderId;
+ @ApiModelProperty(value = "创建时间", required = true)
+ private Date createTime;
+
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderPageReqVO.java
new file mode 100644
index 000000000..5c8b6c872
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderPageReqVO.java
@@ -0,0 +1,17 @@
+package cn.iocoder.yudao.module.trade.controller.app.order.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@ApiModel("交易订单分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TradeOrderPageReqVO extends PageParam {
+
+ @ApiModelProperty(value = "订单状态", example = "1", notes = "参见 TradeOrderStatusEnum 枚举")
+ private Integer orderStatus;
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java
new file mode 100644
index 000000000..4b7ffa77c
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java
@@ -0,0 +1,70 @@
+package cn.iocoder.yudao.module.trade.controller.app.order.vo;
+
+import lombok.*;
+import io.swagger.annotations.*;
+import java.util.*;
+
+@ApiModel("订单交易 Response VO")
+@Data
+public class TradeOrderRespVO {
+
+ @ApiModelProperty(value = "订单编号", required = true)
+ private Integer id;
+ @ApiModelProperty(value = "用户编号", required = true)
+ private Integer userId;
+ @ApiModelProperty(value = "订单单号", required = true)
+ private String orderNo;
+ @ApiModelProperty(value = "订单状态", required = true)
+ private Integer orderStatus;
+ @ApiModelProperty(value = "备注")
+ private String remark;
+ @ApiModelProperty(value = "订单结束时间")
+ private Date endTime;
+ @ApiModelProperty(value = "订单金额(总金额),单位:分", required = true)
+ private Integer buyPrice;
+ @ApiModelProperty(value = "优惠总金额,单位:分", required = true)
+ private Integer discountPrice;
+ @ApiModelProperty(value = "物流金额,单位:分", required = true)
+ private Integer logisticsPrice;
+ @ApiModelProperty(value = "最终金额,单位:分", required = true)
+ private Integer presentPrice;
+ @ApiModelProperty(value = "支付金额,单位:分", required = true)
+ private Integer payPrice;
+ @ApiModelProperty(value = "退款金额,单位:分", required = true)
+ private Integer refundPrice;
+ @ApiModelProperty(value = "付款时间")
+ private Date payTime;
+ @ApiModelProperty(value = "支付订单编号")
+ private Integer payTransactionId;
+ @ApiModelProperty(value = "支付渠道")
+ private Integer payChannel;
+ @ApiModelProperty(value = "配送类型", required = true)
+ private Integer deliveryType;
+ @ApiModelProperty(value = "发货时间")
+ private Date deliveryTime;
+ @ApiModelProperty(value = "收货时间")
+ private Date receiveTime;
+ @ApiModelProperty(value = "收件人名称", required = true)
+ private String receiverName;
+ @ApiModelProperty(value = "手机号", required = true)
+ private String receiverMobile;
+ @ApiModelProperty(value = "地区编码", required = true)
+ private Integer receiverAreaCode;
+ @ApiModelProperty(value = "收件详细地址", required = true)
+ private String receiverDetailAddress;
+ @ApiModelProperty(value = "售后状态", required = true)
+ private Integer afterSaleStatus;
+ @ApiModelProperty(value = "优惠劵编号")
+ private Integer couponCardId;
+ @ApiModelProperty(value = "创建时间", required = true)
+ private Date createTime;
+
+ /**
+ * 订单项数组
+ *
+ * // TODO 芋艿,后续考虑怎么优化下,目前是内嵌了别的 dto
+ */
+ private List orderItems;
+
+
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/refund/TradeRefundController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/refund/TradeRefundController.java
new file mode 100644
index 000000000..aa419190e
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/refund/TradeRefundController.java
@@ -0,0 +1,4 @@
+package cn.iocoder.yudao.module.trade.controller.app.refund;
+
+public class TradeRefundController {
+}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/package-info.java
new file mode 100644
index 000000000..aa2f99f35
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * 提供 RESTful API 给前端:
+ * 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目
+ * 2. app 包:提供给用户 APP yudao-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分
+ */
+package cn.iocoder.yudao.module.trade.controller;
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/CartItemDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/CartItemDO.java
index 5722882ce..b92ca8b54 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/CartItemDO.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/CartItemDO.java
@@ -36,12 +36,6 @@ public class CartItemDO extends BaseDO {
// ========= 买家信息 BEGIN =========
-// /**
-// * 店铺编号
-// *
-// * 关联 {@link ShopDO#getId()} TODO 芋艿:多店铺,暂不考虑
-// */
-// private Long shopId;
/**
* 用户编号
*
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
index 175ebdc95..77bdf66b0 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
@@ -3,10 +3,10 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order;
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.product.enums.delivery.DeliveryTypeEnum;
-import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCloseTypeEnum;
+import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum;
+import cn.iocoder.yudao.module.trade.enums.order.TradeOrderRefundStatusEnum;
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
-import cn.iocoder.yudao.module.trade.enums.order.TradeOrderRefundStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
@@ -32,67 +32,68 @@ public class TradeOrderDO extends BaseDO {
/**
* 订单编号,主键自增
*/
- private Integer id;
+ private Long id;
/**
* 订单流水号
*
* 例如说,1146347329394184195
*/
private String sn;
- // TODO 芋艿:order_type 订单类型
/**
* 订单类型
*
* 枚举 {@link TradeOrderTypeEnum}
*/
- private Integer type;
+ private Integer type; // TODO order_promotion_type
/**
* 订单来源终端
*
* 枚举 {@link TerminalEnum}
*/
private Integer terminal;
-// /**
-// * 店铺编号
-// *
-// * 关联 {@link ShopDO#getId()} TODO 芋艿:多店铺,暂不考虑
-// */
-// private Long shopId;
/**
* 用户编号
*
* 关联 MemberUserDO 的 id 编号
*/
private Long userId;
+ /**
+ * 用户 IP
+ */
+ private String userIp;
+ /**
+ * 用户备注
+ */
+ private String userRemark;
/**
* 订单状态
*
* 枚举 {@link TradeOrderStatusEnum}
*/
private Integer status;
- /**
- * 关闭类型
- *
- * 枚举 {@link TradeOrderCloseTypeEnum}
- */
- private Integer closeType;
// TODO 芋艿:要不要存储 prod_name 购买的商品名门?
/**
* 购买的商品数量
*/
private Integer productCount; // total_num
/**
- * 备注
+ * 订单完成时间
*/
- private String remark;
- /**
- * 确认收获时间
- */
- private Date confirmTakeTime;
+ private Date finishTime;
/**
* 订单取消时间
*/
private Date cancelTime;
+ /**
+ * 取消类型
+ *
+ * 枚举 {@link TradeOrderCancelTypeEnum}
+ */
+ private Integer cancelType;
+ /**
+ * 商家备注
+ */
+ private String remark;
// ========== 价格 + 支付基本信息 ==========
/**
@@ -101,38 +102,55 @@ public class TradeOrderDO extends BaseDO {
* true - 已经支付过
* false - 没有支付过
*/
- private Boolean payed; // TODO payStatus 0 - 待付款;1 - 已付款;2 - 已退款
+ private Boolean payed;
/**
* 付款时间
*/
private Date payTime;
- // TODO 芋艿:delete_status 用户订单删除状态;0 - 未删除;1 - 回收站;2 - 永久删除
-
// ========== 价格 + 支付基本信息 ==========
+ // 价格文档 - 淘宝:https://open.taobao.com/docV3.htm?docId=108471&docType=1
+ // 价格文档 - 京东到家:https://openo2o.jddj.com/api/getApiDetail/182/4d1494c5e7ac4679bfdaaed950c5bc7f.htm
+ // 价格文档 - 有赞:https://doc.youzanyun.com/detail/API/0/906
+
+// TODO promotion_details(订单优惠信息明细,商品和订单级优惠一般都在里面)
+
/**
- * 购买(商品)总金额,单位:分
- */
- private Integer buyPrice; // total
- /**
- * 优惠总金额,单位:分。
- */
- private Integer discountPrice; // reduce_amount
- /**
- * 物流金额 (分)
- */
- private Integer logisticsPrice; // freight_amount; freight_price
- /**
- * 最终金额,单位:分
+ * 商品原价(总),单位:分
*
- * buyPrice + logisticsPrice - discountPrice = presentPrice
+ * 基于 {@link TradeOrderItemDO#getTotalOriginalPrice()} 求和
*/
- private Integer presentPrice; // actual_total
+ // niu - goods_money;
+ private Integer skuOriginalPrice;
/**
- * 实际已支付金额,单位:分
+ * 商品优惠(总),单位:分
*
- * 初始时,金额为 0 。等到支付成功后,会进行更新。
+ * 基于 {@link TradeOrderItemDO#getTotalPromotionPrice()} 求和
*/
+ private Integer skuPromotionPrice;
+ /**
+ * 订单优惠(总),单位:分
+ *
+ * 例如说:满减折扣;不包括优惠劵、商品优惠
+ */
+ // niu - promotion_money;taobao - discount_fee(主订单优惠)
+ private Integer orderPromotionPrice;
+ /**
+ * 运费金额,单位:分
+ */
+ // niu - delivery_money;taobao - post_fee(订单邮费)
+ private Integer deliveryPrice;
+ // TODO 芋艿:taobao 的:trade.adjust_fee/order.adjust_fee(调整金额,如:卖家手动修改订单价格,官方数据修复等等)
+ /**
+ * 应付金额(总),单位:分
+ *
+ * = {@link #skuOriginalPrice}
+ * + {@link #deliveryPrice}
+ * - {@link #skuPromotionPrice}
+ * - {@link #orderPromotionPrice}
+ */
+ // niu - pay_money;taobao - payment(主订单实付金额) | trade.total_fee(主订单应付金额,参考使用);
+// * - {@link #couponPrice} // TODO 芋艿:靠营销表记录
private Integer payPrice;
/**
* 支付订单编号
@@ -142,16 +160,27 @@ public class TradeOrderDO extends BaseDO {
private Long payOrderId;
/**
* 支付成功的支付渠道
+ *
+ * 对应 PayChannelEnum 枚举
*/
- private Integer payType;
+ private Integer payChannel;
// ========== 收件 + 物流基本信息 ==========
/**
* 配送方式
+ * 会员用户下单时,选择的配送方式
*
* 枚举 {@link DeliveryTypeEnum}
*/
private Integer deliveryType;
+ /**
+ * 实际的配送方式
+ * 管理后台发货时,选择的配送方式
+ *
+ * 0 - 无需物流
+ * 枚举 {@link DeliveryTypeEnum}
+ */
+ private Integer actualDeliveryType; // like - shipping_status;
/**
* 配置模板的编号
*
@@ -162,6 +191,13 @@ public class TradeOrderDO extends BaseDO {
* 物流公司单号
*/
private String expressNo; // dvy_flow_id
+ /**
+ * 发货状态
+ *
+ * true - 已发货
+ * false - 未发货
+ */
+ private Boolean deliveryStatus;
/**
* 发货时间
*/
@@ -210,26 +246,30 @@ public class TradeOrderDO extends BaseDO {
/**
* 优惠劵编号
*/
- private Integer couponId;
-
- // TODO 芋艿,这块还要结合营销和价格计算,在去优化下。
+ private Long couponId;
+// /**
+// * 优惠劵减免金额,单位:分 // TODO 芋艿:靠营销表记录
+// */
+// // niu - coupon_money;
+// private Integer couponPrice;
+// /**
+// * 积分抵扣的金额,单位:分
+// */
+// private Integer integralPrice;
+// /**
+// * 使用的积分
+// */
+// private Integer useIntegral;
// TODO ========== 待定字段:yv =========
// TODO cart_id:购物车 id
- // TODO total_postage:邮费
- // TODO pay_postage:支付邮费
- // TODO coupon_price:优惠劵金额;
- // TODO refund_status:0 未退款;1 申请中;2 已退款
// TODO refund_reason_wap_img:退款图片
// TODO refund_reason_wap_explain:退款用户说明
// TODO refund_reason_time:退款时间
// TODO refund_reason_wap:前台退款原因
// TODO refund_reason:不退款的理由
- // TODO refund_price:退款金额
// TODO gain_integral:消费赚取积分
- // TODO use_integral:使用积分
- // TODO pay_integral:实际支付积分
// TODO back_integral:给用户退了多少积分
// TODO combination_id:拼团产品id
@@ -246,18 +286,19 @@ public class TradeOrderDO extends BaseDO {
// TODO is_alter_price:是否改价
// TODO out_trade_no:商户系统内部的订单号 String
- // TODO ========== 待定字段:lf =========
- // TODO integral_amount:积分抵扣金额
- // TODO shipping_status:发货状态
- // TODO shipping_time:最后新发货时间
-
// TODO ========== 待定字段:lf =========
// TODO settle_id:未结算
// TODO settle_amount:结算金额
- // TODO use_integral:使用的积分
// TODO team_found_id: 拼团id
// TODO team_id: 拼团活动id
// TODO delivery_id: 发货单ID
// TODO attach_values: 附带的值(赠送时机,赠送积分成长值什么的)Json格式
+ // TODO ========== 待定字段:nf =========
+ // TODO delivery_code:整体提货编码
+
+ // TODO ========== 待定字段:niu =========
+ // TODO adjust_money '订单调整金额'
+ // TODO balance_money ''余额支付金额''
+
}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java
index 6bdb7c6d4..14e4de0f4 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java
@@ -26,13 +26,7 @@ public class TradeOrderItemDO extends BaseDO {
/**
* 编号
*/
- private Integer id;
-// /**
-// * 店铺编号
-// *
-// * 关联 {@link ShopDO#getId()} TODO 芋艿:多店铺,暂不考虑
-// */
-// private Long shopId;
+ private Long id;
/**
* 用户编号
*
@@ -50,7 +44,7 @@ public class TradeOrderItemDO extends BaseDO {
/**
* 商品 SPU 编号
*
- * 关联 ProductSpuDO 的 id 编号
+ * 关联 ProductSkuDO 的 spuId 编号
*/
private Long spuId;
/**
@@ -58,7 +52,7 @@ public class TradeOrderItemDO extends BaseDO {
*
* 关联 ProductSkuDO 的 id 编号
*/
- private Integer skuId;
+ private Long skuId;
/**
* 规格值数组,JSON 格式
*/
@@ -75,7 +69,7 @@ public class TradeOrderItemDO extends BaseDO {
/**
* 购买数量
*/
- private Integer stock;
+ private Integer count;
/**
* 是否评论
*
@@ -86,36 +80,56 @@ public class TradeOrderItemDO extends BaseDO {
// ========== 价格 + 支付基本信息 ==========
/**
- * 原始单价,单位:分。
+ * 商品原价(单),单位:分
+ *
+ * 对应 ProductSkuDO 的 price 字段
*/
- private Integer originPrice; // price
+ // like - original_price;niu - costPrice
+ private Integer originalPrice;
/**
- * 购买单价,单位:分
+ * 商品原价(总),单位:分
+ *
+ * = {@link #originalPrice} * {@link #count}
*/
- private Integer buyPrice;
+ // like - total_price;niu - 暂无
+ private Integer totalOriginalPrice;
/**
- * 最终单价,单位:分。
+ * 商品级优惠(总),单位:分
+ *
+ * 例如说“限时折扣”:商品原价的 8 折;商品原价的减 50 元
+ */
+ // taobao - order.discount_fee(子订单商品优惠)
+ private Integer totalPromotionPrice;
+ /**
+ * 最终购买金额(单),单位:分。
+ *
+ * = {@link #totalPresentPrice} / {@link #count}
*/
private Integer presentPrice;
/**
- * 购买总金额,单位:分
+ * 最终购买金额(总),单位:分。
*
- * 用途类似 {@link #presentTotal}
+ * = {@link #totalOriginalPrice}
+ * - {@link #totalPromotionPrice}
*/
- private Integer buyTotal;
+ // like - total_pay_price;niu - goods_money; taobao - order.payment(子订单实付金额,不算主订单分摊金额) | order.total_fee(子订单应付金额,参考使用)
+ private Integer totalPresentPrice;
+ // TODO 芋艿:part_mjz_discount(子订单分摊金额);本质上,totalOriginalPrice - totalPayPrice
/**
- * 优惠总金额,单位:分。
+ * 应付金额(总),单位:分
*/
- private Integer discountTotal;
- /**
- * 最终总金额,单位:分。
- *
- * 注意,presentPrice * stock 不一定等于 presentTotal 。
- * 因为,存在无法整除的情况。
- * 举个例子,presentPrice = 8.33 ,stock = 3 的情况,presentTotal 有可能是 24.99 ,也可能是 25 。
- * 所以,需要存储一个该字段。
- */
- private Integer presentTotal; // product_total_amount
+ // taobao - divide_order_fee (分摊后子订单实付金额);
+ private Integer totalPayPrice;
+
+ // ========== 营销基本信息 ==========
+// /**
+// * 积分抵扣的金额,单位:分
+// */
+// private Integer integralTotal; // like - integral_price;niu - point_money
+// /**
+// * 使用的积分
+// */
+// private Integer useIntegral; // niu - use_point
// ========== 退款基本信息 ==========
/**
@@ -123,7 +137,7 @@ public class TradeOrderItemDO extends BaseDO {
*
* 枚举 {@link TradeOrderItemRefundStatusEnum}
*/
- private Integer refundStatus;
+ private Integer refundStatus; // TODO 芋艿:可以考虑去查
// 如上字段,举个例子:
// 假设购买三个,即 stock = 3 。
// originPrice = 15
@@ -178,4 +192,23 @@ public class TradeOrderItemDO extends BaseDO {
// TODO goods_info 商品信息
// TODO integral_price:积分抵扣的金额
+
+ // TODO 待确定:niu
+ // TODO is_virtual '是否是虚拟商品'
+ // TODO goods_class '商品种类(1.实物 2.虚拟3.卡券)'
+ // TODO adjust_money ''调整金额''
+
+ // TODO is_fenxiao 是否分销,
+ // TODO adjust_money 是否分销,
+
+ // TODO delivery_status '配送状态'
+ // TODO delivery_no ''配送单号''
+ // TODO gift_flag '赠品标识'
+ // TODO gift_flag '赠品标识'
+
+ // TODO refund_status '退款状态'
+ // TODO refund_type '退款状态'
+ // TODO 一堆退款字段
+
}
+
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/refund/TradeRefundDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/refund/TradeRefundDO.java
index 6c910df4c..cd246a297 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/refund/TradeRefundDO.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/refund/TradeRefundDO.java
@@ -42,12 +42,6 @@ public class TradeRefundDO extends BaseDO {
* 枚举 {@link TradeOrderRefundStatusEnum}
*/
private Integer status;
-// /**
-// * 店铺编号
-// *
-// * 关联 {@link ShopDO#getId()} TODO 芋艿:多店铺,暂不考虑
-// */
-// private Long shopId;
/**
* 用户编号
*
diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml
index 55c91e2f8..c7090aa6e 100644
--- a/yudao-server/pom.xml
+++ b/yudao-server/pom.xml
@@ -51,6 +51,11 @@
yudao-module-product-biz
${revision}
+
+ cn.iocoder.boot
+ yudao-module-trade-biz
+ ${revision}
+
diff --git a/yudao-ui-admin/.eslintignore b/yudao-ui-admin/.eslintignore
index 89be6f659..21cfec76a 100644
--- a/yudao-ui-admin/.eslintignore
+++ b/yudao-ui-admin/.eslintignore
@@ -7,4 +7,4 @@ public
# 忽略当前目录下为js的文件的语法检查
*.js
# 忽略当前目录下为vue的文件的语法检查
-*.vue
\ No newline at end of file
+*.vue
diff --git a/yudao-ui-admin/src/api/mall/CouponTemplete/CouponTemplete.js b/yudao-ui-admin/src/api/mall/CouponTemplete/CouponTemplete.js
new file mode 100644
index 000000000..429dfb8dc
--- /dev/null
+++ b/yudao-ui-admin/src/api/mall/CouponTemplete/CouponTemplete.js
@@ -0,0 +1,54 @@
+import request from '@/utils/request'
+
+// 创建优惠券模板
+export function create(data) {
+ return request({
+ url: '/coupon/CouponTemplete/create',
+ method: 'post',
+ data: data
+ })
+}
+
+// 更新优惠券模板
+export function update(data) {
+ return request({
+ url: '/coupon/CouponTemplete/update',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除优惠券模板
+export function deleteCouponTemplete (id) {
+ return request({
+ url: '/coupon/CouponTemplete/delete?id=' + id,
+ method: 'delete'
+ })
+}
+
+// 获得优惠券模板
+export function get(id) {
+ return request({
+ url: '/coupon/CouponTemplete/get?id=' + id,
+ method: 'get'
+ })
+}
+
+// 获得优惠券模板分页
+export function getPage(query) {
+ return request({
+ url: '/coupon/CouponTemplete/page',
+ method: 'get',
+ params: query
+ })
+}
+
+// 导出优惠券模板 Excel
+export function exportExcel(query) {
+ return request({
+ url: '/coupon/CouponTemplete/export-excel',
+ method: 'get',
+ params: query,
+ responseType: 'blob'
+ })
+}
diff --git a/yudao-ui-admin/src/views/mall/CouponTemplete/index.vue b/yudao-ui-admin/src/views/mall/CouponTemplete/index.vue
new file mode 100644
index 000000000..47be4afd3
--- /dev/null
+++ b/yudao-ui-admin/src/views/mall/CouponTemplete/index.vue
@@ -0,0 +1,457 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+ 新增
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 请选择字典生成
+
+
+
+
+
+
+
+
+ 请选择字典生成
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 请选择字典生成
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 请选择字典生成
+
+
+
+
+
+
+
+ 请选择字典生成
+
+
+
+
+
+
+
+ 请选择字典生成
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 请选择字典生成
+
+
+
+
+
+
+
+ 请选择字典生成
+
+
+
+
+
+
+
+
+
+
+
+