Commit 4f5ac0edbbf925a2aaa865dcad3b357207488038

Authored by YunaiV
1 parent 9e894e04

mall + promotion:增加营销活动的 mock 接口

Showing 14 changed files with 186 additions and 68 deletions
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.framework.mybatis.core.query; @@ -2,7 +2,6 @@ package cn.iocoder.yudao.framework.mybatis.core.query;
2 2
3 import cn.hutool.core.util.ArrayUtil; 3 import cn.hutool.core.util.ArrayUtil;
4 import cn.hutool.core.util.ObjectUtil; 4 import cn.hutool.core.util.ObjectUtil;
5 -import cn.hutool.core.util.StrUtil;  
6 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
7 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 6 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
8 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; 7 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java
@@ -3,17 +3,17 @@ package cn.iocoder.yudao.module.product.controller.app.spu; @@ -3,17 +3,17 @@ package cn.iocoder.yudao.module.product.controller.app.spu;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; 5 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
6 -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; 6 +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageRespVO;
7 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; 7 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
8 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; 8 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
9 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; 9 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
10 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; 10 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
11 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; 11 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
12 -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;  
13 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; 12 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
14 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; 13 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
15 import io.swagger.v3.oas.annotations.Operation; 14 import io.swagger.v3.oas.annotations.Operation;
16 import io.swagger.v3.oas.annotations.Parameter; 15 import io.swagger.v3.oas.annotations.Parameter;
  16 +import io.swagger.v3.oas.annotations.Parameters;
