Merge branch 'feature/1.8.0-uniapp' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/1.8.0-uniapp
This commit is contained in:
commit
fb45f22533
|
@ -1,14 +1,57 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.sku;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO;
|
||||
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
|
||||
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Api(tags = "管理后台 - 商品 sku")
|
||||
@RestController
|
||||
@RequestMapping("/product/sku")
|
||||
@Validated
|
||||
public class ProductSkuController {
|
||||
|
||||
@Resource
|
||||
private ProductSkuService productSkuService;
|
||||
@Resource
|
||||
private ProductSpuService productSpuService;
|
||||
|
||||
@GetMapping("/get-option-list")
|
||||
@ApiOperation("获得商品 SKU 选项的列表")
|
||||
// @PreAuthorize("@ss.hasPermission('product:sku:query')")
|
||||
public CommonResult<List<ProductSkuOptionRespVO>> getSkuOptionList() {
|
||||
// 获得 SKU 列表
|
||||
List<ProductSkuDO> skus = productSkuService.getSkuList();
|
||||
if (CollUtil.isEmpty(skus)) {
|
||||
return success(Collections.emptyList());
|
||||
}
|
||||
|
||||
// 获得对应的 SPU 映射
|
||||
Map<Long, ProductSpuDO> spuMap = productSpuService.getSpuMap(convertSet(skus, ProductSkuDO::getSpuId));
|
||||
// 转换为返回结果
|
||||
List<ProductSkuOptionRespVO> skuVOs = ProductSkuConvert.INSTANCE.convertList05(skus);
|
||||
skuVOs.forEach(sku -> MapUtils.findAndThen(spuMap, sku.getSpuId(),
|
||||
spu -> sku.setSpuId(spu.getId()).setSpuName(spu.getName())));
|
||||
return success(skuVOs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@ApiModel(value = "管理后台 - 商品 SKU 选项 Response VO", description = "用于前端 SELECT 选项")
|
||||
@Data
|
||||
public class ProductSkuOptionRespVO {
|
||||
|
||||
@ApiModelProperty(value = "主键", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "商品 SKU 名字", example = "红色")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "销售价格", required = true, example = "100", notes = "单位:分")
|
||||
private String price;
|
||||
|
||||
@ApiModelProperty(value = "库存", required = true, example = "100")
|
||||
private Integer stock;
|
||||
|
||||
// ========== 商品 SPU 信息 ==========
|
||||
|
||||
@ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1")
|
||||
private Long spuId;
|
||||
|
||||
@ApiModelProperty(value = "商品 SPU 名字", required = true, example = "iPhone 11")
|
||||
private String spuName;
|
||||
|
||||
}
|
|
@ -9,7 +9,7 @@ import lombok.ToString;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel("管理后台 - 商品sku Response VO")
|
||||
@ApiModel("管理后台 - 商品 SKU Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
|
|
|
@ -53,6 +53,7 @@ public class ProductSpuController {
|
|||
return success(true);
|
||||
}
|
||||
|
||||
// TODO 芋艿:修改接口
|
||||
@GetMapping("/get/detail")
|
||||
@ApiOperation("获得商品 SPU")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
|
@ -79,6 +80,14 @@ public class ProductSpuController {
|
|||
return success(ProductSpuConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
@GetMapping("/get-simple-list")
|
||||
@ApiOperation("获得商品 SPU 精简列表")
|
||||
@PreAuthorize("@ss.hasPermission('product:spu:query')")
|
||||
public CommonResult<List<ProductSpuSimpleRespVO>> getSpuSimpleList() {
|
||||
List<ProductSpuDO> list = spuService.getSpuList();
|
||||
return success(ProductSpuConvert.INSTANCE.convertList02(list));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得商品 SPU 分页")
|
||||
@PreAuthorize("@ss.hasPermission('product:spu:query')")
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@ApiModel("管理后台 - 商品 SPU 精简 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ProductSpuSimpleRespVO extends ProductSpuBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "主键", required = true, example = "1")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "商品名称", required = true, example = "芋道")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024")
|
||||
private Integer minPrice;
|
||||
|
||||
@ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024")
|
||||
private Integer maxPrice;
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.convert.sku;
|
|||
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
|
@ -11,7 +12,7 @@ import org.mapstruct.factory.Mappers;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品sku Convert
|
||||
* 商品 SKU Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
|
@ -36,4 +37,6 @@ public interface ProductSkuConvert {
|
|||
|
||||
List<ProductSkuRespDTO> convertList04(List<ProductSkuDO> list);
|
||||
|
||||
List<ProductSkuOptionRespVO> convertList05(List<ProductSkuDO> skus);
|
||||
|
||||
}
|
||||
|
|
|
@ -36,5 +36,7 @@ public interface ProductSpuConvert {
|
|||
AppSpuPageRespVO convertAppResp(ProductSpuDO list);
|
||||
|
||||
List<SpuInfoRespDTO> convertList2(List<ProductSpuDO> list);
|
||||
|
||||
|
||||
List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list);
|
||||
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ public class ProductSkuDO extends BaseDO {
|
|||
* 商品属性
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class Property {
|
||||
|
||||
|
@ -130,19 +131,5 @@ public class ProductSkuDO extends BaseDO {
|
|||
|
||||
}
|
||||
|
||||
// TODO ========== 待定字段:yv =========
|
||||
// TODO brokerage:一级返佣
|
||||
// TODO brokerage_two:二级返佣
|
||||
// TODO pink_price:拼团价
|
||||
// TODO pink_stock:拼团库存
|
||||
// TODO seckill_price:秒杀价
|
||||
// TODO seckill_stock:秒杀库存
|
||||
// TODO integral:需要积分
|
||||
|
||||
// TODO ========== 待定字段:cf =========
|
||||
// TODO type 活动显示排序 0=默认 1=秒 2=砍价 3=拼团
|
||||
// TODO quota 活动限购数量
|
||||
// TODO quota_show 活动限购数量显示
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -14,22 +14,29 @@ import java.util.List;
|
|||
public interface ProductSkuService {
|
||||
|
||||
/**
|
||||
* 删除商品sku
|
||||
* 删除商品 SKU
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteSku(Long id);
|
||||
|
||||
/**
|
||||
* 获得商品sku
|
||||
* 获得商品 SKU 信息
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 商品sku
|
||||
* @return 商品 SKU 信息
|
||||
*/
|
||||
ProductSkuDO getSku(Long id);
|
||||
|
||||
/**
|
||||
* 获得商品sku列表
|
||||
* 获得商品 SKU 列表
|
||||
*
|
||||
* @return 商品sku列表
|
||||
*/
|
||||
List<ProductSkuDO> getSkuList();
|
||||
|
||||
/**
|
||||
* 获得商品 SKU 列表
|
||||
*
|
||||
* @param ids 编号
|
||||
* @return 商品sku列表
|
||||
|
|
|
@ -61,6 +61,11 @@ public class ProductSkuServiceImpl implements ProductSkuService {
|
|||
return productSkuMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductSkuDO> getSkuList() {
|
||||
return productSkuMapper.selectList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductSkuDO> getSkuList(Collection<Long> ids) {
|
||||
return productSkuMapper.selectBatchIds(ids);
|
||||
|
|
|
@ -9,6 +9,9 @@ import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
|||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
|
||||
/**
|
||||
* 商品 SPU Service 接口
|
||||
|
@ -63,6 +66,23 @@ public interface ProductSpuService {
|
|||
*/
|
||||
List<ProductSpuDO> getSpuList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得商品 SPU 映射
|
||||
*
|
||||
* @param ids 编号数组
|
||||
* @return 商品 SPU 映射
|
||||
*/
|
||||
default Map<Long, ProductSpuDO> getSpuMap(Collection<Long> ids) {
|
||||
return convertMap(getSpuList(ids), ProductSpuDO::getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得所有商品 SPU 列表
|
||||
*
|
||||
* @return 商品 SPU 列表
|
||||
*/
|
||||
List<ProductSpuDO> getSpuList();
|
||||
|
||||
/**
|
||||
* 获得商品 SPU 分页
|
||||
*
|
||||
|
|
|
@ -176,6 +176,11 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||
return productSpuMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductSpuDO> getSpuList() {
|
||||
return productSpuMapper.selectList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) {
|
||||
// 库存告警的 SPU 编号的集合
|
||||
|
|
|
@ -48,9 +48,17 @@ public class PriceCalculateRespDTO {
|
|||
* 商品原价(总),单位:分
|
||||
*
|
||||
* 基于 {@link OrderItem#getOriginalPrice()} 求和
|
||||
*
|
||||
* 对应 taobao 的 trade.total_fee 字段
|
||||
*/
|
||||
private Integer originalPrice;
|
||||
/**
|
||||
* 订单原价(总),单位:分
|
||||
*
|
||||
* 基于 {@link OrderItem#getPayPrice()} 求和
|
||||
* 和 {@link #originalPrice} 的差异:去除商品级优惠
|
||||
*/
|
||||
private Integer orderPrice;
|
||||
/**
|
||||
* 订单优惠(总),单位:分
|
||||
*
|
||||
|
@ -82,6 +90,7 @@ public class PriceCalculateRespDTO {
|
|||
* - {@link #couponPrice}
|
||||
* - {@link #pointPrice}
|
||||
* + {@link #deliveryPrice}
|
||||
* - {@link #discountPrice}
|
||||
*/
|
||||
private Integer payPrice;
|
||||
/**
|
||||
|
|
|
@ -3,14 +3,19 @@ package cn.iocoder.yudao.module.promotion.enums;
|
|||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
|
||||
/**
|
||||
* market 错误码枚举类
|
||||
* <p>
|
||||
* promotion 错误码枚举类
|
||||
*
|
||||
* market 系统,使用 1-003-000-000 段
|
||||
*/
|
||||
public interface ErrorCodeConstants {
|
||||
|
||||
// ========== 促销活动相关 1003001000 ============ TODO 芋艿:看看是不是要删除掉
|
||||
ErrorCode ACTIVITY_NOT_EXISTS = new ErrorCode(1003001000, "促销活动不存在");
|
||||
// ========== 促销活动相关 1003001000 ============
|
||||
ErrorCode DISCOUNT_ACTIVITY_NOT_EXISTS = new ErrorCode(1003001000, "限时折扣活动不存在");
|
||||
ErrorCode DISCOUNT_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003006001, "存在商品参加了其它限时折扣活动");
|
||||
ErrorCode DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "限时折扣活动已关闭,不能修改");
|
||||
ErrorCode DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "限时折扣活动未关闭,不能删除");
|
||||
ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "限时折扣活动已关闭,不能重复关闭");
|
||||
ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "限时折扣活动已结束,不能关闭");
|
||||
|
||||
// ========== Banner 相关 1003002000 ============
|
||||
ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1003002000, "Banner 不存在");
|
||||
|
@ -23,4 +28,19 @@ public interface ErrorCodeConstants {
|
|||
ErrorCode COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1003004000, "优惠劵模板不存在");
|
||||
ErrorCode COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL = new ErrorCode(1003004001, "发放数量不能小于已领取数量({})");
|
||||
|
||||
// ========== 优惠劵模板 1003005000 ==========
|
||||
ErrorCode COUPON_NOT_EXISTS = new ErrorCode(1003005000, "优惠劵不存在");
|
||||
ErrorCode COUPON_DELETE_FAIL_USED = new ErrorCode(1003005001, "回收优惠劵失败,优惠劵已被使用");
|
||||
|
||||
// ========== 满减送活动 1003006000 ==========
|
||||
ErrorCode REWARD_ACTIVITY_NOT_EXISTS = new ErrorCode(1003006000, "满减送活动不存在");
|
||||
ErrorCode REWARD_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003006001, "存在商品参加了其它满减送活动");
|
||||
ErrorCode REWARD_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "满减送活动已关闭,不能修改");
|
||||
ErrorCode REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "满减送活动未关闭,不能删除");
|
||||
ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "满减送活动已关闭,不能重复关闭");
|
||||
ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "满减送活动已结束,不能关闭");
|
||||
|
||||
// ========== Price 相关 1003007000 ============
|
||||
ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1003007000, "支付价格计算异常,原因:价格小于等于 0");
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package cn.iocoder.yudao.module.promotion.enums.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 优惠劵状态枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum CouponStatusEnum implements IntArrayValuable {
|
||||
|
||||
UNUSED(1, "未使用"),
|
||||
USED(2, "已使用"),
|
||||
EXPIRE(3, "已过期"),
|
||||
;
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponStatusEnum::getStatus).toArray();
|
||||
|
||||
/**
|
||||
* 值
|
||||
*/
|
||||
private final Integer status;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package cn.iocoder.yudao.module.promotion.enums.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
@ -9,6 +11,8 @@ import java.util.Arrays;
|
|||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum CouponTakeTypeEnum implements IntArrayValuable {
|
||||
|
||||
BY_USER(1, "直接领取"), // 用户可在首页、每日领劵直接领取
|
||||
|
@ -26,19 +30,6 @@ public enum CouponTakeTypeEnum implements IntArrayValuable {
|
|||
*/
|
||||
private final String name;
|
||||
|
||||
CouponTakeTypeEnum(Integer value, String name) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
<artifactId>yudao-module-product-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-member-api</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 业务组件 -->
|
||||
<dependency>
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@Api(tags = "管理后台 - 优惠劵")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/coupon")
|
||||
@Validated
|
||||
public class CouponController {
|
||||
|
||||
@Resource
|
||||
private CouponService couponService;
|
||||
@Resource
|
||||
private MemberUserApi memberUserApi;
|
||||
|
||||
// @GetMapping("/get")
|
||||
// @ApiOperation("获得优惠劵")
|
||||
// @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
// @PreAuthorize("@ss.hasPermission('promotion:coupon:query')")
|
||||
// public CommonResult<CouponRespVO> getCoupon(@RequestParam("id") Long id) {
|
||||
// CouponDO coupon = couponService.getCoupon(id);
|
||||
// return success(CouponConvert.INSTANCE.convert(coupon));
|
||||
// }
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("回收优惠劵")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon:delete')")
|
||||
public CommonResult<Boolean> deleteCoupon(@RequestParam("id") Long id) {
|
||||
couponService.deleteCoupon(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得优惠劵分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon:query')")
|
||||
public CommonResult<PageResult<CouponPageItemRespVO>> getCouponPage(@Valid CouponPageReqVO pageVO) {
|
||||
PageResult<CouponDO> pageResult = couponService.getCouponPage(pageVO);
|
||||
PageResult<CouponPageItemRespVO> pageResulVO = CouponConvert.INSTANCE.convertPage(pageResult);
|
||||
if (CollUtil.isEmpty(pageResulVO.getList())) {
|
||||
return success(pageResulVO);
|
||||
}
|
||||
// 读取用户信息,进行拼接
|
||||
Set<Long> userIds = convertSet(pageResult.getList(), CouponDO::getUserId);
|
||||
Map<Long, UserRespDTO> userMap = memberUserApi.getUserMap(userIds);
|
||||
pageResulVO.getList().forEach(itemRespVO -> MapUtils.findAndThen(userMap, itemRespVO.getUserId(),
|
||||
userRespDTO -> itemRespVO.setNickname(userRespDTO.getNickname())));
|
||||
return success(pageResulVO);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.promotion.controller.admin.coupon;
|
|||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.*;
|
||||
import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.coupon.CouponTemplateService;
|
||||
|
@ -45,6 +42,14 @@ public class CouponTemplateController {
|
|||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/update-status")
|
||||
@ApiOperation("更新优惠劵模板状态")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:coupon-template:update')")
|
||||
public CommonResult<Boolean> updateCouponTemplateStatus(@Valid @RequestBody CouponTemplateUpdateStatusReqVO reqVO) {
|
||||
couponTemplateService.updateCouponTemplateStatus(reqVO.getId(), reqVO.getStatus());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除优惠劵模板")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
|
||||
|
||||
/**
|
||||
* 优惠劵 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class CouponBaseVO {
|
||||
|
||||
// ========== 基本信息 BEGIN ==========
|
||||
@ApiModelProperty(value = "优惠劵模板编号", required = true, example = "1024")
|
||||
@NotNull(message = "优惠劵模板编号不能为空")
|
||||
private Integer templateId;
|
||||
|
||||
@ApiModelProperty(value = "优惠劵名", required = true, example = "春节送送送")
|
||||
@NotNull(message = "优惠劵名不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "优惠码状态", required = true, example = "1", notes = "参见 CouponStatusEnum 枚举")
|
||||
private Integer status;
|
||||
|
||||
// ========== 基本信息 END ==========
|
||||
|
||||
// ========== 领取情况 BEGIN ==========
|
||||
@ApiModelProperty(value = "用户编号", required = true, example = "1")
|
||||
@NotNull(message = "用户编号不能为空")
|
||||
private Long userId;
|
||||
|
||||
@ApiModelProperty(value = "领取方式", required = true, example = "1", notes = "参见 CouponTakeTypeEnum 枚举类")
|
||||
@NotNull(message = "领取方式不能为空")
|
||||
private Integer takeType;
|
||||
// ========== 领取情况 END ==========
|
||||
|
||||
// ========== 使用规则 BEGIN ==========
|
||||
@ApiModelProperty(value = "是否设置满多少金额可用", required = true, example = "100", notes = "单位:分;0 - 不限制")
|
||||
@NotNull(message = "是否设置满多少金额可用不能为空")
|
||||
private Integer usePrice;
|
||||
|
||||
@ApiModelProperty(value = "固定日期 - 生效开始时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private Date validStartTime;
|
||||
|
||||
@ApiModelProperty(value = "固定日期 - 生效结束时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private Date validEndTime;
|
||||
|
||||
@ApiModelProperty(value = "商品范围", required = true, example = "1", notes = "参见 PromotionProductScopeEnum 枚举类")
|
||||
@NotNull(message = "商品范围不能为空")
|
||||
@InEnum(PromotionProductScopeEnum.class)
|
||||
private Integer productScope;
|
||||
|
||||
@ApiModelProperty(value = "商品 SPU 编号的数组", example = "1,3")
|
||||
private List<Long> productSpuIds;
|
||||
// ========== 使用规则 END ==========
|
||||
|
||||
// ========== 使用效果 BEGIN ==========
|
||||
@ApiModelProperty(value = "优惠类型", required = true, example = "1", notes = "参见 PromotionDiscountTypeEnum 枚举")
|
||||
@NotNull(message = "优惠类型不能为空")
|
||||
@InEnum(PromotionDiscountTypeEnum.class)
|
||||
private Integer discountType;
|
||||
|
||||
@ApiModelProperty(value = "折扣百分比", example = "80", notes = "例如说,80% 为 80")
|
||||
private Integer discountPercent;
|
||||
|
||||
@ApiModelProperty(value = "优惠金额", example = "10", notes = "单位:分")
|
||||
@Min(value = 0, message = "优惠金额需要大于等于 0")
|
||||
private Integer discountPrice;
|
||||
|
||||
@ApiModelProperty(value = "折扣上限", example = "100", notes = "单位:分,仅在 discountType 为 PERCENT 使用")
|
||||
private Integer discountLimitPrice;
|
||||
// ========== 使用效果 END ==========
|
||||
|
||||
// ========== 使用情况 BEGIN ==========
|
||||
|
||||
@ApiModelProperty(value = "使用订单号", example = "4096")
|
||||
private Long useOrderId;
|
||||
|
||||
@ApiModelProperty(value = "使用时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private Date useTime;
|
||||
|
||||
// ========== 使用情况 END ==========
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@ApiModel("管理后台 - 优惠劵分页的每一项 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CouponPageItemRespVO extends CouponRespVO {
|
||||
|
||||
@ApiModelProperty(value = "用户昵称", example = "老芋艿")
|
||||
private String nickname;
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@ApiModel("管理后台 - 优惠劵分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CouponPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "优惠劵模板编号", example = "2048")
|
||||
private Long templateId;
|
||||
|
||||
@ApiModelProperty(value = "优惠码状态", example = "1", notes = "参见 CouponStatusEnum 枚举")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private Date[] createTime;
|
||||
|
||||
@ApiModelProperty(value = "用户昵称", example = "芋艿", notes = "模糊匹配")
|
||||
private String nickname;
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ApiModel("管理后台 - 优惠劵 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CouponRespVO extends CouponBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "优惠劵编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo;
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
|
@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.validation.InEnum;
|
|||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
@ -19,6 +20,7 @@ import java.util.List;
|
|||
import java.util.Objects;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT;
|
||||
|
||||
/**
|
||||
* 优惠劵模板 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
|
@ -62,10 +64,12 @@ public class CouponTemplateBaseVO {
|
|||
|
||||
@ApiModelProperty(value = "固定日期 - 生效开始时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private Date validStartTime;
|
||||
|
||||
@ApiModelProperty(value = "固定日期 - 生效结束时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
|
||||
private Date validEndTime;
|
||||
|
||||
@ApiModelProperty(value = "领取日期 - 开始天数")
|
||||
|
@ -82,15 +86,14 @@ public class CouponTemplateBaseVO {
|
|||
private Integer discountType;
|
||||
|
||||
@ApiModelProperty(value = "折扣百分比", example = "80", notes = "例如说,80% 为 80")
|
||||
@Min(value = 1)
|
||||
private Integer discountPercent;
|
||||
|
||||
@ApiModelProperty(value = "优惠金额", example = "10", notes = "单位:分")
|
||||
@Min(value = 1)
|
||||
@Min(value = 0, message = "优惠金额需要大于等于 0")
|
||||
private Integer discountPrice;
|
||||
|
||||
@ApiModelProperty(value = "折扣上限", example = "100", notes = "单位:分,仅在 discountType 为 PERCENT 使用")
|
||||
private Integer discountPriceLimit;
|
||||
private Integer discountLimitPrice;
|
||||
|
||||
@AssertTrue(message = "商品 SPU 编号的数组不能为空")
|
||||
@JsonIgnore
|
||||
|
@ -127,11 +130,11 @@ public class CouponTemplateBaseVO {
|
|||
|| fixedEndTerm != null;
|
||||
}
|
||||
|
||||
@AssertTrue(message = "折扣百分比不能为空")
|
||||
@AssertTrue(message = "折扣百分比需要大于等于 1,小于等于 99")
|
||||
@JsonIgnore
|
||||
public boolean isDiscountPercentValid() {
|
||||
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType())
|
||||
|| discountPercent != null;
|
||||
|| (discountPercent != null && discountPercent >= 1 && discountPercent<= 99);
|
||||
}
|
||||
|
||||
@AssertTrue(message = "优惠金额不能为空")
|
||||
|
@ -143,9 +146,9 @@ public class CouponTemplateBaseVO {
|
|||
|
||||
@AssertTrue(message = "折扣上限不能为空")
|
||||
@JsonIgnore
|
||||
public boolean isDiscountPriceLimit() {
|
||||
public boolean isDiscountLimitPriceValid() {
|
||||
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType())
|
||||
|| discountPriceLimit != null;
|
||||
|| discountLimitPrice != null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo;
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo;
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo;
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo;
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
|
@ -0,0 +1,24 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("管理后台 - 优惠劵模板更新状态 Request VO")
|
||||
@Data
|
||||
public class CouponTemplateUpdateStatusReqVO {
|
||||
|
||||
@ApiModelProperty(value = "优惠劵模板编号", required = true, example = "1024")
|
||||
@NotNull(message = "优惠劵模板编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
|
||||
@NotNull(message = "状态不能为空")
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.discount;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*;
|
||||
import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Api(tags = "管理后台 - 限时折扣活动")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/discount-activity")
|
||||
@Validated
|
||||
public class DiscountActivityController {
|
||||
|
||||
@Resource
|
||||
private DiscountActivityService discountActivityService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建限时折扣活动")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:create')")
|
||||
public CommonResult<Long> createDiscountActivity(@Valid @RequestBody DiscountActivityCreateReqVO createReqVO) {
|
||||
return success(discountActivityService.createDiscountActivity(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("更新限时折扣活动")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:update')")
|
||||
public CommonResult<Boolean> updateDiscountActivity(@Valid @RequestBody DiscountActivityUpdateReqVO updateReqVO) {
|
||||
discountActivityService.updateDiscountActivity(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/close")
|
||||
@ApiOperation("关闭限时折扣活动")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:close')")
|
||||
public CommonResult<Boolean> closeRewardActivity(@RequestParam("id") Long id) {
|
||||
discountActivityService.closeRewardActivity(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除限时折扣活动")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:delete')")
|
||||
public CommonResult<Boolean> deleteDiscountActivity(@RequestParam("id") Long id) {
|
||||
discountActivityService.deleteDiscountActivity(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得限时折扣活动")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')")
|
||||
public CommonResult<DiscountActivityDetailRespVO> getDiscountActivity(@RequestParam("id") Long id) {
|
||||
DiscountActivityDO discountActivity = discountActivityService.getDiscountActivity(id);
|
||||
if (discountActivity == null) {
|
||||
return success(null);
|
||||
}
|
||||
// 拼接结果
|
||||
List<DiscountProductDO> discountProducts = discountActivityService.getDiscountProductsByActivityId(id);
|
||||
return success(DiscountActivityConvert.INSTANCE.convert(discountActivity, discountProducts));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得限时折扣活动分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')")
|
||||
public CommonResult<PageResult<DiscountActivityRespVO>> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) {
|
||||
PageResult<DiscountActivityDO> pageResult = discountActivityService.getDiscountActivityPage(pageVO);
|
||||
return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
/**
|
||||
* TODO 占位
|
||||
*/
|
||||
package cn.iocoder.yudao.module.promotion.controller.admin.discount;
|
|
@ -0,0 +1,82 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Date;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
/**
|
||||
* 限时折扣活动 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class DiscountActivityBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "活动标题", required = true, example = "一个标题")
|
||||
@NotNull(message = "活动标题不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "开始时间", required = true)
|
||||
@NotNull(message = "开始时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private Date startTime;
|
||||
|
||||
@ApiModelProperty(value = "结束时间", required = true)
|
||||
@NotNull(message = "结束时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private Date endTime;
|
||||
|
||||
@ApiModelProperty(value = "备注", example = "我是备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModel("商品")
|
||||
@Data
|
||||
public static class Product {
|
||||
|
||||
@ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1")
|
||||
@NotNull(message = "商品 SPU 编号不能为空")
|
||||
private Long spuId;
|
||||
|
||||
@ApiModelProperty(value = "商品 SKU 编号", required = true, example = "1")
|
||||
@NotNull(message = "商品 SKU 编号不能为空")
|
||||
private Long skuId;
|
||||
|
||||
@ApiModelProperty(value = "优惠类型", required = true, example = "1", notes = "参见 PromotionDiscountTypeEnum 枚举")
|
||||
@NotNull(message = "优惠类型不能为空")
|
||||
@InEnum(PromotionDiscountTypeEnum.class)
|
||||
private Integer discountType;
|
||||
|
||||
@ApiModelProperty(value = "折扣百分比", example = "80", notes = "例如说,80% 为 80")
|
||||
private Integer discountPercent;
|
||||
|
||||
@ApiModelProperty(value = "优惠金额", example = "10", notes = "单位:分")
|
||||
@Min(value = 0, message = "优惠金额需要大于等于 0")
|
||||
private Integer discountPrice;
|
||||
|
||||
@AssertTrue(message = "折扣百分比需要大于等于 1,小于等于 99")
|
||||
@JsonIgnore
|
||||
public boolean isDiscountPercentValid() {
|
||||
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType())
|
||||
|| (discountPercent != null && discountPercent >= 1 && discountPercent<= 99);
|
||||
}
|
||||
|
||||
@AssertTrue(message = "优惠金额不能为空")
|
||||
@JsonIgnore
|
||||
public boolean isDiscountPriceValid() {
|
||||
return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PRICE.getType())
|
||||
|| discountPrice != null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel("管理后台 - 限时折扣活动创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class DiscountActivityCreateReqVO extends DiscountActivityBaseVO {
|
||||
|
||||
/**
|
||||
* 商品列表
|
||||
*/
|
||||
@NotEmpty(message = "商品列表不能为空")
|
||||
@Valid
|
||||
private List<Product> products;
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel("管理后台 - 限时折扣活动的详细 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class DiscountActivityDetailRespVO extends DiscountActivityRespVO {
|
||||
|
||||
/**
|
||||
* 商品列表
|
||||
*/
|
||||
private List<Product> products;
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@ApiModel("管理后台 - 限时折扣活动分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class DiscountActivityPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "活动标题", example = "一个标题")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "活动状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private Date[] createTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Date;
|
||||
|
||||
@ApiModel("管理后台 - 限时折扣活动 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class DiscountActivityRespVO extends DiscountActivityBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "活动编号", required = true, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "活动状态", required = true, example = "1")
|
||||
@NotNull(message = "活动状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel("管理后台 - 限时折扣活动更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class DiscountActivityUpdateReqVO extends DiscountActivityBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "活动编号", required = true, example = "1024")
|
||||
@NotNull(message = "活动编号不能为空")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 商品列表
|
||||
*/
|
||||
@NotEmpty(message = "商品列表不能为空")
|
||||
@Valid
|
||||
private List<DiscountActivityCreateReqVO.Product> products;
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.reward;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.reward.RewardActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Api(tags = "管理后台 - 满减送活动")
|
||||
@RestController
|
||||
@RequestMapping("/promotion/reward-activity")
|
||||
@Validated
|
||||
public class RewardActivityController {
|
||||
|
||||
@Resource
|
||||
private RewardActivityService rewardActivityService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建满减送活动")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:reward-activity:create')")
|
||||
public CommonResult<Long> createRewardActivity(@Valid @RequestBody RewardActivityCreateReqVO createReqVO) {
|
||||
return success(rewardActivityService.createRewardActivity(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@ApiOperation("更新满减送活动")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:reward-activity:update')")
|
||||
public CommonResult<Boolean> updateRewardActivity(@Valid @RequestBody RewardActivityUpdateReqVO updateReqVO) {
|
||||
rewardActivityService.updateRewardActivity(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PutMapping("/close")
|
||||
@ApiOperation("关闭满减送活动")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:reward-activity:close')")
|
||||
public CommonResult<Boolean> closeRewardActivity(@RequestParam("id") Long id) {
|
||||
rewardActivityService.closeRewardActivity(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@ApiOperation("删除满减送活动")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:reward-activity:delete')")
|
||||
public CommonResult<Boolean> deleteRewardActivity(@RequestParam("id") Long id) {
|
||||
rewardActivityService.deleteRewardActivity(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得满减送活动")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('promotion:reward-activity:query')")
|
||||
public CommonResult<RewardActivityRespVO> getRewardActivity(@RequestParam("id") Long id) {
|
||||
RewardActivityDO rewardActivity = rewardActivityService.getRewardActivity(id);
|
||||
return success(RewardActivityConvert.INSTANCE.convert(rewardActivity));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得满减送活动分页")
|
||||
@PreAuthorize("@ss.hasPermission('promotion:reward-activity:query')")
|
||||
public CommonResult<PageResult<RewardActivityRespVO>> getRewardActivityPage(@Valid RewardActivityPageReqVO pageVO) {
|
||||
PageResult<RewardActivityDO> pageResult = rewardActivityService.getRewardActivityPage(pageVO);
|
||||
return success(RewardActivityConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
import javax.validation.constraints.Future;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
/**
|
||||
* 满减送活动 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||
*/
|
||||
@Data
|
||||
public class RewardActivityBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "活动标题", required = true, example = "满啦满啦")
|
||||
@NotNull(message = "活动标题不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "开始时间", required = true)
|
||||
@NotNull(message = "开始时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private Date startTime;
|
||||
|
||||
@ApiModelProperty(value = "结束时间", required = true)
|
||||
@NotNull(message = "结束时间不能为空")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
@Future(message = "结束时间必须大于当前时间")
|
||||
private Date endTime;
|
||||
|
||||
@ApiModelProperty(value = "备注", example = "biubiubiu")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(value = "条件类型", required = true, example = "1")
|
||||
@NotNull(message = "条件类型不能为空")
|
||||
@InEnum(value = PromotionConditionTypeEnum.class, message = "条件类型必须是 {value}")
|
||||
private Integer conditionType;
|
||||
|
||||
@ApiModelProperty(value = "商品范围", required = true, example = "1")
|
||||
@NotNull(message = "商品范围不能为空")
|
||||
@InEnum(value = PromotionConditionTypeEnum.class, message = "商品范围必须是 {value}")
|
||||
private Integer productScope;
|
||||
|
||||
@ApiModelProperty(value = "商品 SPU 编号的数组", example = "1,2,3")
|
||||
private List<Long> productSpuIds;
|
||||
|
||||
/**
|
||||
* 优惠规则的数组
|
||||
*/
|
||||
@Valid // 校验下子对象
|
||||
private List<Rule> rules;
|
||||
|
||||
@ApiModel("优惠规则")
|
||||
@Data
|
||||
public static class Rule {
|
||||
|
||||
@ApiModelProperty(value = "优惠门槛", required = true, example = "100", notes = "1. 满 N 元,单位:分; 2. 满 N 件")
|
||||
@Min(value = 1L, message = "优惠门槛必须大于等于 1")
|
||||
private Integer limit;
|
||||
|
||||
@ApiModelProperty(value = "优惠价格", required = true, example = "100", notes = "单位:分")
|
||||
@Min(value = 1L, message = "优惠价格必须大于等于 1")
|
||||
private Integer discountPrice;
|
||||
|
||||
@ApiModelProperty(value = "是否包邮", required = true, example = "true")
|
||||
private Boolean freeDelivery;
|
||||
|
||||
@ApiModelProperty(value = "赠送的积分", required = true, example = "100")
|
||||
@Min(value = 1L, message = "赠送的积分必须大于等于 1")
|
||||
private Integer point;
|
||||
|
||||
@ApiModelProperty(value = "赠送的优惠劵编号的数组", example = "1,2,3")
|
||||
private List<Long> couponIds;
|
||||
|
||||
@ApiModelProperty(value = "赠送的优惠卷数量的数组", example = "1,2,3")
|
||||
private List<Integer> couponCounts;
|
||||
|
||||
@AssertTrue(message = "优惠劵和数量必须一一对应")
|
||||
@JsonIgnore
|
||||
public boolean isCouponCountsValid() {
|
||||
return CollUtil.size(couponCounts) == CollUtil.size(couponCounts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo;
|
||||
|
||||
import lombok.*;
|
||||
import io.swagger.annotations.*;
|
||||
|
||||
@ApiModel("管理后台 - 满减送活动创建 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class RewardActivityCreateReqVO extends RewardActivityBaseVO {
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo;
|
||||
|
||||
import lombok.*;
|
||||
import io.swagger.annotations.*;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
|
||||
@ApiModel("管理后台 - 满减送活动分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class RewardActivityPageReqVO extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "活动标题", example = "满啦满啦")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "活动状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.annotations.*;
|
||||
|
||||
@ApiModel("管理后台 - 满减送活动 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class RewardActivityRespVO extends RewardActivityBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "活动编号", required = true, example = "1024")
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty(value = "活动状态", required = true, example = "1")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "创建时间", required = true)
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo;
|
||||
|
||||
import lombok.*;
|
||||
import io.swagger.annotations.*;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
@ApiModel("管理后台 - 满减送活动更新 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class RewardActivityUpdateReqVO extends RewardActivityBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "活动编号", required = true, example = "1024")
|
||||
@NotNull(message = "活动编号不能为空")
|
||||
private Long id;
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package cn.iocoder.yudao.module.promotion.convert.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 优惠劵 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface CouponConvert {
|
||||
|
||||
CouponConvert INSTANCE = Mappers.getMapper(CouponConvert.class);
|
||||
|
||||
PageResult<CouponPageItemRespVO> convertPage(PageResult<CouponDO> page);
|
||||
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
package cn.iocoder.yudao.module.promotion.convert.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
package cn.iocoder.yudao.module.promotion.convert.discount;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 限时折扣活动 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface DiscountActivityConvert {
|
||||
|
||||
DiscountActivityConvert INSTANCE = Mappers.getMapper(DiscountActivityConvert.class);
|
||||
|
||||
DiscountActivityDO convert(DiscountActivityCreateReqVO bean);
|
||||
|
||||
DiscountActivityDO convert(DiscountActivityUpdateReqVO bean);
|
||||
|
||||
DiscountActivityRespVO convert(DiscountActivityDO bean);
|
||||
|
||||
List<DiscountActivityRespVO> convertList(List<DiscountActivityDO> list);
|
||||
|
||||
PageResult<DiscountActivityRespVO> convertPage(PageResult<DiscountActivityDO> page);
|
||||
|
||||
DiscountProductDetailBO convert(DiscountProductDO product);
|
||||
|
||||
default List<DiscountProductDetailBO> convertList(List<DiscountProductDO> products, Map<Long, DiscountActivityDO> activityMap) {
|
||||
return CollectionUtils.convertList(products, product -> {
|
||||
DiscountProductDetailBO detail = convert(product);
|
||||
MapUtils.findAndThen(activityMap, product.getActivityId(), activity -> {
|
||||
detail.setActivityName(activity.getName());
|
||||
});
|
||||
return detail;
|
||||
});
|
||||
}
|
||||
|
||||
DiscountProductDO convert(DiscountActivityBaseVO.Product bean);
|
||||
|
||||
DiscountActivityDetailRespVO convert(DiscountActivityDO activity, List<DiscountProductDO> products);
|
||||
|
||||
// =========== 比较是否相等 ==========
|
||||
/**
|
||||
* 比较两个限时折扣商品是否相等
|
||||
*
|
||||
* @param productDO 数据库中的商品
|
||||
* @param productVO 前端传入的商品
|
||||
* @return 是否匹配
|
||||
*/
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
default boolean isEquals(DiscountProductDO productDO, DiscountActivityBaseVO.Product productVO) {
|
||||
if (ObjectUtil.notEqual(productDO.getSpuId(), productVO.getSpuId())
|
||||
|| ObjectUtil.notEqual(productDO.getSkuId(), productVO.getSkuId())
|
||||
|| ObjectUtil.notEqual(productDO.getDiscountType(), productVO.getDiscountType())) {
|
||||
return false;
|
||||
}
|
||||
if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PRICE.getType())) {
|
||||
return ObjectUtil.equal(productDO.getDiscountPrice(), productVO.getDiscountPrice());
|
||||
}
|
||||
if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PERCENT.getType())) {
|
||||
return ObjectUtil.equal(productDO.getDiscountPercent(), productVO.getDiscountPercent());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较两个限时折扣商品是否相等
|
||||
* 注意,比较时忽略 id 编号
|
||||
*
|
||||
* @param productDO 商品 1
|
||||
* @param productVO 商品 2
|
||||
* @return 是否匹配
|
||||
*/
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
default boolean isEquals(DiscountProductDO productDO, DiscountProductDO productVO) {
|
||||
if (ObjectUtil.notEqual(productDO.getSpuId(), productVO.getSpuId())
|
||||
|| ObjectUtil.notEqual(productDO.getSkuId(), productVO.getSkuId())
|
||||
|| ObjectUtil.notEqual(productDO.getDiscountType(), productVO.getDiscountType())) {
|
||||
return false;
|
||||
}
|
||||
if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PRICE.getType())) {
|
||||
return ObjectUtil.equal(productDO.getDiscountPrice(), productVO.getDiscountPrice());
|
||||
}
|
||||
if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PERCENT.getType())) {
|
||||
return ObjectUtil.equal(productDO.getDiscountPercent(), productVO.getDiscountPercent());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
/**
|
||||
* TODO 占位
|
||||
*/
|
||||
package cn.iocoder.yudao.module.promotion.convert.discount;
|
|
@ -36,7 +36,8 @@ public interface PriceConvert {
|
|||
orderItem.setPayPrice(orderItem.getOriginalPrice()).setOrderDividePrice(orderItem.getOriginalPrice());
|
||||
priceCalculate.getOrder().getItems().add(orderItem);
|
||||
// 补充价格信息到 Order 中
|
||||
order.setOriginalPrice(order.getOriginalPrice() + orderItem.getOriginalPrice()).setPayPrice(order.getOriginalPrice());
|
||||
order.setOriginalPrice(order.getOriginalPrice() + orderItem.getOriginalPrice())
|
||||
.setOrderPrice(order.getOriginalPrice()).setPayPrice(order.getOriginalPrice());
|
||||
});
|
||||
return priceCalculate;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package cn.iocoder.yudao.module.promotion.convert.reward;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 满减送活动 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface RewardActivityConvert {
|
||||
|
||||
RewardActivityConvert INSTANCE = Mappers.getMapper(RewardActivityConvert.class);
|
||||
|
||||
RewardActivityDO convert(RewardActivityCreateReqVO bean);
|
||||
|
||||
RewardActivityDO convert(RewardActivityUpdateReqVO bean);
|
||||
|
||||
RewardActivityRespVO convert(RewardActivityDO bean);
|
||||
|
||||
PageResult<RewardActivityRespVO> convertPage(PageResult<RewardActivityDO> page);
|
||||
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
package cn.iocoder.yudao.module.promotion.dal.dataobject.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
|
@ -14,9 +17,11 @@ import java.util.List;
|
|||
|
||||
/**
|
||||
* 优惠劵 DO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "promotion_coupon", autoResultMap = true)
|
||||
@KeySequence("promotion_coupo_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@KeySequence("promotion_coupon_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class CouponDO extends BaseDO {
|
||||
|
@ -35,21 +40,13 @@ public class CouponDO extends BaseDO {
|
|||
/**
|
||||
* 优惠劵名
|
||||
*
|
||||
* 冗余自 {@link CouponTemplateDO} 的 title
|
||||
*
|
||||
* TODO 芋艿,暂时不考虑冗余的更新
|
||||
* 冗余 {@link CouponTemplateDO#getName()}
|
||||
*/
|
||||
private String title;
|
||||
// /**
|
||||
// * 核销码
|
||||
// */
|
||||
// private String verifyCode;
|
||||
private String name;
|
||||
/**
|
||||
* 优惠码状态
|
||||
*
|
||||
* 1-未使用
|
||||
* 2-已使用
|
||||
* 3-已失效
|
||||
* 枚举 {@link CouponStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
|
@ -58,13 +55,14 @@ public class CouponDO extends BaseDO {
|
|||
// ========== 领取情况 BEGIN ==========
|
||||
/**
|
||||
* 用户编号
|
||||
*
|
||||
* 关联 MemberUserDO 的 id 字段
|
||||
*/
|
||||
private Integer userId;
|
||||
private Long userId;
|
||||
/**
|
||||
* 领取类型
|
||||
*
|
||||
* 1 - 用户主动领取
|
||||
* 2 - 后台自动发放
|
||||
* 枚举 {@link CouponTakeTypeEnum}
|
||||
*/
|
||||
private Integer takeType;
|
||||
// ========== 领取情况 END ==========
|
||||
|
@ -72,8 +70,10 @@ public class CouponDO extends BaseDO {
|
|||
// ========== 使用规则 BEGIN ==========
|
||||
/**
|
||||
* 是否设置满多少金额可用,单位:分
|
||||
*
|
||||
* 冗余 {@link CouponTemplateDO#getUsePrice()}
|
||||
*/
|
||||
private Integer priceAvailable;
|
||||
private Integer usePrice;
|
||||
/**
|
||||
* 生效开始时间
|
||||
*/
|
||||
|
@ -90,50 +90,49 @@ public class CouponDO extends BaseDO {
|
|||
private Integer productScope;
|
||||
/**
|
||||
* 商品 SPU 编号的数组
|
||||
*
|
||||
* 冗余 {@link CouponTemplateDO#getProductSpuIds()}
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<Long> spuIds;
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> productSpuIds;
|
||||
// ========== 使用规则 END ==========
|
||||
|
||||
// ========== 使用效果 BEGIN ==========
|
||||
/**
|
||||
* 优惠类型
|
||||
* 折扣类型
|
||||
*
|
||||
* 1-代金卷
|
||||
* 2-折扣卷
|
||||
* 冗余 {@link CouponTemplateDO#getDiscountType()}
|
||||
*/
|
||||
private Integer preferentialType;
|
||||
private Integer discountType;
|
||||
/**
|
||||
* 折扣
|
||||
*/
|
||||
private Integer percentOff;
|
||||
/**
|
||||
* 优惠金额,单位:分。
|
||||
*/
|
||||
private Integer priceOff;
|
||||
/**
|
||||
* 折扣上限,仅在 {@link #preferentialType} 等于 2 时生效。
|
||||
* 折扣百分比
|
||||
*
|
||||
* 例如,折扣上限为 20 元,当使用 8 折优惠券,订单金额为 1000 元时,最高只可折扣 20 元,而非 80 元。
|
||||
* 冗余 {@link CouponTemplateDO#getDiscountPercent()}
|
||||
*/
|
||||
private Integer discountPriceLimit;
|
||||
private Integer discountPercent;
|
||||
/**
|
||||
* 优惠金额,单位:分
|
||||
*
|
||||
* 冗余 {@link CouponTemplateDO#getDiscountPrice()}
|
||||
*/
|
||||
private Integer discountPrice;
|
||||
/**
|
||||
* 折扣上限,仅在 {@link #discountType} 等于 {@link PromotionDiscountTypeEnum#PERCENT} 时生效
|
||||
*
|
||||
* 冗余 {@link CouponTemplateDO#getDiscountLimitPrice()}
|
||||
*/
|
||||
private Integer discountLimitPrice;
|
||||
// ========== 使用效果 END ==========
|
||||
|
||||
// ========== 使用情况 BEGIN ==========
|
||||
// /**
|
||||
// * 使用订单号
|
||||
// */
|
||||
// private Integer usedOrderId; // TODO 芋艿,暂时不考虑这个字段
|
||||
// /**
|
||||
// * 订单中优惠面值,单位:分
|
||||
// */
|
||||
// private Integer usedPrice; // TODO 芋艿,暂时不考虑这个字段
|
||||
/**
|
||||
* 使用订单号
|
||||
*/
|
||||
private Long useOrderId;
|
||||
/**
|
||||
* 使用时间
|
||||
*/
|
||||
private Date usedTime;
|
||||
|
||||
// TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。
|
||||
private Date useTime;
|
||||
|
||||
// ========== 使用情况 END ==========
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ import java.util.List;
|
|||
* 优惠劵模板 DO
|
||||
*
|
||||
* 当用户领取时,会生成 {@link CouponDO} 优惠劵
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@TableName(value = "promotion_coupon_template", autoResultMap = true)
|
||||
@KeySequence("promotion_coupon_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
package cn.iocoder.yudao.module.promotion.dal.dataobject.discount;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 限时折扣商品 DO
|
||||
*
|
||||
|
@ -31,12 +30,6 @@ public class DiscountProductDO extends BaseDO {
|
|||
* 关联 {@link DiscountActivityDO#getId()}
|
||||
*/
|
||||
private Long activityId;
|
||||
/**
|
||||
* 限时折扣活动的名字
|
||||
*
|
||||
* 冗余 {@link DiscountActivityDO#getName()}
|
||||
*/
|
||||
private String activityName;
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*
|
||||
|
@ -49,23 +42,24 @@ public class DiscountProductDO extends BaseDO {
|
|||
* 关联 ProductSkuDO 的 id 编号
|
||||
*/
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
private Date startTime;
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
private Date endTime;
|
||||
/**
|
||||
* 销售价格,单位:分
|
||||
* 折扣类型
|
||||
*
|
||||
* 冗余 ProductSkuDO 的 price 字段
|
||||
* 枚举 {@link PromotionDiscountTypeEnum}
|
||||
*/
|
||||
private Integer originalPrice;
|
||||
private Integer discountType;
|
||||
/**
|
||||
* 优惠价格,单位:分
|
||||
* 折扣百分比
|
||||
*
|
||||
* 例如,80% 为 80
|
||||
*/
|
||||
private Integer promotionPrice;
|
||||
private Integer discountPercent;
|
||||
/**
|
||||
* 优惠金额,单位:分
|
||||
*
|
||||
* 当 {@link #discountType} 为 {@link PromotionDiscountTypeEnum#PRICE} 生效
|
||||
*/
|
||||
private Integer discountPrice;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package cn.iocoder.yudao.module.promotion.dal.dataobject.reward;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
|
@ -8,10 +10,11 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
|
|||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -68,19 +71,19 @@ public class RewardActivityDO extends BaseDO {
|
|||
/**
|
||||
* 商品 SPU 编号的数组
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
@TableField(typeHandler = LongListTypeHandler.class)
|
||||
private List<Long> productSpuIds;
|
||||
/**
|
||||
* 优惠规则的数组
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
@TableField(typeHandler = RuleTypeHandler.class)
|
||||
private List<Rule> rules;
|
||||
|
||||
/**
|
||||
* 优惠规则
|
||||
*/
|
||||
@Data
|
||||
public static class Rule {
|
||||
public static class Rule implements Serializable {
|
||||
|
||||
/**
|
||||
* 优惠门槛
|
||||
|
@ -112,5 +115,19 @@ public class RewardActivityDO extends BaseDO {
|
|||
|
||||
}
|
||||
|
||||
// TODO @芋艿:可以找一些新的思路
|
||||
public static class RuleTypeHandler extends AbstractJsonTypeHandler<List<Rule>> {
|
||||
|
||||
@Override
|
||||
protected List<Rule> parse(String json) {
|
||||
return JsonUtils.parseArray(json, Rule.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toJson(List<Rule> obj) {
|
||||
return JsonUtils.toJsonString(obj);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package cn.iocoder.yudao.module.promotion.dal.mysql.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 优惠劵 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface CouponMapper extends BaseMapperX<CouponDO> {
|
||||
|
||||
default PageResult<CouponDO> selectPage(CouponPageReqVO reqVO, Collection<Long> userIds) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<CouponDO>()
|
||||
.eqIfPresent(CouponDO::getTemplateId, reqVO.getTemplateId())
|
||||
.eqIfPresent(CouponDO::getStatus, reqVO.getStatus())
|
||||
.inIfPresent(CouponDO::getUserId, userIds)
|
||||
.betweenIfPresent(CouponDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(CouponDO::getId));
|
||||
}
|
||||
|
||||
default int delete(Long id, Collection<Integer> whereStatuses) {
|
||||
return update(null, new LambdaUpdateWrapper<CouponDO>()
|
||||
.eq(CouponDO::getId, id).in(CouponDO::getStatus, whereStatuses)
|
||||
.set(CouponDO::getDeleted, 1));
|
||||
}
|
||||
|
||||
}
|
|
@ -3,9 +3,10 @@ package cn.iocoder.yudao.module.promotion.dal.mysql.coupon;
|
|||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 优惠劵模板 Mapper
|
||||
|
@ -24,4 +25,6 @@ public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> {
|
|||
.orderByDesc(CouponTemplateDO::getId));
|
||||
}
|
||||
|
||||
void updateTakeCount(@Param("id") Long id, @Param("incrCount") Integer incrCount);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package cn.iocoder.yudao.module.promotion.dal.mysql.discount;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 限时折扣活动 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface DiscountActivityMapper extends BaseMapperX<DiscountActivityDO> {
|
||||
|
||||
default PageResult<DiscountActivityDO> selectPage(DiscountActivityPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<DiscountActivityDO>()
|
||||
.likeIfPresent(DiscountActivityDO::getName, reqVO.getName())
|
||||
.eqIfPresent(DiscountActivityDO::getStatus, reqVO.getStatus())
|
||||
.betweenIfPresent(DiscountActivityDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(DiscountActivityDO::getId));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package cn.iocoder.yudao.module.promotion.dal.mysql.discount;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 限时折扣商城 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface DiscountProductMapper extends BaseMapperX<DiscountProductDO> {
|
||||
|
||||
default List<DiscountProductDO> selectListBySkuId(Collection<Long> skuIds) {
|
||||
return selectList(DiscountProductDO::getSkuId, skuIds);
|
||||
}
|
||||
|
||||
default List<DiscountProductDO> selectListByActivityId(Long activityId) {
|
||||
return selectList(DiscountProductDO::getActivityId, activityId);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
/**
|
||||
* TODO 占位
|
||||
*/
|
||||
package cn.iocoder.yudao.module.promotion.dal.mysql.discount;
|
|
@ -0,0 +1,38 @@
|
|||
package cn.iocoder.yudao.module.promotion.dal.mysql.reward;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 满减送活动 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface RewardActivityMapper extends BaseMapperX<RewardActivityDO> {
|
||||
|
||||
default PageResult<RewardActivityDO> selectPage(RewardActivityPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<RewardActivityDO>()
|
||||
.likeIfPresent(RewardActivityDO::getName, reqVO.getName())
|
||||
.eqIfPresent(RewardActivityDO::getStatus, reqVO.getStatus())
|
||||
.orderByDesc(RewardActivityDO::getId));
|
||||
}
|
||||
|
||||
default List<RewardActivityDO> selectListByStatus(Collection<Integer> statuses) {
|
||||
return selectList(RewardActivityDO::getStatus, statuses);
|
||||
}
|
||||
|
||||
default List<RewardActivityDO> selectListByProductScopeAndStatus(Integer productScope, Integer status) {
|
||||
return selectList(new LambdaQueryWrapperX<RewardActivityDO>()
|
||||
.eq(RewardActivityDO::getProductScope, productScope)
|
||||
.eq(RewardActivityDO::getStatus, status));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
|
||||
|
||||
/**
|
||||
|
@ -21,4 +23,19 @@ public interface CouponService {
|
|||
*/
|
||||
CouponDO validCoupon(Long id, Long userId);
|
||||
|
||||
/**
|
||||
* 获得优惠劵分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 优惠劵分页
|
||||
*/
|
||||
PageResult<CouponDO> getCouponPage(CouponPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 回收优惠劵
|
||||
*
|
||||
* @param id 优惠劵编号
|
||||
*/
|
||||
void deleteCoupon(Long id);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,27 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.coupon;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponMapper;
|
||||
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_DELETE_FAIL_USED;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NOT_EXISTS;
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
/**
|
||||
* 优惠劵 Service 实现类
|
||||
*
|
||||
|
@ -13,9 +31,56 @@ import org.springframework.validation.annotation.Validated;
|
|||
@Validated
|
||||
public class CouponServiceImpl implements CouponService {
|
||||
|
||||
@Resource
|
||||
private CouponTemplateService couponTemplateService;
|
||||
|
||||
@Resource
|
||||
private CouponMapper couponMapper;
|
||||
|
||||
@Resource
|
||||
private MemberUserApi memberUserApi;
|
||||
|
||||
// TODO 芋艿:待实现
|
||||
@Override
|
||||
public CouponDO validCoupon(Long id, Long userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<CouponDO> getCouponPage(CouponPageReqVO pageReqVO) {
|
||||
// 获得用户编号
|
||||
Set<Long> userIds = null;
|
||||
if (StrUtil.isNotEmpty(pageReqVO.getNickname())) {
|
||||
userIds = CollectionUtils.convertSet(memberUserApi.getUserListByNickname(pageReqVO.getNickname()),
|
||||
UserRespDTO::getId);
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
return PageResult.empty();
|
||||
}
|
||||
}
|
||||
// 分页查询
|
||||
return couponMapper.selectPage(pageReqVO, userIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void deleteCoupon(Long id) {
|
||||
// 校验存在
|
||||
validateCouponExists(id);
|
||||
|
||||
// 更新优惠劵
|
||||
int deleteCount = couponMapper.delete(id,
|
||||
asList(CouponStatusEnum.UNUSED.getStatus(), CouponStatusEnum.EXPIRE.getStatus()));
|
||||
if (deleteCount == 0) {
|
||||
throw exception(COUPON_DELETE_FAIL_USED);
|
||||
}
|
||||
// 减少优惠劵模板的领取数量 -1
|
||||
couponTemplateService.updateCouponTemplateTakeCount(id, -1);
|
||||
}
|
||||
|
||||
private void validateCouponExists(Long id) {
|
||||
if (couponMapper.selectById(id) == null) {
|
||||
throw exception(COUPON_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
@ -30,6 +30,14 @@ public interface CouponTemplateService {
|
|||
*/
|
||||
void updateCouponTemplate(@Valid CouponTemplateUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 更新优惠劵模板的状态
|
||||
*
|
||||
* @param id 编号
|
||||
* @param status 状态
|
||||
*/
|
||||
void updateCouponTemplateStatus(Long id, Integer status);
|
||||
|
||||
/**
|
||||
* 删除优惠劵模板
|
||||
*
|
||||
|
@ -53,4 +61,12 @@ public interface CouponTemplateService {
|
|||
*/
|
||||
PageResult<CouponTemplateDO> getCouponTemplatePage(CouponTemplatePageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 更新优惠劵模板的领取数量
|
||||
*
|
||||
* @param id 优惠劵模板编号
|
||||
* @param incrCount 增加数量
|
||||
*/
|
||||
void updateCouponTemplateTakeCount(Long id, int incrCount);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper;
|
||||
|
@ -30,7 +31,8 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
|
|||
@Override
|
||||
public Long createCouponTemplate(CouponTemplateCreateReqVO createReqVO) {
|
||||
// 插入
|
||||
CouponTemplateDO couponTemplate = CouponTemplateConvert.INSTANCE.convert(createReqVO);
|
||||
CouponTemplateDO couponTemplate = CouponTemplateConvert.INSTANCE.convert(createReqVO)
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
couponTemplateMapper.insert(couponTemplate);
|
||||
// 返回
|
||||
return couponTemplate.getId();
|
||||
|
@ -50,6 +52,14 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
|
|||
couponTemplateMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCouponTemplateStatus(Long id, Integer status) {
|
||||
// 校验存在
|
||||
validateCouponTemplateExists(id);
|
||||
// 更新
|
||||
couponTemplateMapper.updateById(new CouponTemplateDO().setId(id).setStatus(status));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCouponTemplate(Long id) {
|
||||
// 校验存在
|
||||
|
@ -76,4 +86,9 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
|
|||
return couponTemplateMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCouponTemplateTakeCount(Long id, int incrCount) {
|
||||
couponTemplateMapper.updateTakeCount(id, incrCount);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.discount;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 限时折扣 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface DiscountActivityService {
|
||||
|
||||
/**
|
||||
* 基于指定 SKU 编号数组,获得匹配的限时折扣商品
|
||||
*
|
||||
* 注意,匹配的条件,仅仅是日期符合,并且处于开启状态
|
||||
*
|
||||
* @param skuIds SKU 编号数组
|
||||
* @return 匹配的限时折扣商品
|
||||
*/
|
||||
Map<Long, DiscountProductDetailBO> getMatchDiscountProducts(Collection<Long> skuIds);
|
||||
|
||||
/**
|
||||
* 创建限时折扣活动
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createDiscountActivity(@Valid DiscountActivityCreateReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新限时折扣活动
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateDiscountActivity(@Valid DiscountActivityUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 关闭限时折扣活动
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void closeRewardActivity(Long id);
|
||||
|
||||
/**
|
||||
* 删除限时折扣活动
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteDiscountActivity(Long id);
|
||||
|
||||
/**
|
||||
* 获得限时折扣活动
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 限时折扣活动
|
||||
*/
|
||||
DiscountActivityDO getDiscountActivity(Long id);
|
||||
|
||||
/**
|
||||
* 获得限时折扣活动分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 限时折扣活动分页
|
||||
*/
|
||||
PageResult<DiscountActivityDO> getDiscountActivityPage(DiscountActivityPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得活动编号,对应对应的商品列表
|
||||
*
|
||||
* @param activityId 活动编号
|
||||
* @return 活动的商品列表
|
||||
*/
|
||||
List<DiscountProductDO> getDiscountProductsByActivityId(Long activityId);
|
||||
|
||||
}
|
|
@ -0,0 +1,196 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.discount;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountActivityMapper;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
|
||||
import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO;
|
||||
import cn.iocoder.yudao.module.promotion.util.PromotionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
/**
|
||||
* 限时折扣 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class DiscountActivityServiceImpl implements DiscountActivityService {
|
||||
|
||||
@Resource
|
||||
private DiscountActivityMapper discountActivityMapper;
|
||||
@Resource
|
||||
private DiscountProductMapper discountProductMapper;
|
||||
|
||||
@Override
|
||||
public Map<Long, DiscountProductDetailBO> getMatchDiscountProducts(Collection<Long> skuIds) {
|
||||
List<DiscountProductDetailBO> discountProducts = getRewardProductListBySkuIds(skuIds, singleton(PromotionActivityStatusEnum.RUN.getStatus()));
|
||||
return convertMap(discountProducts, DiscountProductDetailBO::getSkuId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long createDiscountActivity(DiscountActivityCreateReqVO createReqVO) {
|
||||
// 校验商品是否冲突
|
||||
validateDiscountActivityProductConflicts(null, createReqVO.getProducts());
|
||||
|
||||
// 插入活动
|
||||
DiscountActivityDO discountActivity = DiscountActivityConvert.INSTANCE.convert(createReqVO)
|
||||
.setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime()));
|
||||
discountActivityMapper.insert(discountActivity);
|
||||
// 插入商品
|
||||
List<DiscountProductDO> discountProducts = convertList(createReqVO.getProducts(),
|
||||
product -> DiscountActivityConvert.INSTANCE.convert(product).setActivityId(discountActivity.getId()));
|
||||
discountProductMapper.insertBatch(discountProducts);
|
||||
// 返回
|
||||
return discountActivity.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDiscountActivity(DiscountActivityUpdateReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
DiscountActivityDO discountActivity = validateDiscountActivityExists(updateReqVO.getId());
|
||||
if (discountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能修改噢
|
||||
throw exception(DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED);
|
||||
}
|
||||
// 校验商品是否冲突
|
||||
validateDiscountActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts());
|
||||
|
||||
// 更新活动
|
||||
DiscountActivityDO updateObj = DiscountActivityConvert.INSTANCE.convert(updateReqVO)
|
||||
.setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime()));
|
||||
discountActivityMapper.updateById(updateObj);
|
||||
// 更新商品
|
||||
updateDiscountProduct(updateReqVO);
|
||||
}
|
||||
|
||||
private void updateDiscountProduct(DiscountActivityUpdateReqVO updateReqVO) {
|
||||
List<DiscountProductDO> dbDiscountProducts = discountProductMapper.selectListByActivityId(updateReqVO.getId());
|
||||
// 计算要删除的记录
|
||||
List<Long> deleteIds = convertList(dbDiscountProducts, DiscountProductDO::getId,
|
||||
discountProductDO -> updateReqVO.getProducts().stream()
|
||||
.noneMatch(product -> DiscountActivityConvert.INSTANCE.isEquals(discountProductDO, product)));
|
||||
if (CollUtil.isNotEmpty(deleteIds)) {
|
||||
discountProductMapper.deleteBatchIds(deleteIds);
|
||||
}
|
||||
// 计算新增的记录
|
||||
List<DiscountProductDO> newDiscountProducts = convertList(updateReqVO.getProducts(),
|
||||
product -> DiscountActivityConvert.INSTANCE.convert(product).setActivityId(updateReqVO.getId()));
|
||||
newDiscountProducts.removeIf(product -> dbDiscountProducts.stream().anyMatch(
|
||||
dbProduct -> DiscountActivityConvert.INSTANCE.isEquals(dbProduct, product))); // 如果匹配到,说明是更新的
|
||||
if (CollectionUtil.isNotEmpty(newDiscountProducts)) {
|
||||
discountProductMapper.insertBatch(newDiscountProducts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验商品是否冲突
|
||||
*
|
||||
* @param id 编号
|
||||
* @param products 商品列表
|
||||
*/
|
||||
private void validateDiscountActivityProductConflicts(Long id, List<DiscountActivityBaseVO.Product> products) {
|
||||
if (CollUtil.isEmpty(products)) {
|
||||
return;
|
||||
}
|
||||
// 查询商品参加的活动
|
||||
List<DiscountProductDetailBO> discountActivityProductList = getRewardProductListBySkuIds(
|
||||
convertSet(products, DiscountActivityBaseVO.Product::getSkuId),
|
||||
asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus()));
|
||||
if (id != null) { // 排除自己这个活动
|
||||
discountActivityProductList.removeIf(product -> id.equals(product.getActivityId()));
|
||||
}
|
||||
// 如果非空,则说明冲突
|
||||
if (CollUtil.isNotEmpty(discountActivityProductList)) {
|
||||
throw exception(DISCOUNT_ACTIVITY_SPU_CONFLICTS);
|
||||
}
|
||||
}
|
||||
|
||||
private List<DiscountProductDetailBO> getRewardProductListBySkuIds(Collection<Long> skuIds,
|
||||
Collection<Integer> statuses) {
|
||||
// 查询商品
|
||||
List<DiscountProductDO> products = discountProductMapper.selectListBySkuId(skuIds);
|
||||
if (CollUtil.isEmpty(products)) {
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
|
||||
// 查询活动
|
||||
List<DiscountActivityDO> activities = discountActivityMapper.selectBatchIds(skuIds);
|
||||
activities.removeIf(activity -> !statuses.contains(activity.getStatus())); // 移除不满足 statuses 状态的
|
||||
Map<Long, DiscountActivityDO> activityMap = CollectionUtils.convertMap(activities, DiscountActivityDO::getId);
|
||||
|
||||
// 移除不满足活动的商品
|
||||
products.removeIf(product -> !activityMap.containsKey(product.getActivityId()));
|
||||
return DiscountActivityConvert.INSTANCE.convertList(products, activityMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeRewardActivity(Long id) {
|
||||
// 校验存在
|
||||
DiscountActivityDO dbDiscountActivity = validateDiscountActivityExists(id);
|
||||
if (dbDiscountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能关闭噢
|
||||
throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED);
|
||||
}
|
||||
if (dbDiscountActivity.getStatus().equals(PromotionActivityStatusEnum.END.getStatus())) { // 已关闭的活动,不能关闭噢
|
||||
throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END);
|
||||
}
|
||||
|
||||
// 更新
|
||||
DiscountActivityDO updateObj = new DiscountActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus());
|
||||
discountActivityMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDiscountActivity(Long id) {
|
||||
// 校验存在
|
||||
DiscountActivityDO discountActivity = validateDiscountActivityExists(id);
|
||||
if (!discountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 未关闭的活动,不能删除噢
|
||||
throw exception(DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED);
|
||||
}
|
||||
|
||||
// 删除
|
||||
discountActivityMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private DiscountActivityDO validateDiscountActivityExists(Long id) {
|
||||
DiscountActivityDO discountActivity = discountActivityMapper.selectById(id);
|
||||
if (discountActivity == null) {
|
||||
throw exception(DISCOUNT_ACTIVITY_NOT_EXISTS);
|
||||
}
|
||||
return discountActivity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiscountActivityDO getDiscountActivity(Long id) {
|
||||
return discountActivityMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<DiscountActivityDO> getDiscountActivityPage(DiscountActivityPageReqVO pageReqVO) {
|
||||
return discountActivityMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DiscountProductDO> getDiscountProductsByActivityId(Long activityId) {
|
||||
return discountProductMapper.selectListByActivityId(activityId);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.discount;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 限时折扣 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface DiscountService {
|
||||
|
||||
/**
|
||||
* 基于指定 SKU 编号数组,获得匹配的限时折扣商品
|
||||
*
|
||||
* 注意,匹配的条件,仅仅是日期符合,并且处于开启状态
|
||||
*
|
||||
* @param skuIds SKU 编号数组
|
||||
* @return 匹配的限时折扣商品
|
||||
*/
|
||||
Map<Long, DiscountProductDO> getMatchDiscountProducts(Collection<Long> skuIds);
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.discount;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 限时折扣 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class DiscountServiceImpl implements DiscountService {
|
||||
|
||||
// TODO 芋艿:待实现
|
||||
@Override
|
||||
public Map<Long, DiscountProductDO> getMatchDiscountProducts(Collection<Long> skuIds) {
|
||||
Map<Long, DiscountProductDO> products = new HashMap<>();
|
||||
products.put(1L, new DiscountProductDO().setPromotionPrice(100));
|
||||
products.put(2L, new DiscountProductDO().setPromotionPrice(50));
|
||||
return products;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.discount.bo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 限时折扣活动商品 BO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class DiscountProductDetailBO {
|
||||
|
||||
// ========== DiscountProductDO 字段 ==========
|
||||
|
||||
/**
|
||||
* 编号,主键自增
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 限时折扣活动的编号
|
||||
*/
|
||||
private Long activityId;
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
private Long spuId;
|
||||
/**
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
private Long skuId;
|
||||
/**
|
||||
* 折扣类型
|
||||
*/
|
||||
private Integer discountType;
|
||||
/**
|
||||
* 折扣百分比
|
||||
*/
|
||||
private Integer discountPercent;
|
||||
/**
|
||||
* 优惠金额,单位:分
|
||||
*/
|
||||
private Integer discountPrice;
|
||||
|
||||
// ========== DiscountActivityDO 字段 ==========
|
||||
/**
|
||||
* 活动标题
|
||||
*/
|
||||
private String activityName;
|
||||
|
||||
}
|
|
@ -4,22 +4,20 @@ import cn.hutool.core.collection.CollUtil;
|
|||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.price.PriceConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.*;
|
||||
import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
|
||||
import cn.iocoder.yudao.module.promotion.service.discount.DiscountService;
|
||||
import cn.iocoder.yudao.module.promotion.service.reward.RewardService;
|
||||
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService;
|
||||
import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO;
|
||||
import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService;
|
||||
import com.google.common.base.Suppliers;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
|
@ -33,9 +31,8 @@ import java.util.function.Supplier;
|
|||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NO_MATCH_MIN_PRICE;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NO_MATCH_SPU;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
/**
|
||||
|
@ -54,12 +51,13 @@ import static java.util.Collections.singletonList;
|
|||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class PriceServiceImpl implements PriceService {
|
||||
|
||||
@Resource
|
||||
private DiscountService discountService;
|
||||
private DiscountActivityService discountService;
|
||||
@Resource
|
||||
private RewardService rewardService;
|
||||
private RewardActivityService rewardActivityService;
|
||||
@Resource
|
||||
private CouponService couponService;
|
||||
|
||||
|
@ -79,7 +77,13 @@ public class PriceServiceImpl implements PriceService {
|
|||
calculatePriceForOrderLevel(calculateReqDTO.getUserId(), priceCalculate);
|
||||
// 计算优惠劵级别的价格
|
||||
calculatePriceForCouponLevel(calculateReqDTO.getUserId(), calculateReqDTO.getCouponId(), priceCalculate);
|
||||
// 计算【优惠劵】促销 TODO 待实现
|
||||
|
||||
// 如果最终支付金额小于等于 0,则抛出业务异常
|
||||
if (priceCalculate.getOrder().getPayPrice() <= 0) {
|
||||
log.error("[calculatePrice][价格计算不正确,请求 calculateReqDTO({}),结果 priceCalculate({})]",
|
||||
calculateReqDTO, priceCalculate);
|
||||
throw exception(PRICE_CALCULATE_PAY_PRICE_ILLEGAL);
|
||||
}
|
||||
return priceCalculate;
|
||||
}
|
||||
|
||||
|
@ -115,24 +119,20 @@ public class PriceServiceImpl implements PriceService {
|
|||
private void calculatePriceForSkuLevel(Long userId, PriceCalculateRespDTO priceCalculate) {
|
||||
// 获取 SKU 级别的所有优惠信息
|
||||
Supplier<Double> memberDiscountPercentSupplier = getMemberDiscountPercentSupplier(userId);
|
||||
Map<Long, DiscountProductDO> discountProducts = discountService.getMatchDiscountProducts(
|
||||
Map<Long, DiscountProductDetailBO> discountProducts = discountService.getMatchDiscountProducts(
|
||||
convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSkuId));
|
||||
|
||||
// 处理每个 SKU 的优惠
|
||||
priceCalculate.getOrder().getItems().forEach(orderItem -> {
|
||||
// 获取该 SKU 的优惠信息
|
||||
Double memberDiscountPercent = memberDiscountPercentSupplier.get();
|
||||
DiscountProductDO discountProduct = discountProducts.get(orderItem.getSkuId());
|
||||
if (discountProduct != null // 假设优惠价格更贵,则认为没优惠
|
||||
&& discountProduct.getPromotionPrice() >= orderItem.getOriginalUnitPrice()) {
|
||||
discountProduct = null;
|
||||
}
|
||||
DiscountProductDetailBO discountProduct = discountProducts.get(orderItem.getSkuId());
|
||||
if (memberDiscountPercent == null && discountProduct == null) {
|
||||
return;
|
||||
}
|
||||
// 计算价格,判断选择哪个折扣
|
||||
Integer memberPrice = memberDiscountPercent != null ? (int) (orderItem.getPayPrice() * memberDiscountPercent / 100) : null;
|
||||
Integer promotionPrice = discountProduct != null ? discountProduct.getPromotionPrice() * orderItem.getCount() : null;
|
||||
Integer promotionPrice = discountProduct != null ? getDiscountProductPrice(discountProduct, orderItem) : null;
|
||||
if (memberPrice == null) {
|
||||
calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice);
|
||||
} else if (promotionPrice == null) {
|
||||
|
@ -145,6 +145,19 @@ public class PriceServiceImpl implements PriceService {
|
|||
});
|
||||
}
|
||||
|
||||
private Integer getDiscountProductPrice(DiscountProductDetailBO discountProduct,
|
||||
PriceCalculateRespDTO.OrderItem orderItem) {
|
||||
Integer price = orderItem.getPayPrice();
|
||||
if (PromotionDiscountTypeEnum.PRICE.getType().equals(discountProduct.getDiscountType())) { // 减价
|
||||
price -= discountProduct.getDiscountPrice() * orderItem.getCount();
|
||||
} else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(discountProduct.getDiscountType())) { // 打折
|
||||
price = price * discountProduct.getDiscountPercent() / 100;
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format("优惠活动的商品(%s) 的优惠类型不正确", discountProduct));
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
||||
private void calculatePriceByMemberDiscount(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem,
|
||||
Integer memberPrice) {
|
||||
// 记录优惠明细
|
||||
|
@ -156,7 +169,7 @@ public class PriceServiceImpl implements PriceService {
|
|||
}
|
||||
|
||||
private void calculatePriceByDiscountActivity(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem,
|
||||
DiscountProductDO discountProduct, Integer promotionPrice) {
|
||||
DiscountProductDetailBO discountProduct, Integer promotionPrice) {
|
||||
// 记录优惠明细
|
||||
addPromotion(priceCalculate, orderItem, discountProduct.getActivityId(), discountProduct.getActivityName(),
|
||||
PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), PromotionLevelEnum.SKU.getLevel(), promotionPrice,
|
||||
|
@ -191,7 +204,7 @@ public class PriceServiceImpl implements PriceService {
|
|||
private void calculatePriceForOrderLevel(Long userId, PriceCalculateRespDTO priceCalculate) {
|
||||
// 获取 SKU 级别的所有优惠信息
|
||||
Set<Long> spuIds = convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSpuId);
|
||||
Map<RewardActivityDO, Set<Long>> rewardActivities = rewardService.getMatchRewardActivities(spuIds);
|
||||
Map<RewardActivityDO, Set<Long>> rewardActivities = rewardActivityService.getMatchRewardActivities(spuIds);
|
||||
|
||||
// 处理满减送活动
|
||||
if (CollUtil.isNotEmpty(rewardActivities)) {
|
||||
|
@ -216,7 +229,6 @@ public class PriceServiceImpl implements PriceService {
|
|||
}
|
||||
|
||||
// 分摊金额
|
||||
// TODO 芋艿:limit 不能超过最大价格
|
||||
List<Integer> discountPartPrices = dividePrice(orderItems, rule.getDiscountPrice());
|
||||
// 记录优惠明细
|
||||
addPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(),
|
||||
|
@ -283,7 +295,7 @@ public class PriceServiceImpl implements PriceService {
|
|||
// 计算是否满足优惠劵的使用金额
|
||||
Integer originPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum);
|
||||
assert originPrice != null;
|
||||
if (originPrice < coupon.getPriceAvailable()) {
|
||||
if (originPrice < coupon.getUsePrice()) {
|
||||
throw exception(COUPON_NO_MATCH_MIN_PRICE);
|
||||
}
|
||||
|
||||
|
@ -291,10 +303,9 @@ public class PriceServiceImpl implements PriceService {
|
|||
priceCalculate.getOrder().setCouponId(couponId);
|
||||
Integer couponPrice = getCouponPrice(coupon, originPrice);
|
||||
// 分摊金额
|
||||
// TODO 芋艿:limit 不能超过最大价格
|
||||
List<Integer> couponPartPrices = dividePrice(orderItems, couponPrice);
|
||||
// 记录优惠明细
|
||||
addPromotion(priceCalculate, orderItems, coupon.getId(), coupon.getTitle(),
|
||||
addPromotion(priceCalculate, orderItems, coupon.getId(), coupon.getName(),
|
||||
PromotionTypeEnum.COUPON.getType(), PromotionLevelEnum.COUPON.getLevel(), couponPartPrices,
|
||||
true, StrUtil.format("优惠劵:省 {} 元", formatPrice(couponPrice)));
|
||||
// 修改 SKU 的分摊
|
||||
|
@ -309,19 +320,18 @@ public class PriceServiceImpl implements PriceService {
|
|||
return priceCalculate.getOrder().getItems();
|
||||
}
|
||||
return CollectionUtils.filterList(priceCalculate.getOrder().getItems(),
|
||||
orderItem -> coupon.getSpuIds().contains(orderItem.getSpuId()));
|
||||
orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId()));
|
||||
}
|
||||
|
||||
private Integer getCouponPrice(CouponDO coupon, Integer originPrice) {
|
||||
// TODO 芋艿 getPreferentialType 的枚举判断
|
||||
if (coupon.getPreferentialType().equals(1)) { // 减价
|
||||
return coupon.getPriceOff();
|
||||
} else if (coupon.getPreferentialType().equals(2)) { // 打折
|
||||
Integer couponPrice = originPrice * coupon.getPercentOff() / 100;
|
||||
return coupon.getDiscountPriceLimit() == null ? couponPrice
|
||||
: Math.min(couponPrice, coupon.getDiscountPriceLimit()); // 优惠上限
|
||||
if (PromotionDiscountTypeEnum.PRICE.getType().equals(coupon.getDiscountType())) { // 减价
|
||||
return coupon.getDiscountPrice();
|
||||
} else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(coupon.getDiscountType())) { // 打折
|
||||
int couponPrice = originPrice * coupon.getDiscountPercent() / 100;
|
||||
return coupon.getDiscountLimitPrice() == null ? couponPrice
|
||||
: Math.min(couponPrice, coupon.getDiscountLimitPrice()); // 优惠上限
|
||||
}
|
||||
throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon.toString()));
|
||||
throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon));
|
||||
}
|
||||
|
||||
// ========== 其它相对通用的方法 ==========
|
||||
|
@ -410,13 +420,16 @@ public class PriceServiceImpl implements PriceService {
|
|||
*/
|
||||
private void modifyOrderItemPayPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer newPayPrice,
|
||||
PriceCalculateRespDTO priceCalculate) {
|
||||
// diffPayPrice 等于额外增加的商品级的优惠
|
||||
int diffPayPrice = orderItem.getPayPrice() - newPayPrice;
|
||||
// 设置 OrderItem 价格相关字段
|
||||
orderItem.setDiscountPrice(orderItem.getDiscountPrice() + diffPayPrice);
|
||||
orderItem.setPayPrice(newPayPrice);
|
||||
orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice());
|
||||
// 设置 Order 相关相关字段
|
||||
priceCalculate.getOrder().setPayPrice(priceCalculate.getOrder().getPayPrice() - diffPayPrice);
|
||||
PriceCalculateRespDTO.Order order = priceCalculate.getOrder();
|
||||
order.setPayPrice(order.getPayPrice() - diffPayPrice);
|
||||
order.setOrderPrice(order.getOrderPrice() - diffPayPrice);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.reward;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 满减送活动 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface RewardActivityService {
|
||||
|
||||
/**
|
||||
* 创建满减送活动
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createRewardActivity(@Valid RewardActivityCreateReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新满减送活动
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateRewardActivity(@Valid RewardActivityUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 关闭满减送活动
|
||||
*
|
||||
* @param id 活动编号
|
||||
*/
|
||||
void closeRewardActivity(Long id);
|
||||
|
||||
/**
|
||||
* 删除满减送活动
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteRewardActivity(Long id);
|
||||
|
||||
/**
|
||||
* 获得满减送活动
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 满减送活动
|
||||
*/
|
||||
RewardActivityDO getRewardActivity(Long id);
|
||||
|
||||
/**
|
||||
* 获得满减送活动分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 满减送活动分页
|
||||
*/
|
||||
PageResult<RewardActivityDO> getRewardActivityPage(RewardActivityPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 基于指定的 SPU 编号数组,获得它们匹配的满减送活动
|
||||
*
|
||||
* @param spuIds SPU 编号数组
|
||||
* @return 满减送活动,与对应的 SPU 编号的映射。即,value 就是 SPU 编号的集合
|
||||
*/
|
||||
Map<RewardActivityDO, Set<Long>> getMatchRewardActivities(Set<Long> spuIds);
|
||||
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.reward;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.reward.RewardActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.reward.RewardActivityMapper;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.util.PromotionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.hutool.core.collection.CollUtil.intersectionDistinct;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singleton;
|
||||
|
||||
/**
|
||||
* 满减送活动 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class RewardActivityServiceImpl implements RewardActivityService {
|
||||
|
||||
@Resource
|
||||
private RewardActivityMapper rewardActivityMapper;
|
||||
|
||||
@Override
|
||||
public Long createRewardActivity(RewardActivityCreateReqVO createReqVO) {
|
||||
// 校验商品是否冲突
|
||||
validateRewardActivitySpuConflicts(null, createReqVO.getProductSpuIds());
|
||||
|
||||
// 插入
|
||||
RewardActivityDO rewardActivity = RewardActivityConvert.INSTANCE.convert(createReqVO)
|
||||
.setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime()));
|
||||
rewardActivityMapper.insert(rewardActivity);
|
||||
// 返回
|
||||
return rewardActivity.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRewardActivity(RewardActivityUpdateReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
RewardActivityDO dbRewardActivity = validateRewardActivityExists(updateReqVO.getId());
|
||||
if (dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能修改噢
|
||||
throw exception(REWARD_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED);
|
||||
}
|
||||
// 校验商品是否冲突
|
||||
validateRewardActivitySpuConflicts(updateReqVO.getId(), updateReqVO.getProductSpuIds());
|
||||
|
||||
// 更新
|
||||
RewardActivityDO updateObj = RewardActivityConvert.INSTANCE.convert(updateReqVO)
|
||||
.setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime()));
|
||||
rewardActivityMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeRewardActivity(Long id) {
|
||||
// 校验存在
|
||||
RewardActivityDO dbRewardActivity = validateRewardActivityExists(id);
|
||||
if (dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能关闭噢
|
||||
throw exception(REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED);
|
||||
}
|
||||
if (dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.END.getStatus())) { // 已关闭的活动,不能关闭噢
|
||||
throw exception(REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END);
|
||||
}
|
||||
|
||||
// 更新
|
||||
RewardActivityDO updateObj = new RewardActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus());
|
||||
rewardActivityMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRewardActivity(Long id) {
|
||||
// 校验存在
|
||||
RewardActivityDO dbRewardActivity = validateRewardActivityExists(id);
|
||||
if (!dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 未关闭的活动,不能删除噢
|
||||
throw exception(REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED);
|
||||
}
|
||||
|
||||
// 删除
|
||||
rewardActivityMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private RewardActivityDO validateRewardActivityExists(Long id) {
|
||||
RewardActivityDO activity = rewardActivityMapper.selectById(id);
|
||||
if (activity == null) {
|
||||
throw exception(REWARD_ACTIVITY_NOT_EXISTS);
|
||||
}
|
||||
return activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验商品参加的活动是否冲突
|
||||
*
|
||||
* @param id 活动编号
|
||||
* @param spuIds 商品 SPU 编号数组
|
||||
*/
|
||||
private void validateRewardActivitySpuConflicts(Long id, Collection<Long> spuIds) {
|
||||
if (CollUtil.isEmpty(spuIds)) {
|
||||
return;
|
||||
}
|
||||
// 查询商品参加的活动
|
||||
List<RewardActivityDO> rewardActivityList = getRewardActivityListBySpuIds(spuIds,
|
||||
asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus()));
|
||||
if (id != null) { // 排除自己这个活动
|
||||
rewardActivityList.removeIf(activity -> id.equals(activity.getId()));
|
||||
}
|
||||
// 如果非空,则说明冲突
|
||||
if (CollUtil.isNotEmpty(rewardActivityList)) {
|
||||
throw exception(REWARD_ACTIVITY_SPU_CONFLICTS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得商品参加的满减送活动的数组
|
||||
*
|
||||
* @param spuIds 商品 SPU 编号数组
|
||||
* @param statuses 活动状态数组
|
||||
* @return 商品参加的满减送活动的数组
|
||||
*/
|
||||
private List<RewardActivityDO> getRewardActivityListBySpuIds(Collection<Long> spuIds,
|
||||
Collection<Integer> statuses) {
|
||||
List<RewardActivityDO> list = rewardActivityMapper.selectListByStatus(statuses);
|
||||
return CollUtil.filter(list, activity -> CollUtil.containsAny(activity.getProductSpuIds(), spuIds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public RewardActivityDO getRewardActivity(Long id) {
|
||||
return rewardActivityMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<RewardActivityDO> getRewardActivityPage(RewardActivityPageReqVO pageReqVO) {
|
||||
return rewardActivityMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<RewardActivityDO, Set<Long>> getMatchRewardActivities(Set<Long> spuIds) {
|
||||
// 如果有全局活动,则直接选择它
|
||||
List<RewardActivityDO> allActivities = rewardActivityMapper.selectListByProductScopeAndStatus(
|
||||
PromotionProductScopeEnum.ALL.getScope(), PromotionActivityStatusEnum.RUN.getStatus());
|
||||
if (CollUtil.isNotEmpty(allActivities)) {
|
||||
return MapUtil.builder(allActivities.get(0), spuIds).build();
|
||||
}
|
||||
|
||||
// 查询某个活动参加的活动
|
||||
List<RewardActivityDO> productActivityList = getRewardActivityListBySpuIds(spuIds,
|
||||
singleton(PromotionActivityStatusEnum.RUN.getStatus()));
|
||||
return convertMap(productActivityList, activity -> activity,
|
||||
rewardActivityDO -> intersectionDistinct(rewardActivityDO.getProductSpuIds(), spuIds)); // 求交集返回
|
||||
}
|
||||
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.reward;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 满减送 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface RewardService {
|
||||
|
||||
/**
|
||||
* 基于指定的 SPU 编号数组,获得它们匹配的满减送活动
|
||||
*
|
||||
* @param spuIds SPU 编号数组
|
||||
* @return 满减送活动,与对应的 SPU 编号的映射。即,value 就是 SPU 编号的集合
|
||||
*/
|
||||
Map<RewardActivityDO, Set<Long>> getMatchRewardActivities(Set<Long> spuIds);
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.reward;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 满减送 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class RewardServiceImpl implements RewardService {
|
||||
|
||||
// TODO 芋艿:待实现
|
||||
@Override
|
||||
public Map<RewardActivityDO, Set<Long>> getMatchRewardActivities(Set<Long> spuIds) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package cn.iocoder.yudao.module.promotion.util;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 活动工具类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class PromotionUtils {
|
||||
|
||||
/**
|
||||
* 根据时间,计算活动状态
|
||||
*
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return 活动状态
|
||||
*/
|
||||
public static Integer calculateActivityStatus(Date startTime, Date endTime) {
|
||||
if (DateUtils.beforeNow(endTime)) {
|
||||
return PromotionActivityStatusEnum.END.getStatus();
|
||||
}
|
||||
if (DateUtils.afterNow(startTime)) {
|
||||
return PromotionActivityStatusEnum.WAIT.getStatus();
|
||||
}
|
||||
return PromotionActivityStatusEnum.RUN.getStatus();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper">
|
||||
|
||||
<update id="updateTakeCount">
|
||||
UPDATE promotion_coupon_template
|
||||
SET take_count = take_count + #{incrCount}
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
</mapper>
|
|
@ -1,19 +1,24 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.coupon;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
|
@ -39,7 +44,10 @@ public class CouponTemplateServiceImplTest extends BaseDbUnitTest {
|
|||
@Test
|
||||
public void testCreateCouponTemplate_success() {
|
||||
// 准备参数
|
||||
CouponTemplateCreateReqVO reqVO = randomPojo(CouponTemplateCreateReqVO.class);
|
||||
CouponTemplateCreateReqVO reqVO = randomPojo(CouponTemplateCreateReqVO.class,
|
||||
o -> o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope())
|
||||
.setValidityType(randomEle(CouponTemplateValidityTypeEnum.values()).getType())
|
||||
.setDiscountType(randomEle(PromotionDiscountTypeEnum.values()).getType()));
|
||||
|
||||
// 调用
|
||||
Long couponTemplateId = couponTemplateService.createCouponTemplate(reqVO);
|
||||
|
@ -58,6 +66,10 @@ public class CouponTemplateServiceImplTest extends BaseDbUnitTest {
|
|||
// 准备参数
|
||||
CouponTemplateUpdateReqVO reqVO = randomPojo(CouponTemplateUpdateReqVO.class, o -> {
|
||||
o.setId(dbCouponTemplate.getId()); // 设置更新的 ID
|
||||
// 其它通用字段
|
||||
o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope())
|
||||
.setValidityType(randomEle(CouponTemplateValidityTypeEnum.values()).getType())
|
||||
.setDiscountType(randomEle(PromotionDiscountTypeEnum.values()).getType());
|
||||
});
|
||||
|
||||
// 调用
|
||||
|
@ -100,30 +112,29 @@ public class CouponTemplateServiceImplTest extends BaseDbUnitTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||
public void testGetCouponTemplatePage() {
|
||||
// mock 数据
|
||||
CouponTemplateDO dbCouponTemplate = randomPojo(CouponTemplateDO.class, o -> { // 等会查询到
|
||||
o.setName(null);
|
||||
o.setStatus(null);
|
||||
o.setDiscountType(null);
|
||||
o.setCreateTime(null);
|
||||
o.setName("芋艿");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType());
|
||||
o.setCreateTime(buildTime(2022, 2, 2));
|
||||
});
|
||||
couponTemplateMapper.insert(dbCouponTemplate);
|
||||
// 测试 name 不匹配
|
||||
couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setName(null)));
|
||||
couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setName("土豆")));
|
||||
// 测试 status 不匹配
|
||||
couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setStatus(null)));
|
||||
couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 type 不匹配
|
||||
couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setDiscountType(null)));
|
||||
couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setDiscountType(PromotionDiscountTypeEnum.PRICE.getType())));
|
||||
// 测试 createTime 不匹配
|
||||
couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setCreateTime(null)));
|
||||
couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setCreateTime(buildTime(2022, 1, 1))));
|
||||
// 准备参数
|
||||
CouponTemplatePageReqVO reqVO = new CouponTemplatePageReqVO();
|
||||
reqVO.setName(null);
|
||||
reqVO.setStatus(null);
|
||||
reqVO.setDiscountType(null);
|
||||
reqVO.setCreateTime((new Date[]{}));
|
||||
reqVO.setName("芋艿");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType());
|
||||
reqVO.setCreateTime((new Date[]{buildTime(2022, 2, 1), buildTime(2022, 2, 3)}));
|
||||
|
||||
// 调用
|
||||
PageResult<CouponTemplateDO> pageResult = couponTemplateService.getCouponTemplatePage(reqVO);
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.discount;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountActivityMapper;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.addTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.DISCOUNT_ACTIVITY_NOT_EXISTS;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link DiscountActivityServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(DiscountActivityServiceImpl.class)
|
||||
public class DiscountActivityServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private DiscountActivityServiceImpl discountActivityService;
|
||||
|
||||
@Resource
|
||||
private DiscountActivityMapper discountActivityMapper;
|
||||
@Resource
|
||||
private DiscountProductMapper discountProductMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateDiscountActivity_success() {
|
||||
// 准备参数
|
||||
DiscountActivityCreateReqVO reqVO = randomPojo(DiscountActivityCreateReqVO.class, o -> {
|
||||
// 用于触发进行中的状态
|
||||
o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2)));
|
||||
// 设置商品
|
||||
o.setProducts(asList(new DiscountActivityBaseVO.Product().setSpuId(1L).setSkuId(2L)
|
||||
.setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(3),
|
||||
new DiscountActivityBaseVO.Product().setSpuId(10L).setSkuId(20L)
|
||||
.setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(30)));
|
||||
});
|
||||
|
||||
// 调用
|
||||
Long discountActivityId = discountActivityService.createDiscountActivity(reqVO);
|
||||
// 断言
|
||||
assertNotNull(discountActivityId);
|
||||
// 校验活动
|
||||
DiscountActivityDO discountActivity = discountActivityMapper.selectById(discountActivityId);
|
||||
assertPojoEquals(reqVO, discountActivity);
|
||||
assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus());
|
||||
// 校验商品
|
||||
List<DiscountProductDO> discountProducts = discountProductMapper.selectList(DiscountProductDO::getActivityId, discountActivity.getId());
|
||||
assertEquals(discountProducts.size(), reqVO.getProducts().size());
|
||||
for (int i = 0; i < reqVO.getProducts().size(); i++) {
|
||||
DiscountActivityBaseVO.Product product = reqVO.getProducts().get(i);
|
||||
DiscountProductDO discountProduct = discountProducts.get(i);
|
||||
assertEquals(discountProduct.getActivityId(), discountActivity.getId());
|
||||
assertEquals(discountProduct.getSpuId(), product.getSpuId());
|
||||
assertEquals(discountProduct.getSkuId(), product.getSkuId());
|
||||
assertEquals(discountProduct.getDiscountType(), product.getDiscountType());
|
||||
assertEquals(discountProduct.getDiscountPrice(), product.getDiscountPrice());
|
||||
assertEquals(discountProduct.getDiscountPercent(), product.getDiscountPercent());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDiscountActivity_success() {
|
||||
// mock 数据(商品)
|
||||
DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class);
|
||||
discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据
|
||||
// mock 数据(活动)
|
||||
DiscountProductDO dbDiscountProduct01 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(dbDiscountActivity.getId())
|
||||
.setSpuId(1L).setSkuId(2L).setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(3).setDiscountPercent(null));
|
||||
DiscountProductDO dbDiscountProduct02 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(dbDiscountActivity.getId())
|
||||
.setSpuId(10L).setSkuId(20L).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(30).setDiscountPrice(null));
|
||||
discountProductMapper.insert(dbDiscountProduct01);
|
||||
discountProductMapper.insert(dbDiscountProduct02);
|
||||
// 准备参数
|
||||
DiscountActivityUpdateReqVO reqVO = randomPojo(DiscountActivityUpdateReqVO.class, o -> {
|
||||
o.setId(dbDiscountActivity.getId()); // 设置更新的 ID
|
||||
// 用于触发进行中的状态
|
||||
o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2)));
|
||||
// 设置商品
|
||||
o.setProducts(asList(new DiscountActivityBaseVO.Product().setSpuId(1L).setSkuId(2L)
|
||||
.setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(3).setDiscountPercent(null),
|
||||
new DiscountActivityBaseVO.Product().setSpuId(100L).setSkuId(200L)
|
||||
.setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(30).setDiscountPrice(null)));
|
||||
});
|
||||
|
||||
// 调用
|
||||
discountActivityService.updateDiscountActivity(reqVO);
|
||||
// 校验活动
|
||||
DiscountActivityDO discountActivity = discountActivityMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, discountActivity);
|
||||
assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus());
|
||||
// 校验商品
|
||||
List<DiscountProductDO> discountProducts = discountProductMapper.selectList(DiscountProductDO::getActivityId, discountActivity.getId());
|
||||
assertEquals(discountProducts.size(), reqVO.getProducts().size());
|
||||
for (int i = 0; i < reqVO.getProducts().size(); i++) {
|
||||
DiscountActivityBaseVO.Product product = reqVO.getProducts().get(i);
|
||||
DiscountProductDO discountProduct = discountProducts.get(i);
|
||||
assertEquals(discountProduct.getActivityId(), discountActivity.getId());
|
||||
assertEquals(discountProduct.getSpuId(), product.getSpuId());
|
||||
assertEquals(discountProduct.getSkuId(), product.getSkuId());
|
||||
assertEquals(discountProduct.getDiscountType(), product.getDiscountType());
|
||||
assertEquals(discountProduct.getDiscountPrice(), product.getDiscountPrice());
|
||||
assertEquals(discountProduct.getDiscountPercent(), product.getDiscountPercent());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseDiscountActivity() {
|
||||
// mock 数据
|
||||
DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class,
|
||||
o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus()));
|
||||
discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbDiscountActivity.getId();
|
||||
|
||||
// 调用
|
||||
discountActivityService.closeRewardActivity(id);
|
||||
// 校验状态
|
||||
DiscountActivityDO discountActivity = discountActivityMapper.selectById(id);
|
||||
assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.CLOSE.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDiscountActivity_notExists() {
|
||||
// 准备参数
|
||||
DiscountActivityUpdateReqVO reqVO = randomPojo(DiscountActivityUpdateReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> discountActivityService.updateDiscountActivity(reqVO), DISCOUNT_ACTIVITY_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDiscountActivity_success() {
|
||||
// mock 数据
|
||||
DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class,
|
||||
o -> o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()));
|
||||
discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbDiscountActivity.getId();
|
||||
|
||||
// 调用
|
||||
discountActivityService.deleteDiscountActivity(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(discountActivityMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDiscountActivity_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> discountActivityService.deleteDiscountActivity(id), DISCOUNT_ACTIVITY_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDiscountActivityPage() {
|
||||
// mock 数据
|
||||
DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class, o -> { // 等会查询到
|
||||
o.setName("芋艿");
|
||||
o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus());
|
||||
o.setCreateTime(buildTime(2021, 1, 15));
|
||||
});
|
||||
discountActivityMapper.insert(dbDiscountActivity);
|
||||
// 测试 name 不匹配
|
||||
discountActivityMapper.insert(cloneIgnoreId(dbDiscountActivity, o -> o.setName("土豆")));
|
||||
// 测试 status 不匹配
|
||||
discountActivityMapper.insert(cloneIgnoreId(dbDiscountActivity, o -> o.setStatus(PromotionActivityStatusEnum.END.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
discountActivityMapper.insert(cloneIgnoreId(dbDiscountActivity, o -> o.setCreateTime(buildTime(2021, 2, 10))));
|
||||
// 准备参数
|
||||
DiscountActivityPageReqVO reqVO = new DiscountActivityPageReqVO();
|
||||
reqVO.setName("芋艿");
|
||||
reqVO.setStatus(PromotionActivityStatusEnum.WAIT.getStatus());
|
||||
reqVO.setCreateTime((new Date[]{buildTime(2021, 1, 1), buildTime(2021, 1, 31)}));
|
||||
|
||||
// 调用
|
||||
PageResult<DiscountActivityDO> pageResult = discountActivityService.getDiscountActivityPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbDiscountActivity, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
}
|
|
@ -2,20 +2,17 @@ package cn.iocoder.yudao.module.promotion.service.price;
|
|||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.*;
|
||||
import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
|
||||
import cn.iocoder.yudao.module.promotion.service.discount.DiscountService;
|
||||
import cn.iocoder.yudao.module.promotion.service.reward.RewardService;
|
||||
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService;
|
||||
import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO;
|
||||
import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
@ -44,9 +41,9 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
|
|||
private PriceServiceImpl priceService;
|
||||
|
||||
@Mock
|
||||
private DiscountService discountService;
|
||||
private DiscountActivityService discountService;
|
||||
@Mock
|
||||
private RewardService rewardService;
|
||||
private RewardActivityService rewardActivityService;
|
||||
@Mock
|
||||
private CouponService couponService;
|
||||
@Mock
|
||||
|
@ -67,6 +64,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
|
|||
// 断言 Order 部分
|
||||
PriceCalculateRespDTO.Order order = priceCalculate.getOrder();
|
||||
assertEquals(order.getOriginalPrice(), 200);
|
||||
assertEquals(order.getOrderPrice(), 180);
|
||||
assertEquals(order.getDiscountPrice(), 0);
|
||||
assertEquals(order.getPointPrice(), 0);
|
||||
assertEquals(order.getDeliveryPrice(), 0);
|
||||
|
@ -112,22 +110,28 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
|
|||
ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50));
|
||||
when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02));
|
||||
// mock 方法(限时折扣 DiscountActivity 信息)
|
||||
DiscountProductDO discountProduct01 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(1000L).setActivityName("活动 1000 号")
|
||||
.setSkuId(10L).setPromotionPrice(80));
|
||||
DiscountProductDO discountProduct02 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(2000L).setActivityName("活动 2000 号")
|
||||
.setSkuId(20L).setPromotionPrice(40));
|
||||
DiscountProductDetailBO discountProduct01 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(1000L)
|
||||
.setActivityName("活动 1000 号").setSkuId(10L)
|
||||
.setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(40));
|
||||
DiscountProductDetailBO discountProduct02 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(2000L)
|
||||
.setActivityName("活动 2000 号").setSkuId(20L)
|
||||
.setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(60));
|
||||
when(discountService.getMatchDiscountProducts(eq(asSet(10L, 20L)))).thenReturn(
|
||||
MapUtil.builder(10L, discountProduct01).put(20L, discountProduct02).map());
|
||||
|
||||
// 10L: 100 * 2 - 40 * 2 = 120
|
||||
// 20L:50 * 3 - 50 * 3 * 0.4 = 90
|
||||
|
||||
// 调用
|
||||
PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO);
|
||||
// 断言 Order 部分
|
||||
PriceCalculateRespDTO.Order order = priceCalculate.getOrder();
|
||||
assertEquals(order.getOriginalPrice(), 350);
|
||||
assertEquals(order.getOrderPrice(), 210);
|
||||
assertEquals(order.getDiscountPrice(), 0);
|
||||
assertEquals(order.getPointPrice(), 0);
|
||||
assertEquals(order.getDeliveryPrice(), 0);
|
||||
assertEquals(order.getPayPrice(), 280);
|
||||
assertEquals(order.getPayPrice(), 210);
|
||||
assertNull(order.getCouponId());
|
||||
// 断言 OrderItem 部分
|
||||
assertEquals(order.getItems().size(), 2);
|
||||
|
@ -136,19 +140,19 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
|
|||
assertEquals(orderItem01.getCount(), 2);
|
||||
assertEquals(orderItem01.getOriginalPrice(), 200);
|
||||
assertEquals(orderItem01.getOriginalUnitPrice(), 100);
|
||||
assertEquals(orderItem01.getDiscountPrice(), 40);
|
||||
assertEquals(orderItem01.getPayPrice(), 160);
|
||||
assertEquals(orderItem01.getDiscountPrice(), 80);
|
||||
assertEquals(orderItem01.getPayPrice(), 120);
|
||||
assertEquals(orderItem01.getOrderPartPrice(), 0);
|
||||
assertEquals(orderItem01.getOrderDividePrice(), 160);
|
||||
assertEquals(orderItem01.getOrderDividePrice(), 120);
|
||||
PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1);
|
||||
assertEquals(orderItem02.getSkuId(), 20L);
|
||||
assertEquals(orderItem02.getCount(), 3);
|
||||
assertEquals(orderItem02.getOriginalPrice(), 150);
|
||||
assertEquals(orderItem02.getOriginalUnitPrice(), 50);
|
||||
assertEquals(orderItem02.getDiscountPrice(), 30);
|
||||
assertEquals(orderItem02.getPayPrice(), 120);
|
||||
assertEquals(orderItem02.getDiscountPrice(), 60);
|
||||
assertEquals(orderItem02.getPayPrice(), 90);
|
||||
assertEquals(orderItem02.getOrderPartPrice(), 0);
|
||||
assertEquals(orderItem02.getOrderDividePrice(), 120);
|
||||
assertEquals(orderItem02.getOrderDividePrice(), 90);
|
||||
// 断言 Promotion 部分
|
||||
assertEquals(priceCalculate.getPromotions().size(), 2);
|
||||
PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0);
|
||||
|
@ -157,28 +161,28 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
|
|||
assertEquals(promotion01.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType());
|
||||
assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel());
|
||||
assertEquals(promotion01.getOriginalPrice(), 200);
|
||||
assertEquals(promotion01.getDiscountPrice(), 40);
|
||||
assertEquals(promotion01.getDiscountPrice(), 80);
|
||||
assertTrue(promotion01.getMeet());
|
||||
assertEquals(promotion01.getMeetTip(), "限时折扣:省 0.40 元");
|
||||
assertEquals(promotion01.getMeetTip(), "限时折扣:省 0.80 元");
|
||||
PriceCalculateRespDTO.PromotionItem promotionItem01 = promotion01.getItems().get(0);
|
||||
assertEquals(promotion01.getItems().size(), 1);
|
||||
assertEquals(promotionItem01.getSkuId(), 10L);
|
||||
assertEquals(promotionItem01.getOriginalPrice(), 200);
|
||||
assertEquals(promotionItem01.getDiscountPrice(), 40);
|
||||
assertEquals(promotionItem01.getDiscountPrice(), 80);
|
||||
PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1);
|
||||
assertEquals(promotion02.getId(), 2000L);
|
||||
assertEquals(promotion02.getName(), "活动 2000 号");
|
||||
assertEquals(promotion02.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType());
|
||||
assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel());
|
||||
assertEquals(promotion02.getOriginalPrice(), 150);
|
||||
assertEquals(promotion02.getDiscountPrice(), 30);
|
||||
assertEquals(promotion02.getDiscountPrice(), 60);
|
||||
assertTrue(promotion02.getMeet());
|
||||
assertEquals(promotion02.getMeetTip(), "限时折扣:省 0.30 元");
|
||||
assertEquals(promotion02.getMeetTip(), "限时折扣:省 0.60 元");
|
||||
PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0);
|
||||
assertEquals(promotion02.getItems().size(), 1);
|
||||
assertEquals(promotionItem02.getSkuId(), 20L);
|
||||
assertEquals(promotionItem02.getOriginalPrice(), 150);
|
||||
assertEquals(promotionItem02.getDiscountPrice(), 30);
|
||||
assertEquals(promotionItem02.getDiscountPrice(), 60);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,13 +212,14 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
|
|||
Map<RewardActivityDO, Set<Long>> matchRewardActivities = new LinkedHashMap<>();
|
||||
matchRewardActivities.put(rewardActivity01, asSet(1L, 2L));
|
||||
matchRewardActivities.put(rewardActivity02, asSet(3L));
|
||||
when(rewardService.getMatchRewardActivities(eq(asSet(1L, 2L, 3L)))).thenReturn(matchRewardActivities);
|
||||
when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L, 3L)))).thenReturn(matchRewardActivities);
|
||||
|
||||
// 调用
|
||||
PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO);
|
||||
// 断言 Order 部分
|
||||
PriceCalculateRespDTO.Order order = priceCalculate.getOrder();
|
||||
assertEquals(order.getOriginalPrice(), 470);
|
||||
assertEquals(order.getOrderPrice(), 470);
|
||||
assertEquals(order.getDiscountPrice(), 130);
|
||||
assertEquals(order.getPointPrice(), 0);
|
||||
assertEquals(order.getDeliveryPrice(), 0);
|
||||
|
@ -305,13 +310,14 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
|
|||
.setRules(singletonList(new RewardActivityDO.Rule().setLimit(351).setDiscountPrice(70))));
|
||||
Map<RewardActivityDO, Set<Long>> matchRewardActivities = new LinkedHashMap<>();
|
||||
matchRewardActivities.put(rewardActivity01, asSet(1L, 2L));
|
||||
when(rewardService.getMatchRewardActivities(eq(asSet(1L, 2L)))).thenReturn(matchRewardActivities);
|
||||
when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L)))).thenReturn(matchRewardActivities);
|
||||
|
||||
// 调用
|
||||
PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO);
|
||||
// 断言 Order 部分
|
||||
PriceCalculateRespDTO.Order order = priceCalculate.getOrder();
|
||||
assertEquals(order.getOriginalPrice(), 350);
|
||||
assertEquals(order.getOrderPrice(), 350);
|
||||
assertEquals(order.getDiscountPrice(), 0);
|
||||
assertEquals(order.getPointPrice(), 0);
|
||||
assertEquals(order.getDeliveryPrice(), 0);
|
||||
|
@ -373,19 +379,18 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
|
|||
ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L));
|
||||
when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03));
|
||||
// mock 方法(优惠劵 Coupon 信息)
|
||||
CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setTitle("程序员节")
|
||||
.setProductScope(PromotionProductScopeEnum.SPU.getScope()).setSpuIds(asList(1L, 2L))
|
||||
.setPriceAvailable(350).setPreferentialType(2).setPercentOff(50).setDiscountPriceLimit(70));
|
||||
CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setName("程序员节")
|
||||
.setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L))
|
||||
.setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType())
|
||||
.setDiscountPercent(50).setDiscountLimitPrice(70));
|
||||
when(couponService.validCoupon(eq(1024L), eq(calculateReqDTO.getUserId()))).thenReturn(coupon);
|
||||
|
||||
// 200 + 150; 350
|
||||
//
|
||||
|
||||
// 调用
|
||||
PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO);
|
||||
// 断言 Order 部分
|
||||
PriceCalculateRespDTO.Order order = priceCalculate.getOrder();
|
||||
assertEquals(order.getOriginalPrice(), 470);
|
||||
assertEquals(order.getOrderPrice(), 470);
|
||||
assertEquals(order.getDiscountPrice(), 0);
|
||||
assertEquals(order.getPointPrice(), 0);
|
||||
assertEquals(order.getDeliveryPrice(), 0);
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
package cn.iocoder.yudao.module.promotion.service.reward;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.mysql.reward.RewardActivityMapper;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum;
|
||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.addTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.REWARD_ACTIVITY_NOT_EXISTS;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link RewardActivityServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(RewardActivityServiceImpl.class)
|
||||
public class RewardActivityServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private RewardActivityServiceImpl rewardActivityService;
|
||||
|
||||
@Resource
|
||||
private RewardActivityMapper rewardActivityMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateRewardActivity_success() {
|
||||
// 准备参数
|
||||
RewardActivityCreateReqVO reqVO = randomPojo(RewardActivityCreateReqVO.class, o -> {
|
||||
o.setConditionType(randomEle(PromotionConditionTypeEnum.values()).getType());
|
||||
o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope());
|
||||
// 用于触发进行中的状态
|
||||
o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2)));
|
||||
});
|
||||
|
||||
// 调用
|
||||
Long rewardActivityId = rewardActivityService.createRewardActivity(reqVO);
|
||||
// 断言
|
||||
assertNotNull(rewardActivityId);
|
||||
// 校验记录的属性是否正确
|
||||
RewardActivityDO rewardActivity = rewardActivityMapper.selectById(rewardActivityId);
|
||||
assertPojoEquals(reqVO, rewardActivity, "rules");
|
||||
assertEquals(rewardActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus());
|
||||
for (int i = 0; i < reqVO.getRules().size(); i++) {
|
||||
assertPojoEquals(reqVO.getRules().get(i), rewardActivity.getRules().get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateRewardActivity_success() {
|
||||
// mock 数据
|
||||
RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus()));
|
||||
rewardActivityMapper.insert(dbRewardActivity);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
RewardActivityUpdateReqVO reqVO = randomPojo(RewardActivityUpdateReqVO.class, o -> {
|
||||
o.setId(dbRewardActivity.getId()); // 设置更新的 ID
|
||||
o.setConditionType(randomEle(PromotionConditionTypeEnum.values()).getType());
|
||||
o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope());
|
||||
// 用于触发进行中的状态
|
||||
o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2)));
|
||||
});
|
||||
|
||||
// 调用
|
||||
rewardActivityService.updateRewardActivity(reqVO);
|
||||
// 校验是否更新正确
|
||||
RewardActivityDO rewardActivity = rewardActivityMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, rewardActivity, "rules");
|
||||
assertEquals(rewardActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus());
|
||||
for (int i = 0; i < reqVO.getRules().size(); i++) {
|
||||
assertPojoEquals(reqVO.getRules().get(i), rewardActivity.getRules().get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseRewardActivity() {
|
||||
// mock 数据
|
||||
RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus()));
|
||||
rewardActivityMapper.insert(dbRewardActivity);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbRewardActivity.getId();
|
||||
|
||||
// 调用
|
||||
rewardActivityService.closeRewardActivity(id);
|
||||
// 校验状态
|
||||
RewardActivityDO rewardActivity = rewardActivityMapper.selectById(id);
|
||||
assertEquals(rewardActivity.getStatus(), PromotionActivityStatusEnum.CLOSE.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateRewardActivity_notExists() {
|
||||
// 准备参数
|
||||
RewardActivityUpdateReqVO reqVO = randomPojo(RewardActivityUpdateReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> rewardActivityService.updateRewardActivity(reqVO), REWARD_ACTIVITY_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteRewardActivity_success() {
|
||||
// mock 数据
|
||||
RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()));
|
||||
rewardActivityMapper.insert(dbRewardActivity);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbRewardActivity.getId();
|
||||
|
||||
// 调用
|
||||
rewardActivityService.deleteRewardActivity(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(rewardActivityMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteRewardActivity_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> rewardActivityService.deleteRewardActivity(id), REWARD_ACTIVITY_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRewardActivityPage() {
|
||||
// mock 数据
|
||||
RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> { // 等会查询到
|
||||
o.setName("芋艿");
|
||||
o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus());
|
||||
});
|
||||
rewardActivityMapper.insert(dbRewardActivity);
|
||||
// 测试 name 不匹配
|
||||
rewardActivityMapper.insert(cloneIgnoreId(dbRewardActivity, o -> o.setName("土豆")));
|
||||
// 测试 status 不匹配
|
||||
rewardActivityMapper.insert(cloneIgnoreId(dbRewardActivity, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus())));
|
||||
// 准备参数
|
||||
RewardActivityPageReqVO reqVO = new RewardActivityPageReqVO();
|
||||
reqVO.setName("芋艿");
|
||||
reqVO.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus());
|
||||
|
||||
// 调用
|
||||
PageResult<RewardActivityDO> pageResult = rewardActivityService.getRewardActivityPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbRewardActivity, pageResult.getList().get(0), "rules");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRewardActivities_all() {
|
||||
// mock 数据
|
||||
RewardActivityDO allActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus())
|
||||
.setProductScope(PromotionProductScopeEnum.ALL.getScope()));
|
||||
rewardActivityMapper.insert(allActivity);
|
||||
RewardActivityDO productActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus())
|
||||
.setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L)));
|
||||
rewardActivityMapper.insert(productActivity);
|
||||
// 准备参数
|
||||
Set<Long> spuIds = asSet(1L, 2L);
|
||||
|
||||
// 调用
|
||||
Map<RewardActivityDO, Set<Long>> matchRewardActivities = rewardActivityService.getMatchRewardActivities(spuIds);
|
||||
// 断言
|
||||
assertEquals(matchRewardActivities.size(), 1);
|
||||
Map.Entry<RewardActivityDO, Set<Long>> next = matchRewardActivities.entrySet().iterator().next();
|
||||
assertPojoEquals(next.getKey(), allActivity);
|
||||
assertEquals(next.getValue(), spuIds);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRewardActivities_product() {
|
||||
// mock 数据
|
||||
RewardActivityDO productActivity01 = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus())
|
||||
.setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L)));
|
||||
rewardActivityMapper.insert(productActivity01);
|
||||
RewardActivityDO productActivity02 = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus())
|
||||
.setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(singletonList(3L)));
|
||||
rewardActivityMapper.insert(productActivity02);
|
||||
// 准备参数
|
||||
Set<Long> spuIds = asSet(1L, 2L, 3L);
|
||||
|
||||
// 调用
|
||||
Map<RewardActivityDO, Set<Long>> matchRewardActivities = rewardActivityService.getMatchRewardActivities(spuIds);
|
||||
// 断言
|
||||
assertEquals(matchRewardActivities.size(), 2);
|
||||
matchRewardActivities.forEach((activity, activitySpuIds) -> {
|
||||
if (activity.getId().equals(productActivity01.getId())) {
|
||||
assertPojoEquals(activity, productActivity01);
|
||||
assertEquals(activitySpuIds, asSet(1L, 2L));
|
||||
} else if (activity.getId().equals(productActivity02.getId())) {
|
||||
assertPojoEquals(activity, productActivity02);
|
||||
assertEquals(activitySpuIds, asSet(3L));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1 +1,6 @@
|
|||
DELETE FROM "market_activity";
|
||||
DELETE FROM "promotion_coupon_template";
|
||||
DELETE FROM "promotion_coupon";
|
||||
DELETE FROM "promotion_reward_activity";
|
||||
DELETE FROM "promotion_discount_activity";
|
||||
DELETE FROM "promotion_discount_product";
|
||||
|
|
|
@ -16,4 +16,109 @@ CREATE TABLE IF NOT EXISTS "market_activity" (
|
|||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
"tenant_id" bigint(20) NOT NULL,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '促销活动';
|
||||
) COMMENT '促销活动';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "promotion_coupon_template" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar NOT NULL,
|
||||
"status" int NOT NULL,
|
||||
"total_count" int NOT NULL,
|
||||
"take_limit_count" int NOT NULL,
|
||||
"take_type" int NOT NULL,
|
||||
"use_price" int NOT NULL,
|
||||
"product_scope" int NOT NULL,
|
||||
"product_spu_ids" varchar,
|
||||
"validity_type" int NOT NULL,
|
||||
"valid_start_time" datetime,
|
||||
"valid_end_time" datetime,
|
||||
"fixed_start_term" int,
|
||||
"fixed_end_term" int,
|
||||
"discount_type" int NOT NULL,
|
||||
"discount_percent" int,
|
||||
"discount_price" int,
|
||||
"discount_limit_price" int,
|
||||
"take_count" int NOT NULL DEFAULT 0,
|
||||
"use_count" int NOT NULL DEFAULT 0,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '优惠劵模板';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "promotion_coupon" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"template_id" bigint NOT NULL,
|
||||
"name" varchar NOT NULL,
|
||||
"status" int NOT NULL,
|
||||
"user_id" bigint NOT NULL,
|
||||
"take_type" int NOT NULL,
|
||||
"useprice" int NOT NULL,
|
||||
"valid_start_time" datetime NOT NULL,
|
||||
"valid_end_time" datetime NOT NULL,
|
||||
"product_scope" int NOT NULL,
|
||||
"product_spu_ids" varchar,
|
||||
"discount_type" int NOT NULL,
|
||||
"discount_percent" int,
|
||||
"discount_price" int,
|
||||
"discount_limit_price" int,
|
||||
"use_order_id" bigint,
|
||||
"use_time" datetime,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '优惠劵';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "promotion_reward_activity" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar NOT NULL,
|
||||
"status" int NOT NULL,
|
||||
"start_time" datetime NOT NULL,
|
||||
"end_time" datetime NOT NULL,
|
||||
"remark" varchar,
|
||||
"condition_type" int NOT NULL,
|
||||
"product_scope" int NOT NULL,
|
||||
"product_spu_ids" varchar,
|
||||
"rules" varchar,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '满减送活动';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "promotion_discount_activity" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"name" varchar NOT NULL,
|
||||
"status" int NOT NULL,
|
||||
"start_time" datetime NOT NULL,
|
||||
"end_time" datetime NOT NULL,
|
||||
"remark" varchar,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '限时折扣活动';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "promotion_discount_product" (
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"activity_id" bigint NOT NULL,
|
||||
"spu_id" bigint NOT NULL,
|
||||
"sku_id" bigint NOT NULL,
|
||||
"discount_type" int NOT NULL,
|
||||
"discount_percent" int,
|
||||
"discount_price" int,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '限时折扣活动';
|
||||
|
|
|
@ -43,13 +43,12 @@ public class AppTradeOrderController {
|
|||
@PreAuthenticated
|
||||
public CommonResult<Long> createTradeOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO,
|
||||
HttpServletRequest servletRequest) {
|
||||
// 获取登录用户
|
||||
// 获取登录用户、用户 IP 地址
|
||||
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
|
||||
// 获取用户ip地址
|
||||
String clientIp = ServletUtil.getClientIP(servletRequest);
|
||||
// 创建交易订单,预支付记录
|
||||
Long result = tradeOrderService.createTradeOrder(loginUserId, clientIp, createReqVO);
|
||||
return CommonResult.success(result);
|
||||
Long orderId = tradeOrderService.createTradeOrder(loginUserId, clientIp, createReqVO);
|
||||
return CommonResult.success(orderId);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
|
|
|
@ -19,7 +19,7 @@ public class AppTradeOrderCreateReqVO {
|
|||
@ApiModelProperty(name = "优惠劵编号", example = "1024")
|
||||
private Long couponId;
|
||||
|
||||
@ApiModelProperty(name = "备注", example = "1024")
|
||||
@ApiModelProperty(name = "备注", example = "这个是我的订单哟")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(name = "是否来自购物车", required = true, example = "true", notes = "true - 来自购物车;false - 立即购买")
|
||||
|
|
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order;
|
|||
|
||||
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO.OrderItem;
|
||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum;
|
||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderRefundStatusEnum;
|
||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
|
||||
|
@ -74,7 +75,7 @@ public class TradeOrderDO extends BaseDO {
|
|||
/**
|
||||
* 购买的商品数量
|
||||
*/
|
||||
private Integer productCount; // total_num
|
||||
private Integer productCount;
|
||||
/**
|
||||
* 订单完成时间
|
||||
*/
|
||||
|
@ -116,14 +117,25 @@ public class TradeOrderDO extends BaseDO {
|
|||
* 商品原价(总),单位:分
|
||||
*
|
||||
* 基于 {@link TradeOrderItemDO#getTotalOriginalPrice()} 求和
|
||||
*
|
||||
* 对应 taobao 的 trade.total_fee 字段
|
||||
*/
|
||||
private Integer originalPrice;
|
||||
/**
|
||||
* 订单原价(总),单位:分
|
||||
*
|
||||
* 基于 {@link OrderItem#getPayPrice()} 求和
|
||||
* 和 {@link #originalPrice} 的差异:去除商品级优惠
|
||||
*/
|
||||
private Integer orderPrice;
|
||||
/**
|
||||
* 订单优惠(总),单位:分
|
||||
*
|
||||
* 例如说:满减折扣;不包括优惠劵、商品优惠(TODO)
|
||||
* 订单级优惠:对主订单的优惠,常见如:订单满 200 元减 10 元;订单满 80 包邮。
|
||||
*
|
||||
* 对应 taobao 的 order.discount_fee 字段
|
||||
*/
|
||||
private Integer promotionPrice;
|
||||
private Integer discountPrice;
|
||||
/**
|
||||
* 运费金额,单位:分
|
||||
*/
|
||||
|
@ -137,12 +149,12 @@ public class TradeOrderDO extends BaseDO {
|
|||
/**
|
||||
* 应付金额(总),单位:分
|
||||
*
|
||||
* = {@link #originalPrice}
|
||||
* + {@link #deliveryPrice}
|
||||
* + {@link #adjustPrice}
|
||||
* - {@link #promotionPrice}
|
||||
* = {@link OrderItem#getPayPrice()} 求和
|
||||
* - {@link #couponPrice}
|
||||
* - {@link #pointPrice}
|
||||
* + {@link #deliveryPrice}
|
||||
* - {@link #discountPrice}
|
||||
* + {@link #adjustPrice}
|
||||
*/
|
||||
private Integer payPrice;
|
||||
/**
|
||||
|
@ -164,11 +176,11 @@ public class TradeOrderDO extends BaseDO {
|
|||
*
|
||||
* 关联 DeliveryTemplateDO 的 id 编号
|
||||
*/
|
||||
private Long deliveryTemplateId; // dvy_id
|
||||
private Long deliveryTemplateId;
|
||||
/**
|
||||
* 物流公司单号
|
||||
*/
|
||||
private String expressNo; // dvy_flow_id
|
||||
private String expressNo;
|
||||
/**
|
||||
* 发货状态
|
||||
*
|
||||
|
@ -227,10 +239,14 @@ public class TradeOrderDO extends BaseDO {
|
|||
private Long couponId;
|
||||
/**
|
||||
* 优惠劵减免金额,单位:分
|
||||
*
|
||||
* 对应 taobao 的 trade.coupon_fee 字段
|
||||
*/
|
||||
private Integer couponPrice;
|
||||
/**
|
||||
* 积分抵扣的金额,单位:分
|
||||
*
|
||||
* 对应 taobao 的 trade.point_fee 字段
|
||||
*/
|
||||
private Integer pointPrice;
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ public class TradeOrderItemDO extends BaseDO {
|
|||
*/
|
||||
private Integer count;
|
||||
/**
|
||||
* 是否评论
|
||||
* 是否评论 TODO
|
||||
*
|
||||
* false - 未评论
|
||||
* true - 已评论
|
||||
|
@ -79,61 +79,61 @@ public class TradeOrderItemDO extends BaseDO {
|
|||
private Boolean commented;
|
||||
|
||||
// ========== 价格 + 支付基本信息 ==========
|
||||
|
||||
/**
|
||||
* 商品原价(总),单位:分
|
||||
*
|
||||
* = {@link #originalUnitPrice} * {@link #getCount()}
|
||||
*/
|
||||
private Integer originalPrice;
|
||||
/**
|
||||
* 商品原价(单),单位:分
|
||||
*
|
||||
* 对应 ProductSkuDO 的 price 字段
|
||||
* 对应 taobao 的 order.price 字段
|
||||
*/
|
||||
// like - original_price;niu - costPrice
|
||||
private Integer originalPrice;
|
||||
private Integer originalUnitPrice;
|
||||
/**
|
||||
* 商品原价(总),单位:分
|
||||
* 商品优惠(总),单位:分
|
||||
*
|
||||
* = {@link #originalPrice} * {@link #count}
|
||||
*/
|
||||
// like - total_price;niu - 暂无
|
||||
private Integer totalOriginalPrice;
|
||||
/**
|
||||
* 商品级优惠(总),单位:分
|
||||
* 商品级优惠:对单个商品的,常见如:商品原价的 8 折;商品原价的减 50 元
|
||||
*
|
||||
* 例如说“限时折扣”:商品原价的 8 折;商品原价的减 50 元
|
||||
* 对应 taobao 的 order.discount_fee 字段
|
||||
*/
|
||||
// taobao - order.discount_fee(子订单商品优惠)
|
||||
private Integer totalPromotionPrice;
|
||||
private Integer discountPrice;
|
||||
/**
|
||||
* 最终购买金额(单),单位:分。
|
||||
* 子订单实付金额,不算主订单分摊金额,单位:分
|
||||
*
|
||||
* = {@link #totalPresentPrice} / {@link #count}
|
||||
*/
|
||||
private Integer presentPrice;
|
||||
/**
|
||||
* 最终购买金额(总),单位:分。
|
||||
* = {@link #originalPrice}
|
||||
* - {@link #discountPrice}
|
||||
*
|
||||
* = {@link #totalOriginalPrice}
|
||||
* - {@link #totalPromotionPrice}
|
||||
* 对应 taobao 的 order.payment 字段
|
||||
*/
|
||||
// like - total_pay_price;niu - goods_money; taobao - order.payment(子订单实付金额,不算主订单分摊金额) | order.total_fee(子订单应付金额,参考使用)
|
||||
private Integer totalPresentPrice;
|
||||
// TODO 芋艿:part_mjz_discount(子订单分摊金额);本质上,totalOriginalPrice - totalPayPrice
|
||||
private Integer payPrice;
|
||||
|
||||
/**
|
||||
* 应付金额(总),单位:分
|
||||
* 子订单分摊金额(总),单位:分
|
||||
* 需要分摊 {@link TradeOrderDO#getDiscountPrice()}、{@link TradeOrderDO#getCouponPrice()}、{@link TradeOrderDO#getPointPrice()}
|
||||
*
|
||||
* 对应 taobao 的 order.part_mjz_discount 字段
|
||||
* 淘宝说明:子订单分摊优惠基础逻辑:一般正常优惠券和满减优惠按照子订单的金额进行分摊,特殊情况如果优惠券是指定商品使用的,只会分摊到对应商品子订单上不分摊。
|
||||
*/
|
||||
// taobao - divide_order_fee (分摊后子订单实付金额);
|
||||
private Integer totalPayPrice;
|
||||
private Integer orderPartPrice;
|
||||
/**
|
||||
* 分摊后子订单实付金额(总),单位:分
|
||||
*
|
||||
* = {@link #payPrice}
|
||||
* - {@link #orderPartPrice}
|
||||
*
|
||||
* 对应 taobao 的 divide_order_fee 字段
|
||||
*/
|
||||
private Integer orderDividePrice;
|
||||
|
||||
// ========== 营销基本信息 ==========
|
||||
// /**
|
||||
// * 积分抵扣的金额,单位:分
|
||||
// */
|
||||
// private Integer integralTotal; // like - integral_price;niu - point_money
|
||||
// /**
|
||||
// * 使用的积分
|
||||
// */
|
||||
// private Integer useIntegral; // niu - use_point
|
||||
|
||||
// ========== 退款基本信息 ==========
|
||||
/**
|
||||
* 退款状态
|
||||
* 退款状态 TODO
|
||||
*
|
||||
* 枚举 {@link TradeOrderItemRefundStatusEnum}
|
||||
*/
|
||||
|
@ -148,7 +148,7 @@ public class TradeOrderItemDO extends BaseDO {
|
|||
// presentTotal = buyTotal - discountTotal = 24 - 11 = 13
|
||||
// 最终 presentPrice = presentTotal / stock = 13 / 3 = 4.33
|
||||
/**
|
||||
* 退款总金额,单位:分
|
||||
* 退款总金额,单位:分 TODO
|
||||
*/
|
||||
private Integer refundTotal;
|
||||
|
||||
|
@ -173,42 +173,5 @@ public class TradeOrderItemDO extends BaseDO {
|
|||
|
||||
}
|
||||
|
||||
// TODO 芋艿:basket_date 加入购物车时间;
|
||||
// TODO 芋艿:distribution_card_no 推广员使用的推销卡号
|
||||
|
||||
// TODO 待确定:mf
|
||||
// TODO give_integral:赠送积分
|
||||
// TODO is_reply:是否评价,0-未评价,1-已评价
|
||||
// TODO is_sub:是否单独分佣,0-否,1-是
|
||||
// TODO vip_price:会员价
|
||||
// TODO product_type:商品类型:0-普通,1-秒杀,2-砍价,3-拼团,4-视频号
|
||||
|
||||
// TODO 待确定:lf
|
||||
// TODO integral_price:积分抵扣的金额
|
||||
// TODO member_price:会员价格
|
||||
// TODO is_member:是否为会员折扣;0-不是;1-是
|
||||
// TODO member_discount:会员折扣(百分比)
|
||||
|
||||
// TODO goods_info 商品信息
|
||||
|
||||
// TODO integral_price:积分抵扣的金额
|
||||
|
||||
// TODO 待确定:niu
|
||||
// TODO is_virtual '是否是虚拟商品'
|
||||
// TODO goods_class '商品种类(1.实物 2.虚拟3.卡券)'
|
||||
// TODO adjust_money ''调整金额''
|
||||
|
||||
// TODO is_fenxiao 是否分销,
|
||||
// TODO adjust_money 是否分销,
|
||||
|
||||
// TODO delivery_status '配送状态'
|
||||
// TODO delivery_no ''配送单号''
|
||||
// TODO gift_flag '赠品标识'
|
||||
// TODO gift_flag '赠品标识'
|
||||
|
||||
// TODO refund_status '退款状态'
|
||||
// TODO refund_type '退款状态'
|
||||
// TODO 一堆退款字段
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -3,18 +3,20 @@ package cn.iocoder.yudao.module.trade.service.order;
|
|||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO;
|
||||
|
||||
/**
|
||||
* TODO @LeeYan9: 类注释
|
||||
* 交易订单 Service 接口
|
||||
*
|
||||
* @author LeeYan9
|
||||
* @since 2022-08-26
|
||||
*/
|
||||
public interface TradeOrderService {
|
||||
|
||||
/**
|
||||
* 创建交易订单 TODO @LeeYan9: 方法注释, 和参数要空一行
|
||||
* 创建交易订单
|
||||
*
|
||||
* @param loginUserId 登录用户
|
||||
* @param clientIp 用户ip地址 // TODO @LeeYan9: 中英文之间, 空一行哈
|
||||
* @param clientIp 用户 IP 地址
|
||||
* @param createReqVO 创建交易订单请求模型
|
||||
* @return 交易订单创建结果
|
||||
* @return 交易订单的编号
|
||||
*/
|
||||
Long createTradeOrder(Long loginUserId, String clientIp, AppTradeOrderCreateReqVO createReqVO);
|
||||
}
|
||||
|
|
|
@ -45,14 +45,17 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* TODO @LeeYan9: 注释
|
||||
* 交易订单 Service 实现类
|
||||
*
|
||||
* @author LeeYan9
|
||||
* @since 2022-08-26
|
||||
*/
|
||||
@Service
|
||||
public class TradeOrderServiceImpl implements TradeOrderService {
|
||||
|
||||
// TODO @LeeYan9: 相同类型的, 可以放在一起,不用空行; 例如说 Mapper 和 API 和 Properties
|
||||
// TODO LeeYan9: 静态变量, 需要在最前面哈; 另外, 静态变量的注释最好写下;
|
||||
private static final String BLANK_PLACEHOLDER = " ";
|
||||
private static final String MULTIPLIER_PLACEHOLDER = "x";
|
||||
|
||||
@Resource
|
||||
private TradeOrderMapper tradeOrderMapper;
|
||||
|
@ -71,15 +74,10 @@ public class TradeOrderServiceImpl implements TradeOrderService {
|
|||
@Resource
|
||||
private TradeOrderProperties tradeOrderProperties;
|
||||
|
||||
// TODO LeeYan9: 静态变量, 需要在最前面哈; 另外, 静态变量的注释最好写下;
|
||||
private static final String BLANK_PLACEHOLDER = " ";
|
||||
private static final String MULTIPLIER_PLACEHOLDER = "x";
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createTradeOrder(Long loginUserId, String clientIp, AppTradeOrderCreateReqVO createReqVO) {
|
||||
|
||||
List<Item> items = createReqVO.getItems(); // TODO @LeeYan9: 方法第一行, 不用空哈;
|
||||
List<Item> items = createReqVO.getItems();
|
||||
// 商品SKU检查 sku可售状态,库存
|
||||
List<ProductSkuRespDTO> skuInfos = productSkuApi.getSkuList(CollectionUtils.convertSet(items, Item::getSkuId));
|
||||
Map<Long, ProductSkuRespDTO> skuInfoMap = CollectionUtils.convertMap(skuInfos, ProductSkuRespDTO::getId);
|
||||
|
|
|
@ -2,6 +2,12 @@ package cn.iocoder.yudao.module.member.api.user;
|
|||
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
|
||||
/**
|
||||
* 会员用户的 API 接口
|
||||
*
|
||||
|
@ -17,4 +23,30 @@ public interface MemberUserApi {
|
|||
*/
|
||||
UserRespDTO getUser(Long id);
|
||||
|
||||
/**
|
||||
* 获得会员用户信息们
|
||||
*
|
||||
* @param ids 用户编号的数组
|
||||
* @return 用户信息们
|
||||
*/
|
||||
List<UserRespDTO> getUsers(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得会员用户 Map
|
||||
*
|
||||
* @param ids 用户编号的数组
|
||||
* @return 会员用户 Map
|
||||
*/
|
||||
default Map<Long, UserRespDTO> getUserMap(Collection<Long> ids) {
|
||||
return convertMap(getUsers(ids), UserRespDTO::getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 基于用户昵称,模糊匹配用户列表
|
||||
*
|
||||
* @param nickname 用户昵称,模糊匹配
|
||||
* @return 用户信息的列表
|
||||
*/
|
||||
List<UserRespDTO> getUserListByNickname(String nickname);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
package cn.iocoder.yudao.module.member.api.user.dto;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户信息 Response DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class UserInfoDTO {
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String nickname;
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 帐号状态
|
||||
*
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 手机
|
||||
*/
|
||||
private String mobile;
|
||||
/**
|
||||
* 注册 IP
|
||||
*/
|
||||
private String registerIp;
|
||||
/**
|
||||
* 最后登录IP
|
||||
*/
|
||||
private String loginIp;
|
||||
/**
|
||||
* 最后登录时间
|
||||
*/
|
||||
private Date loginDate;
|
||||
|
||||
}
|
|
@ -8,6 +8,8 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 会员用户的 API 实现类
|
||||
|
@ -27,4 +29,14 @@ public class MemberUserApiImpl implements MemberUserApi {
|
|||
return UserConvert.INSTANCE.convert2(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserRespDTO> getUsers(Collection<Long> ids) {
|
||||
return UserConvert.INSTANCE.convertList2(userService.getUserList(ids));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserRespDTO> getUserListByNickname(String nickname) {
|
||||
return UserConvert.INSTANCE.convertList2(userService.getUserListByNickname(nickname));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
package cn.iocoder.yudao.module.member.controller.admin.user;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.UserInfoDTO;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO;
|
||||
import cn.iocoder.yudao.module.member.convert.user.UserConvert;
|
||||
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
/**
|
||||
* @author Banging
|
||||
*/
|
||||
@Slf4j
|
||||
@Api("用户管理")
|
||||
@RestController(value = "memberUserController")
|
||||
@RequestMapping("/user")
|
||||
public class UserController {
|
||||
|
||||
@Resource
|
||||
private MemberUserService userService;
|
||||
|
||||
@ApiOperation(value = "用户信息获取",notes = "用户基本信息的获取")
|
||||
@GetMapping("/{tel}")
|
||||
public CommonResult<UserInfoDTO> getUserInfo(@PathVariable String tel){
|
||||
MemberUserDO user = userService.getUserByMobile(tel);
|
||||
return CommonResult.success(UserConvert.INSTANCE.convertInfo(user));
|
||||
}
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
package cn.iocoder.yudao.module.member.convert.user;
|
||||
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.UserInfoDTO;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO;
|
||||
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoRespVO;
|
||||
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface UserConvert {
|
||||
|
||||
|
@ -15,5 +16,7 @@ public interface UserConvert {
|
|||
AppUserInfoRespVO convert(MemberUserDO bean);
|
||||
|
||||
UserRespDTO convert2(MemberUserDO bean);
|
||||
UserInfoDTO convertInfo(MemberUserDO bean);
|
||||
|
||||
List<UserRespDTO> convertList2(List<MemberUserDO> list);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package cn.iocoder.yudao.module.member.dal.mysql.user;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 会员 User Mapper
|
||||
*
|
||||
|
@ -16,4 +19,9 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
|
|||
return selectOne(MemberUserDO::getMobile, mobile);
|
||||
}
|
||||
|
||||
default List<MemberUserDO> selectListByNicknameLike(String nickname) {
|
||||
return selectList(new LambdaQueryWrapperX<MemberUserDO>()
|
||||
.likeIfPresent(MemberUserDO::getNickname, nickname));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobile
|
|||
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 会员用户 Service 接口
|
||||
|
@ -21,6 +23,15 @@ public interface MemberUserService {
|
|||
*/
|
||||
MemberUserDO getUserByMobile(String mobile);
|
||||
|
||||
/**
|
||||
* 基于用户昵称,模糊匹配用户列表
|
||||
*
|
||||
* @param nickname 用户昵称,模糊匹配
|
||||
* @return 用户信息的列表
|
||||
*/
|
||||
List<MemberUserDO> getUserListByNickname(String nickname);
|
||||
|
||||
|
||||
/**
|
||||
* 基于手机号创建用户。
|
||||
* 如果用户已经存在,则直接进行返回
|
||||
|
@ -47,6 +58,14 @@ public interface MemberUserService {
|
|||
*/
|
||||
MemberUserDO getUser(Long id);
|
||||
|
||||
/**
|
||||
* 通过用户 ID 查询用户们
|
||||
*
|
||||
* @param ids 用户 ID
|
||||
* @return 用户对象信息数组
|
||||
*/
|
||||
List<MemberUserDO> getUserList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 修改用户昵称
|
||||
* @param userId 用户id
|
||||
|
|
|
@ -19,7 +19,9 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||
|
@ -51,6 +53,11 @@ public class MemberUserServiceImpl implements MemberUserService {
|
|||
return memberUserMapper.selectByMobile(mobile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MemberUserDO> getUserListByNickname(String nickname) {
|
||||
return memberUserMapper.selectListByNicknameLike(nickname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemberUserDO createUserIfAbsent(String mobile, String registerIp) {
|
||||
// 用户已经存在
|
||||
|
@ -86,6 +93,11 @@ public class MemberUserServiceImpl implements MemberUserService {
|
|||
return memberUserMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MemberUserDO> getUserList(Collection<Long> ids) {
|
||||
return memberUserMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUserNickname(Long userId, String nickname) {
|
||||
MemberUserDO user = this.checkUserExists(userId);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package cn.iocoder.yudao.module.system.controller.admin.permission.vo.role;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
@ -16,7 +18,7 @@ public class RoleUpdateStatusReqVO {
|
|||
|
||||
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举")
|
||||
@NotNull(message = "状态不能为空")
|
||||
// @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
|
|
|
@ -174,6 +174,7 @@ logging:
|
|||
cn.iocoder.yudao.module.tool.dal.mysql: debug
|
||||
cn.iocoder.yudao.module.member.dal.mysql: debug
|
||||
cn.iocoder.yudao.module.trade.dal.mysql: debug
|
||||
cn.iocoder.yudao.module.promotion.dal.mysql: debug
|
||||
|
||||
--- #################### 微信公众号、小程序相关配置 ####################
|
||||
wx:
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 创建优惠券模板
|
||||
export function create(data) {
|
||||
return request({
|
||||
url: '/coupon/template/create',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新优惠券模板
|
||||
export function update(data) {
|
||||
return request({
|
||||
url: '/coupon/template/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除优惠券模板
|
||||
export function deleteCouponTemplete (id) {
|
||||
return request({
|
||||
url: '/coupon/template/delete?id=' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得优惠券模板
|
||||
export function get(id) {
|
||||
return request({
|
||||
url: '/coupon/template/get?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获得优惠券模板分页
|
||||
export function getPage(query) {
|
||||
return request({
|
||||
url: '/coupon/template/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 导出优惠券模板 Excel
|
||||
export function exportExcel(query) {
|
||||
return request({
|
||||
url: '/coupon/template/export-excel',
|
||||
method: 'get',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 获得商品 SKU 选项的列表
|
||||
export function getSkuOptionList() {
|
||||
return request({
|
||||
url: '/product/sku/get-option-list',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 创建商品spu
|
||||
// 创建商品 SPU
|
||||
export function createSpu(data) {
|
||||
return request({
|
||||
url: '/product/spu/create',
|
||||
|
@ -9,7 +9,7 @@ export function createSpu(data) {
|
|||
})
|
||||
}
|
||||
|
||||
// 更新商品spu
|
||||
// 更新商品 SPU
|
||||
export function updateSpu(data) {
|
||||
return request({
|
||||
url: '/product/spu/update',
|
||||
|
@ -18,7 +18,7 @@ export function updateSpu(data) {
|
|||
})
|
||||
}
|
||||
|
||||
// 删除商品spu
|
||||
// 删除商品 SPU
|
||||
export function deleteSpu(id) {
|
||||
return request({
|
||||
url: '/product/spu/delete?id=' + id,
|
||||
|
@ -34,7 +34,7 @@ export function getSpu(id) {
|
|||
})
|
||||
}
|
||||
|
||||
// 获得商品spu详情
|
||||
// 获得商品 SPU 详情
|
||||
export function getSpuDetail(id) {
|
||||
return request({
|
||||
url: '/product/spu/get/detail?id=' + id,
|
||||
|
@ -42,7 +42,7 @@ export function getSpuDetail(id) {
|
|||
})
|
||||
}
|
||||
|
||||
// 获得商品spu分页
|
||||
// 获得商品 SPU 分页
|
||||
export function getSpuPage(query) {
|
||||
return request({
|
||||
url: '/product/spu/page',
|
||||
|
@ -50,3 +50,11 @@ export function getSpuPage(query) {
|
|||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 获得商品 SPU 精简列表
|
||||
export function getSpuSimpleList() {
|
||||
return request({
|
||||
url: '/product/spu/get-simple-list',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue