master:以图搜款功能完善;

pull/1121/head
liujiang 2025-05-25 14:25:20 +08:00
parent 5fcd0d7236
commit 510b780ed5
21 changed files with 511 additions and 205 deletions

View File

@ -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<List<StoreProdViewVO>> 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<List<StoreProdViewVO>> searchHotList() {
return R.ok(BeanUtil.copyToList(picSearchService.listImgSearchTopProduct(), StoreProdViewVO.class));
}
}

View File

@ -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<List<StoreIndexCusSaleTop10ResVO>> 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<List<StoreIndexCusSaleTop10ResVO>> 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));
}
}

View File

@ -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<ESProductDTO>> 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")

View File

@ -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;
}

View File

@ -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<String> prodTagList;
@ApiModelProperty(value = "档口ID")
private Long storeId;
@ApiModelProperty(value = "档口名称")
private String storeName;
// @ApiModelProperty(value = "档口标签列表")
// private List<String> storeTagList;
}

View File

@ -252,5 +252,11 @@ public class Constants
* APP 广 广 广广 205广 3 7 11 15 19
*/
public static final Set<Integer> insertPositions = 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));
}

View File

@ -65,7 +65,7 @@ public class SysLoginService
{
// 验证码校验
// validateCaptcha(username, code, uuid);
validateCaptcha(username, code, uuid);
// 登录前置校验
loginPreCheck(username, password);

View File

@ -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;

View File

@ -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;

View File

@ -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<String> prodTagList;
@ApiModelProperty(value = "档口ID")
private Long storeId;
@ApiModelProperty(value = "档口名称")
private String storeName;
@ApiModelProperty(value = "档口标签列表")
private List<String> storeTagList;
// @ApiModelProperty(value = "档口标签列表")
// private List<String> storeTagList;
}

View File

@ -17,5 +17,5 @@ public class ProductImgSearchCountDTO implements Serializable {
/**
*
*/
private Long imgSearchCount;
private Integer imgSearchCount;
}

View File

@ -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;
/**
*
*/

View File

@ -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<String> prodTagList;
@ApiModelProperty(value = "档口ID")
private Long storeId;
@ApiModelProperty(value = "档口名称")
private String storeName;
// @ApiModelProperty(value = "档口标签列表")
// private List<String> storeTagList;
}

View File

@ -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<StoreProduct> {
/**
*
*
* @param storeProdIdList ID
* @return List<StoreProdPriceAndMainPicAndTagDTO>
*/
List<StoreProdPriceAndMainPicAndTagDTO> selectPriceAndMainPicAndTagList(@Param("storeProdIdList") List<Long> storeProdIdList);
/**
*
*
* @param storeProdIdList ID
* @return List<PicSearchAdvertDTO>
*/
List<StoreProdViewDTO> getStoreProdViewAttr(@Param("storeProdIdList") List<Long> storeProdIdList,
@Param("voucherDateStart") Date voucherDateStart,
@Param("voucherDateEnd") Date voucherDateEnd);
/**
*
*
* @param storeProdIdList ID
* @return List<PicSearchAdvertDTO>
*/
List<StoreProdViewDTO> getSearchHotViewAttr(@Param("storeProdIdList") List<Long> storeProdIdList);
}

View File

@ -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<StoreProdViewDTO>
*/
List<ProductMatchDTO> searchProductByPic(SearchRequestDTO requestDTO);
List<StoreProdViewDTO> searchProductByPic(SearchRequestDTO requestDTO);
/**
*
*
* @return
* @return List<TopProductMatchDTO>
*/
List<TopProductMatchDTO> listImgSearchTopProduct();

View File

