From 1f01746cebb69ffe93250edea08225a6c7028550 Mon Sep 17 00:00:00 2001 From: liujiang <569804566@qq.com> Date: Sat, 20 Sep 2025 22:03:44 +0800 Subject: [PATCH] =?UTF-8?q?master=EF=BC=9Aapp=E6=A1=A3=E5=8F=A3=E8=AE=BF?= =?UTF-8?q?=E9=97=AE=E6=A6=9C=E6=8E=A5=E5=8F=A3=E6=B7=BB=E5=8A=A0=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/xkt/StoreController.java | 11 ++++++ .../xkt/vo/store/StoreAppViewRankResVO.java | 39 +++++++++++++++++++ .../ruoyi/common/constant/CacheConstants.java | 8 ++++ .../xkt/dto/store/StoreAppViewRankResDTO.java | 39 +++++++++++++++++++ .../com/ruoyi/xkt/mapper/StoreMapper.java | 9 +++++ .../com/ruoyi/xkt/service/IStoreService.java | 6 +++ .../StoreProductStatisticsServiceImpl.java | 22 ++++++++++- .../xkt/service/impl/StoreServiceImpl.java | 39 +++++++++++++++++++ xkt/src/main/resources/mapper/StoreMapper.xml | 16 ++++++++ 9 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/store/StoreAppViewRankResVO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/store/StoreAppViewRankResDTO.java diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreController.java index 8796ff401..a4cadd164 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreController.java @@ -92,12 +92,14 @@ public class StoreController extends XktBaseController { return R.ok(storeService.updateStoreWeight(BeanUtil.toBean(storeWeightUpdateVO, StoreWeightUpdateDTO.class))); } + @PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store')||@ss.hasSupplierSubRole()") @ApiOperation(value = "获取档口详细信息", httpMethod = "GET", response = R.class) @GetMapping(value = "/{storeId}") public R getInfo(@PathVariable("storeId") Long storeId) { return R.ok(BeanUtil.toBean(storeService.getInfo(storeId), StoreResVO.class)); } + @PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store,seller,agent')||@ss.hasSupplierSubRole()") @ApiOperation(value = "PC 商城首页 获取档口基础信息", httpMethod = "GET", response = R.class) @GetMapping(value = "/simple/{storeId}") public R getSimpleInfo(@PathVariable("storeId") Long storeId) { @@ -111,6 +113,7 @@ public class StoreController extends XktBaseController { return R.ok(BeanUtil.toBean(storeService.getApproveInfo(storeId), StoreApproveResVO.class)); } + @PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store,seller,agent')||@ss.hasSupplierSubRole()") @ApiOperation(value = "APP获取档口基本信息", httpMethod = "GET", response = R.class) @GetMapping(value = "/app/{storeId}") public R getAppInfo(@PathVariable("storeId") Long storeId) { @@ -180,4 +183,12 @@ public class StoreController extends XktBaseController { return R.ok(storeService.updateStockSys(BeanUtil.toBean(stockSysVO, StoreUpdateStockSysDTO.class))); } + @PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store,seller,agent')||@ss.hasSupplierSubRole()") + @ApiOperation(value = "APP档口访问榜", httpMethod = "GET", response = R.class) + @GetMapping("/app/view-rank") + public R getAppViewRank() { + return R.ok(BeanUtil.toBean(storeService.getAppViewRank(), StoreAppViewRankResVO.class)); + } + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/store/StoreAppViewRankResVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/store/StoreAppViewRankResVO.java new file mode 100644 index 000000000..858004fbf --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/store/StoreAppViewRankResVO.java @@ -0,0 +1,39 @@ +package com.ruoyi.web.controller.xkt.vo.store; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel +@Data +@Accessors(chain = true) +public class StoreAppViewRankResVO { + + @ApiModelProperty(value = "档口浏览量列表") + private List viewCountList; + + @Data + public static class SAVRViewCountVO { + @ApiModelProperty(value = "档口ID") + private Long storeId; + @ApiModelProperty(value = "档口名称") + private String storeName; + @ApiModelProperty(value = "会员等级") + private Integer memberLevel; + @ApiModelProperty(value = "logo") + private String logo; + @ApiModelProperty(value = "在售商品数量") + private Integer prodCount; + @ApiModelProperty(value = "商品浏览量") + private Long viewCount; + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java index 587c5b6c5..60d989f28 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java @@ -304,5 +304,13 @@ public class CacheConstants { * 档口访问次数 */ public static final String STORE_VISIT_COUNT = "store_visit_count"; + /** + * 档口访问次数缓存 + */ + public static final String STORE_VISIT_COUNT_CACHE = "store_visit_count_cache"; + /** + * 档口商品访问次数缓存 + */ + public static final String STORE_PROD_VIEW_COUNT_CACHE = "store_prod_view_count_cache"; } diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/store/StoreAppViewRankResDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/store/StoreAppViewRankResDTO.java new file mode 100644 index 000000000..2ee02c32a --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/store/StoreAppViewRankResDTO.java @@ -0,0 +1,39 @@ +package com.ruoyi.xkt.dto.store; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel +@Data +@Accessors(chain = true) +public class StoreAppViewRankResDTO { + + @ApiModelProperty(value = "档口浏览量列表") + private List viewCountList; + + @Data + public static class SAVRViewCountDTO { + @ApiModelProperty(value = "档口ID") + private Long storeId; + @ApiModelProperty(value = "档口名称") + private String storeName; + @ApiModelProperty(value = "会员等级") + private Integer memberLevel; + @ApiModelProperty(value = "logo") + private String logo; + @ApiModelProperty(value = "在售商品数量") + private Integer prodCount; + @ApiModelProperty(value = "商品浏览量") + private Long viewCount; + } + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreMapper.java index 3cdb3ada0..0b51ba7d6 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreMapper.java @@ -2,12 +2,14 @@ package com.ruoyi.xkt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.xkt.domain.Store; +import com.ruoyi.xkt.dto.store.StoreAppViewRankResDTO; import com.ruoyi.xkt.dto.store.StorePageDTO; import com.ruoyi.xkt.dto.store.StorePageResDTO; import com.ruoyi.xkt.dto.store.StoreSimpleResDTO; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; +import java.util.Date; import java.util.List; /** @@ -35,4 +37,11 @@ public interface StoreMapper extends BaseMapper { */ StoreSimpleResDTO getSimpleInfo(@Param("storeId") Long storeId); + /** + * 获取档口访问榜 过去3个月到现在 + * @param threeMonthAgo 三个月前 + * @param yesterday 昨天 + * @return + */ + List selectTop10AppViewCount(@Param("threeMonthAgo") Date threeMonthAgo, @Param("yesterday") Date yesterday); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreService.java index b276c2a43..07fcb9640 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreService.java @@ -191,4 +191,10 @@ public interface IStoreService { */ Integer updateStockSys(StoreUpdateStockSysDTO stockSysDTO); + /** + * 获取APP档口浏览量排行榜 + * + * @return StoreAppViewRankResDTO + */ + StoreAppViewRankResDTO getAppViewRank(); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreProductStatisticsServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreProductStatisticsServiceImpl.java index 53db25b56..4d78c070e 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreProductStatisticsServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreProductStatisticsServiceImpl.java @@ -1,14 +1,20 @@ package com.ruoyi.xkt.service.impl; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.xkt.dto.StoreProductStatistics.StoreProdAppViewRankResDTO; import com.ruoyi.xkt.mapper.StoreProductStatisticsMapper; import com.ruoyi.xkt.service.IStoreProductStatisticsService; import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; /** * 档口商品统计 服务层实现 @@ -20,6 +26,7 @@ import java.util.Date; public class StoreProductStatisticsServiceImpl implements IStoreProductStatisticsService { final StoreProductStatisticsMapper prodStatisticsMapper; + final RedisCache redisCache; /** * 档口商品访问榜 @@ -29,9 +36,22 @@ public class StoreProductStatisticsServiceImpl implements IStoreProductStatistic @Override @Transactional(readOnly = true) public StoreProdAppViewRankResDTO getAppViewRank() { + // 从redis中获取商品访问量 + StoreProdAppViewRankResDTO redisAppViewRank = redisCache.getCacheObject(CacheConstants.STORE_PROD_VIEW_COUNT_CACHE); + if (ObjectUtils.isNotEmpty(redisAppViewRank)) { + return redisAppViewRank; + } + redisAppViewRank = new StoreProdAppViewRankResDTO(); final Date yesterday = java.sql.Date.valueOf(LocalDate.now().minusDays(1)); final Date threeMonthAgo = java.sql.Date.valueOf(LocalDate.now().minusDays(1).minusMonths(3)); - return new StoreProdAppViewRankResDTO().setViewCountList(prodStatisticsMapper.selectTop10ProdViewCount(threeMonthAgo, yesterday)); + List viewCountList = prodStatisticsMapper.selectTop10ProdViewCount(threeMonthAgo, yesterday); + if (CollectionUtils.isEmpty(viewCountList)) { + return redisAppViewRank; + } + redisAppViewRank.setViewCountList(viewCountList); + // 放到redis中 + redisCache.setCacheObject(CacheConstants.STORE_PROD_VIEW_COUNT_CACHE, redisAppViewRank, 1, TimeUnit.DAYS); + return redisAppViewRank; } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreServiceImpl.java index c0310c56d..1ec8e32c4 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreServiceImpl.java @@ -46,6 +46,7 @@ import java.math.BigDecimal; import java.time.LocalDate; import java.time.ZoneId; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -392,6 +393,44 @@ public class StoreServiceImpl implements IStoreService { return this.storeMapper.updateById(store); } + /** + * 获取APP档口浏览量排行榜 + * + * @return StoreAppViewRankResDTO + */ + @Override + @Transactional(readOnly = true) + public StoreAppViewRankResDTO getAppViewRank() { + // 从redis中获取档口访问量 + StoreAppViewRankResDTO redisAppViewRank = redisCache.getCacheObject(CacheConstants.STORE_VISIT_COUNT_CACHE); + if (ObjectUtils.isNotEmpty(redisAppViewRank)) { + return redisAppViewRank; + } + final Date yesterday = java.sql.Date.valueOf(LocalDate.now().minusDays(1)); + final Date threeMonthAgo = java.sql.Date.valueOf(LocalDate.now().minusDays(1).minusMonths(3)); + List viewCountList = this.storeMapper.selectTop10AppViewCount(threeMonthAgo, yesterday); + redisAppViewRank = new StoreAppViewRankResDTO(); + if (CollectionUtils.isEmpty(viewCountList)) { + return redisAppViewRank; + } + // 获取档口商品总数 + List storeProdList = this.storeProdMapper.selectList(new LambdaQueryWrapper() + .in(StoreProduct::getStoreId, viewCountList.stream().map(StoreAppViewRankResDTO.SAVRViewCountDTO::getStoreId).collect(Collectors.toList())) + .eq(StoreProduct::getDelFlag, Constants.UNDELETED)); + Map prodCountMap = storeProdList.stream().collect(Collectors.groupingBy(StoreProduct::getStoreId, Collectors.summingInt(x -> 1))); + // 获取档口会员 + viewCountList.forEach(x -> { + // 查询档口会员等级 + StoreMember member = this.redisCache.getCacheObject(CacheConstants.STORE_MEMBER + x.getStoreId()); + x.setMemberLevel(ObjectUtils.isNotEmpty(member) ? member.getLevel() : null); + x.setProdCount(prodCountMap.getOrDefault(x.getStoreId(), 0)); + }); + redisAppViewRank.setViewCountList(viewCountList); + // 放到redis中 + redisCache.setCacheObject(CacheConstants.STORE_VISIT_COUNT_CACHE, redisAppViewRank, 1, TimeUnit.DAYS); + return redisAppViewRank; + } + /** * 档口首页今日销售额 * diff --git a/xkt/src/main/resources/mapper/StoreMapper.xml b/xkt/src/main/resources/mapper/StoreMapper.xml index 90d68efc0..03945462d 100644 --- a/xkt/src/main/resources/mapper/StoreMapper.xml +++ b/xkt/src/main/resources/mapper/StoreMapper.xml @@ -41,5 +41,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" s.id = #{storeId} + + \ No newline at end of file