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

pull/4/MERGE
wuwenbin 2020-07-29 22:48:41 +08:00
parent 90047c10d7
commit 495bf2ed58
27 changed files with 1631 additions and 16 deletions

View File

@ -11,9 +11,9 @@ public interface CouponRpc {
// ========== 优惠劵(码)模板 ==========
CouponTemplateBO getCouponTemplate(Integer couponTemplateId);
CouponTemplateReqDTO getCouponTemplate(Integer couponTemplateId);
CouponTemplatePageBO getCouponTemplatePage(CouponTemplatePageReqDTO couponTemplatePageDTO);
CouponTemplatePageRespDTO getCouponTemplatePage(CouponTemplatePageReqDTO couponTemplatePageDTO);
/**
*
@ -21,7 +21,7 @@ public interface CouponRpc {
* @param couponCodeTemplateAddDTO DTO
* @return
*/
CouponTemplateBO addCouponCodeTemplate(CouponCodeTemplateAddReqDTO couponCodeTemplateAddDTO);
CouponTemplateReqDTO addCouponCodeTemplate(CouponCodeTemplateAddReqDTO couponCodeTemplateAddDTO);
/**
*
@ -29,7 +29,7 @@ public interface CouponRpc {
* @param couponCardTemplateAddDTO DTO
* @return
*/
CouponTemplateBO addCouponCardTemplate(CouponCardTemplateAddReqDTO couponCardTemplateAddDTO);
CouponTemplateReqDTO addCouponCardTemplate(CouponCardTemplateAddReqDTO couponCardTemplateAddDTO);
/**
*
@ -60,7 +60,7 @@ public interface CouponRpc {
// ========== 优惠劵 ==========
CouponCardPageBO getCouponCardPage(CouponCardPageReqDTO couponCardPageDTO);
CouponCardPageRespDTO getCouponCardPage(CouponCardPageReqDTO couponCardPageDTO);
/**
*
@ -69,7 +69,7 @@ public interface CouponRpc {
* @param couponTemplateId
* @return
*/
CouponCardBO addCouponCard(Integer userId, Integer couponTemplateId);
CouponCardReqDTO addCouponCard(Integer userId, Integer couponTemplateId);
/**
* 使
@ -97,7 +97,7 @@ public interface CouponRpc {
* @param couponCardId
* @return
*/
CouponCardDetailBO getCouponCardDetail(Integer userId, Integer couponCardId);
CouponCardDetailRespDTO getCouponCardDetail(Integer userId, Integer couponCardId);
/**
*
@ -119,6 +119,6 @@ public interface CouponRpc {
* @param code
* @return
*/
CouponCardBO useCouponCode(Integer userId, String code);
CouponCardReqDTO useCouponCode(Integer userId, String code);
}

View File

