From ec869177b36763f40bde185b678cdf36ef3c1755 Mon Sep 17 00:00:00 2001 From: liujiang <569804566@qq.com> Date: Fri, 30 May 2025 14:43:25 +0800 Subject: [PATCH] =?UTF-8?q?master=EF=BC=9A=E6=A1=A3=E5=8F=A3=E6=8E=A8?= =?UTF-8?q?=E8=8D=90=E5=88=97=E8=A1=A8=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/xkt/WebsiteController.java | 21 +++- .../web/controller/xkt/vo/BasePageVO.java | 4 +- .../xkt/vo/storeProd/StoreProdViewVO.java | 2 +- .../xkt/{ => vo}/website/IndexSearchVO.java | 2 +- .../xkt/vo/website/StoreSearchVO.java | 22 ++++ .../ruoyi/common/constant/CacheConstants.java | 10 +- .../com/ruoyi/common/constant/Constants.java | 8 +- .../java/com/ruoyi/common/enums/AdType.java | 4 +- .../controller/DailyTaskController.java | 8 +- .../java/com/ruoyi/quartz/task/XktTask.java | 55 ++++++++- .../main/java/com/ruoyi/xkt/domain/Store.java | 2 +- .../pc/index/PCIndexMidStyleDTO.java | 1 - .../pc/store/PCStoreRecommendDTO.java | 50 ++++++++ .../pc/store/PCStoreRecommendTempDTO.java | 53 ++++++++ .../dto/storeProduct/StoreProdViewDTO.java | 2 +- .../StoreProdFileLatestFourProdDTO.java | 25 ++++ .../ruoyi/xkt/dto/website/StoreSearchDTO.java | 23 ++++ .../xkt/mapper/StoreProductFileMapper.java | 7 ++ .../xkt/service/IPictureSearchService.java | 4 +- .../ruoyi/xkt/service/IWebsitePCService.java | 10 ++ .../impl/PictureSearchServiceImpl.java | 24 ++-- .../service/impl/WebsiteAPPServiceImpl.java | 16 +-- .../service/impl/WebsitePCServiceImpl.java | 113 +++++++++++++++++- .../mapper/StoreProductFileMapper.xml | 29 +++++ 24 files changed, 458 insertions(+), 37 deletions(-) rename ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/{ => vo}/website/IndexSearchVO.java (96%) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/website/StoreSearchVO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/store/PCStoreRecommendDTO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/store/PCStoreRecommendTempDTO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/storeProductFile/StoreProdFileLatestFourProdDTO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/website/StoreSearchDTO.java diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/WebsiteController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/WebsiteController.java index 2d9b3d600..927b9e4b3 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/WebsiteController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/WebsiteController.java @@ -16,7 +16,8 @@ import com.ruoyi.web.controller.xkt.vo.advertRound.pc.newProd.*; import com.ruoyi.web.controller.xkt.vo.advertRound.pc.store.PCStoreMidBannerVO; import com.ruoyi.web.controller.xkt.vo.advertRound.pc.store.PCStoreTopBannerVO; import com.ruoyi.web.controller.xkt.vo.advertRound.picSearch.PicSearchAdvertVO; -import com.ruoyi.web.controller.xkt.website.IndexSearchVO; +import com.ruoyi.web.controller.xkt.vo.website.IndexSearchVO; +import com.ruoyi.web.controller.xkt.vo.website.StoreSearchVO; import com.ruoyi.xkt.dto.advertRound.app.index.APPIndexHotSaleDTO; import com.ruoyi.xkt.dto.advertRound.app.index.APPIndexNewProdDTO; import com.ruoyi.xkt.dto.advertRound.app.index.APPIndexPopularSaleDTO; @@ -24,7 +25,9 @@ import com.ruoyi.xkt.dto.advertRound.app.index.APPSearchDTO; import com.ruoyi.xkt.dto.advertRound.pc.PCSearchDTO; import com.ruoyi.xkt.dto.advertRound.pc.index.PCIndexRecommendDTO; import com.ruoyi.xkt.dto.advertRound.pc.newProd.PCNewRecommendDTO; +import com.ruoyi.xkt.dto.advertRound.pc.store.PCStoreRecommendDTO; import com.ruoyi.xkt.dto.website.IndexSearchDTO; +import com.ruoyi.xkt.dto.website.StoreSearchDTO; import com.ruoyi.xkt.service.IWebsiteAPPService; import com.ruoyi.xkt.service.IWebsitePCService; import io.swagger.annotations.Api; @@ -48,6 +51,16 @@ import java.util.List; @RequestMapping("/rest/v1/website") public class WebsiteController extends XktBaseController { + + // TODO 查询先按照storeWeight倒排,之后再按照各种 权重 进行排序 + // TODO 查询先按照storeWeight倒排,之后再按照各种 权重 进行排序 + // TODO 查询先按照storeWeight倒排,之后再按照各种 权重 进行排序 + // TODO 查询先按照storeWeight倒排,之后再按照各种 权重 进行排序 + // TODO 查询先按照storeWeight倒排,之后再按照各种 权重 进行排序 + + + + final IWebsitePCService websitePCService; final IWebsiteAPPService websiteAPPService; @ApiOperation(value = "PC 首页 为你推荐", httpMethod = "POST", response = R.class) @@ -164,6 +177,12 @@ public class WebsiteController extends XktBaseController { return R.ok(BeanUtil.copyToList(websitePCService.getPcStoreMidBannerList(), PCStoreMidBannerVO.class)); } + @ApiOperation(value = "PC 档口馆 档口列表", httpMethod = "POST", response = R.class) + @PostMapping("/pc/store/recommend") + public R> pcStoreRecommendPage(@Validated @RequestBody StoreSearchVO searchVO) { + return R.ok(websitePCService.pcStoreRecommendPage(BeanUtil.toBean(searchVO, StoreSearchDTO.class))); + } + @ApiOperation(value = "以图搜款推广", httpMethod = "GET", response = R.class) @GetMapping("/pic-search") public R> getPicSearchList() { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/BasePageVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/BasePageVO.java index 421b7c9a4..5929e2d52 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/BasePageVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/BasePageVO.java @@ -17,9 +17,9 @@ public class BasePageVO { @NotNull(message = "pageNum不能为空") @ApiModelProperty(value = "pageNum", required = true) - private int pageNum; + private int pageNum = 1; @NotNull(message = "pageSize不能为空") @ApiModelProperty(value = "pageSize", required = true) - private int pageSize; + private int pageSize = 20; } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeProd/StoreProdViewVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeProd/StoreProdViewVO.java index 6a9db9b4c..66c1f0d45 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeProd/StoreProdViewVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeProd/StoreProdViewVO.java @@ -31,7 +31,7 @@ public class StoreProdViewVO { @ApiModelProperty(value = "售价") private BigDecimal price; @ApiModelProperty(name = "商品标签列表") - private List prodTagList; + private List tags; @ApiModelProperty(value = "档口ID") private Long storeId; @ApiModelProperty(value = "档口名称") diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/website/IndexSearchVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/website/IndexSearchVO.java similarity index 96% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/website/IndexSearchVO.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/website/IndexSearchVO.java index faca5f76c..dbf3f92a5 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/website/IndexSearchVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/website/IndexSearchVO.java @@ -1,4 +1,4 @@ -package com.ruoyi.web.controller.xkt.website; +package com.ruoyi.web.controller.xkt.vo.website; import co.elastic.clients.elasticsearch._types.SortOrder; import com.ruoyi.web.controller.xkt.vo.BasePageVO; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/website/StoreSearchVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/website/StoreSearchVO.java new file mode 100644 index 000000000..0966e48be --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/website/StoreSearchVO.java @@ -0,0 +1,22 @@ +package com.ruoyi.web.controller.xkt.vo.website; + +import com.ruoyi.web.controller.xkt.vo.BasePageVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@EqualsAndHashCode(callSuper = true) +@ApiModel("档口排行榜搜索") +@Data +public class StoreSearchVO extends BasePageVO { + + @ApiModelProperty(value = "档口名称") + private String storeName; + +} 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 77ad9ed9f..4c9542870 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 @@ -207,6 +207,14 @@ public class CacheConstants { /** * 图搜热款 */ - public static final String TOP_IMG_SEARCH_PRODUCT = "top_img_search_product"; + public static final String IMG_SEARCH_PRODUCT_HOT = "img_search_product_hot"; + /** + * 档口馆 档口推荐列表 + */ + public static final String PC_STORE_RECOMMEND_LIST = "pc_store_recommend_list"; + /** + * 档口馆 档口推荐广告 + */ + public static final String PC_STORE_RECOMMEND_ADVERT = "pc_store_recommend_advert"; } 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 f8944bae7..e2bd4fbd8 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 @@ -251,12 +251,16 @@ public class Constants /** * APP 首页广告位置 插入广告的索引位置集合 获取精选热卖推广,将广告嵌入到列表中 每一页20条,5条广告嵌入到 3 7 11 15 19 */ - public static final Set insertPositions = new HashSet<>(Arrays.asList(2, 6, 10, 14, 18)); + public static final Set APP_INSERT_POSITIONS = new HashSet<>(Arrays.asList(2, 6, 10, 14, 18)); /** * 以图搜款搜索结果,广告插入位置 5 9 13 17 20 */ - public static final Set pic_res_insert_positions = new HashSet<>(Arrays.asList(4, 8, 12, 16, 19)); + public static final Set PIC_SEARCH_INSERT_POSITIONS = new HashSet<>(Arrays.asList(4, 8, 12, 16, 19)); + /** + * 档口搜索结果,广告插入位置 2 9 18 27 36 + */ + public static final Set STORE_RECOMMEND_INSERT_POSITIONS = new HashSet<>(Arrays.asList(2, 9, 18, 27, 36)); } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/enums/AdType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/AdType.java index eba53eeda..6c8d68c02 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/enums/AdType.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/AdType.java @@ -7,6 +7,7 @@ import lombok.Getter; /** * 推广营销类型 + * * @author liujiang * @date 2025-04-02 23:42 */ @@ -69,6 +70,8 @@ public enum AdType { PC_STORE_TOP_BANNER(201, "档口馆顶部轮播图", "/url"), // 档口馆 横幅 PC_STORE_MID_BANNER(202, "档口馆横幅", "/url"), + // 档口馆 推荐档口 + PC_STORE_RECOMMEND(203, "档口馆推荐档口", "/url"), // 首页以图搜款框商品、以图搜款结果商品、点击以图搜款界面 @@ -105,7 +108,6 @@ public enum AdType { APP_USER_CENTER_GUESS_YOU_LIKE(602, "APP我的猜你喜欢", "/url"), - ; private final Integer value; diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailyTaskController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailyTaskController.java index 00683c2b6..19d0deb80 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailyTaskController.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailyTaskController.java @@ -66,6 +66,12 @@ public class DailyTaskController extends BaseController { return R.ok(); } + @PostMapping("/store-weight") + public R dailyStoreWeight(SysJob sysJob) { + task.dailyStoreWeight(); + return R.ok(); + } + @PostMapping("/advert-round") public R dailyRound(SysJob sysJob) throws ParseException { task.dailyAdvertRound(); @@ -79,7 +85,7 @@ public class DailyTaskController extends BaseController { } @PostMapping("/store-redis") - public R saveStoreToRedis(SysJob sysJob) throws ParseException { + public R saveStoreToRedis(SysJob sysJob) { task.saveStoreToRedis(); return R.ok(); } 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 2ad218baa..941c6d851 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 @@ -19,6 +19,8 @@ import com.ruoyi.framework.es.EsClientWrapper; import com.ruoyi.framework.notice.fs.FsNotice; import com.ruoyi.xkt.domain.*; import com.ruoyi.xkt.dto.account.WithdrawPrepareResult; +import com.ruoyi.xkt.dto.advertRound.pc.store.PCStoreRecommendDTO; +import com.ruoyi.xkt.dto.advertRound.pc.store.PCStoreRecommendTempDTO; import com.ruoyi.xkt.dto.dailySale.DailySaleCusDTO; import com.ruoyi.xkt.dto.dailySale.DailySaleDTO; import com.ruoyi.xkt.dto.dailySale.DailySaleProdDTO; @@ -26,6 +28,7 @@ import com.ruoyi.xkt.dto.dailySale.WeekCateSaleDTO; import com.ruoyi.xkt.dto.dailyStoreTag.DailyStoreTagDTO; 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.enums.*; import com.ruoyi.xkt.manager.PaymentManager; import com.ruoyi.xkt.mapper.*; @@ -89,6 +92,7 @@ public class XktTask { final IPictureSearchService pictureSearchService; final PictureSearchMapper pictureSearchMapper; final StoreProductStatisticsMapper storeProdStatMapper; + final StoreProductFileMapper storeProdFileMapper; /** * 定时任务上市季节年份 @@ -315,7 +319,7 @@ public class XktTask { /** - * 每日更新档口商品的各项权重数据 + * 每天凌晨1:00更新档口商品的各项权重数据 */ @Transactional public void dailyProdWeight() { @@ -354,6 +358,55 @@ public class XktTask { this.storeProdMapper.updateById(storeProdList); } + /** + * 每天凌晨1:10更新档口权重数据 + */ + @Transactional + public void dailyStoreWeight() { + List storeProdList = this.storeProdMapper.selectList(new LambdaQueryWrapper().eq(StoreProduct::getDelFlag, Constants.UNDELETED)); + if (CollectionUtils.isEmpty(storeProdList)) { + return; + } + // 按照storeId 的维度,对档口权重 按照 recommendWeight 进行汇总,按照降序排列 + Map storeWeightMap = storeProdList.stream().collect(Collectors.groupingBy(StoreProduct::getStoreId, + Collectors.summingLong(x -> ObjectUtils.defaultIfNull(x.getRecommendWeight(), 0L)))); + // 筛选每个档口最新的4个商品及主图 + List storeList = this.storeMapper.selectList(new LambdaQueryWrapper().eq(Store::getDelFlag, Constants.UNDELETED)); + Map storeMap = storeList.stream().collect(Collectors.toMap(Store::getId, Function.identity())); + List storeTagList = this.dailyStoreTagMapper.selectList(new LambdaQueryWrapper() + .eq(DailyStoreTag::getDelFlag, Constants.UNDELETED)); + // 档口标签map + Map> storeTagMap = storeTagList.stream().collect(Collectors + .groupingBy(DailyStoreTag::getStoreId, Collectors.collectingAndThen(Collectors.toList(), list -> list.stream() + .sorted(Comparator.comparing(DailyStoreTag::getType)).map(DailyStoreTag::getTag).collect(Collectors.toList())))); + List latest4ProdList = this.storeProdFileMapper.selectLatestFourProdList(); + Map> latestProdMap = latest4ProdList.stream().collect(Collectors + .groupingBy(StoreProdFileLatestFourProdDTO::getStoreId)); + List storeRecommendList = new ArrayList<>(); + storeWeightMap.forEach((storeId, recommendWeight) -> { + final Store store = storeMap.get(storeId); + storeRecommendList.add(new PCStoreRecommendTempDTO().setStoreId(storeId).setTags(storeTagMap.get(storeId)) + .setAdvert(Boolean.FALSE).setRecommendWeight(recommendWeight) + .setStoreWeight(ObjectUtils.isNotEmpty(store) ? store.getStoreWeight() : null) + .setStoreName(ObjectUtils.isNotEmpty(store) ? store.getStoreName() : "") + .setStoreAddress(ObjectUtils.isNotEmpty(store) ? store.getStoreAddress() : "") + .setContactPhone(ObjectUtils.isNotEmpty(store) ? store.getContactPhone() : "") + .setQqAccount(ObjectUtils.isNotEmpty(store) ? store.getQqAccount() : "") + .setWechatAccount(ObjectUtils.isNotEmpty(store) ? store.getWechatAccount() : "") + .setProdList(BeanUtil.copyToList(latestProdMap.get(storeId), PCStoreRecommendTempDTO.PCSRNewProdDTO.class))); + }); + if (CollectionUtils.isEmpty(storeRecommendList)) { + return; + } + // 先按照 档口权重 倒序排,再按照 推荐权重 倒序排 + storeRecommendList.sort(Comparator.comparing(PCStoreRecommendTempDTO::getStoreWeight, Comparator.nullsLast(Comparator.reverseOrder())) + .thenComparing(PCStoreRecommendTempDTO::getRecommendWeight, Comparator.nullsLast(Comparator.reverseOrder()))); + // 返回给前端的数据 不包含 storeWeight 和 storeRecommnedWeight + List recommendList = BeanUtil.copyToList(storeRecommendList, PCStoreRecommendDTO.class); + // 放到redis中 + redisCache.setCacheObject(CacheConstants.PC_STORE_RECOMMEND_LIST, recommendList); + } + /** * 定时任务更新推广的播放轮次,这个要次日凌晨更新 凌晨12:01:00分更新 */ diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/Store.java b/xkt/src/main/java/com/ruoyi/xkt/domain/Store.java index 934e049d4..b552e069c 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/Store.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/Store.java @@ -152,7 +152,7 @@ public class Store extends XktBaseEntity { /** * 档口权重值 基础值大家都为100,最低为-100。 */ - private Integer weight; + private Long storeWeight; @Override diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/index/PCIndexMidStyleDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/index/PCIndexMidStyleDTO.java index eaa827839..e0d812946 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/index/PCIndexMidStyleDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/index/PCIndexMidStyleDTO.java @@ -34,7 +34,6 @@ public class PCIndexMidStyleDTO { private List styleList; @Data - @ApiModel(value = "风格榜列表") public static class PCIMSStyleDTO { @ApiModelProperty(value = "2商品") private Integer displayType; diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/store/PCStoreRecommendDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/store/PCStoreRecommendDTO.java new file mode 100644 index 000000000..89b6c3a5e --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/store/PCStoreRecommendDTO.java @@ -0,0 +1,50 @@ +package com.ruoyi.xkt.dto.advertRound.pc.store; + +import com.fasterxml.jackson.annotation.JsonIgnore; +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("PC 档口馆 档口列表") +@Data +@Accessors(chain = true) +public class PCStoreRecommendDTO { + + @ApiModelProperty(value = "档口ID") + private Long storeId; + @ApiModelProperty(value = "档口名称") + private String storeName; + @ApiModelProperty(value = "会员等级") + private Integer memberLevel; + @ApiModelProperty(value = "档口标签") + private List tags; + @ApiModelProperty(value = "是否广告") + private Boolean advert; + @ApiModelProperty(value = "联系电话") + private String contactPhone; + @ApiModelProperty(value = "微信账号") + private String wechatAccount; + @ApiModelProperty(value = "QQ账号") + private String qqAccount; + @ApiModelProperty(value = "档口地址") + private String storeAddress; + @ApiModelProperty(value = "最新上新列表") + List prodList; + + @Data + public static class PCSRNewProdDTO { + @ApiModelProperty(value = "档口商品ID") + private Long storeProdId; + @ApiModelProperty(value = "商品第一张主图路径") + private String mainPicUrl; + } + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/store/PCStoreRecommendTempDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/store/PCStoreRecommendTempDTO.java new file mode 100644 index 000000000..f23f30b7f --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/pc/store/PCStoreRecommendTempDTO.java @@ -0,0 +1,53 @@ +package com.ruoyi.xkt.dto.advertRound.pc.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("PC 档口馆 档口列表") +@Data +@Accessors(chain = true) +public class PCStoreRecommendTempDTO { + + @ApiModelProperty(value = "档口ID") + private Long storeId; + @ApiModelProperty(value = "档口名称") + private String storeName; + @ApiModelProperty(value = "会员等级") + private Integer memberLevel; + @ApiModelProperty(value = "档口标签") + private List tags; + @ApiModelProperty(value = "是否广告") + private Boolean advert; + @ApiModelProperty(value = "联系电话") + private String contactPhone; + @ApiModelProperty(value = "微信账号") + private String wechatAccount; + @ApiModelProperty(value = "QQ账号") + private String qqAccount; + @ApiModelProperty(value = "档口地址") + private String storeAddress; + @ApiModelProperty(value = "推荐数值") + private Long recommendWeight; + @ApiModelProperty(value = "档口权重") + private Long storeWeight; + @ApiModelProperty(value = "最新上新列表") + List prodList; + + @Data + public static class PCSRNewProdDTO { + @ApiModelProperty(value = "档口商品ID") + private Long storeProdId; + @ApiModelProperty(value = "商品第一张主图路径") + private String mainPicUrl; + } + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdViewDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdViewDTO.java index f77c6931e..9269d5a18 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdViewDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdViewDTO.java @@ -36,7 +36,7 @@ public class StoreProdViewDTO { @ApiModelProperty(value = "标签字符串") private String tagStr; @ApiModelProperty(name = "商品标签列表") - private List prodTagList; + private List tags; @ApiModelProperty(value = "档口ID") private Long storeId; @ApiModelProperty(value = "档口名称") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/storeProductFile/StoreProdFileLatestFourProdDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProductFile/StoreProdFileLatestFourProdDTO.java new file mode 100644 index 000000000..e78bebad6 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProductFile/StoreProdFileLatestFourProdDTO.java @@ -0,0 +1,25 @@ +package com.ruoyi.xkt.dto.storeProductFile; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.RequiredArgsConstructor; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("筛选档口最新的4个商品") +@Data +@RequiredArgsConstructor +public class StoreProdFileLatestFourProdDTO { + + @ApiModelProperty(value = "档口ID") + private Long storeId; + @ApiModelProperty(value = "档口商品ID") + private Long storeProdId; + @ApiModelProperty(value = "主图url") + private String mainPicUrl; + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/website/StoreSearchDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/website/StoreSearchDTO.java new file mode 100644 index 000000000..e49b38efc --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/website/StoreSearchDTO.java @@ -0,0 +1,23 @@ +package com.ruoyi.xkt.dto.website; + +import co.elastic.clients.elasticsearch._types.SortOrder; +import com.ruoyi.xkt.dto.BasePageDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@EqualsAndHashCode(callSuper = true) +@ApiModel("档口排行榜搜索") +@Data +public class StoreSearchDTO extends BasePageDTO { + + @ApiModelProperty(value = "档口名称") + private String storeName; + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreProductFileMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreProductFileMapper.java index a1cb149f2..122ac5529 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreProductFileMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreProductFileMapper.java @@ -2,6 +2,7 @@ package com.ruoyi.xkt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.xkt.domain.StoreProductFile; +import com.ruoyi.xkt.dto.storeProductFile.StoreProdFileLatestFourProdDTO; import com.ruoyi.xkt.dto.storeProductFile.StoreProdFilePicSpaceResDTO; import com.ruoyi.xkt.dto.storeProductFile.StoreProdFileResDTO; import com.ruoyi.xkt.dto.storeProductFile.StoreProdMainPicDTO; @@ -71,4 +72,10 @@ public interface StoreProductFileMapper extends BaseMapper { */ List selectMainPic(@Param("storeProdIdList") List storeProdIdList); + /** + * 筛选档口最新的4个商品及主图 + * @return List + */ + List selectLatestFourProdList(); + } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IPictureSearchService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IPictureSearchService.java index 736949adb..4c341b9b3 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IPictureSearchService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IPictureSearchService.java @@ -26,10 +26,10 @@ public interface IPictureSearchService { * * @return List */ - List listImgSearchTopProduct(); + List listImgSearchTopProduct(); /** * 缓存图搜热款 */ - void cacheImgSearchTopProduct(); + List cacheImgSearchTopProduct(); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IWebsitePCService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IWebsitePCService.java index 84c910586..29d026f95 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IWebsitePCService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IWebsitePCService.java @@ -7,10 +7,12 @@ import com.ruoyi.xkt.dto.advertRound.pc.PCUserCenterDTO; import com.ruoyi.xkt.dto.advertRound.pc.index.*; import com.ruoyi.xkt.dto.advertRound.pc.newProd.*; import com.ruoyi.xkt.dto.advertRound.pc.store.PCStoreMidBannerDTO; +import com.ruoyi.xkt.dto.advertRound.pc.store.PCStoreRecommendDTO; import com.ruoyi.xkt.dto.advertRound.pc.store.PCStoreTopBannerDTO; import com.ruoyi.xkt.dto.advertRound.picSearch.PicSearchAdvertDTO; import com.ruoyi.xkt.dto.es.ESProductDTO; import com.ruoyi.xkt.dto.website.IndexSearchDTO; +import com.ruoyi.xkt.dto.website.StoreSearchDTO; import java.io.IOException; import java.util.List; @@ -187,4 +189,12 @@ public interface IWebsitePCService { */ Page psSearchPage(IndexSearchDTO searchDTO) throws IOException; + /** + * PC 档口馆 档口列表 + * + * @param searchDTO 搜索入参 + * @return Page + */ + Page pcStoreRecommendPage(StoreSearchDTO searchDTO); + } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/PictureSearchServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/PictureSearchServiceImpl.java index ef43cbfb7..7bc70af41 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/PictureSearchServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/PictureSearchServiceImpl.java @@ -91,11 +91,11 @@ public class PictureSearchServiceImpl implements IPictureSearchService { .map(ProductMatchDTO::getStoreProductId).distinct().collect(Collectors.toList()), java.sql.Date.valueOf(LocalDate.now()), java.sql.Date.valueOf(LocalDate.now().minusMonths(2))); // 设置商品标签 - storeProdViewAttrList.stream().filter(x -> StringUtils.isNotBlank(x.getTagStr())).forEach(x -> x.setProdTagList(StrUtil.split(x.getTagStr(), ","))); + storeProdViewAttrList.stream().filter(x -> StringUtils.isNotBlank(x.getTagStr())).forEach(x -> x.setTags(StrUtil.split(x.getTagStr(), ","))); // 以图搜款广告 List picSearchAdverts = websitePCService.getPicSearchList(); // 将广告插入到预定位置 - return insertAdvertsIntoList(storeProdViewAttrList, BeanUtil.copyToList(picSearchAdverts, StoreProdViewDTO.class), Constants.pic_res_insert_positions); + return insertAdvertsIntoList(storeProdViewAttrList, BeanUtil.copyToList(picSearchAdverts, StoreProdViewDTO.class), Constants.PIC_SEARCH_INSERT_POSITIONS); } /** @@ -104,24 +104,23 @@ public class PictureSearchServiceImpl implements IPictureSearchService { */ @Override @Transactional(readOnly = true) - public List listImgSearchTopProduct() { - List topProductMatchList = redisCache.getCacheObject(CacheConstants.TOP_IMG_SEARCH_PRODUCT); - if (CollectionUtils.isNotEmpty(topProductMatchList)) { - return topProductMatchList; + public List listImgSearchTopProduct() { + List picSearchHotList = redisCache.getCacheObject(CacheConstants.IMG_SEARCH_PRODUCT_HOT); + if (CollectionUtils.isNotEmpty(picSearchHotList)) { + return picSearchHotList; } // 重新缓存数据到redis - this.cacheImgSearchTopProduct(); - return redisCache.getCacheObject(CacheConstants.TOP_IMG_SEARCH_PRODUCT); + return this.cacheImgSearchTopProduct(); } @Override - public void cacheImgSearchTopProduct() { + public List cacheImgSearchTopProduct() { //热搜规则(暂定):1个月内搜图次数排序,最多返回前100,查询同款商品时最多检索1000条数据 List prodImgSearchCounts = storeProdStatisticsMapper - .listProdImgSearchCount(java.sql.Date.valueOf(LocalDate.now()), java.sql.Date.valueOf(LocalDate.now().minusMonths(1))); + .listProdImgSearchCount(java.sql.Date.valueOf(LocalDate.now().minusMonths(1)), java.sql.Date.valueOf(LocalDate.now())); if (CollUtil.isEmpty(prodImgSearchCounts)) { - return; + return new ArrayList<>(); } Map searchCountMap = prodImgSearchCounts.stream().collect(Collectors .toMap(ProductImgSearchCountDTO::getStoreProductId, ProductImgSearchCountDTO::getImgSearchCount)); @@ -136,7 +135,8 @@ public class PictureSearchServiceImpl implements IPictureSearchService { .sorted(Comparator.comparing(StoreProdViewDTO::getImgSearchCount).reversed()) .limit(100) .collect(Collectors.toList()); - redisCache.setCacheObject(CacheConstants.TOP_IMG_SEARCH_PRODUCT, storeProdViewAttrList); + redisCache.setCacheObject(CacheConstants.IMG_SEARCH_PRODUCT_HOT, storeProdViewAttrList); + return storeProdViewAttrList; } /** 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 5439d008c..4cc427d2b 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 @@ -89,7 +89,7 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { List redisList = this.redisCache.getCacheObject(CacheConstants.APP_INDEX_HOT_SALE_ADVERT); if (CollectionUtils.isNotEmpty(redisList)) { // 添加广告的数据 - return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, redisList, Constants.insertPositions)); + return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, redisList, Constants.APP_INSERT_POSITIONS)); } else { // 从数据库查首页精选热卖推广(精准搜索是否存在推广,不存在从已过期的数据中拉数据来凑数) List advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper() @@ -116,7 +116,7 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { // 放到redis中 有效期1天 this.redisCache.setCacheObject(CacheConstants.APP_INDEX_HOT_SALE_ADVERT, hotSaleList, 1, TimeUnit.DAYS); // 添加了广告的数据 - return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, hotSaleList, Constants.insertPositions)); + return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, hotSaleList, Constants.APP_INSERT_POSITIONS)); } } return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), realDataList); @@ -143,7 +143,7 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { List redisList = this.redisCache.getCacheObject(CacheConstants.APP_INDEX_POPULAR_SALE_ADVERT); if (CollectionUtils.isNotEmpty(redisList)) { // 添加广告的数据 - return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, redisList, Constants.insertPositions)); + return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, redisList, Constants.APP_INSERT_POSITIONS)); } else { // 从数据库查首页 人气爆品 推广(精准搜索是否存在推广,不存在从已过期的数据中拉数据来凑数) List advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper() @@ -170,7 +170,7 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { // 放到redis中 有效期1天 this.redisCache.setCacheObject( CacheConstants.APP_INDEX_POPULAR_SALE_ADVERT, popularSaleList, 1, TimeUnit.DAYS); // 添加了广告的数据 - return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, popularSaleList, Constants.insertPositions)); + return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, popularSaleList, Constants.APP_INSERT_POSITIONS)); } } return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), realDataList); @@ -197,7 +197,7 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { List redisList = this.redisCache.getCacheObject(CacheConstants.APP_INDEX_NEW_PROD); if (CollectionUtils.isNotEmpty(redisList)) { // 添加广告的数据 - return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, redisList, Constants.insertPositions)); + return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, redisList, Constants.APP_INSERT_POSITIONS)); } else { // 从数据库查首页 新品榜 推广(精准搜索是否存在推广,不存在从已过期的数据中拉数据来凑数) List advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper() @@ -224,7 +224,7 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { // 放到redis中 有效期1天 this.redisCache.setCacheObject(CacheConstants.APP_INDEX_NEW_PROD, newProdList, 1, TimeUnit.DAYS); // 添加了广告的数据 - return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, newProdList, Constants.insertPositions)); + return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, newProdList, Constants.APP_INSERT_POSITIONS)); } } return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), realDataList); @@ -251,7 +251,7 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { List redisList = this.redisCache.getCacheObject(CacheConstants.APP_SEARCH); if (CollectionUtils.isNotEmpty(redisList)) { // 添加广告的数据 - return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, redisList, Constants.insertPositions)); + return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, redisList, Constants.APP_INSERT_POSITIONS)); } else { // 从数据库查首页 新品榜 推广(精准搜索是否存在推广,不存在从已过期的数据中拉数据来凑数) List advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper() @@ -278,7 +278,7 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { // 放到redis中 有效期1天 this.redisCache.setCacheObject(CacheConstants.APP_SEARCH, newProdList, 1, TimeUnit.DAYS); // 添加了广告的数据 - return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, newProdList, Constants.insertPositions)); + return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), insertAdvertsIntoList(realDataList, newProdList, Constants.APP_INSERT_POSITIONS)); } } return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), realDataList); 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 f948e5b45..cffe02e8b 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 @@ -3,7 +3,6 @@ package com.ruoyi.xkt.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.StrUtil; import co.elastic.clients.elasticsearch._types.FieldValue; -import co.elastic.clients.elasticsearch._types.SortOrder; import co.elastic.clients.elasticsearch._types.query_dsl.*; import co.elastic.clients.elasticsearch.core.SearchResponse; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -24,6 +23,7 @@ import com.ruoyi.xkt.dto.advertRound.pc.PCUserCenterDTO; import com.ruoyi.xkt.dto.advertRound.pc.index.*; import com.ruoyi.xkt.dto.advertRound.pc.newProd.*; import com.ruoyi.xkt.dto.advertRound.pc.store.PCStoreMidBannerDTO; +import com.ruoyi.xkt.dto.advertRound.pc.store.PCStoreRecommendDTO; import com.ruoyi.xkt.dto.advertRound.pc.store.PCStoreTopBannerDTO; import com.ruoyi.xkt.dto.advertRound.picSearch.PicSearchAdvertDTO; import com.ruoyi.xkt.dto.dailySale.CateSaleRankDTO; @@ -34,6 +34,7 @@ import com.ruoyi.xkt.dto.storeProduct.StoreProdPriceAndMainPicDTO; import com.ruoyi.xkt.dto.storeProduct.StoreProdViewDTO; import com.ruoyi.xkt.dto.storeProductFile.StoreProdFileResDTO; import com.ruoyi.xkt.dto.website.IndexSearchDTO; +import com.ruoyi.xkt.dto.website.StoreSearchDTO; import com.ruoyi.xkt.enums.AdBiddingStatus; import com.ruoyi.xkt.enums.AdDisplayType; import com.ruoyi.xkt.enums.AdLaunchStatus; @@ -247,6 +248,86 @@ public class WebsitePCServiceImpl implements IWebsitePCService { return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), realDataList); } + /** + * PC 档口馆 档口列表 + * + * @param searchDTO 搜索入参 + * @return Page + */ + @Override + @Transactional(readOnly = true) + public Page pcStoreRecommendPage(StoreSearchDTO searchDTO) { + // 从redis中获取档口推荐列表 + List redisList = this.redisCache.getCacheObject(CacheConstants.PC_STORE_RECOMMEND_LIST); + if (CollectionUtils.isEmpty(redisList)) { + return Page.empty(searchDTO.getPageSize(), searchDTO.getPageNum()); + } + // 正确的分页数据 + List realDataList = redisList.stream() + .filter(x -> StringUtils.isEmpty(x.getStoreName()) || x.getStoreName().contains(searchDTO.getStoreName())) + .skip((long) (searchDTO.getPageNum() - 1) * searchDTO.getPageSize()) + .limit(searchDTO.getPageSize()).collect(Collectors.toList()); + final long pages = (long) Math.ceil((double) redisList.size() / searchDTO.getPageSize()); + // APP 只有第一页 有数据 其它页暂时没有广告 + if (searchDTO.getPageNum() > 1) { + return new Page<>(searchDTO.getPageNum(), searchDTO.getPageSize(), pages, redisList.size(), realDataList); + } + // 从redis中获取数据 + List redisAdvertList = this.redisCache.getCacheObject(CacheConstants.PC_STORE_RECOMMEND_ADVERT); + if (CollectionUtils.isNotEmpty(redisAdvertList)) { + // 添加广告的数据 + return new Page<>(searchDTO.getPageNum(), searchDTO.getPageSize(), pages, redisList.size(), + insertAdvertsIntoList(realDataList, redisAdvertList, Constants.STORE_RECOMMEND_INSERT_POSITIONS)); + } else { + // 从数据库查档口推荐列表 是否存在推广 + List advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper() + .isNotNull(AdvertRound::getStoreId).eq(AdvertRound::getDelFlag, Constants.UNDELETED) + .eq(AdvertRound::getTypeId, AdType.PC_STORE_RECOMMEND.getValue()) + .eq(AdvertRound::getLaunchStatus, AdLaunchStatus.LAUNCHING.getValue()) + .eq(AdvertRound::getBiddingStatus, AdBiddingStatus.BIDDING_SUCCESS.getValue())); + if (CollectionUtils.isNotEmpty(advertRoundList)) { + // 档口列表 + List storeList = this.storeMapper.selectList(new LambdaQueryWrapper() + .in(Store::getId, advertRoundList.stream().map(AdvertRound::getStoreId).collect(Collectors.toList()))); + Map storeMap = storeList.stream().collect(Collectors.toMap(Store::getId, Function.identity())); + // 档口所有的标签 + List storeTagList = this.dailyStoreTagMapper.selectList(new LambdaQueryWrapper() + .in(DailyStoreTag::getStoreId, advertRoundList.stream().map(AdvertRound::getStoreId).collect(Collectors.toList()))); + Map> storeTagMap = CollectionUtils.isEmpty(storeTagList) ? new ConcurrentHashMap<>() + : storeTagList.stream().collect(Collectors.groupingBy(DailyStoreTag::getStoreId, Collectors.mapping(DailyStoreTag::getTag, Collectors.toList()))); + // 商品的主图map + List mainPicList = this.storeProdMapper.selectPriceAndMainPicList(advertRoundList.stream().filter(x -> StringUtils.isNotBlank(x.getProdIdStr())) + .map(x -> x.getProdIdStr().split(",")).flatMap(Arrays::stream).map(Long::valueOf).distinct().collect(Collectors.toList())); + Map mainPicMap = mainPicList.stream().collect(Collectors.toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, x -> x)); + List storeRecommendList = new ArrayList<>(); + advertRoundList.stream().filter(x -> StringUtils.isNotBlank(x.getProdIdStr())).forEach(x -> { + Store store = storeMap.get(x.getStoreId()); + PCStoreRecommendDTO storeRecommend = new PCStoreRecommendDTO().setAdvert(Boolean.TRUE).setStoreId(x.getStoreId()) + .setStoreName(ObjectUtils.isNotEmpty(store) ? store.getStoreName() : "").setAdvert(Boolean.TRUE) + .setTags(storeTagMap.getOrDefault(x.getStoreId(), new ArrayList<>())) + .setContactPhone(ObjectUtils.isNotEmpty(store) ? store.getContactPhone() : "") + .setWechatAccount(ObjectUtils.isNotEmpty(store) ? store.getWechatAccount() : "") + .setQqAccount(ObjectUtils.isNotEmpty(store) ? store.getQqAccount() : "") + .setStoreAddress(ObjectUtils.isNotEmpty(store) ? store.getStoreAddress() : ""); + // 这里是一个档口上传多个档口商品,所以需要对prodIdStr的逗号进行分割 + List prodIdList = StrUtil.split(x.getProdIdStr(), ",").stream().map(Long::parseLong).collect(Collectors.toList()); + storeRecommend.setProdList(prodIdList.stream().map(storeProdId -> { + StoreProdPriceAndMainPicDTO mainPicDTO = mainPicMap.get(storeProdId); + return new PCStoreRecommendDTO.PCSRNewProdDTO().setStoreProdId(storeProdId) + .setMainPicUrl(ObjectUtils.isNotEmpty(mainPicDTO) ? mainPicDTO.getMainPicUrl() : ""); + }).collect(Collectors.toList())); + storeRecommendList.add(storeRecommend); + }); + // 放到redis中,过期时间为1天 + this.redisCache.setCacheObject(CacheConstants.PC_STORE_RECOMMEND_ADVERT, storeRecommendList, 1, TimeUnit.DAYS); + // 添加广告的数据 + return new Page<>(searchDTO.getPageNum(), searchDTO.getPageSize(), pages, redisList.size(), + insertAdvertsIntoList(realDataList, storeRecommendList, Constants.STORE_RECOMMEND_INSERT_POSITIONS)); + } + } + return new Page<>(searchDTO.getPageNum(), searchDTO.getPageSize(), pages, redisList.size(), realDataList); + } + /** * PC 首页 顶部左侧 轮播图 * @@ -1580,4 +1661,34 @@ public class WebsitePCServiceImpl implements IWebsitePCService { final List esProdList = resList.hits().hits().stream().map(x -> x.source().setStoreProdId(x.id())).collect(Collectors.toList()); return new Page<>(searchDTO.getPageNum(), searchDTO.getPageSize(), total / searchDTO.getPageSize() + 1, total, esProdList); } + + /** + * 在指定位置插入广告数据到列表中,若位置超出数据长度,则追加到列表末尾 + * + * @param dataList 原始数据列表 + * @param adverts 广告数据列表 + * @param positions 插入广告的位置集合 + * @param 数据类型 + * @return 合并后的列表 + */ + public static List insertAdvertsIntoList(List dataList, List adverts, Set positions) { + List mergedList = new ArrayList<>(dataList); // 先拷贝原始数据 + int advertIndex = 0; + // 遍历所有广告插入位置 + for (Integer position : positions) { + if (advertIndex >= adverts.size()) { + // 广告已经插完,结束循环 + break; + } + if (position >= 0 && position < mergedList.size()) { + // 插入位置合法,插入广告 + mergedList.add(position, adverts.get(advertIndex++)); + } else { + // 插入位置非法(大于等于当前列表长度),追加到末尾 + mergedList.add(adverts.get(advertIndex++)); + } + } + return mergedList; + } + } diff --git a/xkt/src/main/resources/mapper/StoreProductFileMapper.xml b/xkt/src/main/resources/mapper/StoreProductFileMapper.xml index c770bfdb0..4d634b9f9 100644 --- a/xkt/src/main/resources/mapper/StoreProductFileMapper.xml +++ b/xkt/src/main/resources/mapper/StoreProductFileMapper.xml @@ -104,5 +104,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + \ No newline at end of file