mirror of
https://gitee.com/youlaitech/youlai-mall.git
synced 2025-01-03 17:42:20 +08:00
feat: 用户商品浏览历史
用redis zset实现的最近十条记录(高并发时可能会有误差),满足我目前的需求了。想要京东淘宝那样丰富的可能需要借助es。
This commit is contained in:
parent
85c386c2a7
commit
654a1cfe56
@ -0,0 +1,20 @@
|
|||||||
|
package com.youlai.mall.pms.pojo.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gadfly
|
||||||
|
* @since 2021-08-10 15:44
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ProductHistoryVO implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String pic;
|
||||||
|
}
|
@ -110,6 +110,12 @@
|
|||||||
<groupId>com.youlai</groupId>
|
<groupId>com.youlai</groupId>
|
||||||
<artifactId>common-rabbitmq</artifactId>
|
<artifactId>common-rabbitmq</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.youlai</groupId>
|
||||||
|
<artifactId>ums-api</artifactId>
|
||||||
|
<version>2.0.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
package com.youlai.mall.pms;
|
package com.youlai.mall.pms;
|
||||||
|
|
||||||
|
import com.youlai.mall.ums.api.MemberFeignClient;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
|
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
|
||||||
@EnableDiscoveryClient
|
@EnableDiscoveryClient
|
||||||
|
@EnableFeignClients(basePackageClasses = {MemberFeignClient.class})
|
||||||
@EnableTransactionManagement
|
@EnableTransactionManagement
|
||||||
public class PmsApplication {
|
public class PmsApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -14,10 +14,12 @@ import com.youlai.mall.pms.pojo.entity.PmsSku;
|
|||||||
import com.youlai.mall.pms.pojo.entity.PmsSpec;
|
import com.youlai.mall.pms.pojo.entity.PmsSpec;
|
||||||
import com.youlai.mall.pms.pojo.entity.PmsSpu;
|
import com.youlai.mall.pms.pojo.entity.PmsSpu;
|
||||||
import com.youlai.mall.pms.pojo.entity.PmsSpuAttributeValue;
|
import com.youlai.mall.pms.pojo.entity.PmsSpuAttributeValue;
|
||||||
|
import com.youlai.mall.pms.pojo.vo.ProductHistoryVO;
|
||||||
import com.youlai.mall.pms.service.IPmsSkuService;
|
import com.youlai.mall.pms.service.IPmsSkuService;
|
||||||
import com.youlai.mall.pms.service.IPmsSpecService;
|
import com.youlai.mall.pms.service.IPmsSpecService;
|
||||||
import com.youlai.mall.pms.service.IPmsSpuAttributeValueService;
|
import com.youlai.mall.pms.service.IPmsSpuAttributeValueService;
|
||||||
import com.youlai.mall.pms.service.IProductService;
|
import com.youlai.mall.pms.service.IProductService;
|
||||||
|
import com.youlai.mall.ums.api.MemberFeignClient;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.redisson.api.RLock;
|
import org.redisson.api.RLock;
|
||||||
@ -44,6 +46,7 @@ public class ProductServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> implem
|
|||||||
private final RedisUtils redisUtils;
|
private final RedisUtils redisUtils;
|
||||||
private final RedissonClient redissonClient;
|
private final RedissonClient redissonClient;
|
||||||
private final ProductLocalCache productLocalCache;
|
private final ProductLocalCache productLocalCache;
|
||||||
|
private final MemberFeignClient memberFeignClient;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -52,12 +55,18 @@ public class ProductServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> implem
|
|||||||
ProductFormDTO product = productLocalCache.get(PRODUCT_DETAIL_CACHE + spuId);
|
ProductFormDTO product = productLocalCache.get(PRODUCT_DETAIL_CACHE + spuId);
|
||||||
if (null != product) {
|
if (null != product) {
|
||||||
log.info("get LocalCache product:" + product);
|
log.info("get LocalCache product:" + product);
|
||||||
|
ProductHistoryVO vo = new ProductHistoryVO();
|
||||||
|
BeanUtil.copyProperties(product.getSpu(), vo);
|
||||||
|
memberFeignClient.addProductViewHistory(vo);
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
//2、二级缓存设置,Redis中获取商品详情信息
|
//2、二级缓存设置,Redis中获取商品详情信息
|
||||||
product = (ProductFormDTO) redisUtils.get(PRODUCT_DETAIL_CACHE + spuId);
|
product = (ProductFormDTO) redisUtils.get(PRODUCT_DETAIL_CACHE + spuId);
|
||||||
if (null != product) {
|
if (null != product) {
|
||||||
log.info("get redis product:" + product);
|
log.info("get redis product:" + product);
|
||||||
|
ProductHistoryVO vo = new ProductHistoryVO();
|
||||||
|
BeanUtil.copyProperties(product.getSpu(), vo);
|
||||||
|
memberFeignClient.addProductViewHistory(vo);
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
//3、分布式锁,保证原子操作
|
//3、分布式锁,保证原子操作
|
||||||
@ -102,6 +111,9 @@ public class ProductServiceImpl extends ServiceImpl<PmsSpuMapper, PmsSpu> implem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ProductHistoryVO vo = new ProductHistoryVO();
|
||||||
|
BeanUtil.copyProperties(product.getSpu(), vo);
|
||||||
|
memberFeignClient.addProductViewHistory(vo);
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,5 +34,11 @@
|
|||||||
<groupId>com.github.xiaoymin</groupId>
|
<groupId>com.github.xiaoymin</groupId>
|
||||||
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
|
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.youlai</groupId>
|
||||||
|
<artifactId>pms-api</artifactId>
|
||||||
|
<version>2.0.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package com.youlai.mall.ums.api;
|
package com.youlai.mall.ums.api;
|
||||||
|
|
||||||
import com.youlai.common.result.Result;
|
import com.youlai.common.result.Result;
|
||||||
import com.youlai.mall.ums.pojo.entity.UmsMember;
|
import com.youlai.mall.pms.pojo.vo.ProductHistoryVO;
|
||||||
import com.youlai.mall.ums.pojo.dto.MemberDTO;
|
import com.youlai.mall.ums.pojo.dto.MemberDTO;
|
||||||
|
import com.youlai.mall.ums.pojo.entity.UmsMember;
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@ -50,6 +51,12 @@ public interface MemberFeignClient {
|
|||||||
*/
|
*/
|
||||||
@GetMapping("/app-api/v1/members/{id}/balance")
|
@GetMapping("/app-api/v1/members/{id}/balance")
|
||||||
Result<Long> getBalance(@PathVariable Long id);
|
Result<Long> getBalance(@PathVariable Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加浏览记录
|
||||||
|
*/
|
||||||
|
@PostMapping("/app-api/v1/members/view/history")
|
||||||
|
<T> Result<T> addProductViewHistory(@RequestBody ProductHistoryVO product);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.youlai.mall.ums.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gadfly
|
||||||
|
* @since 2021-08-10 12:12
|
||||||
|
*/
|
||||||
|
public interface UmsConstants {
|
||||||
|
String USER_PRODUCT_HISTORY = "user:product:history:";
|
||||||
|
}
|
@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|||||||
import com.youlai.common.result.Result;
|
import com.youlai.common.result.Result;
|
||||||
import com.youlai.common.result.ResultCode;
|
import com.youlai.common.result.ResultCode;
|
||||||
import com.youlai.common.web.util.JwtUtils;
|
import com.youlai.common.web.util.JwtUtils;
|
||||||
|
import com.youlai.mall.pms.pojo.vo.ProductHistoryVO;
|
||||||
import com.youlai.mall.ums.pojo.entity.UmsMember;
|
import com.youlai.mall.ums.pojo.entity.UmsMember;
|
||||||
import com.youlai.mall.ums.pojo.dto.MemberDTO;
|
import com.youlai.mall.ums.pojo.dto.MemberDTO;
|
||||||
import com.youlai.mall.ums.service.IUmsMemberService;
|
import com.youlai.mall.ums.service.IUmsMemberService;
|
||||||
@ -17,6 +18,9 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Api(tags = "【移动端】会员服务")
|
@Api(tags = "【移动端】会员服务")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/app-api/v1/members")
|
@RequestMapping("/app-api/v1/members")
|
||||||
@ -143,4 +147,29 @@ public class MemberController {
|
|||||||
}
|
}
|
||||||
return Result.success(balance);
|
return Result.success(balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "添加浏览历史")
|
||||||
|
@PostMapping("/view/history")
|
||||||
|
public <T> Result<T> addProductViewHistory(@RequestBody ProductHistoryVO product) {
|
||||||
|
Long userId = null;
|
||||||
|
try {
|
||||||
|
userId = JwtUtils.getUserId();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
iUmsMemberService.addProductViewHistory(product, userId);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取浏览历史")
|
||||||
|
@GetMapping("/view/history")
|
||||||
|
public Result<Set<ProductHistoryVO>> getProductViewHistory() {
|
||||||
|
try {
|
||||||
|
Long userId = JwtUtils.getUserId();
|
||||||
|
Set<ProductHistoryVO> historyList = iUmsMemberService.getProductViewHistory(userId);
|
||||||
|
return Result.success(historyList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.success(Collections.emptySet());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,16 @@ package com.youlai.mall.ums.service;
|
|||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.youlai.mall.pms.pojo.vo.ProductHistoryVO;
|
||||||
import com.youlai.mall.ums.pojo.entity.UmsMember;
|
import com.youlai.mall.ums.pojo.entity.UmsMember;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public interface IUmsMemberService extends IService<UmsMember> {
|
public interface IUmsMemberService extends IService<UmsMember> {
|
||||||
|
|
||||||
IPage<UmsMember> list(Page<UmsMember> page, UmsMember user);
|
IPage<UmsMember> list(Page<UmsMember> page, UmsMember user);
|
||||||
|
|
||||||
|
void addProductViewHistory(ProductHistoryVO product, Long userId);
|
||||||
|
|
||||||
|
Set<ProductHistoryVO> getProductViewHistory(Long userId);
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,23 @@ package com.youlai.mall.ums.service.impl;
|
|||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.youlai.mall.pms.pojo.vo.ProductHistoryVO;
|
||||||
|
import com.youlai.mall.ums.constant.UmsConstants;
|
||||||
import com.youlai.mall.ums.pojo.entity.UmsMember;
|
import com.youlai.mall.ums.pojo.entity.UmsMember;
|
||||||
import com.youlai.mall.ums.mapper.UmsUserMapper;
|
import com.youlai.mall.ums.mapper.UmsUserMapper;
|
||||||
import com.youlai.mall.ums.service.IUmsMemberService;
|
import com.youlai.mall.ums.service.IUmsMemberService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class UmsMemberServiceImpl extends ServiceImpl<UmsUserMapper, UmsMember> implements IUmsMemberService {
|
public class UmsMemberServiceImpl extends ServiceImpl<UmsUserMapper, UmsMember> implements IUmsMemberService {
|
||||||
|
|
||||||
|
private final RedisTemplate redisTemplate;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPage<UmsMember> list(Page<UmsMember> page, UmsMember spu) {
|
public IPage<UmsMember> list(Page<UmsMember> page, UmsMember spu) {
|
||||||
@ -20,4 +27,21 @@ public class UmsMemberServiceImpl extends ServiceImpl<UmsUserMapper, UmsMember>
|
|||||||
page.setRecords(list);
|
page.setRecords(list);
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addProductViewHistory(ProductHistoryVO product, Long userId) {
|
||||||
|
if (userId != null) {
|
||||||
|
String key = UmsConstants.USER_PRODUCT_HISTORY + userId;
|
||||||
|
redisTemplate.opsForZSet().add(key, product, System.currentTimeMillis());
|
||||||
|
Long size = redisTemplate.opsForZSet().size(key);
|
||||||
|
if (size > 10) {
|
||||||
|
redisTemplate.opsForZSet().removeRange(key, 0, size - 11);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<ProductHistoryVO> getProductViewHistory(Long userId) {
|
||||||
|
return redisTemplate.opsForZSet().reverseRange(UmsConstants.USER_PRODUCT_HISTORY + userId, 0, 9);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user