@ -10,7 +10,7 @@ import lombok.experimental.Accessors;
*/
@Data
@Accessors(chain = true)
public class CouponCardAvailableRespDTO extends CouponCardBO {
public class CouponCardAvailableRespDTO extends CouponCardReqDTO {
/**
*

View File

@ -0,0 +1,143 @@
package cn.iocoder.mall.promotion.api.rpc.coupon.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* BO
*
* {@link CouponTemplateReqDTO}
*/
@Data
@Accessors(chain = true)
public class CouponCardDetailRespDTO implements Serializable {
// ========== 基本信息 BEGIN ==========
/**
*
*/
private Integer id;
/**
*
*/
private Integer templateId;
/**
*
*/
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 Boolean used;
/**
* 使
*/
private Integer usedOrderId;
/**
*
*/
private Integer usedPrice;
/**
* 使
*/
private Date usedTime;
// TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。
// ========== 使用情况 END ==========
/**
*
*/
private Date createTime;
// ========== FROM template 使用规则 BEGIN ==========
/**
*
*
* 10-ALL
* 20-PART
* 21-PART
* 30-PART
* 31-PART
*/
private Integer rangeType;
/**
* / 使
*/
private List<Integer> rangeValues;
}

View File

@ -11,12 +11,12 @@ import java.util.List;
*/
@Data
@Accessors(chain = true)
public class CouponCardPageBO implements Serializable {
public class CouponCardPageRespDTO implements Serializable {
/**
*
*/
private List<CouponCardBO> list;
private List<CouponCardReqDTO> list;
/**
*
*/

View File

@ -0,0 +1,112 @@
package cn.iocoder.mall.promotion.api.rpc.coupon.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* BO
*/
@Data
@Accessors(chain = true)
public class CouponCardReqDTO implements Serializable {
// ========== 基本信息 BEGIN ==========
/**
*
*/
private Integer id;
/**
*
*/
private Integer templateId;
/**
*
*/
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 Date usedTime;
// TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。
// ========== 使用情况 END ==========
/**
*
*/
private Date createTime;
}

View File

@ -11,12 +11,12 @@ import java.util.List;
*/
@Data
@Accessors(chain = true)
public class CouponTemplatePageBO implements Serializable {
public class CouponTemplatePageRespDTO implements Serializable {
/**
*
*/
private List<CouponTemplateBO> list;
private List<CouponTemplateReqDTO> list;
/**
*
*/

View File

@ -0,0 +1,155 @@
package cn.iocoder.mall.promotion.api.rpc.coupon.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* BO
*/
@Data
@Accessors(chain = true)
public class CouponTemplateReqDTO implements Serializable {
// ========== 基本信息 BEGIN ==========
/**
*
*/
private Integer id;
/**
*
*/
private String title;
/**
* 使
*/
private String description;
/**
*
*
* 1-
* 2-
*/
private Integer type;
/**
*
*
* 1-UNIQUE
* 2-GENERAL
*
* @see CouponCodeDO
*/
private Integer codeType;
/**
*
*
* 1-
* 2-
* 3-
*
*
*/
private Integer status;
/**
*
*
* null -
*/
private Integer quota;
/**
*
*/
private Integer total;
// ========== 领取规则 END ==========
// ========== 使用规则 BEGIN ==========
/**
*
*
* 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;
// ========== 使用规则 END ==========
// ========== 使用效果 BEGIN ==========
/**
*
*
* 1-
* 2-
*/
private Integer preferentialType;
/**
*
*
* 80% 80
* 100% 100
*/
private Integer percentOff;
/**
*
*/
private Integer priceOff;
/**
* {@link #preferentialType} 2
*
* 20 使 8 1000 20 80
*/
private Integer discountPriceLimit;
// ========== 使用效果 END ==========
// ========== 统计信息 BEGIN ==========
/**
*
*/
private Integer statFetchNum;
// ========== 统计信息 END ==========
/**
*
*/
private Date createTime;
}

View File

@ -46,6 +46,12 @@
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>product-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,41 @@
package cn.iocoder.mall.promotionservice.convert.coupon;
import cn.iocoder.mall.promotion.api.rpc.coupon.dto.CouponCardDetailRespDTO;
import cn.iocoder.mall.promotion.api.rpc.coupon.dto.CouponCardReqDTO;
import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.coupon.CouponCardDO;
import cn.iocoder.mall.promotionservice.service.coupon.bo.CouponCardAvailableBO;
import cn.iocoder.mall.promotionservice.service.coupon.bo.CouponCardBO;
import cn.iocoder.mall.promotionservice.service.coupon.bo.CouponCardDetailBO;
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<CouponCardBO> convertToBO(List<CouponCardDO> cardList);
List<CouponCardReqDTO> convertToDTO(List<CouponCardDO> cardList);
CouponCardReqDTO convertToSingleDTO(CouponCardDO card);
@Mappings({})
CouponCardBO convert(CouponCardDO card);
@Mappings({})
CouponCardDetailRespDTO convert2(CouponCardDO card);
CouponCardAvailableBO convertAvailBO(CouponCardDO card,boolean x);
//@Mappings({})
//CouponCardAvailableBO convert2(CouponCardDO card, boolean x); // TODO 芋艿,临时用来解决 mapstruct 无法正确匹配方法的问题
}

View File

@ -0,0 +1,48 @@
package cn.iocoder.mall.promotionservice.convert.coupon;
import cn.iocoder.mall.promotion.api.rpc.coupon.dto.*;
import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.coupon.CouponTemplateDO;
import cn.iocoder.mall.promotionservice.service.coupon.bo.CouponCardTemplateAddBO;
import cn.iocoder.mall.promotionservice.service.coupon.bo.CouponCardTemplateUpdateBO;
import cn.iocoder.mall.promotionservice.service.coupon.bo.CouponTemplateBO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface CouponTemplateConvert {
CouponTemplateConvert INSTANCE = Mappers.getMapper(CouponTemplateConvert.class);
// @Mappings({})
// CouponTemplateBO convertToBO(CouponTemplateDO banner);
//
@Mappings({})
List<CouponTemplateBO> convertToBO(List<CouponTemplateDO> templateList);
List<CouponTemplateReqDTO> convertToDTO(List<CouponTemplateDO> templateList);
@Mappings({})
CouponTemplateDO convert(CouponCodeTemplateUpdateReqDTO template);
@Mappings({})
CouponTemplateDO convert(CouponCardTemplateAddReqDTO template);
@Mappings({})
CouponTemplateDO convert(CouponCardTemplateUpdateReqDTO template);
@Mappings({})
CouponTemplateDO convert(CouponCodeTemplateAddReqDTO template);
@Mappings({})
CouponTemplateDO convert(CouponCardTemplateAddBO template);
@Mappings({})
CouponTemplateDO convert(CouponCardTemplateUpdateBO template);
@Mappings({})
CouponTemplateBO convert(CouponTemplateDO template);
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.mall.promotionservice.convert.recommend;
import cn.iocoder.mall.promotion.api.rpc.recommend.dto.ProductRecommendRespDTO;
import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.recommend.ProductRecommendDO;
import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendAddBO;
import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendBO;
import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendUpdateBO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductRecommendConvert {
ProductRecommendConvert INSTANCE = Mappers.getMapper(ProductRecommendConvert.class);
@Mappings({})
ProductRecommendBO convertToBO(ProductRecommendDO recommend);
@Mappings({})
List<ProductRecommendBO> convertToBO(List<ProductRecommendDO> recommendList);
@Mappings({})
List<ProductRecommendRespDTO> convertToDTO(List<ProductRecommendDO> recommendList);
@Mappings({})
ProductRecommendDO convert(ProductRecommendAddBO recommendAddDTO);
@Mappings({})
ProductRecommendDO convert(ProductRecommendUpdateBO recommendUpdateDTO);
}

View File

@ -0,0 +1,354 @@
package cn.iocoder.mall.promotionservice.service.coupon;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.util.DateUtil;
import cn.iocoder.mall.promotion.api.enums.*;
import cn.iocoder.mall.promotion.api.rpc.coupon.dto.*;
import cn.iocoder.mall.promotionservice.convert.coupon.CouponCardConvert;
import cn.iocoder.mall.promotionservice.convert.coupon.CouponTemplateConvert;
import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.coupon.CouponCardDO;
import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.coupon.CouponTemplateDO;
import cn.iocoder.mall.promotionservice.dal.mysql.mapper.coupon.CouponCardMapper;
import cn.iocoder.mall.promotionservice.dal.mysql.mapper.coupon.CouponTemplateMapper;
import cn.iocoder.mall.promotionservice.service.coupon.bo.*;
import cn.iocoder.common.framework.util.*;
import io.netty.util.internal.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import java.util.stream.Collectors;
@Service
@Validated
public class CouponService {
@Autowired
private CouponTemplateMapper couponTemplateMapper;
@Autowired
private CouponCardMapper couponCardMapper;
// ========== 优惠劵(码)模板 ==========
public cn.iocoder.mall.promotionservice.service.coupon.bo.CouponTemplateBO getCouponTemplate(Integer couponTemplateId) {
CouponTemplateDO template = couponTemplateMapper.selectById(couponTemplateId);
return CouponTemplateConvert.INSTANCE.convert(template);
}
public CouponTemplatePageRespDTO getCouponTemplatePage(CouponTemplatePageReqDTO couponTemplatePageDTO) {
CouponTemplatePageRespDTO couponTemplatePageBO = new CouponTemplatePageRespDTO();
// 查询分页数据
int offset = (couponTemplatePageDTO.getPageNo() - 1) * couponTemplatePageDTO.getPageSize();
couponTemplatePageBO.setList(CouponTemplateConvert.INSTANCE.convertToDTO(couponTemplateMapper.selectListByPage(
couponTemplatePageDTO.getType(), couponTemplatePageDTO.getTitle(),
couponTemplatePageDTO.getStatus(), couponTemplatePageDTO.getPreferentialType(),
offset, couponTemplatePageDTO.getPageSize())));
// 查询分页总数
couponTemplatePageBO.setTotal(couponTemplateMapper.selectCountByPage(
couponTemplatePageDTO.getType(), couponTemplatePageDTO.getTitle(),
couponTemplatePageDTO.getStatus(), couponTemplatePageDTO.getPreferentialType()));
return couponTemplatePageBO;
}
public cn.iocoder.mall.promotionservice.service.coupon.bo.CouponTemplateBO addCouponCardTemplate(CouponCardTemplateAddBO couponCardTemplateAddDTO) {
// 校验生效日期相关
checkCouponTemplateDateType(couponCardTemplateAddDTO.getDateType(),
couponCardTemplateAddDTO.getValidStartTime(), couponCardTemplateAddDTO.getValidEndTime(),
couponCardTemplateAddDTO.getFixedBeginTerm(), couponCardTemplateAddDTO.getFixedEndTerm());
// 校验优惠类型
Boolean checkCouponTemplateDateTypeResult = checkCouponTemplatePreferentialType(
couponCardTemplateAddDTO.getPreferentialType(), couponCardTemplateAddDTO.getPercentOff(),
couponCardTemplateAddDTO.getPriceOff(), couponCardTemplateAddDTO.getPriceAvailable());
// 保存优惠劵模板到数据库
CouponTemplateDO template = CouponTemplateConvert.INSTANCE.convert(couponCardTemplateAddDTO)
.setType(CouponTemplateTypeEnum.CARD.getValue())
.setStatus(CouponTemplateStatusEnum.ENABLE.getValue())
.setStatFetchNum(0);
template.setCreateTime(new Date());
couponTemplateMapper.insert(template);
// 返回成功
return CouponTemplateConvert.INSTANCE.convert(template);
}
public Boolean updateCouponCodeTemplate(CouponCodeTemplateUpdateBO couponCodeTemplateUpdateDTO) {
return null;
}
public Boolean updateCouponCardTemplate(CouponCardTemplateUpdateBO couponCardTemplateUpdateDTO) {
// 校验 CouponCardTemplate 存在
CouponTemplateDO template = couponTemplateMapper.selectById(couponCardTemplateUpdateDTO.getId());
if (template == null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_EXISTS.getCode());
}
// 校验 CouponCardTemplate 是 CARD
if (!CouponTemplateTypeEnum.CARD.getValue().equals(template.getType())) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_CARD.getCode());
}
// 校验发放数量不能减少
if (couponCardTemplateUpdateDTO.getTotal() < template.getTotal()) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_TOTAL_CAN_NOT_REDUCE.getCode());
}
// 更新优惠劵模板到数据库
CouponTemplateDO updateTemplateDO = CouponTemplateConvert.INSTANCE.convert(couponCardTemplateUpdateDTO);
couponTemplateMapper.update(updateTemplateDO);
// 返回成功
return true;
}
public Boolean updateCouponTemplateStatus(Integer adminId, Integer couponTemplateId, Integer status) {
// 校验 CouponCardTemplate 存在
CouponTemplateDO template = couponTemplateMapper.selectById(couponTemplateId);
if (template == null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_EXISTS.getCode());
}
// 更新到数据库
CouponTemplateDO updateTemplateDO = new CouponTemplateDO().setId(couponTemplateId).setStatus(status);
couponTemplateMapper.update(updateTemplateDO);
// 返回成功
return true;
}
private Boolean checkCouponTemplateDateType(Integer dateType, Date validStartTime, Date validEndTime, Integer fixedBeginTerm, Integer fixedEndTerm) {
/*if (CouponTemplateDateTypeEnum.FIXED_DATE.getValue().equals(dateType)) { // 固定日期
if (validStartTime == null) {
throw ServiceExceptionUtil.exception(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "生效开始时间不能为空");
}
if (validEndTime == null) {
throw ServiceExceptionUtil.exception(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "生效结束时间不能为空");
}
if (validStartTime.after(validEndTime)) {
throw ServiceExceptionUtil.exception(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "生效开始时间不能大于生效结束时间");
}
} else if (CouponTemplateDateTypeEnum.FIXED_TERM.getValue().equals(dateType)) { // 领取日期
if (fixedBeginTerm == null) {
throw ServiceExceptionUtil.exception(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "领取日期开始时间不能为空");
}
if (fixedEndTerm == null) {
throw ServiceExceptionUtil.exception(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "领取日期结束时间不能为空");
}
} else {
throw new IllegalArgumentException("未知的生效日期类型:" + dateType);
}*/
return true;
}
private Boolean checkCouponTemplatePreferentialType(Integer preferentialType, Integer percentOff,
Integer priceOff, Integer priceAvailable) {
/*if (PreferentialTypeEnum.PRICE.getValue().equals(preferentialType)) {
if (priceOff == null) {
throw ServiceExceptionUtil.exception(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "优惠金额不能为空");
}
if (priceOff >= priceAvailable) {
throw ServiceExceptionUtil.exception(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "优惠金额不能d大于等于使用金额门槛");
}
} else if (PreferentialTypeEnum.DISCOUNT.getValue().equals(preferentialType)) {
if (percentOff == null) {
throw ServiceExceptionUtil.exception(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "折扣百分比不能为空");
}
} else {
throw new IllegalArgumentException("未知的优惠类型:" + preferentialType);
}*/
return true;
}
// ========== 优惠劵 ==========
public CouponCardPageRespDTO getCouponCardPage(CouponCardPageReqDTO couponCardPageDTO) {
CouponCardPageRespDTO pageBO = new CouponCardPageRespDTO();
// 查询分页数据
int offset = (couponCardPageDTO.getPageNo() - 1) * couponCardPageDTO.getPageSize();
pageBO.setList(CouponCardConvert.INSTANCE.convertToDTO(couponCardMapper.selectListByPage(
couponCardPageDTO.getUserId(), couponCardPageDTO.getStatus(),
offset, couponCardPageDTO.getPageSize())));
// 查询分页总数
pageBO.setTotal(couponCardMapper.selectCountByPage(
couponCardPageDTO.getUserId(), couponCardPageDTO.getStatus()));
return pageBO;
}
@Transactional
public CouponCardReqDTO addCouponCard(Integer userId, Integer couponTemplateId) {
// 校验 CouponCardTemplate 存在
CouponTemplateDO template = couponTemplateMapper.selectById(couponTemplateId);
if (template == null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_EXISTS.getCode());
}
// 校验 CouponCardTemplate 是 CARD
if (!CouponTemplateTypeEnum.CARD.getValue().equals(template.getType())) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_CARD.getCode());
}
// 校验 CouponCardTemplate 状态是否开启
if (!CouponTemplateStatusEnum.ENABLE.getValue().equals(template.getStatus())) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_STATUS_NOT_ENABLE.getCode());
}
// 校验 CouponCardTemplate 是否到达可领取的上限
if (template.getStatFetchNum() > template.getTotal()) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_TOTAL_NOT_ENOUGH.getCode());
}
// 校验单人可领取优惠劵是否到达上限
if (couponCardMapper.selectCountByUserIdAndTemplateId(userId, couponTemplateId) > template.getQuota()) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_CARD_ADD_EXCEED_QUOTA.getCode());
}
// 增加优惠劵已领取量
int updateTemplateCount = couponTemplateMapper.updateStatFetchNumIncr(couponTemplateId);
if (updateTemplateCount == 0) { // 超过 CouponCardTemplate 发放量
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_CARD_ADD_EXCEED_QUOTA.getCode());
}
// 创建优惠劵
// 1. 基本信息 + 领取情况
CouponCardDO card = new CouponCardDO()
.setTemplateId(couponTemplateId)
.setTitle(template.getTitle())
.setStatus(CouponCardStatusEnum.UNUSED.getValue())
.setUserId(userId)
.setTakeType(CouponCardTakeTypeEnum.BY_USER.getValue()); // TODO 需要改
// 2. 使用规则
card.setPriceAvailable(template.getPriceAvailable());
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 CouponCardConvert.INSTANCE.convertToSingleDTO(card);
}
public Boolean useCouponCard(Integer userId, Integer couponCardId) {
// 查询优惠劵
CouponCardDO card = couponCardMapper.selectById(couponCardId);
if (card == null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_NOT_EXISTS.getCode());
}
if (!userId.equals(card.getUserId())) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_ERROR_USER.getCode());
}
if (!CouponCardStatusEnum.UNUSED.getValue().equals(card.getStatus())) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_STATUS_NOT_UNUSED.getCode());
}
if (DateUtil.isBetween(card.getValidStartTime(), card.getValidEndTime())) { // 为避免定时器没跑,实际优惠劵已经过期
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_STATUS_NOT_UNUSED.getCode());
}
// 更新优惠劵已使用
int updateCount = couponCardMapper.updateByIdAndStatus(card.getId(), CouponCardStatusEnum.UNUSED.getValue(),
new CouponCardDO().setStatus(CouponCardStatusEnum.USED.getValue()).setUsedTime(new Date()));
if (updateCount == 0) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_STATUS_NOT_UNUSED.getCode());
}
return true;
}
public Boolean cancelUseCouponCard(Integer userId, Integer couponCardId) {
// 查询优惠劵
CouponCardDO card = couponCardMapper.selectById(couponCardId);
if (card == null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_NOT_EXISTS.getCode());
}
if (!userId.equals(card.getUserId())) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_ERROR_USER.getCode());
}
if (!CouponCardStatusEnum.USED.getValue().equals(card.getStatus())) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_STATUS_NOT_USED.getCode());
}
// 更新优惠劵已使用
int updateCount = couponCardMapper.updateByIdAndStatus(card.getId(), CouponCardStatusEnum.USED.getValue(),
new CouponCardDO().setStatus(CouponCardStatusEnum.UNUSED.getValue())); // TODO 芋艿usedTime 未设置空,后面处理。
if (updateCount == 0) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_STATUS_NOT_USED.getCode());
}
// 有一点要注意,更新会未使用时,优惠劵可能已经过期了,直接让定时器跑过期,这里不做处理。
return true;
}
public CouponCardDetailRespDTO getCouponCardDetail(Integer userId, Integer couponCardId) {
// 查询优惠劵
CouponCardDO card = couponCardMapper.selectById(couponCardId);
if (card == null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_NOT_EXISTS.getCode());
}
if (!userId.equals(card.getUserId())) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_ERROR_USER.getCode());
}
// 查询优惠劵模板
CouponTemplateDO template = couponTemplateMapper.selectById(card.getTemplateId());
if (template == null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_EXISTS.getCode());
}
// 拼接结果
CouponCardDetailRespDTO detail = CouponCardConvert.INSTANCE.convert2(card);
detail.setRangeType(template.getRangeType());
detail.setRangeValues(StringUtils.splitToInt(template.getRangeValues(), ","));
return detail;
}
public List<CouponCardAvailableBO> getCouponCardList(Integer userId, List<CouponCardSpuBO> spus) {
// 查询用户未使用的优惠劵列表
List<CouponCardDO> cards = couponCardMapper.selectListByUserIdAndStatus(userId, CouponCardStatusEnum.UNUSED.getValue());
if (cards.isEmpty()) {
return Collections.emptyList();
}
// 查询优惠劵模板集合
Map<Integer, CouponTemplateDO> templates = couponTemplateMapper.selectListByIds(cards.stream().map(CouponCardDO::getTemplateId).collect(Collectors.toSet()))
.stream().collect(Collectors.toMap(CouponTemplateDO::getId, template -> template));
// 逐个判断是否可用
List<CouponCardAvailableBO> availableCards = cards.stream().map(card -> {
CouponCardAvailableBO availableCard = CouponCardConvert.INSTANCE.convertAvailBO(card, true);
availableCard.setUnavailableReason(isMatch(card, templates.get(card.getTemplateId()), spus));
availableCard.setAvailable(availableCard.getUnavailableReason() == null);
return availableCard;
}).collect(Collectors.toList());
// 返回结果
return availableCards;
}
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));
}
}
// 如果匹配,则返回 null 即可。
private String isMatch(CouponCardDO card, CouponTemplateDO template, List<CouponCardSpuBO> spus) {
int totalPrice = 0;
if (RangeTypeEnum.ALL.getValue().equals(template.getRangeType())) {
totalPrice = spus.stream().mapToInt(spu -> spu.getPrice() * spu.getQuantity()).sum();
} else if (RangeTypeEnum.PRODUCT_INCLUDE_PART.getValue().equals(template.getRangeType())) {
List<Integer> spuIds = StringUtils.splitToInt(template.getRangeValues(), ",");
totalPrice = spus.stream().mapToInt(spu -> spuIds.contains(spu.getSpuId()) ? spu.getPrice() * spu.getQuantity() : 0).sum();
} else if (RangeTypeEnum.PRODUCT_EXCLUDE_PART.getValue().equals(template.getRangeType())) {
List<Integer> spuIds = StringUtils.splitToInt(template.getRangeValues(), ",");
totalPrice = spus.stream().mapToInt(spu -> !spuIds.contains(spu.getSpuId()) ? spu.getPrice() * spu.getQuantity() : 0).sum();
} else if (RangeTypeEnum.CATEGORY_INCLUDE_PART.getValue().equals(template.getRangeType())) {
List<Integer> spuIds = StringUtils.splitToInt(template.getRangeValues(), ",");
totalPrice = spus.stream().mapToInt(spu -> spuIds.contains(spu.getCategoryId()) ? spu.getPrice() * spu.getQuantity() : 0).sum();
} else if (RangeTypeEnum.CATEGORY_EXCLUDE_PART.getValue().equals(template.getRangeType())) {
List<Integer> spuIds = StringUtils.splitToInt(template.getRangeValues(), ",");
totalPrice = spus.stream().mapToInt(spu -> !spuIds.contains(spu.getCategoryId()) ? spu.getPrice() * spu.getQuantity() : 0).sum();
}
// 总价为 0 时,说明优惠劵丫根不匹配
if (totalPrice == 0) {
return "优惠劵不匹配";
}
// 如果不满足金额
if (totalPrice < card.getPriceAvailable()) {
return String.format("差 %1$,.2f 元可用优惠劵", (card.getPriceAvailable() - totalPrice) / 100D);
}
return null;
}
// ========== 优惠码 ==========
public CouponCardReqDTO useCouponCode(Integer userId, String code) {
return null;
}
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.mall.promotionservice.service.coupon.bo;
import cn.iocoder.mall.promotion.api.rpc.coupon.dto.CouponCardReqDTO;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* BO
*
* available = false unavailableReason
*/
@Data
@Accessors(chain = true)
public class CouponCardAvailableBO extends CouponCardReqDTO {
/**
*
*/
private Boolean available;
/**
*
*/
private String unavailableReason;
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.promotion.api.rpc.coupon.dto;
package cn.iocoder.mall.promotionservice.service.coupon.bo;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.promotion.api.rpc.coupon.dto;
package cn.iocoder.mall.promotionservice.service.coupon.bo;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -0,0 +1,26 @@
package cn.iocoder.mall.promotionservice.service.coupon.bo;
import cn.iocoder.mall.promotion.api.rpc.coupon.dto.CouponCardReqDTO;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* BO
*/
@Data
@Accessors(chain = true)
public class CouponCardPageBO implements Serializable {
/**
*
*/
private List<CouponCardReqDTO> list;
/**
*
*/
private Integer total;
}

View File

@ -0,0 +1,40 @@
package cn.iocoder.mall.promotionservice.service.coupon.bo;
import cn.iocoder.mall.promotion.api.rpc.coupon.CouponRpc;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* DTO
*
* {@link CouponRpc#getCouponCardList(Integer, List)}
*/
@Data
@Accessors(chain = true)
public class CouponCardSpuBO implements Serializable {
/**
* SPU
*/
private Integer spuId;
/**
* SKU
*/
private Integer skuId;
/**
*
*/
private Integer categoryId;
/**
*
*/
private Integer price;
/**
*
*/
private Integer quantity;
}

View File

@ -0,0 +1,140 @@
package cn.iocoder.mall.promotionservice.service.coupon.bo;
import cn.iocoder.common.framework.validator.InEnum;
import cn.iocoder.mall.promotion.api.enums.CouponTemplateDateTypeEnum;
import cn.iocoder.mall.promotion.api.enums.PreferentialTypeEnum;
import cn.iocoder.mall.promotion.api.enums.RangeTypeEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
/**
* DTO
*/
@Data
@Accessors(chain = true)
public class CouponCardTemplateAddBO implements Serializable {
// ========== 基本信息 BEGIN ==========
/**
*
*/
@NotEmpty(message = "标题不能为空")
private String title;
/**
* 使
*/
private String description;
// ========== 基本信息 END ==========
// ========== 领取规则 BEGIN ==========
/**
*
*/
@NotNull(message = "每人限领个数不能为空")
@Min(value = 1, message = "每人限领个数最小为 {value}")
private Integer quota;
/**
*
*/
@NotNull(message = "发放总量不能为空")
@Min(value = 1, message = "每人限领个数最小为 {value}")
private Integer total;
// ========== 领取规则 END ==========
// ========== 使用规则 BEGIN ==========
/**
*
*
* 0-
* 0-
*/
@NotNull(message = "使用金额门槛不能为空")
@Min(value = 0L, message = "使用金额门槛最低为 {value}")
private Integer priceAvailable;
/**
*
*
* 10-ALL
* 20-PART
* 21-PART
* 30-PART
* 31-PART
*/
@NotNull(message = "可用范围的类型不能为空")
@InEnum(value = RangeTypeEnum.class, message = "可用范围的类型必须在 {value}")
private Integer rangeType;
/**
* / 使
*/
private String rangeValues;
/**
*
*
* 1-
* 2- {@link #fixedEndTerm} N
*/
@NotNull(message = "生效日期类型不能为空")
@InEnum(value = CouponTemplateDateTypeEnum.class, message = "生效日期类型必须在 {value}")
private Integer dateType;
/**
* -
*/
private Date validStartTime;
/**
* -
*/
private Date validEndTime;
/**
* -
*
* 0-1-
*/
@Min(value = 0L, message = "领取日期开始时间最小为 {value}")
private Integer fixedBeginTerm;
/**
* -
*/
@Min(value = 1L, message = "领取日期结束时间最小为 {value}")
private Integer fixedEndTerm;
// ========== 使用规则 END ==========
// ========== 使用效果 BEGIN ==========
/**
*
*
* 1-
* 2-
*/
@NotNull(message = "优惠类型不能为空")
@InEnum(value = PreferentialTypeEnum.class, message = "优惠类型必须在 {value}")
private Integer preferentialType;
/**
*
*/
@Min(value = 1, message = "优惠金额最小值为 {value}")
private Integer priceOff;
/**
*
*
* 80% 80
* 100% 100
*/
@Max(value = 100, message = "折扣比最大值为 {value}")
private Integer percentOff;
/**
* {@link #preferentialType} 2
*
* 20 使 8 1000 20 80
*/
@Min(value = 1, message = "折扣上限最小值为 {value}")
private Integer discountPriceLimit;
// ========== 使用效果 END ==========
}

View File

@ -0,0 +1,201 @@
package cn.iocoder.mall.promotionservice.service.coupon.bo;
import cn.iocoder.common.framework.validator.InEnum;
import cn.iocoder.mall.promotion.api.enums.RangeTypeEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* DTO
*/
@Data
@Accessors(chain = true)
public class CouponCardTemplateUpdateBO implements Serializable {
@NotNull(message = "编号不能为空")
private Integer id;
// ========== 基本信息 BEGIN ==========
/**
*
*/
@NotEmpty(message = "标题不能为空")
private String title;
/**
* 使
*/
private String description;
// ========== 基本信息 END ==========
// ========== 领取规则 BEGIN ==========
/**
*
*/
@NotNull(message = "每人限领个数不能为空")
@Min(value = 1, message = "每人限领个数最小为 {value}")
private Integer quota;
/**
*
*/
@NotNull(message = "发放总量不能为空")
@Min(value = 1, message = "每人限领个数最小为 {value}")
private Integer total;
// ========== 领取规则 END ==========
// ========== 使用规则 BEGIN ==========
// /**
// * 是否设置满多少金额可用,单位:分
// *
// * 0-不限制
// * 大于0-多少金额可用
// */
// @NotNull(message = "使用金额门槛不能为空")
// @Min(value = 0L, message = "使用金额门槛最低为 {value}")
// private Integer priceAvailable;
/**
*
*
* 10-ALL
* 20-PART
* 21-PART
* 30-PART
* 31-PART
*/
@NotNull(message = "可用范围的类型不能为空")
@InEnum(value = RangeTypeEnum.class, message = "可用范围的类型必须在 {value}")
private Integer rangeType;
/**
* / 使
*/
private String rangeValues;
// /**
// * 生效日期类型
// *
// * 1-固定日期
// * 2-领取日期:领到券 {@link #fixedEndTerm} 日开始 N 天内有效
// */
// @NotNull(message = "生效日期类型不能为空")
// @InEnum(value = CouponTemplateDateTypeEnum.class, message = "生效日期类型必须在 {value}")
// private Integer dateType;
// /**
// * 固定日期-生效开始时间
// */
// private Date validStartTime;
// /**
// * 固定日期-生效结束时间
// */
// private Date validEndTime;
// /**
// * 领取日期-开始天数
// *
// * 例如0-当天1-次天
// */
// @Min(value = 0L, message = "领取日期开始时间最小为 {value}")
// private Integer fixedBeginTerm;
// /**
// * 领取日期-结束天数
// */
// @Min(value = 1L, message = "领取日期结束时间最小为 {value}")
// private Integer fixedEndTerm;
// ========== 使用规则 END ==========
// ========== 使用效果 BEGIN ==========
// /**
// * 优惠类型
// *
// * 1-代金卷
// * 2-折扣卷
// */
// @NotNull(message = "优惠类型不能为空")
// @InEnum(value = CouponTemplatePreferentialTypeEnum.class, message = "优惠类型必须在 {value}")
// private Integer preferentialType;
// /**
// * 优惠金额,单位:分
// */
// @Min(value = 1, message = "优惠金额最小值为 {value}")
// private Integer priceOff;
// /**
// * 折扣百分比。
// *
// * 例如80% 为 80。
// * 当 100% 为 100 ,则代表免费。
// */
// @Max(value = 100, message = "折扣比最大值为 {value}")
// private Integer percentOff;
// /**
// * 折扣上限,仅在 {@link #preferentialType} 等于 2 时生效。
// *
// * 例如,折扣上限为 20 元,当使用 8 折优惠券,订单金额为 1000 元时,最高只可折扣 20 元,而非 80 元。
// */
// @Min(value = 1, message = "折扣上限最小值为 {value}")
// private Integer discountPriceLimit;
// ========== 使用效果 END ==========
public Integer getId() {
return id;
}
public CouponCardTemplateUpdateBO setId(Integer id) {
this.id = id;
return this;
}
public String getTitle() {
return title;
}
public CouponCardTemplateUpdateBO setTitle(String title) {
this.title = title;
return this;
}
public String getDescription() {
return description;
}
public CouponCardTemplateUpdateBO setDescription(String description) {
this.description = description;
return this;
}
public Integer getQuota() {
return quota;
}
public CouponCardTemplateUpdateBO setQuota(Integer quota) {
this.quota = quota;
return this;
}
public Integer getTotal() {
return total;
}
public CouponCardTemplateUpdateBO setTotal(Integer total) {
this.total = total;
return this;
}
public Integer getRangeType() {
return rangeType;
}
public CouponCardTemplateUpdateBO setRangeType(Integer rangeType) {
this.rangeType = rangeType;
return this;
}
public String getRangeValues() {
return rangeValues;
}
public CouponCardTemplateUpdateBO setRangeValues(String rangeValues) {
this.rangeValues = rangeValues;
return this;
}
}

View File

@ -0,0 +1,14 @@
package cn.iocoder.mall.promotionservice.service.coupon.bo;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* DTO
*/
@Data
@Accessors(chain = true)
public class CouponCodeTemplateUpdateBO implements Serializable {
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.mall.promotion.api.rpc.coupon.dto;
package cn.iocoder.mall.promotionservice.service.coupon.bo;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@ -0,0 +1,26 @@
package cn.iocoder.mall.promotionservice.service.coupon.bo;
import cn.iocoder.mall.promotion.api.rpc.coupon.dto.CouponTemplateReqDTO;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* BO
*/
@Data
@Accessors(chain = true)
public class CouponTemplatePageBO implements Serializable {
/**
*
*/
private List<CouponTemplateReqDTO> list;
/**
*
*/
private Integer total;
}

View File

@ -0,0 +1,114 @@
package cn.iocoder.mall.promotionservice.service.recommend;
import cn.iocoder.common.framework.enums.CommonStatusEnum;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
import cn.iocoder.mall.mybatis.core.enums.DeletedStatusEnum;
import cn.iocoder.mall.productservice.rpc.spu.ProductSpuRpc;
import cn.iocoder.mall.promotion.api.enums.PromotionErrorCodeEnum;
import cn.iocoder.mall.promotion.api.rpc.recommend.dto.ProductRecommendPageReqDTO;
import cn.iocoder.mall.promotion.api.rpc.recommend.dto.ProductRecommendPageRespDTO;
import cn.iocoder.mall.promotionservice.convert.recommend.ProductRecommendConvert;
import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.recommend.ProductRecommendDO;
import cn.iocoder.mall.promotionservice.dal.mysql.mapper.recommend.ProductRecommendMapper;
import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendAddBO;
import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendBO;
import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendPageBO;
import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendUpdateBO;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.util.Date;
import java.util.List;
@Service
@Validated
public class ProductRecommendService {
@Reference(validation = "true", version = "${dubbo.consumer.ProductSpuService.version}")
private ProductSpuRpc productSpuRpc;
@Autowired
private ProductRecommendMapper productRecommendMapper;
public List<ProductRecommendBO> getProductRecommendList(Integer type, Integer status) {
List<ProductRecommendDO> productRecommends = productRecommendMapper.selectListByTypeAndStatus(type, status);
return ProductRecommendConvert.INSTANCE.convertToBO(productRecommends);
}
public ProductRecommendPageRespDTO getProductRecommendPage(ProductRecommendPageReqDTO productRecommendPageDTO) {
ProductRecommendPageRespDTO productRecommendPageBO = new ProductRecommendPageRespDTO();
// 查询分页数据
int offset = (productRecommendPageDTO.getPageNo() - 1) * productRecommendPageDTO.getPageSize();
productRecommendPageBO.setList(ProductRecommendConvert.INSTANCE.convertToDTO(productRecommendMapper.selectPageByType(productRecommendPageDTO.getType(),
offset, productRecommendPageDTO.getPageSize())));
// 查询分页总数
productRecommendPageBO.setTotal(productRecommendMapper.selectCountByType(productRecommendPageDTO.getType()));
return productRecommendPageBO;
}
public ProductRecommendBO addProductRecommend(Integer adminId, ProductRecommendAddBO productRecommendAddDTO) {
// 校验商品不存在
if (productSpuRpc.getProductSpu(productRecommendAddDTO.getProductSpuId()) == null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS.getCode());
}
// 校验商品是否已经推荐
if (productRecommendMapper.selectByProductSpuIdAndType(productRecommendAddDTO.getProductSpuId(), productRecommendAddDTO.getType()) != null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_EXISTS.getCode());
}
// 保存到数据库
ProductRecommendDO productRecommend = ProductRecommendConvert.INSTANCE.convert(productRecommendAddDTO).setStatus(CommonStatusEnum.ENABLE.getValue());
productRecommend.setDeleted(DeletedStatusEnum.DELETED_NO.getValue()).setCreateTime(new Date());
productRecommendMapper.insert(productRecommend);
// 返回成功
return ProductRecommendConvert.INSTANCE.convertToBO(productRecommend);
}
public Boolean updateProductRecommend(Integer adminId, ProductRecommendUpdateBO productRecommendUpdateDTO) {
// 校验更新的商品推荐存在
if (productRecommendMapper.selectById(productRecommendUpdateDTO.getId()) == null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_NOT_EXISTS.getCode());
}
// 校验商品不存在
if (productSpuRpc.getProductSpu(productRecommendUpdateDTO.getProductSpuId()) == null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS.getCode());
}
// 校验商品是否已经推荐
ProductRecommendDO existProductRecommend = productRecommendMapper.selectByProductSpuIdAndType(productRecommendUpdateDTO.getProductSpuId(), productRecommendUpdateDTO.getType());
if (existProductRecommend != null && !existProductRecommend.getId().equals(productRecommendUpdateDTO.getId())) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_EXISTS.getCode());
}
// 更新到数据库
ProductRecommendDO updateProductRecommend = ProductRecommendConvert.INSTANCE.convert(productRecommendUpdateDTO);
productRecommendMapper.update(updateProductRecommend);
// 返回成功
return true;
}
public Boolean updateProductRecommendStatus(Integer adminId, Integer productRecommendId, Integer status) {
// 校验更新的商品推荐存在
if (productRecommendMapper.selectById(productRecommendId) == null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_NOT_EXISTS.getCode());
}
// 更新到数据库
ProductRecommendDO updateProductRecommend = new ProductRecommendDO().setId(productRecommendId).setStatus(status);
productRecommendMapper.update(updateProductRecommend);
// 返回成功
return true;
}
public Boolean deleteProductRecommend(Integer adminId, Integer productRecommendId) {
// 校验更新的商品推荐存在
if (productRecommendMapper.selectById(productRecommendId) == null) {
throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_NOT_EXISTS.getCode());
}
// 更新到数据库
ProductRecommendDO updateProductRecommend = new ProductRecommendDO().setId(productRecommendId);
updateProductRecommend.setDeleted(DeletedStatusEnum.DELETED_YES.getValue());
productRecommendMapper.update(updateProductRecommend);
// 返回成功
return true;
}
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.mall.promotionservice.service.recommend.bo;
import cn.iocoder.common.framework.validator.InEnum;
import cn.iocoder.mall.promotion.api.enums.ProductRecommendTypeEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* DTO
*/
@Data
@Accessors(chain = true)
public class ProductRecommendAddBO implements Serializable {
@InEnum(value = ProductRecommendTypeEnum.class, message = "修改推荐类型必须是 {value}")
@NotNull(message = "推荐类型不能为空")
private Integer type;
@NotNull(message = "商品编号不能为空")
private Integer productSpuId;
@NotNull(message = "排序不能为空")
private Integer sort;
@Length(max = 255, message = "备注最大长度为 255 位")
private String memo;
}

View File

@ -0,0 +1,50 @@
package cn.iocoder.mall.promotionservice.service.recommend.bo;
import cn.iocoder.mall.promotion.api.enums.ProductRecommendTypeEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* BO
*/
@Data
@Accessors(chain = true)
public class ProductRecommendBO implements Serializable {
/**
*
*/
private Integer id;
/**
*
*
* {@link ProductRecommendTypeEnum}
*/
private Integer type;
/**
* Spu
*/
private Integer productSpuId;
/**
*
*/
private Integer sort;
/**
*
*
* {@link cn.iocoder.common.framework.enums.CommonStatusEnum}
*/
private Integer status;
/**
*
*/
private String memo;
/**
*
*/
private Date createTime;
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.mall.promotionservice.service.recommend.bo;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* DTO
*/
@Data
@Accessors(chain = true)
public class ProductRecommendPageBO implements Serializable {
/**
*
*/
private Integer type;
@NotNull(message = "页码不能为空")
private Integer pageNo;
@NotNull(message = "每页条数不能为空")
private Integer pageSize;
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.mall.promotionservice.service.recommend.bo;
import cn.iocoder.common.framework.validator.InEnum;
import cn.iocoder.mall.promotion.api.enums.ProductRecommendTypeEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* DTO
*/
@Data
@Accessors(chain = true)
public class ProductRecommendUpdateBO implements Serializable {
@NotNull(message = "编号不能为空")
private Integer id;
@NotNull(message = "类型不能为空")
@InEnum(value = ProductRecommendTypeEnum.class, message = "修改推荐类型必须是 {value}")
private Integer type;
@NotNull(message = "商品编号不能为空")
private Integer productSpuId;
@NotNull(message = "排序不能为空")
private Integer sort;
@Length(max = 255, message = "备注最大长度为 255 位")
private String memo;
}