From 510b780ed58654e38d024cd79c161ac5e52efee3 Mon Sep 17 00:00:00 2001 From: liujiang <569804566@qq.com> Date: Sun, 25 May 2025 14:25:20 +0800 Subject: [PATCH] =?UTF-8?q?master=EF=BC=9A=E4=BB=A5=E5=9B=BE=E6=90=9C?= =?UTF-8?q?=E6=AC=BE=E5=8A=9F=E8=83=BD=E5=AE=8C=E5=96=84=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xkt/PictureSearchController.java | 41 +++- .../web/controller/xkt/StoreController.java | 27 ++- .../web/controller/xkt/WebsiteController.java | 6 +- .../xkt/vo/pictureSearch/PicSearchVO.java | 30 +++ .../xkt/vo/storeProd/StoreProdViewVO.java | 42 ++++ .../com/ruoyi/common/constant/Constants.java | 6 + .../web/service/SysLoginService.java | 2 +- .../com/ruoyi/xkt/domain/PictureSearch.java | 2 + .../java/com/ruoyi/xkt/domain/SysFile.java | 2 + .../picSearch/PicSearchAdvertDTO.java | 10 +- .../dto/picture/ProductImgSearchCountDTO.java | 2 +- .../xkt/dto/picture/SearchRequestDTO.java | 10 +- .../dto/storeProduct/StoreProdViewDTO.java | 47 +++++ .../ruoyi/xkt/mapper/StoreProductMapper.java | 21 ++ .../xkt/service/IPictureSearchService.java | 8 +- .../impl/PictureSearchServiceImpl.java | 140 ++++++++----- .../service/impl/WebsiteAPPServiceImpl.java | 39 +--- .../service/impl/WebsitePCServiceImpl.java | 191 +++++++++++------- .../xkt/service/impl/WebsiteServiceImpl.java | 4 +- .../resources/mapper/PictureSearchMapper.xml | 4 +- .../resources/mapper/StoreProductMapper.xml | 82 ++++++-- 21 files changed, 511 insertions(+), 205 deletions(-) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/pictureSearch/PicSearchVO.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeProd/StoreProdViewVO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdViewDTO.java diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/PictureSearchController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/PictureSearchController.java index 5f94bde20..fe8ccea96 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/PictureSearchController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/PictureSearchController.java @@ -1,18 +1,21 @@ package com.ruoyi.web.controller.xkt; -import com.ruoyi.common.annotation.Log; +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.TableDataInfo; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.poi.ExcelUtil; -import com.ruoyi.xkt.domain.PictureSearch; +import com.ruoyi.web.controller.xkt.vo.pictureSearch.PicSearchVO; +import com.ruoyi.web.controller.xkt.vo.storeProd.StoreProdViewVO; +import com.ruoyi.xkt.dto.picture.SearchRequestDTO; import com.ruoyi.xkt.service.IPictureSearchService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.*; +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; -import javax.servlet.http.HttpServletResponse; import java.util.List; /** @@ -21,10 +24,26 @@ import java.util.List; * @author ruoyi * @date 2025-03-26 */ +@Api(tags = "以图搜款") @RestController +@RequiredArgsConstructor @RequestMapping("/rest/v1/pic-search") public class PictureSearchController extends XktBaseController { - @Autowired - private IPictureSearchService pictureSearchService; + + final IPictureSearchService picSearchService; + + @ApiOperation(value = "电商卖家 以图搜款", httpMethod = "POST", response = R.class) + @PostMapping("") + public R> searchProductByPic(@Validated @RequestBody PicSearchVO searchVO) { + return R.ok(BeanUtil.copyToList(picSearchService + .searchProductByPic(BeanUtil.toBean(searchVO, SearchRequestDTO.class).setNum(20)), StoreProdViewVO.class)); + } + + @ApiOperation(value = "图搜热款列表", httpMethod = "POST", response = R.class) + @PostMapping("/hot") + public R> searchHotList() { + return R.ok(BeanUtil.copyToList(picSearchService.listImgSearchTopProduct(), StoreProdViewVO.class)); + } + } 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 240d0acf2..67252dd09 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 @@ -1,11 +1,13 @@ package com.ruoyi.web.controller.xkt; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.IdUtil; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.XktBaseController; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.page.Page; import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.framework.oss.OSSClientWrapper; import com.ruoyi.web.controller.xkt.vo.store.*; import com.ruoyi.xkt.dto.store.*; import com.ruoyi.xkt.service.IStoreService; @@ -14,6 +16,7 @@ import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -113,9 +116,27 @@ public class StoreController extends XktBaseController { } @ApiOperation(value = "获取档口首页 客户销售榜前10 ", httpMethod = "GET", response = R.class) - @GetMapping(value = "/index/sale-customer/top10") - public R> indexTop10SaleCustomer(@Validated @RequestBody StoreSaleCustomerTop10VO saleCusTop10VO) { - return R.ok(BeanUtil.copyToList(storeService.indexTop10SaleCustomer(BeanUtil.toBean(saleCusTop10VO, StoreSaleCustomerTop10DTO.class)), StoreIndexCusSaleTop10ResVO.class)); + @GetMapping(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)); + } + + final OSSClientWrapper ossClient; + + @GetMapping("/getKey") + public R getKey() { + return R.ok(ossClient.createStsCredentials()); + } + + @PostMapping("/upload") + public void test(@RequestParam("file") MultipartFile file) throws Exception { + final String uuid = IdUtil.randomUUID(); + ossClient.upload("advert/" + uuid + ".png", file.getInputStream()); + } + + @GetMapping("/getUrl/{key}/{expireTime}") + public R getUrl(@PathVariable("key") String key, @PathVariable("expireTime") Long expireTime) throws Exception { + return R.ok(ossClient.generateUrl(key, expireTime)); } } 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 b50a8d77e..d1f65a339 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 @@ -49,15 +49,15 @@ import java.util.List; @RequestMapping("/rest/v1/website") public class WebsiteController extends XktBaseController { - final IWebsiteService websiteService; +// final IWebsiteService websiteService; final IWebsitePCService websitePCService; final IWebsiteAPPService websiteAPPService; - @ApiOperation(value = "网站首页搜索", httpMethod = "POST", response = R.class) + /*@ApiOperation(value = "网站首页搜索", httpMethod = "POST", response = R.class) @PostMapping("/index/search") public R> page(@Validated @RequestBody IndexSearchVO searchVO) throws IOException { return R.ok(websiteService.search(BeanUtil.toBean(searchVO, IndexSearchDTO.class))); - } + }*/ @ApiOperation(value = "PC 首页 为你推荐", httpMethod = "POST", response = R.class) @PostMapping("/pc/index/recommend") diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/pictureSearch/PicSearchVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/pictureSearch/PicSearchVO.java new file mode 100644 index 000000000..da172f859 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/pictureSearch/PicSearchVO.java @@ -0,0 +1,30 @@ +package com.ruoyi.web.controller.xkt.vo.pictureSearch; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("以图搜款入参") +@Data +public class PicSearchVO { + + @NotBlank(message = "图片路径不能为空") + @ApiModelProperty(value = "以图搜款图片路径") + private String picKey; + @ApiModelProperty(value = "图片名称") + @NotBlank(message = "图片名称不能为空") + private String picName; + @ApiModelProperty(value = "图片大小 搜索的图片大小,不超过4M") + @NotNull(message = "图片大小不能为空") + private BigDecimal picSize; + +} 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 new file mode 100644 index 000000000..6a9db9b4c --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/storeProd/StoreProdViewVO.java @@ -0,0 +1,42 @@ +package com.ruoyi.web.controller.xkt.vo.storeProd; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("档口商品基本显示DTO") +@Data +public class StoreProdViewVO { + + @ApiModelProperty(value = "搜索次数") + private Long imgSearchCount; + @ApiModelProperty(value = "同款商品数量") + private Integer sameProdCount; + @ApiModelProperty(value = "商品ID") + private Long storeProdId; + @ApiModelProperty(value = "商品货号") + private String prodArtNum; + @ApiModelProperty(value = "商品第一张主图路径") + private String mainPicUrl; + @ApiModelProperty(name = "商品标题") + private String prodTitle; + @ApiModelProperty(value = "售价") + private BigDecimal price; + @ApiModelProperty(name = "商品标签列表") + private List prodTagList; + @ApiModelProperty(value = "档口ID") + private Long storeId; + @ApiModelProperty(value = "档口名称") + private String storeName; +// @ApiModelProperty(value = "档口标签列表") +// private List storeTagList; + +} 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 57760e4df..f8944bae7 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 @@ -252,5 +252,11 @@ 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)); + /** + * 以图搜款搜索结果,广告插入位置 5 9 13 17 20 + */ + public static final Set pic_res_insert_positions = new HashSet<>(Arrays.asList(4, 8, 12, 16, 19)); + + } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index 51ea8035d..18139b70c 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -65,7 +65,7 @@ public class SysLoginService { // 验证码校验 -// validateCaptcha(username, code, uuid); + validateCaptcha(username, code, uuid); // 登录前置校验 loginPreCheck(username, password); diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/PictureSearch.java b/xkt/src/main/java/com/ruoyi/xkt/domain/PictureSearch.java index 6493564a5..e65af17aa 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/PictureSearch.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/PictureSearch.java @@ -6,6 +6,7 @@ import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.core.domain.XktBaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -19,6 +20,7 @@ import java.util.Date; */ @EqualsAndHashCode(callSuper = true) @Data +@Accessors(chain = true) public class PictureSearch extends XktBaseEntity { private static final long serialVersionUID = 1L; diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/SysFile.java b/xkt/src/main/java/com/ruoyi/xkt/domain/SysFile.java index d137c0664..6ca02fffb 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/SysFile.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/SysFile.java @@ -5,6 +5,7 @@ import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.core.domain.XktBaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @@ -18,6 +19,7 @@ import java.math.BigDecimal; */ @EqualsAndHashCode(callSuper = true) @Data +@Accessors(chain = true) public class SysFile extends XktBaseEntity { private static final long serialVersionUID = 1L; diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/picSearch/PicSearchAdvertDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/picSearch/PicSearchAdvertDTO.java index fa4281bf4..5ecf88837 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/picSearch/PicSearchAdvertDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/picSearch/PicSearchAdvertDTO.java @@ -1,5 +1,6 @@ package com.ruoyi.xkt.dto.advertRound.picSearch; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -23,7 +24,7 @@ public class PicSearchAdvertDTO { @ApiModelProperty(value = "搜索次数") private Long imgSearchCount; @ApiModelProperty(value = "同款商品数量") - private Long sameProdCount; + private Integer sameProdCount; @ApiModelProperty(value = "商品ID") private Long storeProdId; @ApiModelProperty(value = "商品货号") @@ -34,13 +35,16 @@ public class PicSearchAdvertDTO { private String prodTitle; @ApiModelProperty(value = "售价") private BigDecimal price; + @ApiModelProperty(value = "标签字符串") + @JsonIgnore + private String tagStr; @ApiModelProperty(name = "商品标签列表") private List prodTagList; @ApiModelProperty(value = "档口ID") private Long storeId; @ApiModelProperty(value = "档口名称") private String storeName; - @ApiModelProperty(value = "档口标签列表") - private List storeTagList; +// @ApiModelProperty(value = "档口标签列表") +// private List storeTagList; } diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/picture/ProductImgSearchCountDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/picture/ProductImgSearchCountDTO.java index d0b678c5b..7894914c5 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/picture/ProductImgSearchCountDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/picture/ProductImgSearchCountDTO.java @@ -17,5 +17,5 @@ public class ProductImgSearchCountDTO implements Serializable { /** * 图搜次数 */ - private Long imgSearchCount; + private Integer imgSearchCount; } diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/picture/SearchRequestDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/picture/SearchRequestDTO.java index 4f4a28221..4678b1c3d 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/picture/SearchRequestDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/picture/SearchRequestDTO.java @@ -1,6 +1,7 @@ package com.ruoyi.xkt.dto.picture; import lombok.Data; +import lombok.experimental.Accessors; import java.math.BigDecimal; @@ -9,19 +10,20 @@ import java.math.BigDecimal; * @date 2025-05-21 */ @Data +@Accessors(chain = true) public class SearchRequestDTO { /** * 用于搜索的图片对应ossKey */ private String picKey; + /** + * 图搜的图片名称 + */ + private String picName; /** * 用于搜索的图片大小,不超过4M */ private BigDecimal picSize; - /** - * 用户ID - */ - private Long userId; /** * 期望返回条数 */ 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 new file mode 100644 index 000000000..f77c6931e --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdViewDTO.java @@ -0,0 +1,47 @@ +package com.ruoyi.xkt.dto.storeProduct; + +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.math.BigDecimal; +import java.util.List; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("档口商品基本显示DTO") +@Data +@Accessors(chain = true) +public class StoreProdViewDTO { + + @ApiModelProperty(value = "搜索次数") + private Integer imgSearchCount; + @ApiModelProperty(value = "同款商品数量") + private Integer sameProdCount; + @ApiModelProperty(value = "商品ID") + private Long storeProdId; + @ApiModelProperty(value = "商品货号") + private String prodArtNum; + @ApiModelProperty(value = "商品第一张主图路径") + private String mainPicUrl; + @ApiModelProperty(name = "商品标题") + private String prodTitle; + @ApiModelProperty(value = "售价") + private BigDecimal price; + @ApiModelProperty(value = "标签字符串") + private String tagStr; + @ApiModelProperty(name = "商品标签列表") + private List prodTagList; + @ApiModelProperty(value = "档口ID") + private Long storeId; + @ApiModelProperty(value = "档口名称") + private String storeName; +// @ApiModelProperty(value = "档口标签列表") +// private List storeTagList; + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreProductMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreProductMapper.java index afd1cbaed..88489165e 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreProductMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreProductMapper.java @@ -2,10 +2,12 @@ package com.ruoyi.xkt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.xkt.domain.StoreProduct; +import com.ruoyi.xkt.dto.advertRound.picSearch.PicSearchAdvertDTO; import com.ruoyi.xkt.dto.storeProduct.*; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; +import java.util.Date; import java.util.List; /** @@ -74,10 +76,29 @@ public interface StoreProductMapper extends BaseMapper { /** * 获取商品的价格主图及标签列表等 + * * @param storeProdIdList 档口商品ID列表 * @return List */ List selectPriceAndMainPicAndTagList(@Param("storeProdIdList") List storeProdIdList); + /** + * 获取商品展示的各种基本属性 + * + * @param storeProdIdList 档口商品ID列表 + * @return List + */ + List getStoreProdViewAttr(@Param("storeProdIdList") List storeProdIdList, + @Param("voucherDateStart") Date voucherDateStart, + @Param("voucherDateEnd") Date voucherDateEnd); + + /** + * 获取图搜热款时,商品的各种基本属性 + * + * @param storeProdIdList 档口商品ID列表 + * @return List + */ + List getSearchHotViewAttr(@Param("storeProdIdList") List storeProdIdList); + } 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 da6d89c55..736949adb 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IPictureSearchService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IPictureSearchService.java @@ -1,8 +1,8 @@ package com.ruoyi.xkt.service; -import com.ruoyi.xkt.dto.picture.ProductMatchDTO; import com.ruoyi.xkt.dto.picture.SearchRequestDTO; import com.ruoyi.xkt.dto.picture.TopProductMatchDTO; +import com.ruoyi.xkt.dto.storeProduct.StoreProdViewDTO; import java.util.List; @@ -17,14 +17,14 @@ public interface IPictureSearchService { * 图片搜索商品 * * @param requestDTO - * @return + * @return List */ - List searchProductByPic(SearchRequestDTO requestDTO); + List searchProductByPic(SearchRequestDTO requestDTO); /** * 图搜热款列表 * - * @return + * @return List */ List listImgSearchTopProduct(); 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 815ad23be..667d1bf3d 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 @@ -2,43 +2,41 @@ package com.ruoyi.xkt.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.collection.ListUtil; -import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.StrUtil; -import cn.hutool.json.JSONUtil; -import com.github.pagehelper.PageHelper; import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.xkt.domain.PictureSearch; import com.ruoyi.xkt.domain.SysFile; +import com.ruoyi.xkt.dto.advertRound.picSearch.PicSearchAdvertDTO; import com.ruoyi.xkt.dto.picture.ProductImgSearchCountDTO; import com.ruoyi.xkt.dto.picture.ProductMatchDTO; import com.ruoyi.xkt.dto.picture.SearchRequestDTO; import com.ruoyi.xkt.dto.picture.TopProductMatchDTO; -import com.ruoyi.xkt.dto.storeProductFile.StoreProdMainPicDTO; -import com.ruoyi.xkt.enums.FileType; +import com.ruoyi.xkt.dto.storeProduct.StoreProdViewDTO; import com.ruoyi.xkt.mapper.PictureSearchMapper; import com.ruoyi.xkt.mapper.StoreProductFileMapper; +import com.ruoyi.xkt.mapper.StoreProductMapper; import com.ruoyi.xkt.mapper.SysFileMapper; import com.ruoyi.xkt.service.IPictureSearchService; import com.ruoyi.xkt.service.IPictureService; +import com.ruoyi.xkt.service.IWebsitePCService; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.time.LocalDate; +import java.util.*; import java.util.stream.Collectors; -import static com.ruoyi.common.constant.Constants.ORDER_NUM_1; - /** * 以图搜款Service业务层处理 * @@ -58,22 +56,27 @@ public class PictureSearchServiceImpl implements IPictureSearchService { private IPictureService pictureService; @Autowired private RedisCache redisCache; + @Autowired + private IWebsitePCService websitePCService; + @Autowired + private StoreProductMapper storeProdMapper; @Transactional(rollbackFor = Exception.class) @Override - public List searchProductByPic(SearchRequestDTO requestDTO) { + public List searchProductByPic(SearchRequestDTO requestDTO) { + + // TODO 校验当前登录者角色,若非电商卖家 或 管理员 或 超级管理员,则不可操作 + // TODO 校验当前登录者角色,若非电商卖家 或 管理员 或 超级管理员,则不可操作 + // TODO 校验当前登录者角色,若非电商卖家 或 管理员 或 超级管理员,则不可操作 + Assert.notEmpty(requestDTO.getPicKey()); - SysFile sysFile = new SysFile(); - sysFile.setFileUrl(requestDTO.getPicKey()); - sysFile.setFileSize(requestDTO.getPicSize()); + SysFile sysFile = new SysFile().setFileUrl(requestDTO.getPicKey()).setFileName(requestDTO.getPicName()).setFileSize(requestDTO.getPicSize()); sysFile.setVersion(0); sysFile.setDelFlag(Constants.UNDELETED); sysFileMapper.insert(sysFile); - PictureSearch pictureSearch = new PictureSearch(); - pictureSearch.setSearchFileId(sysFile.getId()); - pictureSearch.setUserId(requestDTO.getUserId()); - pictureSearch.setVoucherDate(new Date()); + PictureSearch pictureSearch = new PictureSearch().setSearchFileId(sysFile.getId()).setUserId(SecurityUtils.getUserId()) + .setVoucherDate(java.sql.Date.valueOf(LocalDate.now())); pictureSearch.setVersion(0); pictureSearch.setDelFlag(Constants.UNDELETED); pictureSearchMapper.insert(pictureSearch); @@ -86,46 +89,89 @@ public class PictureSearchServiceImpl implements IPictureSearchService { redisCache.valueIncr(CacheConstants.PRODUCT_STATISTICS_IMG_SEARCH_COUNT, result.getStoreProductId()); } }); - return results; + // 档口商品显示的基本属性 + List storeProdViewAttrList = this.storeProdMapper.getStoreProdViewAttr(results.stream() + .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(), ","))); + // 以图搜款广告 + List picSearchAdverts = websitePCService.getPicSearchList(); + // 将广告插入到预定位置 + return insertAdvertsIntoList(storeProdViewAttrList, BeanUtil.copyToList(picSearchAdverts, StoreProdViewDTO.class), Constants.pic_res_insert_positions); } + /** + * 图搜热款列表 + * @return List + */ @Override + @Transactional(readOnly = true) public List listImgSearchTopProduct() { - String cacheStr = redisCache.getCacheObject(CacheConstants.TOP_IMG_SEARCH_PRODUCT); - if (StrUtil.isEmpty(cacheStr)) { - return ListUtil.empty(); + List topProductMatchList = redisCache.getCacheObject(CacheConstants.TOP_IMG_SEARCH_PRODUCT); + if (CollectionUtils.isNotEmpty(topProductMatchList)) { + return topProductMatchList; } - return JSONUtil.toList(cacheStr, TopProductMatchDTO.class); + // 重新缓存数据到redis + this.cacheImgSearchTopProduct(); + return redisCache.getCacheObject(CacheConstants.TOP_IMG_SEARCH_PRODUCT); } + @Override public void cacheImgSearchTopProduct() { - //热搜规则(暂定):1个月内搜图匹配次数前30的商品,查询同款商品时最多检索1000条数据 - Date end = DateUtil.date(); - Date begin = DateUtil.offset(end, DateField.MONTH, -1); - PageHelper.startPage(1, 30, false); - //统计表数据 + //热搜规则(暂定):1个月内搜图次数排序,最多返回前100,查询同款商品时最多检索1000条数据 List prodImgSearchCounts = pictureSearchMapper - .listProductImgSearchCount(DateUtil.beginOfDay(begin), end); + .listProductImgSearchCount(DateUtil.beginOfDay(java.sql.Date.valueOf(LocalDate.now())), java.sql.Date.valueOf(LocalDate.now().minusMonths(1))); if (CollUtil.isEmpty(prodImgSearchCounts)) { return; } - //产品主图 - List spIds = prodImgSearchCounts.stream().map(ProductImgSearchCountDTO::getStoreProductId) + Map searchCountMap = prodImgSearchCounts.stream().collect(Collectors + .toMap(ProductImgSearchCountDTO::getStoreProductId, ProductImgSearchCountDTO::getImgSearchCount)); + // 档口商品显示的基本属性 + List storeProdViewAttrList = this.storeProdMapper.getSearchHotViewAttr(prodImgSearchCounts.stream() + .map(ProductImgSearchCountDTO::getStoreProductId).distinct().collect(Collectors.toList())); + storeProdViewAttrList = storeProdViewAttrList.stream().map(x -> { + //根据主图搜索同类商品 + List pmList = pictureService.searchProductByPicKey(x.getMainPicUrl(), 1000); + return x.setSameProdCount(pmList.size()).setImgSearchCount(ObjectUtils.defaultIfNull(searchCountMap.get(x.getStoreProdId()), 0)); + }) + .sorted(Comparator.comparing(StoreProdViewDTO::getImgSearchCount).reversed()) + .limit(100) .collect(Collectors.toList()); - Map mainPicMap = storeProductFileMapper.selectMainPicByStoreProdIdList(spIds, - FileType.MAIN_PIC.getValue(), ORDER_NUM_1).stream() - .collect(Collectors.toMap(StoreProdMainPicDTO::getStoreProdId, StoreProdMainPicDTO::getFileUrl, - (o, n) -> n)); - List topProductMatchList = new ArrayList<>(prodImgSearchCounts.size()); - for (ProductImgSearchCountDTO prodImgSearchCount : prodImgSearchCounts) { - TopProductMatchDTO topProductMatch = BeanUtil.toBean(prodImgSearchCount, TopProductMatchDTO.class); - //根据主图搜索同类商品 - List pmList = pictureService.searchProductByPicKey(mainPicMap - .get(prodImgSearchCount.getStoreProductId()), 1000); - topProductMatch.setSameProductCount(pmList.size()); - topProductMatchList.add(topProductMatch); - } - redisCache.setCacheObject(CacheConstants.TOP_IMG_SEARCH_PRODUCT, JSONUtil.toJsonStr(topProductMatchList)); + redisCache.setCacheObject(CacheConstants.TOP_IMG_SEARCH_PRODUCT, storeProdViewAttrList); } + + /** + * 在指定位置插入广告数据到列表中,若位置超出数据长度,则追加到列表末尾 + * + * @param dataList 原始数据列表 + * @param adverts 广告数据列表 + * @param positions 插入广告的位置集合 + * @param 数据类型 + * @return 合并后的列表 + */ + public static List insertAdvertsIntoList(List dataList, List adverts, Set positions) { + if (CollectionUtils.isEmpty(adverts)) { + return dataList; + } + List mergedList = new ArrayList<>(); + int dataIndex = 0; + int advertIndex = 0; + int size = dataList.size(); + for (int i = 0; i < size + positions.size(); i++) { + if (positions.contains(i) && advertIndex < adverts.size()) { + // 如果当前位置需要插入广告,并且还有广告可插入 + mergedList.add(adverts.get(advertIndex++)); + } else if (dataIndex < size) { + // 插入原始数据 + mergedList.add(dataList.get(dataIndex++)); + } else { + // 源数据已经插完,但仍有广告未插入,直接追加到末尾 + mergedList.add(adverts.get(advertIndex++)); + } + } + return mergedList; + } + } 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 5f9fe4f0d..bfad9508a 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 @@ -15,12 +15,10 @@ import com.ruoyi.common.utils.DateUtils; import com.ruoyi.framework.es.EsClientWrapper; import com.ruoyi.xkt.domain.AdvertRound; import com.ruoyi.xkt.domain.DailyProdTag; -import com.ruoyi.xkt.domain.Store; import com.ruoyi.xkt.domain.SysFile; import com.ruoyi.xkt.dto.advertRound.app.category.APPCateDTO; import com.ruoyi.xkt.dto.advertRound.app.index.*; import com.ruoyi.xkt.dto.advertRound.app.own.APPOwnGuessLikeDTO; -import com.ruoyi.xkt.dto.advertRound.picSearch.PicSearchAdvertDTO; import com.ruoyi.xkt.dto.es.ESProductDTO; import com.ruoyi.xkt.dto.storeProduct.StoreProdPriceAndMainPicAndTagDTO; import com.ruoyi.xkt.dto.storeProduct.StoreProdPriceAndMainPicDTO; @@ -631,40 +629,6 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { return appOwnGuessLikeList; } - /** - * 获取以图搜款的广告 - * - * @param picSearchList 图搜热款数据库数据 - * @param prodSearchCountMap 商品搜索次数 - * @param storeMap 档口map - * @param prodPriceAndMainPicMap 档口商品价格及主图map - * @param prodTagMap 商品标签map - * @param storeTagMap 档口标签map - * @return List - */ - private List getPicSearchAdvertList(List picSearchList, Map prodSearchCountMap, Map storeMap, - Map prodPriceAndMainPicMap, Map> prodTagMap, - Map> storeTagMap) { - return picSearchList.stream().map(advertRound -> { - - // TODO 查询同款商品数量 - // TODO 查询同款商品数量 - // TODO 查询同款商品数量 - - final Long storeProdId = Long.valueOf(advertRound.getProdIdStr()); - return new PicSearchAdvertDTO().setImgSearchCount(ObjectUtils.defaultIfNull(prodSearchCountMap.get(storeProdId), (long) (new Random().nextInt(191) + 10))) - .setSameProdCount(null).setStoreProdId(storeProdId).setStoreId(advertRound.getStoreId()) - .setStoreName(ObjectUtils.isNotEmpty(storeMap.get(advertRound.getStoreId())) ? storeMap.get(advertRound.getStoreId()).getStoreName() : "") - .setPrice(ObjectUtils.isNotEmpty(prodPriceAndMainPicMap.get(storeProdId)) ? prodPriceAndMainPicMap.get(storeProdId).getMinPrice() : null) - .setProdArtNum(ObjectUtils.isNotEmpty(prodPriceAndMainPicMap.get(storeProdId)) ? prodPriceAndMainPicMap.get(storeProdId).getProdArtNum() : "") - .setMainPicUrl(ObjectUtils.isNotEmpty(prodPriceAndMainPicMap.get(storeProdId)) ? prodPriceAndMainPicMap.get(storeProdId).getMainPicUrl() : "") - .setProdTitle(ObjectUtils.isNotEmpty(prodPriceAndMainPicMap.get(storeProdId)) ? prodPriceAndMainPicMap.get(storeProdId).getProdTitle() : "") - .setProdTagList(CollectionUtils.isNotEmpty(prodTagMap.get(storeProdId)) ? prodTagMap.get(storeProdId) : null) - .setStoreTagList(CollectionUtils.isNotEmpty(storeTagMap.get(advertRound.getStoreId())) ? storeTagMap.get(advertRound.getStoreId()) : null); - }).limit(10).collect(Collectors.toList()); - } - - /** * 获取近一月档口推广数据 * @@ -710,6 +674,9 @@ public class WebsiteAPPServiceImpl implements IWebsiteAPPService { * @return 合并后的列表 */ public static List insertAdvertsIntoList(List dataList, List adverts, Set positions) { + if (CollectionUtils.isEmpty(adverts)) { + return dataList; + } List mergedList = new ArrayList<>(); int dataIndex = 0; int advertIndex = 0; 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 cb31ca4c6..3e33bb099 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 @@ -1,6 +1,7 @@ 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.*; @@ -13,7 +14,10 @@ import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.enums.AdType; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.framework.es.EsClientWrapper; -import com.ruoyi.xkt.domain.*; +import com.ruoyi.xkt.domain.AdvertRound; +import com.ruoyi.xkt.domain.DailyStoreTag; +import com.ruoyi.xkt.domain.Store; +import com.ruoyi.xkt.domain.SysFile; import com.ruoyi.xkt.dto.advertRound.pc.PCDownloadDTO; import com.ruoyi.xkt.dto.advertRound.pc.PCSearchDTO; import com.ruoyi.xkt.dto.advertRound.pc.PCUserCenterDTO; @@ -24,13 +28,17 @@ import com.ruoyi.xkt.dto.advertRound.pc.store.PCStoreTopBannerDTO; import com.ruoyi.xkt.dto.advertRound.picSearch.PicSearchAdvertDTO; import com.ruoyi.xkt.dto.dailySale.CateSaleRankDTO; import com.ruoyi.xkt.dto.es.ESProductDTO; +import com.ruoyi.xkt.dto.picture.ProductMatchDTO; import com.ruoyi.xkt.dto.storeProduct.StoreProdPriceAndMainPicAndTagDTO; 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.enums.AdBiddingStatus; import com.ruoyi.xkt.enums.AdDisplayType; import com.ruoyi.xkt.enums.AdLaunchStatus; import com.ruoyi.xkt.mapper.*; +import com.ruoyi.xkt.service.IPictureService; import com.ruoyi.xkt.service.IWebsitePCService; import lombok.RequiredArgsConstructor; import org.apache.commons.collections4.CollectionUtils; @@ -48,6 +56,8 @@ import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; +import static com.ruoyi.common.constant.Constants.IMG_SEARCH_MAX_PAGE_NUM; + /** * 首页搜索 * @@ -70,6 +80,7 @@ public class WebsitePCServiceImpl implements IWebsitePCService { final DailyStoreTagMapper dailyStoreTagMapper; final StoreMapper storeMapper; final StoreProductStatisticsMapper prodStatsMapper; + final IPictureService pictureService; /** * PC 首页 为你推荐 @@ -100,11 +111,12 @@ public class WebsitePCServiceImpl implements IWebsitePCService { // 添加广告的数据(PC的规则是将所有的广告数据全部放到最前面展示,不用给广告打标) return new Page<>(page.getPageNum(), page.getPageSize(), page.getPages(), page.getTotal(), redisList); } else { - // 从数据库查首页 推荐商品 推广(精准搜索是否存在推广,不存在从已过期的数据中拉数据来凑数) + // 从数据库查首页 推荐商品 推广(精准搜索是否存在推广,不存在从已过期的数据中拉数据来凑数)而且必须是 竞价成功的推广(有可能当天有新的竞价推广还未正式审核通过) List advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper() .isNotNull(AdvertRound::getStoreId).eq(AdvertRound::getDelFlag, Constants.UNDELETED) .eq(AdvertRound::getTypeId, AdType.PC_HOME_PRODUCT_LIST.getValue()) - .eq(AdvertRound::getLaunchStatus, AdLaunchStatus.LAUNCHING.getValue())); + .eq(AdvertRound::getLaunchStatus, AdLaunchStatus.LAUNCHING.getValue()) + .eq(AdvertRound::getBiddingStatus, AdBiddingStatus.BIDDING_SUCCESS.getValue())); if (CollectionUtils.isNotEmpty(advertRoundList)) { List attrList = storeProdMapper.selectPriceAndMainPicAndTagList(advertRoundList.stream() .map(x -> x.getProdIdStr().split(",")).flatMap(Arrays::stream).map(Long::valueOf).collect(Collectors.toList())); @@ -113,7 +125,7 @@ public class WebsitePCServiceImpl implements IWebsitePCService { List indexRecommendList = new ArrayList<>(); advertRoundList.forEach(x -> { // 这里是一个档口上传多个档口商品,所以需要对prodIdStr的逗号进行分割 - List prodIdList = Arrays.stream(x.getProdIdStr().split(",")).map(Long::parseLong).collect(Collectors.toList()); + List prodIdList = StrUtil.split(x.getProdIdStr(), ",").stream().map(Long::parseLong).collect(Collectors.toList()); prodIdList.forEach(storeProdId -> { StoreProdPriceAndMainPicAndTagDTO attrDto = attrMap.get(storeProdId); indexRecommendList.add(new PCIndexRecommendDTO().setAdvert(Boolean.TRUE).setStoreId(x.getStoreId().toString()) @@ -173,7 +185,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { List advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper() .isNotNull(AdvertRound::getStoreId).eq(AdvertRound::getDelFlag, Constants.UNDELETED) .eq(AdvertRound::getTypeId, AdType.PC_NEW_PROD_PRODUCT_LIST.getValue()) - .eq(AdvertRound::getLaunchStatus, AdLaunchStatus.LAUNCHING.getValue())); + .eq(AdvertRound::getLaunchStatus, AdLaunchStatus.LAUNCHING.getValue()) + .eq(AdvertRound::getBiddingStatus, AdBiddingStatus.BIDDING_SUCCESS.getValue())); if (CollectionUtils.isNotEmpty(advertRoundList)) { List attrList = storeProdMapper.selectPriceAndMainPicAndTagList(advertRoundList.stream() .map(x -> x.getProdIdStr().split(",")).flatMap(Arrays::stream).map(Long::valueOf).collect(Collectors.toList())); @@ -349,7 +362,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { .in(SysFile::getId, oneMonthList.stream().map(AdvertRound::getPicId).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList()))) .stream().collect(Collectors.toMap(SysFile::getId, Function.identity())); // 正在播放 - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); // 已过期 List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); List topLeftList; @@ -399,7 +413,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { List mainPicList = this.prodFileMapper.selectMainPic(oneMonthList.stream().map(AdvertRound::getProdIdStr).collect(Collectors.toList())); Map mainPicMap = mainPicList.stream().collect(Collectors.toMap(StoreProdFileResDTO::getStoreProdId, StoreProdFileResDTO::getFileUrl)); // 正在播放 - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); // 已过期 List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); List topRightList; @@ -514,7 +529,9 @@ public class WebsitePCServiceImpl implements IWebsitePCService { Map prodPriceAndMainPicMap = prodPriceAndMainPicList.stream().collect(Collectors .toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, Function.identity())); // 正在播放 - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + // 必须是竞价成功的推广 + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); // 已过期 List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); List midStyleList; @@ -567,20 +584,22 @@ public class WebsitePCServiceImpl implements IWebsitePCService { // 档口商品的价格及商品主图map Map prodPriceAndMainPicMap = prodPriceAndMainPicList.stream().collect(Collectors .toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, Function.identity())); - // 左侧广告 List leftLaunchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getTypeId(), AdType.PC_HOME_POP_LEFT_BANNER.getValue())) - .filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + .filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); List leftExpiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getTypeId(), AdType.PC_HOME_POP_LEFT_BANNER.getValue())) .filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); // 中部广告 List midLaunchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getTypeId(), AdType.PC_HOME_POP_MID.getValue())) - .filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + .filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); List midExpiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getTypeId(), AdType.PC_HOME_POP_MID.getValue())) .filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); // 右侧广告 List rightLaunchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getTypeId(), AdType.PC_HOME_POP_RIGHT.getValue())) - .filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + .filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); List rightExpiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getTypeId(), AdType.PC_HOME_POP_RIGHT.getValue())) .filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); @@ -681,7 +700,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { .in(SysFile::getId, oneMonthList.stream().map(AdvertRound::getPicId).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList()))) .stream().collect(Collectors.toMap(SysFile::getId, Function.identity())); // 正在播放 - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); // 已过期 List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(launchingList)) { @@ -723,7 +743,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { .eq(Store::getId, oneMonthList.stream().map(AdvertRound::getStoreId).collect(Collectors.toList()))) .stream().collect(Collectors.toMap(Store::getId, Function.identity())); // 正在播放 - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); // 已过期 List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(launchingList)) { @@ -768,7 +789,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { Map prodPriceAndMainPicMap = prodPriceAndMainPicList.stream().collect(Collectors .toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, Function.identity())); // 正在播放 - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); // 已过期 List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(launchingList)) { @@ -822,7 +844,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { .in(SysFile::getId, oneMonthList.stream().map(AdvertRound::getPicId).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList()))) .stream().collect(Collectors.toMap(SysFile::getId, Function.identity())); // 正在播放 - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); // 已过期 List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(launchingList)) { @@ -871,7 +894,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { .in(SysFile::getId, oneMonthList.stream().map(AdvertRound::getPicId).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList()))) .stream().collect(Collectors.toMap(SysFile::getId, Function.identity())); // 正在播放 - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); // 已过期 List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(launchingList)) { @@ -914,7 +938,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { .in(SysFile::getId, oneMonthList.stream().map(AdvertRound::getPicId).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList()))) .stream().collect(Collectors.toMap(SysFile::getId, Function.identity())); // 正在播放 - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); // 已过期 List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(launchingList)) { @@ -962,7 +987,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { .in(SysFile::getId, oneMonthList.stream().map(AdvertRound::getPicId).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList()))) .stream().collect(Collectors.toMap(SysFile::getId, Function.identity())); // 正在播放 - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); // 已过期 List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(launchingList)) { @@ -1007,7 +1033,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { return new ArrayList<>(); } // 正在播放 - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); // 已过期 List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); List prodPriceAndMainPicList = this.storeProdMapper.selectPriceAndMainPicList(oneMonthList.stream() @@ -1064,7 +1091,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { return new ArrayList<>(); } // 正在播放 - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); // 已过期 List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); // 文件map @@ -1112,7 +1140,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { if (CollectionUtils.isEmpty(oneMonthList)) { return new ArrayList<>(); } - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); Map fileMap = fileMapper.selectList(new LambdaQueryWrapper().eq(SysFile::getDelFlag, Constants.UNDELETED) .in(SysFile::getId, oneMonthList.stream().map(AdvertRound::getPicId).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList()))) @@ -1160,7 +1189,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { if (CollectionUtils.isEmpty(oneMonthList)) { return new ArrayList<>(); } - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); Map fileMap = fileMapper.selectList(new LambdaQueryWrapper().eq(SysFile::getDelFlag, Constants.UNDELETED) .in(SysFile::getId, oneMonthList.stream().map(AdvertRound::getPicId).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList()))) @@ -1206,38 +1236,23 @@ public class WebsitePCServiceImpl implements IWebsitePCService { if (CollectionUtils.isEmpty(oneMonthList)) { return new ArrayList<>(); } - // 获取近2个月 该商品的搜索次数 - List prodStatsList = this.prodStatsMapper.selectList(new LambdaQueryWrapper() - .eq(StoreProductStatistics::getDelFlag, Constants.UNDELETED) - .in(StoreProductStatistics::getStoreProdId, oneMonthList.stream().map(AdvertRound::getProdIdStr).map(Long::parseLong).collect(Collectors.toList())) - .between(StoreProductStatistics::getVoucherDate, java.sql.Date.valueOf(LocalDate.now().minusMonths(2)), java.sql.Date.valueOf(LocalDate.now()))); - // 商品搜索次数map - Map prodSearchCountMap = prodStatsList.stream().collect(Collectors.groupingBy(StoreProductStatistics::getStoreProdId, Collectors - .summingLong(StoreProductStatistics::getImgSearchCount))); - List storeList = this.storeMapper.selectByIds(oneMonthList.stream().map(AdvertRound::getStoreId).collect(Collectors.toList())); - Map storeMap = storeList.stream().collect(Collectors.toMap(Store::getId, Function.identity())); List storeProdIdList = oneMonthList.stream().map(AdvertRound::getProdIdStr).map(Long::parseLong).collect(Collectors.toList()); - // 获取所有商品的价格及第一张主图 - List prodPriceAndMainPicList = this.storeProdMapper.selectPriceAndMainPicList(storeProdIdList); - Map prodPriceAndMainPicMap = prodPriceAndMainPicList.stream().collect(Collectors - .toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, Function.identity())); - // 商品标签 - List prodTagList = this.dailyProdTagMapper.selectList(new LambdaQueryWrapper() - .eq(DailyProdTag::getDelFlag, Constants.UNDELETED).in(DailyProdTag::getStoreProdId, storeProdIdList)); - Map> prodTagMap = prodTagList.stream().collect(Collectors.groupingBy(DailyProdTag::getStoreProdId, Collectors - .collectingAndThen(Collectors.toList(), list -> list.stream() - .sorted(Comparator.comparing(DailyProdTag::getType)).map(DailyProdTag::getTag).collect(Collectors.toList())))); + List storeList = this.storeMapper.selectByIds(oneMonthList.stream().map(AdvertRound::getStoreId).collect(Collectors.toList())); + // 获取商品显示的基本属性 + List storeProdViewList = this.storeProdMapper.getStoreProdViewAttr(storeProdIdList, + java.sql.Date.valueOf(LocalDate.now()), java.sql.Date.valueOf(LocalDate.now().minusMonths(2))); + Map viewMap = storeProdViewList.stream().collect(Collectors.toMap(StoreProdViewDTO::getStoreProdId, Function.identity())); // 档口标签 List storeTagList = this.dailyStoreTagMapper.selectList(new LambdaQueryWrapper() .eq(DailyStoreTag::getDelFlag, Constants.UNDELETED).in(DailyStoreTag::getStoreId, storeList.stream().map(Store::getId).collect(Collectors.toList()))); 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 launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); // 从正在播放的图搜热款广告或者历史广告中筛选10条 - picSearchList = getPicSearchAdvertList(CollectionUtils.isEmpty(launchingList) ? expiredList : launchingList, - prodSearchCountMap, storeMap, prodPriceAndMainPicMap, prodTagMap, storeTagMap); + picSearchList = getPicSearchAdvertList(CollectionUtils.isEmpty(launchingList) ? expiredList : launchingList, viewMap, storeTagMap); // 放到redis 中 过期时间1天 redisCache.setCacheObject(CacheConstants.PC_ADVERT + CacheConstants.PIC_SEARCH, picSearchList, 1, TimeUnit.DAYS); return picSearchList; @@ -1266,7 +1281,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { // 档口商品的价格及商品主图map Map prodPriceAndMainPicMap = prodPriceAndMainPicList.stream().collect(Collectors .toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, Function.identity())); - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(launchingList)) { pcUserCenterList = expiredList.stream().map(x -> this.getPcUserCenterDTO(x, prodPriceAndMainPicMap)).limit(18).collect(Collectors.toList()); @@ -1304,7 +1320,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService { .map(AdvertRound::getProdIdStr).map(Long::parseLong).collect(Collectors.toList())); Map prodPriceAndMainPicMap = prodPriceAndMainPicList.stream().collect(Collectors .toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, Function.identity())); - List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList()); + List launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())) + .filter(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())).collect(Collectors.toList()); List expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(launchingList)) { pcDownloadList = expiredList.stream().map(advertRound -> this.getPcDownload(advertRound, prodPriceAndMainPicMap)).limit(10).collect(Collectors.toList()); @@ -1354,34 +1371,31 @@ public class WebsitePCServiceImpl implements IWebsitePCService { /** * 获取以图搜款的广告 * - * @param picSearchList 图搜热款数据库数据 - * @param prodSearchCountMap 商品搜索次数 - * @param storeMap 档口map - * @param prodPriceAndMainPicMap 档口商品价格及主图map - * @param prodTagMap 商品标签map - * @param storeTagMap 档口标签map + * @param picSearchList 图搜热款数据库数据 + * @param storeTagMap 档口标签map * @return List */ - private List getPicSearchAdvertList(List picSearchList, Map prodSearchCountMap, Map storeMap, - Map prodPriceAndMainPicMap, Map> prodTagMap, - Map> storeTagMap) { - return picSearchList.stream().map(advertRound -> { - - // TODO 查询同款商品数量 - // TODO 查询同款商品数量 - // TODO 查询同款商品数量 - + private List getPicSearchAdvertList(List picSearchList, Map viewMap, Map> storeTagMap) { + return picSearchList.stream().limit(10).map(advertRound -> { final Long storeProdId = Long.valueOf(advertRound.getProdIdStr()); - return new PicSearchAdvertDTO().setImgSearchCount(ObjectUtils.defaultIfNull(prodSearchCountMap.get(storeProdId), (long) (new Random().nextInt(191) + 10))) - .setSameProdCount(null).setStoreProdId(storeProdId).setStoreId(advertRound.getStoreId()) - .setStoreName(ObjectUtils.isNotEmpty(storeMap.get(advertRound.getStoreId())) ? storeMap.get(advertRound.getStoreId()).getStoreName() : "") - .setPrice(ObjectUtils.isNotEmpty(prodPriceAndMainPicMap.get(storeProdId)) ? prodPriceAndMainPicMap.get(storeProdId).getMinPrice() : null) - .setProdArtNum(ObjectUtils.isNotEmpty(prodPriceAndMainPicMap.get(storeProdId)) ? prodPriceAndMainPicMap.get(storeProdId).getProdArtNum() : "") - .setMainPicUrl(ObjectUtils.isNotEmpty(prodPriceAndMainPicMap.get(storeProdId)) ? prodPriceAndMainPicMap.get(storeProdId).getMainPicUrl() : "") - .setProdTitle(ObjectUtils.isNotEmpty(prodPriceAndMainPicMap.get(storeProdId)) ? prodPriceAndMainPicMap.get(storeProdId).getProdTitle() : "") - .setProdTagList(CollectionUtils.isNotEmpty(prodTagMap.get(storeProdId)) ? prodTagMap.get(storeProdId) : null) - .setStoreTagList(CollectionUtils.isNotEmpty(storeTagMap.get(advertRound.getStoreId())) ? storeTagMap.get(advertRound.getStoreId()) : null); - }).limit(10).collect(Collectors.toList()); + StoreProdViewDTO viewDTO = viewMap.get(storeProdId); + String mainPic = ObjectUtils.isNotEmpty(viewDTO) ? viewDTO.getMainPicUrl() : ""; + List results = StringUtils.isNotBlank(mainPic) ? pictureService.searchProductByPicKey(mainPic, 1000) : new ArrayList<>(); + List prodTagList = new ArrayList() {{ + add("同类热卖"); + }}; + CollectionUtils.addAll(prodTagList, ObjectUtils.isNotEmpty(viewDTO) && StringUtils.isNotEmpty(viewDTO.getTagStr()) + ? StrUtil.split(viewDTO.getTagStr(), ",") : new ArrayList<>()); + return new PicSearchAdvertDTO().setImgSearchCount(ObjectUtils.isNotEmpty(viewDTO) && ObjectUtils.isNotEmpty(viewDTO.getImgSearchCount()) + ? viewDTO.getImgSearchCount() : (long) (new Random().nextInt(191) + 10)) + .setSameProdCount(results.size()).setStoreProdId(storeProdId).setStoreId(advertRound.getStoreId()).setProdTagList(prodTagList) + .setStoreName(ObjectUtils.isNotEmpty(viewDTO) ? viewDTO.getStoreName() : "") + .setPrice(ObjectUtils.isNotEmpty(viewDTO) ? viewDTO.getPrice() : null) + .setProdArtNum(ObjectUtils.isNotEmpty(viewDTO) ? viewDTO.getProdArtNum() : "") + .setMainPicUrl(ObjectUtils.isNotEmpty(viewDTO) ? viewDTO.getMainPicUrl() : "") + .setProdTitle(ObjectUtils.isNotEmpty(viewDTO) ? viewDTO.getProdTitle() : ""); +// .setStoreTagList(CollectionUtils.isNotEmpty(storeTagMap.get(advertRound.getStoreId())) ? storeTagMap.get(advertRound.getStoreId()) : null); + }).collect(Collectors.toList()); } /** @@ -1466,7 +1480,7 @@ public class WebsitePCServiceImpl implements IWebsitePCService { dbStyleList.stream().collect(Collectors.groupingBy(AdvertRound::getStoreId)) .forEach((storeId, list) -> { AdvertRound advertRound = list.get(0); - List prodIdStrList = Arrays.asList(advertRound.getProdIdStr().split(",")); + List prodIdStrList = StrUtil.split(advertRound.getProdIdStr(), ","); List styleList = new ArrayList<>(); for (int i = 0; i < prodIdStrList.size(); i++) { Long storeProdId = Long.valueOf(prodIdStrList.get(i)); @@ -1540,5 +1554,34 @@ public class WebsitePCServiceImpl implements IWebsitePCService { return FieldValue.of(value); } + /** + * 在指定位置插入广告数据到列表中,若位置超出数据长度,则追加到列表末尾 + * + * @param dataList 原始数据列表 + * @param adverts 广告数据列表 + * @param positions 插入广告的位置集合 + * @param 数据类型 + * @return 合并后的列表 + */ + public static List insertAdvertsIntoList(List dataList, List adverts, Set positions) { + List mergedList = new ArrayList<>(); + int dataIndex = 0; + int advertIndex = 0; + int size = dataList.size(); + for (int i = 0; i < size + positions.size(); i++) { + if (positions.contains(i) && advertIndex < adverts.size()) { + // 如果当前位置需要插入广告,并且还有广告可插入 + mergedList.add(adverts.get(advertIndex++)); + } else if (dataIndex < size) { + // 插入原始数据 + mergedList.add(dataList.get(dataIndex++)); + } else { + // 源数据已经插完,但仍有广告未插入,直接追加到末尾 + mergedList.add(adverts.get(advertIndex++)); + } + } + return mergedList; + } + } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsiteServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsiteServiceImpl.java index d036088bf..e383da16f 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsiteServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/WebsiteServiceImpl.java @@ -1829,8 +1829,8 @@ public class WebsiteServiceImpl implements IWebsiteService { .setProdArtNum(ObjectUtils.isNotEmpty(prodPriceAndMainPicMap.get(storeProdId)) ? prodPriceAndMainPicMap.get(storeProdId).getProdArtNum() : "") .setMainPicUrl(ObjectUtils.isNotEmpty(prodPriceAndMainPicMap.get(storeProdId)) ? prodPriceAndMainPicMap.get(storeProdId).getMainPicUrl() : "") .setProdTitle(ObjectUtils.isNotEmpty(prodPriceAndMainPicMap.get(storeProdId)) ? prodPriceAndMainPicMap.get(storeProdId).getProdTitle() : "") - .setProdTagList(CollectionUtils.isNotEmpty(prodTagMap.get(storeProdId)) ? prodTagMap.get(storeProdId) : null) - .setStoreTagList(CollectionUtils.isNotEmpty(storeTagMap.get(advertRound.getStoreId())) ? storeTagMap.get(advertRound.getStoreId()) : null); + .setProdTagList(CollectionUtils.isNotEmpty(prodTagMap.get(storeProdId)) ? prodTagMap.get(storeProdId) : null); +// .setStoreTagList(CollectionUtils.isNotEmpty(storeTagMap.get(advertRound.getStoreId())) ? storeTagMap.get(advertRound.getStoreId()) : null); }).limit(10).collect(Collectors.toList()); } diff --git a/xkt/src/main/resources/mapper/PictureSearchMapper.xml b/xkt/src/main/resources/mapper/PictureSearchMapper.xml index 87591b676..441168f6e 100644 --- a/xkt/src/main/resources/mapper/PictureSearchMapper.xml +++ b/xkt/src/main/resources/mapper/PictureSearchMapper.xml @@ -14,6 +14,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" sps.voucher_date BETWEEN #{beginDate} AND #{endDate} GROUP BY sps.store_prod_id - ORDER BY img_search_count DESC + ORDER BY + img_search_count DESC + Limit 100 \ No newline at end of file diff --git a/xkt/src/main/resources/mapper/StoreProductMapper.xml b/xkt/src/main/resources/mapper/StoreProductMapper.xml index 3f1fbf313..b95be4050 100644 --- a/xkt/src/main/resources/mapper/StoreProductMapper.xml +++ b/xkt/src/main/resources/mapper/StoreProductMapper.xml @@ -49,16 +49,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" FROM store_product sp LEFT JOIN store s ON sp.store_id = s.id - LEFT JOIN store_product_file spf ON sp.id = spf.store_prod_id - AND spf.file_type = 1 - AND spf.order_num = 1 + LEFT JOIN store_product_file spf ON sp.id = spf.store_prod_id AND spf.del_flag = 0 AND spf.file_type = 1 AND spf.order_num = 1 LEFT JOIN sys_file sf ON spf.file_id = sf.id - LEFT JOIN store_product_category_attribute spca1 ON sp.id = spca1.store_prod_id - AND spca1.dict_type = 'suitable_season' + LEFT JOIN store_product_category_attribute spca1 ON sp.id = spca1.store_prod_id AND spca1.dict_type = 'suitable_season' LEFT JOIN sys_product_category spc1 ON sp.prod_cate_id = spc1.id LEFT JOIN sys_product_category spc2 ON spc1.parent_id = spc2.id - LEFT JOIN store_product_category_attribute spca2 ON sp.id = spca2.store_prod_id - AND spca2.dict_type = 'style' + LEFT JOIN store_product_category_attribute spca2 ON sp.id = spca2.store_prod_id AND spca2.dict_type = 'style' LEFT JOIN ( SELECT store_prod_id, MIN( price ) AS min_price FROM store_product_color_price GROUP BY store_prod_id ) spcp ON sp.id = spcp.store_prod_id WHERE sp.del_flag = 0 AND sp.id IN @@ -92,10 +88,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" spcs.id AS store_prod_color_size_id FROM store_product_color spc - JOIN store_product_color_price spcp ON spc.store_color_id = spcp.store_color_id - AND spc.store_prod_id = spcp.store_prod_id - JOIN store_product_color_size spcs ON spc.store_color_id = spcs.store_color_id - AND spc.store_prod_id = spcs.store_prod_id + JOIN store_product_color_price spcp ON spc.store_color_id = spcp.store_color_id AND spc.store_prod_id = spcp.store_prod_id AND spcp.del_flag = 0 + JOIN store_product_color_size spcs ON spc.store_color_id = spcs.store_color_id AND spc.store_prod_id = spcs.store_prod_id WHERE spc.del_flag = 0 AND spcs.standard = 1 @@ -112,7 +106,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" FROM store_product sp JOIN store_product_color_price spcp ON sp.id = spcp.store_prod_id - JOIN store_product_file spf ON sp.id = spf.store_prod_id + JOIN store_product_file spf ON sp.id = spf.store_prod_id AND spf.del_flag = 0 LEFT JOIN sys_file sf ON spf.file_id = sf.id WHERE sp.del_flag = 0 @@ -142,11 +136,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" FROM store_product sp JOIN store_product_color_price spcp ON sp.id = spcp.store_prod_id - JOIN store_product_file spf ON sp.id = spf.store_prod_id + JOIN store_product_file spf ON sp.id = spf.store_prod_id AND spf.del_flag = 0 LEFT JOIN sys_file sf ON spf.file_id = sf.id JOIN store s ON sp.store_id = s.id - LEFT JOIN daily_prod_tag dpt ON sp.id = dpt.store_prod_id - AND dpt.del_flag = 0 + LEFT JOIN daily_prod_tag dpt ON sp.id = dpt.store_prod_id AND dpt.del_flag = 0 LEFT JOIN sys_product_category spc ON sp.prod_cate_id = spc.id WHERE sp.del_flag = 0 @@ -161,6 +154,65 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" sf.file_url + + + + +