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 27 @NotNull(message = "图片地址不能为空")
28 28 private String picUrl;
29 29  
  30 + @Schema(description = "position", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + @NotNull(message = "position 不能为空")
  32 + private Integer position;
  33 +
30 34 @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
31 35 @NotNull(message = "排序不能为空")
32 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 25 @Schema(description = "标题")
26 26 private String title;
27 27  
28   -
29 28 @Schema(description = "状态")
30 29 @InEnum(CommonStatusEnum.class)
31 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 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 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 10 import io.swagger.v3.oas.annotations.Operation;
  11 +import io.swagger.v3.oas.annotations.Parameter;
6 12 import io.swagger.v3.oas.annotations.tags.Tag;
7 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 18 import java.util.List;
15 19  
16 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 23 @RestController
19 24 @RequestMapping("/promotion/banner")
... ... @@ -21,22 +26,39 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
21 26 @Validated
22 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 44 @GetMapping("/list")
25 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 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 9 @Data
10 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 19 @Schema(description = "跳转链接", requiredMode = Schema.RequiredMode.REQUIRED)
13 20 @NotNull(message = "跳转链接不能为空")
14 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 4 import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO;
5 5 import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO;
6 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 8 import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO;
8 9 import org.mapstruct.Mapper;
9 10 import org.mapstruct.factory.Mappers;
... ... @@ -25,4 +26,6 @@ public interface BannerConvert {
25 26  
26 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 1 package cn.iocoder.yudao.module.promotion.dal.dataobject.banner;
2 2  
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  5 +import cn.iocoder.yudao.module.promotion.enums.banner.BannerPositionEnum;
4 6 import com.baomidou.mybatisplus.annotation.TableName;
5 7 import lombok.*;
6 8  
... ... @@ -40,14 +42,25 @@ public class BannerDO extends BaseDO {
40 42 private Integer sort;
41 43  
42 44 /**
43   - * 状态 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
  45 + * 状态 {@link CommonStatusEnum}
44 46 */
45 47 private Integer status;
  48 +
  49 + /**
  50 + * 定位 {@link BannerPositionEnum}
  51 + */
  52 + private Integer position;
  53 +
46 54 /**
47 55 * 备注
48 56 */
49 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 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 6 import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO;
7 7 import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO;
  8 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
8 9 import org.apache.ibatis.annotations.Mapper;
9 10  
  11 +import java.util.List;
  12 +
10 13 /**
11 14 * Banner Mapper
12 15 *
... ... @@ -23,4 +26,14 @@ public interface BannerMapper extends BaseMapperX&lt;BannerDO&gt; {
23 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 47 BannerDO getBanner(Long id);
48 48  
49 49 /**
50   - * 获得所有 Banner列表
51   - * @return Banner列表
52   - */
53   - List<BannerDO> getBannerList();
54   -
55   - /**
56 50 * 获得 Banner 分页
57 51 *
58 52 * @param pageReqVO 分页查询
... ... @@ -60,4 +54,19 @@ public interface BannerService {
60 54 */
61 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 66 }
67 67  
68 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 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 }
... ...