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