diff --git a/mall-pms/pms-api/src/main/java/com/youlai/mall/pms/pojo/vo/ProductHistoryVO.java b/mall-pms/pms-api/src/main/java/com/youlai/mall/pms/pojo/vo/ProductHistoryVO.java new file mode 100644 index 000000000..fa54f5e9d --- /dev/null +++ b/mall-pms/pms-api/src/main/java/com/youlai/mall/pms/pojo/vo/ProductHistoryVO.java @@ -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; +} diff --git a/mall-pms/pms-boot/pom.xml b/mall-pms/pms-boot/pom.xml index 1f490100a..28486102e 100644 --- a/mall-pms/pms-boot/pom.xml +++ b/mall-pms/pms-boot/pom.xml @@ -110,6 +110,12 @@ com.youlai common-rabbitmq + + com.youlai + ums-api + 2.0.0 + compile + diff --git a/mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/PmsApplication.java b/mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/PmsApplication.java index 00bd44586..4563b1611 100644 --- a/mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/PmsApplication.java +++ b/mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/PmsApplication.java @@ -1,13 +1,16 @@ package com.youlai.mall.pms; +import com.youlai.mall.ums.api.MemberFeignClient; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.transaction.annotation.EnableTransactionManagement; @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) @EnableDiscoveryClient +@EnableFeignClients(basePackageClasses = {MemberFeignClient.class}) @EnableTransactionManagement public class PmsApplication { public static void main(String[] args) { diff --git a/mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/impl/ProductServiceImpl.java b/mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/impl/ProductServiceImpl.java index f436a5a68..f34528a4a 100644 --- a/mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/impl/ProductServiceImpl.java +++ b/mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/impl/ProductServiceImpl.java @@ -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.PmsSpu; 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.IPmsSpecService; import com.youlai.mall.pms.service.IPmsSpuAttributeValueService; import com.youlai.mall.pms.service.IProductService; +import com.youlai.mall.ums.api.MemberFeignClient; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RLock; @@ -44,6 +46,7 @@ public class ProductServiceImpl extends ServiceImpl implem private final RedisUtils redisUtils; private final RedissonClient redissonClient; private final ProductLocalCache productLocalCache; + private final MemberFeignClient memberFeignClient; @Override @@ -52,12 +55,18 @@ public class ProductServiceImpl extends ServiceImpl implem ProductFormDTO product = productLocalCache.get(PRODUCT_DETAIL_CACHE + spuId); if (null != product) { log.info("get LocalCache product:" + product); + ProductHistoryVO vo = new ProductHistoryVO(); + BeanUtil.copyProperties(product.getSpu(), vo); + memberFeignClient.addProductViewHistory(vo); return product; } //2、二级缓存设置,Redis中获取商品详情信息 product = (ProductFormDTO) redisUtils.get(PRODUCT_DETAIL_CACHE + spuId); if (null != product) { log.info("get redis product:" + product); + ProductHistoryVO vo = new ProductHistoryVO(); + BeanUtil.copyProperties(product.getSpu(), vo); + memberFeignClient.addProductViewHistory(vo); return product; } //3、分布式锁,保证原子操作 @@ -102,6 +111,9 @@ public class ProductServiceImpl extends ServiceImpl implem } } } + ProductHistoryVO vo = new ProductHistoryVO(); + BeanUtil.copyProperties(product.getSpu(), vo); + memberFeignClient.addProductViewHistory(vo); return product; } } diff --git a/mall-ums/ums-api/pom.xml b/mall-ums/ums-api/pom.xml index 8e1aba5d5..f57a6f212 100644 --- a/mall-ums/ums-api/pom.xml +++ b/mall-ums/ums-api/pom.xml @@ -34,5 +34,11 @@ com.github.xiaoymin knife4j-micro-spring-boot-starter + + com.youlai + pms-api + 2.0.0 + compile + diff --git a/mall-ums/ums-api/src/main/java/com/youlai/mall/ums/api/MemberFeignClient.java b/mall-ums/ums-api/src/main/java/com/youlai/mall/ums/api/MemberFeignClient.java index e6e7747b3..6ab3c30d8 100644 --- a/mall-ums/ums-api/src/main/java/com/youlai/mall/ums/api/MemberFeignClient.java +++ b/mall-ums/ums-api/src/main/java/com/youlai/mall/ums/api/MemberFeignClient.java @@ -1,19 +1,20 @@ package com.youlai.mall.ums.api; 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.entity.UmsMember; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; -@FeignClient(name = "mall-ums",contextId = "member") +@FeignClient(name = "mall-ums", contextId = "member") public interface MemberFeignClient { @PostMapping("/app-api/v1/members") Result add(@RequestBody UmsMember member); @PutMapping("/app-api/v1/members/{id}") - Result update(@PathVariable Long id,@RequestBody UmsMember member); + Result update(@PathVariable Long id, @RequestBody UmsMember member); /** * 获取会员信息 @@ -50,6 +51,12 @@ public interface MemberFeignClient { */ @GetMapping("/app-api/v1/members/{id}/balance") Result getBalance(@PathVariable Long id); + + /** + * 添加浏览记录 + */ + @PostMapping("/app-api/v1/members/view/history") + Result addProductViewHistory(@RequestBody ProductHistoryVO product); } diff --git a/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/constant/UmsConstants.java b/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/constant/UmsConstants.java new file mode 100644 index 000000000..421a8d905 --- /dev/null +++ b/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/constant/UmsConstants.java @@ -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:"; +} diff --git a/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/controller/app/MemberController.java b/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/controller/app/MemberController.java index 904c75ca9..1ff0c0580 100644 --- a/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/controller/app/MemberController.java +++ b/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/controller/app/MemberController.java @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.youlai.common.result.Result; import com.youlai.common.result.ResultCode; 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.dto.MemberDTO; import com.youlai.mall.ums.service.IUmsMemberService; @@ -17,6 +18,9 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; +import java.util.Collections; +import java.util.Set; + @Api(tags = "【移动端】会员服务") @RestController @RequestMapping("/app-api/v1/members") @@ -143,4 +147,29 @@ public class MemberController { } return Result.success(balance); } + + @ApiOperation(value = "添加浏览历史") + @PostMapping("/view/history") + public Result 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> getProductViewHistory() { + try { + Long userId = JwtUtils.getUserId(); + Set historyList = iUmsMemberService.getProductViewHistory(userId); + return Result.success(historyList); + } catch (Exception e) { + return Result.success(Collections.emptySet()); + } + } } diff --git a/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/service/IUmsMemberService.java b/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/service/IUmsMemberService.java index f5820d1c8..26dffc718 100644 --- a/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/service/IUmsMemberService.java +++ b/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/service/IUmsMemberService.java @@ -4,9 +4,16 @@ package com.youlai.mall.ums.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; +import com.youlai.mall.pms.pojo.vo.ProductHistoryVO; import com.youlai.mall.ums.pojo.entity.UmsMember; +import java.util.Set; + public interface IUmsMemberService extends IService { IPage list(Page page, UmsMember user); + + void addProductViewHistory(ProductHistoryVO product, Long userId); + + Set getProductViewHistory(Long userId); } diff --git a/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/service/impl/UmsMemberServiceImpl.java b/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/service/impl/UmsMemberServiceImpl.java index f813ad530..ed9534155 100644 --- a/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/service/impl/UmsMemberServiceImpl.java +++ b/mall-ums/ums-boot/src/main/java/com/youlai/mall/ums/service/impl/UmsMemberServiceImpl.java @@ -3,16 +3,23 @@ package com.youlai.mall.ums.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 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.mapper.UmsUserMapper; import com.youlai.mall.ums.service.IUmsMemberService; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Set; @Service +@RequiredArgsConstructor public class UmsMemberServiceImpl extends ServiceImpl implements IUmsMemberService { + private final RedisTemplate redisTemplate; @Override public IPage list(Page page, UmsMember spu) { @@ -20,4 +27,21 @@ public class UmsMemberServiceImpl extends ServiceImpl page.setRecords(list); 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 getProductViewHistory(Long userId) { + return redisTemplate.opsForZSet().reverseRange(UmsConstants.USER_PRODUCT_HISTORY + userId, 0, 9); + } }