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 00ae2b2b2..adbb6bc2a 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 @@ -115,14 +115,14 @@ public class StoreController extends XktBaseController { return R.ok(BeanUtil.toBean(storeService.indexTodaySaleRevenue(storeId), StoreIndexTodaySaleResVO.class)); } - @ApiOperation(value = "获取档口首页 商品销售额前10 ", httpMethod = "GET", response = R.class) - @GetMapping(value = "/index/sale/top10") + @ApiOperation(value = "获取档口首页 商品销售额前10 ", httpMethod = "POST", response = R.class) + @PostMapping(value = "/index/sale/top10") public R> indexTop10Sale(@Validated @RequestBody StoreSaleTop10VO saleTop10VO) { return R.ok(BeanUtil.copyToList(storeService.indexTop10Sale(BeanUtil.toBean(saleTop10VO, StoreSaleTop10DTO.class)), StoreIndexSaleTop10ResVO.class)); } - @ApiOperation(value = "获取档口首页 客户销售榜前10 ", httpMethod = "GET", response = R.class) - @GetMapping(value = "/index/sale-cus/top10") + @ApiOperation(value = "获取档口首页 客户销售榜前10 ", httpMethod = "POST", response = R.class) + @PostMapping(value = "/index/sale-cus/top10") public R> indexTop10SaleCus(@Validated @RequestBody StoreSaleCustomerTop10VO saleCusTop10VO) { return R.ok(BeanUtil.copyToList(storeService.indexTop10SaleCus(BeanUtil.toBean(saleCusTop10VO, StoreSaleCustomerTop10DTO.class)), StoreIndexCusSaleTop10ResVO.class)); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreHomepageController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreHomepageController.java index 55676f38b..e5f73df25 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreHomepageController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreHomepageController.java @@ -59,31 +59,31 @@ public class StoreHomepageController extends XktBaseController { } @ApiOperation(value = "获取档口首页 模板一 数据", httpMethod = "GET", response = R.class) - @GetMapping(value = "/template-one/{storeId}") + @GetMapping(value = "/template/one/{storeId}") public R getTemplateOne(@PathVariable("storeId") Long storeId) { return R.ok(BeanUtil.toBean(storeHomeService.getTemplateOne(storeId), StoreHomeTemplateOneResVO.class)); } @ApiOperation(value = "获取档口首页 模板二 数据", httpMethod = "GET", response = R.class) - @GetMapping(value = "/template-two/{storeId}") + @GetMapping(value = "/template/two/{storeId}") public R getTemplateTwo(@PathVariable("storeId") Long storeId) { return R.ok(BeanUtil.toBean(storeHomeService.getTemplateTwo(storeId), StoreHomeTemplateTwoResVO.class)); } @ApiOperation(value = "获取档口首页 模板三 数据", httpMethod = "GET", response = R.class) - @GetMapping(value = "/template-third/{storeId}") + @GetMapping(value = "/template/three/{storeId}") public R getTemplateThird(@PathVariable("storeId") Long storeId) { return R.ok(BeanUtil.toBean(storeHomeService.getTemplateThird(storeId), StoreHomeTemplateThirdResVO.class)); } @ApiOperation(value = "获取档口首页 模板四 数据", httpMethod = "GET", response = R.class) - @GetMapping(value = "/template-four/{storeId}") + @GetMapping(value = "/template/four/{storeId}") public R getTemplateFour(@PathVariable("storeId") Long storeId) { return R.ok(BeanUtil.toBean(storeHomeService.getTemplateFour(storeId), StoreHomeTemplateFourResVO.class)); } @ApiOperation(value = "获取档口首页 模板五 数据", httpMethod = "GET", response = R.class) - @GetMapping(value = "/template-five/{storeId}") + @GetMapping(value = "/template/five/{storeId}") public R getTemplateFive(@PathVariable("storeId") Long storeId) { return R.ok(BeanUtil.toBean(storeHomeService.getTemplateFive(storeId), StoreHomeTemplateFiveResVO.class)); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/UserBrowsingHistoryController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/UserBrowsingHistoryController.java index 1ece268b3..9f909b7e6 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/UserBrowsingHistoryController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/UserBrowsingHistoryController.java @@ -1,9 +1,19 @@ package com.ruoyi.web.controller.xkt; +import cn.hutool.core.bean.BeanUtil; import com.ruoyi.common.core.controller.XktBaseController; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.page.Page; +import com.ruoyi.web.controller.xkt.vo.userBrowsingHistory.UserBrowHisPageVO; +import com.ruoyi.xkt.dto.userBrowsingHistory.UserBrowHisPageDTO; +import com.ruoyi.xkt.dto.userBrowsingHistory.UserBrowsingHisPageResDTO; import com.ruoyi.xkt.service.IUserBrowsingHistoryService; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -21,4 +31,10 @@ public class UserBrowsingHistoryController extends XktBaseController { final IUserBrowsingHistoryService userBrowHisService; + @ApiOperation(value = "获取用户浏览足迹", httpMethod = "POST", response = R.class) + @PostMapping(value = "/page") + public R> page(@Validated @RequestBody UserBrowHisPageVO pageVO) { + return R.ok(userBrowHisService.page(BeanUtil.toBean(pageVO, UserBrowHisPageDTO.class))); + } + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/UserSearchHistoryController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/UserSearchHistoryController.java new file mode 100644 index 000000000..9b0449df4 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/UserSearchHistoryController.java @@ -0,0 +1,35 @@ +package com.ruoyi.web.controller.xkt; + +import com.ruoyi.common.core.controller.XktBaseController; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.xkt.service.IUserSearchHistoryService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 用户搜索历史Controller + * + * @author ruoyi + * @date 2025-03-26 + */ +@Api(tags = "用户搜索历史") +@RestController +@RequiredArgsConstructor +@RequestMapping("/rest/v1/user-search-his") +public class UserSearchHistoryController extends XktBaseController { + + final IUserSearchHistoryService userSearchHisService; + + @ApiOperation(value = "获取用户搜索历史", httpMethod = "GET", response = R.class) + @GetMapping(value = "") + public R> recordList() { + return R.ok(userSearchHisService.recordList()); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/store/StoreIndexTodaySaleResVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/store/StoreIndexTodaySaleResVO.java index 29e0a2930..d6c214534 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/store/StoreIndexTodaySaleResVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/store/StoreIndexTodaySaleResVO.java @@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.math.BigDecimal; import java.util.List; /** @@ -17,6 +18,8 @@ public class StoreIndexTodaySaleResVO { @ApiModelProperty(value = "档口ID") private Long storeId; + @ApiModelProperty(value = "其它销售额") + private BigDecimal otherAmount; @ApiModelProperty(value = "档口商品销售额列表") List saleList; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/userBrowsingHistory/UserBrowHisPageVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/userBrowsingHistory/UserBrowHisPageVO.java new file mode 100644 index 000000000..ed2caed0d --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/userBrowsingHistory/UserBrowHisPageVO.java @@ -0,0 +1,19 @@ +package com.ruoyi.web.controller.xkt.vo.userBrowsingHistory; + +import com.ruoyi.web.controller.xkt.vo.BasePageVO; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@EqualsAndHashCode(callSuper = true) +@ApiModel("用户浏览足迹分页") +@Data +public class UserBrowHisPageVO extends BasePageVO { + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/userSearchHistory/UserSearchHistoryVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/userSearchHistory/UserSearchHistoryVO.java new file mode 100644 index 000000000..ace822895 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/userSearchHistory/UserSearchHistoryVO.java @@ -0,0 +1,35 @@ +package com.ruoyi.web.controller.xkt.vo.userSearchHistory; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("用户搜索记录") +@Data +@Accessors(chain = true) +public class UserSearchHistoryVO { + + @ApiModelProperty(value = "用户搜索ID") + private Long id; + @ApiModelProperty(value = "用户ID") + private Long userId; + @ApiModelProperty(value = "用户名称") + private String userName; + @ApiModelProperty(value = "搜索内容") + private String searchContent; + @ApiModelProperty(value = "平台ID") + private Integer platformId; + @ApiModelProperty(value = "搜索时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date searchTime; + +} 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 d52e05e4c..05ea34581 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 @@ -219,6 +219,10 @@ public class CacheConstants { * 用户搜索历史 */ public static final String USER_SEARCH_HISTORY = "user_search_history:"; + /** + * 用户浏览足迹 + */ + public static final String USER_BROWSING_HISTORY = "user_browsing_history:"; /** * 系统前20条热搜 */ diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index 6b436f457..ad89fea8d 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -264,6 +264,4 @@ public class Constants */ public static final Set STORE_RECOMMEND_INSERT_POSITIONS = new HashSet<>(Arrays.asList(2, 9, 18, 27, 36)); - - } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java index ec6a356f7..5a5aa2d1a 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -125,6 +125,10 @@ public class SecurityConfig .antMatchers("/rest/v1/sys/prod-cate/**").permitAll() // 商品所有风格 .antMatchers("/rest/v1/prods/styles").permitAll() + // 档口首页模板 + .antMatchers("/rest/v1/store-home/template/**").permitAll() + // 档口推荐 + .antMatchers("/rest/v1/store-home/recommend/**").permitAll() // TODO 临时放开 临时放开 @@ -132,6 +136,8 @@ public class SecurityConfig .antMatchers("/rest/v1/pic-search").permitAll() .antMatchers("/rest/v1/stores/simple/**").permitAll() .antMatchers("/rest/v1/prods/status/num/**").permitAll() + .antMatchers("/rest/v1/prods/status/num/**").permitAll() + .antMatchers("/rest/v1/prods/pc/detail/**").permitAll() // 除上面外的所有请求全部需要鉴权认证 diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/XktTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/XktTask.java index c6532faae..9252256b1 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/XktTask.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/XktTask.java @@ -30,6 +30,7 @@ import com.ruoyi.xkt.dto.order.StoreOrderCancelDTO; import com.ruoyi.xkt.dto.order.StoreOrderRefund; import com.ruoyi.xkt.dto.storeProductFile.StoreProdFileLatestFourProdDTO; import com.ruoyi.xkt.dto.useSearchHistory.UserSearchHistoryDTO; +import com.ruoyi.xkt.dto.userBrowsingHistory.UserBrowsingHisDTO; import com.ruoyi.xkt.enums.*; import com.ruoyi.xkt.manager.PaymentManager; import com.ruoyi.xkt.mapper.*; @@ -95,6 +96,7 @@ public class XktTask { final StoreProductStatisticsMapper storeProdStatMapper; final StoreProductFileMapper storeProdFileMapper; final UserSearchHistoryMapper userSearchHisMapper; + final UserBrowsingHistoryMapper userBrowHisMapper; /** * 定时任务上市季节年份 @@ -592,21 +594,62 @@ public class XktTask { }); // 用户最新搜索列表 List insertSearchList = redisSearchList.stream().filter(x -> ObjectUtils.isEmpty(x.getId())).collect(Collectors.toList()); - if (CollectionUtils.isEmpty(insertSearchList)) { - return; + if (CollectionUtils.isNotEmpty(insertSearchList)) { + this.userSearchHisMapper.insert(BeanUtil.copyToList(insertSearchList, UserSearchHistory.class)); } - this.userSearchHisMapper.insert(BeanUtil.copyToList(insertSearchList, UserSearchHistory.class)); + final Date sixMonthAgo = java.sql.Date.valueOf(LocalDate.now().minusMonths(6)); + final Date now = java.sql.Date.valueOf(LocalDate.now()); // 将最新的数据更新到redis中 List latestSearchList = this.userSearchHisMapper.selectList(new LambdaQueryWrapper() - .eq(UserSearchHistory::getDelFlag, Constants.UNDELETED)); + .eq(UserSearchHistory::getDelFlag, Constants.UNDELETED).between(UserSearchHistory::getSearchTime, sixMonthAgo, now)); + if (CollectionUtils.isEmpty(latestSearchList)) { + return; + } latestSearchList.stream().collect(Collectors.groupingBy(UserSearchHistory::getUserId)) .forEach((userId, list) -> { // 获取用户最新搜索的20条数据 list = list.stream().sorted(Comparator.comparing(UserSearchHistory::getSearchTime).reversed()).limit(20).collect(Collectors.toList()); + // 反转列表 + Collections.reverse(list); redisCache.setCacheObject(CacheConstants.USER_SEARCH_HISTORY + userId, BeanUtil.copyToList(list, UserSearchHistoryDTO.class)); }); } + /** + * 每天凌晨2:05更新用户浏览记录入库 + */ + @Transactional + public void dailyUpdateUserBrowsingHistory() { + Collection keyList = this.redisCache.scanKeys(CacheConstants.USER_BROWSING_HISTORY + "*"); + if (CollectionUtils.isEmpty(keyList)) { + return; + } + List redisBrowsingList = new ArrayList<>(); + keyList.forEach(key -> { + List tempList = this.redisCache.getCacheObject(key); + CollectionUtils.addAll(redisBrowsingList, tempList); + }); + // 用户最新浏览列表 + List insertBrowsingList = redisBrowsingList.stream().filter(x -> ObjectUtils.isEmpty(x.getId())).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(insertBrowsingList)) { + this.userBrowHisMapper.insert(BeanUtil.copyToList(insertBrowsingList, UserBrowsingHistory.class)); + } + final Date sixMonthAgo = java.sql.Date.valueOf(LocalDate.now().minusMonths(6)); + final Date now = java.sql.Date.valueOf(LocalDate.now()); + // 将最新的数据更新到redis中 + List latestBrowsingList = this.userBrowHisMapper.selectList(new LambdaQueryWrapper() + .eq(UserBrowsingHistory::getDelFlag, Constants.UNDELETED).between(UserBrowsingHistory::getBrowsingTime, sixMonthAgo, now)); + if (CollectionUtils.isEmpty(latestBrowsingList)) { + return; + } + latestBrowsingList.stream().collect(Collectors.groupingBy(x -> x.getUserId())) + .forEach((userId, list) -> { + // 按照浏览时间升序排 + list.sort(Comparator.comparing(UserBrowsingHistory::getBrowsingTime)); + redisCache.setCacheObject(CacheConstants.USER_BROWSING_HISTORY + userId, BeanUtil.copyToList(list, UserBrowsingHisDTO.class)); + }); + } + /** * 每晚凌晨3点更新系统热搜到redis中 */ diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleProductMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleProductMapper.xml index 5a889080d..9ccbdebaf 100644 --- a/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleProductMapper.xml +++ b/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleProductMapper.xml @@ -50,7 +50,7 @@ - SELECT dsp.store_prod_id, dsp.prod_art_num, diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/UserBrowsingHistory.java b/xkt/src/main/java/com/ruoyi/xkt/domain/UserBrowsingHistory.java index 21d226774..3fd682a56 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/UserBrowsingHistory.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/UserBrowsingHistory.java @@ -57,8 +57,8 @@ public class UserBrowsingHistory extends XktBaseEntity { */ private BigDecimal price; /** - * 凭证日期 + * 浏览日期 */ - private Date voucherDate; + private Date browsingTime; } diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPIndexHotSaleDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPIndexHotSaleDTO.java index abfe5f08e..ad9aa4f04 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPIndexHotSaleDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPIndexHotSaleDTO.java @@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; +import java.math.BigDecimal; import java.util.List; /** @@ -27,6 +28,10 @@ public class APPIndexHotSaleDTO { private String prodArtNum; @ApiModelProperty(value = "主图") private String mainPicUrl; + @ApiModelProperty(value = "主图名称") + private String mainPicName; + @ApiModelProperty(value = "主图大小") + private BigDecimal mainPicSize; @ApiModelProperty(value = "单价") private String prodPrice; @ApiModelProperty(value = "标题") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPIndexNewProdDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPIndexNewProdDTO.java index c91a1802e..6bf1b8ce8 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPIndexNewProdDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPIndexNewProdDTO.java @@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; +import java.math.BigDecimal; import java.util.List; /** @@ -27,6 +28,10 @@ public class APPIndexNewProdDTO { private String prodArtNum; @ApiModelProperty(value = "主图") private String mainPicUrl; + @ApiModelProperty(value = "主图名称") + private String mainPicName; + @ApiModelProperty(value = "主图大小") + private BigDecimal mainPicSize; @ApiModelProperty(value = "单价") private String prodPrice; @ApiModelProperty(value = "是否广告") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPIndexPopularSaleDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPIndexPopularSaleDTO.java index d59d214eb..88f05bb81 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPIndexPopularSaleDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPIndexPopularSaleDTO.java @@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; +import java.math.BigDecimal; import java.util.List; /** @@ -27,6 +28,10 @@ public class APPIndexPopularSaleDTO { private String prodArtNum; @ApiModelProperty(value = "主图") private String mainPicUrl; + @ApiModelProperty(value = "主图名称") + private String mainPicName; + @ApiModelProperty(value = "主图大小") + private BigDecimal mainPicSize; @ApiModelProperty(value = "单价") private String prodPrice; @ApiModelProperty(value = "是否广告") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPSearchDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPSearchDTO.java index ea9a5460a..e6e541b1e 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPSearchDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/app/index/APPSearchDTO.java @@ -6,6 +6,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; +import java.math.BigDecimal; import java.util.List; /** @@ -29,6 +30,10 @@ public class APPSearchDTO { private String prodArtNum; @ApiModelProperty(value = "主图") private String mainPicUrl; + @ApiModelProperty(value = "主图名称") + private String mainPicName; + @ApiModelProperty(value = "主图大小") + private BigDecimal mainPicSize; @ApiModelProperty(value = "单价") private String prodPrice; @ApiModelProperty(value = "是否广告") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/PCSearchDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/PCSearchDTO.java index bd24fb536..84f495de1 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/PCSearchDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/PCSearchDTO.java @@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; +import java.math.BigDecimal; import java.util.List; /** @@ -27,6 +28,10 @@ public class PCSearchDTO { private String prodArtNum; @ApiModelProperty(value = "主图") private String mainPicUrl; + @ApiModelProperty(value = "主图名称") + private String mainPicName; + @ApiModelProperty(value = "主图大小") + private BigDecimal mainPicSize; @ApiModelProperty(value = "单价") private String prodPrice; @ApiModelProperty(value = "是否广告") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/index/PCIndexRecommendDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/index/PCIndexRecommendDTO.java index d52fe7b35..923abf6b0 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/index/PCIndexRecommendDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/index/PCIndexRecommendDTO.java @@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; +import java.math.BigDecimal; import java.util.List; /** @@ -31,6 +32,10 @@ public class PCIndexRecommendDTO { private String prodArtNum; @ApiModelProperty(value = "主图") private String mainPicUrl; + @ApiModelProperty(value = "主图名称") + private String mainPicName; + @ApiModelProperty(value = "主图大小") + private BigDecimal mainPicSize; @ApiModelProperty(value = "单价") private String prodPrice; @ApiModelProperty(value = "是否广告") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/newProd/PCNewRecommendDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/newProd/PCNewRecommendDTO.java index 1f2212677..d347ca435 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/newProd/PCNewRecommendDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/newProd/PCNewRecommendDTO.java @@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; +import java.math.BigDecimal; import java.util.List; /** @@ -31,6 +32,10 @@ public class PCNewRecommendDTO { private String prodArtNum; @ApiModelProperty(value = "主图") private String mainPicUrl; + @ApiModelProperty(value = "主图名称") + private String mainPicName; + @ApiModelProperty(value = "主图大小") + private BigDecimal mainPicSize; @ApiModelProperty(value = "单价") private String prodPrice; @ApiModelProperty(value = "是否广告") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/es/ESProductDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/es/ESProductDTO.java index 6946e633f..ff44a32cd 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/es/ESProductDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/es/ESProductDTO.java @@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; +import java.math.BigDecimal; import java.util.List; /** @@ -37,6 +38,10 @@ public class ESProductDTO { private String createTime; @ApiModelProperty(value = "主图") private String mainPicUrl; + @ApiModelProperty(value = "主图名称") + private String mainPicName; + @ApiModelProperty(value = "主图大小") + private BigDecimal mainPicSize; @ApiModelProperty(value = "上级分类名称") private String parCateName; @ApiModelProperty(value = "上级分类ID") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdAppResDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdAppResDTO.java index 6a4dd8d57..b600198cd 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdAppResDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdAppResDTO.java @@ -27,6 +27,8 @@ public class StoreProdAppResDTO { private Long storeProdId; @ApiModelProperty(value = "档口ID") private Long storeId; + @ApiModelProperty(value = "档口名称") + private String storeName; @ApiModelProperty(value = "档口商品名称") private String prodName; @ApiModelProperty(value = "商品货号") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdPCResDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdPCResDTO.java index b162782ee..700066454 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdPCResDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdPCResDTO.java @@ -20,6 +20,10 @@ import java.util.List; @Accessors(chain = true) public class StoreProdPCResDTO { + @ApiModelProperty(value = "档口ID") + private Long storeId; + @ApiModelProperty(value = "档口名称") + private String storeName; @ApiModelProperty(value = "档口商品ID") private Long storeProdId; @ApiModelProperty(value = "商品货号") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdPriceAndMainPicAndTagDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdPriceAndMainPicAndTagDTO.java index 515ce1271..453cb0b37 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdPriceAndMainPicAndTagDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdPriceAndMainPicAndTagDTO.java @@ -38,6 +38,10 @@ public class StoreProdPriceAndMainPicAndTagDTO { private BigDecimal minPrice; @ApiModelProperty(value = "档口商品主图") private String mainPicUrl; + @ApiModelProperty(value = "主图名称") + private String mainPicName; + @ApiModelProperty(value = "主图大小") + private BigDecimal mainPicSize; @ApiModelProperty(value = "商品标题") private String prodTitle; @ApiModelProperty(value = "是否有主图视频") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/userBrowsingHistory/UserBrowHisPageDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/userBrowsingHistory/UserBrowHisPageDTO.java new file mode 100644 index 000000000..ed132a6c3 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/userBrowsingHistory/UserBrowHisPageDTO.java @@ -0,0 +1,19 @@ +package com.ruoyi.xkt.dto.userBrowsingHistory; + +import com.ruoyi.xkt.dto.BasePageDTO; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@EqualsAndHashCode(callSuper = true) +@ApiModel("用户浏览足迹分页") +@Data +public class UserBrowHisPageDTO extends BasePageDTO { + + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/userBrowsingHistory/UserBrowsingHisDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/userBrowsingHistory/UserBrowsingHisDTO.java new file mode 100644 index 000000000..2b6e9358d --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/userBrowsingHistory/UserBrowsingHisDTO.java @@ -0,0 +1,43 @@ +package com.ruoyi.xkt.dto.userBrowsingHistory; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("用户浏览历史") +@Data +@Accessors(chain = true) +public class UserBrowsingHisDTO { + + @ApiModelProperty(value = "浏览历史ID") + private Long id; + @ApiModelProperty(value = "用户ID") + private Long userId; + @ApiModelProperty(value = "档口ID") + private Long storeId; + @ApiModelProperty(value = "档口名称") + private String storeName; + @ApiModelProperty(value = "档口商品ID") + private Long storeProdId; + @ApiModelProperty(value = "档口商品标题") + private String prodTitle; + @ApiModelProperty(value = "档口商品主图url") + private String mainPicUrl; + @ApiModelProperty(value = "商品货号") + private String prodArtNum; + @ApiModelProperty(value = "商品价格") + private BigDecimal prodPrice; + @ApiModelProperty(value = "浏览日期") + private Date browsingTime; + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/userBrowsingHistory/UserBrowsingHisPageResDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/userBrowsingHistory/UserBrowsingHisPageResDTO.java new file mode 100644 index 000000000..82478222a --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/userBrowsingHistory/UserBrowsingHisPageResDTO.java @@ -0,0 +1,42 @@ +package com.ruoyi.xkt.dto.userBrowsingHistory; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("用户浏览历史") +@Data +@Accessors(chain = true) +public class UserBrowsingHisPageResDTO { + + @ApiModelProperty(value = "浏览历史ID") + private Long id; + @ApiModelProperty(value = "档口ID") + private Long storeId; + @ApiModelProperty(value = "档口名称") + private String storeName; + @ApiModelProperty(value = "档口商品ID") + private Long storeProdId; + @ApiModelProperty(value = "档口商品标题") + private String prodTitle; + @ApiModelProperty(value = "档口商品主图url") + private String mainPicUrl; + @ApiModelProperty(value = "商品货号") + private String prodArtNum; + @ApiModelProperty(value = "商品价格") + private BigDecimal prodPrice; + @ApiModelProperty(value = "浏览日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date browsingTime; + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IUserBrowsingHistoryService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IUserBrowsingHistoryService.java index 5ce7ff12f..746c85eae 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IUserBrowsingHistoryService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IUserBrowsingHistoryService.java @@ -1,15 +1,23 @@ package com.ruoyi.xkt.service; -import com.ruoyi.xkt.domain.UserBrowsingHistory; - -import java.util.List; +import com.ruoyi.common.core.page.Page; +import com.ruoyi.xkt.dto.userBrowsingHistory.UserBrowHisPageDTO; +import com.ruoyi.xkt.dto.userBrowsingHistory.UserBrowsingHisPageResDTO; /** - * 用户浏览历史Service接口 + * 用户搜索历史Service接口 * * @author ruoyi * @date 2025-03-26 */ public interface IUserBrowsingHistoryService { + /** + * 查询用户浏览历史分页 + * + * @param pageDTO 查询入参 + * @return Page + */ + Page page(UserBrowHisPageDTO pageDTO); + } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IUserSearchHistoryService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IUserSearchHistoryService.java new file mode 100644 index 000000000..86c05e9a5 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IUserSearchHistoryService.java @@ -0,0 +1,19 @@ +package com.ruoyi.xkt.service; + +import java.util.List; + +/** + * 用户浏览历史Service接口 + * + * @author ruoyi + * @date 2025-03-26 + */ +public interface IUserSearchHistoryService { + + /** + * 获取用户的搜索历史 + * + * @return List + */ + List recordList(); +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreProductServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreProductServiceImpl.java index 94aeac53a..53bbf3611 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreProductServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreProductServiceImpl.java @@ -16,9 +16,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; +import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.core.page.Page; +import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.SecurityUtils; @@ -39,6 +41,7 @@ import com.ruoyi.xkt.dto.storeProduct.*; import com.ruoyi.xkt.dto.storeProductFile.StoreProdFileDTO; import com.ruoyi.xkt.dto.storeProductFile.StoreProdFileResDTO; import com.ruoyi.xkt.dto.storeProductFile.StoreProdMainPicDTO; +import com.ruoyi.xkt.dto.userBrowsingHistory.UserBrowsingHisDTO; import com.ruoyi.xkt.enums.EProductStatus; import com.ruoyi.xkt.enums.FileType; import com.ruoyi.xkt.enums.ListingType; @@ -96,6 +99,7 @@ public class StoreProductServiceImpl implements IStoreProductService { final IPictureService pictureService; final StoreProductStatisticsMapper storeProductStatisticsMapper; final StoreHomepageMapper storeHomepageMapper; + final RedisCache redisCache; /** @@ -552,6 +556,17 @@ public class StoreProductServiceImpl implements IStoreProductService { List colorSizeList = this.storeProdColorSizeMapper.selectList(new LambdaQueryWrapper() .eq(StoreProductColorSize::getStoreProdId, storeProdId).eq(StoreProductColorSize::getDelFlag, Constants.UNDELETED) .eq(StoreProductColorSize::getStandard, ProductSizeStatus.STANDARD.getValue())); + List fileList = this.storeProdFileMapper.selectVideoAndMainPicList(storeProdId); + // 第一张商品主图 + final String mainPicUrl = fileList.stream().filter(x -> Objects.equals(x.getFileType(), FileType.MAIN_PIC.getValue())) + .filter(x -> Objects.equals(x.getOrderNum(), ORDER_NUM_1)).map(StoreProdFileResDTO::getFileUrl).findAny().orElse(""); + // 将用户浏览足迹添加到redis中 + try { + this.updateUserBrowsingToRedis(storeProdId, appResDTO.getStoreId(), appResDTO.getStoreName(), appResDTO.getProdArtNum(), + appResDTO.getProdTitle(), appResDTO.getMinPrice(), mainPicUrl); + } catch (Exception e) { + e.printStackTrace(); + } return appResDTO.setTags(StringUtils.isNotBlank(appResDTO.getTagStr()) ? StrUtil.split(appResDTO.getTagStr(), ",") : null) // 拼接几色几码 .setSpecification((CollectionUtils.isNotEmpty(colorList) ? colorList.size() + "色" : "") + @@ -559,7 +574,7 @@ public class StoreProductServiceImpl implements IStoreProductService { // 获取商品的属性 .setCateAttr(BeanUtil.toBean(cateAttr, StoreProdCateAttrDTO.class)) // 获取商品的主图视频及主图 - .setFileList(this.storeProdFileMapper.selectVideoAndMainPicList(storeProdId)) + .setFileList(fileList) // 获取商品的服务承诺 .setSvc(this.storeProdSvcMapper.selectSvc(storeProdId)); } @@ -640,14 +655,25 @@ public class StoreProductServiceImpl implements IStoreProductService { @Override @Transactional(readOnly = true) public StoreProdPCResDTO getPCInfo(Long storeProdId) { + + // TODO 去掉 + // TODO 去掉 + // TODO 去掉 + // TODO 去掉 + + final Long userId = 1L; + + // 商品基础信息 - StoreProdPCResDTO prodInfoDTO = ObjectUtils.defaultIfNull(this.storeProdMapper.selectPCProdInfo(storeProdId, SecurityUtils.getUserId()), new StoreProdPCResDTO()); + StoreProdPCResDTO prodInfoDTO = ObjectUtils.defaultIfNull(this.storeProdMapper.selectPCProdInfo(storeProdId, 1L), new StoreProdPCResDTO()); +// StoreProdPCResDTO prodInfoDTO = ObjectUtils.defaultIfNull(this.storeProdMapper.selectPCProdInfo(storeProdId, SecurityUtils.getUserId()), new StoreProdPCResDTO()); // 获取商品的属性 StoreProductCategoryAttribute cateAttr = this.storeProdCateAttrMapper.selectOne(new LambdaQueryWrapper() .eq(StoreProductCategoryAttribute::getStoreProdId, storeProdId).eq(StoreProductCategoryAttribute::getDelFlag, Constants.UNDELETED)); + List fileList = this.storeProdFileMapper.selectVideoAndMainPicList(storeProdId); prodInfoDTO.setCateAttr(BeanUtil.toBean(cateAttr, StoreProdPCResDTO.StoreProdCateAttrDTO.class)) // 获取商品的主图视频及主图 - .setFileList(this.storeProdFileMapper.selectVideoAndMainPicList(storeProdId)); + .setFileList(fileList); // 档口商品的sku列表 List prodSkuList = this.storeProdMapper.selectSkuList(storeProdId); if (CollectionUtils.isEmpty(prodSkuList)) { @@ -667,6 +693,15 @@ public class StoreProductServiceImpl implements IStoreProductService { .setStock(colorSizeStockMap.get(color.getStoreColorId() + ":" + size.getSize()))) .collect(Collectors.toList())); }); + final BigDecimal minPrice = Objects.requireNonNull(colorList.stream().min(Comparator.comparing(StoreProdSkuItemDTO::getPrice)).orElse(null)).getPrice(); + final String mainPicUrl = fileList.stream().filter(x -> Objects.equals(x.getFileType(), FileType.MAIN_PIC.getValue())) + .filter(x -> Objects.equals(x.getOrderNum(), ORDER_NUM_1)).map(StoreProdFileResDTO::getFileUrl).findAny().orElse(""); + // 将用户浏览足迹添加到redis中 + try { + this.updateUserBrowsingToRedis(storeProdId, prodInfoDTO.getStoreId(), prodInfoDTO.getStoreName(), prodInfoDTO.getProdArtNum(), prodInfoDTO.getProdTitle(), minPrice, mainPicUrl); + } catch (Exception e) { + e.printStackTrace(); + } return prodInfoDTO.setColorList(colorList); } @@ -935,4 +970,30 @@ public class StoreProductServiceImpl implements IStoreProductService { } + /** + * 更新用户浏览记录到Redis + * 此方法用于将用户的商品浏览信息更新到Redis缓存中,以便后续推荐或展示相关商品 + * + * @param storeProdId 商店商品ID + * @param storeId 商店ID + * @param storeName 商店名称 + * @param prodArtNum 商品货号 + * @param prodTitle 商品标题 + * @param minPrice 商品的最低价格 + * @param mainPicUrl 商品主图URL + */ + private void updateUserBrowsingToRedis(Long storeProdId, Long storeId, String storeName, String prodArtNum, String prodTitle, BigDecimal minPrice, String mainPicUrl) { + final Long userId = SecurityUtils.getUserId(); + if (ObjectUtils.isEmpty(userId)) { + return; + } + List browsingList = CollUtil.defaultIfEmpty(this.redisCache + .getCacheList(CacheConstants.USER_BROWSING_HISTORY + SecurityUtils.getUserId()), new ArrayList<>()); + browsingList.add(new UserBrowsingHisDTO().setUserId(userId).setProdArtNum(prodArtNum).setProdTitle(prodTitle) + .setStoreId(storeId).setStoreName(storeName).setProdPrice(minPrice).setMainPicUrl(mainPicUrl) + .setBrowsingTime(new Date()).setStoreProdId(storeProdId)); + this.redisCache.setCacheObject(CacheConstants.USER_BROWSING_HISTORY + SecurityUtils.getUserId(), browsingList); + } + + } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/UserBrowsingHistoryServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/UserBrowsingHistoryServiceImpl.java index f6687e1aa..0cf392039 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/UserBrowsingHistoryServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/UserBrowsingHistoryServiceImpl.java @@ -1,14 +1,22 @@ package com.ruoyi.xkt.service.impl; -import com.ruoyi.common.utils.DateUtils; -import com.ruoyi.xkt.domain.UserBrowsingHistory; -import com.ruoyi.xkt.mapper.UserBrowsingHistoryMapper; +import cn.hutool.core.bean.BeanUtil; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.page.Page; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.xkt.dto.userBrowsingHistory.UserBrowHisPageDTO; +import com.ruoyi.xkt.dto.userBrowsingHistory.UserBrowsingHisDTO; +import com.ruoyi.xkt.dto.userBrowsingHistory.UserBrowsingHisPageResDTO; import com.ruoyi.xkt.service.IUserBrowsingHistoryService; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.Comparator; import java.util.List; +import java.util.stream.Collectors; /** * 用户浏览历史Service业务层处理 @@ -17,9 +25,33 @@ import java.util.List; * @date 2025-03-26 */ @Service +@RequiredArgsConstructor public class UserBrowsingHistoryServiceImpl implements IUserBrowsingHistoryService { + final RedisCache redisCache; - + /** + * 查询用户浏览历史分页 + * + * @param pageDTO 查询入参 + * @return Page + */ + @Override + @Transactional(readOnly = true) + public Page page(UserBrowHisPageDTO pageDTO) { + // 从redis获取所有的浏览足迹 + List redisList = this.redisCache.getCacheObject(CacheConstants.USER_BROWSING_HISTORY + SecurityUtils.getUserId()); + if (CollectionUtils.isEmpty(redisList)) { + return Page.empty(pageDTO.getPageSize(), pageDTO.getPageNum()); + } + // 按照浏览时间倒序排 + redisList.sort(Comparator.comparing(UserBrowsingHisDTO::getBrowsingTime).reversed()); + List page = redisList.stream().sorted(Comparator.comparing(UserBrowsingHisDTO::getBrowsingTime).reversed()) + .skip((long) (pageDTO.getPageNum() - 1) * pageDTO.getPageSize()).limit(pageDTO.getPageSize()) + .map(x -> BeanUtil.toBean(x, UserBrowsingHisPageResDTO.class)) + .collect(Collectors.toList()); + final long pages = (long) Math.ceil((double) redisList.size() / pageDTO.getPageSize()); + return new Page<>(pageDTO.getPageNum(), pageDTO.getPageSize(), pages, redisList.size(), page); + } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/UserSearchHistoryServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/UserSearchHistoryServiceImpl.java new file mode 100644 index 000000000..ea81e4ce9 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/UserSearchHistoryServiceImpl.java @@ -0,0 +1,37 @@ +package com.ruoyi.xkt.service.impl; + +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.xkt.dto.useSearchHistory.UserSearchHistoryDTO; +import com.ruoyi.xkt.service.IUserSearchHistoryService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 用户浏览历史Service业务层处理 + * + * @author ruoyi + * @date 2025-03-26 + */ +@Service +@RequiredArgsConstructor +public class UserSearchHistoryServiceImpl implements IUserSearchHistoryService { + + final RedisCache redisCache; + + @Override + @Transactional(readOnly = true) + public List recordList() { + List redisList = this.redisCache.getCacheObject(CacheConstants.USER_SEARCH_HISTORY + SecurityUtils.getUserId()); + // 按照搜索时间倒序排列,最新的搜索数据展示在最前面 + return redisList.stream().sorted(Comparator.comparing(UserSearchHistoryDTO::getSearchTime).reversed()) + .map(UserSearchHistoryDTO::getSearchContent).collect(Collectors.toList()); + } + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsiteAPPServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsiteAPPServiceImpl.java index 42ae4ee6c..02acfc4c6 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsiteAPPServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsiteAPPServiceImpl.java @@ -116,7 +116,9 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { .setStoreName(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getStoreName() : "") .setProdPrice(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMinPrice().toString() : null) .setProdArtNum(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getProdArtNum() : "") - .setMainPicUrl(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicUrl() : ""); + .setMainPicUrl(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicUrl() : "") + .setMainPicName(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicName() : "") + .setMainPicSize(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicSize() : null); }).collect(Collectors.toList()); // 放到redis中 有效期1天 this.redisCache.setCacheObject(CacheConstants.APP_INDEX_HOT_SALE_ADVERT, hotSaleList, 1, TimeUnit.DAYS); @@ -170,7 +172,9 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { .setStoreName(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getStoreName() : "") .setProdPrice(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMinPrice().toString() : null) .setProdArtNum(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getProdArtNum() : "") - .setMainPicUrl(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicUrl() : ""); + .setMainPicUrl(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicUrl() : "") + .setMainPicName(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicName() : "") + .setMainPicSize(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicSize() : null); }).collect(Collectors.toList()); // 放到redis中 有效期1天 this.redisCache.setCacheObject(CacheConstants.APP_INDEX_POPULAR_SALE_ADVERT, popularSaleList, 1, TimeUnit.DAYS); @@ -224,7 +228,9 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { .setStoreName(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getStoreName() : "") .setProdPrice(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMinPrice().toString() : null) .setProdArtNum(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getProdArtNum() : "") - .setMainPicUrl(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicUrl() : ""); + .setMainPicUrl(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicUrl() : "") + .setMainPicName(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicName() : "") + .setMainPicSize(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicSize() : null); }).collect(Collectors.toList()); // 放到redis中 有效期1天 this.redisCache.setCacheObject(CacheConstants.APP_INDEX_NEW_PROD, newProdList, 1, TimeUnit.DAYS); @@ -245,7 +251,11 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { @Transactional(readOnly = true) public Page appSearchPage(IndexSearchDTO searchDTO) throws IOException { // 更新用户搜索历史 - updateRedisUserSearchHistory(searchDTO.getSearch()); + try { + updateRedisUserSearchHistory(searchDTO.getSearch()); + } catch (Exception e) { + e.printStackTrace(); + } // 用户搜索结果 Page page = this.search(searchDTO); // 筛选出真实的数据 @@ -281,7 +291,9 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { .setStoreName(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getStoreName() : "") .setProdPrice(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMinPrice().toString() : null) .setProdArtNum(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getProdArtNum() : "") - .setMainPicUrl(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicUrl() : ""); + .setMainPicUrl(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicUrl() : "") + .setMainPicName(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicName() : "") + .setMainPicSize(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicSize() : null); }).collect(Collectors.toList()); // 放到redis中 有效期1天 this.redisCache.setCacheObject(CacheConstants.APP_SEARCH, newProdList, 1, TimeUnit.DAYS); diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsitePCServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsitePCServiceImpl.java index 487e16ff7..4bc71351a 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsitePCServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsitePCServiceImpl.java @@ -144,6 +144,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { .setProdPrice(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMinPrice().toString() : null) .setProdArtNum(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getProdArtNum() : "") .setMainPicUrl(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicUrl() : "") + .setMainPicName(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicName() : "") + .setMainPicSize(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicSize() : null) .setTags(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getTags() : null)); }); }); @@ -218,6 +220,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { .setProdPrice(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMinPrice().toString() : null) .setProdArtNum(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getProdArtNum() : "") .setMainPicUrl(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicUrl() : "") + .setMainPicName(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicName() : "") + .setMainPicSize(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getMainPicSize() : null) .setTags(ObjectUtils.isNotEmpty(attrDto) ? attrDto.getTags() : null)); }); }); @@ -247,7 +251,11 @@ public class WebsitePCServiceImpl implements IWebsitePCService { @Transactional(readOnly = true) public Page psSearchPage(IndexSearchDTO searchDTO) throws IOException { // 更新用户搜索历史 - updateRedisUserSearchHistory(searchDTO.getSearch()); + try { + updateRedisUserSearchHistory(searchDTO.getSearch()); + } catch (Exception e) { + e.printStackTrace(); + } // 获取用户搜索结果列表 Page page = this.search(searchDTO); // 筛选出真实的数据 diff --git a/xkt/src/main/resources/mapper/StoreProductFileMapper.xml b/xkt/src/main/resources/mapper/StoreProductFileMapper.xml index a2a031f87..46ece7342 100644 --- a/xkt/src/main/resources/mapper/StoreProductFileMapper.xml +++ b/xkt/src/main/resources/mapper/StoreProductFileMapper.xml @@ -138,6 +138,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" spf.store_prod_id, spf.file_id, sf.file_url, + sf.file_name, + sf.file_size, spf.file_type, spf.order_num FROM diff --git a/xkt/src/main/resources/mapper/StoreProductMapper.xml b/xkt/src/main/resources/mapper/StoreProductMapper.xml index 93d598e01..445f2a9e9 100644 --- a/xkt/src/main/resources/mapper/StoreProductMapper.xml +++ b/xkt/src/main/resources/mapper/StoreProductMapper.xml @@ -114,6 +114,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" spc.parent_id AS parCateId, sp.prod_art_num AS prodArtNum, sf.file_url AS mainPicUrl, + sf.file_name AS mainPicName, + sf.file_size AS mainPicSize, sp.prod_title, MIN( spcp.price ) AS minPrice, sp.store_id, @@ -217,6 +219,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"