master:档口推荐列表功能;
parent
e7f333e21d
commit
ec869177b3
|
|
@ -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<Page<PCStoreRecommendDTO>> 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<List<PicSearchAdvertVO>> getPicSearchList() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public class StoreProdViewVO {
|
|||
@ApiModelProperty(value = "售价")
|
||||
private BigDecimal price;
|
||||
@ApiModelProperty(name = "商品标签列表")
|
||||
private List<String> prodTagList;
|
||||
private List<String> tags;
|
||||
@ApiModelProperty(value = "档口ID")
|
||||
private Long storeId;
|
||||
@ApiModelProperty(value = "档口名称")
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
@ -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";
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,12 +251,16 @@ public class Constants
|
|||
/**
|
||||
* APP 首页广告位置 插入广告的索引位置集合 获取精选热卖推广,将广告嵌入到列表中 每一页20条,5条广告嵌入到 3 7 11 15 19
|
||||
*/
|
||||
public static final Set<Integer> insertPositions = new HashSet<>(Arrays.asList(2, 6, 10, 14, 18));
|
||||
public static final Set<Integer> APP_INSERT_POSITIONS = new HashSet<>(Arrays.asList(2, 6, 10, 14, 18));
|
||||
/**
|
||||
* 以图搜款搜索结果,广告插入位置 5 9 13 17 20
|
||||
*/
|
||||
public static final Set<Integer> pic_res_insert_positions = new HashSet<>(Arrays.asList(4, 8, 12, 16, 19));
|
||||
public static final Set<Integer> PIC_SEARCH_INSERT_POSITIONS = new HashSet<>(Arrays.asList(4, 8, 12, 16, 19));
|
||||
|
||||
/**
|
||||
* 档口搜索结果,广告插入位置 2 9 18 27 36
|
||||
*/
|
||||
public static final Set<Integer> STORE_RECOMMEND_INSERT_POSITIONS = new HashSet<>(Arrays.asList(2, 9, 18, 27, 36));
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<StoreProduct> storeProdList = this.storeProdMapper.selectList(new LambdaQueryWrapper<StoreProduct>().eq(StoreProduct::getDelFlag, Constants.UNDELETED));
|
||||
if (CollectionUtils.isEmpty(storeProdList)) {
|
||||
return;
|
||||
}
|
||||
// 按照storeId 的维度,对档口权重 按照 recommendWeight 进行汇总,按照降序排列
|
||||
Map<Long, Long> storeWeightMap = storeProdList.stream().collect(Collectors.groupingBy(StoreProduct::getStoreId,
|
||||
Collectors.summingLong(x -> ObjectUtils.defaultIfNull(x.getRecommendWeight(), 0L))));
|
||||
// 筛选每个档口最新的4个商品及主图
|
||||
List<Store> storeList = this.storeMapper.selectList(new LambdaQueryWrapper<Store>().eq(Store::getDelFlag, Constants.UNDELETED));
|
||||
Map<Long, Store> storeMap = storeList.stream().collect(Collectors.toMap(Store::getId, Function.identity()));
|
||||
List<DailyStoreTag> storeTagList = this.dailyStoreTagMapper.selectList(new LambdaQueryWrapper<DailyStoreTag>()
|
||||
.eq(DailyStoreTag::getDelFlag, Constants.UNDELETED));
|
||||
// 档口标签map
|
||||
Map<Long, List<String>> 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<StoreProdFileLatestFourProdDTO> latest4ProdList = this.storeProdFileMapper.selectLatestFourProdList();
|
||||
Map<Long, List<StoreProdFileLatestFourProdDTO>> latestProdMap = latest4ProdList.stream().collect(Collectors
|
||||
.groupingBy(StoreProdFileLatestFourProdDTO::getStoreId));
|
||||
List<PCStoreRecommendTempDTO> 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<PCStoreRecommendDTO> recommendList = BeanUtil.copyToList(storeRecommendList, PCStoreRecommendDTO.class);
|
||||
// 放到redis中
|
||||
redisCache.setCacheObject(CacheConstants.PC_STORE_RECOMMEND_LIST, recommendList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时任务更新推广的播放轮次,这个要次日凌晨更新 凌晨12:01:00分更新
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ public class Store extends XktBaseEntity {
|
|||
/**
|
||||
* 档口权重值 基础值大家都为100,最低为-100。
|
||||
*/
|
||||
private Integer weight;
|
||||
private Long storeWeight;
|
||||
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ public class PCIndexMidStyleDTO {
|
|||
private List<PCIMSStyleDTO> styleList;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "风格榜列表")
|
||||
public static class PCIMSStyleDTO {
|
||||
@ApiModelProperty(value = "2商品")
|
||||
private Integer displayType;
|
||||
|
|
|
|||
|
|
@ -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<String> 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<PCSRNewProdDTO> prodList;
|
||||
|
||||
@Data
|
||||
public static class PCSRNewProdDTO {
|
||||
@ApiModelProperty(value = "档口商品ID")
|
||||
private Long storeProdId;
|
||||
@ApiModelProperty(value = "商品第一张主图路径")
|
||||
private String mainPicUrl;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<String> 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<PCSRNewProdDTO> prodList;
|
||||
|
||||
@Data
|
||||
public static class PCSRNewProdDTO {
|
||||
@ApiModelProperty(value = "档口商品ID")
|
||||
private Long storeProdId;
|
||||
@ApiModelProperty(value = "商品第一张主图路径")
|
||||
private String mainPicUrl;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ public class StoreProdViewDTO {
|
|||
@ApiModelProperty(value = "标签字符串")
|
||||
private String tagStr;
|
||||
@ApiModelProperty(name = "商品标签列表")
|
||||
private List<String> prodTagList;
|
||||
private List<String> tags;
|
||||
@ApiModelProperty(value = "档口ID")
|
||||
private Long storeId;
|
||||
@ApiModelProperty(value = "档口名称")
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
@ -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<StoreProductFile> {
|
|||
*/
|
||||
List<StoreProdFileResDTO> selectMainPic(@Param("storeProdIdList") List<String> storeProdIdList);
|
||||
|
||||
/**
|
||||
* 筛选档口最新的4个商品及主图
|
||||
* @return List<StoreProdFileLatestFourProdDTO>
|
||||
*/
|
||||
List<StoreProdFileLatestFourProdDTO> selectLatestFourProdList();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@ public interface IPictureSearchService {
|
|||
*
|
||||
* @return List<TopProductMatchDTO>
|
||||
*/
|
||||
List<TopProductMatchDTO> listImgSearchTopProduct();
|
||||
List<StoreProdViewDTO> listImgSearchTopProduct();
|
||||
|
||||
/**
|
||||
* 缓存图搜热款
|
||||
*/
|
||||
void cacheImgSearchTopProduct();
|
||||
List<StoreProdViewDTO> cacheImgSearchTopProduct();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<PCSearchDTO> psSearchPage(IndexSearchDTO searchDTO) throws IOException;
|
||||
|
||||
/**
|
||||
* PC 档口馆 档口列表
|
||||
*
|
||||
* @param searchDTO 搜索入参
|
||||
* @return Page<PCStoreRecommendDTO>
|
||||
*/
|
||||
Page<PCStoreRecommendDTO> pcStoreRecommendPage(StoreSearchDTO searchDTO);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<PicSearchAdvertDTO> 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<TopProductMatchDTO> listImgSearchTopProduct() {
|
||||
List<TopProductMatchDTO> topProductMatchList = redisCache.getCacheObject(CacheConstants.TOP_IMG_SEARCH_PRODUCT);
|
||||
if (CollectionUtils.isNotEmpty(topProductMatchList)) {
|
||||
return topProductMatchList;
|
||||
public List<StoreProdViewDTO> listImgSearchTopProduct() {
|
||||
List<StoreProdViewDTO> 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<StoreProdViewDTO> cacheImgSearchTopProduct() {
|
||||
//热搜规则(暂定):1个月内搜图次数排序,最多返回前100,查询同款商品时最多检索1000条数据
|
||||
List<ProductImgSearchCountDTO> 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<Long, Integer> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService {
|
|||
List<APPIndexHotSaleDTO> 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<AdvertRound> advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper<AdvertRound>()
|
||||
|
|
@ -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<APPIndexPopularSaleDTO> 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<AdvertRound> advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper<AdvertRound>()
|
||||
|
|
@ -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<APPIndexNewProdDTO> 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<AdvertRound> advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper<AdvertRound>()
|
||||
|
|
@ -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<APPSearchDTO> 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<AdvertRound> advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper<AdvertRound>()
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<PCStoreRecommendDTO>
|
||||
*/
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Page<PCStoreRecommendDTO> pcStoreRecommendPage(StoreSearchDTO searchDTO) {
|
||||
// 从redis中获取档口推荐列表
|
||||
List<PCStoreRecommendDTO> redisList = this.redisCache.getCacheObject(CacheConstants.PC_STORE_RECOMMEND_LIST);
|
||||
if (CollectionUtils.isEmpty(redisList)) {
|
||||
return Page.empty(searchDTO.getPageSize(), searchDTO.getPageNum());
|
||||
}
|
||||
// 正确的分页数据
|
||||
List<PCStoreRecommendDTO> 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<PCStoreRecommendDTO> 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<AdvertRound> advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper<AdvertRound>()
|
||||
.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<Store> storeList = this.storeMapper.selectList(new LambdaQueryWrapper<Store>()
|
||||
.in(Store::getId, advertRoundList.stream().map(AdvertRound::getStoreId).collect(Collectors.toList())));
|
||||
Map<Long, Store> storeMap = storeList.stream().collect(Collectors.toMap(Store::getId, Function.identity()));
|
||||
// 档口所有的标签
|
||||
List<DailyStoreTag> storeTagList = this.dailyStoreTagMapper.selectList(new LambdaQueryWrapper<DailyStoreTag>()
|
||||
.in(DailyStoreTag::getStoreId, advertRoundList.stream().map(AdvertRound::getStoreId).collect(Collectors.toList())));
|
||||
Map<Long, List<String>> storeTagMap = CollectionUtils.isEmpty(storeTagList) ? new ConcurrentHashMap<>()
|
||||
: storeTagList.stream().collect(Collectors.groupingBy(DailyStoreTag::getStoreId, Collectors.mapping(DailyStoreTag::getTag, Collectors.toList())));
|
||||
// 商品的主图map
|
||||
List<StoreProdPriceAndMainPicDTO> 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<Long, StoreProdPriceAndMainPicDTO> mainPicMap = mainPicList.stream().collect(Collectors.toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, x -> x));
|
||||
List<PCStoreRecommendDTO> 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<Long> 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<ESProductDTO> 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 <T> 数据类型
|
||||
* @return 合并后的列表
|
||||
*/
|
||||
public static <T> List<T> insertAdvertsIntoList(List<T> dataList, List<T> adverts, Set<Integer> positions) {
|
||||
List<T> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,5 +104,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</foreach>
|
||||
</select>
|
||||
|
||||
<select id="selectLatestFourProdList" resultType="com.ruoyi.xkt.dto.storeProductFile.StoreProdFileLatestFourProdDTO">
|
||||
WITH RankedProducts AS (
|
||||
SELECT
|
||||
spf.store_prod_id,
|
||||
spf.store_id,
|
||||
sf.file_url AS mainPicUrl,
|
||||
ROW_NUMBER() OVER ( PARTITION BY spf.store_id ORDER BY spf.create_time DESC ) AS rank_num
|
||||
FROM
|
||||
store_product_file spf
|
||||
LEFT JOIN store_product sp ON spf.store_prod_id = sp.id
|
||||
LEFT JOIN sys_file sf ON spf.file_id = sf.id
|
||||
LEFT JOIN store s ON spf.store_id = s.id
|
||||
WHERE
|
||||
spf.del_flag = 0
|
||||
AND spf.file_type = 1
|
||||
AND spf.order_num = 1
|
||||
) SELECT
|
||||
store_prod_id,
|
||||
store_id,
|
||||
mainPicUrl
|
||||
FROM
|
||||
RankedProducts
|
||||
WHERE
|
||||
rank_num <= 4
|
||||
ORDER BY
|
||||
store_id,
|
||||
rank_num
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue