fix promotion优惠券工程继续迁移,未完成,再提交下

This commit is contained in:
wuwenbin 2020-07-26 17:45:01 +08:00
parent ac5ab0b70b
commit 67f8b61f47
24 changed files with 1219 additions and 6 deletions

View File

@ -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<PromotionActivityRespDTO> getPromotionActivityListBySpuId(Integer spuId,
Collection<Integer> activityStatuses);

View File

@ -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<BannerRespDTO> getBannerListByStatus(Integer status);

View File

@ -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 {
// ========== 优惠劵模板 ==========

View File

@ -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)

View File

@ -6,7 +6,7 @@ import cn.iocoder.common.framework.validator.InEnum;
import java.util.List;
public interface ProductRecommendService {
public interface ProductRecommendRpc {
List<ProductRecommendRespDTO> getProductRecommendList(Integer type, Integer status);

View File

@ -12,10 +12,40 @@
<artifactId>promotion-service-app</artifactId>
<dependencies>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>promotion-service-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -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);
}
}

View File

@ -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 {
}

View File

@ -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 分页插件
}
}

View File

@ -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<PromotionActivityBO> convertToBO(List<PromotionActivityDO> activityList);
@Mappings({})
List<PromotionActivityDO> convertToDO(List<PromotionActivityBO> activityList);
@Mappings({})
List<PromotionActivityRespDTO> convertToRespDTO(List<PromotionActivityDO> activityList);
// @Mappings({})
// PromotionActivityDO convert(PromotionActivityAddDTO activityAddDTO);
//
// @Mappings({})
// PromotionActivityDO convert(PromotionActivityUpdateDTO activityUpdateDTO);
}

View File

@ -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<Item> 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<Integer> rangeValues;
/**
* 是否循环
*/
private Boolean cycled;
/**
* 优惠数组
*/
private List<Privilege> privileges;
}
}

View File

@ -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 芋艿 点击次数&& 其他数据相关
}

View File

@ -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 ==========
}

View File

@ -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 芋艿后续要考虑状态的追踪
}

View File

@ -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 ==========
}

View File

@ -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;
}

View File

@ -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<PromotionActivityDO> selectListByStatus(@Param("statuses") Collection<Integer> statuses);
void insert(PromotionActivityDO activity);
List<PromotionActivityDO> selectListByPage(@Param("title") String title,
@Param("activityType") Integer activityType,
@Param("statuses") Collection<Integer> statuses,
@Param("offset") Integer offset,
@Param("limit") Integer limit);
Integer selectCountByPage(@Param("title") String title,
@Param("activityType") Integer activityType,
@Param("statuses") Collection<Integer> statuses);
}

View File

@ -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<BannerDO> selectListByStatus(@Param("status") Integer status);
List<BannerDO> 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);
}

View File

@ -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<CouponCardDO> selectListByUserIdAndStatus(@Param("userId") Integer userId,
@Param("status") Integer status);
List<CouponCardDO> 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);
}

View File

@ -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<CouponTemplateDO> selectListByIds(@Param("ids") Collection<Integer> ids);
List<CouponTemplateDO> 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);
}

View File

@ -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<ProductRecommendDO> selectListByTypeAndStatus(@Param("type") Integer type,
@Param("status") Integer status);
List<ProductRecommendDO> 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);
}

View File

@ -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<PromotionActivityDO> getPromotionActivityListBySpuId(Integer spuId, Collection<Integer> activityStatuses) {
return this.getPromotionActivityListBySpuIds(Collections.singleton(spuId), activityStatuses);
}
public List<PromotionActivityDO> getPromotionActivityListBySpuIds(Collection<Integer> spuIds, Collection<Integer> activityStatuses) {
if (spuIds.isEmpty() || activityStatuses.isEmpty()) {
return Collections.emptyList();
}
// 查询指定状态的促销活动
List<PromotionActivityDO> activityList = promotionActivityMapper.selectListByStatus(activityStatuses);
if (activityList.isEmpty()) {
return Collections.emptyList();
}
// 匹配商品
for (Iterator<PromotionActivityDO> 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<Integer> 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()));
}
}
}

View File

@ -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<Item> 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<Integer> rangeValues;
/**
* 是否循环
*/
private Boolean cycled;
/**
* 优惠数组
*/
private List<Privilege> privileges;
}
}

View File

@ -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<PromotionActivityRespDTO> list;
/**
* 总量
*/
private Integer total;
}