17 import io.swagger.v3.oas.annotations.tags.Tag; 17 import io.swagger.v3.oas.annotations.tags.Tag;
18 import org.springframework.validation.annotation.Validated; 18 import org.springframework.validation.annotation.Validated;
19 import org.springframework.web.bind.annotation.GetMapping; 19 import org.springframework.web.bind.annotation.GetMapping;
@@ -40,12 +40,23 @@ public class AppProductSpuController { @@ -40,12 +40,23 @@ public class AppProductSpuController {
40 private ProductSpuService productSpuService; 40 private ProductSpuService productSpuService;
41 @Resource 41 @Resource
42 private ProductSkuService productSkuService; 42 private ProductSkuService productSkuService;
43 - @Resource  
44 - private ProductPropertyValueService productPropertyValueService; 43 +
  44 + @GetMapping("/list")
  45 + @Operation(summary = "获得商品 SPU 列表")
  46 + @Parameters({
  47 + @Parameter(name = "recommendType", description = "推荐类型", required = true), // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常量
  48 + @Parameter(name = "count", description = "数量", required = true)
  49 + })
  50 + public CommonResult<List<AppProductSpuPageRespVO>> getSpuList(
  51 + @RequestParam("recommendType") String recommendType,
  52 + @RequestParam(value = "count", defaultValue = "10") Integer count) {
  53 + List<ProductSpuDO> list = productSpuService.getSpuList(recommendType, count);
  54 + return success(ProductSpuConvert.INSTANCE.convertListForGetSpuList(list));
  55 + }
45 56
46 @GetMapping("/page") 57 @GetMapping("/page")
47 @Operation(summary = "获得商品 SPU 分页") 58 @Operation(summary = "获得商品 SPU 分页")
48 - public CommonResult<PageResult<AppProductSpuPageItemRespVO>> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) { 59 + public CommonResult<PageResult<AppProductSpuPageRespVO>> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) {
49 PageResult<ProductSpuDO> pageResult = productSpuService.getSpuPage(pageVO); 60 PageResult<ProductSpuDO> pageResult = productSpuService.getSpuPage(pageVO);
50 return success(ProductSpuConvert.INSTANCE.convertPageForGetSpuPage(pageResult)); 61 return success(ProductSpuConvert.INSTANCE.convertPageForGetSpuPage(pageResult));
51 } 62 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java
@@ -39,6 +39,11 @@ public class AppProductSpuDetailRespVO { @@ -39,6 +39,11 @@ public class AppProductSpuDetailRespVO {
39 @Schema(description = "单位名", required = true, example = "个") 39 @Schema(description = "单位名", required = true, example = "个")
40 private String unitName; 40 private String unitName;
41 41
  42 + // ========== 营销相关字段 =========
  43 +
  44 + @Schema(description = "活动排序数组", required = true, example = "1024")
  45 + private List<Integer> activityOrders;
  46 +
42 // ========== SKU 相关字段 ========= 47 // ========== SKU 相关字段 =========
43 48
44 @Schema(description = "规格类型", required = true, example = "true") 49 @Schema(description = "规格类型", required = true, example = "true")
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java
@@ -20,6 +20,7 @@ public class AppProductSpuPageReqVO extends PageParam { @@ -20,6 +20,7 @@ public class AppProductSpuPageReqVO extends PageParam {
20 public static final String SORT_FIELD_SALES_COUNT = "salesCount"; 20 public static final String SORT_FIELD_SALES_COUNT = "salesCount";
21 21
22 public static final String RECOMMEND_TYPE_HOT = "hot"; 22 public static final String RECOMMEND_TYPE_HOT = "hot";
  23 + public static final String RECOMMEND_TYPE_GOOD = "good";
23 24
24 @Schema(description = "分类编号", example = "1") 25 @Schema(description = "分类编号", example = "1")
25 private Long categoryId; 26 private Long categoryId;
@@ -33,7 +34,7 @@ public class AppProductSpuPageReqVO extends PageParam { @@ -33,7 +34,7 @@ public class AppProductSpuPageReqVO extends PageParam {
33 @Schema(description = "排序方式", example = "true") 34 @Schema(description = "排序方式", example = "true")
34 private Boolean sortAsc; 35 private Boolean sortAsc;
35 36
36 - @Schema(description = "推荐类型", example = "hot") // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常亮 37 + @Schema(description = "推荐类型", example = "hot") // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常量
37 private String recommendType; 38 private String recommendType;
38 39
39 @AssertTrue(message = "排序字段不合法") 40 @AssertTrue(message = "排序字段不合法")
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java renamed to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageRespVO.java
@@ -5,9 +5,9 @@ import lombok.Data; @@ -5,9 +5,9 @@ import lombok.Data;
5 5
6 import java.util.List; 6 import java.util.List;
7 7
8 -@Schema(description = "用户 App - 商品 SPU 分页项 Response VO") 8 +@Schema(description = "用户 App - 商品 SPU Response VO")
9 @Data 9 @Data
10 -public class AppProductSpuPageItemRespVO { 10 +public class AppProductSpuPageRespVO {
11 11
12 @Schema(description = "商品 SPU 编号", required = true, example = "1") 12 @Schema(description = "商品 SPU 编号", required = true, example = "1")
13 private Long id; 13 private Long id;
@@ -35,6 +35,11 @@ public class AppProductSpuPageItemRespVO { @@ -35,6 +35,11 @@ public class AppProductSpuPageItemRespVO {
35 @Schema(description = "库存", required = true, example = "666") 35 @Schema(description = "库存", required = true, example = "666")
36 private Integer stock; 36 private Integer stock;
37 37
  38 + // ========== 营销相关字段 =========
  39 +
  40 + @Schema(description = "活动排序数组", required = true, example = "1024")
  41 + private List<Integer> activityOrders;
  42 +
38 // ========== 统计相关字段 ========= 43 // ========== 统计相关字段 =========
39 44
40 @Schema(description = "商品销量", required = true, example = "1024") 45 @Schema(description = "商品销量", required = true, example = "1024")
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
1 package cn.iocoder.yudao.module.product.convert.spu; 1 package cn.iocoder.yudao.module.product.convert.spu;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; 5 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
7 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; 6 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
8 -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;  
9 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; 7 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
10 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; 8 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
11 -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; 9 +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageRespVO;
12 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; 10 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
13 import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; 11 import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
14 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; 12 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
@@ -80,14 +78,15 @@ public interface ProductSpuConvert { @@ -80,14 +78,15 @@ public interface ProductSpuConvert {
80 78
81 // ========== 用户 App 相关 ========== 79 // ========== 用户 App 相关 ==========
82 80
83 - default PageResult<AppProductSpuPageItemRespVO> convertPageForGetSpuPage(PageResult<ProductSpuDO> page) {  
84 - // 累加虚拟销量  
85 - page.getList().forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount()));  
86 - // 然后进行转换  
87 - return convertPageForGetSpuPage0(page);  
88 - } 81 + PageResult<AppProductSpuPageRespVO> convertPageForGetSpuPage(PageResult<ProductSpuDO> page);
89 82
90 - PageResult<AppProductSpuPageItemRespVO> convertPageForGetSpuPage0(PageResult<ProductSpuDO> page); 83 + default List<AppProductSpuPageRespVO> convertListForGetSpuList(List<ProductSpuDO> list) {
  84 + // 处理虚拟销量
  85 + list.forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount()));
  86 + return convertListForGetSpuList0(list);
  87 + }
  88 + @Named("convertListForGetSpuList0")
  89 + List<AppProductSpuPageRespVO> convertListForGetSpuList0(List<ProductSpuDO> list);
91 90
92 default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List<ProductSkuDO> skus) { 91 default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List<ProductSkuDO> skus) {
93 // 处理 SPU 92 // 处理 SPU
@@ -109,15 +108,9 @@ public interface ProductSpuConvert { @@ -109,15 +108,9 @@ public interface ProductSpuConvert {
109 List<AppProductSpuDetailRespVO.Sku> convertListForGetSpuDetail(List<ProductSkuDO> skus); 108 List<AppProductSpuDetailRespVO.Sku> convertListForGetSpuDetail(List<ProductSkuDO> skus);
110 109
111 default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List<ProductSkuDO> skus) { 110 default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List<ProductSkuDO> skus) {
112 - ProductSpuDetailRespVO productSpuDetailRespVO = convert03(spu);  
113 - // skus 为空直接返回  
114 - if (CollUtil.isEmpty(skus)) {  
115 - return productSpuDetailRespVO;  
116 - }  
117 - List<ProductSkuRespVO> skuVOs = ProductSkuConvert.INSTANCE.convertList(skus);  
118 - // fix: 因为现在已改为 sku 属性列表 属性 已包含 属性名字 属性值名字 所以不需要再额外处理,属性更新时更新 sku 中的属性相关冗余即可  
119 - productSpuDetailRespVO.setSkus(skuVOs);  
120 - return productSpuDetailRespVO; 111 + ProductSpuDetailRespVO detailRespVO = convert03(spu);
  112 + detailRespVO.setSkus(ProductSkuConvert.INSTANCE.convertList(skus));
  113 + return detailRespVO;
121 } 114 }
122 115
123 } 116 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
@@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil; @@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
7 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 7 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  8 +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
8 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuExportReqVO; 9 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuExportReqVO;
9 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; 10 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
10 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; 11 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
@@ -66,7 +67,10 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; { @@ -66,7 +67,10 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; {
66 // 推荐类型的过滤条件 67 // 推荐类型的过滤条件
67 if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_HOT)) { 68 if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_HOT)) {
68 query.eq(ProductSpuDO::getRecommendHot, true); 69 query.eq(ProductSpuDO::getRecommendHot, true);
  70 + } else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_GOOD)) {
  71 + query.eq(ProductSpuDO::getRecommendGood, true);
69 } 72 }
  73 +
70 // 排序逻辑 74 // 排序逻辑
71 if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) { 75 if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) {
72 query.last(String.format(" ORDER BY (sales_count + virtual_sales_count) %s, sort DESC, id DESC", 76 query.last(String.format(" ORDER BY (sales_count + virtual_sales_count) %s, sort DESC, id DESC",
@@ -80,6 +84,21 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; { @@ -80,6 +84,21 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; {
80 return selectPage(pageReqVO, query); 84 return selectPage(pageReqVO, query);
81 } 85 }
82 86
  87 + default List<ProductSpuDO> selectListByRecommendType(String recommendType, Integer count) {
  88 + QueryWrapperX<ProductSpuDO> query = new QueryWrapperX<>();
  89 + // 上架状态 且有库存
  90 + query.eq("status", ProductSpuStatusEnum.ENABLE.getStatus()).gt("stock", 0);
  91 + // 推荐类型的过滤条件
  92 + if (ObjUtil.equal(recommendType, AppProductSpuPageReqVO.RECOMMEND_TYPE_HOT)) {
  93 + query.eq("recommend_hot", true);
  94 + } else if (ObjUtil.equal(recommendType, AppProductSpuPageReqVO.RECOMMEND_TYPE_GOOD)) {
  95 + query.eq("recommend_good", true);
  96 + }
  97 + // 设置最大长度
  98 + query.limitN(count);
  99 + return selectList(query);
  100 + }
  101 +
83 /** 102 /**
84 * 更新商品 SPU 库存 103 * 更新商品 SPU 库存
85 * 104 *
@@ -111,33 +130,34 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; { @@ -111,33 +130,34 @@ public interface ProductSpuMapper extends BaseMapperX&lt;ProductSpuDO&gt; {
111 } 130 }
112 131
113 /** 132 /**
114 - * 验证选项卡类型构建条件 133 + * 添加后台 Tab 选项的查询条件
115 * 134 *
116 * @param tabType 标签类型 135 * @param tabType 标签类型
117 - * @param queryWrapper 查询条件 136 + * @param query 查询条件
118 */ 137 */
119 - static void appendTabQuery(Integer tabType, LambdaQueryWrapperX<ProductSpuDO> queryWrapper) { 138 + static void appendTabQuery(Integer tabType, LambdaQueryWrapperX<ProductSpuDO> query) {
120 // 出售中商品 139 // 出售中商品
121 if (ObjectUtil.equals(ProductSpuPageReqVO.FOR_SALE, tabType)) { 140 if (ObjectUtil.equals(ProductSpuPageReqVO.FOR_SALE, tabType)) {
122 - queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()); 141 + query.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus());
123 } 142 }
124 // 仓储中商品 143 // 仓储中商品
125 if (ObjectUtil.equals(ProductSpuPageReqVO.IN_WAREHOUSE, tabType)) { 144 if (ObjectUtil.equals(ProductSpuPageReqVO.IN_WAREHOUSE, tabType)) {
126 - queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus()); 145 + query.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus());
127 } 146 }
128 // 已售空商品 147 // 已售空商品
129 if (ObjectUtil.equals(ProductSpuPageReqVO.SOLD_OUT, tabType)) { 148 if (ObjectUtil.equals(ProductSpuPageReqVO.SOLD_OUT, tabType)) {
130 - queryWrapper.eqIfPresent(ProductSpuDO::getStock, 0); 149 + query.eqIfPresent(ProductSpuDO::getStock, 0);
131 } 150 }
132 // 警戒库存 151 // 警戒库存
133 if (ObjectUtil.equals(ProductSpuPageReqVO.ALERT_STOCK, tabType)) { 152 if (ObjectUtil.equals(ProductSpuPageReqVO.ALERT_STOCK, tabType)) {
134 - queryWrapper.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK) 153 + query.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK)
135 // 如果库存触发警戒库存且状态为回收站的话则不在警戒库存列表展示 154 // 如果库存触发警戒库存且状态为回收站的话则不在警戒库存列表展示
136 .notIn(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()); 155 .notIn(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus());
137 } 156 }
138 // 回收站 157 // 回收站
139 if (ObjectUtil.equals(ProductSpuPageReqVO.RECYCLE_BIN, tabType)) { 158 if (ObjectUtil.equals(ProductSpuPageReqVO.RECYCLE_BIN, tabType)) {
140 - queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()); 159 + query.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus());
141 } 160 }
142 } 161 }
  162 +
