diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/PromotionActivityService.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/PromotionActivityRpc.java similarity index 93% rename from promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/PromotionActivityService.java rename to promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/PromotionActivityRpc.java index a8ea7dadd..744340e3e 100644 --- a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/PromotionActivityService.java +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/PromotionActivityRpc.java @@ -3,7 +3,7 @@ package cn.iocoder.mall.promotion.api.rpc.activity.dto; import java.util.Collection; import java.util.List; -public interface PromotionActivityService { +public interface PromotionActivityRpc { List getPromotionActivityListBySpuId(Integer spuId, Collection activityStatuses); diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/banner/BannerService.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/banner/BannerRpc.java similarity index 97% rename from promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/banner/BannerService.java rename to promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/banner/BannerRpc.java index 87a8ba179..62521cae1 100644 --- a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/banner/BannerService.java +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/banner/BannerRpc.java @@ -10,7 +10,7 @@ import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerUpdateReqDTO; import java.util.List; -public interface BannerService { +public interface BannerRpc { List getBannerListByStatus(Integer status); diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/coupon/CouponService.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/coupon/CouponRpc.java similarity index 99% rename from promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/coupon/CouponService.java rename to promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/coupon/CouponRpc.java index 903a6319c..b6722673b 100644 --- a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/coupon/CouponService.java +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/coupon/CouponRpc.java @@ -7,7 +7,7 @@ import cn.iocoder.mall.promotion.api.rpc.coupon.dto.*; import javax.validation.constraints.NotNull; import java.util.List; -public interface CouponService { +public interface CouponRpc { // ========== 优惠劵(码)模板 ========== diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/coupon/dto/CouponCardSpuRespDTO.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/coupon/dto/CouponCardSpuRespDTO.java index 46a49468b..9f0709cd6 100644 --- a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/coupon/dto/CouponCardSpuRespDTO.java +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/coupon/dto/CouponCardSpuRespDTO.java @@ -1,6 +1,6 @@ package cn.iocoder.mall.promotion.api.rpc.coupon.dto; -import cn.iocoder.mall.promotion.api.rpc.coupon.CouponService; +import cn.iocoder.mall.promotion.api.rpc.coupon.CouponRpc; import lombok.Data; import lombok.experimental.Accessors; @@ -10,7 +10,7 @@ import java.util.List; /** * 优惠劵商品 DTO * - * 主要用于 {@link CouponService#getCouponCardList(Integer, List)} + * 主要用于 {@link CouponRpc#getCouponCardList(Integer, List)} */ @Data @Accessors(chain = true) diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/recommend/ProductRecommendService.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/recommend/ProductRecommendRpc.java similarity index 96% rename from promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/recommend/ProductRecommendService.java rename to promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/recommend/ProductRecommendRpc.java index 5d6a2f98f..982f20c40 100644 --- a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/recommend/ProductRecommendService.java +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/recommend/ProductRecommendRpc.java @@ -6,7 +6,7 @@ import cn.iocoder.common.framework.validator.InEnum; import java.util.List; -public interface ProductRecommendService { +public interface ProductRecommendRpc { List getProductRecommendList(Integer type, Integer status); diff --git a/promotion-service-project/promotion-service-app/pom.xml b/promotion-service-project/promotion-service-app/pom.xml index 3c61c34ec..935e831b6 100644 --- a/promotion-service-project/promotion-service-app/pom.xml +++ b/promotion-service-project/promotion-service-app/pom.xml @@ -12,10 +12,40 @@ promotion-service-app + + + cn.iocoder.mall + mall-spring-boot-starter-dubbo + + cn.iocoder.mall promotion-service-api + + + org.springframework.boot + spring-boot + + + org.springframework.boot + spring-boot-autoconfigure + + + + mysql + mysql-connector-java + + + + com.alibaba + druid-spring-boot-starter + + + + cn.iocoder.mall + mall-spring-boot-starter-mybatis + \ No newline at end of file diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/PromotionServiceApplication.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/PromotionServiceApplication.java new file mode 100644 index 000000000..fc6422543 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/PromotionServiceApplication.java @@ -0,0 +1,14 @@ +package cn.iocoder.mall.promotionservice; + + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class PromotionServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(PromotionServiceApplication.class, args); + } + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/config/AsyncConfiguration.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/config/AsyncConfiguration.java new file mode 100644 index 000000000..84ca8a91f --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/config/AsyncConfiguration.java @@ -0,0 +1,9 @@ +package cn.iocoder.mall.promotionservice.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; + +@Configuration +@EnableAsync(proxyTargetClass = true) // 开启 Spring Async 异步的功能 +public class AsyncConfiguration { +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/config/DatabaseConfiguration.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/config/DatabaseConfiguration.java new file mode 100644 index 000000000..efded6dc4 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/config/DatabaseConfiguration.java @@ -0,0 +1,28 @@ +package cn.iocoder.mall.promotionservice.config; + +import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; +import com.baomidou.mybatisplus.core.injector.ISqlInjector; +import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@MapperScan("cn.iocoder.mall.promotionservice.dal.mysql.mapper") // 扫描对应的 Mapper 接口 +@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理。 +public class DatabaseConfiguration { + + // 数据库连接池 Druid + + @Bean + public ISqlInjector sqlInjector() { + return new DefaultSqlInjector(); // MyBatis Plus 逻辑删除 + } + + @Bean + public PaginationInterceptor paginationInterceptor() { + return new PaginationInterceptor(); // MyBatis Plus 分页插件 + } + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/convert/activity/PromotionActivityConvert.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/convert/activity/PromotionActivityConvert.java new file mode 100644 index 000000000..3e0f5b053 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/convert/activity/PromotionActivityConvert.java @@ -0,0 +1,35 @@ +package cn.iocoder.mall.promotionservice.convert.activity; + +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO; +import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.activity.PromotionActivityDO; +import cn.iocoder.mall.promotionservice.service.activity.bo.PromotionActivityBO; +import org.mapstruct.Mapper; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface PromotionActivityConvert { + + PromotionActivityConvert INSTANCE = Mappers.getMapper(PromotionActivityConvert.class); + + @Mappings({}) + PromotionActivityBO convertToBO(PromotionActivityDO activity); + + @Mappings({}) + List convertToBO(List activityList); + + @Mappings({}) + List convertToDO(List activityList); + + @Mappings({}) + List convertToRespDTO(List activityList); + +// @Mappings({}) +// PromotionActivityDO convert(PromotionActivityAddDTO activityAddDTO); +// +// @Mappings({}) +// PromotionActivityDO convert(PromotionActivityUpdateDTO activityUpdateDTO); + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/activity/PromotionActivityDO.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/activity/PromotionActivityDO.java new file mode 100644 index 000000000..2cca869a1 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/activity/PromotionActivityDO.java @@ -0,0 +1,188 @@ +package cn.iocoder.mall.promotionservice.dal.mysql.dataobject.activity; + +import cn.iocoder.mall.mybatis.core.dataobject.BaseDO; +import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; +import java.util.List; + +/** + * 促销活动 DO + */ +@Data +@Accessors(chain = true) +public class PromotionActivityDO extends DeletableDO { + + /** + * 活动编号 + */ + private Integer id; + /** + * 活动标题 + */ + private String title; + /** + * 活动类型 + * + * 参见 {@link cn.iocoder.mall.promotion.api.enums.PromotionActivityTypeEnum} 枚举 + */ + private Integer activityType; +// /** +// * 促销类型 +// * // TODO 芋艿 https://jos.jd.com/api/complexTemplate.htm?webPamer=promotion_v_o&groupName=%E4%BF%83%E9%94%80API&id=54&restName=jingdong.seller.promotion.list&isMulti=false 促销类型,可选值:单品促销(1),赠品促销(4),套装促销(6),总价促销(10) +// */ +// private Integer promotionType; + /** + * 活动状态 + * + * 参见 {@link cn.iocoder.mall.promotion.api.enums.PromotionActivityStatusEnum} 枚举 + */ + private Integer status; + /** + * 开始时间 + */ + private Date startTime; + /** + * 结束时间 + */ + private Date endTime; + /** + * 失效时间 + */ + private Date invalidTime; + /** + * 删除时间 + */ + private Date deleteTime; + /** + * 限制折扣字符串,使用 JSON 序列化成字符串存储 + */ + private TimeLimitedDiscount timeLimitedDiscount; + /** + * 满减送字符串,使用 JSON 序列化成字符串存储 + */ + private FullPrivilege fullPrivilege; + + /** + * 限制折扣 + */ + @Data + @Accessors(chain = true) + public static class TimeLimitedDiscount { + + /** + * 商品折扣 + */ + @Data + @Accessors(chain = true) + public static class Item { + + /** + * 商品 SPU 编号 + */ + private Integer spuId; + /** + * 优惠类型 + */ + private Integer preferentialType; + /** + * 优惠值 + */ + private Integer preferentialValue; + + } + + /** + * 每人每种限购多少 + * + * 当 quota = 0 时,表示不限购 + */ + private Integer quota; + /** + * 商品折扣数组 + */ + private List items; + + } + + /** + * 满减送 + */ + @Data + @Accessors(chain = true) + public static class FullPrivilege { + + /** + * 优惠 + */ + @Data + @Accessors(chain = true) + public static class Privilege { + + /** + * 满足类型 + * + * 1 - 金额 + * 2 - 件数 + */ + private Integer meetType; + /** + * 满足值 + */ + private Integer meetValue; + /** + * 优惠类型 + */ + private Integer preferentialType; + /** + * 优惠值 + */ + private Integer preferentialValue; +// /** +// * 是否包邮 +// */ +// private Boolean isPostage; +// /** +// * 积分 +// */ +// private Integer score; +// /** +// * 优惠劵(码)分组编号 +// */ +// private Integer couponTemplateId; +// /** +// * 优惠劵(码)数量 +// */ +// private Integer couponNum; +// /** +// * 赠品编号 +// */ +// private Integer presentId; + + } + + /** + * 可用范围的类型 + * + * 参见 {@link cn.iocoder.mall.promotion.api.enums.RangeTypeEnum} 枚举 + * 暂时只用 “所有可用” + “PRODUCT_INCLUDE_PRT” + */ + private Integer rangeType; + /** + * 指定可用商品列表 + */ + private List rangeValues; + /** + * 是否循环 + */ + private Boolean cycled; + /** + * 优惠数组 + */ + private List privileges; + + } + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/banner/BannerDO.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/banner/BannerDO.java new file mode 100644 index 000000000..ea8836961 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/banner/BannerDO.java @@ -0,0 +1,47 @@ +package cn.iocoder.mall.promotionservice.dal.mysql.dataobject.banner; + +import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * Banner 广告页 + */ +@Data +@Accessors(chain = true) +public class BannerDO extends DeletableDO { + + /** + * 编号 + */ + private Integer id; + /** + * 标题 + */ + private String title; + /** + * 跳转链接 + */ + private String url; + /** + * 图片链接 + */ + private String picUrl; + /** + * 排序 + */ + private Integer sort; + /** + * 状态 + * + * {@link cn.iocoder.common.framework.enums.CommonStatusEnum} + */ + private Integer status; + /** + * 备注 + */ + private String memo; + + // TODO 芋艿 点击次数。&& 其他数据相关 + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/coupon/CouponCardDO.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/coupon/CouponCardDO.java new file mode 100644 index 000000000..666b3e90f --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/coupon/CouponCardDO.java @@ -0,0 +1,119 @@ +package cn.iocoder.mall.promotionservice.dal.mysql.dataobject.coupon; + +import cn.iocoder.mall.mybatis.core.dataobject.BaseDO; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; + +/** + * 优惠劵 DO + */ +@Data +@Accessors(chain = true) +public class CouponCardDO extends BaseDO { + + // ========== 基本信息 BEGIN ========== + /** + * 优惠劵编号 + */ + private Integer id; + /** + * 优惠劵(码)分组编号,{@link CouponTemplateDO} 的 id + */ + private Integer templateId; + /** + * 优惠劵名 + * + * 冗余自 {@link CouponTemplateDO} 的 title + * + * TODO 芋艿,暂时不考虑冗余的更新 + */ + private String title; +// /** +// * 核销码 +// */ +// private String verifyCode; + /** + * 优惠码状态 + * + * 1-未使用 + * 2-已使用 + * 3-已失效 + */ + private Integer status; + + // ========== 基本信息 END ========== + + // ========== 领取情况 BEGIN ========== + /** + * 用户编号 + */ + private Integer userId; + /** + * 领取类型 + * + * 1 - 用户主动领取 + * 2 - 后台自动发放 + */ + private Integer takeType; + // ========== 领取情况 END ========== + + // ========== 使用规则 BEGIN ========== + /** + * 是否设置满多少金额可用,单位:分 + */ + private Integer priceAvailable; + /** + * 生效开始时间 + */ + 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 Integer usedOrderId; // TODO 芋艿,暂时不考虑这个字段 +// /** +// * 订单中优惠面值,单位:分 +// */ +// private Integer usedPrice; // TODO 芋艿,暂时不考虑这个字段 + /** + * 使用时间 + */ + private Date usedTime; + + // TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。 + + // ========== 使用情况 END ========== + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/coupon/CouponCodeDO.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/coupon/CouponCodeDO.java new file mode 100644 index 000000000..b8651fe1b --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/coupon/CouponCodeDO.java @@ -0,0 +1,43 @@ +package cn.iocoder.mall.promotionservice.dal.mysql.dataobject.coupon; + +import cn.iocoder.mall.mybatis.core.dataobject.BaseDO; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; + +/** + * 优惠码 + */ +@Data +@Accessors(chain = true) +public class CouponCodeDO extends BaseDO { + + /** + * 编号 + */ + private Integer id; + /** + * 模板编号 {@link CouponTemplateDO} 的 id + */ + private Integer templateId; + /** + * 优惠码 + */ + private Integer code; + /** + * 领取时间 + */ + private Date takeTime; + /** + * 领取用户编号 + */ + private Integer userId; + /** + * 领取的优惠劵编号 + */ + private Integer couponId; + + // TODO 芋艿,后续要考虑状态的追踪 + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/coupon/CouponTemplateDO.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/coupon/CouponTemplateDO.java new file mode 100644 index 000000000..23661d1c3 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/coupon/CouponTemplateDO.java @@ -0,0 +1,220 @@ +package cn.iocoder.mall.promotionservice.dal.mysql.dataobject.coupon; + +import cn.iocoder.mall.mybatis.core.dataobject.BaseDO; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; + +/** + * 优惠劵(码)模板 DO + * + * 当用户领取时,会生成 {@link CouponCardDO} 优惠劵(码)。 + */ +@Data +@Accessors(chain = true) +public class CouponTemplateDO extends BaseDO { + + // ========== 基本信息 BEGIN ========== + /** + * 模板编号,自增唯一。 + */ + private Integer id; + /** + * 标题 + */ + private String title; + /** + * 使用说明 + */ + private String description; + /** + * 类型 + * + * 1-优惠劵 + * 2-优惠码 + */ + private Integer type; + /** + * 优惠码状态 + * + * {@link cn.iocoder.mall.promotion.api.enums.CouponTemplateStatusEnum} + * + * 当优惠劵(码)开启中,可以手动操作,设置禁用中。 + */ + private Integer status; +// /** +// * 是否可分享领取链接 +// */ +// private Boolean isShare; +// /** +// * 设置为失效时间 +// */ +// private Date invalidTime; +// /** +// * 删除时间 +// */ +// private Date deleteTime; + + // ========== 基本信息 END ========== + + // ========== 领取规则 BEGIN ========== +// /** +// * 是否限制领用者的等级 +// * +// * 0-不限制 +// * 大于0-领用者必须是这个等级编号 +// * +// * 【优惠劵独有】 +// */ +// private Integer needUserLevel; + /** + * 每人限领个数 + * + * null - 则表示不限制 + */ + private Integer quota; + /** + * 发行总量 + */ + private Integer total; + // ========== 领取规则 END ========== + + // ========== 使用规则 BEGIN ========== +// /** +// * 是否仅原价购买商品时可用 +// * +// * true-是 +// * false-否 +// */ +// private Boolean isForbidPreference; + /** + * 是否设置满多少金额可用,单位:分 + * + * 0-不限制 + * 大于0-多少金额可用 + */ + private Integer priceAvailable; + /** + * 可用范围的类型 + * + * 10-全部(ALL):所有可用 + * 20-部分(PART):部分商品可用,或指定商品可用 + * 21-部分(PART):部分商品不可用,或指定商品可用 + * 30-部分(PART):部分分类可用,或指定商品可用 + * 31-部分(PART):部分分类不可用,或指定商品可用 + */ + private Integer rangeType; + /** + * 指定商品 / 分类列表,使用逗号分隔商品编号 + */ + private String rangeValues; + /** + * 生效日期类型 + * + * 1-固定日期 + * 2-领取日期:领到券 {@link #fixedStartTerm} 日开始 N 天内有效 + */ + private Integer dateType; + /** + * 固定日期-生效开始时间 + */ + private Date validStartTime; + /** + * 固定日期-生效结束时间 + */ + private Date validEndTime; + /** + * 领取日期-开始天数 + * + * 例如,0-当天;1-次天 + */ + private Integer fixedStartTerm; + /** + * 领取日期-结束天数 + */ + private Integer fixedEndTerm; +// /** +// * 是否到期前4天发送提醒 +// * +// * true-发送 +// * false-不发送 +// */ +// private Boolean expireNotice; + // ========== 使用规则 END ========== + + // ========== 使用效果 BEGIN ========== + /** + * 优惠类型 + * + * 1-代金卷 + * 2-折扣卷 + */ + private Integer preferentialType; + /** + * 折扣百分比。 + * + * 例如,80% 为 80。 + * 当 100% 为 100 ,则代表免费。 + */ + private Integer percentOff; +// /** +// * 是否是随机优惠券 +// * +// * true-随机 +// * false-不随机 +// * +// * 【优惠劵独有】 +// */ +// private Boolean isRandom; + /** + * 优惠金额,单位:分 + */ +// * 当 {@link #isRandom} 为 true 时,代表随机优惠金额的下限 + private Integer priceOff; +// /** +// * 优惠金额上限 +// * +// * 【优惠劵独有】 +// */ +// private Integer valueRandomTo; + /** + * 折扣上限,仅在 {@link #preferentialType} 等于 2 时生效。 + * + * 例如,折扣上限为 20 元,当使用 8 折优惠券,订单金额为 1000 元时,最高只可折扣 20 元,而非 80 元。 + */ + private Integer discountPriceLimit; + // ========== 使用效果 END ========== + + // ========== 统计信息 BEGIN ========== +// /** +// * 领取优惠券的人数 +// */ +// private Integer statFetchUserNum; + /** + * 领取优惠券的次数 + */ + private Integer statFetchNum; +// /** +// * 使用优惠券的次数 +// */ +// private Integer statUseNum; + // ========== 统计信息 END ========== + + // ========== 优惠码 BEGIN ========== + /** + * 码类型 + * + * 1-一卡一码(UNIQUE) + * 2-通用码(GENERAL) + * + * 【优惠码独有】 @see CouponCodeDO + */ + private Integer codeType; + /** + * 通用码 + */ + private String commonCode; + // ========== 优惠码 BEGIN ========== + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/recommend/ProductRecommendDO.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/recommend/ProductRecommendDO.java new file mode 100644 index 000000000..ae114f13e --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/dataobject/recommend/ProductRecommendDO.java @@ -0,0 +1,46 @@ +package cn.iocoder.mall.promotionservice.dal.mysql.dataobject.recommend; + + +import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO; +import cn.iocoder.mall.promotion.api.enums.ProductRecommendTypeEnum; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 商品推荐 DO + */ +@Data +@Accessors(chain = true) +public class ProductRecommendDO extends DeletableDO { + + /** + * 编号 + */ + private Integer id; + /** + * 类型 + * + * {@link ProductRecommendTypeEnum} + */ + private Integer type; + /** + * 商品 Spu 编号 + */ + private Integer productSpuId; + // TODO 芋艿,商品 spu 名 + /** + * 排序 + */ + private Integer sort; + /** + * 状态 + * + * {@link cn.iocoder.common.framework.enums.CommonStatusEnum} + */ + private Integer status; + /** + * 备注 + */ + private String memo; + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/activity/PromotionActivityMapper.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/activity/PromotionActivityMapper.java new file mode 100644 index 000000000..0f0cfcdd2 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/activity/PromotionActivityMapper.java @@ -0,0 +1,29 @@ +package cn.iocoder.mall.promotionservice.dal.mysql.mapper.activity; + +import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.activity.PromotionActivityDO; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.Collection; +import java.util.List; + +@Repository +public interface PromotionActivityMapper { + + PromotionActivityDO selectById(@Param("id") Integer id); + + List selectListByStatus(@Param("statuses") Collection statuses); + + void insert(PromotionActivityDO activity); + + List selectListByPage(@Param("title") String title, + @Param("activityType") Integer activityType, + @Param("statuses") Collection statuses, + @Param("offset") Integer offset, + @Param("limit") Integer limit); + + Integer selectCountByPage(@Param("title") String title, + @Param("activityType") Integer activityType, + @Param("statuses") Collection statuses); + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/banner/BannerMapper.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/banner/BannerMapper.java new file mode 100644 index 000000000..62e53a2d3 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/banner/BannerMapper.java @@ -0,0 +1,26 @@ +package cn.iocoder.mall.promotionservice.dal.mysql.mapper.banner; + +import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.banner.BannerDO; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface BannerMapper { + + BannerDO selectById(@Param("id") Integer id); + + List selectListByStatus(@Param("status") Integer status); + + List selectListByTitleLike(@Param("title") String title, + @Param("offset") Integer offset, + @Param("limit") Integer limit); + + Integer selectCountByTitleLike(@Param("title") String title); + + void insert(BannerDO bannerDO); + + int update(BannerDO bannerDO); + +} \ No newline at end of file diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/coupon/CouponCardMapper.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/coupon/CouponCardMapper.java new file mode 100644 index 000000000..496fd0014 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/coupon/CouponCardMapper.java @@ -0,0 +1,36 @@ +package cn.iocoder.mall.promotionservice.dal.mysql.mapper.coupon; + +import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.coupon.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 selectListByUserIdAndStatus(@Param("userId") Integer userId, + @Param("status") Integer status); + + List selectListByPage(@Param("userId") Integer userId, + @Param("status") Integer status, + @Param("offset") Integer offset, + @Param("limit") Integer limit); + + Integer selectCountByPage(@Param("userId") Integer userId, + @Param("status") Integer status); + + int selectCountByUserIdAndTemplateId(@Param("userId") Integer userId, + @Param("templateId") Integer templateId); + + void insert(CouponCardDO couponCardDO); + + int update(CouponCardDO couponCardDO); + + int updateByIdAndStatus(@Param("id") Integer id, + @Param("status") Integer status, + @Param("updateObj") CouponCardDO updateObj); + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/coupon/CouponTemplateMapper.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/coupon/CouponTemplateMapper.java new file mode 100644 index 000000000..ed0bf1b34 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/coupon/CouponTemplateMapper.java @@ -0,0 +1,35 @@ +package cn.iocoder.mall.promotionservice.dal.mysql.mapper.coupon; + +import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.coupon.CouponTemplateDO; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.Collection; +import java.util.List; + +@Repository +public interface CouponTemplateMapper { + + CouponTemplateDO selectById(@Param("id") Integer id); + + List selectListByIds(@Param("ids") Collection ids); + + List selectListByPage(@Param("type") Integer type, + @Param("title") String title, + @Param("status") Integer status, + @Param("preferentialType") Integer preferentialType, + @Param("offset") Integer offset, + @Param("limit") Integer limit); + + Integer selectCountByPage(@Param("type") Integer type, + @Param("title") String title, + @Param("status") Integer status, + @Param("preferentialType") Integer preferentialType); + + void insert(CouponTemplateDO couponTemplate); + + int update(CouponTemplateDO couponTemplate); + + int updateStatFetchNumIncr(@Param("id") Integer id); + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/recommend/ProductRecommendMapper.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/recommend/ProductRecommendMapper.java new file mode 100644 index 000000000..b676c40df --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/recommend/ProductRecommendMapper.java @@ -0,0 +1,30 @@ +package cn.iocoder.mall.promotionservice.dal.mysql.mapper.recommend; + +import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.recommend.ProductRecommendDO; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ProductRecommendMapper { + + ProductRecommendDO selectById(@Param("id") Integer id); + + ProductRecommendDO selectByProductSpuIdAndType(@Param("productSpuId") Integer productSpuId, + @Param("type") Integer type); + + List selectListByTypeAndStatus(@Param("type") Integer type, + @Param("status") Integer status); + + List selectPageByType(@Param("type") Integer type, + @Param("offset") Integer offset, + @Param("limit") Integer limit); + + Integer selectCountByType(@Param("type") Integer type); + + void insert(ProductRecommendDO bannerDO); + + int update(ProductRecommendDO bannerDO); + +} \ No newline at end of file diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/PromotionActivityService.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/PromotionActivityService.java new file mode 100644 index 000000000..df8c99e27 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/PromotionActivityService.java @@ -0,0 +1,102 @@ +package cn.iocoder.mall.promotionservice.service.activity; + +import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil; +import cn.iocoder.mall.promotion.api.enums.PromotionActivityTypeEnum; +import cn.iocoder.mall.promotion.api.enums.RangeTypeEnum; +import cn.iocoder.mall.promotionservice.convert.activity.PromotionActivityConvert; +import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.activity.PromotionActivityDO; +import cn.iocoder.mall.promotionservice.dal.mysql.mapper.activity.PromotionActivityMapper; +import cn.iocoder.mall.promotionservice.service.activity.bo.PromotionActivityPageBO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.Assert; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + + +@Service +@Validated +public class PromotionActivityService { + + @Autowired + private PromotionActivityMapper promotionActivityMapper; + + public List getPromotionActivityListBySpuId(Integer spuId, Collection activityStatuses) { + return this.getPromotionActivityListBySpuIds(Collections.singleton(spuId), activityStatuses); + } + + public List getPromotionActivityListBySpuIds(Collection spuIds, Collection activityStatuses) { + if (spuIds.isEmpty() || activityStatuses.isEmpty()) { + return Collections.emptyList(); + } + // 查询指定状态的促销活动 + List activityList = promotionActivityMapper.selectListByStatus(activityStatuses); + if (activityList.isEmpty()) { + return Collections.emptyList(); + } + // 匹配商品 + for (Iterator iterator = activityList.iterator(); iterator.hasNext();) { + PromotionActivityDO activity = iterator.next(); + boolean matched = false; + for (Integer spuId : spuIds) { + if (PromotionActivityTypeEnum.TIME_LIMITED_DISCOUNT.getValue().equals(activity.getActivityType())) { + matched = isSpuMatchTimeLimitDiscount(spuId, activity); + } else if (PromotionActivityTypeEnum.FULL_PRIVILEGE.getValue().equals(activity.getActivityType())) { + matched = isSpuMatchFullPrivilege(spuId, activity); + } + if (matched) { + break; + } + } + // 不匹配,则进行移除 + if (!matched) { + iterator.remove(); + } else { // 匹配,则做一些后续的处理 + // 如果是限时折扣,移除不在 spuId 数组中的折扣规则 + if (PromotionActivityTypeEnum.TIME_LIMITED_DISCOUNT.getValue().equals(activity.getActivityType())) { + activity.getTimeLimitedDiscount().getItems().removeIf(item -> !spuIds.contains(item.getSpuId())); + } + } + } + // 返回最终结果 + return activityList; + } + + public PromotionActivityPageBO getPromotionActivityPage(Integer pageNo,Integer pageSize,String title,Integer activityType,Collection statuses) { + PromotionActivityPageBO promotionActivityPageBO = new PromotionActivityPageBO(); + // 查询分页数据 + int offset = (pageNo - 1) * pageSize; + promotionActivityPageBO.setList(PromotionActivityConvert.INSTANCE.convertToRespDTO(promotionActivityMapper.selectListByPage( + title, activityType,statuses, offset, pageSize))); + // 查询分页总数 + promotionActivityPageBO.setTotal(promotionActivityMapper.selectCountByPage( + title,activityType,statuses)); + return promotionActivityPageBO; + } + + private boolean isSpuMatchTimeLimitDiscount(Integer spuId, PromotionActivityDO activity) { + Assert.isTrue(PromotionActivityTypeEnum.TIME_LIMITED_DISCOUNT.getValue().equals(activity.getActivityType()), + "传入的必须的促销活动必须是限时折扣"); + return activity.getTimeLimitedDiscount().getItems().stream() + .anyMatch(item -> spuId.equals(item.getSpuId())); + } + + private boolean isSpuMatchFullPrivilege(Integer spuId, PromotionActivityDO activity) { + Assert.isTrue(PromotionActivityTypeEnum.FULL_PRIVILEGE.getValue().equals(activity.getActivityType()), + "传入的必须的促销活动必须是满减送"); + PromotionActivityDO.FullPrivilege fullPrivilege = activity.getFullPrivilege(); + if (RangeTypeEnum.ALL.getValue().equals(fullPrivilege.getRangeType())) { + return true; + } else if (RangeTypeEnum.PRODUCT_INCLUDE_PART.getValue().equals(fullPrivilege.getRangeType())) { + return fullPrivilege.getRangeValues().contains(spuId); + } else { + throw new IllegalArgumentException(String.format("促销活动(%s) 可用范围的类型是不正确", activity.toString())); + } + } + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/bo/PromotionActivityBO.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/bo/PromotionActivityBO.java new file mode 100644 index 000000000..3c5d34b1e --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/bo/PromotionActivityBO.java @@ -0,0 +1,151 @@ +package cn.iocoder.mall.promotionservice.service.activity.bo; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +@Data +@Accessors(chain = true) +public class PromotionActivityBO implements Serializable { + + /** + * 活动编号 + */ + private Integer id; + /** + * 活动标题 + */ + private String title; + /** + * 活动类型 + * + * 参见 {@link cn.iocoder.mall.promotion.api.enums.PromotionActivityTypeEnum} 枚举 + */ + private Integer activityType; + /** + * 活动状态 + * + * 参见 {@link cn.iocoder.mall.promotion.api.enums.PromotionActivityStatusEnum} 枚举 + */ + private Integer status; + /** + * 开始时间 + */ + private Date startTime; + /** + * 结束时间 + */ + private Date endTime; + /** + * 限制折扣 + */ + private TimeLimitedDiscount timeLimitedDiscount; + /** + * 满减送 + */ + private FullPrivilege fullPrivilege; + + /** + * 限时折扣 + */ + @Data + @Accessors(chain = true) + public static class TimeLimitedDiscount implements Serializable { + + /** + * 商品折扣 + */ + @Data + @Accessors(chain = true) + public static class Item implements Serializable { + + /** + * 商品 SPU 编号 + */ + private Integer spuId; + /** + * 优惠类型 + */ + private Integer preferentialType; + /** + * 优惠值 + */ + private Integer preferentialValue; + + } + + /** + * 每人每种限购多少 + * + * 当 quota = 0 时,表示不限购 + */ + private Integer quota; + /** + * 商品折扣数组 + */ + private List items; + + } + + /** + * 满减送 + */ + @Data + @Accessors(chain = true) + public static class FullPrivilege implements Serializable { + + /** + * 优惠 + */ + @Data + @Accessors(chain = true) + public static class Privilege implements Serializable { + + /** + * 满足类型 + * + * 1 - 金额 + * 2 - 件数 + */ + private Integer meetType; + /** + * 满足值 + */ + private Integer meetValue; + /** + * 优惠类型 + */ + private Integer preferentialType; + /** + * 优惠值 + */ + private Integer preferentialValue; + + } + + /** + * 可用范围的类型 + * + * 参见 {@link cn.iocoder.mall.promotion.api.enums.RangeTypeEnum} 枚举 + * 暂时只用 “所有可用” + “PRODUCT_INCLUDE_PRT” + */ + private Integer rangeType; + /** + * 指定可用商品列表 + */ + private List rangeValues; + /** + * 是否循环 + */ + private Boolean cycled; + /** + * 优惠数组 + */ + private List privileges; + + } + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/bo/PromotionActivityPageBO.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/bo/PromotionActivityPageBO.java new file mode 100644 index 000000000..bbaeac8ae --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/bo/PromotionActivityPageBO.java @@ -0,0 +1,25 @@ +package cn.iocoder.mall.promotionservice.service.activity.bo; + +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * 促销活动分页 BO + */ +@Data +@Accessors(chain = true) +public class PromotionActivityPageBO { + + /** + * PromotionActivityBO 数组 + */ + private List list; + /** + * 总量 + */ + private Integer total; + +}