Commit f363c598d8100ff2db1114551e3af18902451e4a

Authored by puhui999
1 parent 1bb2010d

Banner:完善 review 提到的问题

yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/banner/BannerPositionEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.enums.banner;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import cn.iocoder.yudao.module.promotion.enums.bargain.BargainRecordStatusEnum;
  5 +import lombok.AllArgsConstructor;
  6 +import lombok.Getter;
  7 +
  8 +import java.util.Arrays;
  9 +
  10 +/**
  11 + * Banner Position 枚举
  12 + *
  13 + * @author HUIHUI
  14 + */
  15 +@AllArgsConstructor
  16 +@Getter
  17 +public enum BannerPositionEnum implements IntArrayValuable {
  18 +
  19 + HOME_POSITION(1, "首页"),
  20 + SECKILL_POSITION(2, "秒杀活动页"),
  21 + COMBINATION_POSITION(3, "砍价活动页"),
  22 + DISCOUNT_POSITION(4, "限时折扣页"),
  23 + REWARD_POSITION(5, "满减送页");
  24 +
  25 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BargainRecordStatusEnum::getStatus).toArray();
  26 + /**
  27 + * 值
  28 + */
  29 + private final Integer position;
  30 + /**
  31 + * 名字
  32 + */
  33 + private final String name;
  34 +
  35 + @Override
  36 + public int[] array() {
  37 + return ARRAYS;
  38 + }
  39 +
  40 +}
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java
@@ -27,6 +27,10 @@ public class BannerBaseVO { @@ -27,6 +27,10 @@ public class BannerBaseVO {
27 @NotNull(message = "图片地址不能为空") 27 @NotNull(message = "图片地址不能为空")
28 private String picUrl; 28 private String picUrl;
29 29
  30 + @Schema(description = "position", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + @NotNull(message = "position 不能为空")
  32 + private Integer position;
  33 +
30 @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED) 34 @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
31 @NotNull(message = "排序不能为空") 35 @NotNull(message = "排序不能为空")
32 private Integer sort; 36 private Integer sort;
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java
@@ -25,7 +25,6 @@ public class BannerPageReqVO extends PageParam { @@ -25,7 +25,6 @@ public class BannerPageReqVO extends PageParam {
25 @Schema(description = "标题") 25 @Schema(description = "标题")
26 private String title; 26 private String title;
27 27
28 -  
29 @Schema(description = "状态") 28 @Schema(description = "状态")
30 @InEnum(CommonStatusEnum.class) 29 @InEnum(CommonStatusEnum.class)
31 private Integer status; 30 private Integer status;
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java
@@ -2,18 +2,23 @@ package cn.iocoder.yudao.module.promotion.controller.app.banner; @@ -2,18 +2,23 @@ package cn.iocoder.yudao.module.promotion.controller.app.banner;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.module.promotion.controller.app.banner.vo.AppBannerRespVO; 4 import cn.iocoder.yudao.module.promotion.controller.app.banner.vo.AppBannerRespVO;
  5 +import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert;
  6 +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO;
  7 +import cn.iocoder.yudao.module.promotion.service.banner.BannerService;
  8 +import com.google.common.cache.CacheLoader;
  9 +import com.google.common.cache.LoadingCache;
5 import io.swagger.v3.oas.annotations.Operation; 10 import io.swagger.v3.oas.annotations.Operation;
  11 +import io.swagger.v3.oas.annotations.Parameter;
6 import io.swagger.v3.oas.annotations.tags.Tag; 12 import io.swagger.v3.oas.annotations.tags.Tag;
7 import org.springframework.validation.annotation.Validated; 13 import org.springframework.validation.annotation.Validated;
8 -import org.springframework.web.bind.annotation.GetMapping;  
9 -import org.springframework.web.bind.annotation.RequestMapping;  
10 -import org.springframework.web.bind.annotation.RequestParam;  
11 -import org.springframework.web.bind.annotation.RestController; 14 +import org.springframework.web.bind.annotation.*;
12 15
13 -import java.util.ArrayList; 16 +import javax.annotation.Resource;
  17 +import java.time.Duration;
14 import java.util.List; 18 import java.util.List;
15 19
16 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 20 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  21 +import static cn.iocoder.yudao.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
17 22
18 @RestController 23 @RestController
19 @RequestMapping("/promotion/banner") 24 @RequestMapping("/promotion/banner")
@@ -21,22 +26,39 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -21,22 +26,39 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
21 @Validated 26 @Validated
22 public class AppBannerController { 27 public class AppBannerController {
23 28
  29 + @Resource
  30 + private BannerService bannerService;
  31 + /**
  32 + * {@link AppBannerRespVO} 缓存,通过它异步刷新 {@link #getBannerList0(Integer)} 所要的首页数据
  33 + */
  34 + private final LoadingCache<Integer, List<AppBannerRespVO>> bannerListCache = buildAsyncReloadingCache(Duration.ofSeconds(10L),
  35 + new CacheLoader<Integer, List<AppBannerRespVO>>() {
  36 +
  37 + @Override
  38 + public List<AppBannerRespVO> load(Integer position) {
  39 + return getBannerList0(position);
  40 + }
  41 +
  42 + });
  43 +
24 @GetMapping("/list") 44 @GetMapping("/list")
25 @Operation(summary = "获得 banner 列表") 45 @Operation(summary = "获得 banner 列表")
26 - // todo @芋艿:swagger 注解,待补全  
27 - // TODO @芋艿:可以增加缓存,提升性能  
28 - // TODO @芋艿:position = 1 时,首页;position = 10 时,拼团活动页 46 + @Parameter(name = "position", description = "Banner position", example = "1")
29 public CommonResult<List<AppBannerRespVO>> getBannerList(@RequestParam("position") Integer position) { 47 public CommonResult<List<AppBannerRespVO>> getBannerList(@RequestParam("position") Integer position) {
30 - List<AppBannerRespVO> bannerList = new ArrayList<>();  
31 - AppBannerRespVO banner1 = new AppBannerRespVO();  
32 - banner1.setUrl("https://www.example.com/link1");  
33 - banner1.setPicUrl("https://api.java.crmeb.net/crmebimage/public/content/2022/08/04/0f78716213f64bfa83f191d51a832cbf73f6axavoy.jpg");  
34 - bannerList.add(banner1);  
35 - AppBannerRespVO banner2 = new AppBannerRespVO();  
36 - banner2.setUrl("https://www.example.com/link2");  
37 - banner2.setPicUrl("https://api.java.crmeb.net/crmebimage/public/content/2023/01/11/be09e755268b43ee90b0db3a3e1b7132r7a6t2wvsm.jpg");  
38 - bannerList.add(banner2);  
39 - return success(bannerList); 48 + return success(bannerListCache.getUnchecked(position));
  49 + }
  50 +
  51 + private List<AppBannerRespVO> getBannerList0(Integer position) {
  52 + List<BannerDO> bannerList = bannerService.getBannerListByPosition(position);
  53 + return BannerConvert.INSTANCE.convertList01(bannerList);
  54 + }
  55 +
  56 + @PutMapping("/add-browse-count")
  57 + @Operation(summary = "增加 Banner 点击量")
  58 + @Parameter(name = "id", description = "Banner 编号", example = "1024")
  59 + public CommonResult<Boolean> addBrowseCount(@RequestParam("id") Long id) {
  60 + bannerService.addBannerBrowseCount(id);
  61 + return success(true);
40 } 62 }
41 63
42 } 64 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/vo/AppBannerRespVO.java
@@ -9,6 +9,13 @@ import javax.validation.constraints.NotNull; @@ -9,6 +9,13 @@ import javax.validation.constraints.NotNull;
9 @Data 9 @Data
10 public class AppBannerRespVO { 10 public class AppBannerRespVO {
11 11
  12 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED)
  13 + private Long id;
  14 +
  15 + @Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED)
  16 + @NotNull(message = "标题不能为空")
  17 + private String title;
  18 +
12 @Schema(description = "跳转链接", requiredMode = Schema.RequiredMode.REQUIRED) 19 @Schema(description = "跳转链接", requiredMode = Schema.RequiredMode.REQUIRED)
13 @NotNull(message = "跳转链接不能为空") 20 @NotNull(message = "跳转链接不能为空")
14 private String url; 21 private String url;
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO; 4 import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO;
5 import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO; 5 import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO;
6 import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO; 6 import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.app.banner.vo.AppBannerRespVO;
7 import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; 8 import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO;
8 import org.mapstruct.Mapper; 9 import org.mapstruct.Mapper;
9 import org.mapstruct.factory.Mappers; 10 import org.mapstruct.factory.Mappers;
@@ -25,4 +26,6 @@ public interface BannerConvert { @@ -25,4 +26,6 @@ public interface BannerConvert {
25 26
26 BannerDO convert(BannerUpdateReqVO updateReqVO); 27 BannerDO convert(BannerUpdateReqVO updateReqVO);
27 28
  29 + List<AppBannerRespVO> convertList01(List<BannerDO> bannerList);
  30 +
28 } 31 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java
1 package cn.iocoder.yudao.module.promotion.dal.dataobject.banner; 1 package cn.iocoder.yudao.module.promotion.dal.dataobject.banner;
2 2
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  5 +import cn.iocoder.yudao.module.promotion.enums.banner.BannerPositionEnum;
4 import com.baomidou.mybatisplus.annotation.TableName; 6 import com.baomidou.mybatisplus.annotation.TableName;
5 import lombok.*; 7 import lombok.*;
6 8
@@ -40,14 +42,25 @@ public class BannerDO extends BaseDO { @@ -40,14 +42,25 @@ public class BannerDO extends BaseDO {
40 private Integer sort; 42 private Integer sort;
41 43
42 /** 44 /**
43 - * 状态 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum} 45 + * 状态 {@link CommonStatusEnum}
44 */ 46 */
45 private Integer status; 47 private Integer status;
  48 +
  49 + /**
  50 + * 定位 {@link BannerPositionEnum}
  51 + */
  52 + private Integer position;
  53 +
46 /** 54 /**
47 * 备注 55 * 备注
48 */ 56 */
49 private String memo; 57 private String memo;
50 58
51 - // TODO 芋艿 点击次数。&& 其他数据相关 59 + /**
  60 + * 点击次数
  61 + */
  62 + private Integer browseCount;
  63 +
  64 + // TODO 芋艿 其他数据相关
52 65
53 } 66 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java
@@ -5,8 +5,11 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; @@ -5,8 +5,11 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO; 6 import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO;
7 import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; 7 import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO;
  8 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
8 import org.apache.ibatis.annotations.Mapper; 9 import org.apache.ibatis.annotations.Mapper;
9 10
  11 +import java.util.List;
  12 +
10 /** 13 /**
11 * Banner Mapper 14 * Banner Mapper
12 * 15 *
@@ -23,4 +26,14 @@ public interface BannerMapper extends BaseMapperX&lt;BannerDO&gt; { @@ -23,4 +26,14 @@ public interface BannerMapper extends BaseMapperX&lt;BannerDO&gt; {
23 .orderByDesc(BannerDO::getSort)); 26 .orderByDesc(BannerDO::getSort));
24 } 27 }
25 28
  29 + default void updateBrowseCount(Long id) {
  30 + update(null, new LambdaUpdateWrapper<BannerDO>()
  31 + .eq(BannerDO::getId, id)
  32 + .setSql("browse_count = browse_count + 1"));
  33 + }
  34 +
  35 + default List<BannerDO> selectBannerListByPosition(Integer position) {
  36 + return selectList(new LambdaQueryWrapperX<BannerDO>().eq(BannerDO::getPosition, position));
  37 + }
  38 +
26 } 39 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java
@@ -47,12 +47,6 @@ public interface BannerService { @@ -47,12 +47,6 @@ public interface BannerService {
47 BannerDO getBanner(Long id); 47 BannerDO getBanner(Long id);
48 48
49 /** 49 /**
50 - * 获得所有 Banner列表  
51 - * @return Banner列表  
52 - */  
53 - List<BannerDO> getBannerList();  
54 -  
55 - /**  
56 * 获得 Banner 分页 50 * 获得 Banner 分页
57 * 51 *
58 * @param pageReqVO 分页查询 52 * @param pageReqVO 分页查询
@@ -60,4 +54,19 @@ public interface BannerService { @@ -60,4 +54,19 @@ public interface BannerService {
60 */ 54 */
61 PageResult<BannerDO> getBannerPage(BannerPageReqVO pageReqVO); 55 PageResult<BannerDO> getBannerPage(BannerPageReqVO pageReqVO);
62 56
  57 + /**
  58 + * 增加 Banner 点击量
  59 + *
  60 + * @param id Banner编号
  61 + */
  62 + void addBannerBrowseCount(Long id);
  63 +
  64 + /**
  65 + * 获得 Banner 列表
  66 + *
  67 + * @param position 定位
  68 + * @return Banner 列表
  69 + */
  70 + List<BannerDO> getBannerListByPosition(Integer position);
  71 +
63 } 72 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java
@@ -66,13 +66,21 @@ public class BannerServiceImpl implements BannerService { @@ -66,13 +66,21 @@ public class BannerServiceImpl implements BannerService {
66 } 66 }
67 67
68 @Override 68 @Override
69 - public List<BannerDO> getBannerList() {  
70 - return bannerMapper.selectList(); 69 + public PageResult<BannerDO> getBannerPage(BannerPageReqVO pageReqVO) {
  70 + return bannerMapper.selectPage(pageReqVO);
71 } 71 }
72 72
73 @Override 73 @Override
74 - public PageResult<BannerDO> getBannerPage(BannerPageReqVO pageReqVO) {  
75 - return bannerMapper.selectPage(pageReqVO); 74 + public void addBannerBrowseCount(Long id) {
  75 + // 校验 Banner 是否存在
  76 + validateBannerExists(id);
  77 + // 增加点击次数
  78 + bannerMapper.updateBrowseCount(id);
  79 + }
  80 +
  81 + @Override
  82 + public List<BannerDO> getBannerListByPosition(Integer position) {
  83 + return bannerMapper.selectBannerListByPosition(position);
76 } 84 }
77 85
78 } 86 }