143 } 163 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
@@ -99,6 +99,15 @@ public interface ProductSpuService { @@ -99,6 +99,15 @@ public interface ProductSpuService {
99 PageResult<ProductSpuDO> getSpuPage(AppProductSpuPageReqVO pageReqVO); 99 PageResult<ProductSpuDO> getSpuPage(AppProductSpuPageReqVO pageReqVO);
100 100
101 /** 101 /**
  102 + * 获得商品 SPU 列表,提供给用户 App 使用
  103 + *
  104 + * @param recommendType 推荐类型
  105 + * @param count 数量
  106 + * @return 商品 SPU 列表
  107 + */
  108 + List<ProductSpuDO> getSpuList(String recommendType, Integer count);
  109 +
  110 + /**
102 * 更新商品 SPU 库存(增量) 111 * 更新商品 SPU 库存(增量)
103 * 112 *
104 * @param stockIncrCounts SPU 编号与库存变化(增量)的映射 113 * @param stockIncrCounts SPU 编号与库存变化(增量)的映射
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
@@ -202,6 +202,11 @@ public class ProductSpuServiceImpl implements ProductSpuService { @@ -202,6 +202,11 @@ public class ProductSpuServiceImpl implements ProductSpuService {
202 } 202 }
203 203
204 @Override 204 @Override
  205 + public List<ProductSpuDO> getSpuList(String recommendType, Integer count) {
  206 + return productSpuMapper.selectListByRecommendType(recommendType, count);
  207 + }
  208 +
  209 + @Override
205 @Transactional(rollbackFor = Exception.class) 210 @Transactional(rollbackFor = Exception.class)
206 public void updateSpuStock(Map<Long, Integer> stockIncrCounts) { 211 public void updateSpuStock(Map<Long, Integer> stockIncrCounts) {
207 stockIncrCounts.forEach((id, incCount) -> productSpuMapper.updateStock(id, incCount)); 212 stockIncrCounts.forEach((id, incCount) -> productSpuMapper.updateStock(id, incCount));
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java
@@ -15,11 +15,15 @@ import java.util.Arrays; @@ -15,11 +15,15 @@ import java.util.Arrays;
15 @AllArgsConstructor 15 @AllArgsConstructor
16 public enum PromotionTypeEnum implements IntArrayValuable { 16 public enum PromotionTypeEnum implements IntArrayValuable {
17 17
18 - DISCOUNT_ACTIVITY(1, "限时折扣"),  
19 - REWARD_ACTIVITY(2, "满减送"), 18 + SECKILL_ACTIVITY(1, "秒杀活动"),
  19 + BARGAIN_ACTIVITY(2, "拼团活动"),
  20 + COMBINATION_ACTIVITY(3, "砍价活动"),
20 21
21 - MEMBER(3, "会员折扣"), // TODO 芋艿:待实现 StrUtil.format("会员折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - memberPrice)  
22 - COUPON(4, "优惠劵") 22 + DISCOUNT_ACTIVITY(4, "限时折扣"),
  23 + REWARD_ACTIVITY(5, "满减送"),
  24 +
  25 + MEMBER(6, "会员折扣"),
  26 + COUPON(7, "优惠劵")
23 ; 27 ;
24 28
25 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionTypeEnum::getType).toArray(); 29 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionTypeEnum::getType).toArray();
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java deleted
1 -package cn.iocoder.yudao.module.promotion.controller.app;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
4 -import io.swagger.v3.oas.annotations.Operation;  
5 -import io.swagger.v3.oas.annotations.tags.Tag;  
6 -import org.springframework.validation.annotation.Validated;  
7 -import org.springframework.web.bind.annotation.GetMapping;  
8 -import org.springframework.web.bind.annotation.RequestMapping;  
9 -import org.springframework.web.bind.annotation.RestController;  
10 -  
11 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
12 -  
13 -@Tag(name = "用户 App - 营销")  
14 -@RestController  
15 -@RequestMapping("/market/test")  
16 -@Validated  
17 -public class AppMarketTestController {  
18 -  
19 - @GetMapping("/get")  
20 - @Operation(summary = "获取 market 信息")  
21 - public CommonResult<String> get() {  
22 - return success("true");  
23 - }  
24 -}  
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.app.activity;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.promotion.controller.app.activity.vo.AppActivityRespVO;
  5 +import io.swagger.v3.oas.annotations.Operation;
  6 +import io.swagger.v3.oas.annotations.Parameter;
  7 +import io.swagger.v3.oas.annotations.tags.Tag;
  8 +import org.springframework.validation.annotation.Validated;
  9 +import org.springframework.web.bind.annotation.GetMapping;
  10 +import org.springframework.web.bind.annotation.RequestMapping;
  11 +import org.springframework.web.bind.annotation.RequestParam;
  12 +import org.springframework.web.bind.annotation.RestController;
  13 +
  14 +import java.time.LocalDateTime;
  15 +import java.util.*;
  16 +
  17 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  18 +
  19 +@Tag(name = "用户 APP - 营销活动") // 用于提供跨多个活动的 HTTP 接口
  20 +@RestController
  21 +@RequestMapping("/promotion/activity")
  22 +@Validated
  23 +public class AppActivityController {
  24 +
  25 + @GetMapping("/list-by-spu-id")
  26 + @Operation(summary = "获得单个商品,近期参与的每个活动") // 每种活动,只返回一个
  27 + @Parameter(name = "spuId", description = "商品编号", required = true)
  28 + public CommonResult<List<AppActivityRespVO>> getActivityListBySpuId(@RequestParam("spuId") Long spuId) {
  29 + // TODO 芋艿,实现
  30 + List<AppActivityRespVO> randomList = new ArrayList<>();
  31 + Random random = new Random();
  32 + for (int i = 0; i < 3; i++) { // 生成5个随机对象
  33 + AppActivityRespVO vo = new AppActivityRespVO();
  34 + vo.setId(random.nextLong()); // 随机生成一个长整型 ID
  35 + vo.setType(i + 1); // 随机生成一个介于0到2之间的整数,对应枚举类型的三种类型之一
  36 + vo.setName(String.format("活动%d", random.nextInt(100))); // 随机生成一个类似于“活动XX”的活动名称,XX为0到99之间的随机整数
  37 + vo.setStartTime(LocalDateTime.now()); // 随机生成一个在过去的一年内的开始时间(以毫秒为单位)
  38 + vo.setEndTime(LocalDateTime.now()); // 随机生成一个在未来的一年内的结束时间(以毫秒为单位)
  39 + randomList.add(vo);
  40 + }
  41 + return success(randomList);
  42 + }
  43 +
  44 + @GetMapping("/list-by-spu-ids")
  45 + @Operation(summary = "获得多个商品,近期参与的每个活动") // 每种活动,只返回一个;key 为 SPU 编号
  46 + @Parameter(name = "spuIds", description = "商品编号数组", required = true)
  47 + public CommonResult<Map<Long, List<AppActivityRespVO>>> getActivityListBySpuIds(@RequestParam("spuIds") List<Long> spuIds) {
  48 + // TODO 芋艿,实现
  49 + List<AppActivityRespVO> randomList = new ArrayList<>();
  50 + Random random = new Random();
  51 + for (int i = 0; i < 5; i++) { // 生成5个随机对象
  52 + AppActivityRespVO vo = new AppActivityRespVO();
  53 + vo.setId(random.nextLong()); // 随机生成一个长整型 ID
  54 + vo.setType(random.nextInt(3)); // 随机生成一个介于0到2之间的整数,对应枚举类型的三种类型之一
  55 + vo.setName(String.format("活动%d", random.nextInt(100))); // 随机生成一个类似于“活动XX”的活动名称,XX为0到99之间的随机整数
  56 + vo.setStartTime(LocalDateTime.now()); // 随机生成一个在过去的一年内的开始时间(以毫秒为单位)
  57 + vo.setEndTime(LocalDateTime.now()); // 随机生成一个在未来的一年内的结束时间(以毫秒为单位)
  58 + randomList.add(vo);
  59 + }
  60 + Map<Long, List<AppActivityRespVO>> map = new HashMap<>();
  61 + map.put(109L, randomList);
  62 + return success(map);
  63 + }
  64 +
  65 +}
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/vo/AppActivityRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.app.activity.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +@Schema(description = "用户 App - 营销活动 Response VO")
  9 +@Data
  10 +public class AppActivityRespVO {
  11 +
  12 + @Schema(description = "活动编号", required = true, example = "1024")
  13 + private Long id;
  14 +
  15 + @Schema(description = "活动类型", required = true, example = "1") // 对应 PromotionTypeEnum 枚举
  16 + private Integer type;
  17 +
  18 + @Schema(description = "活动名称", required = true, example = "618 大促")
  19 + private String name;
  20 +
  21 + @Schema(description = "活动开始时间", required = true)
  22 + private LocalDateTime startTime;
  23 +
  24 + @Schema(description = "活动结束时间", required = true)
  25 + private LocalDateTime endTime;
  26 +
  27 +}
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java
@@ -17,10 +17,8 @@ public enum TradeOrderTypeEnum implements IntArrayValuable { @@ -17,10 +17,8 @@ public enum TradeOrderTypeEnum implements IntArrayValuable {
17 17
18 NORMAL(0, "普通订单"), 18 NORMAL(0, "普通订单"),
19 SECKILL(1, "秒杀订单"), 19 SECKILL(1, "秒杀订单"),
20 - // TODO 芋艿:如下三个字段,名字需要改下,等后面表设计完成后。  
21 - KANJIA(2, "砍价订单"),  
22 - PINTUAN(3, "拼团订单"),  
23 - YUSHOU(4, "预售订单"), 20 + BARGAIN(2, "砍价订单"),
  21 + COMBINATION(3, "拼团订单"),
24 ; 22 ;
25 23
26 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderTypeEnum::getType).toArray(); 24 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderTypeEnum::getType).toArray();