Commit fb45f2253339f4e844801fc7bbcf3774c1e24c60
Merge branch 'feature/1.8.0-uniapp' of https://gitee.com/zhijiantianya/ruoyi-vue…
…-pro into feature/1.8.0-uniapp
Showing
110 changed files
with
4078 additions
and
1007 deletions
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java
| 1 | 1 | package cn.iocoder.yudao.module.product.controller.admin.sku; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 5 | +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | |
| 6 | +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO; | |
| 7 | +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; | |
| 8 | +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; | |
| 9 | +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; | |
| 10 | +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; | |
| 11 | +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; | |
| 3 | 12 | import io.swagger.annotations.Api; |
| 13 | +import io.swagger.annotations.ApiOperation; | |
| 4 | 14 | import org.springframework.validation.annotation.Validated; |
| 15 | +import org.springframework.web.bind.annotation.GetMapping; | |
| 5 | 16 | import org.springframework.web.bind.annotation.RequestMapping; |
| 6 | 17 | import org.springframework.web.bind.annotation.RestController; |
| 7 | 18 | |
| 19 | +import javax.annotation.Resource; | |
| 20 | +import java.util.Collections; | |
| 21 | +import java.util.List; | |
| 22 | +import java.util.Map; | |
| 23 | + | |
| 24 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 25 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 26 | + | |
| 8 | 27 | @Api(tags = "管理后台 - 商品 sku") |
| 9 | 28 | @RestController |
| 10 | 29 | @RequestMapping("/product/sku") |
| 11 | 30 | @Validated |
| 12 | 31 | public class ProductSkuController { |
| 13 | 32 | |
| 33 | + @Resource | |
| 34 | + private ProductSkuService productSkuService; | |
| 35 | + @Resource | |
| 36 | + private ProductSpuService productSpuService; | |
| 37 | + | |
| 38 | + @GetMapping("/get-option-list") | |
| 39 | + @ApiOperation("获得商品 SKU 选项的列表") | |
| 40 | +// @PreAuthorize("@ss.hasPermission('product:sku:query')") | |
| 41 | + public CommonResult<List<ProductSkuOptionRespVO>> getSkuOptionList() { | |
| 42 | + // 获得 SKU 列表 | |
| 43 | + List<ProductSkuDO> skus = productSkuService.getSkuList(); | |
| 44 | + if (CollUtil.isEmpty(skus)) { | |
| 45 | + return success(Collections.emptyList()); | |
| 46 | + } | |
| 47 | + | |
| 48 | + // 获得对应的 SPU 映射 | |
| 49 | + Map<Long, ProductSpuDO> spuMap = productSpuService.getSpuMap(convertSet(skus, ProductSkuDO::getSpuId)); | |
| 50 | + // 转换为返回结果 | |
| 51 | + List<ProductSkuOptionRespVO> skuVOs = ProductSkuConvert.INSTANCE.convertList05(skus); | |
| 52 | + skuVOs.forEach(sku -> MapUtils.findAndThen(spuMap, sku.getSpuId(), | |
| 53 | + spu -> sku.setSpuId(spu.getId()).setSpuName(spu.getName()))); | |
| 54 | + return success(skuVOs); | |
| 55 | + } | |
| 56 | + | |
| 14 | 57 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.product.controller.admin.sku.vo; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +@ApiModel(value = "管理后台 - 商品 SKU 选项 Response VO", description = "用于前端 SELECT 选项") | |
| 8 | +@Data | |
| 9 | +public class ProductSkuOptionRespVO { | |
| 10 | + | |
| 11 | + @ApiModelProperty(value = "主键", required = true, example = "1024") | |
| 12 | + private Long id; | |
| 13 | + | |
| 14 | + @ApiModelProperty(value = "商品 SKU 名字", example = "红色") | |
| 15 | + private String name; | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "销售价格", required = true, example = "100", notes = "单位:分") | |
| 18 | + private String price; | |
| 19 | + | |
| 20 | + @ApiModelProperty(value = "库存", required = true, example = "100") | |
| 21 | + private Integer stock; | |
| 22 | + | |
| 23 | + // ========== 商品 SPU 信息 ========== | |
| 24 | + | |
| 25 | + @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") | |
| 26 | + private Long spuId; | |
| 27 | + | |
| 28 | + @ApiModelProperty(value = "商品 SPU 名字", required = true, example = "iPhone 11") | |
| 29 | + private String spuName; | |
| 30 | + | |
| 31 | +} | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
| ... | ... | @@ -53,6 +53,7 @@ public class ProductSpuController { |
| 53 | 53 | return success(true); |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | + // TODO 芋艿:修改接口 | |
| 56 | 57 | @GetMapping("/get/detail") |
| 57 | 58 | @ApiOperation("获得商品 SPU") |
| 58 | 59 | @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) |
| ... | ... | @@ -79,6 +80,14 @@ public class ProductSpuController { |
| 79 | 80 | return success(ProductSpuConvert.INSTANCE.convertList(list)); |
| 80 | 81 | } |
| 81 | 82 | |
| 83 | + @GetMapping("/get-simple-list") | |
| 84 | + @ApiOperation("获得商品 SPU 精简列表") | |
| 85 | + @PreAuthorize("@ss.hasPermission('product:spu:query')") | |
| 86 | + public CommonResult<List<ProductSpuSimpleRespVO>> getSpuSimpleList() { | |
| 87 | + List<ProductSpuDO> list = spuService.getSpuList(); | |
| 88 | + return success(ProductSpuConvert.INSTANCE.convertList02(list)); | |
| 89 | + } | |
| 90 | + | |
| 82 | 91 | @GetMapping("/page") |
| 83 | 92 | @ApiOperation("获得商品 SPU 分页") |
| 84 | 93 | @PreAuthorize("@ss.hasPermission('product:spu:query')") | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.product.controller.admin.spu.vo; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +@ApiModel("管理后台 - 商品 SPU 精简 Response VO") | |
| 10 | +@Data | |
| 11 | +@EqualsAndHashCode(callSuper = true) | |
| 12 | +@ToString(callSuper = true) | |
| 13 | +public class ProductSpuSimpleRespVO extends ProductSpuBaseVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "主键", required = true, example = "1") | |
| 16 | + private Long id; | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "商品名称", required = true, example = "芋道") | |
| 19 | + private String name; | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024") | |
| 22 | + private Integer minPrice; | |
| 23 | + | |
| 24 | + @ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024") | |
| 25 | + private Integer maxPrice; | |
| 26 | + | |
| 27 | +} | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java
| ... | ... | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.convert.sku; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 4 | 4 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; |
| 5 | +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO; | |
| 5 | 6 | import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; |
| 6 | 7 | import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuDetailRespVO; |
| 7 | 8 | import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; |
| ... | ... | @@ -11,7 +12,7 @@ import org.mapstruct.factory.Mappers; |
| 11 | 12 | import java.util.List; |
| 12 | 13 | |
| 13 | 14 | /** |
| 14 | - * 商品sku Convert | |
| 15 | + * 商品 SKU Convert | |
| 15 | 16 | * |
| 16 | 17 | * @author 芋道源码 |
| 17 | 18 | */ |
| ... | ... | @@ -36,4 +37,6 @@ public interface ProductSkuConvert { |
| 36 | 37 | |
| 37 | 38 | List<ProductSkuRespDTO> convertList04(List<ProductSkuDO> list); |
| 38 | 39 | |
| 40 | + List<ProductSkuOptionRespVO> convertList05(List<ProductSkuDO> skus); | |
| 41 | + | |
| 39 | 42 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java
| ... | ... | @@ -97,6 +97,7 @@ public class ProductSkuDO extends BaseDO { |
| 97 | 97 | * 商品属性 |
| 98 | 98 | */ |
| 99 | 99 | @Data |
| 100 | + @NoArgsConstructor | |
| 100 | 101 | @AllArgsConstructor |
| 101 | 102 | public static class Property { |
| 102 | 103 | |
| ... | ... | @@ -130,19 +131,5 @@ public class ProductSkuDO extends BaseDO { |
| 130 | 131 | |
| 131 | 132 | } |
| 132 | 133 | |
| 133 | - // TODO ========== 待定字段:yv ========= | |
| 134 | - // TODO brokerage:一级返佣 | |
| 135 | - // TODO brokerage_two:二级返佣 | |
| 136 | - // TODO pink_price:拼团价 | |
| 137 | - // TODO pink_stock:拼团库存 | |
| 138 | - // TODO seckill_price:秒杀价 | |
| 139 | - // TODO seckill_stock:秒杀库存 | |
| 140 | - // TODO integral:需要积分 | |
| 141 | - | |
| 142 | - // TODO ========== 待定字段:cf ========= | |
| 143 | - // TODO type 活动显示排序 0=默认 1=秒 2=砍价 3=拼团 | |
| 144 | - // TODO quota 活动限购数量 | |
| 145 | - // TODO quota_show 活动限购数量显示 | |
| 146 | - | |
| 147 | 134 | } |
| 148 | 135 | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java
| ... | ... | @@ -14,22 +14,29 @@ import java.util.List; |
| 14 | 14 | public interface ProductSkuService { |
| 15 | 15 | |
| 16 | 16 | /** |
| 17 | - * 删除商品sku | |
| 17 | + * 删除商品 SKU | |
| 18 | 18 | * |
| 19 | 19 | * @param id 编号 |
| 20 | 20 | */ |
| 21 | 21 | void deleteSku(Long id); |
| 22 | 22 | |
| 23 | 23 | /** |
| 24 | - * 获得商品sku | |
| 24 | + * 获得商品 SKU 信息 | |
| 25 | 25 | * |
| 26 | 26 | * @param id 编号 |
| 27 | - * @return 商品sku | |
| 27 | + * @return 商品 SKU 信息 | |
| 28 | 28 | */ |
| 29 | 29 | ProductSkuDO getSku(Long id); |
| 30 | 30 | |
| 31 | 31 | /** |
| 32 | - * 获得商品sku列表 | |
| 32 | + * 获得商品 SKU 列表 | |
| 33 | + * | |
| 34 | + * @return 商品sku列表 | |
| 35 | + */ | |
| 36 | + List<ProductSkuDO> getSkuList(); | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * 获得商品 SKU 列表 | |
| 33 | 40 | * |
| 34 | 41 | * @param ids 编号 |
| 35 | 42 | * @return 商品sku列表 | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
| ... | ... | @@ -62,6 +62,11 @@ public class ProductSkuServiceImpl implements ProductSkuService { |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | 64 | @Override |
| 65 | + public List<ProductSkuDO> getSkuList() { | |
| 66 | + return productSkuMapper.selectList(); | |
| 67 | + } | |
| 68 | + | |
| 69 | + @Override | |
| 65 | 70 | public List<ProductSkuDO> getSkuList(Collection<Long> ids) { |
| 66 | 71 | return productSkuMapper.selectBatchIds(ids); |
| 67 | 72 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
| ... | ... | @@ -9,6 +9,9 @@ import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; |
| 9 | 9 | import javax.validation.Valid; |
| 10 | 10 | import java.util.Collection; |
| 11 | 11 | import java.util.List; |
| 12 | +import java.util.Map; | |
| 13 | + | |
| 14 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | |
| 12 | 15 | |
| 13 | 16 | /** |
| 14 | 17 | * 商品 SPU Service 接口 |
| ... | ... | @@ -64,6 +67,23 @@ public interface ProductSpuService { |
| 64 | 67 | List<ProductSpuDO> getSpuList(Collection<Long> ids); |
| 65 | 68 | |
| 66 | 69 | /** |
| 70 | + * 获得商品 SPU 映射 | |
| 71 | + * | |
| 72 | + * @param ids 编号数组 | |
| 73 | + * @return 商品 SPU 映射 | |
| 74 | + */ | |
| 75 | + default Map<Long, ProductSpuDO> getSpuMap(Collection<Long> ids) { | |
| 76 | + return convertMap(getSpuList(ids), ProductSpuDO::getId); | |
| 77 | + } | |
| 78 | + | |
| 79 | + /** | |
| 80 | + * 获得所有商品 SPU 列表 | |
| 81 | + * | |
| 82 | + * @return 商品 SPU 列表 | |
| 83 | + */ | |
| 84 | + List<ProductSpuDO> getSpuList(); | |
| 85 | + | |
| 86 | + /** | |
| 67 | 87 | * 获得商品 SPU 分页 |
| 68 | 88 | * |
| 69 | 89 | * @param pageReqVO 分页查询 | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
| ... | ... | @@ -177,6 +177,11 @@ public class ProductSpuServiceImpl implements ProductSpuService { |
| 177 | 177 | } |
| 178 | 178 | |
| 179 | 179 | @Override |
| 180 | + public List<ProductSpuDO> getSpuList() { | |
| 181 | + return productSpuMapper.selectList(); | |
| 182 | + } | |
| 183 | + | |
| 184 | + @Override | |
| 180 | 185 | public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) { |
| 181 | 186 | // 库存告警的 SPU 编号的集合 |
| 182 | 187 | Set<Long> alarmStockSpuIds = null; | ... | ... |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java
| ... | ... | @@ -48,10 +48,18 @@ public class PriceCalculateRespDTO { |
| 48 | 48 | * 商品原价(总),单位:分 |
| 49 | 49 | * |
| 50 | 50 | * 基于 {@link OrderItem#getOriginalPrice()} 求和 |
| 51 | + * | |
| 51 | 52 | * 对应 taobao 的 trade.total_fee 字段 |
| 52 | 53 | */ |
| 53 | 54 | private Integer originalPrice; |
| 54 | 55 | /** |
| 56 | + * 订单原价(总),单位:分 | |
| 57 | + * | |
| 58 | + * 基于 {@link OrderItem#getPayPrice()} 求和 | |
| 59 | + * 和 {@link #originalPrice} 的差异:去除商品级优惠 | |
| 60 | + */ | |
| 61 | + private Integer orderPrice; | |
| 62 | + /** | |
| 55 | 63 | * 订单优惠(总),单位:分 |
| 56 | 64 | * |
| 57 | 65 | * 订单级优惠:对主订单的优惠,常见如:订单满 200 元减 10 元;订单满 80 包邮。 |
| ... | ... | @@ -82,6 +90,7 @@ public class PriceCalculateRespDTO { |
| 82 | 90 | * - {@link #couponPrice} |
| 83 | 91 | * - {@link #pointPrice} |
| 84 | 92 | * + {@link #deliveryPrice} |
| 93 | + * - {@link #discountPrice} | |
| 85 | 94 | */ |
| 86 | 95 | private Integer payPrice; |
| 87 | 96 | /** | ... | ... |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
| ... | ... | @@ -3,14 +3,19 @@ package cn.iocoder.yudao.module.promotion.enums; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.exception.ErrorCode; |
| 4 | 4 | |
| 5 | 5 | /** |
| 6 | - * market 错误码枚举类 | |
| 7 | - * <p> | |
| 6 | + * promotion 错误码枚举类 | |
| 7 | + * | |
| 8 | 8 | * market 系统,使用 1-003-000-000 段 |
| 9 | 9 | */ |
| 10 | 10 | public interface ErrorCodeConstants { |
| 11 | 11 | |
| 12 | - // ========== 促销活动相关 1003001000 ============ TODO 芋艿:看看是不是要删除掉 | |
| 13 | - ErrorCode ACTIVITY_NOT_EXISTS = new ErrorCode(1003001000, "促销活动不存在"); | |
| 12 | + // ========== 促销活动相关 1003001000 ============ | |
| 13 | + ErrorCode DISCOUNT_ACTIVITY_NOT_EXISTS = new ErrorCode(1003001000, "限时折扣活动不存在"); | |
| 14 | + ErrorCode DISCOUNT_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003006001, "存在商品参加了其它限时折扣活动"); | |
| 15 | + ErrorCode DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "限时折扣活动已关闭,不能修改"); | |
| 16 | + ErrorCode DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "限时折扣活动未关闭,不能删除"); | |
| 17 | + ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "限时折扣活动已关闭,不能重复关闭"); | |
| 18 | + ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "限时折扣活动已结束,不能关闭"); | |
| 14 | 19 | |
| 15 | 20 | // ========== Banner 相关 1003002000 ============ |
| 16 | 21 | ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1003002000, "Banner 不存在"); |
| ... | ... | @@ -23,4 +28,19 @@ public interface ErrorCodeConstants { |
| 23 | 28 | ErrorCode COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1003004000, "优惠劵模板不存在"); |
| 24 | 29 | ErrorCode COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL = new ErrorCode(1003004001, "发放数量不能小于已领取数量({})"); |
| 25 | 30 | |
| 31 | + // ========== 优惠劵模板 1003005000 ========== | |
| 32 | + ErrorCode COUPON_NOT_EXISTS = new ErrorCode(1003005000, "优惠劵不存在"); | |
| 33 | + ErrorCode COUPON_DELETE_FAIL_USED = new ErrorCode(1003005001, "回收优惠劵失败,优惠劵已被使用"); | |
| 34 | + | |
| 35 | + // ========== 满减送活动 1003006000 ========== | |
| 36 | + ErrorCode REWARD_ACTIVITY_NOT_EXISTS = new ErrorCode(1003006000, "满减送活动不存在"); | |
| 37 | + ErrorCode REWARD_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003006001, "存在商品参加了其它满减送活动"); | |
| 38 | + ErrorCode REWARD_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "满减送活动已关闭,不能修改"); | |
| 39 | + ErrorCode REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "满减送活动未关闭,不能删除"); | |
| 40 | + ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "满减送活动已关闭,不能重复关闭"); | |
| 41 | + ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "满减送活动已结束,不能关闭"); | |
| 42 | + | |
| 43 | + // ========== Price 相关 1003007000 ============ | |
| 44 | + ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1003007000, "支付价格计算异常,原因:价格小于等于 0"); | |
| 45 | + | |
| 26 | 46 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponStatusEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.enums.coupon; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; | |
| 4 | +import lombok.AllArgsConstructor; | |
| 5 | +import lombok.Getter; | |
| 6 | + | |
| 7 | +import java.util.Arrays; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * 优惠劵状态枚举 | |
| 11 | + * | |
| 12 | + * @author 芋道源码 | |
| 13 | + */ | |
| 14 | +@AllArgsConstructor | |
| 15 | +@Getter | |
| 16 | +public enum CouponStatusEnum implements IntArrayValuable { | |
| 17 | + | |
| 18 | + UNUSED(1, "未使用"), | |
| 19 | + USED(2, "已使用"), | |
| 20 | + EXPIRE(3, "已过期"), | |
| 21 | + ; | |
| 22 | + | |
| 23 | + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponStatusEnum::getStatus).toArray(); | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * 值 | |
| 27 | + */ | |
| 28 | + private final Integer status; | |
| 29 | + /** | |
| 30 | + * 名字 | |
| 31 | + */ | |
| 32 | + private final String name; | |
| 33 | + | |
| 34 | + @Override | |
| 35 | + public int[] array() { | |
| 36 | + return ARRAYS; | |
| 37 | + } | |
| 38 | + | |
| 39 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTakeTypeEnum.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.enums.coupon; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.core.IntArrayValuable; |
| 4 | +import lombok.AllArgsConstructor; | |
| 5 | +import lombok.Getter; | |
| 4 | 6 | |
| 5 | 7 | import java.util.Arrays; |
| 6 | 8 | |
| ... | ... | @@ -9,6 +11,8 @@ import java.util.Arrays; |
| 9 | 11 | * |
| 10 | 12 | * @author 芋道源码 |
| 11 | 13 | */ |
| 14 | +@AllArgsConstructor | |
| 15 | +@Getter | |
| 12 | 16 | public enum CouponTakeTypeEnum implements IntArrayValuable { |
| 13 | 17 | |
| 14 | 18 | BY_USER(1, "直接领取"), // 用户可在首页、每日领劵直接领取 |
| ... | ... | @@ -26,19 +30,6 @@ public enum CouponTakeTypeEnum implements IntArrayValuable { |
| 26 | 30 | */ |
| 27 | 31 | private final String name; |
| 28 | 32 | |
| 29 | - CouponTakeTypeEnum(Integer value, String name) { | |
| 30 | - this.value = value; | |
| 31 | - this.name = name; | |
| 32 | - } | |
| 33 | - | |
| 34 | - public Integer getValue() { | |
| 35 | - return value; | |
| 36 | - } | |
| 37 | - | |
| 38 | - public String getName() { | |
| 39 | - return name; | |
| 40 | - } | |
| 41 | - | |
| 42 | 33 | @Override |
| 43 | 34 | public int[] array() { |
| 44 | 35 | return ARRAYS; | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/pom.xml
| ... | ... | @@ -29,6 +29,11 @@ |
| 29 | 29 | <artifactId>yudao-module-product-api</artifactId> |
| 30 | 30 | <version>${revision}</version> |
| 31 | 31 | </dependency> |
| 32 | + <dependency> | |
| 33 | + <groupId>cn.iocoder.boot</groupId> | |
| 34 | + <artifactId>yudao-module-member-api</artifactId> | |
| 35 | + <version>${revision}</version> | |
| 36 | + </dependency> | |
| 32 | 37 | |
| 33 | 38 | <!-- 业务组件 --> |
| 34 | 39 | <dependency> | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.coupon; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | |
| 7 | +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | |
| 8 | +import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO; | |
| 9 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageItemRespVO; | |
| 10 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; | |
| 11 | +import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert; | |
| 12 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; | |
| 13 | +import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; | |
| 14 | +import io.swagger.annotations.Api; | |
| 15 | +import io.swagger.annotations.ApiImplicitParam; | |
| 16 | +import io.swagger.annotations.ApiOperation; | |
| 17 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 18 | +import org.springframework.validation.annotation.Validated; | |
| 19 | +import org.springframework.web.bind.annotation.*; | |
| 20 | + | |
| 21 | +import javax.annotation.Resource; | |
| 22 | +import javax.validation.Valid; | |
| 23 | +import java.util.Map; | |
| 24 | +import java.util.Set; | |
| 25 | + | |
| 26 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 27 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 28 | + | |
| 29 | +@Api(tags = "管理后台 - 优惠劵") | |
| 30 | +@RestController | |
| 31 | +@RequestMapping("/promotion/coupon") | |
| 32 | +@Validated | |
| 33 | +public class CouponController { | |
| 34 | + | |
| 35 | + @Resource | |
| 36 | + private CouponService couponService; | |
| 37 | + @Resource | |
| 38 | + private MemberUserApi memberUserApi; | |
| 39 | + | |
| 40 | +// @GetMapping("/get") | |
| 41 | +// @ApiOperation("获得优惠劵") | |
| 42 | +// @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) | |
| 43 | +// @PreAuthorize("@ss.hasPermission('promotion:coupon:query')") | |
| 44 | +// public CommonResult<CouponRespVO> getCoupon(@RequestParam("id") Long id) { | |
| 45 | +// CouponDO coupon = couponService.getCoupon(id); | |
| 46 | +// return success(CouponConvert.INSTANCE.convert(coupon)); | |
| 47 | +// } | |
| 48 | + | |
| 49 | + @DeleteMapping("/delete") | |
| 50 | + @ApiOperation("回收优惠劵") | |
| 51 | + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) | |
| 52 | + @PreAuthorize("@ss.hasPermission('promotion:coupon:delete')") | |
| 53 | + public CommonResult<Boolean> deleteCoupon(@RequestParam("id") Long id) { | |
| 54 | + couponService.deleteCoupon(id); | |
| 55 | + return success(true); | |
| 56 | + } | |
| 57 | + | |
| 58 | + @GetMapping("/page") | |
| 59 | + @ApiOperation("获得优惠劵分页") | |
| 60 | + @PreAuthorize("@ss.hasPermission('promotion:coupon:query')") | |
| 61 | + public CommonResult<PageResult<CouponPageItemRespVO>> getCouponPage(@Valid CouponPageReqVO pageVO) { | |
| 62 | + PageResult<CouponDO> pageResult = couponService.getCouponPage(pageVO); | |
| 63 | + PageResult<CouponPageItemRespVO> pageResulVO = CouponConvert.INSTANCE.convertPage(pageResult); | |
| 64 | + if (CollUtil.isEmpty(pageResulVO.getList())) { | |
| 65 | + return success(pageResulVO); | |
| 66 | + } | |
| 67 | + // 读取用户信息,进行拼接 | |
| 68 | + Set<Long> userIds = convertSet(pageResult.getList(), CouponDO::getUserId); | |
| 69 | + Map<Long, UserRespDTO> userMap = memberUserApi.getUserMap(userIds); | |
| 70 | + pageResulVO.getList().forEach(itemRespVO -> MapUtils.findAndThen(userMap, itemRespVO.getUserId(), | |
| 71 | + userRespDTO -> itemRespVO.setNickname(userRespDTO.getNickname()))); | |
| 72 | + return success(pageResulVO); | |
| 73 | + } | |
| 74 | + | |
| 75 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java
| ... | ... | @@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.promotion.controller.admin.coupon; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateCreateReqVO; | |
| 6 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplatePageReqVO; | |
| 7 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateRespVO; | |
| 8 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateUpdateReqVO; | |
| 5 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.*; | |
| 9 | 6 | import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert; |
| 10 | 7 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; |
| 11 | 8 | import cn.iocoder.yudao.module.promotion.service.coupon.CouponTemplateService; |
| ... | ... | @@ -45,6 +42,14 @@ public class CouponTemplateController { |
| 45 | 42 | return success(true); |
| 46 | 43 | } |
| 47 | 44 | |
| 45 | + @PutMapping("/update-status") | |
| 46 | + @ApiOperation("更新优惠劵模板状态") | |
| 47 | + @PreAuthorize("@ss.hasPermission('promotion:coupon-template:update')") | |
| 48 | + public CommonResult<Boolean> updateCouponTemplateStatus(@Valid @RequestBody CouponTemplateUpdateStatusReqVO reqVO) { | |
| 49 | + couponTemplateService.updateCouponTemplateStatus(reqVO.getId(), reqVO.getStatus()); | |
| 50 | + return success(true); | |
| 51 | + } | |
| 52 | + | |
| 48 | 53 | @DeleteMapping("/delete") |
| 49 | 54 | @ApiOperation("删除优惠劵模板") |
| 50 | 55 | @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 4 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; | |
| 5 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; | |
| 6 | +import com.fasterxml.jackson.annotation.JsonFormat; | |
| 7 | +import io.swagger.annotations.ApiModelProperty; | |
| 8 | +import lombok.Data; | |
| 9 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 10 | + | |
| 11 | +import javax.validation.constraints.Min; | |
| 12 | +import javax.validation.constraints.NotNull; | |
| 13 | +import java.util.Date; | |
| 14 | +import java.util.List; | |
| 15 | + | |
| 16 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 17 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; | |
| 18 | + | |
| 19 | +/** | |
| 20 | +* 优惠劵 Base VO,提供给添加、修改、详细的子 VO 使用 | |
| 21 | +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | |
| 22 | +*/ | |
| 23 | +@Data | |
| 24 | +public class CouponBaseVO { | |
| 25 | + | |
| 26 | + // ========== 基本信息 BEGIN ========== | |
| 27 | + @ApiModelProperty(value = "优惠劵模板编号", required = true, example = "1024") | |
| 28 | + @NotNull(message = "优惠劵模板编号不能为空") | |
| 29 | + private Integer templateId; | |
| 30 | + | |
| 31 | + @ApiModelProperty(value = "优惠劵名", required = true, example = "春节送送送") | |
| 32 | + @NotNull(message = "优惠劵名不能为空") | |
| 33 | + private String name; | |
| 34 | + | |
| 35 | + @ApiModelProperty(value = "优惠码状态", required = true, example = "1", notes = "参见 CouponStatusEnum 枚举") | |
| 36 | + private Integer status; | |
| 37 | + | |
| 38 | + // ========== 基本信息 END ========== | |
| 39 | + | |
| 40 | + // ========== 领取情况 BEGIN ========== | |
| 41 | + @ApiModelProperty(value = "用户编号", required = true, example = "1") | |
| 42 | + @NotNull(message = "用户编号不能为空") | |
| 43 | + private Long userId; | |
| 44 | + | |
| 45 | + @ApiModelProperty(value = "领取方式", required = true, example = "1", notes = "参见 CouponTakeTypeEnum 枚举类") | |
| 46 | + @NotNull(message = "领取方式不能为空") | |
| 47 | + private Integer takeType; | |
| 48 | + // ========== 领取情况 END ========== | |
| 49 | + | |
| 50 | + // ========== 使用规则 BEGIN ========== | |
| 51 | + @ApiModelProperty(value = "是否设置满多少金额可用", required = true, example = "100", notes = "单位:分;0 - 不限制") | |
| 52 | + @NotNull(message = "是否设置满多少金额可用不能为空") | |
| 53 | + private Integer usePrice; | |
| 54 | + | |
| 55 | + @ApiModelProperty(value = "固定日期 - 生效开始时间") | |
| 56 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 57 | + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) | |
| 58 | + private Date validStartTime; | |
| 59 | + | |
| 60 | + @ApiModelProperty(value = "固定日期 - 生效结束时间") | |
| 61 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 62 | + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) | |
| 63 | + private Date validEndTime; | |
| 64 | + | |
| 65 | + @ApiModelProperty(value = "商品范围", required = true, example = "1", notes = "参见 PromotionProductScopeEnum 枚举类") | |
| 66 | + @NotNull(message = "商品范围不能为空") | |
| 67 | + @InEnum(PromotionProductScopeEnum.class) | |
| 68 | + private Integer productScope; | |
| 69 | + | |
| 70 | + @ApiModelProperty(value = "商品 SPU 编号的数组", example = "1,3") | |
| 71 | + private List<Long> productSpuIds; | |
| 72 | + // ========== 使用规则 END ========== | |
| 73 | + | |
| 74 | + // ========== 使用效果 BEGIN ========== | |
| 75 | + @ApiModelProperty(value = "优惠类型", required = true, example = "1", notes = "参见 PromotionDiscountTypeEnum 枚举") | |
| 76 | + @NotNull(message = "优惠类型不能为空") | |
| 77 | + @InEnum(PromotionDiscountTypeEnum.class) | |
| 78 | + private Integer discountType; | |
| 79 | + | |
| 80 | + @ApiModelProperty(value = "折扣百分比", example = "80", notes = "例如说,80% 为 80") | |
| 81 | + private Integer discountPercent; | |
| 82 | + | |
| 83 | + @ApiModelProperty(value = "优惠金额", example = "10", notes = "单位:分") | |
| 84 | + @Min(value = 0, message = "优惠金额需要大于等于 0") | |
| 85 | + private Integer discountPrice; | |
| 86 | + | |
| 87 | + @ApiModelProperty(value = "折扣上限", example = "100", notes = "单位:分,仅在 discountType 为 PERCENT 使用") | |
| 88 | + private Integer discountLimitPrice; | |
| 89 | + // ========== 使用效果 END ========== | |
| 90 | + | |
| 91 | + // ========== 使用情况 BEGIN ========== | |
| 92 | + | |
| 93 | + @ApiModelProperty(value = "使用订单号", example = "4096") | |
| 94 | + private Long useOrderId; | |
| 95 | + | |
| 96 | + @ApiModelProperty(value = "使用时间") | |
| 97 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 98 | + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) | |
| 99 | + private Date useTime; | |
| 100 | + | |
| 101 | + // ========== 使用情况 END ========== | |
| 102 | + | |
| 103 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +@ApiModel("管理后台 - 优惠劵分页的每一项 Response VO") | |
| 10 | +@Data | |
| 11 | +@EqualsAndHashCode(callSuper = true) | |
| 12 | +@ToString(callSuper = true) | |
| 13 | +public class CouponPageItemRespVO extends CouponRespVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "用户昵称", example = "老芋艿") | |
| 16 | + private String nickname; | |
| 17 | + | |
| 18 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 4 | +import io.swagger.annotations.ApiModel; | |
| 5 | +import io.swagger.annotations.ApiModelProperty; | |
| 6 | +import lombok.Data; | |
| 7 | +import lombok.EqualsAndHashCode; | |
| 8 | +import lombok.ToString; | |
| 9 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 10 | + | |
| 11 | +import java.util.Date; | |
| 12 | + | |
| 13 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 14 | + | |
| 15 | +@ApiModel("管理后台 - 优惠劵分页 Request VO") | |
| 16 | +@Data | |
| 17 | +@EqualsAndHashCode(callSuper = true) | |
| 18 | +@ToString(callSuper = true) | |
| 19 | +public class CouponPageReqVO extends PageParam { | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "优惠劵模板编号", example = "2048") | |
| 22 | + private Long templateId; | |
| 23 | + | |
| 24 | + @ApiModelProperty(value = "优惠码状态", example = "1", notes = "参见 CouponStatusEnum 枚举") | |
| 25 | + private Integer status; | |
| 26 | + | |
| 27 | + @ApiModelProperty(value = "创建时间") | |
| 28 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 29 | + private Date[] createTime; | |
| 30 | + | |
| 31 | + @ApiModelProperty(value = "用户昵称", example = "芋艿", notes = "模糊匹配") | |
| 32 | + private String nickname; | |
| 33 | + | |
| 34 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +import java.util.Date; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 优惠劵 Response VO") | |
| 12 | +@Data | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +@ToString(callSuper = true) | |
| 15 | +public class CouponRespVO extends CouponBaseVO { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "优惠劵编号", required = true, example = "1024") | |
| 18 | + private Long id; | |
| 19 | + | |
| 20 | + @ApiModelProperty(value = "创建时间", required = true) | |
| 21 | + private Date createTime; | |
| 22 | + | |
| 23 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/CouponTemplateBaseVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java
| 1 | -package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo; | |
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; | |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.util.ObjectUtil; |
| ... | ... | @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 6 | 6 | import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; |
| 7 | 7 | import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; |
| 8 | 8 | import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum; |
| 9 | +import com.fasterxml.jackson.annotation.JsonFormat; | |
| 9 | 10 | import com.fasterxml.jackson.annotation.JsonIgnore; |
| 10 | 11 | import io.swagger.annotations.ApiModelProperty; |
| 11 | 12 | import lombok.Data; |
| ... | ... | @@ -19,6 +20,7 @@ import java.util.List; |
| 19 | 20 | import java.util.Objects; |
| 20 | 21 | |
| 21 | 22 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| 23 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; | |
| 22 | 24 | |
| 23 | 25 | /** |
| 24 | 26 | * 优惠劵模板 Base VO,提供给添加、修改、详细的子 VO 使用 |
| ... | ... | @@ -62,10 +64,12 @@ public class CouponTemplateBaseVO { |
| 62 | 64 | |
| 63 | 65 | @ApiModelProperty(value = "固定日期 - 生效开始时间") |
| 64 | 66 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 67 | + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) | |
| 65 | 68 | private Date validStartTime; |
| 66 | 69 | |
| 67 | 70 | @ApiModelProperty(value = "固定日期 - 生效结束时间") |
| 68 | 71 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 72 | + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) | |
| 69 | 73 | private Date validEndTime; |
| 70 | 74 | |
| 71 | 75 | @ApiModelProperty(value = "领取日期 - 开始天数") |
| ... | ... | @@ -82,15 +86,14 @@ public class CouponTemplateBaseVO { |
| 82 | 86 | private Integer discountType; |
| 83 | 87 | |
| 84 | 88 | @ApiModelProperty(value = "折扣百分比", example = "80", notes = "例如说,80% 为 80") |
| 85 | - @Min(value = 1) | |
| 86 | 89 | private Integer discountPercent; |
| 87 | 90 | |
| 88 | 91 | @ApiModelProperty(value = "优惠金额", example = "10", notes = "单位:分") |
| 89 | - @Min(value = 1) | |
| 92 | + @Min(value = 0, message = "优惠金额需要大于等于 0") | |
| 90 | 93 | private Integer discountPrice; |
| 91 | 94 | |
| 92 | 95 | @ApiModelProperty(value = "折扣上限", example = "100", notes = "单位:分,仅在 discountType 为 PERCENT 使用") |
| 93 | - private Integer discountPriceLimit; | |
| 96 | + private Integer discountLimitPrice; | |
| 94 | 97 | |
| 95 | 98 | @AssertTrue(message = "商品 SPU 编号的数组不能为空") |
| 96 | 99 | @JsonIgnore |
| ... | ... | @@ -127,11 +130,11 @@ public class CouponTemplateBaseVO { |
| 127 | 130 | || fixedEndTerm != null; |
| 128 | 131 | } |
| 129 | 132 | |
| 130 | - @AssertTrue(message = "折扣百分比不能为空") | |
| 133 | + @AssertTrue(message = "折扣百分比需要大于等于 1,小于等于 99") | |
| 131 | 134 | @JsonIgnore |
| 132 | 135 | public boolean isDiscountPercentValid() { |
| 133 | 136 | return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType()) |
| 134 | - || discountPercent != null; | |
| 137 | + || (discountPercent != null && discountPercent >= 1 && discountPercent<= 99); | |
| 135 | 138 | } |
| 136 | 139 | |
| 137 | 140 | @AssertTrue(message = "优惠金额不能为空") |
| ... | ... | @@ -143,9 +146,9 @@ public class CouponTemplateBaseVO { |
| 143 | 146 | |
| 144 | 147 | @AssertTrue(message = "折扣上限不能为空") |
| 145 | 148 | @JsonIgnore |
| 146 | - public boolean isDiscountPriceLimit() { | |
| 149 | + public boolean isDiscountLimitPriceValid() { | |
| 147 | 150 | return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType()) |
| 148 | - || discountPriceLimit != null; | |
| 151 | + || discountLimitPrice != null; | |
| 149 | 152 | } |
| 150 | 153 | |
| 151 | 154 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/CouponTemplateCreateReqVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/CouponTemplatePageReqVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/CouponTemplateRespVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/CouponTemplateUpdateReqVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 4 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 5 | +import io.swagger.annotations.ApiModel; | |
| 6 | +import io.swagger.annotations.ApiModelProperty; | |
| 7 | +import lombok.Data; | |
| 8 | + | |
| 9 | +import javax.validation.constraints.NotNull; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 优惠劵模板更新状态 Request VO") | |
| 12 | +@Data | |
| 13 | +public class CouponTemplateUpdateStatusReqVO { | |
| 14 | + | |
| 15 | + @ApiModelProperty(value = "优惠劵模板编号", required = true, example = "1024") | |
| 16 | + @NotNull(message = "优惠劵模板编号不能为空") | |
| 17 | + private Long id; | |
| 18 | + | |
| 19 | + @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举") | |
| 20 | + @NotNull(message = "状态不能为空") | |
| 21 | + @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") | |
| 22 | + private Integer status; | |
| 23 | + | |
| 24 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.discount; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*; | |
| 6 | +import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert; | |
| 7 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; | |
| 8 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; | |
| 9 | +import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; | |
| 10 | +import io.swagger.annotations.Api; | |
| 11 | +import io.swagger.annotations.ApiImplicitParam; | |
| 12 | +import io.swagger.annotations.ApiOperation; | |
| 13 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 14 | +import org.springframework.validation.annotation.Validated; | |
| 15 | +import org.springframework.web.bind.annotation.*; | |
| 16 | + | |
| 17 | +import javax.annotation.Resource; | |
| 18 | +import javax.validation.Valid; | |
| 19 | +import java.util.List; | |
| 20 | + | |
| 21 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 22 | + | |
| 23 | +@Api(tags = "管理后台 - 限时折扣活动") | |
| 24 | +@RestController | |
| 25 | +@RequestMapping("/promotion/discount-activity") | |
| 26 | +@Validated | |
| 27 | +public class DiscountActivityController { | |
| 28 | + | |
| 29 | + @Resource | |
| 30 | + private DiscountActivityService discountActivityService; | |
| 31 | + | |
| 32 | + @PostMapping("/create") | |
| 33 | + @ApiOperation("创建限时折扣活动") | |
| 34 | + @PreAuthorize("@ss.hasPermission('promotion:discount-activity:create')") | |
| 35 | + public CommonResult<Long> createDiscountActivity(@Valid @RequestBody DiscountActivityCreateReqVO createReqVO) { | |
| 36 | + return success(discountActivityService.createDiscountActivity(createReqVO)); | |
| 37 | + } | |
| 38 | + | |
| 39 | + @PutMapping("/update") | |
| 40 | + @ApiOperation("更新限时折扣活动") | |
| 41 | + @PreAuthorize("@ss.hasPermission('promotion:discount-activity:update')") | |
| 42 | + public CommonResult<Boolean> updateDiscountActivity(@Valid @RequestBody DiscountActivityUpdateReqVO updateReqVO) { | |
| 43 | + discountActivityService.updateDiscountActivity(updateReqVO); | |
| 44 | + return success(true); | |
| 45 | + } | |
| 46 | + | |
| 47 | + @PutMapping("/close") | |
| 48 | + @ApiOperation("关闭限时折扣活动") | |
| 49 | + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) | |
| 50 | + @PreAuthorize("@ss.hasPermission('promotion:discount-activity:close')") | |
| 51 | + public CommonResult<Boolean> closeRewardActivity(@RequestParam("id") Long id) { | |
| 52 | + discountActivityService.closeRewardActivity(id); | |
| 53 | + return success(true); | |
| 54 | + } | |
| 55 | + | |
| 56 | + @DeleteMapping("/delete") | |
| 57 | + @ApiOperation("删除限时折扣活动") | |
| 58 | + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) | |
| 59 | + @PreAuthorize("@ss.hasPermission('promotion:discount-activity:delete')") | |
| 60 | + public CommonResult<Boolean> deleteDiscountActivity(@RequestParam("id") Long id) { | |
| 61 | + discountActivityService.deleteDiscountActivity(id); | |
| 62 | + return success(true); | |
| 63 | + } | |
| 64 | + | |
| 65 | + @GetMapping("/get") | |
| 66 | + @ApiOperation("获得限时折扣活动") | |
| 67 | + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) | |
| 68 | + @PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')") | |
| 69 | + public CommonResult<DiscountActivityDetailRespVO> getDiscountActivity(@RequestParam("id") Long id) { | |
| 70 | + DiscountActivityDO discountActivity = discountActivityService.getDiscountActivity(id); | |
| 71 | + if (discountActivity == null) { | |
| 72 | + return success(null); | |
| 73 | + } | |
| 74 | + // 拼接结果 | |
| 75 | + List<DiscountProductDO> discountProducts = discountActivityService.getDiscountProductsByActivityId(id); | |
| 76 | + return success(DiscountActivityConvert.INSTANCE.convert(discountActivity, discountProducts)); | |
| 77 | + } | |
| 78 | + | |
| 79 | + @GetMapping("/page") | |
| 80 | + @ApiOperation("获得限时折扣活动分页") | |
| 81 | + @PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')") | |
| 82 | + public CommonResult<PageResult<DiscountActivityRespVO>> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) { | |
| 83 | + PageResult<DiscountActivityDO> pageResult = discountActivityService.getDiscountActivityPage(pageVO); | |
| 84 | + return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult)); | |
| 85 | + } | |
| 86 | + | |
| 87 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/package-info.java deleted
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.ObjectUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 5 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; | |
| 6 | +import com.fasterxml.jackson.annotation.JsonIgnore; | |
| 7 | +import io.swagger.annotations.ApiModel; | |
| 8 | +import io.swagger.annotations.ApiModelProperty; | |
| 9 | +import lombok.Data; | |
| 10 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 11 | + | |
| 12 | +import javax.validation.constraints.AssertTrue; | |
| 13 | +import javax.validation.constraints.Min; | |
| 14 | +import javax.validation.constraints.NotNull; | |
| 15 | +import java.util.Date; | |
| 16 | + | |
| 17 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 18 | + | |
| 19 | +/** | |
| 20 | +* 限时折扣活动 Base VO,提供给添加、修改、详细的子 VO 使用 | |
| 21 | +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | |
| 22 | +*/ | |
| 23 | +@Data | |
| 24 | +public class DiscountActivityBaseVO { | |
| 25 | + | |
| 26 | + @ApiModelProperty(value = "活动标题", required = true, example = "一个标题") | |
| 27 | + @NotNull(message = "活动标题不能为空") | |
| 28 | + private String name; | |
| 29 | + | |
| 30 | + @ApiModelProperty(value = "开始时间", required = true) | |
| 31 | + @NotNull(message = "开始时间不能为空") | |
| 32 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 33 | + private Date startTime; | |
| 34 | + | |
| 35 | + @ApiModelProperty(value = "结束时间", required = true) | |
| 36 | + @NotNull(message = "结束时间不能为空") | |
| 37 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 38 | + private Date endTime; | |
| 39 | + | |
| 40 | + @ApiModelProperty(value = "备注", example = "我是备注") | |
| 41 | + private String remark; | |
| 42 | + | |
| 43 | + @ApiModel("商品") | |
| 44 | + @Data | |
| 45 | + public static class Product { | |
| 46 | + | |
| 47 | + @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") | |
| 48 | + @NotNull(message = "商品 SPU 编号不能为空") | |
| 49 | + private Long spuId; | |
| 50 | + | |
| 51 | + @ApiModelProperty(value = "商品 SKU 编号", required = true, example = "1") | |
| 52 | + @NotNull(message = "商品 SKU 编号不能为空") | |
| 53 | + private Long skuId; | |
| 54 | + | |
| 55 | + @ApiModelProperty(value = "优惠类型", required = true, example = "1", notes = "参见 PromotionDiscountTypeEnum 枚举") | |
| 56 | + @NotNull(message = "优惠类型不能为空") | |
| 57 | + @InEnum(PromotionDiscountTypeEnum.class) | |
| 58 | + private Integer discountType; | |
| 59 | + | |
| 60 | + @ApiModelProperty(value = "折扣百分比", example = "80", notes = "例如说,80% 为 80") | |
| 61 | + private Integer discountPercent; | |
| 62 | + | |
| 63 | + @ApiModelProperty(value = "优惠金额", example = "10", notes = "单位:分") | |
| 64 | + @Min(value = 0, message = "优惠金额需要大于等于 0") | |
| 65 | + private Integer discountPrice; | |
| 66 | + | |
| 67 | + @AssertTrue(message = "折扣百分比需要大于等于 1,小于等于 99") | |
| 68 | + @JsonIgnore | |
| 69 | + public boolean isDiscountPercentValid() { | |
| 70 | + return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType()) | |
| 71 | + || (discountPercent != null && discountPercent >= 1 && discountPercent<= 99); | |
| 72 | + } | |
| 73 | + | |
| 74 | + @AssertTrue(message = "优惠金额不能为空") | |
| 75 | + @JsonIgnore | |
| 76 | + public boolean isDiscountPriceValid() { | |
| 77 | + return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PRICE.getType()) | |
| 78 | + || discountPrice != null; | |
| 79 | + } | |
| 80 | + | |
| 81 | + } | |
| 82 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import lombok.Data; | |
| 5 | +import lombok.EqualsAndHashCode; | |
| 6 | +import lombok.ToString; | |
| 7 | + | |
| 8 | +import javax.validation.Valid; | |
| 9 | +import javax.validation.constraints.NotEmpty; | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 12 | +@ApiModel("管理后台 - 限时折扣活动创建 Request VO") | |
| 13 | +@Data | |
| 14 | +@EqualsAndHashCode(callSuper = true) | |
| 15 | +@ToString(callSuper = true) | |
| 16 | +public class DiscountActivityCreateReqVO extends DiscountActivityBaseVO { | |
| 17 | + | |
| 18 | + /** | |
| 19 | + * 商品列表 | |
| 20 | + */ | |
| 21 | + @NotEmpty(message = "商品列表不能为空") | |
| 22 | + @Valid | |
| 23 | + private List<Product> products; | |
| 24 | + | |
| 25 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import lombok.Data; | |
| 5 | +import lombok.EqualsAndHashCode; | |
| 6 | +import lombok.ToString; | |
| 7 | + | |
| 8 | +import java.util.List; | |
| 9 | + | |
| 10 | +@ApiModel("管理后台 - 限时折扣活动的详细 Response VO") | |
| 11 | +@Data | |
| 12 | +@EqualsAndHashCode(callSuper = true) | |
| 13 | +@ToString(callSuper = true) | |
| 14 | +public class DiscountActivityDetailRespVO extends DiscountActivityRespVO { | |
| 15 | + | |
| 16 | + /** | |
| 17 | + * 商品列表 | |
| 18 | + */ | |
| 19 | + private List<Product> products; | |
| 20 | + | |
| 21 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import java.util.*; | |
| 5 | +import io.swagger.annotations.*; | |
| 6 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 7 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 8 | + | |
| 9 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 10 | + | |
| 11 | +@ApiModel("管理后台 - 限时折扣活动分页 Request VO") | |
| 12 | +@Data | |
| 13 | +@EqualsAndHashCode(callSuper = true) | |
| 14 | +@ToString(callSuper = true) | |
| 15 | +public class DiscountActivityPageReqVO extends PageParam { | |
| 16 | + | |
| 17 | + @ApiModelProperty(value = "活动标题", example = "一个标题") | |
| 18 | + private String name; | |
| 19 | + | |
| 20 | + @ApiModelProperty(value = "活动状态", example = "1") | |
| 21 | + private Integer status; | |
| 22 | + | |
| 23 | + @ApiModelProperty(value = "创建时间") | |
| 24 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 25 | + private Date[] createTime; | |
| 26 | + | |
| 27 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +import javax.validation.constraints.NotNull; | |
| 10 | +import java.util.Date; | |
| 11 | + | |
| 12 | +@ApiModel("管理后台 - 限时折扣活动 Response VO") | |
| 13 | +@Data | |
| 14 | +@EqualsAndHashCode(callSuper = true) | |
| 15 | +@ToString(callSuper = true) | |
| 16 | +public class DiscountActivityRespVO extends DiscountActivityBaseVO { | |
| 17 | + | |
| 18 | + @ApiModelProperty(value = "活动编号", required = true, example = "1024") | |
| 19 | + private Long id; | |
| 20 | + | |
| 21 | + @ApiModelProperty(value = "活动状态", required = true, example = "1") | |
| 22 | + @NotNull(message = "活动状态不能为空") | |
| 23 | + private Integer status; | |
| 24 | + | |
| 25 | + @ApiModelProperty(value = "创建时间", required = true) | |
| 26 | + private Date createTime; | |
| 27 | + | |
| 28 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; | |
| 2 | + | |
| 3 | +import io.swagger.annotations.ApiModel; | |
| 4 | +import io.swagger.annotations.ApiModelProperty; | |
| 5 | +import lombok.Data; | |
| 6 | +import lombok.EqualsAndHashCode; | |
| 7 | +import lombok.ToString; | |
| 8 | + | |
| 9 | +import javax.validation.Valid; | |
| 10 | +import javax.validation.constraints.NotEmpty; | |
| 11 | +import javax.validation.constraints.NotNull; | |
| 12 | +import java.util.List; | |
| 13 | + | |
| 14 | +@ApiModel("管理后台 - 限时折扣活动更新 Request VO") | |
| 15 | +@Data | |
| 16 | +@EqualsAndHashCode(callSuper = true) | |
| 17 | +@ToString(callSuper = true) | |
| 18 | +public class DiscountActivityUpdateReqVO extends DiscountActivityBaseVO { | |
| 19 | + | |
| 20 | + @ApiModelProperty(value = "活动编号", required = true, example = "1024") | |
| 21 | + @NotNull(message = "活动编号不能为空") | |
| 22 | + private Long id; | |
| 23 | + | |
| 24 | + /** | |
| 25 | + * 商品列表 | |
| 26 | + */ | |
| 27 | + @NotEmpty(message = "商品列表不能为空") | |
| 28 | + @Valid | |
| 29 | + private List<DiscountActivityCreateReqVO.Product> products; | |
| 30 | + | |
| 31 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.reward; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; | |
| 7 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityRespVO; | |
| 8 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; | |
| 9 | +import cn.iocoder.yudao.module.promotion.convert.reward.RewardActivityConvert; | |
| 10 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; | |
| 11 | +import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; | |
| 12 | +import io.swagger.annotations.Api; | |
| 13 | +import io.swagger.annotations.ApiImplicitParam; | |
| 14 | +import io.swagger.annotations.ApiOperation; | |
| 15 | +import org.springframework.security.access.prepost.PreAuthorize; | |
| 16 | +import org.springframework.validation.annotation.Validated; | |
| 17 | +import org.springframework.web.bind.annotation.*; | |
| 18 | + | |
| 19 | +import javax.annotation.Resource; | |
| 20 | +import javax.validation.Valid; | |
| 21 | + | |
| 22 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 23 | + | |
| 24 | +@Api(tags = "管理后台 - 满减送活动") | |
| 25 | +@RestController | |
| 26 | +@RequestMapping("/promotion/reward-activity") | |
| 27 | +@Validated | |
| 28 | +public class RewardActivityController { | |
| 29 | + | |
| 30 | + @Resource | |
| 31 | + private RewardActivityService rewardActivityService; | |
| 32 | + | |
| 33 | + @PostMapping("/create") | |
| 34 | + @ApiOperation("创建满减送活动") | |
| 35 | + @PreAuthorize("@ss.hasPermission('promotion:reward-activity:create')") | |
| 36 | + public CommonResult<Long> createRewardActivity(@Valid @RequestBody RewardActivityCreateReqVO createReqVO) { | |
| 37 | + return success(rewardActivityService.createRewardActivity(createReqVO)); | |
| 38 | + } | |
| 39 | + | |
| 40 | + @PutMapping("/update") | |
| 41 | + @ApiOperation("更新满减送活动") | |
| 42 | + @PreAuthorize("@ss.hasPermission('promotion:reward-activity:update')") | |
| 43 | + public CommonResult<Boolean> updateRewardActivity(@Valid @RequestBody RewardActivityUpdateReqVO updateReqVO) { | |
| 44 | + rewardActivityService.updateRewardActivity(updateReqVO); | |
| 45 | + return success(true); | |
| 46 | + } | |
| 47 | + | |
| 48 | + @PutMapping("/close") | |
| 49 | + @ApiOperation("关闭满减送活动") | |
| 50 | + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) | |
| 51 | + @PreAuthorize("@ss.hasPermission('promotion:reward-activity:close')") | |
| 52 | + public CommonResult<Boolean> closeRewardActivity(@RequestParam("id") Long id) { | |
| 53 | + rewardActivityService.closeRewardActivity(id); | |
| 54 | + return success(true); | |
| 55 | + } | |
| 56 | + | |
| 57 | + @DeleteMapping("/delete") | |
| 58 | + @ApiOperation("删除满减送活动") | |
| 59 | + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) | |
| 60 | + @PreAuthorize("@ss.hasPermission('promotion:reward-activity:delete')") | |
| 61 | + public CommonResult<Boolean> deleteRewardActivity(@RequestParam("id") Long id) { | |
| 62 | + rewardActivityService.deleteRewardActivity(id); | |
| 63 | + return success(true); | |
| 64 | + } | |
| 65 | + | |
| 66 | + @GetMapping("/get") | |
| 67 | + @ApiOperation("获得满减送活动") | |
| 68 | + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) | |
| 69 | + @PreAuthorize("@ss.hasPermission('promotion:reward-activity:query')") | |
| 70 | + public CommonResult<RewardActivityRespVO> getRewardActivity(@RequestParam("id") Long id) { | |
| 71 | + RewardActivityDO rewardActivity = rewardActivityService.getRewardActivity(id); | |
| 72 | + return success(RewardActivityConvert.INSTANCE.convert(rewardActivity)); | |
| 73 | + } | |
| 74 | + | |
| 75 | + @GetMapping("/page") | |
| 76 | + @ApiOperation("获得满减送活动分页") | |
| 77 | + @PreAuthorize("@ss.hasPermission('promotion:reward-activity:query')") | |
| 78 | + public CommonResult<PageResult<RewardActivityRespVO>> getRewardActivityPage(@Valid RewardActivityPageReqVO pageVO) { | |
| 79 | + PageResult<RewardActivityDO> pageResult = rewardActivityService.getRewardActivityPage(pageVO); | |
| 80 | + return success(RewardActivityConvert.INSTANCE.convertPage(pageResult)); | |
| 81 | + } | |
| 82 | + | |
| 83 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 5 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; | |
| 6 | +import com.fasterxml.jackson.annotation.JsonIgnore; | |
| 7 | +import io.swagger.annotations.ApiModel; | |
| 8 | +import io.swagger.annotations.ApiModelProperty; | |
| 9 | +import lombok.Data; | |
| 10 | +import org.springframework.format.annotation.DateTimeFormat; | |
| 11 | + | |
| 12 | +import javax.validation.Valid; | |
| 13 | +import javax.validation.constraints.AssertTrue; | |
| 14 | +import javax.validation.constraints.Future; | |
| 15 | +import javax.validation.constraints.Min; | |
| 16 | +import javax.validation.constraints.NotNull; | |
| 17 | +import java.util.Date; | |
| 18 | +import java.util.List; | |
| 19 | + | |
| 20 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 21 | + | |
| 22 | +/** | |
| 23 | +* 满减送活动 Base VO,提供给添加、修改、详细的子 VO 使用 | |
| 24 | +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | |
| 25 | +*/ | |
| 26 | +@Data | |
| 27 | +public class RewardActivityBaseVO { | |
| 28 | + | |
| 29 | + @ApiModelProperty(value = "活动标题", required = true, example = "满啦满啦") | |
| 30 | + @NotNull(message = "活动标题不能为空") | |
| 31 | + private String name; | |
| 32 | + | |
| 33 | + @ApiModelProperty(value = "开始时间", required = true) | |
| 34 | + @NotNull(message = "开始时间不能为空") | |
| 35 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 36 | + private Date startTime; | |
| 37 | + | |
| 38 | + @ApiModelProperty(value = "结束时间", required = true) | |
| 39 | + @NotNull(message = "结束时间不能为空") | |
| 40 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 41 | + @Future(message = "结束时间必须大于当前时间") | |
| 42 | + private Date endTime; | |
| 43 | + | |
| 44 | + @ApiModelProperty(value = "备注", example = "biubiubiu") | |
| 45 | + private String remark; | |
| 46 | + | |
| 47 | + @ApiModelProperty(value = "条件类型", required = true, example = "1") | |
| 48 | + @NotNull(message = "条件类型不能为空") | |
| 49 | + @InEnum(value = PromotionConditionTypeEnum.class, message = "条件类型必须是 {value}") | |
| 50 | + private Integer conditionType; | |
| 51 | + | |
| 52 | + @ApiModelProperty(value = "商品范围", required = true, example = "1") | |
| 53 | + @NotNull(message = "商品范围不能为空") | |
| 54 | + @InEnum(value = PromotionConditionTypeEnum.class, message = "商品范围必须是 {value}") | |
| 55 | + private Integer productScope; | |
| 56 | + | |
| 57 | + @ApiModelProperty(value = "商品 SPU 编号的数组", example = "1,2,3") | |
| 58 | + private List<Long> productSpuIds; | |
| 59 | + | |
| 60 | + /** | |
| 61 | + * 优惠规则的数组 | |
| 62 | + */ | |
| 63 | + @Valid // 校验下子对象 | |
| 64 | + private List<Rule> rules; | |
| 65 | + | |
| 66 | + @ApiModel("优惠规则") | |
| 67 | + @Data | |
| 68 | + public static class Rule { | |
| 69 | + | |
| 70 | + @ApiModelProperty(value = "优惠门槛", required = true, example = "100", notes = "1. 满 N 元,单位:分; 2. 满 N 件") | |
| 71 | + @Min(value = 1L, message = "优惠门槛必须大于等于 1") | |
| 72 | + private Integer limit; | |
| 73 | + | |
| 74 | + @ApiModelProperty(value = "优惠价格", required = true, example = "100", notes = "单位:分") | |
| 75 | + @Min(value = 1L, message = "优惠价格必须大于等于 1") | |
| 76 | + private Integer discountPrice; | |
| 77 | + | |
| 78 | + @ApiModelProperty(value = "是否包邮", required = true, example = "true") | |
| 79 | + private Boolean freeDelivery; | |
| 80 | + | |
| 81 | + @ApiModelProperty(value = "赠送的积分", required = true, example = "100") | |
| 82 | + @Min(value = 1L, message = "赠送的积分必须大于等于 1") | |
| 83 | + private Integer point; | |
| 84 | + | |
| 85 | + @ApiModelProperty(value = "赠送的优惠劵编号的数组", example = "1,2,3") | |
| 86 | + private List<Long> couponIds; | |
| 87 | + | |
| 88 | + @ApiModelProperty(value = "赠送的优惠卷数量的数组", example = "1,2,3") | |
| 89 | + private List<Integer> couponCounts; | |
| 90 | + | |
| 91 | + @AssertTrue(message = "优惠劵和数量必须一一对应") | |
| 92 | + @JsonIgnore | |
| 93 | + public boolean isCouponCountsValid() { | |
| 94 | + return CollUtil.size(couponCounts) == CollUtil.size(couponCounts); | |
| 95 | + } | |
| 96 | + | |
| 97 | + } | |
| 98 | + | |
| 99 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import io.swagger.annotations.*; | |
| 5 | + | |
| 6 | +@ApiModel("管理后台 - 满减送活动创建 Request VO") | |
| 7 | +@Data | |
| 8 | +@EqualsAndHashCode(callSuper = true) | |
| 9 | +@ToString(callSuper = true) | |
| 10 | +public class RewardActivityCreateReqVO extends RewardActivityBaseVO { | |
| 11 | + | |
| 12 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import io.swagger.annotations.*; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 6 | + | |
| 7 | +@ApiModel("管理后台 - 满减送活动分页 Request VO") | |
| 8 | +@Data | |
| 9 | +@EqualsAndHashCode(callSuper = true) | |
| 10 | +@ToString(callSuper = true) | |
| 11 | +public class RewardActivityPageReqVO extends PageParam { | |
| 12 | + | |
| 13 | + @ApiModelProperty(value = "活动标题", example = "满啦满啦") | |
| 14 | + private String name; | |
| 15 | + | |
| 16 | + @ApiModelProperty(value = "活动状态", example = "1") | |
| 17 | + private Integer status; | |
| 18 | + | |
| 19 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import java.util.*; | |
| 5 | +import io.swagger.annotations.*; | |
| 6 | + | |
| 7 | +@ApiModel("管理后台 - 满减送活动 Response VO") | |
| 8 | +@Data | |
| 9 | +@EqualsAndHashCode(callSuper = true) | |
| 10 | +@ToString(callSuper = true) | |
| 11 | +public class RewardActivityRespVO extends RewardActivityBaseVO { | |
| 12 | + | |
| 13 | + @ApiModelProperty(value = "活动编号", required = true, example = "1024") | |
| 14 | + private Integer id; | |
| 15 | + | |
| 16 | + @ApiModelProperty(value = "活动状态", required = true, example = "1") | |
| 17 | + private Integer status; | |
| 18 | + | |
| 19 | + @ApiModelProperty(value = "创建时间", required = true) | |
| 20 | + private Date createTime; | |
| 21 | + | |
| 22 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; | |
| 2 | + | |
| 3 | +import lombok.*; | |
| 4 | +import io.swagger.annotations.*; | |
| 5 | +import javax.validation.constraints.*; | |
| 6 | + | |
| 7 | +@ApiModel("管理后台 - 满减送活动更新 Request VO") | |
| 8 | +@Data | |
| 9 | +@EqualsAndHashCode(callSuper = true) | |
| 10 | +@ToString(callSuper = true) | |
| 11 | +public class RewardActivityUpdateReqVO extends RewardActivityBaseVO { | |
| 12 | + | |
| 13 | + @ApiModelProperty(value = "活动编号", required = true, example = "1024") | |
| 14 | + @NotNull(message = "活动编号不能为空") | |
| 15 | + private Long id; | |
| 16 | + | |
| 17 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.convert.coupon; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageItemRespVO; | |
| 5 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; | |
| 6 | +import org.mapstruct.Mapper; | |
| 7 | +import org.mapstruct.factory.Mappers; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * 优惠劵 Convert | |
| 11 | + * | |
| 12 | + * @author 芋道源码 | |
| 13 | + */ | |
| 14 | +@Mapper | |
| 15 | +public interface CouponConvert { | |
| 16 | + | |
| 17 | + CouponConvert INSTANCE = Mappers.getMapper(CouponConvert.class); | |
| 18 | + | |
| 19 | + PageResult<CouponPageItemRespVO> convertPage(PageResult<CouponDO> page); | |
| 20 | + | |
| 21 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.convert.coupon; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateCreateReqVO; | |
| 5 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateRespVO; | |
| 6 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateUpdateReqVO; | |
| 4 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; | |
| 5 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateRespVO; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; | |
| 7 | 7 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; |
| 8 | 8 | import org.mapstruct.Mapper; |
| 9 | 9 | import org.mapstruct.factory.Mappers; | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.convert.discount; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.ObjectUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 5 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 6 | +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | |
| 7 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*; | |
| 8 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; | |
| 9 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; | |
| 10 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; | |
| 11 | +import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; | |
| 12 | +import org.mapstruct.Mapper; | |
| 13 | +import org.mapstruct.factory.Mappers; | |
| 14 | + | |
| 15 | +import java.util.List; | |
| 16 | +import java.util.Map; | |
| 17 | + | |
| 18 | +/** | |
| 19 | + * 限时折扣活动 Convert | |
| 20 | + * | |
| 21 | + * @author 芋道源码 | |
| 22 | + */ | |
| 23 | +@Mapper | |
| 24 | +public interface DiscountActivityConvert { | |
| 25 | + | |
| 26 | + DiscountActivityConvert INSTANCE = Mappers.getMapper(DiscountActivityConvert.class); | |
| 27 | + | |
| 28 | + DiscountActivityDO convert(DiscountActivityCreateReqVO bean); | |
| 29 | + | |
| 30 | + DiscountActivityDO convert(DiscountActivityUpdateReqVO bean); | |
| 31 | + | |
| 32 | + DiscountActivityRespVO convert(DiscountActivityDO bean); | |
| 33 | + | |
| 34 | + List<DiscountActivityRespVO> convertList(List<DiscountActivityDO> list); | |
| 35 | + | |
| 36 | + PageResult<DiscountActivityRespVO> convertPage(PageResult<DiscountActivityDO> page); | |
| 37 | + | |
| 38 | + DiscountProductDetailBO convert(DiscountProductDO product); | |
| 39 | + | |
| 40 | + default List<DiscountProductDetailBO> convertList(List<DiscountProductDO> products, Map<Long, DiscountActivityDO> activityMap) { | |
| 41 | + return CollectionUtils.convertList(products, product -> { | |
| 42 | + DiscountProductDetailBO detail = convert(product); | |
| 43 | + MapUtils.findAndThen(activityMap, product.getActivityId(), activity -> { | |
| 44 | + detail.setActivityName(activity.getName()); | |
| 45 | + }); | |
| 46 | + return detail; | |
| 47 | + }); | |
| 48 | + } | |
| 49 | + | |
| 50 | + DiscountProductDO convert(DiscountActivityBaseVO.Product bean); | |
| 51 | + | |
| 52 | + DiscountActivityDetailRespVO convert(DiscountActivityDO activity, List<DiscountProductDO> products); | |
| 53 | + | |
| 54 | + // =========== 比较是否相等 ========== | |
| 55 | + /** | |
| 56 | + * 比较两个限时折扣商品是否相等 | |
| 57 | + * | |
| 58 | + * @param productDO 数据库中的商品 | |
| 59 | + * @param productVO 前端传入的商品 | |
| 60 | + * @return 是否匹配 | |
| 61 | + */ | |
| 62 | + @SuppressWarnings("DuplicatedCode") | |
| 63 | + default boolean isEquals(DiscountProductDO productDO, DiscountActivityBaseVO.Product productVO) { | |
| 64 | + if (ObjectUtil.notEqual(productDO.getSpuId(), productVO.getSpuId()) | |
| 65 | + || ObjectUtil.notEqual(productDO.getSkuId(), productVO.getSkuId()) | |
| 66 | + || ObjectUtil.notEqual(productDO.getDiscountType(), productVO.getDiscountType())) { | |
| 67 | + return false; | |
| 68 | + } | |
| 69 | + if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PRICE.getType())) { | |
| 70 | + return ObjectUtil.equal(productDO.getDiscountPrice(), productVO.getDiscountPrice()); | |
| 71 | + } | |
| 72 | + if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PERCENT.getType())) { | |
| 73 | + return ObjectUtil.equal(productDO.getDiscountPercent(), productVO.getDiscountPercent()); | |
| 74 | + } | |
| 75 | + return true; | |
| 76 | + } | |
| 77 | + | |
| 78 | + /** | |
| 79 | + * 比较两个限时折扣商品是否相等 | |
| 80 | + * 注意,比较时忽略 id 编号 | |
| 81 | + * | |
| 82 | + * @param productDO 商品 1 | |
| 83 | + * @param productVO 商品 2 | |
| 84 | + * @return 是否匹配 | |
| 85 | + */ | |
| 86 | + @SuppressWarnings("DuplicatedCode") | |
| 87 | + default boolean isEquals(DiscountProductDO productDO, DiscountProductDO productVO) { | |
| 88 | + if (ObjectUtil.notEqual(productDO.getSpuId(), productVO.getSpuId()) | |
| 89 | + || ObjectUtil.notEqual(productDO.getSkuId(), productVO.getSkuId()) | |
| 90 | + || ObjectUtil.notEqual(productDO.getDiscountType(), productVO.getDiscountType())) { | |
| 91 | + return false; | |
| 92 | + } | |
| 93 | + if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PRICE.getType())) { | |
| 94 | + return ObjectUtil.equal(productDO.getDiscountPrice(), productVO.getDiscountPrice()); | |
| 95 | + } | |
| 96 | + if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PERCENT.getType())) { | |
| 97 | + return ObjectUtil.equal(productDO.getDiscountPercent(), productVO.getDiscountPercent()); | |
| 98 | + } | |
| 99 | + return true; | |
| 100 | + } | |
| 101 | + | |
| 102 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/package-info.java deleted
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java
| ... | ... | @@ -36,7 +36,8 @@ public interface PriceConvert { |
| 36 | 36 | orderItem.setPayPrice(orderItem.getOriginalPrice()).setOrderDividePrice(orderItem.getOriginalPrice()); |
| 37 | 37 | priceCalculate.getOrder().getItems().add(orderItem); |
| 38 | 38 | // 补充价格信息到 Order 中 |
| 39 | - order.setOriginalPrice(order.getOriginalPrice() + orderItem.getOriginalPrice()).setPayPrice(order.getOriginalPrice()); | |
| 39 | + order.setOriginalPrice(order.getOriginalPrice() + orderItem.getOriginalPrice()) | |
| 40 | + .setOrderPrice(order.getOriginalPrice()).setPayPrice(order.getOriginalPrice()); | |
| 40 | 41 | }); |
| 41 | 42 | return priceCalculate; |
| 42 | 43 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/reward/RewardActivityConvert.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.convert.reward; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; | |
| 5 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityRespVO; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; | |
| 8 | +import org.mapstruct.Mapper; | |
| 9 | +import org.mapstruct.factory.Mappers; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * 满减送活动 Convert | |
| 13 | + * | |
| 14 | + * @author 芋道源码 | |
| 15 | + */ | |
| 16 | +@Mapper | |
| 17 | +public interface RewardActivityConvert { | |
| 18 | + | |
| 19 | + RewardActivityConvert INSTANCE = Mappers.getMapper(RewardActivityConvert.class); | |
| 20 | + | |
| 21 | + RewardActivityDO convert(RewardActivityCreateReqVO bean); | |
| 22 | + | |
| 23 | + RewardActivityDO convert(RewardActivityUpdateReqVO bean); | |
| 24 | + | |
| 25 | + RewardActivityRespVO convert(RewardActivityDO bean); | |
| 26 | + | |
| 27 | + PageResult<RewardActivityRespVO> convertPage(PageResult<RewardActivityDO> page); | |
| 28 | + | |
| 29 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.dal.dataobject.coupon; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; | |
| 5 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; | |
| 4 | 6 | import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; |
| 7 | +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; | |
| 8 | +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; | |
| 5 | 9 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 6 | 10 | import com.baomidou.mybatisplus.annotation.TableField; |
| 7 | 11 | import com.baomidou.mybatisplus.annotation.TableName; |
| 8 | -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | |
| 9 | 12 | import lombok.Data; |
| 10 | 13 | import lombok.EqualsAndHashCode; |
| 11 | 14 | |
| ... | ... | @@ -14,9 +17,11 @@ import java.util.List; |
| 14 | 17 | |
| 15 | 18 | /** |
| 16 | 19 | * 优惠劵 DO |
| 20 | + * | |
| 21 | + * @author 芋道源码 | |
| 17 | 22 | */ |
| 18 | 23 | @TableName(value = "promotion_coupon", autoResultMap = true) |
| 19 | -@KeySequence("promotion_coupo_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | |
| 24 | +@KeySequence("promotion_coupon_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | |
| 20 | 25 | @Data |
| 21 | 26 | @EqualsAndHashCode(callSuper = true) |
| 22 | 27 | public class CouponDO extends BaseDO { |
| ... | ... | @@ -35,21 +40,13 @@ public class CouponDO extends BaseDO { |
| 35 | 40 | /** |
| 36 | 41 | * 优惠劵名 |
| 37 | 42 | * |
| 38 | - * 冗余自 {@link CouponTemplateDO} 的 title | |
| 39 | - * | |
| 40 | - * TODO 芋艿,暂时不考虑冗余的更新 | |
| 43 | + * 冗余 {@link CouponTemplateDO#getName()} | |
| 41 | 44 | */ |
| 42 | - private String title; | |
| 43 | -// /** | |
| 44 | -// * 核销码 | |
| 45 | -// */ | |
| 46 | -// private String verifyCode; | |
| 45 | + private String name; | |
| 47 | 46 | /** |
| 48 | 47 | * 优惠码状态 |
| 49 | 48 | * |
| 50 | - * 1-未使用 | |
| 51 | - * 2-已使用 | |
| 52 | - * 3-已失效 | |
| 49 | + * 枚举 {@link CouponStatusEnum} | |
| 53 | 50 | */ |
| 54 | 51 | private Integer status; |
| 55 | 52 | |
| ... | ... | @@ -58,13 +55,14 @@ public class CouponDO extends BaseDO { |
| 58 | 55 | // ========== 领取情况 BEGIN ========== |
| 59 | 56 | /** |
| 60 | 57 | * 用户编号 |
| 58 | + * | |
| 59 | + * 关联 MemberUserDO 的 id 字段 | |
| 61 | 60 | */ |
| 62 | - private Integer userId; | |
| 61 | + private Long userId; | |
| 63 | 62 | /** |
| 64 | 63 | * 领取类型 |
| 65 | 64 | * |
| 66 | - * 1 - 用户主动领取 | |
| 67 | - * 2 - 后台自动发放 | |
| 65 | + * 枚举 {@link CouponTakeTypeEnum} | |
| 68 | 66 | */ |
| 69 | 67 | private Integer takeType; |
| 70 | 68 | // ========== 领取情况 END ========== |
| ... | ... | @@ -72,8 +70,10 @@ public class CouponDO extends BaseDO { |
| 72 | 70 | // ========== 使用规则 BEGIN ========== |
| 73 | 71 | /** |
| 74 | 72 | * 是否设置满多少金额可用,单位:分 |
| 73 | + * | |
| 74 | + * 冗余 {@link CouponTemplateDO#getUsePrice()} | |
| 75 | 75 | */ |
| 76 | - private Integer priceAvailable; | |
| 76 | + private Integer usePrice; | |
| 77 | 77 | /** |
| 78 | 78 | * 生效开始时间 |
| 79 | 79 | */ |
| ... | ... | @@ -90,50 +90,49 @@ public class CouponDO extends BaseDO { |
| 90 | 90 | private Integer productScope; |
| 91 | 91 | /** |
| 92 | 92 | * 商品 SPU 编号的数组 |
| 93 | + * | |
| 94 | + * 冗余 {@link CouponTemplateDO#getProductSpuIds()} | |
| 93 | 95 | */ |
| 94 | - @TableField(typeHandler = JacksonTypeHandler.class) | |
| 95 | - private List<Long> spuIds; | |
| 96 | + @TableField(typeHandler = LongListTypeHandler.class) | |
| 97 | + private List<Long> productSpuIds; | |
| 96 | 98 | // ========== 使用规则 END ========== |
| 97 | 99 | |
| 98 | 100 | // ========== 使用效果 BEGIN ========== |
| 99 | 101 | /** |
| 100 | - * 优惠类型 | |
| 102 | + * 折扣类型 | |
| 101 | 103 | * |
| 102 | - * 1-代金卷 | |
| 103 | - * 2-折扣卷 | |
| 104 | + * 冗余 {@link CouponTemplateDO#getDiscountType()} | |
| 104 | 105 | */ |
| 105 | - private Integer preferentialType; | |
| 106 | + private Integer discountType; | |
| 106 | 107 | /** |
| 107 | - * 折扣 | |
| 108 | + * 折扣百分比 | |
| 109 | + * | |
| 110 | + * 冗余 {@link CouponTemplateDO#getDiscountPercent()} | |
| 108 | 111 | */ |
| 109 | - private Integer percentOff; | |
| 112 | + private Integer discountPercent; | |
| 110 | 113 | /** |
| 111 | - * 优惠金额,单位:分。 | |
| 114 | + * 优惠金额,单位:分 | |
| 115 | + * | |
| 116 | + * 冗余 {@link CouponTemplateDO#getDiscountPrice()} | |
| 112 | 117 | */ |
| 113 | - private Integer priceOff; | |
| 118 | + private Integer discountPrice; | |
| 114 | 119 | /** |
| 115 | - * 折扣上限,仅在 {@link #preferentialType} 等于 2 时生效。 | |
| 120 | + * 折扣上限,仅在 {@link #discountType} 等于 {@link PromotionDiscountTypeEnum#PERCENT} 时生效 | |
| 116 | 121 | * |
| 117 | - * 例如,折扣上限为 20 元,当使用 8 折优惠券,订单金额为 1000 元时,最高只可折扣 20 元,而非 80 元。 | |
| 122 | + * 冗余 {@link CouponTemplateDO#getDiscountLimitPrice()} | |
| 118 | 123 | */ |
| 119 | - private Integer discountPriceLimit; | |
| 124 | + private Integer discountLimitPrice; | |
| 120 | 125 | // ========== 使用效果 END ========== |
| 121 | 126 | |
| 122 | 127 | // ========== 使用情况 BEGIN ========== |
| 123 | -// /** | |
| 124 | -// * 使用订单号 | |
| 125 | -// */ | |
| 126 | -// private Integer usedOrderId; // TODO 芋艿,暂时不考虑这个字段 | |
| 127 | -// /** | |
| 128 | -// * 订单中优惠面值,单位:分 | |
| 129 | -// */ | |
| 130 | -// private Integer usedPrice; // TODO 芋艿,暂时不考虑这个字段 | |
| 128 | + /** | |
| 129 | + * 使用订单号 | |
| 130 | + */ | |
| 131 | + private Long useOrderId; | |
| 131 | 132 | /** |
| 132 | 133 | * 使用时间 |
| 133 | 134 | */ |
| 134 | - private Date usedTime; | |
| 135 | - | |
| 136 | - // TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。 | |
| 135 | + private Date useTime; | |
| 137 | 136 | |
| 138 | 137 | // ========== 使用情况 END ========== |
| 139 | 138 | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java
| ... | ... | @@ -21,6 +21,8 @@ import java.util.List; |
| 21 | 21 | * 优惠劵模板 DO |
| 22 | 22 | * |
| 23 | 23 | * 当用户领取时,会生成 {@link CouponDO} 优惠劵 |
| 24 | + * | |
| 25 | + * @author 芋道源码 | |
| 24 | 26 | */ |
| 25 | 27 | @TableName(value = "promotion_coupon_template", autoResultMap = true) |
| 26 | 28 | @KeySequence("promotion_coupon_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.dal.dataobject.discount; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; | |
| 4 | 5 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 5 | 6 | import com.baomidou.mybatisplus.annotation.TableId; |
| 6 | 7 | import com.baomidou.mybatisplus.annotation.TableName; |
| 7 | 8 | import lombok.Data; |
| 8 | 9 | import lombok.EqualsAndHashCode; |
| 9 | 10 | |
| 10 | -import java.util.Date; | |
| 11 | - | |
| 12 | 11 | /** |
| 13 | 12 | * 限时折扣商品 DO |
| 14 | 13 | * |
| ... | ... | @@ -32,12 +31,6 @@ public class DiscountProductDO extends BaseDO { |
| 32 | 31 | */ |
| 33 | 32 | private Long activityId; |
| 34 | 33 | /** |
| 35 | - * 限时折扣活动的名字 | |
| 36 | - * | |
| 37 | - * 冗余 {@link DiscountActivityDO#getName()} | |
| 38 | - */ | |
| 39 | - private String activityName; | |
| 40 | - /** | |
| 41 | 34 | * 商品 SPU 编号 |
| 42 | 35 | * |
| 43 | 36 | * 关联 ProductSpuDO 的 id 编号 |
| ... | ... | @@ -49,23 +42,24 @@ public class DiscountProductDO extends BaseDO { |
| 49 | 42 | * 关联 ProductSkuDO 的 id 编号 |
| 50 | 43 | */ |
| 51 | 44 | private Long skuId; |
| 45 | + | |
| 52 | 46 | /** |
| 53 | - * 开始时间 | |
| 54 | - */ | |
| 55 | - private Date startTime; | |
| 56 | - /** | |
| 57 | - * 结束时间 | |
| 47 | + * 折扣类型 | |
| 48 | + * | |
| 49 | + * 枚举 {@link PromotionDiscountTypeEnum} | |
| 58 | 50 | */ |
| 59 | - private Date endTime; | |
| 51 | + private Integer discountType; | |
| 60 | 52 | /** |
| 61 | - * 销售价格,单位:分 | |
| 53 | + * 折扣百分比 | |
| 62 | 54 | * |
| 63 | - * 冗余 ProductSkuDO 的 price 字段 | |
| 55 | + * 例如,80% 为 80 | |
| 64 | 56 | */ |
| 65 | - private Integer originalPrice; | |
| 57 | + private Integer discountPercent; | |
| 66 | 58 | /** |
| 67 | - * 优惠价格,单位:分 | |
| 59 | + * 优惠金额,单位:分 | |
| 60 | + * | |
| 61 | + * 当 {@link #discountType} 为 {@link PromotionDiscountTypeEnum#PRICE} 生效 | |
| 68 | 62 | */ |
| 69 | - private Integer promotionPrice; | |
| 63 | + private Integer discountPrice; | |
| 70 | 64 | |
| 71 | 65 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.dal.dataobject.reward; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |
| 3 | 4 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; | |
| 4 | 6 | import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; |
| 5 | 7 | import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; |
| 6 | 8 | import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; |
| ... | ... | @@ -8,10 +10,11 @@ import com.baomidou.mybatisplus.annotation.KeySequence; |
| 8 | 10 | import com.baomidou.mybatisplus.annotation.TableField; |
| 9 | 11 | import com.baomidou.mybatisplus.annotation.TableId; |
| 10 | 12 | import com.baomidou.mybatisplus.annotation.TableName; |
| 11 | -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | |
| 13 | +import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; | |
| 12 | 14 | import lombok.Data; |
| 13 | 15 | import lombok.EqualsAndHashCode; |
| 14 | 16 | |
| 17 | +import java.io.Serializable; | |
| 15 | 18 | import java.util.Date; |
| 16 | 19 | import java.util.List; |
| 17 | 20 | |
| ... | ... | @@ -68,19 +71,19 @@ public class RewardActivityDO extends BaseDO { |
| 68 | 71 | /** |
| 69 | 72 | * 商品 SPU 编号的数组 |
| 70 | 73 | */ |
| 71 | - @TableField(typeHandler = JacksonTypeHandler.class) | |
| 74 | + @TableField(typeHandler = LongListTypeHandler.class) | |
| 72 | 75 | private List<Long> productSpuIds; |
| 73 | 76 | /** |
| 74 | 77 | * 优惠规则的数组 |
| 75 | 78 | */ |
| 76 | - @TableField(typeHandler = JacksonTypeHandler.class) | |
| 79 | + @TableField(typeHandler = RuleTypeHandler.class) | |
| 77 | 80 | private List<Rule> rules; |
| 78 | 81 | |
| 79 | 82 | /** |
| 80 | 83 | * 优惠规则 |
| 81 | 84 | */ |
| 82 | 85 | @Data |
| 83 | - public static class Rule { | |
| 86 | + public static class Rule implements Serializable { | |
| 84 | 87 | |
| 85 | 88 | /** |
| 86 | 89 | * 优惠门槛 |
| ... | ... | @@ -112,5 +115,19 @@ public class RewardActivityDO extends BaseDO { |
| 112 | 115 | |
| 113 | 116 | } |
| 114 | 117 | |
| 118 | + // TODO @芋艿:可以找一些新的思路 | |
| 119 | + public static class RuleTypeHandler extends AbstractJsonTypeHandler<List<Rule>> { | |
| 120 | + | |
| 121 | + @Override | |
| 122 | + protected List<Rule> parse(String json) { | |
| 123 | + return JsonUtils.parseArray(json, Rule.class); | |
| 124 | + } | |
| 125 | + | |
| 126 | + @Override | |
| 127 | + protected String toJson(List<Rule> obj) { | |
| 128 | + return JsonUtils.toJsonString(obj); | |
| 129 | + } | |
| 130 | + | |
| 131 | + } | |
| 115 | 132 | |
| 116 | 133 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.dal.mysql.coupon; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; | |
| 7 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; | |
| 8 | +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | |
| 9 | +import org.apache.ibatis.annotations.Mapper; | |
| 10 | + | |
| 11 | +import java.util.Collection; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * 优惠劵 Mapper | |
| 15 | + * | |
| 16 | + * @author 芋道源码 | |
| 17 | + */ | |
| 18 | +@Mapper | |
| 19 | +public interface CouponMapper extends BaseMapperX<CouponDO> { | |
| 20 | + | |
| 21 | + default PageResult<CouponDO> selectPage(CouponPageReqVO reqVO, Collection<Long> userIds) { | |
| 22 | + return selectPage(reqVO, new LambdaQueryWrapperX<CouponDO>() | |
| 23 | + .eqIfPresent(CouponDO::getTemplateId, reqVO.getTemplateId()) | |
| 24 | + .eqIfPresent(CouponDO::getStatus, reqVO.getStatus()) | |
| 25 | + .inIfPresent(CouponDO::getUserId, userIds) | |
| 26 | + .betweenIfPresent(CouponDO::getCreateTime, reqVO.getCreateTime()) | |
| 27 | + .orderByDesc(CouponDO::getId)); | |
| 28 | + } | |
| 29 | + | |
| 30 | + default int delete(Long id, Collection<Integer> whereStatuses) { | |
| 31 | + return update(null, new LambdaUpdateWrapper<CouponDO>() | |
| 32 | + .eq(CouponDO::getId, id).in(CouponDO::getStatus, whereStatuses) | |
| 33 | + .set(CouponDO::getDeleted, 1)); | |
| 34 | + } | |
| 35 | + | |
| 36 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java
| ... | ... | @@ -3,9 +3,10 @@ package cn.iocoder.yudao.module.promotion.dal.mysql.coupon; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplatePageReqVO; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; | |
| 7 | 7 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; |
| 8 | 8 | import org.apache.ibatis.annotations.Mapper; |
| 9 | +import org.apache.ibatis.annotations.Param; | |
| 9 | 10 | |
| 10 | 11 | /** |
| 11 | 12 | * 优惠劵模板 Mapper |
| ... | ... | @@ -24,4 +25,6 @@ public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> { |
| 24 | 25 | .orderByDesc(CouponTemplateDO::getId)); |
| 25 | 26 | } |
| 26 | 27 | |
| 28 | + void updateTakeCount(@Param("id") Long id, @Param("incrCount") Integer incrCount); | |
| 29 | + | |
| 27 | 30 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountActivityMapper.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.dal.mysql.discount; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; | |
| 7 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; | |
| 8 | +import org.apache.ibatis.annotations.Mapper; | |
| 9 | + | |
| 10 | +import java.util.Collection; | |
| 11 | +import java.util.List; | |
| 12 | +import java.util.Set; | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * 限时折扣活动 Mapper | |
| 16 | + * | |
| 17 | + * @author 芋道源码 | |
| 18 | + */ | |
| 19 | +@Mapper | |
| 20 | +public interface DiscountActivityMapper extends BaseMapperX<DiscountActivityDO> { | |
| 21 | + | |
| 22 | + default PageResult<DiscountActivityDO> selectPage(DiscountActivityPageReqVO reqVO) { | |
| 23 | + return selectPage(reqVO, new LambdaQueryWrapperX<DiscountActivityDO>() | |
| 24 | + .likeIfPresent(DiscountActivityDO::getName, reqVO.getName()) | |
| 25 | + .eqIfPresent(DiscountActivityDO::getStatus, reqVO.getStatus()) | |
| 26 | + .betweenIfPresent(DiscountActivityDO::getCreateTime, reqVO.getCreateTime()) | |
| 27 | + .orderByDesc(DiscountActivityDO::getId)); | |
| 28 | + } | |
| 29 | + | |
| 30 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.dal.mysql.discount; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 4 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; | |
| 5 | +import org.apache.ibatis.annotations.Mapper; | |
| 6 | + | |
| 7 | +import java.util.Collection; | |
| 8 | +import java.util.List; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * 限时折扣商城 Mapper | |
| 12 | + * | |
| 13 | + * @author 芋道源码 | |
| 14 | + */ | |
| 15 | +@Mapper | |
| 16 | +public interface DiscountProductMapper extends BaseMapperX<DiscountProductDO> { | |
| 17 | + | |
| 18 | + default List<DiscountProductDO> selectListBySkuId(Collection<Long> skuIds) { | |
| 19 | + return selectList(DiscountProductDO::getSkuId, skuIds); | |
| 20 | + } | |
| 21 | + | |
| 22 | + default List<DiscountProductDO> selectListByActivityId(Long activityId) { | |
| 23 | + return selectList(DiscountProductDO::getActivityId, activityId); | |
| 24 | + } | |
| 25 | + | |
| 26 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/package-info.java deleted
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/reward/RewardActivityMapper.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.dal.mysql.reward; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; | |
| 7 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; | |
| 8 | +import org.apache.ibatis.annotations.Mapper; | |
| 9 | + | |
| 10 | +import java.util.Collection; | |
| 11 | +import java.util.List; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * 满减送活动 Mapper | |
| 15 | + * | |
| 16 | + * @author 芋道源码 | |
| 17 | + */ | |
| 18 | +@Mapper | |
| 19 | +public interface RewardActivityMapper extends BaseMapperX<RewardActivityDO> { | |
| 20 | + | |
| 21 | + default PageResult<RewardActivityDO> selectPage(RewardActivityPageReqVO reqVO) { | |
| 22 | + return selectPage(reqVO, new LambdaQueryWrapperX<RewardActivityDO>() | |
| 23 | + .likeIfPresent(RewardActivityDO::getName, reqVO.getName()) | |
| 24 | + .eqIfPresent(RewardActivityDO::getStatus, reqVO.getStatus()) | |
| 25 | + .orderByDesc(RewardActivityDO::getId)); | |
| 26 | + } | |
| 27 | + | |
| 28 | + default List<RewardActivityDO> selectListByStatus(Collection<Integer> statuses) { | |
| 29 | + return selectList(RewardActivityDO::getStatus, statuses); | |
| 30 | + } | |
| 31 | + | |
| 32 | + default List<RewardActivityDO> selectListByProductScopeAndStatus(Integer productScope, Integer status) { | |
| 33 | + return selectList(new LambdaQueryWrapperX<RewardActivityDO>() | |
| 34 | + .eq(RewardActivityDO::getProductScope, productScope) | |
| 35 | + .eq(RewardActivityDO::getStatus, status)); | |
| 36 | + } | |
| 37 | + | |
| 38 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.service.coupon; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; | |
| 3 | 5 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; |
| 4 | 6 | |
| 5 | 7 | /** |
| ... | ... | @@ -21,4 +23,19 @@ public interface CouponService { |
| 21 | 23 | */ |
| 22 | 24 | CouponDO validCoupon(Long id, Long userId); |
| 23 | 25 | |
| 26 | + /** | |
| 27 | + * 获得优惠劵分页 | |
| 28 | + * | |
| 29 | + * @param pageReqVO 分页查询 | |
| 30 | + * @return 优惠劵分页 | |
| 31 | + */ | |
| 32 | + PageResult<CouponDO> getCouponPage(CouponPageReqVO pageReqVO); | |
| 33 | + | |
| 34 | + /** | |
| 35 | + * 回收优惠劵 | |
| 36 | + * | |
| 37 | + * @param id 优惠劵编号 | |
| 38 | + */ | |
| 39 | + void deleteCoupon(Long id); | |
| 40 | + | |
| 24 | 41 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.service.coupon; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.util.StrUtil; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 7 | +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | |
| 8 | +import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO; | |
| 9 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; | |
| 3 | 10 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; |
| 11 | +import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponMapper; | |
| 12 | +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; | |
| 4 | 13 | import org.springframework.stereotype.Service; |
| 14 | +import org.springframework.transaction.annotation.Transactional; | |
| 5 | 15 | import org.springframework.validation.annotation.Validated; |
| 6 | 16 | |
| 17 | +import javax.annotation.Resource; | |
| 18 | +import java.util.Set; | |
| 19 | + | |
| 20 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 21 | +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_DELETE_FAIL_USED; | |
| 22 | +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NOT_EXISTS; | |
| 23 | +import static java.util.Arrays.asList; | |
| 24 | + | |
| 7 | 25 | /** |
| 8 | 26 | * 优惠劵 Service 实现类 |
| 9 | 27 | * |
| ... | ... | @@ -13,9 +31,56 @@ import org.springframework.validation.annotation.Validated; |
| 13 | 31 | @Validated |
| 14 | 32 | public class CouponServiceImpl implements CouponService { |
| 15 | 33 | |
| 34 | + @Resource | |
| 35 | + private CouponTemplateService couponTemplateService; | |
| 36 | + | |
| 37 | + @Resource | |
| 38 | + private CouponMapper couponMapper; | |
| 39 | + | |
| 40 | + @Resource | |
| 41 | + private MemberUserApi memberUserApi; | |
| 42 | + | |
| 16 | 43 | // TODO 芋艿:待实现 |
| 17 | 44 | @Override |
| 18 | 45 | public CouponDO validCoupon(Long id, Long userId) { |
| 19 | 46 | return null; |
| 20 | 47 | } |
| 48 | + | |
| 49 | + @Override | |
| 50 | + public PageResult<CouponDO> getCouponPage(CouponPageReqVO pageReqVO) { | |
| 51 | + // 获得用户编号 | |
| 52 | + Set<Long> userIds = null; | |
| 53 | + if (StrUtil.isNotEmpty(pageReqVO.getNickname())) { | |
| 54 | + userIds = CollectionUtils.convertSet(memberUserApi.getUserListByNickname(pageReqVO.getNickname()), | |
| 55 | + UserRespDTO::getId); | |
| 56 | + if (CollUtil.isEmpty(userIds)) { | |
| 57 | + return PageResult.empty(); | |
| 58 | + } | |
| 59 | + } | |
| 60 | + // 分页查询 | |
| 61 | + return couponMapper.selectPage(pageReqVO, userIds); | |
| 62 | + } | |
| 63 | + | |
| 64 | + @Override | |
| 65 | + @Transactional | |
| 66 | + public void deleteCoupon(Long id) { | |
| 67 | + // 校验存在 | |
| 68 | + validateCouponExists(id); | |
| 69 | + | |
| 70 | + // 更新优惠劵 | |
| 71 | + int deleteCount = couponMapper.delete(id, | |
| 72 | + asList(CouponStatusEnum.UNUSED.getStatus(), CouponStatusEnum.EXPIRE.getStatus())); | |
| 73 | + if (deleteCount == 0) { | |
| 74 | + throw exception(COUPON_DELETE_FAIL_USED); | |
| 75 | + } | |
| 76 | + // 减少优惠劵模板的领取数量 -1 | |
| 77 | + couponTemplateService.updateCouponTemplateTakeCount(id, -1); | |
| 78 | + } | |
| 79 | + | |
| 80 | + private void validateCouponExists(Long id) { | |
| 81 | + if (couponMapper.selectById(id) == null) { | |
| 82 | + throw exception(COUPON_NOT_EXISTS); | |
| 83 | + } | |
| 84 | + } | |
| 85 | + | |
| 21 | 86 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.service.coupon; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateCreateReqVO; | |
| 5 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplatePageReqVO; | |
| 6 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateUpdateReqVO; | |
| 4 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; | |
| 5 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; | |
| 7 | 7 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; |
| 8 | 8 | |
| 9 | 9 | import javax.validation.Valid; |
| ... | ... | @@ -31,6 +31,14 @@ public interface CouponTemplateService { |
| 31 | 31 | void updateCouponTemplate(@Valid CouponTemplateUpdateReqVO updateReqVO); |
| 32 | 32 | |
| 33 | 33 | /** |
| 34 | + * 更新优惠劵模板的状态 | |
| 35 | + * | |
| 36 | + * @param id 编号 | |
| 37 | + * @param status 状态 | |
| 38 | + */ | |
| 39 | + void updateCouponTemplateStatus(Long id, Integer status); | |
| 40 | + | |
| 41 | + /** | |
| 34 | 42 | * 删除优惠劵模板 |
| 35 | 43 | * |
| 36 | 44 | * @param id 编号 |
| ... | ... | @@ -53,4 +61,12 @@ public interface CouponTemplateService { |
| 53 | 61 | */ |
| 54 | 62 | PageResult<CouponTemplateDO> getCouponTemplatePage(CouponTemplatePageReqVO pageReqVO); |
| 55 | 63 | |
| 64 | + /** | |
| 65 | + * 更新优惠劵模板的领取数量 | |
| 66 | + * | |
| 67 | + * @param id 优惠劵模板编号 | |
| 68 | + * @param incrCount 增加数量 | |
| 69 | + */ | |
| 70 | + void updateCouponTemplateTakeCount(Long id, int incrCount); | |
| 71 | + | |
| 56 | 72 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.service.coupon; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateCreateReqVO; | |
| 5 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplatePageReqVO; | |
| 6 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateUpdateReqVO; | |
| 5 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; | |
| 7 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; | |
| 7 | 8 | import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert; |
| 8 | 9 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; |
| 9 | 10 | import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper; |
| ... | ... | @@ -30,7 +31,8 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { |
| 30 | 31 | @Override |
| 31 | 32 | public Long createCouponTemplate(CouponTemplateCreateReqVO createReqVO) { |
| 32 | 33 | // 插入 |
| 33 | - CouponTemplateDO couponTemplate = CouponTemplateConvert.INSTANCE.convert(createReqVO); | |
| 34 | + CouponTemplateDO couponTemplate = CouponTemplateConvert.INSTANCE.convert(createReqVO) | |
| 35 | + .setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 34 | 36 | couponTemplateMapper.insert(couponTemplate); |
| 35 | 37 | // 返回 |
| 36 | 38 | return couponTemplate.getId(); |
| ... | ... | @@ -51,6 +53,14 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { |
| 51 | 53 | } |
| 52 | 54 | |
| 53 | 55 | @Override |
| 56 | + public void updateCouponTemplateStatus(Long id, Integer status) { | |
| 57 | + // 校验存在 | |
| 58 | + validateCouponTemplateExists(id); | |
| 59 | + // 更新 | |
| 60 | + couponTemplateMapper.updateById(new CouponTemplateDO().setId(id).setStatus(status)); | |
| 61 | + } | |
| 62 | + | |
| 63 | + @Override | |
| 54 | 64 | public void deleteCouponTemplate(Long id) { |
| 55 | 65 | // 校验存在 |
| 56 | 66 | validateCouponTemplateExists(id); |
| ... | ... | @@ -76,4 +86,9 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { |
| 76 | 86 | return couponTemplateMapper.selectPage(pageReqVO); |
| 77 | 87 | } |
| 78 | 88 | |
| 89 | + @Override | |
| 90 | + public void updateCouponTemplateTakeCount(Long id, int incrCount) { | |
| 91 | + couponTemplateMapper.updateTakeCount(id, incrCount); | |
| 92 | + } | |
| 93 | + | |
| 79 | 94 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.service.discount; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; | |
| 5 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; | |
| 8 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; | |
| 9 | +import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; | |
| 10 | + | |
| 11 | +import javax.validation.Valid; | |
| 12 | +import java.util.Collection; | |
| 13 | +import java.util.List; | |
| 14 | +import java.util.Map; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * 限时折扣 Service 接口 | |
| 18 | + * | |
| 19 | + * @author 芋道源码 | |
| 20 | + */ | |
| 21 | +public interface DiscountActivityService { | |
| 22 | + | |
| 23 | + /** | |
| 24 | + * 基于指定 SKU 编号数组,获得匹配的限时折扣商品 | |
| 25 | + * | |
| 26 | + * 注意,匹配的条件,仅仅是日期符合,并且处于开启状态 | |
| 27 | + * | |
| 28 | + * @param skuIds SKU 编号数组 | |
| 29 | + * @return 匹配的限时折扣商品 | |
| 30 | + */ | |
| 31 | + Map<Long, DiscountProductDetailBO> getMatchDiscountProducts(Collection<Long> skuIds); | |
| 32 | + | |
| 33 | + /** | |
| 34 | + * 创建限时折扣活动 | |
| 35 | + * | |
| 36 | + * @param createReqVO 创建信息 | |
| 37 | + * @return 编号 | |
| 38 | + */ | |
| 39 | + Long createDiscountActivity(@Valid DiscountActivityCreateReqVO createReqVO); | |
| 40 | + | |
| 41 | + /** | |
| 42 | + * 更新限时折扣活动 | |
| 43 | + * | |
| 44 | + * @param updateReqVO 更新信息 | |
| 45 | + */ | |
| 46 | + void updateDiscountActivity(@Valid DiscountActivityUpdateReqVO updateReqVO); | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * 关闭限时折扣活动 | |
| 50 | + * | |
| 51 | + * @param id 编号 | |
| 52 | + */ | |
| 53 | + void closeRewardActivity(Long id); | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * 删除限时折扣活动 | |
| 57 | + * | |
| 58 | + * @param id 编号 | |
| 59 | + */ | |
| 60 | + void deleteDiscountActivity(Long id); | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * 获得限时折扣活动 | |
| 64 | + * | |
| 65 | + * @param id 编号 | |
| 66 | + * @return 限时折扣活动 | |
| 67 | + */ | |
| 68 | + DiscountActivityDO getDiscountActivity(Long id); | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * 获得限时折扣活动分页 | |
| 72 | + * | |
| 73 | + * @param pageReqVO 分页查询 | |
| 74 | + * @return 限时折扣活动分页 | |
| 75 | + */ | |
| 76 | + PageResult<DiscountActivityDO> getDiscountActivityPage(DiscountActivityPageReqVO pageReqVO); | |
| 77 | + | |
| 78 | + /** | |
| 79 | + * 获得活动编号,对应对应的商品列表 | |
| 80 | + * | |
| 81 | + * @param activityId 活动编号 | |
| 82 | + * @return 活动的商品列表 | |
| 83 | + */ | |
| 84 | + List<DiscountProductDO> getDiscountProductsByActivityId(Long activityId); | |
| 85 | + | |
| 86 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.service.discount; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.collection.CollectionUtil; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 7 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; | |
| 8 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; | |
| 9 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; | |
| 10 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; | |
| 11 | +import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert; | |
| 12 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; | |
| 13 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; | |
| 14 | +import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountActivityMapper; | |
| 15 | +import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper; | |
| 16 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; | |
| 17 | +import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; | |
| 18 | +import cn.iocoder.yudao.module.promotion.util.PromotionUtils; | |
| 19 | +import org.springframework.stereotype.Service; | |
| 20 | +import org.springframework.validation.annotation.Validated; | |
| 21 | + | |
| 22 | +import javax.annotation.Resource; | |
| 23 | +import java.util.*; | |
| 24 | + | |
| 25 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 26 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | |
| 27 | +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; | |
| 28 | +import static java.util.Arrays.asList; | |
| 29 | + | |
| 30 | +/** | |
| 31 | + * 限时折扣 Service 实现类 | |
| 32 | + * | |
| 33 | + * @author 芋道源码 | |
| 34 | + */ | |
| 35 | +@Service | |
| 36 | +@Validated | |
| 37 | +public class DiscountActivityServiceImpl implements DiscountActivityService { | |
| 38 | + | |
| 39 | + @Resource | |
| 40 | + private DiscountActivityMapper discountActivityMapper; | |
| 41 | + @Resource | |
| 42 | + private DiscountProductMapper discountProductMapper; | |
| 43 | + | |
| 44 | + @Override | |
| 45 | + public Map<Long, DiscountProductDetailBO> getMatchDiscountProducts(Collection<Long> skuIds) { | |
| 46 | + List<DiscountProductDetailBO> discountProducts = getRewardProductListBySkuIds(skuIds, singleton(PromotionActivityStatusEnum.RUN.getStatus())); | |
| 47 | + return convertMap(discountProducts, DiscountProductDetailBO::getSkuId); | |
| 48 | + } | |
| 49 | + | |
| 50 | + @Override | |
| 51 | + public Long createDiscountActivity(DiscountActivityCreateReqVO createReqVO) { | |
| 52 | + // 校验商品是否冲突 | |
| 53 | + validateDiscountActivityProductConflicts(null, createReqVO.getProducts()); | |
| 54 | + | |
| 55 | + // 插入活动 | |
| 56 | + DiscountActivityDO discountActivity = DiscountActivityConvert.INSTANCE.convert(createReqVO) | |
| 57 | + .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime())); | |
| 58 | + discountActivityMapper.insert(discountActivity); | |
| 59 | + // 插入商品 | |
| 60 | + List<DiscountProductDO> discountProducts = convertList(createReqVO.getProducts(), | |
| 61 | + product -> DiscountActivityConvert.INSTANCE.convert(product).setActivityId(discountActivity.getId())); | |
| 62 | + discountProductMapper.insertBatch(discountProducts); | |
| 63 | + // 返回 | |
| 64 | + return discountActivity.getId(); | |
| 65 | + } | |
| 66 | + | |
| 67 | + @Override | |
| 68 | + public void updateDiscountActivity(DiscountActivityUpdateReqVO updateReqVO) { | |
| 69 | + // 校验存在 | |
| 70 | + DiscountActivityDO discountActivity = validateDiscountActivityExists(updateReqVO.getId()); | |
| 71 | + if (discountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能修改噢 | |
| 72 | + throw exception(DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED); | |
| 73 | + } | |
| 74 | + // 校验商品是否冲突 | |
| 75 | + validateDiscountActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts()); | |
| 76 | + | |
| 77 | + // 更新活动 | |
| 78 | + DiscountActivityDO updateObj = DiscountActivityConvert.INSTANCE.convert(updateReqVO) | |
| 79 | + .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime())); | |
| 80 | + discountActivityMapper.updateById(updateObj); | |
| 81 | + // 更新商品 | |
| 82 | + updateDiscountProduct(updateReqVO); | |
| 83 | + } | |
| 84 | + | |
| 85 | + private void updateDiscountProduct(DiscountActivityUpdateReqVO updateReqVO) { | |
| 86 | + List<DiscountProductDO> dbDiscountProducts = discountProductMapper.selectListByActivityId(updateReqVO.getId()); | |
| 87 | + // 计算要删除的记录 | |
| 88 | + List<Long> deleteIds = convertList(dbDiscountProducts, DiscountProductDO::getId, | |
| 89 | + discountProductDO -> updateReqVO.getProducts().stream() | |
| 90 | + .noneMatch(product -> DiscountActivityConvert.INSTANCE.isEquals(discountProductDO, product))); | |
| 91 | + if (CollUtil.isNotEmpty(deleteIds)) { | |
| 92 | + discountProductMapper.deleteBatchIds(deleteIds); | |
| 93 | + } | |
| 94 | + // 计算新增的记录 | |
| 95 | + List<DiscountProductDO> newDiscountProducts = convertList(updateReqVO.getProducts(), | |
| 96 | + product -> DiscountActivityConvert.INSTANCE.convert(product).setActivityId(updateReqVO.getId())); | |
| 97 | + newDiscountProducts.removeIf(product -> dbDiscountProducts.stream().anyMatch( | |
| 98 | + dbProduct -> DiscountActivityConvert.INSTANCE.isEquals(dbProduct, product))); // 如果匹配到,说明是更新的 | |
| 99 | + if (CollectionUtil.isNotEmpty(newDiscountProducts)) { | |
| 100 | + discountProductMapper.insertBatch(newDiscountProducts); | |
| 101 | + } | |
| 102 | + } | |
| 103 | + | |
| 104 | + /** | |
| 105 | + * 校验商品是否冲突 | |
| 106 | + * | |
| 107 | + * @param id 编号 | |
| 108 | + * @param products 商品列表 | |
| 109 | + */ | |
| 110 | + private void validateDiscountActivityProductConflicts(Long id, List<DiscountActivityBaseVO.Product> products) { | |
| 111 | + if (CollUtil.isEmpty(products)) { | |
| 112 | + return; | |
| 113 | + } | |
| 114 | + // 查询商品参加的活动 | |
| 115 | + List<DiscountProductDetailBO> discountActivityProductList = getRewardProductListBySkuIds( | |
| 116 | + convertSet(products, DiscountActivityBaseVO.Product::getSkuId), | |
| 117 | + asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus())); | |
| 118 | + if (id != null) { // 排除自己这个活动 | |
| 119 | + discountActivityProductList.removeIf(product -> id.equals(product.getActivityId())); | |
| 120 | + } | |
| 121 | + // 如果非空,则说明冲突 | |
| 122 | + if (CollUtil.isNotEmpty(discountActivityProductList)) { | |
| 123 | + throw exception(DISCOUNT_ACTIVITY_SPU_CONFLICTS); | |
| 124 | + } | |
| 125 | + } | |
| 126 | + | |
| 127 | + private List<DiscountProductDetailBO> getRewardProductListBySkuIds(Collection<Long> skuIds, | |
| 128 | + Collection<Integer> statuses) { | |
| 129 | + // 查询商品 | |
| 130 | + List<DiscountProductDO> products = discountProductMapper.selectListBySkuId(skuIds); | |
| 131 | + if (CollUtil.isEmpty(products)) { | |
| 132 | + return new ArrayList<>(0); | |
| 133 | + } | |
| 134 | + | |
| 135 | + // 查询活动 | |
| 136 | + List<DiscountActivityDO> activities = discountActivityMapper.selectBatchIds(skuIds); | |
| 137 | + activities.removeIf(activity -> !statuses.contains(activity.getStatus())); // 移除不满足 statuses 状态的 | |
| 138 | + Map<Long, DiscountActivityDO> activityMap = CollectionUtils.convertMap(activities, DiscountActivityDO::getId); | |
| 139 | + | |
| 140 | + // 移除不满足活动的商品 | |
| 141 | + products.removeIf(product -> !activityMap.containsKey(product.getActivityId())); | |
| 142 | + return DiscountActivityConvert.INSTANCE.convertList(products, activityMap); | |
| 143 | + } | |
| 144 | + | |
| 145 | + @Override | |
| 146 | + public void closeRewardActivity(Long id) { | |
| 147 | + // 校验存在 | |
| 148 | + DiscountActivityDO dbDiscountActivity = validateDiscountActivityExists(id); | |
| 149 | + if (dbDiscountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能关闭噢 | |
| 150 | + throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED); | |
| 151 | + } | |
| 152 | + if (dbDiscountActivity.getStatus().equals(PromotionActivityStatusEnum.END.getStatus())) { // 已关闭的活动,不能关闭噢 | |
| 153 | + throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END); | |
| 154 | + } | |
| 155 | + | |
| 156 | + // 更新 | |
| 157 | + DiscountActivityDO updateObj = new DiscountActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); | |
| 158 | + discountActivityMapper.updateById(updateObj); | |
| 159 | + } | |
| 160 | + | |
| 161 | + @Override | |
| 162 | + public void deleteDiscountActivity(Long id) { | |
| 163 | + // 校验存在 | |
| 164 | + DiscountActivityDO discountActivity = validateDiscountActivityExists(id); | |
| 165 | + if (!discountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 未关闭的活动,不能删除噢 | |
| 166 | + throw exception(DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED); | |
| 167 | + } | |
| 168 | + | |
| 169 | + // 删除 | |
| 170 | + discountActivityMapper.deleteById(id); | |
| 171 | + } | |
| 172 | + | |
| 173 | + private DiscountActivityDO validateDiscountActivityExists(Long id) { | |
| 174 | + DiscountActivityDO discountActivity = discountActivityMapper.selectById(id); | |
| 175 | + if (discountActivity == null) { | |
| 176 | + throw exception(DISCOUNT_ACTIVITY_NOT_EXISTS); | |
| 177 | + } | |
| 178 | + return discountActivity; | |
| 179 | + } | |
| 180 | + | |
| 181 | + @Override | |
| 182 | + public DiscountActivityDO getDiscountActivity(Long id) { | |
| 183 | + return discountActivityMapper.selectById(id); | |
| 184 | + } | |
| 185 | + | |
| 186 | + @Override | |
| 187 | + public PageResult<DiscountActivityDO> getDiscountActivityPage(DiscountActivityPageReqVO pageReqVO) { | |
| 188 | + return discountActivityMapper.selectPage(pageReqVO); | |
| 189 | + } | |
| 190 | + | |
| 191 | + @Override | |
| 192 | + public List<DiscountProductDO> getDiscountProductsByActivityId(Long activityId) { | |
| 193 | + return discountProductMapper.selectListByActivityId(activityId); | |
| 194 | + } | |
| 195 | + | |
| 196 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountService.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.service.discount; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; | |
| 4 | - | |
| 5 | -import java.util.Collection; | |
| 6 | -import java.util.Map; | |
| 7 | - | |
| 8 | -/** | |
| 9 | - * 限时折扣 Service 接口 | |
| 10 | - * | |
| 11 | - * @author 芋道源码 | |
| 12 | - */ | |
| 13 | -public interface DiscountService { | |
| 14 | - | |
| 15 | - /** | |
| 16 | - * 基于指定 SKU 编号数组,获得匹配的限时折扣商品 | |
| 17 | - * | |
| 18 | - * 注意,匹配的条件,仅仅是日期符合,并且处于开启状态 | |
| 19 | - * | |
| 20 | - * @param skuIds SKU 编号数组 | |
| 21 | - * @return 匹配的限时折扣商品 | |
| 22 | - */ | |
| 23 | - Map<Long, DiscountProductDO> getMatchDiscountProducts(Collection<Long> skuIds); | |
| 24 | - | |
| 25 | -} |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountServiceImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.service.discount; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; | |
| 4 | -import org.springframework.stereotype.Service; | |
| 5 | -import org.springframework.validation.annotation.Validated; | |
| 6 | - | |
| 7 | -import java.util.Collection; | |
| 8 | -import java.util.HashMap; | |
| 9 | -import java.util.Map; | |
| 10 | - | |
| 11 | -/** | |
| 12 | - * 限时折扣 Service 实现类 | |
| 13 | - * | |
| 14 | - * @author 芋道源码 | |
| 15 | - */ | |
| 16 | -@Service | |
| 17 | -@Validated | |
| 18 | -public class DiscountServiceImpl implements DiscountService { | |
| 19 | - | |
| 20 | - // TODO 芋艿:待实现 | |
| 21 | - @Override | |
| 22 | - public Map<Long, DiscountProductDO> getMatchDiscountProducts(Collection<Long> skuIds) { | |
| 23 | - Map<Long, DiscountProductDO> products = new HashMap<>(); | |
| 24 | - products.put(1L, new DiscountProductDO().setPromotionPrice(100)); | |
| 25 | - products.put(2L, new DiscountProductDO().setPromotionPrice(50)); | |
| 26 | - return products; | |
| 27 | - } | |
| 28 | - | |
| 29 | -} |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/dto/UserInfoDTO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java
| 1 | -package cn.iocoder.yudao.module.member.api.user.dto; | |
| 1 | +package cn.iocoder.yudao.module.promotion.service.discount.bo; | |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 4 | 3 | import lombok.Data; |
| 5 | 4 | |
| 6 | -import java.util.Date; | |
| 7 | - | |
| 8 | 5 | /** |
| 9 | - * 用户信息 Response DTO | |
| 6 | + * 限时折扣活动商品 BO | |
| 10 | 7 | * |
| 11 | 8 | * @author 芋道源码 |
| 12 | 9 | */ |
| 13 | 10 | @Data |
| 14 | -public class UserInfoDTO { | |
| 11 | +public class DiscountProductDetailBO { | |
| 12 | + | |
| 13 | + // ========== DiscountProductDO 字段 ========== | |
| 15 | 14 | |
| 16 | 15 | /** |
| 17 | - * 用户ID | |
| 16 | + * 编号,主键自增 | |
| 18 | 17 | */ |
| 19 | 18 | private Long id; |
| 20 | 19 | /** |
| 21 | - * 用户昵称 | |
| 20 | + * 限时折扣活动的编号 | |
| 22 | 21 | */ |
| 23 | - private String nickname; | |
| 22 | + private Long activityId; | |
| 24 | 23 | /** |
| 25 | - * 用户头像 | |
| 24 | + * 商品 SPU 编号 | |
| 26 | 25 | */ |
| 27 | - private String avatar; | |
| 26 | + private Long spuId; | |
| 28 | 27 | /** |
| 29 | - * 帐号状态 | |
| 30 | - * | |
| 31 | - * 枚举 {@link CommonStatusEnum} | |
| 28 | + * 商品 SKU 编号 | |
| 32 | 29 | */ |
| 33 | - private Integer status; | |
| 34 | - | |
| 30 | + private Long skuId; | |
| 35 | 31 | /** |
| 36 | - * 手机 | |
| 32 | + * 折扣类型 | |
| 37 | 33 | */ |
| 38 | - private String mobile; | |
| 34 | + private Integer discountType; | |
| 39 | 35 | /** |
| 40 | - * 注册 IP | |
| 36 | + * 折扣百分比 | |
| 41 | 37 | */ |
| 42 | - private String registerIp; | |
| 38 | + private Integer discountPercent; | |
| 43 | 39 | /** |
| 44 | - * 最后登录IP | |
| 40 | + * 优惠金额,单位:分 | |
| 45 | 41 | */ |
| 46 | - private String loginIp; | |
| 42 | + private Integer discountPrice; | |
| 43 | + | |
| 44 | + // ========== DiscountActivityDO 字段 ========== | |
| 47 | 45 | /** |
| 48 | - * 最后登录时间 | |
| 46 | + * 活动标题 | |
| 49 | 47 | */ |
| 50 | - private Date loginDate; | |
| 48 | + private String activityName; | |
| 51 | 49 | |
| 52 | 50 | } | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java
| ... | ... | @@ -4,22 +4,20 @@ import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.hutool.core.lang.Assert; |
| 5 | 5 | import cn.hutool.core.util.StrUtil; |
| 6 | 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 7 | +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | |
| 8 | +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | |
| 7 | 9 | import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; |
| 8 | 10 | import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; |
| 9 | 11 | import cn.iocoder.yudao.module.promotion.convert.price.PriceConvert; |
| 10 | 12 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; |
| 11 | -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; | |
| 12 | 13 | import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; |
| 13 | -import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; | |
| 14 | -import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; | |
| 15 | -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; | |
| 16 | -import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; | |
| 14 | +import cn.iocoder.yudao.module.promotion.enums.common.*; | |
| 17 | 15 | import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; |
| 18 | -import cn.iocoder.yudao.module.promotion.service.discount.DiscountService; | |
| 19 | -import cn.iocoder.yudao.module.promotion.service.reward.RewardService; | |
| 20 | -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | |
| 21 | -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | |
| 16 | +import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; | |
| 17 | +import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; | |
| 18 | +import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; | |
| 22 | 19 | import com.google.common.base.Suppliers; |
| 20 | +import lombok.extern.slf4j.Slf4j; | |
| 23 | 21 | import org.springframework.stereotype.Service; |
| 24 | 22 | import org.springframework.validation.annotation.Validated; |
| 25 | 23 | |
| ... | ... | @@ -33,9 +31,8 @@ import java.util.function.Supplier; |
| 33 | 31 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 34 | 32 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| 35 | 33 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; |
| 36 | -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NO_MATCH_MIN_PRICE; | |
| 37 | -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NO_MATCH_SPU; | |
| 38 | 34 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; |
| 35 | +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; | |
| 39 | 36 | import static java.util.Collections.singletonList; |
| 40 | 37 | |
| 41 | 38 | /** |
| ... | ... | @@ -54,12 +51,13 @@ import static java.util.Collections.singletonList; |
| 54 | 51 | */ |
| 55 | 52 | @Service |
| 56 | 53 | @Validated |
| 54 | +@Slf4j | |
| 57 | 55 | public class PriceServiceImpl implements PriceService { |
| 58 | 56 | |
| 59 | 57 | @Resource |
| 60 | - private DiscountService discountService; | |
| 58 | + private DiscountActivityService discountService; | |
| 61 | 59 | @Resource |
| 62 | - private RewardService rewardService; | |
| 60 | + private RewardActivityService rewardActivityService; | |
| 63 | 61 | @Resource |
| 64 | 62 | private CouponService couponService; |
| 65 | 63 | |
| ... | ... | @@ -79,7 +77,13 @@ public class PriceServiceImpl implements PriceService { |
| 79 | 77 | calculatePriceForOrderLevel(calculateReqDTO.getUserId(), priceCalculate); |
| 80 | 78 | // 计算优惠劵级别的价格 |
| 81 | 79 | calculatePriceForCouponLevel(calculateReqDTO.getUserId(), calculateReqDTO.getCouponId(), priceCalculate); |
| 82 | - // 计算【优惠劵】促销 TODO 待实现 | |
| 80 | + | |
| 81 | + // 如果最终支付金额小于等于 0,则抛出业务异常 | |
| 82 | + if (priceCalculate.getOrder().getPayPrice() <= 0) { | |
| 83 | + log.error("[calculatePrice][价格计算不正确,请求 calculateReqDTO({}),结果 priceCalculate({})]", | |
| 84 | + calculateReqDTO, priceCalculate); | |
| 85 | + throw exception(PRICE_CALCULATE_PAY_PRICE_ILLEGAL); | |
| 86 | + } | |
| 83 | 87 | return priceCalculate; |
| 84 | 88 | } |
| 85 | 89 | |
| ... | ... | @@ -115,24 +119,20 @@ public class PriceServiceImpl implements PriceService { |
| 115 | 119 | private void calculatePriceForSkuLevel(Long userId, PriceCalculateRespDTO priceCalculate) { |
| 116 | 120 | // 获取 SKU 级别的所有优惠信息 |
| 117 | 121 | Supplier<Double> memberDiscountPercentSupplier = getMemberDiscountPercentSupplier(userId); |
| 118 | - Map<Long, DiscountProductDO> discountProducts = discountService.getMatchDiscountProducts( | |
| 122 | + Map<Long, DiscountProductDetailBO> discountProducts = discountService.getMatchDiscountProducts( | |
| 119 | 123 | convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSkuId)); |
| 120 | 124 | |
| 121 | 125 | // 处理每个 SKU 的优惠 |
| 122 | 126 | priceCalculate.getOrder().getItems().forEach(orderItem -> { |
| 123 | 127 | // 获取该 SKU 的优惠信息 |
| 124 | 128 | Double memberDiscountPercent = memberDiscountPercentSupplier.get(); |
| 125 | - DiscountProductDO discountProduct = discountProducts.get(orderItem.getSkuId()); | |
| 126 | - if (discountProduct != null // 假设优惠价格更贵,则认为没优惠 | |
| 127 | - && discountProduct.getPromotionPrice() >= orderItem.getOriginalUnitPrice()) { | |
| 128 | - discountProduct = null; | |
| 129 | - } | |
| 129 | + DiscountProductDetailBO discountProduct = discountProducts.get(orderItem.getSkuId()); | |
| 130 | 130 | if (memberDiscountPercent == null && discountProduct == null) { |
| 131 | 131 | return; |
| 132 | 132 | } |
| 133 | 133 | // 计算价格,判断选择哪个折扣 |
| 134 | 134 | Integer memberPrice = memberDiscountPercent != null ? (int) (orderItem.getPayPrice() * memberDiscountPercent / 100) : null; |
| 135 | - Integer promotionPrice = discountProduct != null ? discountProduct.getPromotionPrice() * orderItem.getCount() : null; | |
| 135 | + Integer promotionPrice = discountProduct != null ? getDiscountProductPrice(discountProduct, orderItem) : null; | |
| 136 | 136 | if (memberPrice == null) { |
| 137 | 137 | calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); |
| 138 | 138 | } else if (promotionPrice == null) { |
| ... | ... | @@ -145,6 +145,19 @@ public class PriceServiceImpl implements PriceService { |
| 145 | 145 | }); |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | + private Integer getDiscountProductPrice(DiscountProductDetailBO discountProduct, | |
| 149 | + PriceCalculateRespDTO.OrderItem orderItem) { | |
| 150 | + Integer price = orderItem.getPayPrice(); | |
| 151 | + if (PromotionDiscountTypeEnum.PRICE.getType().equals(discountProduct.getDiscountType())) { // 减价 | |
| 152 | + price -= discountProduct.getDiscountPrice() * orderItem.getCount(); | |
| 153 | + } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(discountProduct.getDiscountType())) { // 打折 | |
| 154 | + price = price * discountProduct.getDiscountPercent() / 100; | |
| 155 | + } else { | |
| 156 | + throw new IllegalArgumentException(String.format("优惠活动的商品(%s) 的优惠类型不正确", discountProduct)); | |
| 157 | + } | |
| 158 | + return price; | |
| 159 | + } | |
| 160 | + | |
| 148 | 161 | private void calculatePriceByMemberDiscount(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, |
| 149 | 162 | Integer memberPrice) { |
| 150 | 163 | // 记录优惠明细 |
| ... | ... | @@ -156,7 +169,7 @@ public class PriceServiceImpl implements PriceService { |
| 156 | 169 | } |
| 157 | 170 | |
| 158 | 171 | private void calculatePriceByDiscountActivity(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, |
| 159 | - DiscountProductDO discountProduct, Integer promotionPrice) { | |
| 172 | + DiscountProductDetailBO discountProduct, Integer promotionPrice) { | |
| 160 | 173 | // 记录优惠明细 |
| 161 | 174 | addPromotion(priceCalculate, orderItem, discountProduct.getActivityId(), discountProduct.getActivityName(), |
| 162 | 175 | PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), PromotionLevelEnum.SKU.getLevel(), promotionPrice, |
| ... | ... | @@ -191,7 +204,7 @@ public class PriceServiceImpl implements PriceService { |
| 191 | 204 | private void calculatePriceForOrderLevel(Long userId, PriceCalculateRespDTO priceCalculate) { |
| 192 | 205 | // 获取 SKU 级别的所有优惠信息 |
| 193 | 206 | Set<Long> spuIds = convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSpuId); |
| 194 | - Map<RewardActivityDO, Set<Long>> rewardActivities = rewardService.getMatchRewardActivities(spuIds); | |
| 207 | + Map<RewardActivityDO, Set<Long>> rewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); | |
| 195 | 208 | |
| 196 | 209 | // 处理满减送活动 |
| 197 | 210 | if (CollUtil.isNotEmpty(rewardActivities)) { |
| ... | ... | @@ -216,7 +229,6 @@ public class PriceServiceImpl implements PriceService { |
| 216 | 229 | } |
| 217 | 230 | |
| 218 | 231 | // 分摊金额 |
| 219 | - // TODO 芋艿:limit 不能超过最大价格 | |
| 220 | 232 | List<Integer> discountPartPrices = dividePrice(orderItems, rule.getDiscountPrice()); |
| 221 | 233 | // 记录优惠明细 |
| 222 | 234 | addPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), |
| ... | ... | @@ -283,7 +295,7 @@ public class PriceServiceImpl implements PriceService { |
| 283 | 295 | // 计算是否满足优惠劵的使用金额 |
| 284 | 296 | Integer originPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); |
| 285 | 297 | assert originPrice != null; |
| 286 | - if (originPrice < coupon.getPriceAvailable()) { | |
| 298 | + if (originPrice < coupon.getUsePrice()) { | |
| 287 | 299 | throw exception(COUPON_NO_MATCH_MIN_PRICE); |
| 288 | 300 | } |
| 289 | 301 | |
| ... | ... | @@ -291,10 +303,9 @@ public class PriceServiceImpl implements PriceService { |
| 291 | 303 | priceCalculate.getOrder().setCouponId(couponId); |
| 292 | 304 | Integer couponPrice = getCouponPrice(coupon, originPrice); |
| 293 | 305 | // 分摊金额 |
| 294 | - // TODO 芋艿:limit 不能超过最大价格 | |
| 295 | 306 | List<Integer> couponPartPrices = dividePrice(orderItems, couponPrice); |
| 296 | 307 | // 记录优惠明细 |
| 297 | - addPromotion(priceCalculate, orderItems, coupon.getId(), coupon.getTitle(), | |
| 308 | + addPromotion(priceCalculate, orderItems, coupon.getId(), coupon.getName(), | |
| 298 | 309 | PromotionTypeEnum.COUPON.getType(), PromotionLevelEnum.COUPON.getLevel(), couponPartPrices, |
| 299 | 310 | true, StrUtil.format("优惠劵:省 {} 元", formatPrice(couponPrice))); |
| 300 | 311 | // 修改 SKU 的分摊 |
| ... | ... | @@ -309,19 +320,18 @@ public class PriceServiceImpl implements PriceService { |
| 309 | 320 | return priceCalculate.getOrder().getItems(); |
| 310 | 321 | } |
| 311 | 322 | return CollectionUtils.filterList(priceCalculate.getOrder().getItems(), |
| 312 | - orderItem -> coupon.getSpuIds().contains(orderItem.getSpuId())); | |
| 323 | + orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId())); | |
| 313 | 324 | } |
| 314 | 325 | |
| 315 | 326 | private Integer getCouponPrice(CouponDO coupon, Integer originPrice) { |
| 316 | - // TODO 芋艿 getPreferentialType 的枚举判断 | |
| 317 | - if (coupon.getPreferentialType().equals(1)) { // 减价 | |
| 318 | - return coupon.getPriceOff(); | |
| 319 | - } else if (coupon.getPreferentialType().equals(2)) { // 打折 | |
| 320 | - Integer couponPrice = originPrice * coupon.getPercentOff() / 100; | |
| 321 | - return coupon.getDiscountPriceLimit() == null ? couponPrice | |
| 322 | - : Math.min(couponPrice, coupon.getDiscountPriceLimit()); // 优惠上限 | |
| 327 | + if (PromotionDiscountTypeEnum.PRICE.getType().equals(coupon.getDiscountType())) { // 减价 | |
| 328 | + return coupon.getDiscountPrice(); | |
| 329 | + } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(coupon.getDiscountType())) { // 打折 | |
| 330 | + int couponPrice = originPrice * coupon.getDiscountPercent() / 100; | |
| 331 | + return coupon.getDiscountLimitPrice() == null ? couponPrice | |
| 332 | + : Math.min(couponPrice, coupon.getDiscountLimitPrice()); // 优惠上限 | |
| 323 | 333 | } |
| 324 | - throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon.toString())); | |
| 334 | + throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon)); | |
| 325 | 335 | } |
| 326 | 336 | |
| 327 | 337 | // ========== 其它相对通用的方法 ========== |
| ... | ... | @@ -410,13 +420,16 @@ public class PriceServiceImpl implements PriceService { |
| 410 | 420 | */ |
| 411 | 421 | private void modifyOrderItemPayPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer newPayPrice, |
| 412 | 422 | PriceCalculateRespDTO priceCalculate) { |
| 423 | + // diffPayPrice 等于额外增加的商品级的优惠 | |
| 413 | 424 | int diffPayPrice = orderItem.getPayPrice() - newPayPrice; |
| 414 | 425 | // 设置 OrderItem 价格相关字段 |
| 415 | 426 | orderItem.setDiscountPrice(orderItem.getDiscountPrice() + diffPayPrice); |
| 416 | 427 | orderItem.setPayPrice(newPayPrice); |
| 417 | 428 | orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); |
| 418 | 429 | // 设置 Order 相关相关字段 |
| 419 | - priceCalculate.getOrder().setPayPrice(priceCalculate.getOrder().getPayPrice() - diffPayPrice); | |
| 430 | + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); | |
| 431 | + order.setPayPrice(order.getPayPrice() - diffPayPrice); | |
| 432 | + order.setOrderPrice(order.getOrderPrice() - diffPayPrice); | |
| 420 | 433 | } |
| 421 | 434 | |
| 422 | 435 | /** | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.service.reward; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; | |
| 5 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; | |
| 8 | + | |
| 9 | +import javax.validation.Valid; | |
| 10 | +import java.util.Map; | |
| 11 | +import java.util.Set; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * 满减送活动 Service 接口 | |
| 15 | + * | |
| 16 | + * @author 芋道源码 | |
| 17 | + */ | |
| 18 | +public interface RewardActivityService { | |
| 19 | + | |
| 20 | + /** | |
| 21 | + * 创建满减送活动 | |
| 22 | + * | |
| 23 | + * @param createReqVO 创建信息 | |
| 24 | + * @return 编号 | |
| 25 | + */ | |
| 26 | + Long createRewardActivity(@Valid RewardActivityCreateReqVO createReqVO); | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * 更新满减送活动 | |
| 30 | + * | |
| 31 | + * @param updateReqVO 更新信息 | |
| 32 | + */ | |
| 33 | + void updateRewardActivity(@Valid RewardActivityUpdateReqVO updateReqVO); | |
| 34 | + | |
| 35 | + /** | |
| 36 | + * 关闭满减送活动 | |
| 37 | + * | |
| 38 | + * @param id 活动编号 | |
| 39 | + */ | |
| 40 | + void closeRewardActivity(Long id); | |
| 41 | + | |
| 42 | + /** | |
| 43 | + * 删除满减送活动 | |
| 44 | + * | |
| 45 | + * @param id 编号 | |
| 46 | + */ | |
| 47 | + void deleteRewardActivity(Long id); | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * 获得满减送活动 | |
| 51 | + * | |
| 52 | + * @param id 编号 | |
| 53 | + * @return 满减送活动 | |
| 54 | + */ | |
| 55 | + RewardActivityDO getRewardActivity(Long id); | |
| 56 | + | |
| 57 | + /** | |
| 58 | + * 获得满减送活动分页 | |
| 59 | + * | |
| 60 | + * @param pageReqVO 分页查询 | |
| 61 | + * @return 满减送活动分页 | |
| 62 | + */ | |
| 63 | + PageResult<RewardActivityDO> getRewardActivityPage(RewardActivityPageReqVO pageReqVO); | |
| 64 | + | |
| 65 | + /** | |
| 66 | + * 基于指定的 SPU 编号数组,获得它们匹配的满减送活动 | |
| 67 | + * | |
| 68 | + * @param spuIds SPU 编号数组 | |
| 69 | + * @return 满减送活动,与对应的 SPU 编号的映射。即,value 就是 SPU 编号的集合 | |
| 70 | + */ | |
| 71 | + Map<RewardActivityDO, Set<Long>> getMatchRewardActivities(Set<Long> spuIds); | |
| 72 | + | |
| 73 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.service.reward; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.map.MapUtil; | |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; | |
| 8 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; | |
| 9 | +import cn.iocoder.yudao.module.promotion.convert.reward.RewardActivityConvert; | |
| 10 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; | |
| 11 | +import cn.iocoder.yudao.module.promotion.dal.mysql.reward.RewardActivityMapper; | |
| 12 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; | |
| 13 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; | |
| 14 | +import cn.iocoder.yudao.module.promotion.util.PromotionUtils; | |
| 15 | +import org.springframework.stereotype.Service; | |
| 16 | +import org.springframework.validation.annotation.Validated; | |
| 17 | + | |
| 18 | +import javax.annotation.Resource; | |
| 19 | +import java.util.Collection; | |
| 20 | +import java.util.List; | |
| 21 | +import java.util.Map; | |
| 22 | +import java.util.Set; | |
| 23 | + | |
| 24 | +import static cn.hutool.core.collection.CollUtil.intersectionDistinct; | |
| 25 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 26 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | |
| 27 | +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; | |
| 28 | +import static java.util.Arrays.asList; | |
| 29 | +import static java.util.Collections.singleton; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * 满减送活动 Service 实现类 | |
| 33 | + * | |
| 34 | + * @author 芋道源码 | |
| 35 | + */ | |
| 36 | +@Service | |
| 37 | +@Validated | |
| 38 | +public class RewardActivityServiceImpl implements RewardActivityService { | |
| 39 | + | |
| 40 | + @Resource | |
| 41 | + private RewardActivityMapper rewardActivityMapper; | |
| 42 | + | |
| 43 | + @Override | |
| 44 | + public Long createRewardActivity(RewardActivityCreateReqVO createReqVO) { | |
| 45 | + // 校验商品是否冲突 | |
| 46 | + validateRewardActivitySpuConflicts(null, createReqVO.getProductSpuIds()); | |
| 47 | + | |
| 48 | + // 插入 | |
| 49 | + RewardActivityDO rewardActivity = RewardActivityConvert.INSTANCE.convert(createReqVO) | |
| 50 | + .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime())); | |
| 51 | + rewardActivityMapper.insert(rewardActivity); | |
| 52 | + // 返回 | |
| 53 | + return rewardActivity.getId(); | |
| 54 | + } | |
| 55 | + | |
| 56 | + @Override | |
| 57 | + public void updateRewardActivity(RewardActivityUpdateReqVO updateReqVO) { | |
| 58 | + // 校验存在 | |
| 59 | + RewardActivityDO dbRewardActivity = validateRewardActivityExists(updateReqVO.getId()); | |
| 60 | + if (dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能修改噢 | |
| 61 | + throw exception(REWARD_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED); | |
| 62 | + } | |
| 63 | + // 校验商品是否冲突 | |
| 64 | + validateRewardActivitySpuConflicts(updateReqVO.getId(), updateReqVO.getProductSpuIds()); | |
| 65 | + | |
| 66 | + // 更新 | |
| 67 | + RewardActivityDO updateObj = RewardActivityConvert.INSTANCE.convert(updateReqVO) | |
| 68 | + .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime())); | |
| 69 | + rewardActivityMapper.updateById(updateObj); | |
| 70 | + } | |
| 71 | + | |
| 72 | + @Override | |
| 73 | + public void closeRewardActivity(Long id) { | |
| 74 | + // 校验存在 | |
| 75 | + RewardActivityDO dbRewardActivity = validateRewardActivityExists(id); | |
| 76 | + if (dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能关闭噢 | |
| 77 | + throw exception(REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED); | |
| 78 | + } | |
| 79 | + if (dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.END.getStatus())) { // 已关闭的活动,不能关闭噢 | |
| 80 | + throw exception(REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END); | |
| 81 | + } | |
| 82 | + | |
| 83 | + // 更新 | |
| 84 | + RewardActivityDO updateObj = new RewardActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); | |
| 85 | + rewardActivityMapper.updateById(updateObj); | |
| 86 | + } | |
| 87 | + | |
| 88 | + @Override | |
| 89 | + public void deleteRewardActivity(Long id) { | |
| 90 | + // 校验存在 | |
| 91 | + RewardActivityDO dbRewardActivity = validateRewardActivityExists(id); | |
| 92 | + if (!dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 未关闭的活动,不能删除噢 | |
| 93 | + throw exception(REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED); | |
| 94 | + } | |
| 95 | + | |
| 96 | + // 删除 | |
| 97 | + rewardActivityMapper.deleteById(id); | |
| 98 | + } | |
| 99 | + | |
| 100 | + private RewardActivityDO validateRewardActivityExists(Long id) { | |
| 101 | + RewardActivityDO activity = rewardActivityMapper.selectById(id); | |
| 102 | + if (activity == null) { | |
| 103 | + throw exception(REWARD_ACTIVITY_NOT_EXISTS); | |
| 104 | + } | |
| 105 | + return activity; | |
| 106 | + } | |
| 107 | + | |
| 108 | + /** | |
| 109 | + * 校验商品参加的活动是否冲突 | |
| 110 | + * | |
| 111 | + * @param id 活动编号 | |
| 112 | + * @param spuIds 商品 SPU 编号数组 | |
| 113 | + */ | |
| 114 | + private void validateRewardActivitySpuConflicts(Long id, Collection<Long> spuIds) { | |
| 115 | + if (CollUtil.isEmpty(spuIds)) { | |
| 116 | + return; | |
| 117 | + } | |
| 118 | + // 查询商品参加的活动 | |
| 119 | + List<RewardActivityDO> rewardActivityList = getRewardActivityListBySpuIds(spuIds, | |
| 120 | + asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus())); | |
| 121 | + if (id != null) { // 排除自己这个活动 | |
| 122 | + rewardActivityList.removeIf(activity -> id.equals(activity.getId())); | |
| 123 | + } | |
| 124 | + // 如果非空,则说明冲突 | |
| 125 | + if (CollUtil.isNotEmpty(rewardActivityList)) { | |
| 126 | + throw exception(REWARD_ACTIVITY_SPU_CONFLICTS); | |
| 127 | + } | |
| 128 | + } | |
| 129 | + | |
| 130 | + /** | |
| 131 | + * 获得商品参加的满减送活动的数组 | |
| 132 | + * | |
| 133 | + * @param spuIds 商品 SPU 编号数组 | |
| 134 | + * @param statuses 活动状态数组 | |
| 135 | + * @return 商品参加的满减送活动的数组 | |
| 136 | + */ | |
| 137 | + private List<RewardActivityDO> getRewardActivityListBySpuIds(Collection<Long> spuIds, | |
| 138 | + Collection<Integer> statuses) { | |
| 139 | + List<RewardActivityDO> list = rewardActivityMapper.selectListByStatus(statuses); | |
| 140 | + return CollUtil.filter(list, activity -> CollUtil.containsAny(activity.getProductSpuIds(), spuIds)); | |
| 141 | + } | |
| 142 | + | |
| 143 | + @Override | |
| 144 | + public RewardActivityDO getRewardActivity(Long id) { | |
| 145 | + return rewardActivityMapper.selectById(id); | |
| 146 | + } | |
| 147 | + | |
| 148 | + @Override | |
| 149 | + public PageResult<RewardActivityDO> getRewardActivityPage(RewardActivityPageReqVO pageReqVO) { | |
| 150 | + return rewardActivityMapper.selectPage(pageReqVO); | |
| 151 | + } | |
| 152 | + | |
| 153 | + @Override | |
| 154 | + public Map<RewardActivityDO, Set<Long>> getMatchRewardActivities(Set<Long> spuIds) { | |
| 155 | + // 如果有全局活动,则直接选择它 | |
| 156 | + List<RewardActivityDO> allActivities = rewardActivityMapper.selectListByProductScopeAndStatus( | |
| 157 | + PromotionProductScopeEnum.ALL.getScope(), PromotionActivityStatusEnum.RUN.getStatus()); | |
| 158 | + if (CollUtil.isNotEmpty(allActivities)) { | |
| 159 | + return MapUtil.builder(allActivities.get(0), spuIds).build(); | |
| 160 | + } | |
| 161 | + | |
| 162 | + // 查询某个活动参加的活动 | |
| 163 | + List<RewardActivityDO> productActivityList = getRewardActivityListBySpuIds(spuIds, | |
| 164 | + singleton(PromotionActivityStatusEnum.RUN.getStatus())); | |
| 165 | + return convertMap(productActivityList, activity -> activity, | |
| 166 | + rewardActivityDO -> intersectionDistinct(rewardActivityDO.getProductSpuIds(), spuIds)); // 求交集返回 | |
| 167 | + } | |
| 168 | + | |
| 169 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardService.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.service.reward; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; | |
| 4 | - | |
| 5 | -import java.util.Map; | |
| 6 | -import java.util.Set; | |
| 7 | - | |
| 8 | -/** | |
| 9 | - * 满减送 Service 接口 | |
| 10 | - * | |
| 11 | - * @author 芋道源码 | |
| 12 | - */ | |
| 13 | -public interface RewardService { | |
| 14 | - | |
| 15 | - /** | |
| 16 | - * 基于指定的 SPU 编号数组,获得它们匹配的满减送活动 | |
| 17 | - * | |
| 18 | - * @param spuIds SPU 编号数组 | |
| 19 | - * @return 满减送活动,与对应的 SPU 编号的映射。即,value 就是 SPU 编号的集合 | |
| 20 | - */ | |
| 21 | - Map<RewardActivityDO, Set<Long>> getMatchRewardActivities(Set<Long> spuIds); | |
| 22 | - | |
| 23 | -} |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardServiceImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.service.reward; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; | |
| 4 | -import org.springframework.stereotype.Service; | |
| 5 | -import org.springframework.validation.annotation.Validated; | |
| 6 | - | |
| 7 | -import java.util.Collections; | |
| 8 | -import java.util.Map; | |
| 9 | -import java.util.Set; | |
| 10 | - | |
| 11 | -/** | |
| 12 | - * 满减送 Service 实现类 | |
| 13 | - * | |
| 14 | - * @author 芋道源码 | |
| 15 | - */ | |
| 16 | -@Service | |
| 17 | -@Validated | |
| 18 | -public class RewardServiceImpl implements RewardService { | |
| 19 | - | |
| 20 | - // TODO 芋艿:待实现 | |
| 21 | - @Override | |
| 22 | - public Map<RewardActivityDO, Set<Long>> getMatchRewardActivities(Set<Long> spuIds) { | |
| 23 | - return Collections.emptyMap(); | |
| 24 | - } | |
| 25 | - | |
| 26 | -} |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.util; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.util.date.DateUtils; | |
| 4 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; | |
| 5 | + | |
| 6 | +import java.util.Date; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * 活动工具类 | |
| 10 | + * | |
| 11 | + * @author 芋道源码 | |
| 12 | + */ | |
| 13 | +public class PromotionUtils { | |
| 14 | + | |
| 15 | + /** | |
| 16 | + * 根据时间,计算活动状态 | |
| 17 | + * | |
| 18 | + * @param startTime 开始时间 | |
| 19 | + * @param endTime 结束时间 | |
| 20 | + * @return 活动状态 | |
| 21 | + */ | |
| 22 | + public static Integer calculateActivityStatus(Date startTime, Date endTime) { | |
| 23 | + if (DateUtils.beforeNow(endTime)) { | |
| 24 | + return PromotionActivityStatusEnum.END.getStatus(); | |
| 25 | + } | |
| 26 | + if (DateUtils.afterNow(startTime)) { | |
| 27 | + return PromotionActivityStatusEnum.WAIT.getStatus(); | |
| 28 | + } | |
| 29 | + return PromotionActivityStatusEnum.RUN.getStatus(); | |
| 30 | + } | |
| 31 | + | |
| 32 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/coupon/CouponTemplateMapper.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |
| 3 | +<mapper namespace="cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper"> | |
| 4 | + | |
| 5 | + <update id="updateTakeCount"> | |
| 6 | + UPDATE promotion_coupon_template | |
| 7 | + SET take_count = take_count + #{incrCount} | |
| 8 | + WHERE id = #{id} | |
| 9 | + </update> | |
| 10 | + | |
| 11 | +</mapper> | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImplTest.java
| 1 | 1 | package cn.iocoder.yudao.module.promotion.service.coupon; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 5 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateCreateReqVO; | |
| 6 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplatePageReqVO; | |
| 7 | -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.CouponTemplateUpdateReqVO; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; | |
| 8 | +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; | |
| 8 | 9 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; |
| 9 | 10 | import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper; |
| 10 | -import org.junit.jupiter.api.Disabled; | |
| 11 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; | |
| 12 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; | |
| 13 | +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum; | |
| 11 | 14 | import org.junit.jupiter.api.Test; |
| 12 | 15 | import org.springframework.context.annotation.Import; |
| 13 | 16 | |
| 14 | 17 | import javax.annotation.Resource; |
| 15 | 18 | import java.util.Date; |
| 16 | 19 | |
| 20 | +import static cn.hutool.core.util.RandomUtil.randomEle; | |
| 21 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime; | |
| 17 | 22 | import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; |
| 18 | 23 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; |
| 19 | 24 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; |
| ... | ... | @@ -39,7 +44,10 @@ public class CouponTemplateServiceImplTest extends BaseDbUnitTest { |
| 39 | 44 | @Test |
| 40 | 45 | public void testCreateCouponTemplate_success() { |
| 41 | 46 | // 准备参数 |
| 42 | - CouponTemplateCreateReqVO reqVO = randomPojo(CouponTemplateCreateReqVO.class); | |
| 47 | + CouponTemplateCreateReqVO reqVO = randomPojo(CouponTemplateCreateReqVO.class, | |
| 48 | + o -> o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope()) | |
| 49 | + .setValidityType(randomEle(CouponTemplateValidityTypeEnum.values()).getType()) | |
| 50 | + .setDiscountType(randomEle(PromotionDiscountTypeEnum.values()).getType())); | |
| 43 | 51 | |
| 44 | 52 | // 调用 |
| 45 | 53 | Long couponTemplateId = couponTemplateService.createCouponTemplate(reqVO); |
| ... | ... | @@ -58,6 +66,10 @@ public class CouponTemplateServiceImplTest extends BaseDbUnitTest { |
| 58 | 66 | // 准备参数 |
| 59 | 67 | CouponTemplateUpdateReqVO reqVO = randomPojo(CouponTemplateUpdateReqVO.class, o -> { |
| 60 | 68 | o.setId(dbCouponTemplate.getId()); // 设置更新的 ID |
| 69 | + // 其它通用字段 | |
| 70 | + o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope()) | |
| 71 | + .setValidityType(randomEle(CouponTemplateValidityTypeEnum.values()).getType()) | |
| 72 | + .setDiscountType(randomEle(PromotionDiscountTypeEnum.values()).getType()); | |
| 61 | 73 | }); |
| 62 | 74 | |
| 63 | 75 | // 调用 |
| ... | ... | @@ -100,30 +112,29 @@ public class CouponTemplateServiceImplTest extends BaseDbUnitTest { |
| 100 | 112 | } |
| 101 | 113 | |
| 102 | 114 | @Test |
| 103 | - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 | |
| 104 | 115 | public void testGetCouponTemplatePage() { |
| 105 | 116 | // mock 数据 |
| 106 | 117 | CouponTemplateDO dbCouponTemplate = randomPojo(CouponTemplateDO.class, o -> { // 等会查询到 |
| 107 | - o.setName(null); | |
| 108 | - o.setStatus(null); | |
| 109 | - o.setDiscountType(null); | |
| 110 | - o.setCreateTime(null); | |
| 118 | + o.setName("芋艿"); | |
| 119 | + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 120 | + o.setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()); | |
| 121 | + o.setCreateTime(buildTime(2022, 2, 2)); | |
| 111 | 122 | }); |
| 112 | 123 | couponTemplateMapper.insert(dbCouponTemplate); |
| 113 | 124 | // 测试 name 不匹配 |
| 114 | - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setName(null))); | |
| 125 | + couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setName("土豆"))); | |
| 115 | 126 | // 测试 status 不匹配 |
| 116 | - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setStatus(null))); | |
| 127 | + couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); | |
| 117 | 128 | // 测试 type 不匹配 |
| 118 | - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setDiscountType(null))); | |
| 129 | + couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()))); | |
| 119 | 130 | // 测试 createTime 不匹配 |
| 120 | - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setCreateTime(null))); | |
| 131 | + couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setCreateTime(buildTime(2022, 1, 1)))); | |
| 121 | 132 | // 准备参数 |
| 122 | 133 | CouponTemplatePageReqVO reqVO = new CouponTemplatePageReqVO(); |
| 123 | - reqVO.setName(null); | |
| 124 | - reqVO.setStatus(null); | |
| 125 | - reqVO.setDiscountType(null); | |
| 126 | - reqVO.setCreateTime((new Date[]{})); | |
| 134 | + reqVO.setName("芋艿"); | |
| 135 | + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 136 | + reqVO.setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()); | |
| 137 | + reqVO.setCreateTime((new Date[]{buildTime(2022, 2, 1), buildTime(2022, 2, 3)})); | |
| 127 | 138 | |
| 128 | 139 | // 调用 |
| 129 | 140 | PageResult<CouponTemplateDO> pageResult = couponTemplateService.getCouponTemplatePage(reqVO); | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.service.discount; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 5 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; | |
| 7 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; | |
| 8 | +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; | |
| 9 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; | |
| 10 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; | |
| 11 | +import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountActivityMapper; | |
| 12 | +import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper; | |
| 13 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; | |
| 14 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; | |
| 15 | +import org.junit.jupiter.api.Test; | |
| 16 | +import org.springframework.context.annotation.Import; | |
| 17 | + | |
| 18 | +import javax.annotation.Resource; | |
| 19 | +import java.time.Duration; | |
| 20 | +import java.util.Date; | |
| 21 | +import java.util.List; | |
| 22 | + | |
| 23 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.addTime; | |
| 24 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime; | |
| 25 | +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; | |
| 26 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | |
| 27 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | |
| 28 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; | |
| 29 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | |
| 30 | +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.DISCOUNT_ACTIVITY_NOT_EXISTS; | |
| 31 | +import static java.util.Arrays.asList; | |
| 32 | +import static org.junit.jupiter.api.Assertions.*; | |
| 33 | + | |
| 34 | +/** | |
| 35 | +* {@link DiscountActivityServiceImpl} 的单元测试类 | |
| 36 | +* | |
| 37 | +* @author 芋道源码 | |
| 38 | +*/ | |
| 39 | +@Import(DiscountActivityServiceImpl.class) | |
| 40 | +public class DiscountActivityServiceImplTest extends BaseDbUnitTest { | |
| 41 | + | |
| 42 | + @Resource | |
| 43 | + private DiscountActivityServiceImpl discountActivityService; | |
| 44 | + | |
| 45 | + @Resource | |
| 46 | + private DiscountActivityMapper discountActivityMapper; | |
| 47 | + @Resource | |
| 48 | + private DiscountProductMapper discountProductMapper; | |
| 49 | + | |
| 50 | + @Test | |
| 51 | + public void testCreateDiscountActivity_success() { | |
| 52 | + // 准备参数 | |
| 53 | + DiscountActivityCreateReqVO reqVO = randomPojo(DiscountActivityCreateReqVO.class, o -> { | |
| 54 | + // 用于触发进行中的状态 | |
| 55 | + o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); | |
| 56 | + // 设置商品 | |
| 57 | + o.setProducts(asList(new DiscountActivityBaseVO.Product().setSpuId(1L).setSkuId(2L) | |
| 58 | + .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(3), | |
| 59 | + new DiscountActivityBaseVO.Product().setSpuId(10L).setSkuId(20L) | |
| 60 | + .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(30))); | |
| 61 | + }); | |
| 62 | + | |
| 63 | + // 调用 | |
| 64 | + Long discountActivityId = discountActivityService.createDiscountActivity(reqVO); | |
| 65 | + // 断言 | |
| 66 | + assertNotNull(discountActivityId); | |
| 67 | + // 校验活动 | |
| 68 | + DiscountActivityDO discountActivity = discountActivityMapper.selectById(discountActivityId); | |
| 69 | + assertPojoEquals(reqVO, discountActivity); | |
| 70 | + assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); | |
| 71 | + // 校验商品 | |
| 72 | + List<DiscountProductDO> discountProducts = discountProductMapper.selectList(DiscountProductDO::getActivityId, discountActivity.getId()); | |
| 73 | + assertEquals(discountProducts.size(), reqVO.getProducts().size()); | |
| 74 | + for (int i = 0; i < reqVO.getProducts().size(); i++) { | |
| 75 | + DiscountActivityBaseVO.Product product = reqVO.getProducts().get(i); | |
| 76 | + DiscountProductDO discountProduct = discountProducts.get(i); | |
| 77 | + assertEquals(discountProduct.getActivityId(), discountActivity.getId()); | |
| 78 | + assertEquals(discountProduct.getSpuId(), product.getSpuId()); | |
| 79 | + assertEquals(discountProduct.getSkuId(), product.getSkuId()); | |
| 80 | + assertEquals(discountProduct.getDiscountType(), product.getDiscountType()); | |
| 81 | + assertEquals(discountProduct.getDiscountPrice(), product.getDiscountPrice()); | |
| 82 | + assertEquals(discountProduct.getDiscountPercent(), product.getDiscountPercent()); | |
| 83 | + } | |
| 84 | + } | |
| 85 | + | |
| 86 | + @Test | |
| 87 | + public void testUpdateDiscountActivity_success() { | |
| 88 | + // mock 数据(商品) | |
| 89 | + DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class); | |
| 90 | + discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据 | |
| 91 | + // mock 数据(活动) | |
| 92 | + DiscountProductDO dbDiscountProduct01 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(dbDiscountActivity.getId()) | |
| 93 | + .setSpuId(1L).setSkuId(2L).setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(3).setDiscountPercent(null)); | |
| 94 | + DiscountProductDO dbDiscountProduct02 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(dbDiscountActivity.getId()) | |
| 95 | + .setSpuId(10L).setSkuId(20L).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(30).setDiscountPrice(null)); | |
| 96 | + discountProductMapper.insert(dbDiscountProduct01); | |
| 97 | + discountProductMapper.insert(dbDiscountProduct02); | |
| 98 | + // 准备参数 | |
| 99 | + DiscountActivityUpdateReqVO reqVO = randomPojo(DiscountActivityUpdateReqVO.class, o -> { | |
| 100 | + o.setId(dbDiscountActivity.getId()); // 设置更新的 ID | |
| 101 | + // 用于触发进行中的状态 | |
| 102 | + o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); | |
| 103 | + // 设置商品 | |
| 104 | + o.setProducts(asList(new DiscountActivityBaseVO.Product().setSpuId(1L).setSkuId(2L) | |
| 105 | + .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(3).setDiscountPercent(null), | |
| 106 | + new DiscountActivityBaseVO.Product().setSpuId(100L).setSkuId(200L) | |
| 107 | + .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(30).setDiscountPrice(null))); | |
| 108 | + }); | |
| 109 | + | |
| 110 | + // 调用 | |
| 111 | + discountActivityService.updateDiscountActivity(reqVO); | |
| 112 | + // 校验活动 | |
| 113 | + DiscountActivityDO discountActivity = discountActivityMapper.selectById(reqVO.getId()); // 获取最新的 | |
| 114 | + assertPojoEquals(reqVO, discountActivity); | |
| 115 | + assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); | |
| 116 | + // 校验商品 | |
| 117 | + List<DiscountProductDO> discountProducts = discountProductMapper.selectList(DiscountProductDO::getActivityId, discountActivity.getId()); | |
| 118 | + assertEquals(discountProducts.size(), reqVO.getProducts().size()); | |
| 119 | + for (int i = 0; i < reqVO.getProducts().size(); i++) { | |
| 120 | + DiscountActivityBaseVO.Product product = reqVO.getProducts().get(i); | |
| 121 | + DiscountProductDO discountProduct = discountProducts.get(i); | |
| 122 | + assertEquals(discountProduct.getActivityId(), discountActivity.getId()); | |
| 123 | + assertEquals(discountProduct.getSpuId(), product.getSpuId()); | |
| 124 | + assertEquals(discountProduct.getSkuId(), product.getSkuId()); | |
| 125 | + assertEquals(discountProduct.getDiscountType(), product.getDiscountType()); | |
| 126 | + assertEquals(discountProduct.getDiscountPrice(), product.getDiscountPrice()); | |
| 127 | + assertEquals(discountProduct.getDiscountPercent(), product.getDiscountPercent()); | |
| 128 | + } | |
| 129 | + } | |
| 130 | + | |
| 131 | + @Test | |
| 132 | + public void testCloseDiscountActivity() { | |
| 133 | + // mock 数据 | |
| 134 | + DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class, | |
| 135 | + o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus())); | |
| 136 | + discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据 | |
| 137 | + // 准备参数 | |
| 138 | + Long id = dbDiscountActivity.getId(); | |
| 139 | + | |
| 140 | + // 调用 | |
| 141 | + discountActivityService.closeRewardActivity(id); | |
| 142 | + // 校验状态 | |
| 143 | + DiscountActivityDO discountActivity = discountActivityMapper.selectById(id); | |
| 144 | + assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.CLOSE.getStatus()); | |
| 145 | + } | |
| 146 | + | |
| 147 | + @Test | |
| 148 | + public void testUpdateDiscountActivity_notExists() { | |
| 149 | + // 准备参数 | |
| 150 | + DiscountActivityUpdateReqVO reqVO = randomPojo(DiscountActivityUpdateReqVO.class); | |
| 151 | + | |
| 152 | + // 调用, 并断言异常 | |
| 153 | + assertServiceException(() -> discountActivityService.updateDiscountActivity(reqVO), DISCOUNT_ACTIVITY_NOT_EXISTS); | |
| 154 | + } | |
| 155 | + | |
| 156 | + @Test | |
| 157 | + public void testDeleteDiscountActivity_success() { | |
| 158 | + // mock 数据 | |
| 159 | + DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class, | |
| 160 | + o -> o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus())); | |
| 161 | + discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据 | |
| 162 | + // 准备参数 | |
| 163 | + Long id = dbDiscountActivity.getId(); | |
| 164 | + | |
| 165 | + // 调用 | |
| 166 | + discountActivityService.deleteDiscountActivity(id); | |
| 167 | + // 校验数据不存在了 | |
| 168 | + assertNull(discountActivityMapper.selectById(id)); | |
| 169 | + } | |
| 170 | + | |
| 171 | + @Test | |
| 172 | + public void testDeleteDiscountActivity_notExists() { | |
| 173 | + // 准备参数 | |
| 174 | + Long id = randomLongId(); | |
| 175 | + | |
| 176 | + // 调用, 并断言异常 | |
| 177 | + assertServiceException(() -> discountActivityService.deleteDiscountActivity(id), DISCOUNT_ACTIVITY_NOT_EXISTS); | |
| 178 | + } | |
| 179 | + | |
| 180 | + @Test | |
| 181 | + public void testGetDiscountActivityPage() { | |
| 182 | + // mock 数据 | |
| 183 | + DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class, o -> { // 等会查询到 | |
| 184 | + o.setName("芋艿"); | |
| 185 | + o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus()); | |
| 186 | + o.setCreateTime(buildTime(2021, 1, 15)); | |
| 187 | + }); | |
| 188 | + discountActivityMapper.insert(dbDiscountActivity); | |
| 189 | + // 测试 name 不匹配 | |
| 190 | + discountActivityMapper.insert(cloneIgnoreId(dbDiscountActivity, o -> o.setName("土豆"))); | |
| 191 | + // 测试 status 不匹配 | |
| 192 | + discountActivityMapper.insert(cloneIgnoreId(dbDiscountActivity, o -> o.setStatus(PromotionActivityStatusEnum.END.getStatus()))); | |
| 193 | + // 测试 createTime 不匹配 | |
| 194 | + discountActivityMapper.insert(cloneIgnoreId(dbDiscountActivity, o -> o.setCreateTime(buildTime(2021, 2, 10)))); | |
| 195 | + // 准备参数 | |
| 196 | + DiscountActivityPageReqVO reqVO = new DiscountActivityPageReqVO(); | |
| 197 | + reqVO.setName("芋艿"); | |
| 198 | + reqVO.setStatus(PromotionActivityStatusEnum.WAIT.getStatus()); | |
| 199 | + reqVO.setCreateTime((new Date[]{buildTime(2021, 1, 1), buildTime(2021, 1, 31)})); | |
| 200 | + | |
| 201 | + // 调用 | |
| 202 | + PageResult<DiscountActivityDO> pageResult = discountActivityService.getDiscountActivityPage(reqVO); | |
| 203 | + // 断言 | |
| 204 | + assertEquals(1, pageResult.getTotal()); | |
| 205 | + assertEquals(1, pageResult.getList().size()); | |
| 206 | + assertPojoEquals(dbDiscountActivity, pageResult.getList().get(0)); | |
| 207 | + } | |
| 208 | + | |
| 209 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java
| ... | ... | @@ -2,20 +2,17 @@ package cn.iocoder.yudao.module.promotion.service.price; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.map.MapUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; |
| 5 | +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | |
| 6 | +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | |
| 5 | 7 | import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; |
| 6 | 8 | import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; |
| 7 | 9 | import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; |
| 8 | -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; | |
| 9 | 10 | import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; |
| 10 | -import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; | |
| 11 | -import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; | |
| 12 | -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; | |
| 13 | -import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; | |
| 11 | +import cn.iocoder.yudao.module.promotion.enums.common.*; | |
| 14 | 12 | import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; |
| 15 | -import cn.iocoder.yudao.module.promotion.service.discount.DiscountService; | |
| 16 | -import cn.iocoder.yudao.module.promotion.service.reward.RewardService; | |
| 17 | -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | |
| 18 | -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | |
| 13 | +import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; | |
| 14 | +import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; | |
| 15 | +import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; | |
| 19 | 16 | import org.junit.jupiter.api.Test; |
| 20 | 17 | import org.mockito.InjectMocks; |
| 21 | 18 | import org.mockito.Mock; |
| ... | ... | @@ -44,9 +41,9 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 44 | 41 | private PriceServiceImpl priceService; |
| 45 | 42 | |
| 46 | 43 | @Mock |
| 47 | - private DiscountService discountService; | |
| 44 | + private DiscountActivityService discountService; | |
| 48 | 45 | @Mock |
| 49 | - private RewardService rewardService; | |
| 46 | + private RewardActivityService rewardActivityService; | |
| 50 | 47 | @Mock |
| 51 | 48 | private CouponService couponService; |
| 52 | 49 | @Mock |
| ... | ... | @@ -67,6 +64,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 67 | 64 | // 断言 Order 部分 |
| 68 | 65 | PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); |
| 69 | 66 | assertEquals(order.getOriginalPrice(), 200); |
| 67 | + assertEquals(order.getOrderPrice(), 180); | |
| 70 | 68 | assertEquals(order.getDiscountPrice(), 0); |
| 71 | 69 | assertEquals(order.getPointPrice(), 0); |
| 72 | 70 | assertEquals(order.getDeliveryPrice(), 0); |
| ... | ... | @@ -112,22 +110,28 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 112 | 110 | ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50)); |
| 113 | 111 | when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02)); |
| 114 | 112 | // mock 方法(限时折扣 DiscountActivity 信息) |
| 115 | - DiscountProductDO discountProduct01 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(1000L).setActivityName("活动 1000 号") | |
| 116 | - .setSkuId(10L).setPromotionPrice(80)); | |
| 117 | - DiscountProductDO discountProduct02 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(2000L).setActivityName("活动 2000 号") | |
| 118 | - .setSkuId(20L).setPromotionPrice(40)); | |
| 113 | + DiscountProductDetailBO discountProduct01 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(1000L) | |
| 114 | + .setActivityName("活动 1000 号").setSkuId(10L) | |
| 115 | + .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(40)); | |
| 116 | + DiscountProductDetailBO discountProduct02 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(2000L) | |
| 117 | + .setActivityName("活动 2000 号").setSkuId(20L) | |
| 118 | + .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(60)); | |
| 119 | 119 | when(discountService.getMatchDiscountProducts(eq(asSet(10L, 20L)))).thenReturn( |
| 120 | 120 | MapUtil.builder(10L, discountProduct01).put(20L, discountProduct02).map()); |
| 121 | 121 | |
| 122 | + // 10L: 100 * 2 - 40 * 2 = 120 | |
| 123 | + // 20L:50 * 3 - 50 * 3 * 0.4 = 90 | |
| 124 | + | |
| 122 | 125 | // 调用 |
| 123 | 126 | PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); |
| 124 | 127 | // 断言 Order 部分 |
| 125 | 128 | PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); |
| 126 | 129 | assertEquals(order.getOriginalPrice(), 350); |
| 130 | + assertEquals(order.getOrderPrice(), 210); | |
| 127 | 131 | assertEquals(order.getDiscountPrice(), 0); |
| 128 | 132 | assertEquals(order.getPointPrice(), 0); |
| 129 | 133 | assertEquals(order.getDeliveryPrice(), 0); |
| 130 | - assertEquals(order.getPayPrice(), 280); | |
| 134 | + assertEquals(order.getPayPrice(), 210); | |
| 131 | 135 | assertNull(order.getCouponId()); |
| 132 | 136 | // 断言 OrderItem 部分 |
| 133 | 137 | assertEquals(order.getItems().size(), 2); |
| ... | ... | @@ -136,19 +140,19 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 136 | 140 | assertEquals(orderItem01.getCount(), 2); |
| 137 | 141 | assertEquals(orderItem01.getOriginalPrice(), 200); |
| 138 | 142 | assertEquals(orderItem01.getOriginalUnitPrice(), 100); |
| 139 | - assertEquals(orderItem01.getDiscountPrice(), 40); | |
| 140 | - assertEquals(orderItem01.getPayPrice(), 160); | |
| 143 | + assertEquals(orderItem01.getDiscountPrice(), 80); | |
| 144 | + assertEquals(orderItem01.getPayPrice(), 120); | |
| 141 | 145 | assertEquals(orderItem01.getOrderPartPrice(), 0); |
| 142 | - assertEquals(orderItem01.getOrderDividePrice(), 160); | |
| 146 | + assertEquals(orderItem01.getOrderDividePrice(), 120); | |
| 143 | 147 | PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); |
| 144 | 148 | assertEquals(orderItem02.getSkuId(), 20L); |
| 145 | 149 | assertEquals(orderItem02.getCount(), 3); |
| 146 | 150 | assertEquals(orderItem02.getOriginalPrice(), 150); |
| 147 | 151 | assertEquals(orderItem02.getOriginalUnitPrice(), 50); |
| 148 | - assertEquals(orderItem02.getDiscountPrice(), 30); | |
| 149 | - assertEquals(orderItem02.getPayPrice(), 120); | |
| 152 | + assertEquals(orderItem02.getDiscountPrice(), 60); | |
| 153 | + assertEquals(orderItem02.getPayPrice(), 90); | |
| 150 | 154 | assertEquals(orderItem02.getOrderPartPrice(), 0); |
| 151 | - assertEquals(orderItem02.getOrderDividePrice(), 120); | |
| 155 | + assertEquals(orderItem02.getOrderDividePrice(), 90); | |
| 152 | 156 | // 断言 Promotion 部分 |
| 153 | 157 | assertEquals(priceCalculate.getPromotions().size(), 2); |
| 154 | 158 | PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); |
| ... | ... | @@ -157,28 +161,28 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 157 | 161 | assertEquals(promotion01.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); |
| 158 | 162 | assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel()); |
| 159 | 163 | assertEquals(promotion01.getOriginalPrice(), 200); |
| 160 | - assertEquals(promotion01.getDiscountPrice(), 40); | |
| 164 | + assertEquals(promotion01.getDiscountPrice(), 80); | |
| 161 | 165 | assertTrue(promotion01.getMeet()); |
| 162 | - assertEquals(promotion01.getMeetTip(), "限时折扣:省 0.40 元"); | |
| 166 | + assertEquals(promotion01.getMeetTip(), "限时折扣:省 0.80 元"); | |
| 163 | 167 | PriceCalculateRespDTO.PromotionItem promotionItem01 = promotion01.getItems().get(0); |
| 164 | 168 | assertEquals(promotion01.getItems().size(), 1); |
| 165 | 169 | assertEquals(promotionItem01.getSkuId(), 10L); |
| 166 | 170 | assertEquals(promotionItem01.getOriginalPrice(), 200); |
| 167 | - assertEquals(promotionItem01.getDiscountPrice(), 40); | |
| 171 | + assertEquals(promotionItem01.getDiscountPrice(), 80); | |
| 168 | 172 | PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1); |
| 169 | 173 | assertEquals(promotion02.getId(), 2000L); |
| 170 | 174 | assertEquals(promotion02.getName(), "活动 2000 号"); |
| 171 | 175 | assertEquals(promotion02.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); |
| 172 | 176 | assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel()); |
| 173 | 177 | assertEquals(promotion02.getOriginalPrice(), 150); |
| 174 | - assertEquals(promotion02.getDiscountPrice(), 30); | |
| 178 | + assertEquals(promotion02.getDiscountPrice(), 60); | |
| 175 | 179 | assertTrue(promotion02.getMeet()); |
| 176 | - assertEquals(promotion02.getMeetTip(), "限时折扣:省 0.30 元"); | |
| 180 | + assertEquals(promotion02.getMeetTip(), "限时折扣:省 0.60 元"); | |
| 177 | 181 | PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); |
| 178 | 182 | assertEquals(promotion02.getItems().size(), 1); |
| 179 | 183 | assertEquals(promotionItem02.getSkuId(), 20L); |
| 180 | 184 | assertEquals(promotionItem02.getOriginalPrice(), 150); |
| 181 | - assertEquals(promotionItem02.getDiscountPrice(), 30); | |
| 185 | + assertEquals(promotionItem02.getDiscountPrice(), 60); | |
| 182 | 186 | } |
| 183 | 187 | |
| 184 | 188 | /** |
| ... | ... | @@ -208,13 +212,14 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 208 | 212 | Map<RewardActivityDO, Set<Long>> matchRewardActivities = new LinkedHashMap<>(); |
| 209 | 213 | matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); |
| 210 | 214 | matchRewardActivities.put(rewardActivity02, asSet(3L)); |
| 211 | - when(rewardService.getMatchRewardActivities(eq(asSet(1L, 2L, 3L)))).thenReturn(matchRewardActivities); | |
| 215 | + when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L, 3L)))).thenReturn(matchRewardActivities); | |
| 212 | 216 | |
| 213 | 217 | // 调用 |
| 214 | 218 | PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); |
| 215 | 219 | // 断言 Order 部分 |
| 216 | 220 | PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); |
| 217 | 221 | assertEquals(order.getOriginalPrice(), 470); |
| 222 | + assertEquals(order.getOrderPrice(), 470); | |
| 218 | 223 | assertEquals(order.getDiscountPrice(), 130); |
| 219 | 224 | assertEquals(order.getPointPrice(), 0); |
| 220 | 225 | assertEquals(order.getDeliveryPrice(), 0); |
| ... | ... | @@ -305,13 +310,14 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 305 | 310 | .setRules(singletonList(new RewardActivityDO.Rule().setLimit(351).setDiscountPrice(70)))); |
| 306 | 311 | Map<RewardActivityDO, Set<Long>> matchRewardActivities = new LinkedHashMap<>(); |
| 307 | 312 | matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); |
| 308 | - when(rewardService.getMatchRewardActivities(eq(asSet(1L, 2L)))).thenReturn(matchRewardActivities); | |
| 313 | + when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L)))).thenReturn(matchRewardActivities); | |
| 309 | 314 | |
| 310 | 315 | // 调用 |
| 311 | 316 | PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); |
| 312 | 317 | // 断言 Order 部分 |
| 313 | 318 | PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); |
| 314 | 319 | assertEquals(order.getOriginalPrice(), 350); |
| 320 | + assertEquals(order.getOrderPrice(), 350); | |
| 315 | 321 | assertEquals(order.getDiscountPrice(), 0); |
| 316 | 322 | assertEquals(order.getPointPrice(), 0); |
| 317 | 323 | assertEquals(order.getDeliveryPrice(), 0); |
| ... | ... | @@ -373,19 +379,18 @@ public class PriceServiceTest extends BaseMockitoUnitTest { |
| 373 | 379 | ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); |
| 374 | 380 | when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); |
| 375 | 381 | // mock 方法(优惠劵 Coupon 信息) |
| 376 | - CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setTitle("程序员节") | |
| 377 | - .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setSpuIds(asList(1L, 2L)) | |
| 378 | - .setPriceAvailable(350).setPreferentialType(2).setPercentOff(50).setDiscountPriceLimit(70)); | |
| 382 | + CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setName("程序员节") | |
| 383 | + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L)) | |
| 384 | + .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()) | |
| 385 | + .setDiscountPercent(50).setDiscountLimitPrice(70)); | |
| 379 | 386 | when(couponService.validCoupon(eq(1024L), eq(calculateReqDTO.getUserId()))).thenReturn(coupon); |
| 380 | 387 | |
| 381 | - // 200 + 150; 350 | |
| 382 | - // | |
| 383 | - | |
| 384 | 388 | // 调用 |
| 385 | 389 | PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); |
| 386 | 390 | // 断言 Order 部分 |
| 387 | 391 | PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); |
| 388 | 392 | assertEquals(order.getOriginalPrice(), 470); |
| 393 | + assertEquals(order.getOrderPrice(), 470); | |
| 389 | 394 | assertEquals(order.getDiscountPrice(), 0); |
| 390 | 395 | assertEquals(order.getPointPrice(), 0); |
| 391 | 396 | assertEquals(order.getDeliveryPrice(), 0); | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.promotion.service.reward; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 5 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; | |
| 6 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; | |
| 7 | +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; | |
| 8 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; | |
| 9 | +import cn.iocoder.yudao.module.promotion.dal.mysql.reward.RewardActivityMapper; | |
| 10 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; | |
| 11 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; | |
| 12 | +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; | |
| 13 | +import org.junit.jupiter.api.Test; | |
| 14 | +import org.springframework.context.annotation.Import; | |
| 15 | + | |
| 16 | +import javax.annotation.Resource; | |
| 17 | +import java.time.Duration; | |
| 18 | +import java.util.Map; | |
| 19 | +import java.util.Set; | |
| 20 | + | |
| 21 | +import static cn.hutool.core.util.RandomUtil.randomEle; | |
| 22 | +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; | |
| 23 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.addTime; | |
| 24 | +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; | |
| 25 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | |
| 26 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | |
| 27 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; | |
| 28 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | |
| 29 | +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.REWARD_ACTIVITY_NOT_EXISTS; | |
| 30 | +import static java.util.Arrays.asList; | |
| 31 | +import static java.util.Collections.singletonList; | |
| 32 | +import static org.junit.jupiter.api.Assertions.*; | |
| 33 | + | |
| 34 | +/** | |
| 35 | +* {@link RewardActivityServiceImpl} 的单元测试类 | |
| 36 | +* | |
| 37 | +* @author 芋道源码 | |
| 38 | +*/ | |
| 39 | +@Import(RewardActivityServiceImpl.class) | |
| 40 | +public class RewardActivityServiceImplTest extends BaseDbUnitTest { | |
| 41 | + | |
| 42 | + @Resource | |
| 43 | + private RewardActivityServiceImpl rewardActivityService; | |
| 44 | + | |
| 45 | + @Resource | |
| 46 | + private RewardActivityMapper rewardActivityMapper; | |
| 47 | + | |
| 48 | + @Test | |
| 49 | + public void testCreateRewardActivity_success() { | |
| 50 | + // 准备参数 | |
| 51 | + RewardActivityCreateReqVO reqVO = randomPojo(RewardActivityCreateReqVO.class, o -> { | |
| 52 | + o.setConditionType(randomEle(PromotionConditionTypeEnum.values()).getType()); | |
| 53 | + o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope()); | |
| 54 | + // 用于触发进行中的状态 | |
| 55 | + o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); | |
| 56 | + }); | |
| 57 | + | |
| 58 | + // 调用 | |
| 59 | + Long rewardActivityId = rewardActivityService.createRewardActivity(reqVO); | |
| 60 | + // 断言 | |
| 61 | + assertNotNull(rewardActivityId); | |
| 62 | + // 校验记录的属性是否正确 | |
| 63 | + RewardActivityDO rewardActivity = rewardActivityMapper.selectById(rewardActivityId); | |
| 64 | + assertPojoEquals(reqVO, rewardActivity, "rules"); | |
| 65 | + assertEquals(rewardActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); | |
| 66 | + for (int i = 0; i < reqVO.getRules().size(); i++) { | |
| 67 | + assertPojoEquals(reqVO.getRules().get(i), rewardActivity.getRules().get(i)); | |
| 68 | + } | |
| 69 | + } | |
| 70 | + | |
| 71 | + @Test | |
| 72 | + public void testUpdateRewardActivity_success() { | |
| 73 | + // mock 数据 | |
| 74 | + RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus())); | |
| 75 | + rewardActivityMapper.insert(dbRewardActivity);// @Sql: 先插入出一条存在的数据 | |
| 76 | + // 准备参数 | |
| 77 | + RewardActivityUpdateReqVO reqVO = randomPojo(RewardActivityUpdateReqVO.class, o -> { | |
| 78 | + o.setId(dbRewardActivity.getId()); // 设置更新的 ID | |
| 79 | + o.setConditionType(randomEle(PromotionConditionTypeEnum.values()).getType()); | |
| 80 | + o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope()); | |
| 81 | + // 用于触发进行中的状态 | |
| 82 | + o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); | |
| 83 | + }); | |
| 84 | + | |
| 85 | + // 调用 | |
| 86 | + rewardActivityService.updateRewardActivity(reqVO); | |
| 87 | + // 校验是否更新正确 | |
| 88 | + RewardActivityDO rewardActivity = rewardActivityMapper.selectById(reqVO.getId()); // 获取最新的 | |
| 89 | + assertPojoEquals(reqVO, rewardActivity, "rules"); | |
| 90 | + assertEquals(rewardActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); | |
| 91 | + for (int i = 0; i < reqVO.getRules().size(); i++) { | |
| 92 | + assertPojoEquals(reqVO.getRules().get(i), rewardActivity.getRules().get(i)); | |
| 93 | + } | |
| 94 | + } | |
| 95 | + | |
| 96 | + @Test | |
| 97 | + public void testCloseRewardActivity() { | |
| 98 | + // mock 数据 | |
| 99 | + RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus())); | |
| 100 | + rewardActivityMapper.insert(dbRewardActivity);// @Sql: 先插入出一条存在的数据 | |
| 101 | + // 准备参数 | |
| 102 | + Long id = dbRewardActivity.getId(); | |
| 103 | + | |
| 104 | + // 调用 | |
| 105 | + rewardActivityService.closeRewardActivity(id); | |
| 106 | + // 校验状态 | |
| 107 | + RewardActivityDO rewardActivity = rewardActivityMapper.selectById(id); | |
| 108 | + assertEquals(rewardActivity.getStatus(), PromotionActivityStatusEnum.CLOSE.getStatus()); | |
| 109 | + } | |
| 110 | + | |
| 111 | + @Test | |
| 112 | + public void testUpdateRewardActivity_notExists() { | |
| 113 | + // 准备参数 | |
| 114 | + RewardActivityUpdateReqVO reqVO = randomPojo(RewardActivityUpdateReqVO.class); | |
| 115 | + | |
| 116 | + // 调用, 并断言异常 | |
| 117 | + assertServiceException(() -> rewardActivityService.updateRewardActivity(reqVO), REWARD_ACTIVITY_NOT_EXISTS); | |
| 118 | + } | |
| 119 | + | |
| 120 | + @Test | |
| 121 | + public void testDeleteRewardActivity_success() { | |
| 122 | + // mock 数据 | |
| 123 | + RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus())); | |
| 124 | + rewardActivityMapper.insert(dbRewardActivity);// @Sql: 先插入出一条存在的数据 | |
| 125 | + // 准备参数 | |
| 126 | + Long id = dbRewardActivity.getId(); | |
| 127 | + | |
| 128 | + // 调用 | |
| 129 | + rewardActivityService.deleteRewardActivity(id); | |
| 130 | + // 校验数据不存在了 | |
| 131 | + assertNull(rewardActivityMapper.selectById(id)); | |
| 132 | + } | |
| 133 | + | |
| 134 | + @Test | |
| 135 | + public void testDeleteRewardActivity_notExists() { | |
| 136 | + // 准备参数 | |
| 137 | + Long id = randomLongId(); | |
| 138 | + | |
| 139 | + // 调用, 并断言异常 | |
| 140 | + assertServiceException(() -> rewardActivityService.deleteRewardActivity(id), REWARD_ACTIVITY_NOT_EXISTS); | |
| 141 | + } | |
| 142 | + | |
| 143 | + @Test | |
| 144 | + public void testGetRewardActivityPage() { | |
| 145 | + // mock 数据 | |
| 146 | + RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> { // 等会查询到 | |
| 147 | + o.setName("芋艿"); | |
| 148 | + o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); | |
| 149 | + }); | |
| 150 | + rewardActivityMapper.insert(dbRewardActivity); | |
| 151 | + // 测试 name 不匹配 | |
| 152 | + rewardActivityMapper.insert(cloneIgnoreId(dbRewardActivity, o -> o.setName("土豆"))); | |
| 153 | + // 测试 status 不匹配 | |
| 154 | + rewardActivityMapper.insert(cloneIgnoreId(dbRewardActivity, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()))); | |
| 155 | + // 准备参数 | |
| 156 | + RewardActivityPageReqVO reqVO = new RewardActivityPageReqVO(); | |
| 157 | + reqVO.setName("芋艿"); | |
| 158 | + reqVO.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); | |
| 159 | + | |
| 160 | + // 调用 | |
| 161 | + PageResult<RewardActivityDO> pageResult = rewardActivityService.getRewardActivityPage(reqVO); | |
| 162 | + // 断言 | |
| 163 | + assertEquals(1, pageResult.getTotal()); | |
| 164 | + assertEquals(1, pageResult.getList().size()); | |
| 165 | + assertPojoEquals(dbRewardActivity, pageResult.getList().get(0), "rules"); | |
| 166 | + } | |
| 167 | + | |
| 168 | + @Test | |
| 169 | + public void testGetRewardActivities_all() { | |
| 170 | + // mock 数据 | |
| 171 | + RewardActivityDO allActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()) | |
| 172 | + .setProductScope(PromotionProductScopeEnum.ALL.getScope())); | |
| 173 | + rewardActivityMapper.insert(allActivity); | |
| 174 | + RewardActivityDO productActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()) | |
| 175 | + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L))); | |
| 176 | + rewardActivityMapper.insert(productActivity); | |
| 177 | + // 准备参数 | |
| 178 | + Set<Long> spuIds = asSet(1L, 2L); | |
| 179 | + | |
| 180 | + // 调用 | |
| 181 | + Map<RewardActivityDO, Set<Long>> matchRewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); | |
| 182 | + // 断言 | |
| 183 | + assertEquals(matchRewardActivities.size(), 1); | |
| 184 | + Map.Entry<RewardActivityDO, Set<Long>> next = matchRewardActivities.entrySet().iterator().next(); | |
| 185 | + assertPojoEquals(next.getKey(), allActivity); | |
| 186 | + assertEquals(next.getValue(), spuIds); | |
| 187 | + } | |
| 188 | + | |
| 189 | + @Test | |
| 190 | + public void testGetRewardActivities_product() { | |
| 191 | + // mock 数据 | |
| 192 | + RewardActivityDO productActivity01 = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()) | |
| 193 | + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L))); | |
| 194 | + rewardActivityMapper.insert(productActivity01); | |
| 195 | + RewardActivityDO productActivity02 = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()) | |
| 196 | + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(singletonList(3L))); | |
| 197 | + rewardActivityMapper.insert(productActivity02); | |
| 198 | + // 准备参数 | |
| 199 | + Set<Long> spuIds = asSet(1L, 2L, 3L); | |
| 200 | + | |
| 201 | + // 调用 | |
| 202 | + Map<RewardActivityDO, Set<Long>> matchRewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); | |
| 203 | + // 断言 | |
| 204 | + assertEquals(matchRewardActivities.size(), 2); | |
| 205 | + matchRewardActivities.forEach((activity, activitySpuIds) -> { | |
| 206 | + if (activity.getId().equals(productActivity01.getId())) { | |
| 207 | + assertPojoEquals(activity, productActivity01); | |
| 208 | + assertEquals(activitySpuIds, asSet(1L, 2L)); | |
| 209 | + } else if (activity.getId().equals(productActivity02.getId())) { | |
| 210 | + assertPojoEquals(activity, productActivity02); | |
| 211 | + assertEquals(activitySpuIds, asSet(3L)); | |
| 212 | + } else { | |
| 213 | + fail(); | |
| 214 | + } | |
| 215 | + }); | |
| 216 | + } | |
| 217 | + | |
| 218 | +} | ... | ... |
yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql
yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql
| ... | ... | @@ -16,4 +16,109 @@ CREATE TABLE IF NOT EXISTS "market_activity" ( |
| 16 | 16 | "deleted" bit NOT NULL DEFAULT FALSE, |
| 17 | 17 | "tenant_id" bigint(20) NOT NULL, |
| 18 | 18 | PRIMARY KEY ("id") |
| 19 | - ) COMMENT '促销活动'; | |
| 20 | 19 | \ No newline at end of file |
| 20 | + ) COMMENT '促销活动'; | |
| 21 | + | |
| 22 | +CREATE TABLE IF NOT EXISTS "promotion_coupon_template" ( | |
| 23 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 24 | + "name" varchar NOT NULL, | |
| 25 | + "status" int NOT NULL, | |
| 26 | + "total_count" int NOT NULL, | |
| 27 | + "take_limit_count" int NOT NULL, | |
| 28 | + "take_type" int NOT NULL, | |
| 29 | + "use_price" int NOT NULL, | |
| 30 | + "product_scope" int NOT NULL, | |
| 31 | + "product_spu_ids" varchar, | |
| 32 | + "validity_type" int NOT NULL, | |
| 33 | + "valid_start_time" datetime, | |
| 34 | + "valid_end_time" datetime, | |
| 35 | + "fixed_start_term" int, | |
| 36 | + "fixed_end_term" int, | |
| 37 | + "discount_type" int NOT NULL, | |
| 38 | + "discount_percent" int, | |
| 39 | + "discount_price" int, | |
| 40 | + "discount_limit_price" int, | |
| 41 | + "take_count" int NOT NULL DEFAULT 0, | |
| 42 | + "use_count" int NOT NULL DEFAULT 0, | |
| 43 | + "creator" varchar DEFAULT '', | |
| 44 | + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 45 | + "updater" varchar DEFAULT '', | |
| 46 | + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| 47 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 48 | + PRIMARY KEY ("id") | |
| 49 | +) COMMENT '优惠劵模板'; | |
| 50 | + | |
| 51 | +CREATE TABLE IF NOT EXISTS "promotion_coupon" ( | |
| 52 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 53 | + "template_id" bigint NOT NULL, | |
| 54 | + "name" varchar NOT NULL, | |
| 55 | + "status" int NOT NULL, | |
| 56 | + "user_id" bigint NOT NULL, | |
| 57 | + "take_type" int NOT NULL, | |
| 58 | + "useprice" int NOT NULL, | |
| 59 | + "valid_start_time" datetime NOT NULL, | |
| 60 | + "valid_end_time" datetime NOT NULL, | |
| 61 | + "product_scope" int NOT NULL, | |
| 62 | + "product_spu_ids" varchar, | |
| 63 | + "discount_type" int NOT NULL, | |
| 64 | + "discount_percent" int, | |
| 65 | + "discount_price" int, | |
| 66 | + "discount_limit_price" int, | |
| 67 | + "use_order_id" bigint, | |
| 68 | + "use_time" datetime, | |
| 69 | + "creator" varchar DEFAULT '', | |
| 70 | + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 71 | + "updater" varchar DEFAULT '', | |
| 72 | + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| 73 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 74 | + PRIMARY KEY ("id") | |
| 75 | +) COMMENT '优惠劵'; | |
| 76 | + | |
| 77 | +CREATE TABLE IF NOT EXISTS "promotion_reward_activity" ( | |
| 78 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 79 | + "name" varchar NOT NULL, | |
| 80 | + "status" int NOT NULL, | |
| 81 | + "start_time" datetime NOT NULL, | |
| 82 | + "end_time" datetime NOT NULL, | |
| 83 | + "remark" varchar, | |
| 84 | + "condition_type" int NOT NULL, | |
| 85 | + "product_scope" int NOT NULL, | |
| 86 | + "product_spu_ids" varchar, | |
| 87 | + "rules" varchar, | |
| 88 | + "creator" varchar DEFAULT '', | |
| 89 | + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 90 | + "updater" varchar DEFAULT '', | |
| 91 | + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| 92 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 93 | + PRIMARY KEY ("id") | |
| 94 | +) COMMENT '满减送活动'; | |
| 95 | + | |
| 96 | +CREATE TABLE IF NOT EXISTS "promotion_discount_activity" ( | |
| 97 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 98 | + "name" varchar NOT NULL, | |
| 99 | + "status" int NOT NULL, | |
| 100 | + "start_time" datetime NOT NULL, | |
| 101 | + "end_time" datetime NOT NULL, | |
| 102 | + "remark" varchar, | |
| 103 | + "creator" varchar DEFAULT '', | |
| 104 | + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 105 | + "updater" varchar DEFAULT '', | |
| 106 | + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| 107 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 108 | + PRIMARY KEY ("id") | |
| 109 | +) COMMENT '限时折扣活动'; | |
| 110 | + | |
| 111 | +CREATE TABLE IF NOT EXISTS "promotion_discount_product" ( | |
| 112 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 113 | + "activity_id" bigint NOT NULL, | |
| 114 | + "spu_id" bigint NOT NULL, | |
| 115 | + "sku_id" bigint NOT NULL, | |
| 116 | + "discount_type" int NOT NULL, | |
| 117 | + "discount_percent" int, | |
| 118 | + "discount_price" int, | |
| 119 | + "creator" varchar DEFAULT '', | |
| 120 | + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 121 | + "updater" varchar DEFAULT '', | |
| 122 | + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |
| 123 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 124 | + PRIMARY KEY ("id") | |
| 125 | +) COMMENT '限时折扣活动'; | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
| ... | ... | @@ -43,13 +43,12 @@ public class AppTradeOrderController { |
| 43 | 43 | @PreAuthenticated |
| 44 | 44 | public CommonResult<Long> createTradeOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO, |
| 45 | 45 | HttpServletRequest servletRequest) { |
| 46 | - // 获取登录用户 | |
| 46 | + // 获取登录用户、用户 IP 地址 | |
| 47 | 47 | Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); |
| 48 | - // 获取用户ip地址 | |
| 49 | 48 | String clientIp = ServletUtil.getClientIP(servletRequest); |
| 50 | 49 | // 创建交易订单,预支付记录 |
| 51 | - Long result = tradeOrderService.createTradeOrder(loginUserId, clientIp, createReqVO); | |
| 52 | - return CommonResult.success(result); | |
| 50 | + Long orderId = tradeOrderService.createTradeOrder(loginUserId, clientIp, createReqVO); | |
| 51 | + return CommonResult.success(orderId); | |
| 53 | 52 | } |
| 54 | 53 | |
| 55 | 54 | @GetMapping("/get") | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java
| ... | ... | @@ -19,7 +19,7 @@ public class AppTradeOrderCreateReqVO { |
| 19 | 19 | @ApiModelProperty(name = "优惠劵编号", example = "1024") |
| 20 | 20 | private Long couponId; |
| 21 | 21 | |
| 22 | - @ApiModelProperty(name = "备注", example = "1024") | |
| 22 | + @ApiModelProperty(name = "备注", example = "这个是我的订单哟") | |
| 23 | 23 | private String remark; |
| 24 | 24 | |
| 25 | 25 | @ApiModelProperty(name = "是否来自购物车", required = true, example = "true", notes = "true - 来自购物车;false - 立即购买") | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
| ... | ... | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.enums.TerminalEnum; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 5 | +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO.OrderItem; | |
| 5 | 6 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum; |
| 6 | 7 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderRefundStatusEnum; |
| 7 | 8 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; |
| ... | ... | @@ -74,7 +75,7 @@ public class TradeOrderDO extends BaseDO { |
| 74 | 75 | /** |
| 75 | 76 | * 购买的商品数量 |
| 76 | 77 | */ |
| 77 | - private Integer productCount; // total_num | |
| 78 | + private Integer productCount; | |
| 78 | 79 | /** |
| 79 | 80 | * 订单完成时间 |
| 80 | 81 | */ |
| ... | ... | @@ -116,14 +117,25 @@ public class TradeOrderDO extends BaseDO { |
| 116 | 117 | * 商品原价(总),单位:分 |
| 117 | 118 | * |
| 118 | 119 | * 基于 {@link TradeOrderItemDO#getTotalOriginalPrice()} 求和 |
| 120 | + * | |
| 121 | + * 对应 taobao 的 trade.total_fee 字段 | |
| 119 | 122 | */ |
| 120 | 123 | private Integer originalPrice; |
| 121 | 124 | /** |
| 125 | + * 订单原价(总),单位:分 | |
| 126 | + * | |
| 127 | + * 基于 {@link OrderItem#getPayPrice()} 求和 | |
| 128 | + * 和 {@link #originalPrice} 的差异:去除商品级优惠 | |
| 129 | + */ | |
| 130 | + private Integer orderPrice; | |
| 131 | + /** | |
| 122 | 132 | * 订单优惠(总),单位:分 |
| 123 | 133 | * |
| 124 | - * 例如说:满减折扣;不包括优惠劵、商品优惠(TODO) | |
| 134 | + * 订单级优惠:对主订单的优惠,常见如:订单满 200 元减 10 元;订单满 80 包邮。 | |
| 135 | + * | |
| 136 | + * 对应 taobao 的 order.discount_fee 字段 | |
| 125 | 137 | */ |
| 126 | - private Integer promotionPrice; | |
| 138 | + private Integer discountPrice; | |
| 127 | 139 | /** |
| 128 | 140 | * 运费金额,单位:分 |
| 129 | 141 | */ |
| ... | ... | @@ -137,12 +149,12 @@ public class TradeOrderDO extends BaseDO { |
| 137 | 149 | /** |
| 138 | 150 | * 应付金额(总),单位:分 |
| 139 | 151 | * |
| 140 | - * = {@link #originalPrice} | |
| 141 | - * + {@link #deliveryPrice} | |
| 142 | - * + {@link #adjustPrice} | |
| 143 | - * - {@link #promotionPrice} | |
| 152 | + * = {@link OrderItem#getPayPrice()} 求和 | |
| 144 | 153 | * - {@link #couponPrice} |
| 145 | 154 | * - {@link #pointPrice} |
| 155 | + * + {@link #deliveryPrice} | |
| 156 | + * - {@link #discountPrice} | |
| 157 | + * + {@link #adjustPrice} | |
| 146 | 158 | */ |
| 147 | 159 | private Integer payPrice; |
| 148 | 160 | /** |
| ... | ... | @@ -164,11 +176,11 @@ public class TradeOrderDO extends BaseDO { |
| 164 | 176 | * |
| 165 | 177 | * 关联 DeliveryTemplateDO 的 id 编号 |
| 166 | 178 | */ |
| 167 | - private Long deliveryTemplateId; // dvy_id | |
| 179 | + private Long deliveryTemplateId; | |
| 168 | 180 | /** |
| 169 | 181 | * 物流公司单号 |
| 170 | 182 | */ |
| 171 | - private String expressNo; // dvy_flow_id | |
| 183 | + private String expressNo; | |
| 172 | 184 | /** |
| 173 | 185 | * 发货状态 |
| 174 | 186 | * |
| ... | ... | @@ -227,10 +239,14 @@ public class TradeOrderDO extends BaseDO { |
| 227 | 239 | private Long couponId; |
| 228 | 240 | /** |
| 229 | 241 | * 优惠劵减免金额,单位:分 |
| 242 | + * | |
| 243 | + * 对应 taobao 的 trade.coupon_fee 字段 | |
| 230 | 244 | */ |
| 231 | 245 | private Integer couponPrice; |
| 232 | 246 | /** |
| 233 | 247 | * 积分抵扣的金额,单位:分 |
| 248 | + * | |
| 249 | + * 对应 taobao 的 trade.point_fee 字段 | |
| 234 | 250 | */ |
| 235 | 251 | private Integer pointPrice; |
| 236 | 252 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java
| ... | ... | @@ -71,7 +71,7 @@ public class TradeOrderItemDO extends BaseDO { |
| 71 | 71 | */ |
| 72 | 72 | private Integer count; |
| 73 | 73 | /** |
| 74 | - * 是否评论 | |
| 74 | + * 是否评论 TODO | |
| 75 | 75 | * |
| 76 | 76 | * false - 未评论 |
| 77 | 77 | * true - 已评论 |
| ... | ... | @@ -79,61 +79,61 @@ public class TradeOrderItemDO extends BaseDO { |
| 79 | 79 | private Boolean commented; |
| 80 | 80 | |
| 81 | 81 | // ========== 价格 + 支付基本信息 ========== |
| 82 | + | |
| 82 | 83 | /** |
| 83 | - * 商品原价(单),单位:分 | |
| 84 | + * 商品原价(总),单位:分 | |
| 84 | 85 | * |
| 85 | - * 对应 ProductSkuDO 的 price 字段 | |
| 86 | + * = {@link #originalUnitPrice} * {@link #getCount()} | |
| 86 | 87 | */ |
| 87 | - // like - original_price;niu - costPrice | |
| 88 | 88 | private Integer originalPrice; |
| 89 | 89 | /** |
| 90 | - * 商品原价(总),单位:分 | |
| 90 | + * 商品原价(单),单位:分 | |
| 91 | 91 | * |
| 92 | - * = {@link #originalPrice} * {@link #count} | |
| 92 | + * 对应 ProductSkuDO 的 price 字段 | |
| 93 | + * 对应 taobao 的 order.price 字段 | |
| 93 | 94 | */ |
| 94 | - // like - total_price;niu - 暂无 | |
| 95 | - private Integer totalOriginalPrice; | |
| 95 | + private Integer originalUnitPrice; | |
| 96 | 96 | /** |
| 97 | - * 商品级优惠(总),单位:分 | |
| 97 | + * 商品优惠(总),单位:分 | |
| 98 | + * | |
| 99 | + * 商品级优惠:对单个商品的,常见如:商品原价的 8 折;商品原价的减 50 元 | |
| 98 | 100 | * |
| 99 | - * 例如说“限时折扣”:商品原价的 8 折;商品原价的减 50 元 | |
| 101 | + * 对应 taobao 的 order.discount_fee 字段 | |
| 100 | 102 | */ |
| 101 | - // taobao - order.discount_fee(子订单商品优惠) | |
| 102 | - private Integer totalPromotionPrice; | |
| 103 | + private Integer discountPrice; | |
| 103 | 104 | /** |
| 104 | - * 最终购买金额(单),单位:分。 | |
| 105 | + * 子订单实付金额,不算主订单分摊金额,单位:分 | |
| 106 | + * | |
| 107 | + * = {@link #originalPrice} | |
| 108 | + * - {@link #discountPrice} | |
| 105 | 109 | * |
| 106 | - * = {@link #totalPresentPrice} / {@link #count} | |
| 110 | + * 对应 taobao 的 order.payment 字段 | |
| 107 | 111 | */ |
| 108 | - private Integer presentPrice; | |
| 112 | + private Integer payPrice; | |
| 113 | + | |
| 109 | 114 | /** |
| 110 | - * 最终购买金额(总),单位:分。 | |
| 115 | + * 子订单分摊金额(总),单位:分 | |
| 116 | + * 需要分摊 {@link TradeOrderDO#getDiscountPrice()}、{@link TradeOrderDO#getCouponPrice()}、{@link TradeOrderDO#getPointPrice()} | |
| 111 | 117 | * |
| 112 | - * = {@link #totalOriginalPrice} | |
| 113 | - * - {@link #totalPromotionPrice} | |
| 118 | + * 对应 taobao 的 order.part_mjz_discount 字段 | |
| 119 | + * 淘宝说明:子订单分摊优惠基础逻辑:一般正常优惠券和满减优惠按照子订单的金额进行分摊,特殊情况如果优惠券是指定商品使用的,只会分摊到对应商品子订单上不分摊。 | |
| 114 | 120 | */ |
| 115 | - // like - total_pay_price;niu - goods_money; taobao - order.payment(子订单实付金额,不算主订单分摊金额) | order.total_fee(子订单应付金额,参考使用) | |
| 116 | - private Integer totalPresentPrice; | |
| 117 | - // TODO 芋艿:part_mjz_discount(子订单分摊金额);本质上,totalOriginalPrice - totalPayPrice | |
| 121 | + private Integer orderPartPrice; | |
| 118 | 122 | /** |
| 119 | - * 应付金额(总),单位:分 | |
| 123 | + * 分摊后子订单实付金额(总),单位:分 | |
| 124 | + * | |
| 125 | + * = {@link #payPrice} | |
| 126 | + * - {@link #orderPartPrice} | |
| 127 | + * | |
| 128 | + * 对应 taobao 的 divide_order_fee 字段 | |
| 120 | 129 | */ |
| 121 | - // taobao - divide_order_fee (分摊后子订单实付金额); | |
| 122 | - private Integer totalPayPrice; | |
| 130 | + private Integer orderDividePrice; | |
| 123 | 131 | |
| 124 | 132 | // ========== 营销基本信息 ========== |
| 125 | -// /** | |
| 126 | -// * 积分抵扣的金额,单位:分 | |
| 127 | -// */ | |
| 128 | -// private Integer integralTotal; // like - integral_price;niu - point_money | |
| 129 | -// /** | |
| 130 | -// * 使用的积分 | |
| 131 | -// */ | |
| 132 | -// private Integer useIntegral; // niu - use_point | |
| 133 | 133 | |
| 134 | 134 | // ========== 退款基本信息 ========== |
| 135 | 135 | /** |
| 136 | - * 退款状态 | |
| 136 | + * 退款状态 TODO | |
| 137 | 137 | * |
| 138 | 138 | * 枚举 {@link TradeOrderItemRefundStatusEnum} |
| 139 | 139 | */ |
| ... | ... | @@ -148,7 +148,7 @@ public class TradeOrderItemDO extends BaseDO { |
| 148 | 148 | // presentTotal = buyTotal - discountTotal = 24 - 11 = 13 |
| 149 | 149 | // 最终 presentPrice = presentTotal / stock = 13 / 3 = 4.33 |
| 150 | 150 | /** |
| 151 | - * 退款总金额,单位:分 | |
| 151 | + * 退款总金额,单位:分 TODO | |
| 152 | 152 | */ |
| 153 | 153 | private Integer refundTotal; |
| 154 | 154 | |
| ... | ... | @@ -173,42 +173,5 @@ public class TradeOrderItemDO extends BaseDO { |
| 173 | 173 | |
| 174 | 174 | } |
| 175 | 175 | |
| 176 | - // TODO 芋艿:basket_date 加入购物车时间; | |
| 177 | - // TODO 芋艿:distribution_card_no 推广员使用的推销卡号 | |
| 178 | - | |
| 179 | - // TODO 待确定:mf | |
| 180 | - // TODO give_integral:赠送积分 | |
| 181 | - // TODO is_reply:是否评价,0-未评价,1-已评价 | |
| 182 | - // TODO is_sub:是否单独分佣,0-否,1-是 | |
| 183 | - // TODO vip_price:会员价 | |
| 184 | - // TODO product_type:商品类型:0-普通,1-秒杀,2-砍价,3-拼团,4-视频号 | |
| 185 | - | |
| 186 | - // TODO 待确定:lf | |
| 187 | - // TODO integral_price:积分抵扣的金额 | |
| 188 | - // TODO member_price:会员价格 | |
| 189 | - // TODO is_member:是否为会员折扣;0-不是;1-是 | |
| 190 | - // TODO member_discount:会员折扣(百分比) | |
| 191 | - | |
| 192 | - // TODO goods_info 商品信息 | |
| 193 | - | |
| 194 | - // TODO integral_price:积分抵扣的金额 | |
| 195 | - | |
| 196 | - // TODO 待确定:niu | |
| 197 | - // TODO is_virtual '是否是虚拟商品' | |
| 198 | - // TODO goods_class '商品种类(1.实物 2.虚拟3.卡券)' | |
| 199 | - // TODO adjust_money ''调整金额'' | |
| 200 | - | |
| 201 | - // TODO is_fenxiao 是否分销, | |
| 202 | - // TODO adjust_money 是否分销, | |
| 203 | - | |
| 204 | - // TODO delivery_status '配送状态' | |
| 205 | - // TODO delivery_no ''配送单号'' | |
| 206 | - // TODO gift_flag '赠品标识' | |
| 207 | - // TODO gift_flag '赠品标识' | |
| 208 | - | |
| 209 | - // TODO refund_status '退款状态' | |
| 210 | - // TODO refund_type '退款状态' | |
| 211 | - // TODO 一堆退款字段 | |
| 212 | - | |
| 213 | 176 | } |
| 214 | 177 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java
| ... | ... | @@ -3,18 +3,20 @@ package cn.iocoder.yudao.module.trade.service.order; |
| 3 | 3 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; |
| 4 | 4 | |
| 5 | 5 | /** |
| 6 | - * TODO @LeeYan9: 类注释 | |
| 6 | + * 交易订单 Service 接口 | |
| 7 | + * | |
| 7 | 8 | * @author LeeYan9 |
| 8 | 9 | * @since 2022-08-26 |
| 9 | 10 | */ |
| 10 | 11 | public interface TradeOrderService { |
| 11 | 12 | |
| 12 | 13 | /** |
| 13 | - * 创建交易订单 TODO @LeeYan9: 方法注释, 和参数要空一行 | |
| 14 | + * 创建交易订单 | |
| 15 | + * | |
| 14 | 16 | * @param loginUserId 登录用户 |
| 15 | - * @param clientIp 用户ip地址 // TODO @LeeYan9: 中英文之间, 空一行哈 | |
| 17 | + * @param clientIp 用户 IP 地址 | |
| 16 | 18 | * @param createReqVO 创建交易订单请求模型 |
| 17 | - * @return 交易订单创建结果 | |
| 19 | + * @return 交易订单的编号 | |
| 18 | 20 | */ |
| 19 | 21 | Long createTradeOrder(Long loginUserId, String clientIp, AppTradeOrderCreateReqVO createReqVO); |
| 20 | 22 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
| ... | ... | @@ -45,14 +45,17 @@ import java.util.Map; |
| 45 | 45 | import java.util.Objects; |
| 46 | 46 | |
| 47 | 47 | /** |
| 48 | - * TODO @LeeYan9: 注释 | |
| 48 | + * 交易订单 Service 实现类 | |
| 49 | + * | |
| 49 | 50 | * @author LeeYan9 |
| 50 | 51 | * @since 2022-08-26 |
| 51 | 52 | */ |
| 52 | 53 | @Service |
| 53 | 54 | public class TradeOrderServiceImpl implements TradeOrderService { |
| 54 | 55 | |
| 55 | - // TODO @LeeYan9: 相同类型的, 可以放在一起,不用空行; 例如说 Mapper 和 API 和 Properties | |
| 56 | + // TODO LeeYan9: 静态变量, 需要在最前面哈; 另外, 静态变量的注释最好写下; | |
| 57 | + private static final String BLANK_PLACEHOLDER = " "; | |
| 58 | + private static final String MULTIPLIER_PLACEHOLDER = "x"; | |
| 56 | 59 | |
| 57 | 60 | @Resource |
| 58 | 61 | private TradeOrderMapper tradeOrderMapper; |
| ... | ... | @@ -71,15 +74,10 @@ public class TradeOrderServiceImpl implements TradeOrderService { |
| 71 | 74 | @Resource |
| 72 | 75 | private TradeOrderProperties tradeOrderProperties; |
| 73 | 76 | |
| 74 | - // TODO LeeYan9: 静态变量, 需要在最前面哈; 另外, 静态变量的注释最好写下; | |
| 75 | - private static final String BLANK_PLACEHOLDER = " "; | |
| 76 | - private static final String MULTIPLIER_PLACEHOLDER = "x"; | |
| 77 | - | |
| 78 | 77 | @Override |
| 79 | 78 | @Transactional(rollbackFor = Exception.class) |
| 80 | 79 | public Long createTradeOrder(Long loginUserId, String clientIp, AppTradeOrderCreateReqVO createReqVO) { |
| 81 | - | |
| 82 | - List<Item> items = createReqVO.getItems(); // TODO @LeeYan9: 方法第一行, 不用空哈; | |
| 80 | + List<Item> items = createReqVO.getItems(); | |
| 83 | 81 | // 商品SKU检查 sku可售状态,库存 |
| 84 | 82 | List<ProductSkuRespDTO> skuInfos = productSkuApi.getSkuList(CollectionUtils.convertSet(items, Item::getSkuId)); |
| 85 | 83 | Map<Long, ProductSkuRespDTO> skuInfoMap = CollectionUtils.convertMap(skuInfos, ProductSkuRespDTO::getId); | ... | ... |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java
| ... | ... | @@ -2,6 +2,12 @@ package cn.iocoder.yudao.module.member.api.user; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO; |
| 4 | 4 | |
| 5 | +import java.util.Collection; | |
| 6 | +import java.util.List; | |
| 7 | +import java.util.Map; | |
| 8 | + | |
| 9 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | |
| 10 | + | |
| 5 | 11 | /** |
| 6 | 12 | * 会员用户的 API 接口 |
| 7 | 13 | * |
| ... | ... | @@ -17,4 +23,30 @@ public interface MemberUserApi { |
| 17 | 23 | */ |
| 18 | 24 | UserRespDTO getUser(Long id); |
| 19 | 25 | |
| 26 | + /** | |
| 27 | + * 获得会员用户信息们 | |
| 28 | + * | |
| 29 | + * @param ids 用户编号的数组 | |
| 30 | + * @return 用户信息们 | |
| 31 | + */ | |
| 32 | + List<UserRespDTO> getUsers(Collection<Long> ids); | |
| 33 | + | |
| 34 | + /** | |
| 35 | + * 获得会员用户 Map | |
| 36 | + * | |
| 37 | + * @param ids 用户编号的数组 | |
| 38 | + * @return 会员用户 Map | |
| 39 | + */ | |
| 40 | + default Map<Long, UserRespDTO> getUserMap(Collection<Long> ids) { | |
| 41 | + return convertMap(getUsers(ids), UserRespDTO::getId); | |
| 42 | + } | |
| 43 | + | |
| 44 | + /** | |
| 45 | + * 基于用户昵称,模糊匹配用户列表 | |
| 46 | + * | |
| 47 | + * @param nickname 用户昵称,模糊匹配 | |
| 48 | + * @return 用户信息的列表 | |
| 49 | + */ | |
| 50 | + List<UserRespDTO> getUserListByNickname(String nickname); | |
| 51 | + | |
| 20 | 52 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java
| ... | ... | @@ -8,6 +8,8 @@ import org.springframework.stereotype.Service; |
| 8 | 8 | import org.springframework.validation.annotation.Validated; |
| 9 | 9 | |
| 10 | 10 | import javax.annotation.Resource; |
| 11 | +import java.util.Collection; | |
| 12 | +import java.util.List; | |
| 11 | 13 | |
| 12 | 14 | /** |
| 13 | 15 | * 会员用户的 API 实现类 |
| ... | ... | @@ -27,4 +29,14 @@ public class MemberUserApiImpl implements MemberUserApi { |
| 27 | 29 | return UserConvert.INSTANCE.convert2(user); |
| 28 | 30 | } |
| 29 | 31 | |
| 32 | + @Override | |
| 33 | + public List<UserRespDTO> getUsers(Collection<Long> ids) { | |
| 34 | + return UserConvert.INSTANCE.convertList2(userService.getUserList(ids)); | |
| 35 | + } | |
| 36 | + | |
| 37 | + @Override | |
| 38 | + public List<UserRespDTO> getUserListByNickname(String nickname) { | |
| 39 | + return UserConvert.INSTANCE.convertList2(userService.getUserListByNickname(nickname)); | |
| 40 | + } | |
| 41 | + | |
| 30 | 42 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/UserController.java deleted
| 1 | -package cn.iocoder.yudao.module.member.controller.admin.user; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | -import cn.iocoder.yudao.module.member.api.user.dto.UserInfoDTO; | |
| 5 | -import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO; | |
| 6 | -import cn.iocoder.yudao.module.member.convert.user.UserConvert; | |
| 7 | -import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; | |
| 8 | -import cn.iocoder.yudao.module.member.service.user.MemberUserService; | |
| 9 | -import io.swagger.annotations.Api; | |
| 10 | -import io.swagger.annotations.ApiOperation; | |
| 11 | -import lombok.extern.slf4j.Slf4j; | |
| 12 | -import org.springframework.web.bind.annotation.GetMapping; | |
| 13 | -import org.springframework.web.bind.annotation.PathVariable; | |
| 14 | -import org.springframework.web.bind.annotation.RequestMapping; | |
| 15 | -import org.springframework.web.bind.annotation.RestController; | |
| 16 | - | |
| 17 | -import javax.annotation.Resource; | |
| 18 | - | |
| 19 | -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | |
| 20 | - | |
| 21 | -/** | |
| 22 | - * @author Banging | |
| 23 | - */ | |
| 24 | -@Slf4j | |
| 25 | -@Api("用户管理") | |
| 26 | -@RestController(value = "memberUserController") | |
| 27 | -@RequestMapping("/user") | |
| 28 | -public class UserController { | |
| 29 | - | |
| 30 | - @Resource | |
| 31 | - private MemberUserService userService; | |
| 32 | - | |
| 33 | - @ApiOperation(value = "用户信息获取",notes = "用户基本信息的获取") | |
| 34 | - @GetMapping("/{tel}") | |
| 35 | - public CommonResult<UserInfoDTO> getUserInfo(@PathVariable String tel){ | |
| 36 | - MemberUserDO user = userService.getUserByMobile(tel); | |
| 37 | - return CommonResult.success(UserConvert.INSTANCE.convertInfo(user)); | |
| 38 | - } | |
| 39 | -} |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/user/UserConvert.java
| 1 | 1 | package cn.iocoder.yudao.module.member.convert.user; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.module.member.api.user.dto.UserInfoDTO; | |
| 4 | 3 | import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO; |
| 5 | 4 | import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoRespVO; |
| 6 | 5 | import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; |
| 7 | 6 | import org.mapstruct.Mapper; |
| 8 | 7 | import org.mapstruct.factory.Mappers; |
| 9 | 8 | |
| 9 | +import java.util.List; | |
| 10 | + | |
| 10 | 11 | @Mapper |
| 11 | 12 | public interface UserConvert { |
| 12 | 13 | |
| ... | ... | @@ -15,5 +16,7 @@ public interface UserConvert { |
| 15 | 16 | AppUserInfoRespVO convert(MemberUserDO bean); |
| 16 | 17 | |
| 17 | 18 | UserRespDTO convert2(MemberUserDO bean); |
| 18 | - UserInfoDTO convertInfo(MemberUserDO bean); | |
| 19 | + | |
| 20 | + List<UserRespDTO> convertList2(List<MemberUserDO> list); | |
| 21 | + | |
| 19 | 22 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/user/MemberUserMapper.java
| 1 | 1 | package cn.iocoder.yudao.module.member.dal.mysql.user; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | |
| 4 | 5 | import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; |
| 5 | 6 | import org.apache.ibatis.annotations.Mapper; |
| 6 | 7 | |
| 8 | +import java.util.List; | |
| 9 | + | |
| 7 | 10 | /** |
| 8 | 11 | * 会员 User Mapper |
| 9 | 12 | * |
| ... | ... | @@ -16,4 +19,9 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> { |
| 16 | 19 | return selectOne(MemberUserDO::getMobile, mobile); |
| 17 | 20 | } |
| 18 | 21 | |
| 22 | + default List<MemberUserDO> selectListByNicknameLike(String nickname) { | |
| 23 | + return selectList(new LambdaQueryWrapperX<MemberUserDO>() | |
| 24 | + .likeIfPresent(MemberUserDO::getNickname, nickname)); | |
| 25 | + } | |
| 26 | + | |
| 19 | 27 | } | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java
| ... | ... | @@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobile |
| 5 | 5 | import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; |
| 6 | 6 | |
| 7 | 7 | import java.io.InputStream; |
| 8 | +import java.util.Collection; | |
| 9 | +import java.util.List; | |
| 8 | 10 | |
| 9 | 11 | /** |
| 10 | 12 | * 会员用户 Service 接口 |
| ... | ... | @@ -22,6 +24,15 @@ public interface MemberUserService { |
| 22 | 24 | MemberUserDO getUserByMobile(String mobile); |
| 23 | 25 | |
| 24 | 26 | /** |
| 27 | + * 基于用户昵称,模糊匹配用户列表 | |
| 28 | + * | |
| 29 | + * @param nickname 用户昵称,模糊匹配 | |
| 30 | + * @return 用户信息的列表 | |
| 31 | + */ | |
| 32 | + List<MemberUserDO> getUserListByNickname(String nickname); | |
| 33 | + | |
| 34 | + | |
| 35 | + /** | |
| 25 | 36 | * 基于手机号创建用户。 |
| 26 | 37 | * 如果用户已经存在,则直接进行返回 |
| 27 | 38 | * |
| ... | ... | @@ -48,6 +59,14 @@ public interface MemberUserService { |
| 48 | 59 | MemberUserDO getUser(Long id); |
| 49 | 60 | |
| 50 | 61 | /** |
| 62 | + * 通过用户 ID 查询用户们 | |
| 63 | + * | |
| 64 | + * @param ids 用户 ID | |
| 65 | + * @return 用户对象信息数组 | |
| 66 | + */ | |
| 67 | + List<MemberUserDO> getUserList(Collection<Long> ids); | |
| 68 | + | |
| 69 | + /** | |
| 51 | 70 | * 修改用户昵称 |
| 52 | 71 | * @param userId 用户id |
| 53 | 72 | * @param nickname 用户新昵称 | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java
| ... | ... | @@ -19,7 +19,9 @@ import org.springframework.transaction.annotation.Transactional; |
| 19 | 19 | import javax.annotation.Resource; |
| 20 | 20 | import javax.validation.Valid; |
| 21 | 21 | import java.io.InputStream; |
| 22 | +import java.util.Collection; | |
| 22 | 23 | import java.util.Date; |
| 24 | +import java.util.List; | |
| 23 | 25 | |
| 24 | 26 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 25 | 27 | import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; |
| ... | ... | @@ -52,6 +54,11 @@ public class MemberUserServiceImpl implements MemberUserService { |
| 52 | 54 | } |
| 53 | 55 | |
| 54 | 56 | @Override |
| 57 | + public List<MemberUserDO> getUserListByNickname(String nickname) { | |
| 58 | + return memberUserMapper.selectListByNicknameLike(nickname); | |
| 59 | + } | |
| 60 | + | |
| 61 | + @Override | |
| 55 | 62 | public MemberUserDO createUserIfAbsent(String mobile, String registerIp) { |
| 56 | 63 | // 用户已经存在 |
| 57 | 64 | MemberUserDO user = memberUserMapper.selectByMobile(mobile); |
| ... | ... | @@ -87,6 +94,11 @@ public class MemberUserServiceImpl implements MemberUserService { |
| 87 | 94 | } |
| 88 | 95 | |
| 89 | 96 | @Override |
| 97 | + public List<MemberUserDO> getUserList(Collection<Long> ids) { | |
| 98 | + return memberUserMapper.selectBatchIds(ids); | |
| 99 | + } | |
| 100 | + | |
| 101 | + @Override | |
| 90 | 102 | public void updateUserNickname(Long userId, String nickname) { |
| 91 | 103 | MemberUserDO user = this.checkUserExists(userId); |
| 92 | 104 | // 仅当新昵称不等于旧昵称时进行修改 | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateStatusReqVO.java
| 1 | 1 | package cn.iocoder.yudao.module.system.controller.admin.permission.vo.role; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 4 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 3 | 5 | import io.swagger.annotations.ApiModel; |
| 4 | 6 | import io.swagger.annotations.ApiModelProperty; |
| 5 | 7 | import lombok.Data; |
| ... | ... | @@ -16,7 +18,7 @@ public class RoleUpdateStatusReqVO { |
| 16 | 18 | |
| 17 | 19 | @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举") |
| 18 | 20 | @NotNull(message = "状态不能为空") |
| 19 | -// @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") | |
| 21 | + @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") | |
| 20 | 22 | private Integer status; |
| 21 | 23 | |
| 22 | 24 | } | ... | ... |
yudao-server/src/main/resources/application-local.yaml
| ... | ... | @@ -174,6 +174,7 @@ logging: |
| 174 | 174 | cn.iocoder.yudao.module.tool.dal.mysql: debug |
| 175 | 175 | cn.iocoder.yudao.module.member.dal.mysql: debug |
| 176 | 176 | cn.iocoder.yudao.module.trade.dal.mysql: debug |
| 177 | + cn.iocoder.yudao.module.promotion.dal.mysql: debug | |
| 177 | 178 | |
| 178 | 179 | --- #################### 微信公众号、小程序相关配置 #################### |
| 179 | 180 | wx: | ... | ... |
yudao-ui-admin/src/api/mall/product/sku.js
0 → 100644
yudao-ui-admin/src/api/mall/product/spu.js
| 1 | 1 | import request from '@/utils/request' |
| 2 | 2 | |
| 3 | -// 创建商品spu | |
| 3 | +// 创建商品 SPU | |
| 4 | 4 | export function createSpu(data) { |
| 5 | 5 | return request({ |
| 6 | 6 | url: '/product/spu/create', |
| ... | ... | @@ -9,7 +9,7 @@ export function createSpu(data) { |
| 9 | 9 | }) |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | -// 更新商品spu | |
| 12 | +// 更新商品 SPU | |
| 13 | 13 | export function updateSpu(data) { |
| 14 | 14 | return request({ |
| 15 | 15 | url: '/product/spu/update', |
| ... | ... | @@ -18,7 +18,7 @@ export function updateSpu(data) { |
| 18 | 18 | }) |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | -// 删除商品spu | |
| 21 | +// 删除商品 SPU | |
| 22 | 22 | export function deleteSpu(id) { |
| 23 | 23 | return request({ |
| 24 | 24 | url: '/product/spu/delete?id=' + id, |
| ... | ... | @@ -34,7 +34,7 @@ export function getSpu(id) { |
| 34 | 34 | }) |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | -// 获得商品spu详情 | |
| 37 | +// 获得商品 SPU 详情 | |
| 38 | 38 | export function getSpuDetail(id) { |
| 39 | 39 | return request({ |
| 40 | 40 | url: '/product/spu/get/detail?id=' + id, |
| ... | ... | @@ -42,7 +42,7 @@ export function getSpuDetail(id) { |
| 42 | 42 | }) |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | -// 获得商品spu分页 | |
| 45 | +// 获得商品 SPU 分页 | |
| 46 | 46 | export function getSpuPage(query) { |
| 47 | 47 | return request({ |
| 48 | 48 | url: '/product/spu/page', |
| ... | ... | @@ -50,3 +50,11 @@ export function getSpuPage(query) { |
| 50 | 50 | params: query |
| 51 | 51 | }) |
| 52 | 52 | } |
| 53 | + | |
| 54 | +// 获得商品 SPU 精简列表 | |
| 55 | +export function getSpuSimpleList() { | |
| 56 | + return request({ | |
| 57 | + url: '/product/spu/get-simple-list', | |
| 58 | + method: 'get', | |
| 59 | + }) | |
| 60 | +} | ... | ... |
yudao-ui-admin/src/api/mall/promotion/coupon.js
0 → 100755
| 1 | +import request from '@/utils/request' | |
| 2 | + | |
| 3 | +// 删除优惠劵 | |
| 4 | +export function deleteCoupon(id) { | |
| 5 | + return request({ | |
| 6 | + url: '/promotion/coupon/delete?id=' + id, | |
| 7 | + method: 'delete' | |
| 8 | + }) | |
| 9 | +} | |
| 10 | + | |
| 11 | +// 获得优惠劵分页 | |
| 12 | +export function getCouponPage(query) { | |
| 13 | + return request({ | |
| 14 | + url: '/promotion/coupon/page', | |
| 15 | + method: 'get', | |
| 16 | + params: query | |
| 17 | + }) | |
| 18 | +} | ... | ... |
yudao-ui-admin/src/api/promotion/couponTemplate.js renamed to yudao-ui-admin/src/api/mall/promotion/couponTemplate.js
| ... | ... | @@ -18,6 +18,19 @@ export function updateCouponTemplate(data) { |
| 18 | 18 | }) |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | +// 更新优惠劵模板的状态 | |
| 22 | +export function updateCouponTemplateStatus(id, status) { | |
| 23 | + const data = { | |
| 24 | + id, | |
| 25 | + status | |
| 26 | + } | |
| 27 | + return request({ | |
| 28 | + url: '/promotion/coupon-template/update-status', | |
| 29 | + method: 'put', | |
| 30 | + data: data | |
| 31 | + }) | |
| 32 | +} | |
| 33 | + | |
| 21 | 34 | // 删除优惠劵模板 |
| 22 | 35 | export function deleteCouponTemplate(id) { |
| 23 | 36 | return request({ | ... | ... |
yudao-ui-admin/src/api/mall/CouponTemplete/CouponTemplete.js renamed to yudao-ui-admin/src/api/mall/promotion/discountActivity.js
100644 → 100755
| 1 | 1 | import request from '@/utils/request' |
| 2 | 2 | |
| 3 | -// 创建优惠券模板 | |
| 4 | -export function create(data) { | |
| 3 | +// 创建限时折扣活动 | |
| 4 | +export function createDiscountActivity(data) { | |
| 5 | 5 | return request({ |
| 6 | - url: '/coupon/template/create', | |
| 6 | + url: '/promotion/discount-activity/create', | |
| 7 | 7 | method: 'post', |
| 8 | 8 | data: data |
| 9 | 9 | }) |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | -// 更新优惠券模板 | |
| 13 | -export function update(data) { | |
| 12 | +// 更新限时折扣活动 | |
| 13 | +export function updateDiscountActivity(data) { | |
| 14 | 14 | return request({ |
| 15 | - url: '/coupon/template/update', | |
| 15 | + url: '/promotion/discount-activity/update', | |
| 16 | 16 | method: 'put', |
| 17 | 17 | data: data |
| 18 | 18 | }) |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | -// 删除优惠券模板 | |
| 22 | -export function deleteCouponTemplete (id) { | |
| 21 | +// 关闭限时折扣活动 | |
| 22 | +export function closeDiscountActivity(id) { | |
| 23 | 23 | return request({ |
| 24 | - url: '/coupon/template/delete?id=' + id, | |
| 25 | - method: 'delete' | |
| 24 | + url: '/promotion/discount-activity/close?id=' + id, | |
| 25 | + method: 'put' | |
| 26 | 26 | }) |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | -// 获得优惠券模板 | |
| 30 | -export function get(id) { | |
| 29 | +// 删除限时折扣活动 | |
| 30 | +export function deleteDiscountActivity(id) { | |
| 31 | 31 | return request({ |
| 32 | - url: '/coupon/template/get?id=' + id, | |
| 33 | - method: 'get' | |
| 32 | + url: '/promotion/discount-activity/delete?id=' + id, | |
| 33 | + method: 'delete' | |
| 34 | 34 | }) |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | -// 获得优惠券模板分页 | |
| 38 | -export function getPage(query) { | |
| 37 | +// 获得限时折扣活动 | |
| 38 | +export function getDiscountActivity(id) { | |
| 39 | 39 | return request({ |
| 40 | - url: '/coupon/template/page', | |
| 41 | - method: 'get', | |
| 42 | - params: query | |
| 40 | + url: '/promotion/discount-activity/get?id=' + id, | |
| 41 | + method: 'get' | |
| 43 | 42 | }) |
| 44 | 43 | } |
| 45 | 44 | |
| 46 | -// 导出优惠券模板 Excel | |
| 47 | -export function exportExcel(query) { | |
| 45 | +// 获得限时折扣活动分页 | |
| 46 | +export function getDiscountActivityPage(query) { | |
| 48 | 47 | return request({ |
| 49 | - url: '/coupon/template/export-excel', | |
| 48 | + url: '/promotion/discount-activity/page', | |
| 50 | 49 | method: 'get', |
| 51 | - params: query, | |
| 52 | - responseType: 'blob' | |
| 50 | + params: query | |
| 53 | 51 | }) |
| 54 | 52 | } | ... | ... |
yudao-ui-admin/src/api/mall/promotion/rewardActivity.js
0 → 100755
| 1 | +import request from '@/utils/request' | |
| 2 | + | |
| 3 | +// 创建满减送活动 | |
| 4 | +export function createRewardActivity(data) { | |
| 5 | + return request({ | |
| 6 | + url: '/promotion/reward-activity/create', | |
| 7 | + method: 'post', | |
| 8 | + data: data | |
| 9 | + }) | |
| 10 | +} | |
| 11 | + | |
| 12 | +// 更新满减送活动 | |
| 13 | +export function updateRewardActivity(data) { | |
| 14 | + return request({ | |
| 15 | + url: '/promotion/reward-activity/update', | |
| 16 | + method: 'put', | |
| 17 | + data: data | |
| 18 | + }) | |
| 19 | +} | |
| 20 | + | |
| 21 | +// 关闭满减送活动 | |
| 22 | +export function closeRewardActivity(id) { | |
| 23 | + return request({ | |
| 24 | + url: '/promotion/reward-activity/close?id=' + id, | |
| 25 | + method: 'put' | |
| 26 | + }) | |
| 27 | +} | |
| 28 | + | |
| 29 | +// 删除满减送活动 | |
| 30 | +export function deleteRewardActivity(id) { | |
| 31 | + return request({ | |
| 32 | + url: '/promotion/reward-activity/delete?id=' + id, | |
| 33 | + method: 'delete' | |
| 34 | + }) | |
| 35 | +} | |
| 36 | + | |
| 37 | +// 获得满减送活动 | |
| 38 | +export function getRewardActivity(id) { | |
| 39 | + return request({ | |
| 40 | + url: '/promotion/reward-activity/get?id=' + id, | |
| 41 | + method: 'get' | |
| 42 | + }) | |
| 43 | +} | |
| 44 | + | |
| 45 | +// 获得满减送活动分页 | |
| 46 | +export function getRewardActivityPage(query) { | |
| 47 | + return request({ | |
| 48 | + url: '/promotion/reward-activity/page', | |
| 49 | + method: 'get', | |
| 50 | + params: query | |
| 51 | + }) | |
| 52 | +} | ... | ... |
yudao-ui-admin/src/utils/constants.js
| ... | ... | @@ -278,3 +278,39 @@ export const PromotionProductScopeEnum = { |
| 278 | 278 | name: '指定商品参与' |
| 279 | 279 | } |
| 280 | 280 | } |
| 281 | + | |
| 282 | +/** | |
| 283 | + * 营销的条件类型枚举 | |
| 284 | + */ | |
| 285 | +export const PromotionConditionTypeEnum = { | |
| 286 | + PRICE: { | |
| 287 | + type: 10, | |
| 288 | + name: '满 N 元' | |
| 289 | + }, | |
| 290 | + COUNT: { | |
| 291 | + type: 20, | |
| 292 | + name: '满 N 件' | |
| 293 | + } | |
| 294 | +} | |
| 295 | + | |
| 296 | +/** | |
| 297 | + * 促销活动的状态枚举 | |
| 298 | + */ | |
| 299 | +export const PromotionActivityStatusEnum = { | |
| 300 | + WAIT: { | |
| 301 | + type: 10, | |
| 302 | + name: '未开始' | |
| 303 | + }, | |
| 304 | + RUN: { | |
| 305 | + type: 20, | |
| 306 | + name: '进行中' | |
| 307 | + }, | |
| 308 | + END: { | |
| 309 | + type: 30, | |
| 310 | + name: '已结束' | |
| 311 | + }, | |
| 312 | + CLOSE: { | |
| 313 | + type: 40, | |
| 314 | + name: '已关闭' | |
| 315 | + } | |
| 316 | +} | ... | ... |
yudao-ui-admin/src/utils/dict.js
| ... | ... | @@ -63,7 +63,11 @@ export const DICT_TYPE = { |
| 63 | 63 | // ========== MALL - PROMOTION 模块 ========== |
| 64 | 64 | PROMOTION_DISCOUNT_TYPE: 'promotion_discount_type', // 优惠类型 |
| 65 | 65 | PROMOTION_PRODUCT_SCOPE: 'promotion_product_scope', // 营销的商品范围 |
| 66 | - COUPON_TEMPLATE_VALIDITY_TYPE: 'coupon_template_validity_type', // 优惠劵模板的有限期类型 | |
| 66 | + PROMOTION_COUPON_TEMPLATE_VALIDITY_TYPE: 'promotion_coupon_template_validity_type', // 优惠劵模板的有限期类型 | |
| 67 | + PROMOTION_COUPON_STATUS: 'promotion_coupon_status', // 优惠劵的状态 | |
| 68 | + PROMOTION_COUPON_TAKE_TYPE: 'promotion_coupon_take_type', // 优惠劵的领取方式 | |
| 69 | + PROMOTION_ACTIVITY_STATUS: 'promotion_activity_status', // 优惠活动的状态 | |
| 70 | + PROMOTION_CONDITION_TYPE: 'promotion_condition_type', // 营销的条件类型枚举 | |
| 67 | 71 | } |
| 68 | 72 | |
| 69 | 73 | /** | ... | ... |
yudao-ui-admin/src/views/mall/CouponTemplete/index.vue deleted
| 1 | -<template> | |
| 2 | - <div class="app-container"> | |
| 3 | - | |
| 4 | - <!-- 搜索工作栏 --> | |
| 5 | - <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> | |
| 6 | - <el-form-item label="优惠券类" prop="type"> | |
| 7 | - <el-select v-model="queryParams.type" placeholder="请选择优惠券类型 reward-满减 discount-折扣 random-随机" clearable size="small"> | |
| 8 | - <el-option label="请选择字典生成" value="" /> | |
| 9 | - </el-select> | |
| 10 | - </el-form-item> | |
| 11 | - <el-form-item label="优惠券名称" prop="name"> | |
| 12 | - <el-input v-model="queryParams.name" placeholder="请输入优惠券名称" clearable @keyup.enter.native="handleQuery"/> | |
| 13 | - </el-form-item> | |
| 14 | - | |
| 15 | - <el-form-item label="状态" prop="status"> | |
| 16 | - <el-select v-model="queryParams.status" placeholder="请选择状态(1进行中2已结束-1已关闭)" clearable size="small"> | |
| 17 | - <el-option label="请选择字典生成" value="" /> | |
| 18 | - </el-select> | |
| 19 | - </el-form-item> | |
| 20 | - <el-form-item label="有效日期结束时间" prop="endTime"> | |
| 21 | - <el-date-picker v-model="queryParams.endTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange" | |
| 22 | - range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" /> | |
| 23 | - </el-form-item> | |
| 24 | - | |
| 25 | - <el-form-item> | |
| 26 | - <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> | |
| 27 | - <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> | |
| 28 | - </el-form-item> | |
| 29 | - </el-form> | |
| 30 | - | |
| 31 | - <!-- 操作工具栏 --> | |
| 32 | - <el-row :gutter="10" class="mb8"> | |
| 33 | - <el-col :span="1.5"> | |
| 34 | - <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" | |
| 35 | - v-hasPermi="['CouponTemplete::create']">新增</el-button> | |
| 36 | - </el-col> | |
| 37 | - <el-col :span="1.5"> | |
| 38 | - <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading" | |
| 39 | - v-hasPermi="['CouponTemplete::export']">导出</el-button> | |
| 40 | - </el-col> | |
| 41 | - <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> | |
| 42 | - </el-row> | |
| 43 | - | |
| 44 | - <!-- 列表 --> | |
| 45 | - <el-table v-loading="loading" :data="list"> | |
| 46 | - | |
| 47 | - <!-- todo 优惠券类型--> | |
| 48 | - <el-table-column label="优惠券类型" align="center" prop="type" /> | |
| 49 | - <el-table-column label="优惠券名称" align="center" prop="name" /> | |
| 50 | - <el-table-column label="优惠券图片" align="center" prop="image" /> | |
| 51 | - <el-table-column label="发放数量" align="center" prop="count" /> | |
| 52 | - <el-table-column label="已领取数量" align="center" prop="leadCount" /> | |
| 53 | - <el-table-column label="已使用数量" align="center" prop="usedCount" /> | |
| 54 | -<!-- todo 适用商品类型--> | |
| 55 | -<!-- <el-table-column label="适用商品类型" align="center" prop="goodsType" />--> | |
| 56 | - <!-- todo 使用门槛0-无门槛 1-有门槛--> | |
| 57 | - | |
| 58 | - <el-table-column label="使用门槛" align="center" prop="hasUseLimit" /> | |
| 59 | -<!-- <el-table-column label="满多少元使用 0代表无限制" align="center" prop="atLeast" />--> | |
| 60 | - <!-- todo 发放面额 折扣--> | |
| 61 | - <el-table-column label="优惠金额/折扣" align="center" prop="money" /> | |
| 62 | -<!-- <el-table-column label="1 =< 折扣 <= 9.9 当type为discount时需要添加" align="center" prop="discount" />--> | |
| 63 | -<!-- <el-table-column label="最多折扣金额 当type为discount时可选择性添加" align="center" prop="discountLimit" />--> | |
| 64 | -<!-- <el-table-column label="最低金额 当type为radom时需要添加" align="center" prop="minMoney" />--> | |
| 65 | -<!-- <el-table-column label="最大金额 当type为radom时需要添加" align="center" prop="maxMoney" />--> | |
| 66 | - <!-- todo 1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期 --> | |
| 67 | - <el-table-column label="有效期限" align="center" prop="validityType" /> | |
| 68 | -<!-- <el-table-column label="使用开始日期 过期类型1时必填" align="center" prop="startUseTime" width="180">--> | |
| 69 | -<!-- <template slot-scope="scope">--> | |
| 70 | -<!-- <span>{{ parseTime(scope.row.startUseTime) }}</span>--> | |
| 71 | -<!-- </template>--> | |
| 72 | -<!-- </el-table-column>--> | |
| 73 | -<!-- <el-table-column label="使用结束日期 过期类型1时必填" align="center" prop="endUseTime" width="180">--> | |
| 74 | -<!-- <template slot-scope="scope">--> | |
| 75 | -<!-- <span>{{ parseTime(scope.row.endUseTime) }}</span>--> | |
| 76 | -<!-- </template>--> | |
| 77 | -<!-- </el-table-column>--> | |
| 78 | -<!-- <el-table-column label="有效日期结束时间" align="center" prop="endTime" width="180">--> | |
| 79 | -<!-- <template slot-scope="scope">--> | |
| 80 | -<!-- <span>{{ parseTime(scope.row.endTime) }}</span>--> | |
| 81 | -<!-- </template>--> | |
| 82 | -<!-- </el-table-column>--> | |
| 83 | -<!-- <el-table-column label="当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效" align="center" prop="fixedTerm" />--> | |
| 84 | -<!-- <el-table-column label="是否无限制0-否 1是" align="center" prop="whetherLimitless" />--> | |
| 85 | - <el-table-column label="领取上限" align="center" prop="maxFetch" /> | |
| 86 | - <!-- todo 0-不限制 1- 优惠券仅原价购买商品时可用--> | |
| 87 | - <el-table-column label="优惠叠加" align="center" prop="whetherForbidPreference" /> | |
| 88 | - <el-table-column label="是否显示" align="center" prop="whetherShow" /> | |
| 89 | - <el-table-column label="订单的优惠总金额" align="center" prop="discountOrderMoney" /> | |
| 90 | - <el-table-column label="用券总成交额" align="center" prop="orderMoney" /> | |
| 91 | - <el-table-column label="是否禁止发放" align="center" prop="whetherForbidden" /> | |
| 92 | - <el-table-column label="使用优惠券购买的商品数量" align="center" prop="orderGoodsNum" /> | |
| 93 | - <el-table-column label="状态" align="center" prop="status" /> | |
| 94 | - | |
| 95 | - <el-table-column label="备注" align="center" prop="couponNameRemark" /> | |
| 96 | - | |
| 97 | - <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |
| 98 | - | |
| 99 | - <template #scope> | |
| 100 | - <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | |
| 101 | - v-hasPermi="['CouponTemplete::update']">修改</el-button> | |
| 102 | - <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | |
| 103 | - v-hasPermi="['CouponTemplete::delete']">删除</el-button> | |
| 104 | - </template> | |
| 105 | - </el-table-column> | |
| 106 | - </el-table> | |
| 107 | - <!-- 分页组件 --> | |
| 108 | - <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" | |
| 109 | - @pagination="getList"/> | |
| 110 | - | |
| 111 | - <!-- 对话框(添加 / 修改) --> | |
| 112 | - <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body> | |
| 113 | - <el-form ref="form" :model="form" :rules="rules" label-width="150px"> | |
| 114 | - <el-form-item label="优惠券类型" prop="type"> | |
| 115 | - <el-select v-model="form.type" placeholder="请选择优惠券类型 reward-满减 discount-折扣 random-随机"> | |
| 116 | - <el-option label="请选择字典生成" value="" /> | |
| 117 | - </el-select> | |
| 118 | - </el-form-item> | |
| 119 | - <el-form-item label="优惠券名称" prop="name"> | |
| 120 | - <el-input v-model="form.name" placeholder="请输入优惠券名称" /> | |
| 121 | - </el-form-item> | |
| 122 | - <el-form-item label="名称备注" prop="couponNameRemark"> | |
| 123 | - <el-input v-model="form.couponNameRemark" placeholder="请输入名称备注" /> | |
| 124 | - </el-form-item> | |
| 125 | - <el-form-item label="发放数量" prop="count"> | |
| 126 | - <el-input v-model="form.count" placeholder="请输入发放数量" /> | |
| 127 | - </el-form-item> | |
| 128 | - <el-form-item label="适用商品类型" prop="goodsType"> | |
| 129 | - <el-radio-group v-model="form.goodsType"> | |
| 130 | - <el-radio label="1">请选择字典生成</el-radio> | |
| 131 | - </el-radio-group> | |
| 132 | - </el-form-item> | |
| 133 | - <!-- todo 请输入适用商品id--> | |
| 134 | - <el-form-item label="适用商品id" prop="productIds"> | |
| 135 | - <el-input v-model="form.productIds" placeholder="请输入适用商品id" /> | |
| 136 | - </el-form-item> | |
| 137 | - <el-form-item label="使用门槛" prop="hasUseLimit"> | |
| 138 | - <el-radio-group v-model="form.hasUseLimit"> | |
| 139 | - <el-radio label="1">请选择字典生成</el-radio> | |
| 140 | - </el-radio-group> | |
| 141 | - </el-form-item> | |
| 142 | - <el-form-item label="满多少元使用" prop="atLeast"> | |
| 143 | - <el-input v-model="form.atLeast" placeholder="请输入满多少元使用 0代表无限制" /> | |
| 144 | - </el-form-item> | |
| 145 | - <el-form-item label="发放面额" prop="money"> | |
| 146 | - <el-input v-model="form.money" placeholder="请输入发放面额 当type为reward时需要添加" /> | |
| 147 | - </el-form-item> | |
| 148 | - <el-form-item label="1 =< 折扣 <= 9.9" prop="discount"> | |
| 149 | - <el-input v-model="form.discount" placeholder="请输入1 =< 折扣 <= 9.9 当type为discount时需要添加" /> | |
| 150 | - </el-form-item> | |
| 151 | - <el-form-item label="最多折扣金额" prop="discountLimit"> | |
| 152 | - <el-input v-model="form.discountLimit" placeholder="请输入最多折扣金额 当type为discount时可选择性添加" /> | |
| 153 | - </el-form-item> | |
| 154 | - <el-form-item label="最低金额" prop="minMoney"> | |
| 155 | - <el-input v-model="form.minMoney" placeholder="请输入最低金额 当type为radom时需要添加" /> | |
| 156 | - </el-form-item> | |
| 157 | - <el-form-item label="最大金额" prop="maxMoney"> | |
| 158 | - <el-input v-model="form.maxMoney" placeholder="请输入最大金额 当type为radom时需要添加" /> | |
| 159 | - </el-form-item> | |
| 160 | - <el-form-item label="过期类型" prop="validityType"> | |
| 161 | - <el-radio-group v-model="form.validityType"> | |
| 162 | - <el-radio label="1">请选择字典生成</el-radio> | |
| 163 | - </el-radio-group> | |
| 164 | - </el-form-item> | |
| 165 | - <el-form-item label="使用开始日期 过期类型1时必填" prop="startUseTime"> | |
| 166 | - <el-date-picker clearable v-model="form.startUseTime" type="date" value-format="timestamp" placeholder="选择使用开始日期 过期类型1时必填" /> | |
| 167 | - </el-form-item> | |
| 168 | - <el-form-item label="使用结束日期 过期类型1时必填" prop="endUseTime"> | |
| 169 | - <el-date-picker clearable v-model="form.endUseTime" type="date" value-format="timestamp" placeholder="选择使用结束日期 过期类型1时必填" /> | |
| 170 | - </el-form-item> | |
| 171 | - <el-form-item label="当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效" prop="fixedTerm"> | |
| 172 | - <el-input v-model="form.fixedTerm" placeholder="请输入当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效" /> | |
| 173 | - </el-form-item> | |
| 174 | - <el-form-item label="是否无限制0-否 1是" prop="whetherLimitless"> | |
| 175 | - <el-radio-group v-model="form.whetherLimitless"> | |
| 176 | - <el-radio label="1">请选择字典生成</el-radio> | |
| 177 | - </el-radio-group> | |
| 178 | - </el-form-item> | |
| 179 | - <el-form-item label="每人最大领取个数" prop="maxFetch"> | |
| 180 | - <el-input v-model="form.maxFetch" placeholder="请输入每人最大领取个数" /> | |
| 181 | - </el-form-item> | |
| 182 | - <el-form-item label="是否开启过期提醒0-不开启 1-开启" prop="whetherExpireNotice"> | |
| 183 | - <el-radio-group v-model="form.whetherExpireNotice"> | |
| 184 | - <el-radio label="1">请选择字典生成</el-radio> | |
| 185 | - </el-radio-group> | |
| 186 | - </el-form-item> | |
| 187 | - <el-form-item label="过期前N天提醒" prop="expireNoticeFixedTerm"> | |
| 188 | - <el-input v-model="form.expireNoticeFixedTerm" placeholder="请输入过期前N天提醒" /> | |
| 189 | - </el-form-item> | |
| 190 | - <el-form-item label="优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用" prop="whetherForbidPreference"> | |
| 191 | - <el-radio-group v-model="form.whetherForbidPreference"> | |
| 192 | - <el-radio label="1">请选择字典生成</el-radio> | |
| 193 | - </el-radio-group> | |
| 194 | - </el-form-item> | |
| 195 | - <el-form-item label="是否显示" prop="whetherShow"> | |
| 196 | - <el-input v-model="form.whetherShow" placeholder="请输入是否显示" /> | |
| 197 | - </el-form-item> | |
| 198 | - <el-form-item label="订单的优惠总金额" prop="discountOrderMoney"> | |
| 199 | - <el-input v-model="form.discountOrderMoney" placeholder="请输入订单的优惠总金额" /> | |
| 200 | - </el-form-item> | |
| 201 | - <el-form-item label="用券总成交额" prop="orderMoney"> | |
| 202 | - <el-input v-model="form.orderMoney" placeholder="请输入用券总成交额" /> | |
| 203 | - </el-form-item> | |
| 204 | - <el-form-item label="是否禁止发放0-否 1-是" prop="whetherForbidden"> | |
| 205 | - <el-radio-group v-model="form.whetherForbidden"> | |
| 206 | - <el-radio label="1">请选择字典生成</el-radio> | |
| 207 | - </el-radio-group> | |
| 208 | - </el-form-item> | |
| 209 | - <el-form-item label="使用优惠券购买的商品数量" prop="orderGoodsNum"> | |
| 210 | - <el-input v-model="form.orderGoodsNum" placeholder="请输入使用优惠券购买的商品数量" /> | |
| 211 | - </el-form-item> | |
| 212 | - <el-form-item label="状态" prop="status"> | |
| 213 | - <el-radio-group v-model="form.status"> | |
| 214 | - <el-radio label="1">请选择字典生成</el-radio> | |
| 215 | - </el-radio-group> | |
| 216 | - </el-form-item> | |
| 217 | - <el-form-item label="有效日期结束时间" prop="endTime"> | |
| 218 | - <el-date-picker clearable v-model="form.endTime" type="date" value-format="timestamp" placeholder="选择有效日期结束时间" /> | |
| 219 | - </el-form-item> | |
| 220 | - </el-form> | |
| 221 | - <div slot="footer" class="dialog-footer"> | |
| 222 | - <el-button type="primary" @click="submitForm">确 定</el-button> | |
| 223 | - <el-button @click="cancel">取 消</el-button> | |
| 224 | - </div> | |
| 225 | - </el-dialog> | |
| 226 | - </div> | |
| 227 | -</template> | |
| 228 | - | |
| 229 | -<script> | |
| 230 | -import { create, update, deleteCouponTemplete, get, getPage, exportExcel } from "@/api/mall/CouponTemplete/CouponTemplete.js"; | |
| 231 | -import {getDictDatas} from "@/utils/dict"; | |
| 232 | - | |
| 233 | -export default { | |
| 234 | - name: "", | |
| 235 | - components: { | |
| 236 | - }, | |
| 237 | - data() { | |
| 238 | - return { | |
| 239 | - // 遮罩层 | |
| 240 | - loading: true, | |
| 241 | - // 导出遮罩层 | |
| 242 | - exportLoading: false, | |
| 243 | - // 显示搜索条件 | |
| 244 | - showSearch: true, | |
| 245 | - // 总条数 | |
| 246 | - total: 0, | |
| 247 | - // 优惠券模板列表 | |
| 248 | - list: [], | |
| 249 | - // 弹出层标题 | |
| 250 | - title: "", | |
| 251 | - // 是否显示弹出层 | |
| 252 | - open: false, | |
| 253 | - // 查询参数 | |
| 254 | - queryParams: { | |
| 255 | - pageNo: 1, | |
| 256 | - pageSize: 10, | |
| 257 | - type: null, | |
| 258 | - name: null, | |
| 259 | - couponNameRemark: null, | |
| 260 | - image: null, | |
| 261 | - count: null, | |
| 262 | - leadCount: null, | |
| 263 | - usedCount: null, | |
| 264 | - goodsType: null, | |
| 265 | - productIds: null, | |
| 266 | - hasUseLimit: null, | |
| 267 | - atLeast: null, | |
| 268 | - money: null, | |
| 269 | - discount: null, | |
| 270 | - discountLimit: null, | |
| 271 | - minMoney: null, | |
| 272 | - maxMoney: null, | |
| 273 | - validityType: null, | |
| 274 | - startUseTime: [], | |
| 275 | - endUseTime: [], | |
| 276 | - fixedTerm: null, | |
| 277 | - whetherLimitless: null, | |
| 278 | - maxFetch: null, | |
| 279 | - whetherExpireNotice: null, | |
| 280 | - expireNoticeFixedTerm: null, | |
| 281 | - whetherForbidPreference: null, | |
| 282 | - whetherShow: null, | |
| 283 | - discountOrderMoney: null, | |
| 284 | - orderMoney: null, | |
| 285 | - whetherForbidden: null, | |
| 286 | - orderGoodsNum: null, | |
| 287 | - status: null, | |
| 288 | - endTime: [], | |
| 289 | - createTime: [], | |
| 290 | - }, | |
| 291 | - //数据字典 | |
| 292 | - datas:getDictDatas(), | |
| 293 | - | |
| 294 | - // 表单参数 | |
| 295 | - form: {}, | |
| 296 | - // 表单校验 | |
| 297 | - rules: { | |
| 298 | - type: [{ required: true, message: "优惠券类型 reward-满减 discount-折扣 random-随机不能为空", trigger: "change" }], | |
| 299 | - name: [{ required: true, message: "优惠券名称不能为空", trigger: "blur" }], | |
| 300 | - count: [{ required: true, message: "发放数量不能为空", trigger: "blur" }], | |
| 301 | - leadCount: [{ required: true, message: "已领取数量不能为空", trigger: "blur" }], | |
| 302 | - usedCount: [{ required: true, message: "已使用数量不能为空", trigger: "blur" }], | |
| 303 | - goodsType: [{ required: true, message: "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用不能为空", trigger: "blur" }], | |
| 304 | - hasUseLimit: [{ required: true, message: "使用门槛0-无门槛 1-有门槛不能为空", trigger: "blur" }], | |
| 305 | - atLeast: [{ required: true, message: "满多少元使用 0代表无限制不能为空", trigger: "blur" }], | |
| 306 | - money: [{ required: true, message: "发放面额 当type为reward时需要添加不能为空", trigger: "blur" }], | |
| 307 | - discount: [{ required: true, message: "1 =< 折扣 <= 9.9 当type为discount时需要添加不能为空", trigger: "blur" }], | |
| 308 | - discountLimit: [{ required: true, message: "最多折扣金额 当type为discount时可选择性添加不能为空", trigger: "blur" }], | |
| 309 | - minMoney: [{ required: true, message: "最低金额 当type为radom时需要添加不能为空", trigger: "blur" }], | |
| 310 | - maxMoney: [{ required: true, message: "最大金额 当type为radom时需要添加不能为空", trigger: "blur" }], | |
| 311 | - validityType: [{ required: true, message: "过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期不能为空", trigger: "blur" }], | |
| 312 | - fixedTerm: [{ required: true, message: "当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效不能为空", trigger: "blur" }], | |
| 313 | - whetherLimitless: [{ required: true, message: "是否无限制0-否 1是不能为空", trigger: "blur" }], | |
| 314 | - maxFetch: [{ required: true, message: "每人最大领取个数不能为空", trigger: "blur" }], | |
| 315 | - whetherExpireNotice: [{ required: true, message: "是否开启过期提醒0-不开启 1-开启不能为空", trigger: "blur" }], | |
| 316 | - expireNoticeFixedTerm: [{ required: true, message: "过期前N天提醒不能为空", trigger: "blur" }], | |
| 317 | - whetherForbidPreference: [{ required: true, message: "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用不能为空", trigger: "blur" }], | |
| 318 | - whetherShow: [{ required: true, message: "是否显示不能为空", trigger: "blur" }], | |
| 319 | - discountOrderMoney: [{ required: true, message: "订单的优惠总金额不能为空", trigger: "blur" }], | |
| 320 | - orderMoney: [{ required: true, message: "用券总成交额不能为空", trigger: "blur" }], | |
| 321 | - whetherForbidden: [{ required: true, message: "是否禁止发放0-否 1-是不能为空", trigger: "blur" }], | |
| 322 | - orderGoodsNum: [{ required: true, message: "使用优惠券购买的商品数量不能为空", trigger: "blur" }], | |
| 323 | - status: [{ required: true, message: "状态(1进行中2已结束-1已关闭)不能为空", trigger: "blur" }], | |
| 324 | - } | |
| 325 | - }; | |
| 326 | - }, | |
| 327 | - created() { | |
| 328 | - this.getList(); | |
| 329 | - }, | |
| 330 | - methods: { | |
| 331 | - /** 查询列表 */ | |
| 332 | - getList() { | |
| 333 | - this.loading = true; | |
| 334 | - // 执行查询 | |
| 335 | - getPage(this.queryParams).then(response => { | |
| 336 | - this.list = response.data.list; | |
| 337 | - this.total = response.data.total; | |
| 338 | - this.loading = false; | |
| 339 | - }); | |
| 340 | - }, | |
| 341 | - /** 取消按钮 */ | |
| 342 | - cancel() { | |
| 343 | - this.open = false; | |
| 344 | - this.reset(); | |
| 345 | - }, | |
| 346 | - /** 表单重置 */ | |
| 347 | - reset() { | |
| 348 | - this.form = { | |
| 349 | - id: undefined, | |
| 350 | - type: undefined, | |
| 351 | - name: undefined, | |
| 352 | - couponNameRemark: undefined, | |
| 353 | - image: undefined, | |
| 354 | - count: undefined, | |
| 355 | - leadCount: undefined, | |
| 356 | - usedCount: undefined, | |
| 357 | - goodsType: undefined, | |
| 358 | - productIds: undefined, | |
| 359 | - hasUseLimit: undefined, | |
| 360 | - atLeast: undefined, | |
| 361 | - money: undefined, | |
| 362 | - discount: undefined, | |
| 363 | - discountLimit: undefined, | |
| 364 | - minMoney: undefined, | |
| 365 | - maxMoney: undefined, | |
| 366 | - validityType: undefined, | |
| 367 | - startUseTime: undefined, | |
| 368 | - endUseTime: undefined, | |
| 369 | - fixedTerm: undefined, | |
| 370 | - whetherLimitless: undefined, | |
| 371 | - maxFetch: undefined, | |
| 372 | - whetherExpireNotice: undefined, | |
| 373 | - expireNoticeFixedTerm: undefined, | |
| 374 | - whetherForbidPreference: undefined, | |
| 375 | - whetherShow: undefined, | |
| 376 | - discountOrderMoney: undefined, | |
| 377 | - orderMoney: undefined, | |
| 378 | - whetherForbidden: undefined, | |
| 379 | - orderGoodsNum: undefined, | |
| 380 | - status: undefined, | |
| 381 | - endTime: undefined, | |
| 382 | - }; | |
| 383 | - this.resetForm("form"); | |
| 384 | - }, | |
| 385 | - /** 搜索按钮操作 */ | |
| 386 | - handleQuery() { | |
| 387 | - this.queryParams.pageNo = 1; | |
| 388 | - this.getList(); | |
| 389 | - }, | |
| 390 | - /** 重置按钮操作 */ | |
| 391 | - resetQuery() { | |
| 392 | - this.resetForm("queryForm"); | |
| 393 | - this.handleQuery(); | |
| 394 | - }, | |
| 395 | - /** 新增按钮操作 */ | |
| 396 | - handleAdd() { | |
| 397 | - this.reset(); | |
| 398 | - this.open = true; | |
| 399 | - this.title = "添加优惠券模板"; | |
| 400 | - }, | |
| 401 | - /** 修改按钮操作 */ | |
| 402 | - handleUpdate(row) { | |
| 403 | - this.reset(); | |
| 404 | - const id = row.id; | |
| 405 | - get(id).then(response => { | |
| 406 | - this.form = response.data; | |
| 407 | - this.open = true; | |
| 408 | - this.title = "修改优惠券模板"; | |
| 409 | - }); | |
| 410 | - }, | |
| 411 | - /** 提交按钮 */ | |
| 412 | - submitForm() { | |
| 413 | - this.$refs["form"].validate(valid => { | |
| 414 | - if (!valid) { | |
| 415 | - return; | |
| 416 | - } | |
| 417 | - // 修改的提交 | |
| 418 | - if (this.form.id != null) { | |
| 419 | - update(this.form).then(response => { | |
| 420 | - this.$modal.msgSuccess("修改成功"); | |
| 421 | - this.open = false; | |
| 422 | - this.getList(); | |
| 423 | - }); | |
| 424 | - return; | |
| 425 | - } | |
| 426 | - // 添加的提交 | |
| 427 | - create(this.form).then(response => { | |
| 428 | - this.$modal.msgSuccess("新增成功"); | |
| 429 | - this.open = false; | |
| 430 | - this.getList(); | |
| 431 | - }); | |
| 432 | - }); | |
| 433 | - }, | |
| 434 | - /** 删除按钮操作 */ | |
| 435 | - handleDelete(row) { | |
| 436 | - const id = row.id; | |
| 437 | - this.$modal.confirm('是否确认删除优惠券模板编号为"' + id + '"的数据项?').then(function() { | |
| 438 | - return deleteCouponTemplete(id); | |
| 439 | - }).then(() => { | |
| 440 | - this.getList(); | |
| 441 | - this.$modal.msgSuccess("删除成功"); | |
| 442 | - }).catch(() => {}); | |
| 443 | - }, | |
| 444 | - /** 导出按钮操作 */ | |
| 445 | - handleExport() { | |
| 446 | - // 处理查询参数 | |
| 447 | - let params = {...this.queryParams}; | |
| 448 | - params.pageNo = undefined; | |
| 449 | - params.pageSize = undefined; | |
| 450 | - this.$modal.confirm('是否确认导出所有优惠券模板数据项?').then(() => { | |
| 451 | - this.exportLoading = true; | |
| 452 | - return exportExcel(params); | |
| 453 | - }).then(response => { | |
| 454 | - this.$download.excel(response, '优惠券模板.xls'); | |
| 455 | - this.exportLoading = false; | |
| 456 | - }).catch(() => {}); | |
| 457 | - } | |
| 458 | - } | |
| 459 | -}; | |
| 460 | -</script> |
yudao-ui-admin/src/views/mall/promotion/coupon/index.vue
0 → 100755
| 1 | +<template> | |
| 2 | + <div class="app-container"> | |
| 3 | + <!-- 搜索工作栏 --> | |
| 4 | + <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> | |
| 5 | + <el-form-item label="会员昵称" prop="nickname"> | |
| 6 | + <el-input v-model="queryParams.nickname" placeholder="请输入会员昵称" clearable @keyup.enter.native="handleQuery"/> | |
| 7 | + </el-form-item> | |
| 8 | + <el-form-item label="创建时间" prop="createTime"> | |
| 9 | + <el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange" | |
| 10 | + range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" /> | |
| 11 | + </el-form-item> | |
| 12 | + <el-form-item> | |
| 13 | + <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> | |
| 14 | + <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> | |
| 15 | + </el-form-item> | |
| 16 | + </el-form> | |
| 17 | + | |
| 18 | + <!-- 操作工具栏 --> | |
| 19 | + <el-row :gutter="10" class="mb8"> | |
| 20 | + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> | |
| 21 | + </el-row> | |
| 22 | + | |
| 23 | + <!-- Tab 选项:真正的内容在 Lab --> | |
| 24 | + <el-tabs v-model="activeTab" type="card" @tab-click="tabClick" style="margin-top: -40px;"> | |
| 25 | + <el-tab-pane v-for="tab in statusTabs" :key="tab.value" :label="tab.label" :name="tab.value" /> | |
| 26 | + </el-tabs> | |
| 27 | + | |
| 28 | + <!-- 列表 --> | |
| 29 | + <el-table v-loading="loading" :data="list"> | |
| 30 | + <el-table-column label="会员信息" align="center" prop="nickname" /> <!-- TODO 芋艿:以后支持头像,支持跳转 --> | |
| 31 | + <el-table-column label="优惠劵" align="center" prop="name" /> | |
| 32 | + <el-table-column label="优惠券类型" align="center" prop="discountType"> | |
| 33 | + <template slot-scope="scope"> | |
| 34 | + <dict-tag :type="DICT_TYPE.PROMOTION_DISCOUNT_TYPE" :value="scope.row.discountType" /> | |
| 35 | + </template> | |
| 36 | + </el-table-column> | |
| 37 | + <el-table-column label="领取方式" align="center" prop="takeType"> | |
| 38 | + <template slot-scope="scope"> | |
| 39 | + <dict-tag :type="DICT_TYPE.PROMOTION_COUPON_TAKE_TYPE" :value="scope.row.takeType" /> | |
| 40 | + </template> | |
| 41 | + </el-table-column> | |
| 42 | + <el-table-column label="状态" align="center" prop="status"> | |
| 43 | + <template slot-scope="scope"> | |
| 44 | + <dict-tag :type="DICT_TYPE.PROMOTION_COUPON_STATUS" :value="scope.row.status" /> | |
| 45 | + </template> | |
| 46 | + </el-table-column> | |
| 47 | + <el-table-column label="领取时间" align="center" prop="createTime" width="180"> | |
| 48 | + <template slot-scope="scope"> | |
| 49 | + <span>{{ parseTime(scope.row.createTime) }}</span> | |
| 50 | + </template> | |
| 51 | + </el-table-column> | |
| 52 | + <el-table-column label="使用时间" align="center" prop="useTime" width="180"> | |
| 53 | + <template slot-scope="scope"> | |
| 54 | + <span>{{ parseTime(scope.row.useTime) }}</span> | |
| 55 | + </template> | |
| 56 | + </el-table-column> | |
| 57 | + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |
| 58 | + <template slot-scope="scope"> | |
| 59 | + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | |
| 60 | + v-hasPermi="['promotion:coupon:delete']">回收</el-button> | |
| 61 | + </template> | |
| 62 | + </el-table-column> | |
| 63 | + </el-table> | |
| 64 | + <!-- 分页组件 --> | |
| 65 | + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" | |
| 66 | + @pagination="getList"/> | |
| 67 | + </div> | |
| 68 | +</template> | |
| 69 | + | |
| 70 | +<script> | |
| 71 | +import { deleteCoupon, getCouponPage } from "@/api/mall/promotion/coupon"; | |
| 72 | +import { DICT_TYPE, getDictDatas} from "@/utils/dict"; | |
| 73 | + | |
| 74 | +export default { | |
| 75 | + name: "Coupon", | |
| 76 | + components: { | |
| 77 | + }, | |
| 78 | + data() { | |
| 79 | + return { | |
| 80 | + // 遮罩层 | |
| 81 | + loading: true, | |
| 82 | + // 导出遮罩层 | |
| 83 | + exportLoading: false, | |
| 84 | + // 显示搜索条件 | |
| 85 | + showSearch: true, | |
| 86 | + // 总条数 | |
| 87 | + total: 0, | |
| 88 | + // 优惠劵列表 | |
| 89 | + list: [], | |
| 90 | + // 弹出层标题 | |
| 91 | + title: "", | |
| 92 | + // 是否显示弹出层 | |
| 93 | + open: false, | |
| 94 | + // 查询参数 | |
| 95 | + queryParams: { | |
| 96 | + pageNo: 1, | |
| 97 | + pageSize: 10, | |
| 98 | + createTime: [], | |
| 99 | + status: undefined, | |
| 100 | + }, | |
| 101 | + // Tab 筛选 | |
| 102 | + activeTab: 'all', | |
| 103 | + statusTabs: [{ | |
| 104 | + label: '全部', | |
| 105 | + value: 'all' | |
| 106 | + }], | |
| 107 | + }; | |
| 108 | + }, | |
| 109 | + created() { | |
| 110 | + this.getList(); | |
| 111 | + // 设置 statuses 过滤 | |
| 112 | + for (const dict of getDictDatas(DICT_TYPE.PROMOTION_COUPON_STATUS)) { | |
| 113 | + this.statusTabs.push({ | |
| 114 | + label: dict.label, | |
| 115 | + value: dict.value | |
| 116 | + }) | |
| 117 | + } | |
| 118 | + }, | |
| 119 | + methods: { | |
| 120 | + /** 查询列表 */ | |
| 121 | + getList() { | |
| 122 | + this.loading = true; | |
| 123 | + // 执行查询 | |
| 124 | + getCouponPage(this.queryParams).then(response => { | |
| 125 | + this.list = response.data.list; | |
| 126 | + this.total = response.data.total; | |
| 127 | + this.loading = false; | |
| 128 | + }); | |
| 129 | + }, | |
| 130 | + /** 取消按钮 */ | |
| 131 | + cancel() { | |
| 132 | + this.open = false; | |
| 133 | + this.reset(); | |
| 134 | + }, | |
| 135 | + /** 搜索按钮操作 */ | |
| 136 | + handleQuery() { | |
| 137 | + this.queryParams.pageNo = 1; | |
| 138 | + this.getList(); | |
| 139 | + }, | |
| 140 | + /** 重置按钮操作 */ | |
| 141 | + resetQuery() { | |
| 142 | + this.resetForm("queryForm"); | |
| 143 | + this.handleQuery(); | |
| 144 | + }, | |
| 145 | + /** 删除按钮操作 */ | |
| 146 | + handleDelete(row) { | |
| 147 | + const id = row.id; | |
| 148 | + this.$modal.confirm('回收将会收回会员领取的待使用的优惠券,已使用的将无法回收,确定要回收所选优惠券吗?').then(function() { | |
| 149 | + return deleteCoupon(id); | |
| 150 | + }).then(() => { | |
| 151 | + this.getList(); | |
| 152 | + this.$modal.msgSuccess("回收成功"); | |
| 153 | + }).catch(() => {}); | |
| 154 | + }, | |
| 155 | + /** tab 切换 */ | |
| 156 | + tabClick(tab) { | |
| 157 | + this.queryParams.status = tab.name === 'all' ? undefined : tab.name; | |
| 158 | + this.getList(); | |
| 159 | + } | |
| 160 | + } | |
| 161 | +}; | |
| 162 | +</script> | ... | ... |
yudao-ui-admin/src/views/promotion/couponTemplate/index.vue renamed to yudao-ui-admin/src/views/mall/promotion/couponTemplate/index.vue
| ... | ... | @@ -33,6 +33,9 @@ |
| 33 | 33 | <el-col :span="1.5"> |
| 34 | 34 | <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" |
| 35 | 35 | v-hasPermi="['promotion:coupon-template:create']">新增</el-button> |
| 36 | + <el-button type="info" plain icon="el-icon-s-operation" size="mini" | |
| 37 | + @click="() => this.$router.push('/promotion/coupon')" | |
| 38 | + v-hasPermi="['promotion:coupon:query']">会员优惠劵</el-button> | |
| 36 | 39 | </el-col> |
| 37 | 40 | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| 38 | 41 | </el-row> |
| ... | ... | @@ -52,7 +55,7 @@ |
| 52 | 55 | <el-table-column label="有效期限" align="center" prop="validityType" width="180" :formatter="validityTypeFormat" /> |
| 53 | 56 | <el-table-column label="状态" align="center" prop="status"> |
| 54 | 57 | <template slot-scope="scope"> |
| 55 | - <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" /> | |
| 58 | + <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1" @change="handleStatusChange(scope.row)"/> | |
| 56 | 59 | </template> |
| 57 | 60 | </el-table-column> |
| 58 | 61 | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> |
| ... | ... | @@ -108,7 +111,7 @@ |
| 108 | 111 | </el-radio-group> |
| 109 | 112 | </el-form-item> |
| 110 | 113 | <el-form-item v-if="form.takeType === 1" label="发放数量" prop="totalCount"> |
| 111 | - <el-input-number v-model="form.usePrice" placeholder="发放数量,没有之后不能领取或发放,-1 为不限制" | |
| 114 | + <el-input-number v-model="form.totalCount" placeholder="发放数量,没有之后不能领取或发放,-1 为不限制" | |
| 112 | 115 | style="width: 400px" :precision="0" :min="-1" /> 张 |
| 113 | 116 | </el-form-item> |
| 114 | 117 | <el-form-item v-if="form.takeType === 1" label="每人限领个数" prop="takeLimitCount"> |
| ... | ... | @@ -117,13 +120,13 @@ |
| 117 | 120 | </el-form-item> |
| 118 | 121 | <el-form-item label="有效期类型" prop="validityType"> |
| 119 | 122 | <el-radio-group v-model="form.validityType"> |
| 120 | - <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COUPON_TEMPLATE_VALIDITY_TYPE)" | |
| 123 | + <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.PROMOTION_COUPON_TEMPLATE_VALIDITY_TYPE)" | |
| 121 | 124 | :key="dict.value" :label="parseInt(dict.value)">{{dict.label}}</el-radio> |
| 122 | 125 | </el-radio-group> |
| 123 | 126 | </el-form-item> |
| 124 | 127 | <el-form-item v-if="form.validityType === CouponTemplateValidityTypeEnum.DATE.type" label="固定日期" prop="validTimes"> |
| 125 | - <el-date-picker v-model="queryParams.validTimes" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange" | |
| 126 | - range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" /> | |
| 128 | + <el-date-picker v-model="form.validTimes" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange" | |
| 129 | + :default-time="['00:00:00', '23:59:59']" /> | |
| 127 | 130 | </el-form-item> |
| 128 | 131 | <el-form-item v-if="form.validityType === CouponTemplateValidityTypeEnum.TERM.type" label="领取日期" prop="fixedStartTerm"> |
| 129 | 132 | 第 <el-input-number v-model="form.fixedStartTerm" placeholder="0 为今天生效" |
| ... | ... | @@ -138,7 +141,13 @@ |
| 138 | 141 | </el-radio-group> |
| 139 | 142 | </el-form-item> |
| 140 | 143 | <el-form-item v-if="form.productScope === PromotionProductScopeEnum.SPU.scope" prop="productSpuIds"> |
| 141 | - <el-input v-model="form.productSpuIds" placeholder="请输入商品 SPU 编号的数组" /> | |
| 144 | + <el-select v-model="form.productSpuIds" placeholder="请选择活动商品" clearable size="small" | |
| 145 | + multiple filterable style="width: 400px"> | |
| 146 | + <el-option v-for="item in productSpus" :key="item.id" :label="item.name" :value="item.id"> | |
| 147 | + <span style="float: left">{{ item.name }}</span> | |
| 148 | + <span style="float: right; color: #8492a6; font-size: 13px">¥{{ (item.minPrice / 100.0).toFixed(2) }}</span> | |
| 149 | + </el-option> | |
| 150 | + </el-select> | |
| 142 | 151 | </el-form-item> |
| 143 | 152 | </el-form> |
| 144 | 153 | <div slot="footer" class="dialog-footer"> |
| ... | ... | @@ -150,8 +159,23 @@ |
| 150 | 159 | </template> |
| 151 | 160 | |
| 152 | 161 | <script> |
| 153 | -import { createCouponTemplate, updateCouponTemplate, deleteCouponTemplate, getCouponTemplate, getCouponTemplatePage } from "@/api/promotion/couponTemplate"; | |
| 154 | -import { CommonStatusEnum, CouponTemplateValidityTypeEnum, PromotionDiscountTypeEnum, PromotionProductScopeEnum} from "@/utils/constants"; | |
| 162 | +import { | |
| 163 | + createCouponTemplate, | |
| 164 | + updateCouponTemplate, | |
| 165 | + deleteCouponTemplate, | |
| 166 | + getCouponTemplate, | |
| 167 | + getCouponTemplatePage, | |
| 168 | + updateCouponTemplateStatus | |
| 169 | +} from "@/api/mall/promotion/couponTemplate"; | |
| 170 | +import { | |
| 171 | + CommonStatusEnum, | |
| 172 | + CouponTemplateValidityTypeEnum, | |
| 173 | + PromotionDiscountTypeEnum, | |
| 174 | + PromotionProductScopeEnum | |
| 175 | +} from "@/utils/constants"; | |
| 176 | +import { getSpuSimpleList } from "@/api/mall/product/spu"; | |
| 177 | +import { parseTime } from "@/utils/ruoyi"; | |
| 178 | +import {changeRoleStatus} from "@/api/system/role"; | |
| 155 | 179 | |
| 156 | 180 | export default { |
| 157 | 181 | name: "CouponTemplate", |
| ... | ... | @@ -202,6 +226,8 @@ export default { |
| 202 | 226 | productScope: [{ required: true, message: "商品范围不能为空", trigger: "blur" }], |
| 203 | 227 | productSpuIds: [{ required: true, message: "商品范围不能为空", trigger: "blur" }], |
| 204 | 228 | }, |
| 229 | + // 商品列表 | |
| 230 | + productSpus: [], | |
| 205 | 231 | // 如下的变量,主要为了 v-if 判断可以使用到 |
| 206 | 232 | PromotionProductScopeEnum: PromotionProductScopeEnum, |
| 207 | 233 | CouponTemplateValidityTypeEnum: CouponTemplateValidityTypeEnum, |
| ... | ... | @@ -221,6 +247,10 @@ export default { |
| 221 | 247 | this.total = response.data.total; |
| 222 | 248 | this.loading = false; |
| 223 | 249 | }); |
| 250 | + // 查询商品列表 | |
| 251 | + getSpuSimpleList().then(response => { | |
| 252 | + this.productSpus = response.data | |
| 253 | + }) | |
| 224 | 254 | }, |
| 225 | 255 | /** 取消按钮 */ |
| 226 | 256 | cancel() { |
| ... | ... | @@ -233,7 +263,7 @@ export default { |
| 233 | 263 | id: undefined, |
| 234 | 264 | name: undefined, |
| 235 | 265 | discountType: PromotionDiscountTypeEnum.PRICE.type, |
| 236 | - discountPrice: 0, | |
| 266 | + discountPrice: undefined, | |
| 237 | 267 | discountPercent: undefined, |
| 238 | 268 | discountLimitPrice: undefined, |
| 239 | 269 | usePrice: undefined, |
| ... | ... | @@ -274,9 +304,11 @@ export default { |
| 274 | 304 | getCouponTemplate(id).then(response => { |
| 275 | 305 | this.form = { |
| 276 | 306 | ...response.data, |
| 277 | - discountPrice: response.data.discountPrice ? response.data.discountPrice / 100.0 : undefined, | |
| 278 | - discountPercent: response.data.discountPercent ? response.data.discountPercent / 10.0 : undefined, | |
| 279 | - usePrice: response.data.usePrice ? response.data.usePrice / 100.0 : undefined, | |
| 307 | + discountPrice: response.data.discountPrice !== undefined ? response.data.discountPrice / 100.0 : undefined, | |
| 308 | + discountPercent: response.data.discountPercent !== undefined ? response.data.discountPercent / 10.0 : undefined, | |
| 309 | + discountLimitPrice: response.data.discountLimitPrice !== undefined ? response.data.discountLimitPrice / 100.0 : undefined, | |
| 310 | + usePrice: response.data.usePrice !== undefined ? response.data.usePrice / 100.0 : undefined, | |
| 311 | + validTimes: [response.data.validStartTime, response.data.validEndTime] | |
| 280 | 312 | } |
| 281 | 313 | this.open = true; |
| 282 | 314 | this.title = "修改优惠劵"; |
| ... | ... | @@ -291,9 +323,12 @@ export default { |
| 291 | 323 | // 金额相关字段的缩放 |
| 292 | 324 | let data = { |
| 293 | 325 | ...this.form, |
| 294 | - discountPrice: this.form.discountPrice ? this.form.discountPrice * 100 : undefined, | |
| 295 | - discountPercent: this.form.discountPercent ? this.form.discountPercent * 10 : undefined, | |
| 296 | - usePrice: this.form.usePrice ? this.form.usePrice * 100 : undefined, | |
| 326 | + discountPrice: this.form.discountPrice !== undefined ? this.form.discountPrice * 100 : undefined, | |
| 327 | + discountPercent: this.form.discountPercent !== undefined ? this.form.discountPercent * 10 : undefined, | |
| 328 | + discountLimitPrice: this.form.discountLimitPrice !== undefined ? this.form.discountLimitPrice * 100 : undefined, | |
| 329 | + usePrice: this.form.usePrice !== undefined ? this.form.usePrice * 100 : undefined, | |
| 330 | + validStartTime: this.form.validTimes && this.form.validTimes.length === 2 ? this.form.validTimes[0] : undefined, | |
| 331 | + validEndTime: this.form.validTimes && this.form.validTimes.length === 2 ? this.form.validTimes[1] : undefined, | |
| 297 | 332 | } |
| 298 | 333 | // 修改的提交 |
| 299 | 334 | if (this.form.id != null) { |
| ... | ... | @@ -312,6 +347,20 @@ export default { |
| 312 | 347 | }); |
| 313 | 348 | }); |
| 314 | 349 | }, |
| 350 | + /** 优惠劵模板状态修改 */ | |
| 351 | + handleStatusChange(row) { | |
| 352 | + // 此时,row 已经变成目标状态了,所以可以直接提交请求和提示 | |
| 353 | + let text = row.status === CommonStatusEnum.ENABLE ? "启用" : "停用"; | |
| 354 | + this.$modal.confirm('确认要"' + text + '""' + row.name + '"优惠劵吗?').then(function() { | |
| 355 | + return updateCouponTemplateStatus(row.id, row.status); | |
| 356 | + }).then(() => { | |
| 357 | + this.$modal.msgSuccess(text + "成功"); | |
| 358 | + }).catch(function() { | |
| 359 | + // 异常时,需要将 row.status 状态重置回之前的 | |
| 360 | + row.status = row.status === CommonStatusEnum.ENABLE ? CommonStatusEnum.DISABLE | |
| 361 | + : CommonStatusEnum.ENABLE; | |
| 362 | + }); | |
| 363 | + }, | |
| 315 | 364 | /** 删除按钮操作 */ |
| 316 | 365 | handleDelete(row) { |
| 317 | 366 | const id = row.id; | ... | ... |
yudao-ui-admin/src/views/mall/promotion/discountActivity/index.vue
0 → 100755
| 1 | +<template> | |
| 2 | + <div class="app-container"> | |
| 3 | + | |
| 4 | + <!-- 搜索工作栏 --> | |
| 5 | + <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> | |
| 6 | + <el-form-item label="活动名称" prop="name"> | |
| 7 | + <el-input v-model="queryParams.name" placeholder="请输入活动名称" clearable @keyup.enter.native="handleQuery"/> | |
| 8 | + </el-form-item> | |
| 9 | + <el-form-item label="活动状态" prop="status"> | |
| 10 | + <el-select v-model="queryParams.status" placeholder="请选择活动状态" clearable size="small"> | |
| 11 | + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.PROMOTION_ACTIVITY_STATUS)" | |
| 12 | + :key="dict.value" :label="dict.label" :value="dict.value"/> | |
| 13 | + </el-select> | |
| 14 | + </el-form-item> | |
| 15 | + <el-form-item label="创建时间" prop="createTime"> | |
| 16 | + <el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange" | |
| 17 | + range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" /> | |
| 18 | + </el-form-item> | |
| 19 | + <el-form-item> | |
| 20 | + <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> | |
| 21 | + <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> | |
| 22 | + </el-form-item> | |
| 23 | + </el-form> | |
| 24 | + | |
| 25 | + <!-- 操作工具栏 --> | |
| 26 | + <el-row :gutter="10" class="mb8"> | |
| 27 | + <el-col :span="1.5"> | |
| 28 | + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" | |
| 29 | + v-hasPermi="['promotion:discount-activity:create']">新增</el-button> | |
| 30 | + </el-col> | |
| 31 | + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> | |
| 32 | + </el-row> | |
| 33 | + | |
| 34 | + <!-- 列表 --> | |
| 35 | + <el-table v-loading="loading" :data="list"> | |
| 36 | + <el-table-column label="活动名称" align="center" prop="name" /> | |
| 37 | + <el-table-column label="活动时间" align="center" prop="startTime" width="240"> | |
| 38 | + <template slot-scope="scope"> | |
| 39 | + <div>开始:{{ parseTime(scope.row.startTime) }}</div> | |
| 40 | + <div>结束:{{ parseTime(scope.row.endTime) }}</div> | |
| 41 | + </template> | |
| 42 | + </el-table-column> | |
| 43 | + <el-table-column label="状态" align="center" prop="status"> | |
| 44 | + <template slot-scope="scope"> | |
| 45 | + <dict-tag :type="DICT_TYPE.PROMOTION_ACTIVITY_STATUS" :value="scope.row.status" /> | |
| 46 | + </template> | |
| 47 | + </el-table-column> | |
| 48 | + <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | |
| 49 | + <template slot-scope="scope"> | |
| 50 | + <span>{{ parseTime(scope.row.createTime) }}</span> | |
| 51 | + </template> | |
| 52 | + </el-table-column> | |
| 53 | + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |
| 54 | + <template slot-scope="scope"> | |
| 55 | + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | |
| 56 | + v-if="scope.row.status !== PromotionActivityStatusEnum.CLOSE.type" | |
| 57 | + v-hasPermi="['promotion:discount-activity:update']">修改</el-button> | |
| 58 | + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleClose(scope.row)" | |
| 59 | + v-if="scope.row.status !== PromotionActivityStatusEnum.CLOSE.type && | |
| 60 | + scope.row.status !== PromotionActivityStatusEnum.END.type" | |
| 61 | + v-hasPermi="['promotion:discount-activity:close']">关闭</el-button> | |
| 62 | + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | |
| 63 | + v-if="scope.row.status === PromotionActivityStatusEnum.CLOSE.type" | |
| 64 | + v-hasPermi="['promotion:discount-activity:delete']">删除</el-button> | |
| 65 | + </template> | |
| 66 | + </el-table-column> | |
| 67 | + </el-table> | |
| 68 | + <!-- 分页组件 --> | |
| 69 | + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" | |
| 70 | + @pagination="getList"/> | |
| 71 | + | |
| 72 | + <!-- 对话框(添加 / 修改) --> | |
| 73 | + <el-dialog :title="title" :visible.sync="open" width="1000px" v-dialogDrag append-to-body> | |
| 74 | + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> | |
| 75 | + <el-form-item label="活动名称" prop="name"> | |
| 76 | + <el-input v-model="form.name" placeholder="请输入活动名称" /> | |
| 77 | + </el-form-item> | |
| 78 | + <el-form-item label="备注" prop="remark"> | |
| 79 | + <el-input type="textarea" v-model="form.remark" placeholder="请输入备注" /> | |
| 80 | + </el-form-item> | |
| 81 | + <el-form-item label="活动时间" prop="startAndEndTime"> | |
| 82 | + <el-date-picker clearable v-model="form.startAndEndTime" type="datetimerange" :default-time="['00:00:00', '23:59:59']" | |
| 83 | + value-format="timestamp" placeholder="选择开始时间" style="width: 880px" /> | |
| 84 | + </el-form-item> | |
| 85 | + <el-form-item label="商品选择"> | |
| 86 | + <el-select v-model="form.skuIds" placeholder="请选择活动商品" clearable size="small" | |
| 87 | + multiple filterable style="width: 880px" @change="changeFormSku"> | |
| 88 | + <el-option v-for="item in productSkus" :key="item.id" :label="item.spuName + ' ' + item.name" :value="item.id"> | |
| 89 | + <span style="float: left">{{ item.spuName }} {{ item.name}}</span> | |
| 90 | + <span style="float: right; color: #8492a6; font-size: 13px">¥{{ (item.price / 100.0).toFixed(2) }}</span> | |
| 91 | + </el-option> | |
| 92 | + </el-select> | |
| 93 | + <el-table v-loading="loading" :data="form.products"> | |
| 94 | + <el-table-column label="商品名称" align="center" width="200"> | |
| 95 | + <template slot-scope="scope"> | |
| 96 | + {{ scope.row.spuName }} {{ scope.row.name}} | |
| 97 | + </template> | |
| 98 | + </el-table-column> | |
| 99 | + <el-table-column label="商品价格" align="center" prop="price"> | |
| 100 | + <template slot-scope="scope"> | |
| 101 | + ¥{{ (scope.row.price / 100.0).toFixed(2) }} | |
| 102 | + </template> | |
| 103 | + </el-table-column> | |
| 104 | + <el-table-column label="库存" align="center" prop="stock" /> | |
| 105 | + <el-table-column label="优惠类型" align="center" property="discountType"> | |
| 106 | + <template slot-scope="scope"> | |
| 107 | + <el-select v-model="scope.row.discountType" placeholder="请选择优惠类型"> | |
| 108 | + <el-option v-for="dict in getDictDatas(DICT_TYPE.PROMOTION_DISCOUNT_TYPE)" | |
| 109 | + :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"/> | |
| 110 | + </el-select> | |
| 111 | + </template> | |
| 112 | + </el-table-column> | |
| 113 | + <el-table-column label="优惠" align="center" prop="startTime" width="250"> | |
| 114 | + <template slot-scope="scope"> | |
| 115 | + <el-form-item v-if="scope.row.discountType === PromotionDiscountTypeEnum.PRICE.type" prop="discountPrice"> | |
| 116 | + 减 <el-input-number v-model="scope.row.discountPrice" placeholder="请输入优惠金额" | |
| 117 | + style="width: 190px" :precision="2" :min="0" :max="scope.row.price / 100.0 - 0.01" /> 元 | |
| 118 | + </el-form-item> | |
| 119 | + <el-form-item v-if="scope.row.discountType === PromotionDiscountTypeEnum.PERCENT.type" prop="discountPercent"> | |
| 120 | + 打 <el-input-number v-model="scope.row.discountPercent" placeholder="请输入优惠折扣" | |
| 121 | + style="width: 190px" :precision="1" :min="1" :max="9.9" /> 折 | |
| 122 | + </el-form-item> | |
| 123 | + </template> | |
| 124 | + </el-table-column> | |
| 125 | + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |
| 126 | + <template slot-scope="scope"> | |
| 127 | + <el-button size="mini" type="text" icon="el-icon-delete" @click="removeFormSku(scope.row.skuId)">删除</el-button> | |
| 128 | + </template> | |
| 129 | + </el-table-column> | |
| 130 | + </el-table> | |
| 131 | + </el-form-item> | |
| 132 | + </el-form> | |
| 133 | + <div slot="footer" class="dialog-footer"> | |
| 134 | + <el-button type="primary" @click="submitForm">确 定</el-button> | |
| 135 | + <el-button @click="cancel">取 消</el-button> | |
| 136 | + </div> | |
| 137 | + </el-dialog> | |
| 138 | + </div> | |
| 139 | +</template> | |
| 140 | + | |
| 141 | +<script> | |
| 142 | +import { | |
| 143 | + createDiscountActivity, | |
| 144 | + updateDiscountActivity, | |
| 145 | + deleteDiscountActivity, | |
| 146 | + getDiscountActivity, | |
| 147 | + getDiscountActivityPage, | |
| 148 | + closeDiscountActivity | |
| 149 | +} from "@/api/mall/promotion/discountActivity"; | |
| 150 | +import { | |
| 151 | + PromotionActivityStatusEnum, PromotionDiscountTypeEnum, | |
| 152 | + PromotionProductScopeEnum | |
| 153 | +} from "@/utils/constants"; | |
| 154 | +import { getSkuOptionList } from "@/api/mall/product/sku"; | |
| 155 | +import { deepClone } from "@/utils"; | |
| 156 | + | |
| 157 | +export default { | |
| 158 | + name: "DiscountActivity", | |
| 159 | + components: { | |
| 160 | + }, | |
| 161 | + data() { | |
| 162 | + return { | |
| 163 | + // 遮罩层 | |
| 164 | + loading: true, | |
| 165 | + // 导出遮罩层 | |
| 166 | + exportLoading: false, | |
| 167 | + // 显示搜索条件 | |
| 168 | + showSearch: true, | |
| 169 | + // 总条数 | |
| 170 | + total: 0, | |
| 171 | + // 限时折扣活动列表 | |
| 172 | + list: [], | |
| 173 | + // 弹出层名称 | |
| 174 | + title: "", | |
| 175 | + // 是否显示弹出层 | |
| 176 | + open: false, | |
| 177 | + // 查询参数 | |
| 178 | + queryParams: { | |
| 179 | + pageNo: 1, | |
| 180 | + pageSize: 10, | |
| 181 | + name: null, | |
| 182 | + status: null, | |
| 183 | + createTime: [], | |
| 184 | + }, | |
| 185 | + // 表单参数 | |
| 186 | + form: { | |
| 187 | + skuIds: [], // 选中的 SKU | |
| 188 | + products: [], // 商品信息 | |
| 189 | + }, | |
| 190 | + // 表单校验 | |
| 191 | + rules: { | |
| 192 | + name: [{ required: true, message: "活动名称不能为空", trigger: "blur" }], | |
| 193 | + startAndEndTime: [{ required: true, message: "活动时间不能为空", trigger: "blur" }], | |
| 194 | + skuIds: [{ required: true, message: "选择商品不能为空", trigger: "blur" }], | |
| 195 | + }, | |
| 196 | + // 商品 SKU 列表 | |
| 197 | + productSkus: [], | |
| 198 | + // 如下的变量,主要为了 v-if 判断可以使用到 | |
| 199 | + PromotionProductScopeEnum: PromotionProductScopeEnum, | |
| 200 | + PromotionActivityStatusEnum: PromotionActivityStatusEnum, | |
| 201 | + PromotionDiscountTypeEnum: PromotionDiscountTypeEnum, | |
| 202 | + }; | |
| 203 | + }, | |
| 204 | + created() { | |
| 205 | + this.getList(); | |
| 206 | + }, | |
| 207 | + methods: { | |
| 208 | + /** 查询列表 */ | |
| 209 | + getList() { | |
| 210 | + this.loading = true; | |
| 211 | + // 执行查询 | |
| 212 | + getDiscountActivityPage(this.queryParams).then(response => { | |
| 213 | + this.list = response.data.list; | |
| 214 | + this.total = response.data.total; | |
| 215 | + this.loading = false; | |
| 216 | + }); | |
| 217 | + // 获得 SKU 商品列表 | |
| 218 | + getSkuOptionList().then(response => { | |
| 219 | + this.productSkus = response.data; | |
| 220 | + }); | |
| 221 | + }, | |
| 222 | + /** 取消按钮 */ | |
| 223 | + cancel() { | |
| 224 | + this.open = false; | |
| 225 | + this.reset(); | |
| 226 | + }, | |
| 227 | + /** 表单重置 */ | |
| 228 | + reset() { | |
| 229 | + this.form = { | |
| 230 | + id: undefined, | |
| 231 | + name: undefined, | |
| 232 | + startAndEndTime: undefined, | |
| 233 | + startTime: undefined, | |
| 234 | + endTime: undefined, | |
| 235 | + remark: undefined, | |
| 236 | + skuIds: [], | |
| 237 | + products: [], | |
| 238 | + }; | |
| 239 | + this.resetForm("form"); | |
| 240 | + }, | |
| 241 | + /** 搜索按钮操作 */ | |
| 242 | + handleQuery() { | |
| 243 | + this.queryParams.pageNo = 1; | |
| 244 | + this.getList(); | |
| 245 | + }, | |
| 246 | + /** 重置按钮操作 */ | |
| 247 | + resetQuery() { | |
| 248 | + this.resetForm("queryForm"); | |
| 249 | + this.handleQuery(); | |
| 250 | + }, | |
| 251 | + /** 新增按钮操作 */ | |
| 252 | + handleAdd() { | |
| 253 | + this.reset(); | |
| 254 | + this.open = true; | |
| 255 | + this.title = "添加限时折扣活动"; | |
| 256 | + }, | |
| 257 | + /** 修改按钮操作 */ | |
| 258 | + handleUpdate(row) { | |
| 259 | + this.reset(); | |
| 260 | + const id = row.id; | |
| 261 | + getDiscountActivity(id).then(response => { | |
| 262 | + this.form = response.data; | |
| 263 | + // 修改数据 | |
| 264 | + this.form.startAndEndTime = [response.data.startTime, response.data.endTime]; | |
| 265 | + this.form.skuIds = response.data.products.map(item => item.skuId); | |
| 266 | + this.form.products.forEach(product => { | |
| 267 | + // 获得对应的 SKU 信息 | |
| 268 | + const sku = this.productSkus.find(item => item.id === product.skuId); | |
| 269 | + if (!sku) { | |
| 270 | + return; | |
| 271 | + } | |
| 272 | + // 设置商品信息 | |
| 273 | + product.name = sku.name; | |
| 274 | + product.spuName = sku.spuName; | |
| 275 | + product.price = sku.price; | |
| 276 | + product.stock = sku.stock; | |
| 277 | + product.discountPrice = product.discountPrice !== undefined ? product.discountPrice / 100.0 : undefined; | |
| 278 | + product.discountPercent = product.discountPercent !== undefined ? product.discountPercent / 10.0 : undefined; | |
| 279 | + }); | |
| 280 | + // 打开弹窗 | |
| 281 | + this.open = true; | |
| 282 | + this.title = "修改限时折扣活动"; | |
| 283 | + }); | |
| 284 | + }, | |
| 285 | + /** 提交按钮 */ | |
| 286 | + submitForm() { | |
| 287 | + this.$refs["form"].validate(valid => { | |
| 288 | + if (!valid) { | |
| 289 | + return; | |
| 290 | + } | |
| 291 | + // 处理数据 | |
| 292 | + const data = deepClone(this.form); // 必须深拷贝,不然后面的 products 操作会有影响 | |
| 293 | + data.startTime = this.form.startAndEndTime[0]; | |
| 294 | + data.endTime = this.form.startAndEndTime[1]; | |
| 295 | + data.products.forEach(product => { | |
| 296 | + product.discountPrice = product.discountPrice !== undefined ? product.discountPrice * 100 : undefined; | |
| 297 | + product.discountPercent = product.discountPercent !== undefined ? product.discountPercent * 10 : undefined; | |
| 298 | + }); | |
| 299 | + if (!valid) { | |
| 300 | + return; | |
| 301 | + } | |
| 302 | + | |
| 303 | + // 修改的提交 | |
| 304 | + if (this.form.id != null) { | |
| 305 | + updateDiscountActivity(data).then(response => { | |
| 306 | + this.$modal.msgSuccess("修改成功"); | |
| 307 | + this.open = false; | |
| 308 | + this.getList(); | |
| 309 | + }); | |
| 310 | + return; | |
| 311 | + } | |
| 312 | + // 添加的提交 | |
| 313 | + createDiscountActivity(data).then(response => { | |
| 314 | + this.$modal.msgSuccess("新增成功"); | |
| 315 | + this.open = false; | |
| 316 | + this.getList(); | |
| 317 | + }); | |
| 318 | + }); | |
| 319 | + }, | |
| 320 | + /** 删除按钮操作 */ | |
| 321 | + handleDelete(row) { | |
| 322 | + const id = row.id; | |
| 323 | + this.$modal.confirm('是否确认删除限时折扣活动编号为"' + id + '"的数据项?').then(function() { | |
| 324 | + return deleteDiscountActivity(id); | |
| 325 | + }).then(() => { | |
| 326 | + this.getList(); | |
| 327 | + this.$modal.msgSuccess("删除成功"); | |
| 328 | + }).catch(() => {}); | |
| 329 | + }, | |
| 330 | + /** 关闭按钮操作 */ | |
| 331 | + handleClose(row) { | |
| 332 | + const id = row.id; | |
| 333 | + this.$modal.confirm('是否确认关闭限时折扣活动编号为"' + id + '"的数据项?').then(function() { | |
| 334 | + return closeDiscountActivity(id); | |
| 335 | + }).then(() => { | |
| 336 | + this.getList(); | |
| 337 | + this.$modal.msgSuccess("关闭成功"); | |
| 338 | + }).catch(() => {}); | |
| 339 | + }, | |
| 340 | + /** 当 Form 的 SKU 发生变化时 */ | |
| 341 | + changeFormSku(skuIds) { | |
| 342 | + // 处理【新增】 | |
| 343 | + skuIds.forEach(skuId => { | |
| 344 | + // 获得对应的 SKU 信息 | |
| 345 | + const sku = this.productSkus.find(item => item.id === skuId); | |
| 346 | + if (!sku) { | |
| 347 | + return; | |
| 348 | + } | |
| 349 | + // 判断已存在,直接跳过 | |
| 350 | + const product = this.form.products.find(item => item.skuId === skuId); | |
| 351 | + if (product) { | |
| 352 | + return; | |
| 353 | + } | |
| 354 | + this.form.products.push({ | |
| 355 | + skuId: sku.id, | |
| 356 | + name: sku.name, | |
| 357 | + price: sku.price, | |
| 358 | + stock: sku.stock, | |
| 359 | + spuId: sku.spuId, | |
| 360 | + spuName: sku.spuName, | |
| 361 | + discountType: PromotionDiscountTypeEnum.PRICE.type, | |
| 362 | + }); | |
| 363 | + }); | |
| 364 | + // 处理【移除】 | |
| 365 | + this.form.products.map((product, index) => { | |
| 366 | + if (!skuIds.includes(product.skuId)) { | |
| 367 | + this.form.products.splice(index, 1); | |
| 368 | + } | |
| 369 | + }); | |
| 370 | + }, | |
| 371 | + /** 移除 Form 的 SKU */ | |
| 372 | + removeFormSku(skuId) { | |
| 373 | + this.form.skuIds.map((id, index) => { | |
| 374 | + if (skuId === id) { | |
| 375 | + this.form.skuIds.splice(index, 1); | |
| 376 | + } | |
| 377 | + }); | |
| 378 | + this.changeFormSku(this.form.skuIds); | |
| 379 | + }, | |
| 380 | + } | |
| 381 | +} | |
| 382 | +</script> | ... | ... |
yudao-ui-admin/src/views/mall/promotion/rewardActivity/index.vue
0 → 100755
| 1 | +<template> | |
| 2 | + <div class="app-container"> | |
| 3 | + | |
| 4 | + <!-- 搜索工作栏 --> | |
| 5 | + <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> | |
| 6 | + <el-form-item label="活动名称" prop="name"> | |
| 7 | + <el-input v-model="queryParams.name" placeholder="请输入活动名称" clearable @keyup.enter.native="handleQuery"/> | |
| 8 | + </el-form-item> | |
| 9 | + <el-form-item label="活动状态" prop="status"> | |
| 10 | + <el-select v-model="queryParams.status" placeholder="请选择活动状态" clearable size="small"> | |
| 11 | + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.PROMOTION_ACTIVITY_STATUS)" | |
| 12 | + :key="dict.value" :label="dict.label" :value="dict.value"/> | |
| 13 | + </el-select> | |
| 14 | + </el-form-item> | |
| 15 | + <el-form-item> | |
| 16 | + <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> | |
| 17 | + <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button> | |
| 18 | + </el-form-item> | |
| 19 | + </el-form> | |
| 20 | + | |
| 21 | + <!-- 操作工具栏 --> | |
| 22 | + <el-row :gutter="10" class="mb8"> | |
| 23 | + <el-col :span="1.5"> | |
| 24 | + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" | |
| 25 | + v-hasPermi="['promotion:reward-activity:create']">新增</el-button> | |
| 26 | + </el-col> | |
| 27 | + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> | |
| 28 | + </el-row> | |
| 29 | + | |
| 30 | + <!-- 列表 --> | |
| 31 | + <el-table v-loading="loading" :data="list"> | |
| 32 | + <el-table-column label="活动名称" align="center" prop="name" /> | |
| 33 | + <el-table-column label="活动时间" align="center" prop="startTime" width="240"> | |
| 34 | + <template slot-scope="scope"> | |
| 35 | + <div>开始:{{ parseTime(scope.row.startTime) }}</div> | |
| 36 | + <div>结束:{{ parseTime(scope.row.endTime) }}</div> | |
| 37 | + </template> | |
| 38 | + </el-table-column> | |
| 39 | + <el-table-column label="状态" align="center" prop="status"> | |
| 40 | + <template slot-scope="scope"> | |
| 41 | + <dict-tag :type="DICT_TYPE.PROMOTION_ACTIVITY_STATUS" :value="scope.row.status" /> | |
| 42 | + </template> | |
| 43 | + </el-table-column> | |
| 44 | + <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | |
| 45 | + <template slot-scope="scope"> | |
| 46 | + <span>{{ parseTime(scope.row.createTime) }}</span> | |
| 47 | + </template> | |
| 48 | + </el-table-column> | |
| 49 | + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |
| 50 | + <template slot-scope="scope"> | |
| 51 | + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | |
| 52 | + v-if="scope.row.status !== PromotionActivityStatusEnum.CLOSE.type" | |
| 53 | + v-hasPermi="['promotion:reward-activity:update']">修改</el-button> | |
| 54 | + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleClose(scope.row)" | |
| 55 | + v-if="scope.row.status !== PromotionActivityStatusEnum.CLOSE.type && | |
| 56 | + scope.row.status !== PromotionActivityStatusEnum.END.type" | |
| 57 | + v-hasPermi="['promotion:reward-activity:close']">关闭</el-button> | |
| 58 | + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | |
| 59 | + v-if="scope.row.status === PromotionActivityStatusEnum.CLOSE.type" | |
| 60 | + v-hasPermi="['promotion:reward-activity:delete']">删除</el-button> | |
| 61 | + </template> | |
| 62 | + </el-table-column> | |
| 63 | + </el-table> | |
| 64 | + <!-- 分页组件 --> | |
| 65 | + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" | |
| 66 | + @pagination="getList"/> | |
| 67 | + | |
| 68 | + <!-- 对话框(添加 / 修改) --> | |
| 69 | + <el-dialog :title="title" :visible.sync="open" width="600px" v-dialogDrag append-to-body> | |
| 70 | + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> | |
| 71 | + <el-form-item label="活动名称" prop="name"> | |
| 72 | + <el-input v-model="form.name" placeholder="请输入活动名称" /> | |
| 73 | + </el-form-item> | |
| 74 | + <el-form-item label="活动时间" prop="startAndEndTime"> | |
| 75 | + <el-date-picker clearable v-model="form.startAndEndTime" type="datetimerange" :default-time="['00:00:00', '23:59:59']" | |
| 76 | + value-format="timestamp" placeholder="选择开始时间" style="width: 480px" /> | |
| 77 | + </el-form-item> | |
| 78 | + <el-form-item label="条件类型" prop="conditionType"> | |
| 79 | + <el-radio-group v-model="form.conditionType"> | |
| 80 | + <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.PROMOTION_CONDITION_TYPE)" | |
| 81 | + :key="dict.value" :label="parseInt(dict.value)">{{dict.label}}</el-radio> | |
| 82 | + </el-radio-group> | |
| 83 | + </el-form-item> | |
| 84 | + <el-form-item label="优惠设置" prop="conditionType"> | |
| 85 | + <!-- TODO 芋艿:待实现! --> | |
| 86 | + </el-form-item> | |
| 87 | + <el-form-item label="活动商品" prop="productScope"> | |
| 88 | + <el-radio-group v-model="form.productScope"> | |
| 89 | + <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.PROMOTION_PRODUCT_SCOPE)" | |
| 90 | + :key="dict.value" :label="parseInt(dict.value)">{{dict.label}}</el-radio> | |
| 91 | + </el-radio-group> | |
| 92 | + </el-form-item> | |
| 93 | + <el-form-item v-if="form.productScope === PromotionProductScopeEnum.SPU.scope" prop="productSpuIds"> | |
| 94 | + <el-select v-model="form.productSpuIds" placeholder="请选择活动商品" clearable size="small" | |
| 95 | + multiple filterable style="width: 400px"> | |
| 96 | + <el-option v-for="item in productSpus" :key="item.id" :label="item.name" :value="item.id"> | |
| 97 | + <span style="float: left">{{ item.name }}</span> | |
| 98 | + <span style="float: right; color: #8492a6; font-size: 13px">¥{{ (item.minPrice / 100.0).toFixed(2) }}</span> | |
| 99 | + </el-option> | |
| 100 | + </el-select> | |
| 101 | + </el-form-item> | |
| 102 | + <el-form-item label="备注" prop="remark"> | |
| 103 | + <el-input v-model="form.remark" placeholder="请输入备注" /> | |
| 104 | + </el-form-item> | |
| 105 | + </el-form> | |
| 106 | + <div slot="footer" class="dialog-footer"> | |
| 107 | + <el-button type="primary" @click="submitForm">确 定</el-button> | |
| 108 | + <el-button @click="cancel">取 消</el-button> | |
| 109 | + </div> | |
| 110 | + </el-dialog> | |
| 111 | + </div> | |
| 112 | +</template> | |
| 113 | + | |
| 114 | +<script> | |
| 115 | +import { | |
| 116 | + createRewardActivity, | |
| 117 | + updateRewardActivity, | |
| 118 | + deleteRewardActivity, | |
| 119 | + getRewardActivity, | |
| 120 | + getRewardActivityPage, | |
| 121 | + closeRewardActivity | |
| 122 | +} from "@/api/mall/promotion/rewardActivity"; | |
| 123 | +import { | |
| 124 | + PromotionConditionTypeEnum, | |
| 125 | + PromotionProductScopeEnum, | |
| 126 | + PromotionActivityStatusEnum | |
| 127 | +} from "@/utils/constants"; | |
| 128 | +import {getSpuSimpleList} from "@/api/mall/product/spu"; | |
| 129 | + | |
| 130 | +export default { | |
| 131 | + name: "RewardActivity", | |
| 132 | + components: { | |
| 133 | + }, | |
| 134 | + data() { | |
| 135 | + return { | |
| 136 | + // 遮罩层 | |
| 137 | + loading: true, | |
| 138 | + // 导出遮罩层 | |
| 139 | + exportLoading: false, | |
| 140 | + // 显示搜索条件 | |
| 141 | + showSearch: true, | |
| 142 | + // 总条数 | |
| 143 | + total: 0, | |
| 144 | + // 满减送活动列表 | |
| 145 | + list: [], | |
| 146 | + // 弹出层标题 | |
| 147 | + title: "", | |
| 148 | + // 是否显示弹出层 | |
| 149 | + open: false, | |
| 150 | + // 查询参数 | |
| 151 | + queryParams: { | |
| 152 | + pageNo: 1, | |
| 153 | + pageSize: 10, | |
| 154 | + name: null, | |
| 155 | + status: null, | |
| 156 | + }, | |
| 157 | + // 表单参数 | |
| 158 | + form: {}, | |
| 159 | + // 表单校验 | |
| 160 | + rules: { | |
| 161 | + name: [{ required: true, message: "活动名称不能为空", trigger: "blur" }], | |
| 162 | + startAndEndTime: [{ required: true, message: "活动时间不能为空", trigger: "blur" }], | |
| 163 | + conditionType: [{ required: true, message: "条件类型不能为空", trigger: "change" }], | |
| 164 | + productScope: [{ required: true, message: "商品范围不能为空", trigger: "blur" }], | |
| 165 | + productSpuIds: [{ required: true, message: "商品范围不能为空", trigger: "blur" }], | |
| 166 | + }, | |
| 167 | + // 商品列表 | |
| 168 | + productSpus: [], | |
| 169 | + // 如下的变量,主要为了 v-if 判断可以使用到 | |
| 170 | + PromotionProductScopeEnum: PromotionProductScopeEnum, | |
| 171 | + PromotionActivityStatusEnum: PromotionActivityStatusEnum, | |
| 172 | + }; | |
| 173 | + }, | |
| 174 | + created() { | |
| 175 | + this.getList(); | |
| 176 | + // 查询商品列表 | |
| 177 | + getSpuSimpleList().then(response => { | |
| 178 | + this.productSpus = response.data | |
| 179 | + }) | |
| 180 | + }, | |
| 181 | + methods: { | |
| 182 | + /** 查询列表 */ | |
| 183 | + getList() { | |
| 184 | + this.loading = true; | |
| 185 | + // 执行查询 | |
| 186 | + getRewardActivityPage(this.queryParams).then(response => { | |
| 187 | + this.list = response.data.list; | |
| 188 | + this.total = response.data.total; | |
| 189 | + this.loading = false; | |
| 190 | + }); | |
| 191 | + }, | |
| 192 | + /** 取消按钮 */ | |
| 193 | + cancel() { | |
| 194 | + this.open = false; | |
| 195 | + this.reset(); | |
| 196 | + }, | |
| 197 | + /** 表单重置 */ | |
| 198 | + reset() { | |
| 199 | + this.form = { | |
| 200 | + id: undefined, | |
| 201 | + name: undefined, | |
| 202 | + startAndEndTime: undefined, | |
| 203 | + startTime: undefined, | |
| 204 | + endTime: undefined, | |
| 205 | + conditionType: PromotionConditionTypeEnum.PRICE.type, | |
| 206 | + remark: undefined, | |
| 207 | + productScope: PromotionProductScopeEnum.ALL.scope, | |
| 208 | + productSpuIds: undefined, | |
| 209 | + rules: undefined, | |
| 210 | + }; | |
| 211 | + this.resetForm("form"); | |
| 212 | + }, | |
| 213 | + /** 搜索按钮操作 */ | |
| 214 | + handleQuery() { | |
| 215 | + this.queryParams.pageNo = 1; | |
| 216 | + this.getList(); | |
| 217 | + }, | |
| 218 | + /** 重置按钮操作 */ | |
| 219 | + resetQuery() { | |
| 220 | + this.resetForm("queryForm"); | |
| 221 | + this.handleQuery(); | |
| 222 | + }, | |
| 223 | + /** 新增按钮操作 */ | |
| 224 | + handleAdd() { | |
| 225 | + this.reset(); | |
| 226 | + this.open = true; | |
| 227 | + this.title = "添加满减送活动"; | |
| 228 | + }, | |
| 229 | + /** 修改按钮操作 */ | |
| 230 | + handleUpdate(row) { | |
| 231 | + this.reset(); | |
| 232 | + const id = row.id; | |
| 233 | + getRewardActivity(id).then(response => { | |
| 234 | + this.form = response.data; | |
| 235 | + this.form.startAndEndTime = [response.data.startTime, response.data.endTime]; | |
| 236 | + this.open = true; | |
| 237 | + this.title = "修改满减送活动"; | |
| 238 | + }); | |
| 239 | + }, | |
| 240 | + /** 提交按钮 */ | |
| 241 | + submitForm() { | |
| 242 | + this.$refs["form"].validate(valid => { | |
| 243 | + if (!valid) { | |
| 244 | + return; | |
| 245 | + } | |
| 246 | + this.form.startTime = this.form.startAndEndTime[0]; | |
| 247 | + this.form.endTime = this.form.startAndEndTime[1]; | |
| 248 | + // TODO 芋艿:临时实现 | |
| 249 | + this.form.rules = [ | |
| 250 | + { | |
| 251 | + limit: 1, | |
| 252 | + discountPrice: 10, | |
| 253 | + freeDelivery: true, | |
| 254 | + point: 10, | |
| 255 | + couponIds: [10, 20], | |
| 256 | + couponCounts: [1, 2] | |
| 257 | + }, { | |
| 258 | + limit: 2, | |
| 259 | + discountPrice: 20, | |
| 260 | + freeDelivery: false, | |
| 261 | + point: 20, | |
| 262 | + couponIds: [30, 40], | |
| 263 | + couponCounts: [3, 4] | |
| 264 | + } | |
| 265 | + ]; | |
| 266 | + // 修改的提交 | |
| 267 | + if (this.form.id != null) { | |
| 268 | + updateRewardActivity(this.form).then(response => { | |
| 269 | + this.$modal.msgSuccess("修改成功"); | |
| 270 | + this.open = false; | |
| 271 | + this.getList(); | |
| 272 | + }); | |
| 273 | + return; | |
| 274 | + } | |
| 275 | + // 添加的提交 | |
| 276 | + createRewardActivity(this.form).then(response => { | |
| 277 | + this.$modal.msgSuccess("新增成功"); | |
| 278 | + this.open = false; | |
| 279 | + this.getList(); | |
| 280 | + }); | |
| 281 | + }); | |
| 282 | + }, | |
| 283 | + /** 删除按钮操作 */ | |
| 284 | + handleDelete(row) { | |
| 285 | + const id = row.id; | |
| 286 | + this.$modal.confirm('是否确认删除满减送活动编号为"' + id + '"的数据项?').then(function() { | |
| 287 | + return deleteRewardActivity(id); | |
| 288 | + }).then(() => { | |
| 289 | + this.getList(); | |
| 290 | + this.$modal.msgSuccess("删除成功"); | |
| 291 | + }).catch(() => {}); | |
| 292 | + }, | |
| 293 | + /** 关闭按钮操作 */ | |
| 294 | + handleClose(row) { | |
| 295 | + const id = row.id; | |
| 296 | + this.$modal.confirm('是否确认关闭满减送活动编号为"' + id + '"的数据项?').then(function() { | |
| 297 | + return closeRewardActivity(id); | |
| 298 | + }).then(() => { | |
| 299 | + this.getList(); | |
| 300 | + this.$modal.msgSuccess("关闭成功"); | |
| 301 | + }).catch(() => {}); | |
| 302 | + } | |
| 303 | + } | |
| 304 | +}; | |
| 305 | +</script> | ... | ... |
yudao-ui-admin/src/views/system/role/index.vue
| ... | ... | @@ -50,7 +50,7 @@ |
| 50 | 50 | <el-table-column label="显示顺序" prop="sort" width="100" /> |
| 51 | 51 | <el-table-column label="状态" align="center" width="100"> |
| 52 | 52 | <template slot-scope="scope"> |
| 53 | - <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch> | |
| 53 | + <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1" @change="handleStatusChange(scope.row)"/> | |
| 54 | 54 | </template> |
| 55 | 55 | </el-table-column> |
| 56 | 56 | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> |
| ... | ... | @@ -167,7 +167,6 @@ |
| 167 | 167 | import { |
| 168 | 168 | addRole, |
| 169 | 169 | changeRoleStatus, |
| 170 | - dataScope, | |
| 171 | 170 | delRole, |
| 172 | 171 | exportRole, |
| 173 | 172 | getRole, | ... | ... |