diff --git a/common/common-framework/src/main/java/cn/iocoder/common/framework/util/DateUtil.java b/common/common-framework/src/main/java/cn/iocoder/common/framework/util/DateUtil.java index e0f92c8fa..3219252f0 100644 --- a/common/common-framework/src/main/java/cn/iocoder/common/framework/util/DateUtil.java +++ b/common/common-framework/src/main/java/cn/iocoder/common/framework/util/DateUtil.java @@ -26,6 +26,9 @@ public class DateUtil { * @return 计算后的日志 */ public static Date addDate(Date date, int field, int amount) { + if (amount == 0) { + return date; + } Calendar c = Calendar.getInstance(); if (date != null) { c.setTime(date); diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsCouponTemplateController.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsCouponController.java similarity index 72% rename from promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsCouponTemplateController.java rename to promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsCouponController.java index ce277c738..589564ebb 100644 --- a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsCouponTemplateController.java +++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsCouponController.java @@ -25,7 +25,7 @@ import java.util.Date; @RestController @RequestMapping("admins/coupon") @Api("优惠劵(码)模块") -public class AdminsCouponTemplateController { +public class AdminsCouponController { @Reference(validation = "true") private CouponService couponService; @@ -39,12 +39,12 @@ public class AdminsCouponTemplateController { @ApiImplicitParam(name = "pageNo", value = "页码,从 1 开始", example = "1"), @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, example = "10"), }) - public CommonResult page(@RequestParam(value = "type", required = false) Integer type, - @RequestParam(value = "title", required = false) String title, - @RequestParam(value = "status", required = false) Integer status, - @RequestParam(value = "preferentialType", required = false) Integer preferentialType, - @RequestParam(value = "pageNo", defaultValue = "0") Integer pageNo, - @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) { + public CommonResult templatePage(@RequestParam(value = "type", required = false) Integer type, + @RequestParam(value = "title", required = false) String title, + @RequestParam(value = "status", required = false) Integer status, + @RequestParam(value = "preferentialType", required = false) Integer preferentialType, + @RequestParam(value = "pageNo", defaultValue = "0") Integer pageNo, + @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) { CommonResult result = couponService.getCouponTemplatePage(new CouponTemplatePageDTO() .setType(type).setTitle(title).setStatus(status).setPreferentialType(preferentialType) .setPageNo(pageNo).setPageSize(pageSize)); @@ -71,24 +71,24 @@ public class AdminsCouponTemplateController { @ApiImplicitParam(name = "percentOff", value = "折扣百分比", example = "当 preferentialType 为折扣卷时,非空"), @ApiImplicitParam(name = "discountPriceLimit", value = "折扣上限", example = "当 preferentialType 为折扣卷时,非空"), }) - public CommonResult add(@RequestParam(value = "title") String title, - @RequestParam(value = "description", required = false) String description, - @RequestParam(value = "quota") Integer quota, - @RequestParam(value = "total", required = false) Integer total, - @RequestParam(value = "priceAvailable") Integer priceAvailable, - @RequestParam(value = "rangeType") Integer rangeType, - @RequestParam(value = "rangeValues", required = false) String rangeValues, - @RequestParam(value = "dateType") Integer dateType, - @DateTimeFormat(pattern = "yyyy-MM-dd") + public CommonResult templateCardAdd(@RequestParam(value = "title") String title, + @RequestParam(value = "description", required = false) String description, + @RequestParam(value = "quota") Integer quota, + @RequestParam(value = "total", required = false) Integer total, + @RequestParam(value = "priceAvailable") Integer priceAvailable, + @RequestParam(value = "rangeType") Integer rangeType, + @RequestParam(value = "rangeValues", required = false) String rangeValues, + @RequestParam(value = "dateType") Integer dateType, + @DateTimeFormat(pattern = "yyyy-MM-dd") @RequestParam(value = "validStartTime", required = false) Date validStartTime, - @DateTimeFormat(pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") @RequestParam(value = "validEndTime", required = false) Date validEndTime, - @RequestParam(value = "fixedBeginTerm", required = false) Integer fixedBeginTerm, - @RequestParam(value = "fixedEndTerm", required = false) Integer fixedEndTerm, - @RequestParam(value = "preferentialType") Integer preferentialType, - @RequestParam(value = "priceOff", required = false) Integer priceOff, - @RequestParam(value = "percentOff", required = false) Integer percentOff, - @RequestParam(value = "discountPriceLimit", required = false) Integer discountPriceLimit) { + @RequestParam(value = "fixedBeginTerm", required = false) Integer fixedBeginTerm, + @RequestParam(value = "fixedEndTerm", required = false) Integer fixedEndTerm, + @RequestParam(value = "preferentialType") Integer preferentialType, + @RequestParam(value = "priceOff", required = false) Integer priceOff, + @RequestParam(value = "percentOff", required = false) Integer percentOff, + @RequestParam(value = "discountPriceLimit", required = false) Integer discountPriceLimit) { // 创建 CouponCardTemplateAddDTO 对象 validStartTime = DateUtil.getDayBegin(validStartTime); // 开始时间,以当前 00:00:00 为准 validEndTime = DateUtil.getDayBegin(validEndTime); // 结束时间,以当前 25:59:59 为准 @@ -116,13 +116,13 @@ public class AdminsCouponTemplateController { @ApiImplicitParam(name = "rangeType", value = "可用范围的类型", required = true, example = "参见 CouponTemplateRangeTypeEnum 枚举"), @ApiImplicitParam(name = "rangeValues", value = "指定商品 / 分类列表,使用逗号分隔商品编号"), }) - public CommonResult update(@RequestParam(value = "id") Integer id, - @RequestParam(value = "title") String title, - @RequestParam(value = "description", required = false) String description, - @RequestParam(value = "quota") Integer quota, - @RequestParam(value = "total", required = false) Integer total, - @RequestParam(value = "rangeType") Integer rangeType, - @RequestParam(value = "rangeValues", required = false) String rangeValues) { + public CommonResult templateCardUpdate(@RequestParam(value = "id") Integer id, + @RequestParam(value = "title") String title, + @RequestParam(value = "description", required = false) String description, + @RequestParam(value = "quota") Integer quota, + @RequestParam(value = "total", required = false) Integer total, + @RequestParam(value = "rangeType") Integer rangeType, + @RequestParam(value = "rangeValues", required = false) String rangeValues) { // 创建 CouponCardTemplateAddDTO 对象 CouponCardTemplateUpdateDTO couponCardTemplateUpdateDTO = new CouponCardTemplateUpdateDTO() .setId(id) @@ -138,8 +138,8 @@ public class AdminsCouponTemplateController { @ApiImplicitParam(name = "id", value = "Banner 编号", required = true, example = "1"), @ApiImplicitParam(name = "status", value = "状态。1 - 开启;2 - 禁用", required = true, example = "1"), }) - public CommonResult updateStatus(@RequestParam("id") Integer id, - @RequestParam("status") Integer status) { + public CommonResult templateUpdateStatus(@RequestParam("id") Integer id, + @RequestParam("status") Integer status) { return couponService.updateCouponTemplateStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status); } diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductCategoryController.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersBannerController.java similarity index 96% rename from promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductCategoryController.java rename to promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersBannerController.java index fd7e8463e..eb436bb4d 100644 --- a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductCategoryController.java +++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersBannerController.java @@ -19,7 +19,7 @@ import java.util.List; @RestController @RequestMapping("users/banner") @Api("Banner 模块") -public class UsersProductCategoryController { +public class UsersBannerController { @Reference(validation = "true") private BannerService bannerService; @@ -35,4 +35,4 @@ public class UsersProductCategoryController { return CommonResult.success(BannerConvert.INSTANCE.convertList(result)); } -} \ No newline at end of file +} diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersCouponController.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersCouponController.java new file mode 100644 index 000000000..4dc623315 --- /dev/null +++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersCouponController.java @@ -0,0 +1,52 @@ +package cn.iocoder.mall.promotion.application.controller.users; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.promotion.api.CouponService; +import cn.iocoder.mall.promotion.api.bo.CouponCardBO; +import cn.iocoder.mall.promotion.api.bo.CouponTemplateBO; +import cn.iocoder.mall.promotion.application.convert.CouponCardConvert; +import cn.iocoder.mall.promotion.application.convert.CouponTemplateConvert; +import cn.iocoder.mall.promotion.application.vo.users.UsersCouponCardVO; +import cn.iocoder.mall.promotion.application.vo.users.UsersCouponTemplateVO; +import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder; +import com.alibaba.dubbo.config.annotation.Reference; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("admins/coupon") +@Api("优惠劵(码)模块") +public class UsersCouponController { + + @Reference(validation = "true") + private CouponService couponService; + + // ========== 优惠劵(码)模板 ========== + + @GetMapping("/template/get") + @ApiOperation(value = "优惠劵(码)模板信息") + @ApiImplicitParam(name = "id", value = "优惠劵(码)模板编号", required = true, example = "10") + public CommonResult templateGet(@RequestParam("id") Integer id) { + CouponTemplateBO template = couponService.getCouponTemplate(id).getData(); + return CommonResult.success(CouponTemplateConvert.INSTANCE.convert2(template)); + } + + // ========== 优惠劵 ========== + + @GetMapping("/card/add") + @ApiOperation(value = "领取优惠劵") + @ApiImplicitParam(name = "templateId", value = "优惠劵(码)模板编号", required = true, example = "10") + public CommonResult cardAdd(@RequestParam("templateId") Integer templateId) { + CommonResult result = couponService.addCouponCard(UserSecurityContextHolder.getContext().getUserId(), templateId); + return CouponCardConvert.INSTANCE.convert(result); + } + + // ========== 优惠码 ========== + + +} diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/CouponCardConvert.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/CouponCardConvert.java new file mode 100644 index 000000000..3ec4d00f2 --- /dev/null +++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/CouponCardConvert.java @@ -0,0 +1,21 @@ +package cn.iocoder.mall.promotion.application.convert; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.promotion.api.bo.CouponCardBO; +import cn.iocoder.mall.promotion.application.vo.users.UsersCouponCardVO; +import org.mapstruct.Mapper; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface CouponCardConvert { + + CouponCardConvert INSTANCE = Mappers.getMapper(CouponCardConvert.class); + + @Mappings({}) + CommonResult convert(CommonResult result); +// +// @Mappings({}) +// List convertList2(List banners); + +} diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/CouponTemplateConvert.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/CouponTemplateConvert.java index 17a1c896d..e1fc03972 100644 --- a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/CouponTemplateConvert.java +++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/CouponTemplateConvert.java @@ -5,6 +5,7 @@ import cn.iocoder.mall.promotion.api.bo.CouponTemplateBO; import cn.iocoder.mall.promotion.api.bo.CouponTemplatePageBO; import cn.iocoder.mall.promotion.application.vo.admins.AdminsCouponTemplatePageVO; import cn.iocoder.mall.promotion.application.vo.admins.AdminsCouponTemplateVO; +import cn.iocoder.mall.promotion.application.vo.users.UsersCouponTemplateVO; import org.mapstruct.Mapper; import org.mapstruct.Mappings; import org.mapstruct.factory.Mappers; @@ -28,6 +29,9 @@ public interface CouponTemplateConvert { @Mappings({}) List convertList(List templates); + @Mappings({}) + UsersCouponTemplateVO convert2(CouponTemplateBO template); + // // @Mappings({}) // List convertList2(List banners); diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsCouponTemplateVO.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsCouponTemplateVO.java index e956506cd..cc5663ad1 100644 --- a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsCouponTemplateVO.java +++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsCouponTemplateVO.java @@ -59,7 +59,7 @@ public class AdminsCouponTemplateVO { // ========== 使用规则 END ========== // ========== 使用效果 BEGIN ========== - @ApiModelProperty(value = "优惠类型", example = "参见 CouponTemplatePreferentialTypeEnum 枚举") + @ApiModelProperty(value = "优惠类型", required = true, example = "参见 CouponTemplatePreferentialTypeEnum 枚举") private Integer preferentialType; @ApiModelProperty(value = "折扣百分比") private Integer percentOff; @@ -70,11 +70,11 @@ public class AdminsCouponTemplateVO { // ========== 使用效果 END ========== // ========== 统计信息 BEGIN ========== - @ApiModelProperty(value = "折扣上限", required = true) + @ApiModelProperty(value = "领取优惠券的次数", required = true) private Integer statFetchNum; // ========== 统计信息 END ========== - @ApiModelProperty(value = "折扣上限", required = true) + @ApiModelProperty(value = "创建时间", required = true) private Date createTime; } diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/users/UsersCouponCardVO.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/users/UsersCouponCardVO.java new file mode 100644 index 000000000..ba3a6363e --- /dev/null +++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/users/UsersCouponCardVO.java @@ -0,0 +1,55 @@ +package cn.iocoder.mall.promotion.application.vo.users; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; + +/** + * 优惠劵 VO + */ +@Data +@Accessors(chain = true) +public class UsersCouponCardVO { + + // ========== 基本信息 BEGIN ========== + @ApiModelProperty(value = "优惠劵编号", required = true, example = "1") + private Integer id; + @ApiModelProperty(value = "模板编号,自增唯一", required = true, example = "1") + private Integer templateId; + @ApiModelProperty(value = "优惠码状态", required = true, example = "参见 CouponCardStatusEnum 枚举") + private Integer status; + + // ========== 基本信息 END ========== + + // ========== 使用规则 BEGIN ========== + @ApiModelProperty(value = "固定日期-生效开始时间", required = true) + private Date validStartTime; + @ApiModelProperty(value = "固定日期-生效结束时间", required = true) + private Date validEndTime; + // ========== 使用规则 END ========== + + // ========== 使用效果 BEGIN ========== + @ApiModelProperty(value = "优惠类型", required = true, example = "参见 CouponTemplatePreferentialTypeEnum 枚举") + private Integer preferentialType; + @ApiModelProperty(value = "折扣百分比") + private Integer percentOff; + @ApiModelProperty(value = "优惠金额,单位:分") + private Integer priceOff; + @ApiModelProperty(value = "折扣上限") + private Integer discountPriceLimit; + // ========== 使用效果 END ========== + + // ========== 使用情况 BEGIN ========== + /** + * 是否使用 + */ + @ApiModelProperty(value = "是否使用", required = true) + private Boolean used; + + // TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。 + + // ========== 使用情况 END ========== + +} diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/users/UsersCouponTemplateVO.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/users/UsersCouponTemplateVO.java new file mode 100644 index 000000000..c664d348b --- /dev/null +++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/users/UsersCouponTemplateVO.java @@ -0,0 +1,54 @@ +package cn.iocoder.mall.promotion.application.vo.users; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; + +@ApiModel("CouponTemplate VO") +@Data +@Accessors(chain = true) +public class UsersCouponTemplateVO { + + // ========== 基本信息 BEGIN ========== + @ApiModelProperty(value = "模板编号,自增唯一", required = true, example = "1") + private Integer id; + @ApiModelProperty(value = "标题", required = true, example = "优惠劵牛逼") + private String title; + @ApiModelProperty(value = "优惠码状态", required = true, example = "参见 CouponTemplateStatusEnum 枚举") + private Integer status; + // ========== 领取规则 END ========== + + // ========== 使用规则 BEGIN ========== + @ApiModelProperty(value = "是否设置满多少金额可用,单位:分", required = true, example = "0-不限制;大于0-多少金额可用") + private Integer priceAvailable; + @ApiModelProperty(value = "可用范围的类型", required = true, example = "参见 CouponTemplateRangeTypeEnum 枚举") + private Integer rangeType; + @ApiModelProperty(value = "指定商品 / 分类列表,使用逗号分隔商品编号", example = "参见 CouponTemplateRangeTypeEnum 枚举") + private String rangeValues; + @ApiModelProperty(value = "生效日期类型", example = "参见 CouponTemplateDateTypeEnum 枚举") + private Integer dateType; + @ApiModelProperty(value = "固定日期-生效开始时间") + private Date validStartTime; + @ApiModelProperty(value = "固定日期-生效结束时间") + private Date validEndTime; + @ApiModelProperty(value = "领取日期-开始天数", example = "例如,0-当天;1-次天") + private Integer fixedStartTerm; + @ApiModelProperty(value = "领取日期-结束天数") + private Integer fixedEndTerm; + // ========== 使用规则 END ========== + + // ========== 使用效果 BEGIN ========== + @ApiModelProperty(value = "优惠类型", required = true, example = "参见 CouponTemplatePreferentialTypeEnum 枚举") + private Integer preferentialType; + @ApiModelProperty(value = "折扣百分比") + private Integer percentOff; + @ApiModelProperty(value = "优惠金额,单位:分") + private Integer priceOff; + @ApiModelProperty(value = "折扣上限") + private Integer discountPriceLimit; + // ========== 使用效果 END ========== + +} diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/CouponService.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/CouponService.java index 01f22c3bd..2c867cd4f 100644 --- a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/CouponService.java +++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/CouponService.java @@ -12,6 +12,8 @@ public interface CouponService { // ========== 优惠劵(码)模板 ========== + CommonResult getCouponTemplate(Integer couponTemplateId); + CommonResult getCouponTemplatePage(CouponTemplatePageDTO couponTemplatePageDTO); /** diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/CouponCardBO.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/CouponCardBO.java index 30182fa94..00fa60e31 100644 --- a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/CouponCardBO.java +++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/CouponCardBO.java @@ -3,10 +3,113 @@ package cn.iocoder.mall.promotion.api.bo; import lombok.Data; import lombok.experimental.Accessors; +import java.util.Date; + /** * 优惠劵 BO */ @Data @Accessors(chain = true) public class CouponCardBO { + + // ========== 基本信息 BEGIN ========== + /** + * 优惠劵编号 + */ + private Integer id; + /** + * 优惠劵(码)分组编号 + */ + private Integer templateId; +// /** +// * 核销码 +// */ +// private String verifyCode; + /** + * 优惠码状态 + * + * 1-未使用 + * 2-已使用 + * 3-已失效 + */ + private Integer status; + + // ========== 基本信息 END ========== + + // ========== 领取情况 BEGIN ========== + /** + * 用户编号 + */ + private Integer userId; + /** + * 领取类型 + * + * 1 - 用户主动领取 + * 2 - 后台自动发放 + */ + private Integer takeType; + // ========== 领取情况 END ========== + + // ========== 使用规则 BEGIN ========== + /** + * 生效开始时间 + */ + private Date validStartTime; + /** + * 生效结束时间 + */ + private Date validEndTime; + // ========== 使用规则 END ========== + + // ========== 使用效果 BEGIN ========== + /** + * 优惠类型 + * + * 1-代金卷 + * 2-折扣卷 + */ + private Integer preferentialType; + /** + * 折扣 + */ + private Integer percentOff; + /** + * 优惠金额,单位:分。 + */ + private Integer priceOff; + /** + * 折扣上限,仅在 {@link #preferentialType} 等于 2 时生效。 + * + * 例如,折扣上限为 20 元,当使用 8 折优惠券,订单金额为 1000 元时,最高只可折扣 20 元,而非 80 元。 + */ + private Integer discountPriceLimit; + // ========== 使用效果 END ========== + + // ========== 使用情况 BEGIN ========== + /** + * 是否使用 + */ + private Boolean used; + /** + * 使用订单号 + */ + private Integer usedOrderId; + /** + * 订单中优惠面值,单位:分 + */ + private Integer usedPrice; + /** + * 使用时间 + */ + private Date usedTime; + + // TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。 + + // ========== 使用情况 END ========== + + /** + * 创建时间 + */ + private Date createTime; + } diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/CouponCardStatusEnum.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/CouponCardStatusEnum.java new file mode 100644 index 000000000..0f1079438 --- /dev/null +++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/CouponCardStatusEnum.java @@ -0,0 +1,45 @@ +package cn.iocoder.mall.promotion.api.constant; + +import cn.iocoder.common.framework.core.IntArrayValuable; + +import java.util.Arrays; + +/** + * 优惠劵状态枚举 + */ +public enum CouponCardStatusEnum implements IntArrayValuable { + + UNUSED(1, "未使用"), + USED(2, "已使用"), + EXPIRE(3, "已过期"), + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponCardStatusEnum::getValue).toArray(); + + /** + * 值 + */ + private final Integer value; + /** + * 名字 + */ + private final String name; + + CouponCardStatusEnum(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/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/CouponCardTakeTypeEnum.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/CouponCardTakeTypeEnum.java new file mode 100644 index 000000000..020f3fbb0 --- /dev/null +++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/CouponCardTakeTypeEnum.java @@ -0,0 +1,44 @@ +package cn.iocoder.mall.promotion.api.constant; + +import cn.iocoder.common.framework.core.IntArrayValuable; + +import java.util.Arrays; + +/** + * 优惠劵领取方式 + */ +public enum CouponCardTakeTypeEnum implements IntArrayValuable { + + BY_USER(1, "用户主动领取"), + BY_ADMIN(2, "已使用"), + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponCardTakeTypeEnum::getValue).toArray(); + + /** + * 值 + */ + private final Integer value; + /** + * 名字 + */ + private final String name; + + CouponCardTakeTypeEnum(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/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java index aa40e719e..999b663f2 100644 --- a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java +++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java @@ -21,6 +21,7 @@ public enum PromotionErrorCodeEnum { PRODUCT_TEMPLATE_NOT_CARD(1006002001, "不是优惠劵模板"), PRODUCT_TEMPLATE_NOT_CODE(1006002002, "不是优惠码模板"), PRODUCT_TEMPLATE_TOTAL_CAN_NOT_REDUCE(1006002003, "优惠劵(码)模板的发放数量不能减小"), + PRODUCT_TEMPLATE_STATUS_NOT_ENABLE(1006002004, "优惠劵模板(码)未开启"), ; diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/convert/CouponCardConvert.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/convert/CouponCardConvert.java new file mode 100644 index 000000000..81b211446 --- /dev/null +++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/convert/CouponCardConvert.java @@ -0,0 +1,25 @@ +package cn.iocoder.mall.promotion.biz.convert; + +import cn.iocoder.mall.promotion.api.bo.CouponCardBO; +import cn.iocoder.mall.promotion.biz.dataobject.CouponCardDO; +import org.mapstruct.Mapper; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface CouponCardConvert { + + CouponCardConvert INSTANCE = Mappers.getMapper(CouponCardConvert.class); + +// @Mappings({}) +// CouponCardBO convertToBO(CouponCardDO banner); +// + @Mappings({}) + List convertToBO(List cardList); + + @Mappings({}) + CouponCardBO convert(CouponCardDO card); + +} diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dao/CouponCardMapper.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dao/CouponCardMapper.java new file mode 100644 index 000000000..8560c2e7c --- /dev/null +++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dao/CouponCardMapper.java @@ -0,0 +1,22 @@ +package cn.iocoder.mall.promotion.biz.dao; + +import cn.iocoder.mall.promotion.biz.dataobject.CouponCardDO; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface CouponCardMapper { + + CouponCardDO selectById(@Param("id") Integer id); + + List selectListByPage(@Param("status") Integer status); + + Integer selectCountByPage(@Param("status") Integer status); + + void insert(CouponCardDO couponCardDO); + + int update(CouponCardDO couponCardDO); + +} diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dataobject/CouponCardDO.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dataobject/CouponCardDO.java index 5223c8d74..45569cf1d 100644 --- a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dataobject/CouponCardDO.java +++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dataobject/CouponCardDO.java @@ -53,11 +53,11 @@ public class CouponCardDO extends BaseDO { // ========== 使用规则 BEGIN ========== /** - * 固定日期-生效开始时间 + * 生效开始时间 */ private Date validStartTime; /** - * 固定日期-生效结束时间 + * 生效结束时间 */ private Date validEndTime; // ========== 使用规则 END ========== @@ -73,7 +73,7 @@ public class CouponCardDO extends BaseDO { /** * 折扣 */ - private Double percentOff; + private Integer percentOff; /** * 优惠金额,单位:分。 */ @@ -87,14 +87,10 @@ public class CouponCardDO extends BaseDO { // ========== 使用效果 END ========== // ========== 使用情况 BEGIN ========== - /** - * 是否使用 - */ - private Boolean used; /** * 使用订单号 */ - private String usedOrderId; + private Integer usedOrderId; /** * 订单中优惠面值,单位:分 */ diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/CouponServiceImpl.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/CouponServiceImpl.java index 270feaeaf..5cd78f229 100644 --- a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/CouponServiceImpl.java +++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/CouponServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.mall.promotion.biz.service; import cn.iocoder.common.framework.constant.SysErrorCodeEnum; +import cn.iocoder.common.framework.util.DateUtil; import cn.iocoder.common.framework.util.ServiceExceptionUtil; import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.promotion.api.CouponService; @@ -9,12 +10,17 @@ import cn.iocoder.mall.promotion.api.bo.CouponTemplateBO; import cn.iocoder.mall.promotion.api.bo.CouponTemplatePageBO; import cn.iocoder.mall.promotion.api.constant.*; import cn.iocoder.mall.promotion.api.dto.*; +import cn.iocoder.mall.promotion.biz.convert.CouponCardConvert; import cn.iocoder.mall.promotion.biz.convert.CouponTemplateConvert; +import cn.iocoder.mall.promotion.biz.convert.CouponTemplateConvertImpl; +import cn.iocoder.mall.promotion.biz.dao.CouponCardMapper; import cn.iocoder.mall.promotion.biz.dao.CouponTemplateMapper; +import cn.iocoder.mall.promotion.biz.dataobject.CouponCardDO; import cn.iocoder.mall.promotion.biz.dataobject.CouponTemplateDO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.Calendar; import java.util.Date; @Service // 实际上不用添加。添加的原因是,必须 Spring 报错提示 @@ -23,9 +29,17 @@ public class CouponServiceImpl implements CouponService { @Autowired private CouponTemplateMapper couponTemplateMapper; + @Autowired + private CouponCardMapper couponCardMapper; // ========== 优惠劵(码)模板 ========== + @Override + public CommonResult getCouponTemplate(Integer couponTemplateId) { + CouponTemplateDO template = couponTemplateMapper.selectById(couponTemplateId); + return CommonResult.success(CouponTemplateConvertImpl.INSTANCE.convert(template)); + } + @Override public CommonResult getCouponTemplatePage(CouponTemplatePageDTO couponTemplatePageDTO) { CouponTemplatePageBO couponTemplatePageBO = new CouponTemplatePageBO(); @@ -163,7 +177,37 @@ public class CouponServiceImpl implements CouponService { @Override public CommonResult addCouponCard(Integer userId, Integer couponTemplateId) { - return null; + // 校验 CouponCardTemplate 存在 + CouponTemplateDO template = couponTemplateMapper.selectById(couponTemplateId); + if (template == null) { + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_NOT_EXISTS.getCode()); + } + // 校验 CouponCardTemplate 是 CARD + if (!CouponTemplateTypeEnum.CARD.getValue().equals(template.getType())) { + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_NOT_CARD.getCode()); + } + // 校验 CouponCardTemplate 状态是否开启 + if (!CouponTemplateStatusEnum.ENABLE.getValue().equals(template.getStatus())) { + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_STATUS_NOT_ENABLE.getCode()); + } + // 创建优惠劵 + // 1. 基本信息 + 领取情况 + CouponCardDO card = new CouponCardDO() + .setTemplateId(couponTemplateId) + .setStatus(CouponCardStatusEnum.UNUSED.getValue()) + .setUserId(userId) + .setTakeType(CouponCardTakeTypeEnum.BY_USER.getValue()); // TODO 需要改 + // 2. 使用规则 + setCouponCardValidTime(card, template); + // 3. 使用效果 + card.setPreferentialType(template.getPreferentialType()) + .setPriceOff(template.getPriceOff()) + .setPercentOff(template.getPercentOff()).setDiscountPriceLimit(template.getDiscountPriceLimit()); + // 保存优惠劵模板到数据库 + card.setCreateTime(new Date()); + couponCardMapper.insert(card); + // 返回成功 + return CommonResult.success(CouponCardConvert.INSTANCE.convert(card)); } @Override @@ -176,6 +220,17 @@ public class CouponServiceImpl implements CouponService { return null; } + private void setCouponCardValidTime(CouponCardDO card, CouponTemplateDO template) { + if (CouponTemplateDateTypeEnum.FIXED_DATE.getValue().equals(template.getDateType())) { + card.setValidStartTime(template.getValidStartTime()).setValidEndTime(template.getValidEndTime()); + } else if (CouponTemplateDateTypeEnum.FIXED_TERM.getValue().equals(template.getDateType())) { + Date validStartTime = DateUtil.getDayBegin(new Date()); + card.setValidStartTime(DateUtil.addDate(validStartTime, Calendar.DAY_OF_YEAR, template.getFixedStartTerm())); + Date validEndTime = DateUtil.getDayEnd(card.getValidStartTime()); + card.setValidEndTime(DateUtil.addDate(validEndTime, Calendar.DAY_OF_YEAR, template.getFixedEndTerm() - 1)); + } + } + // ========== 优惠码 ========== @Override diff --git a/promotion/promotion-service-impl/src/main/resources/mapper/CouponCardMapper.xml b/promotion/promotion-service-impl/src/main/resources/mapper/CouponCardMapper.xml new file mode 100644 index 000000000..1082ebe80 --- /dev/null +++ b/promotion/promotion-service-impl/src/main/resources/mapper/CouponCardMapper.xml @@ -0,0 +1,92 @@ + + + + + + id, template_id, status, user_id, take_type, + valid_start_time, valid_end_time, preferential_type, percent_off, price_off, + discount_price_limit, used_order_id, used_price, used_time, + create_time + + + + + + + + + + + + + + + + + + + + + + + + + + + INSERT INTO coupon_card ( + template_id, status, user_id, take_type, + valid_start_time, valid_end_time, preferential_type, percent_off, price_off, + discount_price_limit, used_order_id, used_price, used_time, + create_time + ) VALUES ( + #{templateId}, #{status}, #{userId}, #{takeType}, + #{validStartTime}, #{validEndTime}, #{preferentialType}, #{percentOff}, #{priceOff}, + #{discountPriceLimit}, #{usedOrderId}, #{usedPrice}, #{usedTime}, + #{createTime} + ) + + + + UPDATE coupon_card + + + status = #{status}, + + + used_order_id = #{usedOrderId}, + + + used_price = #{usedPrice}, + + + used_time = #{usedTime}, + + + WHERE id = #{id} + + +