Commit 0200fa6e5346a27297caaa203fa716448b80cccf

Authored by xiaqing
2 parents c7ced55a 5ffea937

Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product

# Conflicts:
#	yudao-module-member/yudao-module-member-biz/pom.xml
Showing 27 changed files with 482 additions and 39 deletions
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java
... ... @@ -85,7 +85,7 @@ public class AppProductCommentController {
85 85 }
86 86  
87 87 // TODO 芋艿:需要搞下
88   - @GetMapping("/getCommentStatistics")
  88 + @GetMapping("/statistics")
89 89 @Operation(summary = "获得商品的评价统计")
90 90 public CommonResult<AppCommentStatisticsRespVO> getCommentStatistics(@Valid @RequestParam("spuId") Long spuId) {
91 91 return success(productCommentService.getCommentStatistics(spuId, Boolean.TRUE));
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentStatisticsRespVO.java
... ... @@ -9,9 +9,6 @@ import lombok.ToString;
9 9 @ToString(callSuper = true)
10 10 public class AppCommentStatisticsRespVO {
11 11  
12   - @Schema(description = "所有评论数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15721")
13   - private Long allCount;
14   -
15 12 @Schema(description = "好评数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15721")
16 13 private Long goodCount;
17 14  
... ... @@ -21,4 +18,7 @@ public class AppCommentStatisticsRespVO {
21 18 @Schema(description = "差评数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15721")
22 19 private Long negativeCount;
23 20  
  21 + @Schema(description = "总平均分", requiredMode = Schema.RequiredMode.REQUIRED, example = "3.55")
  22 + private Double scores;
  23 +
24 24 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java
... ... @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
  7 +import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteBatchReqVO;
7 8 import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO;
8 9 import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO;
9 10 import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO;
... ... @@ -43,15 +44,24 @@ public class AppFavoriteController {
43 44 }
44 45  
45 46 @DeleteMapping(value = "/delete")
46   - @Operation(summary = "取消商品收藏")
  47 + @Operation(summary = "取消单个商品收藏")
47 48 @PreAuthenticated
48 49 public CommonResult<Boolean> deleteFavorite(@RequestBody @Valid AppFavoriteReqVO reqVO) {
49 50 productFavoriteService.deleteFavorite(getLoginUserId(), reqVO.getSpuId());
50 51 return success(Boolean.TRUE);
51 52 }
52 53  
  54 + @DeleteMapping(value = "/delete-list")
  55 + @Operation(summary = "取消多个商品收藏")
  56 + @PreAuthenticated
  57 + public CommonResult<Boolean> deleteFavoriteList(@RequestBody @Valid AppFavoriteBatchReqVO reqVO) {
  58 + // todo @jason:待实现
  59 +// productFavoriteService.deleteFavorite(getLoginUserId(), reqVO.getSpuId());
  60 + return success(Boolean.TRUE);
  61 + }
  62 +
53 63 @GetMapping(value = "/page")
54   - @Operation(summary = "分页获取商品收藏列表")
  64 + @Operation(summary = "获得商品收藏分页")
55 65 @PreAuthenticated
56 66 public CommonResult<PageResult<AppFavoriteRespVO>> getFavoritePage(AppFavoritePageReqVO reqVO) {
57 67 PageResult<ProductFavoriteDO> favoritePage = productFavoriteService.getFavoritePage(getLoginUserId(), reqVO);
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteBatchReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.app.favorite.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotEmpty;
  7 +import java.util.List;
  8 +
  9 +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
  10 +
  11 +@Schema(description = "用户 APP - 商品收藏的批量 Request VO") // 用于收藏、取消收藏、获取收藏
  12 +@Data
  13 +public class AppFavoriteBatchReqVO {
  14 +
  15 + @Schema(description = "商品 SPU 编号数组", requiredMode = REQUIRED, example = "29502")
  16 + @NotEmpty(message = "商品 SPU 编号数组不能为空")
  17 + private List<Long> spuIds;
  18 +
  19 +}
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java
... ... @@ -7,7 +7,7 @@ import javax.validation.constraints.NotNull;
7 7  
8 8 import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
9 9  
10   -@Schema(description = "用户 APP - 商品收藏 Request VO") // 用于收藏、取消收藏、获取收藏
  10 +@Schema(description = "用户 APP - 商品收藏的单个 Request VO") // 用于收藏、取消收藏、获取收藏
11 11 @Data
12 12 public class AppFavoriteReqVO {
13 13  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java
... ... @@ -33,11 +33,10 @@ public interface ProductCommentConvert {
33 33 ProductCommentRespVO convert(ProductCommentDO bean);
34 34  
35 35 // TODO @puhui999:这里貌似字段对上,就不用 mapping 了;可以测试下看看哈
36   - @Mapping(target = "allCount", source = "allCount")
37 36 @Mapping(target = "goodCount", source = "goodCount")
38 37 @Mapping(target = "mediocreCount", source = "mediocreCount")
39 38 @Mapping(target = "negativeCount", source = "negativeCount")
40   - AppCommentStatisticsRespVO convert(Long allCount, Long goodCount, Long mediocreCount, Long negativeCount);
  39 + AppCommentStatisticsRespVO convert(Long goodCount, Long mediocreCount, Long negativeCount);
41 40  
42 41 List<ProductCommentRespVO> convertList(List<ProductCommentDO> list);
43 42  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java
... ... @@ -135,15 +135,13 @@ public class ProductCommentServiceImpl implements ProductCommentService {
135 135 @Override
136 136 public AppCommentStatisticsRespVO getCommentStatistics(Long spuId, Boolean visible) {
137 137 return ProductCommentConvert.INSTANCE.convert(
138   - // 查询商品 id = spuId 的所有评论数量
139   - productCommentMapper.selectCountBySpuId(spuId, visible, null),
140 138 // 查询商品 id = spuId 的所有好评数量
141 139 productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.GOOD_COMMENT),
142 140 // 查询商品 id = spuId 的所有中评数量
143 141 productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT),
144 142 // 查询商品 id = spuId 的所有差评数量
145 143 productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT)
146   - );
  144 + ).setScores(3.0); // TODO @puhui999:这里要实现下;;
147 145 }
148 146  
149 147 @Override
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleCategoryController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.app.article;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.promotion.controller.app.article.vo.category.AppArticleCategoryRespVO;
  5 +import io.swagger.v3.oas.annotations.Operation;
  6 +import io.swagger.v3.oas.annotations.tags.Tag;
  7 +import org.springframework.validation.annotation.Validated;
  8 +import org.springframework.web.bind.annotation.RequestMapping;
  9 +import org.springframework.web.bind.annotation.RestController;
  10 +
  11 +import java.util.ArrayList;
  12 +import java.util.List;
  13 +import java.util.Random;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  16 +
  17 +@Tag(name = "用户 APP - 文章分类")
  18 +@RestController
  19 +@RequestMapping("/promotion/article-category")
  20 +@Validated
  21 +public class AppArticleCategoryController {
  22 +
  23 + @RequestMapping("/list")
  24 + @Operation(summary = "获得文章分类列表")
  25 + // TODO @芋艿:swagger 注解
  26 + public CommonResult<List<AppArticleCategoryRespVO>> getArticleCategoryList() {
  27 + List<AppArticleCategoryRespVO> appArticleRespVOList = new ArrayList<>();
  28 + Random random = new Random();
  29 + for (int i = 0; i < 10; i++) {
  30 + AppArticleCategoryRespVO appArticleRespVO = new AppArticleCategoryRespVO();
  31 + appArticleRespVO.setId((long) (i + 1));
  32 + appArticleRespVO.setName("分类 - " + i);
  33 + appArticleRespVO.setPicUrl("https://www.iocoder.cn/" + (i + 1) + ".png");
  34 + appArticleRespVOList.add(appArticleRespVO);
  35 + }
  36 + return success(appArticleRespVOList);
  37 + }
  38 +
  39 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.app.article;
  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.app.article.vo.article.AppArticlePageReqVO;
  6 +import cn.iocoder.yudao.module.promotion.controller.app.article.vo.article.AppArticleRespVO;
  7 +import io.swagger.v3.oas.annotations.tags.Tag;
  8 +import org.springframework.validation.annotation.Validated;
  9 +import org.springframework.web.bind.annotation.RequestMapping;
  10 +import org.springframework.web.bind.annotation.RequestParam;
  11 +import org.springframework.web.bind.annotation.RestController;
  12 +
  13 +import java.time.LocalDateTime;
  14 +import java.util.ArrayList;
  15 +import java.util.List;
  16 +import java.util.Random;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  19 +
  20 +@Tag(name = "用户 APP - 文章")
  21 +@RestController
  22 +@RequestMapping("/promotion/article")
  23 +@Validated
  24 +public class AppArticleController {
  25 +
  26 + @RequestMapping("/list")
  27 + // TODO @芋艿:swagger 注解
  28 + public CommonResult<List<AppArticleRespVO>> getArticleList(@RequestParam(value = "recommendHot", required = false) Boolean recommendHot,
  29 + @RequestParam(value = "recommendBanner", required = false) Boolean recommendBanner) {
  30 + List<AppArticleRespVO> appArticleRespVOList = new ArrayList<>();
  31 + Random random = new Random();
  32 + for (int i = 0; i < 10; i++) {
  33 + AppArticleRespVO appArticleRespVO = new AppArticleRespVO();
  34 + appArticleRespVO.setId((long) (i + 1));
  35 + appArticleRespVO.setTitle("芋道源码 - " + i + "模块");
  36 + appArticleRespVO.setAuthor("芋道源码");
  37 + appArticleRespVO.setCategoryId((long) random.nextInt(10000));
  38 + appArticleRespVO.setPicUrl("https://www.iocoder.cn/" + (i + 1) + ".png");
  39 + appArticleRespVO.setIntroduction("我是简介");
  40 + appArticleRespVO.setDescription("我是详细");
  41 + appArticleRespVO.setCreateTime(LocalDateTime.now());
  42 + appArticleRespVO.setBrowseCount(random.nextInt(10000));
  43 + appArticleRespVO.setSpuId((long) random.nextInt(10000));
  44 + appArticleRespVOList.add(appArticleRespVO);
  45 + }
  46 + return success(appArticleRespVOList);
  47 + }
  48 +
  49 + @RequestMapping("/page")
  50 + // TODO @芋艿:swagger 注解
  51 + public CommonResult<PageResult<AppArticleRespVO>> getArticlePage(AppArticlePageReqVO pageReqVO) {
  52 + List<AppArticleRespVO> appArticleRespVOList = new ArrayList<>();
  53 + Random random = new Random();
  54 + for (int i = 0; i < 10; i++) {
  55 + AppArticleRespVO appArticleRespVO = new AppArticleRespVO();
  56 + appArticleRespVO.setId((long) (i + 1));
  57 + appArticleRespVO.setTitle("芋道源码 - " + i + "模块");
  58 + appArticleRespVO.setAuthor("芋道源码");
  59 + appArticleRespVO.setCategoryId((long) random.nextInt(10000));
  60 + appArticleRespVO.setPicUrl("https://www.iocoder.cn/" + (i + 1) + ".png");
  61 + appArticleRespVO.setIntroduction("我是简介");
  62 + appArticleRespVO.setDescription("我是详细");
  63 + appArticleRespVO.setCreateTime(LocalDateTime.now());
  64 + appArticleRespVO.setBrowseCount(random.nextInt(10000));
  65 + appArticleRespVO.setSpuId((long) random.nextInt(10000));
  66 + appArticleRespVOList.add(appArticleRespVO);
  67 + }
  68 + return success(new PageResult<>(appArticleRespVOList, 10L));
  69 + }
  70 +
  71 + @RequestMapping("/get")
  72 + // TODO @芋艿:swagger 注解
  73 + public CommonResult<AppArticleRespVO> getArticlePage(@RequestParam("id") Long id) {
  74 + Random random = new Random();
  75 + AppArticleRespVO appArticleRespVO = new AppArticleRespVO();
  76 + appArticleRespVO.setId((long) (1));
  77 + appArticleRespVO.setTitle("芋道源码 - " + 0 + "模块");
  78 + appArticleRespVO.setAuthor("芋道源码");
  79 + appArticleRespVO.setCategoryId((long) random.nextInt(10000));
  80 + appArticleRespVO.setPicUrl("https://www.iocoder.cn/" + (0 + 1) + ".png");
  81 + appArticleRespVO.setIntroduction("我是简介");
  82 + appArticleRespVO.setDescription("我是详细");
  83 + appArticleRespVO.setCreateTime(LocalDateTime.now());
  84 + appArticleRespVO.setBrowseCount(random.nextInt(10000));
  85 + appArticleRespVO.setSpuId((long) random.nextInt(10000));
  86 + appArticleRespVO.setSpuId(633L);
  87 + return success(appArticleRespVO);
  88 + }
  89 +
  90 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/vo/article/AppArticlePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.app.article.vo.article;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +
  7 +@Schema(description = "应用 App - 文章的分页 Request VO")
  8 +@Data
  9 +public class AppArticlePageReqVO extends PageParam {
  10 +
  11 + @Schema(description = "分类编号", example = "2048")
  12 + private Long categoryId;
  13 +
  14 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/vo/article/AppArticleRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.app.article.vo.article;
  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 AppArticleRespVO {
  11 +
  12 + @Schema(description = "文章编号", required = true, example = "1")
  13 + private Long id;
  14 +
  15 + @Schema(description = "文章标题", required = true, example = "芋道源码 - 促销模块")
  16 + private String title;
  17 +
  18 + @Schema(description = "文章作者", required = true, example = "芋道源码")
  19 + private String author;
  20 +
  21 + @Schema(description = "分类编号", required = true, example = "2048")
  22 + private Long categoryId;
  23 +
  24 + @Schema(description = "图文封面", required = true, example = "https://www.iocoder.cn/1.png")
  25 + private String picUrl;
  26 +
  27 + @Schema(description = "文章简介", required = true, example = "我是简介")
  28 + private String introduction;
  29 +
  30 + @Schema(description = "文章内容", required = true, example = "我是详细")
  31 + private String description;
  32 +
  33 + @Schema(description = "发布时间", required = true)
  34 + private LocalDateTime createTime;
  35 +
  36 + @Schema(description = "浏览量", required = true, example = "1024")
  37 + private Integer browseCount;
  38 +
  39 + @Schema(description = "关联的商品 SPU 编号", example = "1024")
  40 + private Long spuId;
  41 +
  42 +// TODO 芋艿:下面 2 个字段,后端要存储,前端不用返回;
  43 +// @Schema(description = "是否热卖推荐", required = true, example = "true")
  44 +// private Boolean recommendHot;
  45 +//
  46 +// @Schema(description = "是否 Banner 推荐", required = true, example = "true")
  47 +// private Boolean recommendBanner;
  48 +
  49 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/vo/category/AppArticleCategoryRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.app.article.vo.category;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "应用 App - 文章分类 Response VO")
  7 +@Data
  8 +public class AppArticleCategoryRespVO {
  9 +
  10 + @Schema(description = "分类编号", required = true, example = "1")
  11 + private Long id;
  12 +
  13 + @Schema(description = "分类名称", required = true, example = "技术")
  14 + private String name;
  15 +
  16 + @Schema(description = "分类图标", required = true, example = "https://www.iocoder.cn/1.png")
  17 + private String picUrl;
  18 +
  19 + // TODO 芋艿:下面 2 个字段,后端要存储,前端不用返回;
  20 +// @Schema(description = "状态", required = true, example = "1")
  21 +// private Integer status;
  22 +//
  23 +// @Schema(description = "排序", required = true, example = "1024")
  24 +// private Integer sort;
  25 +
  26 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponController.java
1 1 package cn.iocoder.yudao.module.promotion.controller.app.coupon;
2 2  
3 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.app.coupon.vo.coupon.AppCouponPageReqVO;
  6 +import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon.AppCouponRespVO;
4 7 import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.template.AppCouponTemplatePageReqVO;
5 8 import io.swagger.v3.oas.annotations.Operation;
6 9 import io.swagger.v3.oas.annotations.tags.Tag;
7 10 import org.springframework.validation.annotation.Validated;
8   -import org.springframework.web.bind.annotation.PostMapping;
9   -import org.springframework.web.bind.annotation.RequestBody;
10   -import org.springframework.web.bind.annotation.RequestMapping;
11   -import org.springframework.web.bind.annotation.RestController;
  11 +import org.springframework.web.bind.annotation.*;
  12 +
  13 +import java.time.LocalDateTime;
  14 +import java.util.ArrayList;
  15 +import java.util.List;
  16 +import java.util.Random;
12 17  
13 18 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
14 19  
... ... @@ -25,4 +30,33 @@ public class AppCouponController {
25 30 return success(1L);
26 31 }
27 32  
  33 + // TODO 芋艿:待实现
  34 + @GetMapping("/page")
  35 + @Operation(summary = "优惠劵列表", description = "我的优惠劵")
  36 + public CommonResult<PageResult<AppCouponRespVO>> takeCoupon(AppCouponPageReqVO pageReqVO) {
  37 + List<AppCouponRespVO> list = new ArrayList<>();
  38 + Random random = new Random();
  39 + for (int i = 0; i < 10; i++) {
  40 + AppCouponRespVO vo = new AppCouponRespVO();
  41 + vo.setId(i + 1L);
  42 + vo.setName("优惠劵" + (i + 1));
  43 + vo.setStatus(pageReqVO.getStatus());
  44 + vo.setUsePrice(random.nextInt(100) * 100);
  45 + vo.setValidStartTime(LocalDateTime.now().plusDays(random.nextInt(10)));
  46 + vo.setValidEndTime(LocalDateTime.now().plusDays(random.nextInt(20) + 10));
  47 + vo.setDiscountType(random.nextInt(2) + 1);
  48 + if (vo.getDiscountType() == 1) {
  49 + vo.setDiscountPercent(null);
  50 + vo.setDiscountPrice(random.nextInt(50) * 100);
  51 + vo.setDiscountLimitPrice(null);
  52 + } else {
  53 + vo.setDiscountPercent(random.nextInt(90) + 10);
  54 + vo.setDiscountPrice(null);
  55 + vo.setDiscountLimitPrice(random.nextInt(200) * 100);
  56 + }
  57 + list.add(vo);
  58 + }
  59 + return success(new PageResult<>(list, 20L));
  60 + }
  61 +
28 62 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java
... ... @@ -34,14 +34,15 @@ public class AppCouponTemplateController {
34 34  
35 35 // TODO 芋艿:待实现
36 36 @GetMapping("/list")
37   - @Operation(summary = "获得优惠劵模版列表") // 目前主要给商品详情使用
  37 + @Operation(summary = "获得优惠劵模版列表")
38 38 @Parameters({
39   - @Parameter(name = "spuId", description = "商品 SPU 编号", required = true),
  39 + @Parameter(name = "spuId", description = "商品 SPU 编号"), // 目前主要给商品详情使用
40 40 @Parameter(name = "useType", description = "使用类型"),
41 41 @Parameter(name = "count", description = "数量", required = true)
42 42 })
43   - public CommonResult<List<AppCouponTemplateRespVO>> getCouponTemplateList(@RequestParam("spuId") Long spuId,
44   - @RequestParam(value = "useType", required = false) Integer useType) {
  43 + public CommonResult<List<AppCouponTemplateRespVO>> getCouponTemplateList(@RequestParam(value = "spuId", required = false) Long spuId,
  44 + @RequestParam(value = "useType", required = false) Integer useType,
  45 + @RequestParam(value = "count", required = false, defaultValue = "10") Integer count) {
45 46 List<AppCouponTemplateRespVO> list = new ArrayList<>();
46 47 Random random = new Random();
47 48 for (int i = 0; i < 10; i++) {
... ... @@ -74,11 +75,40 @@ public class AppCouponTemplateController {
74 75 return success(list);
75 76 }
76 77  
77   - // TODO 芋艿:待实现
  78 + // TODO 芋艿:待实现;和 getCouponTemplateList 类似
78 79 @GetMapping("/page")
79 80 @Operation(summary = "获得优惠劵模版分页")
80 81 public CommonResult<PageResult<AppCouponTemplateRespVO>> getCouponTemplatePage(AppCouponTemplatePageReqVO pageReqVO) {
81   - return null;
  82 + List<AppCouponTemplateRespVO> list = new ArrayList<>();
  83 + Random random = new Random();
  84 + for (int i = 0; i < 10; i++) {
  85 + AppCouponTemplateRespVO vo = new AppCouponTemplateRespVO();
  86 + vo.setId(i + 1L);
  87 + vo.setName("优惠劵" + (i + 1));
  88 + vo.setTakeLimitCount(random.nextInt(10) + 1);
  89 + vo.setUsePrice(random.nextInt(100) * 100);
  90 + vo.setValidityType(random.nextInt(2) + 1);
  91 + if (vo.getValidityType() == 1) {
  92 + vo.setValidStartTime(LocalDateTime.now().plusDays(random.nextInt(10)));
  93 + vo.setValidEndTime(LocalDateTime.now().plusDays(random.nextInt(20) + 10));
  94 + } else {
  95 + vo.setFixedStartTerm(random.nextInt(10));
  96 + vo.setFixedEndTerm(random.nextInt(10) + vo.getFixedStartTerm() + 1);
  97 + }
  98 + vo.setDiscountType(random.nextInt(2) + 1);
  99 + if (vo.getDiscountType() == 1) {
  100 + vo.setDiscountPercent(null);
  101 + vo.setDiscountPrice(random.nextInt(50) * 100);
  102 + vo.setDiscountLimitPrice(null);
  103 + } else {
  104 + vo.setDiscountPercent(random.nextInt(90) + 10);
  105 + vo.setDiscountPrice(null);
  106 + vo.setDiscountLimitPrice(random.nextInt(200) * 100);
  107 + }
  108 + vo.setTakeStatus(random.nextBoolean());
  109 + list.add(vo);
  110 + }
  111 + return success(new PageResult<>(list, 20L));
82 112 }
83 113  
84 114 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +@Schema(description = "用户 App - 优惠劵分页 Request VO")
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +@ToString(callSuper = true)
  13 +public class AppCouponPageReqVO extends PageParam {
  14 +
  15 + @Schema(description = "优惠劵状态", example = "1")
  16 + private Integer status;
  17 +
  18 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponRespVO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.Min;
  7 +import java.time.LocalDateTime;
  8 +
  9 +@Schema(description = "用户 App - 优惠劵 Response VO")
  10 +@Data
  11 +public class AppCouponRespVO {
  12 +
  13 + @Schema(description = "优惠劵编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  14 + private Long id;
  15 +
  16 + @Schema(description = "优惠劵名", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节送送送")
  17 + private String name;
  18 +
  19 + @Schema(description = "优惠劵状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") // 参见 CouponStatusEnum 枚举
  20 + private Integer status;
  21 +
  22 + @Schema(description = "是否设置满多少金额可用", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
  23 + // 单位:分;0 - 不限制
  24 + private Integer usePrice;
  25 +
  26 + @Schema(description = "固定日期 - 生效开始时间")
  27 + private LocalDateTime validStartTime;
  28 +
  29 + @Schema(description = "固定日期 - 生效结束时间")
  30 + private LocalDateTime validEndTime;
  31 +
  32 + @Schema(description = "优惠类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  33 + private Integer discountType;
  34 +
  35 + @Schema(description = "折扣百分比", example = "80") // 例如说,80% 为 80
  36 + private Integer discountPercent;
  37 +
  38 + @Schema(description = "优惠金额", example = "10")
  39 + @Min(value = 0, message = "优惠金额需要大于等于 0")
  40 + private Integer discountPrice;
  41 +
  42 + @Schema(description = "折扣上限", example = "100") // 单位:分,仅在 discountType 为 PERCENT 使用
  43 + private Integer discountLimitPrice;
  44 +
  45 +}
... ...
yudao-module-member/yudao-module-member-biz/pom.xml
... ... @@ -89,6 +89,11 @@
89 89 <artifactId>yudao-spring-boot-starter-excel</artifactId>
90 90 </dependency>
91 91  
  92 + <dependency>
  93 + <groupId>cn.iocoder.boot</groupId>
  94 + <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
  95 + </dependency>
  96 +
92 97 </dependencies>
93 98  
94 99 </project>
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java
... ... @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.member.controller.app.address.vo;
2 2 import io.swagger.v3.oas.annotations.media.Schema;
3 3 import lombok.Data;
4 4  
5   -import javax.validation.constraints.NotEmpty;
6 5 import javax.validation.constraints.NotNull;
7 6  
8 7 // TODO 芋艿:example 缺失
... ... @@ -31,6 +30,6 @@ public class AppAddressBaseVO {
31 30  
32 31 @Schema(description = "是否默认地址", requiredMode = Schema.RequiredMode.REQUIRED)
33 32 @NotNull(message = "是否默认地址不能为空")
34   - private Boolean defaulted;
  33 + private Boolean defaultStatus;
35 34  
36 35 }
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressRespVO.java
1 1 package cn.iocoder.yudao.module.member.controller.app.address.vo;
  2 +
2 3 import io.swagger.v3.oas.annotations.media.Schema;
3   -import lombok.*;
4   -import java.time.LocalDateTime;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
5 7  
6 8 @Schema(description = "用户 APP - 用户收件地址 Response VO")
7 9 @Data
... ... @@ -9,10 +11,10 @@ import java.time.LocalDateTime;
9 11 @ToString(callSuper = true)
10 12 public class AppAddressRespVO extends AppAddressBaseVO {
11 13  
12   - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED)
  14 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
13 15 private Long id;
14 16  
15   - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
16   - private LocalDateTime createTime;
  17 + @Schema(description = "地区名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "上海上海市普陀区")
  18 + private String areaName;
17 19  
18 20 }
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressUpdateReqVO.java
... ... @@ -9,7 +9,7 @@ import javax.validation.constraints.*;
9 9 @ToString(callSuper = true)
10 10 public class AppAddressUpdateReqVO extends AppAddressBaseVO {
11 11  
12   - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED)
  12 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
13 13 @NotNull(message = "编号不能为空")
14 14 private Long id;
15 15  
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/address/AddressConvert.java
1 1 package cn.iocoder.yudao.module.member.convert.address;
2 2  
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
  3 +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
4 4 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
5 5 import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO;
6 6 import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressRespVO;
7 7 import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO;
8 8 import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO;
9 9 import org.mapstruct.Mapper;
  10 +import org.mapstruct.Mapping;
  11 +import org.mapstruct.Named;
10 12 import org.mapstruct.factory.Mappers;
11 13  
12 14 import java.util.List;
... ... @@ -25,12 +27,16 @@ public interface AddressConvert {
25 27  
26 28 MemberAddressDO convert(AppAddressUpdateReqVO bean);
27 29  
  30 + @Mapping(source = "areaId", target = "areaName", qualifiedByName = "convertAreaIdToAreaName")
28 31 AppAddressRespVO convert(MemberAddressDO bean);
29 32  
30 33 List<AppAddressRespVO> convertList(List<MemberAddressDO> list);
31 34  
32   - PageResult<AppAddressRespVO> convertPage(PageResult<MemberAddressDO> page);
33   -
34 35 AddressRespDTO convert02(MemberAddressDO bean);
35 36  
  37 + @Named("convertAreaIdToAreaName")
  38 + default String convertAreaIdToAreaName(Integer areaId) {
  39 + return AreaUtils.format(areaId);
  40 + }
  41 +
36 42 }
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/address/MemberAddressDO.java
... ... @@ -49,6 +49,6 @@ public class MemberAddressDO extends BaseDO {
49 49 *
50 50 * true - 默认收件地址
51 51 */
52   - private Boolean defaulted;
  52 + private Boolean defaultStatus;
53 53  
54 54 }
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/AddressMapper.java
... ... @@ -16,7 +16,7 @@ public interface AddressMapper extends BaseMapperX&lt;MemberAddressDO&gt; {
16 16  
17 17 default List<MemberAddressDO> selectListByUserIdAndDefaulted(Long userId, Boolean defaulted) {
18 18 return selectList(new LambdaQueryWrapperX<MemberAddressDO>().eq(MemberAddressDO::getUserId, userId)
19   - .eqIfPresent(MemberAddressDO::getDefaulted, defaulted));
  19 + .eqIfPresent(MemberAddressDO::getDefaultStatus, defaulted));
20 20 }
21 21  
22 22 }
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImpl.java
... ... @@ -32,9 +32,9 @@ public class AddressServiceImpl implements AddressService {
32 32 @Transactional(rollbackFor = Exception.class)
33 33 public Long createAddress(Long userId, AppAddressCreateReqVO createReqVO) {
34 34 // 如果添加的是默认收件地址,则将原默认地址修改为非默认
35   - if (Boolean.TRUE.equals(createReqVO.getDefaulted())) {
  35 + if (Boolean.TRUE.equals(createReqVO.getDefaultStatus())) {
36 36 List<MemberAddressDO> addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true);
37   - addresses.forEach(address -> addressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaulted(false)));
  37 + addresses.forEach(address -> addressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaultStatus(false)));
38 38 }
39 39  
40 40 // 插入
... ... @@ -52,10 +52,10 @@ public class AddressServiceImpl implements AddressService {
52 52 validAddressExists(userId, updateReqVO.getId());
53 53  
54 54 // 如果修改的是默认收件地址,则将原默认地址修改为非默认
55   - if (Boolean.TRUE.equals(updateReqVO.getDefaulted())) {
  55 + if (Boolean.TRUE.equals(updateReqVO.getDefaultStatus())) {
56 56 List<MemberAddressDO> addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true);
57 57 addresses.stream().filter(u -> !u.getId().equals(updateReqVO.getId())) // 排除自己
58   - .forEach(address -> addressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaulted(false)));
  58 + .forEach(address -> addressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaultStatus(false)));
59 59 }
60 60  
61 61 // 更新
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/ip/AppAreaController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.app.ip;
  2 +
  3 +import cn.hutool.core.lang.Assert;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.ip.core.Area;
  6 +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
  7 +import cn.iocoder.yudao.module.system.controller.app.ip.vo.AppAreaNodeRespVO;
  8 +import cn.iocoder.yudao.module.system.convert.ip.AreaConvert;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.tags.Tag;
  11 +import org.springframework.validation.annotation.Validated;
  12 +import org.springframework.web.bind.annotation.GetMapping;
  13 +import org.springframework.web.bind.annotation.RequestMapping;
  14 +import org.springframework.web.bind.annotation.RestController;
  15 +
  16 +import java.util.List;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  19 +
  20 +@Tag(name = "用户 App - 地区")
  21 +@RestController
  22 +@RequestMapping("/system/area")
  23 +@Validated
  24 +public class AppAreaController {
  25 +
  26 + @GetMapping("/tree")
  27 + @Operation(summary = "获得地区树")
  28 + public CommonResult<List<AppAreaNodeRespVO>> getAreaTree() {
  29 + Area area = AreaUtils.getArea(Area.ID_CHINA);
  30 + Assert.notNull(area, "获取不到中国");
  31 + return success(AreaConvert.INSTANCE.convertList3(area.getChildren()));
  32 + }
  33 +
  34 +}
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/ip/vo/AppAreaNodeRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.app.ip.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.util.List;
  7 +
  8 +@Schema(description = "用户 App - 地区节点 Response VO")
  9 +@Data
  10 +public class AppAreaNodeRespVO {
  11 +
  12 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "110000")
  13 + private Integer id;
  14 +
  15 + @Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "北京")
  16 + private String name;
  17 +
  18 + /**
  19 + * 子节点
  20 + */
  21 + private List<AppAreaNodeRespVO> children;
  22 +
  23 +}
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java
... ... @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.ip.core.Area;
4 4 import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
5 5 import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO;
6 6 import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeSimpleRespVO;
  7 +import cn.iocoder.yudao.module.system.controller.app.ip.vo.AppAreaNodeRespVO;
7 8 import org.mapstruct.Mapper;
8 9 import org.mapstruct.Mapping;
9 10 import org.mapstruct.factory.Mappers;
... ... @@ -27,4 +28,6 @@ public interface AreaConvert {
27 28 return Objects.equals(AreaTypeEnum.DISTRICT.getType(), type);
28 29 }
29 30  
  31 + List<AppAreaNodeRespVO> convertList3(List<Area> list);
  32 +
30 33 }
... ...