@ -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<ProductMatchDTO> searchProductByPic(SearchRequestDTO requestDTO) {
public List<StoreProdViewDTO> 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<StoreProdViewDTO> 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<PicSearchAdvertDTO> picSearchAdverts = websitePCService.getPicSearchList();
// 将广告插入到预定位置
return insertAdvertsIntoList(storeProdViewAttrList, BeanUtil.copyToList(picSearchAdverts, StoreProdViewDTO.class), Constants.pic_res_insert_positions);
}
/**
*
* @return List<TopProductMatchDTO>
*/
@Override
@Transactional(readOnly = true)
public List<TopProductMatchDTO> listImgSearchTopProduct() {
String cacheStr = redisCache.getCacheObject(CacheConstants.TOP_IMG_SEARCH_PRODUCT);
if (StrUtil.isEmpty(cacheStr)) {
return ListUtil.empty();
List<TopProductMatchDTO> 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<ProductImgSearchCountDTO> 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<Long> spIds = prodImgSearchCounts.stream().map(ProductImgSearchCountDTO::getStoreProductId)
Map<Long, Integer> searchCountMap = prodImgSearchCounts.stream().collect(Collectors
.toMap(ProductImgSearchCountDTO::getStoreProductId, ProductImgSearchCountDTO::getImgSearchCount));
// 档口商品显示的基本属性
List<StoreProdViewDTO> storeProdViewAttrList = this.storeProdMapper.getSearchHotViewAttr(prodImgSearchCounts.stream()
.map(ProductImgSearchCountDTO::getStoreProductId).distinct().collect(Collectors.toList()));
storeProdViewAttrList = storeProdViewAttrList.stream().map(x -> {
//根据主图搜索同类商品
List<ProductMatchDTO> 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<Long, String> mainPicMap = storeProductFileMapper.selectMainPicByStoreProdIdList(spIds,
FileType.MAIN_PIC.getValue(), ORDER_NUM_1).stream()
.collect(Collectors.toMap(StoreProdMainPicDTO::getStoreProdId, StoreProdMainPicDTO::getFileUrl,
(o, n) -> n));
List<TopProductMatchDTO> topProductMatchList = new ArrayList<>(prodImgSearchCounts.size());
for (ProductImgSearchCountDTO prodImgSearchCount : prodImgSearchCounts) {
TopProductMatchDTO topProductMatch = BeanUtil.toBean(prodImgSearchCount, TopProductMatchDTO.class);
//根据主图搜索同类商品
List<ProductMatchDTO> 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 <T>
* @return
*/
public static <T> List<T> insertAdvertsIntoList(List<T> dataList, List<T> adverts, Set<Integer> positions) {
if (CollectionUtils.isEmpty(adverts)) {
return dataList;
}
List<T> 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;
}
}

View File

@ -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<PicSearchAdvertDTO>
*/
private List<PicSearchAdvertDTO> getPicSearchAdvertList(List<AdvertRound> picSearchList, Map<Long, Long> prodSearchCountMap, Map<Long, Store> storeMap,
Map<Long, StoreProdPriceAndMainPicDTO> prodPriceAndMainPicMap, Map<Long, List<String>> prodTagMap,
Map<Long, List<String>> 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 <T> List<T> insertAdvertsIntoList(List<T> dataList, List<T> adverts, Set<Integer> positions) {
if (CollectionUtils.isEmpty(adverts)) {
return dataList;
}
List<T> mergedList = new ArrayList<>();
int dataIndex = 0;
int advertIndex = 0;

View File

@ -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<AdvertRound> advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper<AdvertRound>()
.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<StoreProdPriceAndMainPicAndTagDTO> 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<PCIndexRecommendDTO> indexRecommendList = new ArrayList<>();
advertRoundList.forEach(x -> {
// 这里是一个档口上传多个档口商品所以需要对prodIdStr的逗号进行分割
List<Long> prodIdList = Arrays.stream(x.getProdIdStr().split(",")).map(Long::parseLong).collect(Collectors.toList());
List<Long> 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<AdvertRound> advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper<AdvertRound>()
.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<StoreProdPriceAndMainPicAndTagDTO> 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<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList());
List<PCIndexTopLeftBannerDTO> topLeftList;
@ -399,7 +413,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService {
List<StoreProdFileResDTO> mainPicList = this.prodFileMapper.selectMainPic(oneMonthList.stream().map(AdvertRound::getProdIdStr).collect(Collectors.toList()));
Map<Long, String> mainPicMap = mainPicList.stream().collect(Collectors.toMap(StoreProdFileResDTO::getStoreProdId, StoreProdFileResDTO::getFileUrl));
// 正在播放
List<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList());
List<PCIndexTopRightBannerDTO> topRightList;
@ -514,7 +529,9 @@ public class WebsitePCServiceImpl implements IWebsitePCService {
Map<Long, StoreProdPriceAndMainPicDTO> prodPriceAndMainPicMap = prodPriceAndMainPicList.stream().collect(Collectors
.toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, Function.identity()));
// 正在播放
List<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList());
List<PCIndexMidStyleDTO> midStyleList;
@ -567,20 +584,22 @@ public class WebsitePCServiceImpl implements IWebsitePCService {
// 档口商品的价格及商品主图map
Map<Long, StoreProdPriceAndMainPicDTO> prodPriceAndMainPicMap = prodPriceAndMainPicList.stream().collect(Collectors
.toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, Function.identity()));
// 左侧广告
List<AdvertRound> 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<AdvertRound> 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<AdvertRound> 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<AdvertRound> 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<AdvertRound> 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<AdvertRound> 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<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> 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<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> 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<Long, StoreProdPriceAndMainPicDTO> prodPriceAndMainPicMap = prodPriceAndMainPicList.stream().collect(Collectors
.toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, Function.identity()));
// 正在播放
List<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> 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<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> 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<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> 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<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> 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<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> 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<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList());
List<StoreProdPriceAndMainPicDTO> prodPriceAndMainPicList = this.storeProdMapper.selectPriceAndMainPicList(oneMonthList.stream()
@ -1064,7 +1091,8 @@ public class WebsitePCServiceImpl implements IWebsitePCService {
return new ArrayList<>();
}
// 正在播放
List<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> 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<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList());
Map<Long, SysFile> fileMap = fileMapper.selectList(new LambdaQueryWrapper<SysFile>().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<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> expiredList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.EXPIRED.getValue())).collect(Collectors.toList());
Map<Long, SysFile> fileMap = fileMapper.selectList(new LambdaQueryWrapper<SysFile>().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<StoreProductStatistics> prodStatsList = this.prodStatsMapper.selectList(new LambdaQueryWrapper<StoreProductStatistics>()
.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<Long, Long> prodSearchCountMap = prodStatsList.stream().collect(Collectors.groupingBy(StoreProductStatistics::getStoreProdId, Collectors
.summingLong(StoreProductStatistics::getImgSearchCount)));
List<Store> storeList = this.storeMapper.selectByIds(oneMonthList.stream().map(AdvertRound::getStoreId).collect(Collectors.toList()));
Map<Long, Store> storeMap = storeList.stream().collect(Collectors.toMap(Store::getId, Function.identity()));
List<Long> storeProdIdList = oneMonthList.stream().map(AdvertRound::getProdIdStr).map(Long::parseLong).collect(Collectors.toList());
// 获取所有商品的价格及第一张主图
List<StoreProdPriceAndMainPicDTO> prodPriceAndMainPicList = this.storeProdMapper.selectPriceAndMainPicList(storeProdIdList);
Map<Long, StoreProdPriceAndMainPicDTO> prodPriceAndMainPicMap = prodPriceAndMainPicList.stream().collect(Collectors
.toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, Function.identity()));
// 商品标签
List<DailyProdTag> prodTagList = this.dailyProdTagMapper.selectList(new LambdaQueryWrapper<DailyProdTag>()
.eq(DailyProdTag::getDelFlag, Constants.UNDELETED).in(DailyProdTag::getStoreProdId, storeProdIdList));
Map<Long, List<String>> 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<Store> storeList = this.storeMapper.selectByIds(oneMonthList.stream().map(AdvertRound::getStoreId).collect(Collectors.toList()));
// 获取商品显示的基本属性
List<StoreProdViewDTO> storeProdViewList = this.storeProdMapper.getStoreProdViewAttr(storeProdIdList,
java.sql.Date.valueOf(LocalDate.now()), java.sql.Date.valueOf(LocalDate.now().minusMonths(2)));
Map<Long, StoreProdViewDTO> viewMap = storeProdViewList.stream().collect(Collectors.toMap(StoreProdViewDTO::getStoreProdId, Function.identity()));
// 档口标签
List<DailyStoreTag> storeTagList = this.dailyStoreTagMapper.selectList(new LambdaQueryWrapper<DailyStoreTag>()
.eq(DailyStoreTag::getDelFlag, Constants.UNDELETED).in(DailyStoreTag::getStoreId, storeList.stream().map(Store::getId).collect(Collectors.toList())));
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<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> 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<Long, StoreProdPriceAndMainPicDTO> prodPriceAndMainPicMap = prodPriceAndMainPicList.stream().collect(Collectors
.toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, Function.identity()));
List<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> 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<Long, StoreProdPriceAndMainPicDTO> prodPriceAndMainPicMap = prodPriceAndMainPicList.stream().collect(Collectors
.toMap(StoreProdPriceAndMainPicDTO::getStoreProdId, Function.identity()));
List<AdvertRound> launchingList = oneMonthList.stream().filter(x -> Objects.equals(x.getLaunchStatus(), AdLaunchStatus.LAUNCHING.getValue())).collect(Collectors.toList());
List<AdvertRound> 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<AdvertRound> 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<PicSearchAdvertDTO>
*/
private List<PicSearchAdvertDTO> getPicSearchAdvertList(List<AdvertRound> picSearchList, Map<Long, Long> prodSearchCountMap, Map<Long, Store> storeMap,
Map<Long, StoreProdPriceAndMainPicDTO> prodPriceAndMainPicMap, Map<Long, List<String>> prodTagMap,
Map<Long, List<String>> storeTagMap) {
return picSearchList.stream().map(advertRound -> {
// TODO 查询同款商品数量
// TODO 查询同款商品数量
// TODO 查询同款商品数量
private List<PicSearchAdvertDTO> getPicSearchAdvertList(List<AdvertRound> picSearchList, Map<Long, StoreProdViewDTO> viewMap, Map<Long, List<String>> 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<ProductMatchDTO> results = StringUtils.isNotBlank(mainPic) ? pictureService.searchProductByPicKey(mainPic, 1000) : new ArrayList<>();
List<String> prodTagList = new ArrayList<String>() {{
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<String> prodIdStrList = Arrays.asList(advertRound.getProdIdStr().split(","));
List<String> prodIdStrList = StrUtil.split(advertRound.getProdIdStr(), ",");
List<PCIndexMidStyleDTO.PCIMSStyleDTO> 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 <T>
* @return
*/
public static <T> List<T> insertAdvertsIntoList(List<T> dataList, List<T> adverts, Set<Integer> positions) {
List<T> 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;
}
}

View File

@ -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());
}

View File

@ -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
</select>
</mapper>

View File

@ -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
</select>
<select id="getStoreProdViewAttr" resultType="com.ruoyi.xkt.dto.storeProduct.StoreProdViewDTO">
SELECT
sp.id AS storeProdId,
sp.prod_art_num,
sp.prod_title,
SUM( sps.img_search_count ) AS img_search_count,
sf.file_url AS mainPicUrl,
GROUP_CONCAT( DISTINCT dpt.tag ORDER BY dpt.type ) AS tagStr,
sp.store_id,
s.store_name,
MIN( spcp.price ) AS price
FROM
store_product sp
LEFT JOIN store_product_statistics sps ON sp.id = sps.store_prod_id AND sps.voucher_date BETWEEN #{voucherDateStart} AND #{voucherDateEnd}
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 s ON sp.store_id = s.id
LEFT JOIN store_product_color_price spcp ON sp.id = spcp.store_prod_id AND spcp.del_flag = 0
LEFT JOIN daily_prod_tag dpt ON sp.id = dpt.store_prod_id AND dpt.del_flag = 0
WHERE
sp.del_flag = 0
AND sp.id IN
<foreach item="id" collection="storeProdIdList" open="(" separator="," close=")">
#{id}
</foreach>
GROUP BY
sp.id,
sf.file_url
</select>
<select id="getSearchHotViewAttr" resultType="com.ruoyi.xkt.dto.storeProduct.StoreProdViewDTO">
SELECT
sp.id AS storeProdId,
sp.prod_art_num,
sp.prod_title,
sf.file_url AS mainPicUrl,
GROUP_CONCAT( DISTINCT dpt.tag ORDER BY dpt.type ) AS tagStr,
sp.store_id,
s.store_name,
MIN( spcp.price ) AS price
FROM
store_product sp
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 s ON sp.store_id = s.id
LEFT JOIN store_product_color_price spcp ON sp.id = spcp.store_prod_id AND spcp.del_flag = 0
LEFT JOIN daily_prod_tag dpt ON sp.id = dpt.store_prod_id AND dpt.del_flag = 0
WHERE
sp.del_flag = 0
AND sp.id IN
<foreach item="id" collection="storeProdIdList" open="(" separator="," close=")">
#{id}
</foreach>
GROUP BY
sp.id,
sf.file_url
</select>