修正项目

This commit is contained in:
2024-01-07 01:10:08 +08:00
parent 2f29241806
commit b22014e976
943 changed files with 27699 additions and 28227 deletions

View File

@@ -0,0 +1,5 @@
FROM openjdk:8-jdk-alpine
LABEL authors="yovinchen"
VOLUME /tmp
ADD ./target/service-search.jar service-search.jar
ENTRYPOINT ["java","-jar","/service-search.jar", "&"]

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.yovinchen</groupId>
<artifactId>service</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>service-search</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>com.yovinchen</groupId>
<artifactId>service-product-client</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.yovinchen</groupId>
<artifactId>rabbit_util</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.yovinchen</groupId>
<artifactId>service-activity-client</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@@ -0,0 +1,24 @@
package com.yovinchen.xlcs;
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;
/**
* ClassName: ServiceSearchApplication
* Package: com.yovinchen.xlcs
*
* @author yovinchen
* @Create 2023/9/16 17:20
*/
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//取消数据源自动配置
@EnableDiscoveryClient
@EnableFeignClients
public class ServiceSearchApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceSearchApplication.class, args);
}
}

View File

@@ -0,0 +1,11 @@
package com.yovinchen.xlcs.search.api;
/**
* ClassName: SearchApiController
* Package: com.yovinchen.xlcs.search.api
*
* @author yovinchen
* @Create 2023/9/26 14:21
*/
public class SearchApiController {
}

View File

@@ -0,0 +1,72 @@
package com.yovinchen.xlcs.search.controller;
import com.yovinchen.xlcs.common.result.Result;
import com.yovinchen.xlcs.model.search.SkuEs;
import com.yovinchen.xlcs.search.service.SkuService;
import com.yovinchen.xlcs.vo.search.SkuEsQueryVo;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* ClassName: SkuApiController
* Package: com.yovinchen.xlcs.search.controller
*
* @author yovinchen
* @Create 2023/9/16 17:22
*/
@RestController
@RequestMapping("api/search/sku")
public class SkuApiController {
@Autowired
private SkuService skuService;
@ApiOperation(value = "上架商品")
@GetMapping("inner/upperSku/{skuId}")
public Result upperGoods(@PathVariable("skuId") Long skuId) {
skuService.upperSku(skuId);
return Result.ok(null);
}
@ApiOperation(value = "下架商品")
@GetMapping("inner/lowerSku/{skuId}")
public Result lowerGoods(@PathVariable("skuId") Long skuId) {
skuService.lowerSku(skuId);
return Result.ok(null);
}
@ApiOperation(value = "获取爆品商品")
@GetMapping("inner/findHotSkuList")
public List<SkuEs> findHotSkuList() {
return skuService.findHotSkuList();
}
@ApiOperation(value = "搜索分类商品")
@GetMapping("{page}/{limit}")
public Result list(
@ApiParam(name = "page", value = "当前页码", required = true) @PathVariable Integer page,
@ApiParam(name = "limit", value = "每页记录数", required = true) @PathVariable Integer limit,
@ApiParam(name = "searchParamVo", value = "查询对象", required = false) SkuEsQueryVo searchParamVo) {
Pageable pageable = PageRequest.of(page - 1, limit);
Page<SkuEs> pageModel = skuService.search(pageable, searchParamVo);
return Result.ok(pageModel);
}
@ApiOperation(value = "更新商品热度")
@GetMapping("inner/incrHotScore/{skuId}")
public Boolean incrHotScore(@PathVariable("skuId") Long skuId) {
skuService.incrHotScore(skuId);
return true;
}
}

View File

@@ -0,0 +1,73 @@
package com.yovinchen.xlcs.search.receiver;
import com.yovinchen.xlcs.mq.constant.MqConst;
import com.yovinchen.xlcs.search.service.SkuService;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* ClassName: SkuReceiver
* Package: com.yovinchen.xlcs.search.receiver
*
* @author yovinchen
* @Create 2023/9/16 23:57
*/
@Component
public class SkuReceiver {
@Autowired
private SkuService skuService;
/**
* 商品上架
*
* @param skuId
* @param message
* @param channel
* @throws IOException
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = MqConst.QUEUE_GOODS_UPPER, durable = "true"),
exchange = @Exchange(value = MqConst.EXCHANGE_GOODS_DIRECT),
key = {MqConst.ROUTING_GOODS_UPPER}
))
public void upperSku(Long skuId, Message message, Channel channel) throws IOException {
if (null != skuId) {
skuService.upperSku(skuId);
}
//第一个参数:表示收到的消息的标号
//第二个参数如果为true表示可以签收多个消息
channel.basicAck(message
.getMessageProperties()
.getDeliveryTag(), false);
}
/**
* 商品下架
*
* @param skuId
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = MqConst.QUEUE_GOODS_LOWER, durable = "true"),
exchange = @Exchange(value = MqConst.EXCHANGE_GOODS_DIRECT),
key = {MqConst.ROUTING_GOODS_LOWER}
))
public void lowerSku(Long skuId, Message message, Channel channel) throws IOException {
if (null != skuId) {
skuService.lowerSku(skuId);
}
//第一个参数:表示收到的消息的标号
//第二个参数如果为true表示可以签收多个消息
channel.basicAck(message
.getMessageProperties()
.getDeliveryTag(), false);
}
}

View File

@@ -0,0 +1,39 @@
package com.yovinchen.xlcs.search.repository;
import com.yovinchen.xlcs.model.search.SkuEs;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
/**
* ClassName: SkuRepository
* Package: com.yovinchen.xlcs.search.repository
*
* @author yovinchen
* @Create 2023/9/16 17:24
*/
public interface SkuRepository extends ElasticsearchRepository<SkuEs, Long> {
//获取爆款商品
Page<SkuEs> findByOrderByHotScoreDesc(Pageable pageable);
/**
* 根据仓库id + 分类id查询
*
* @param categoryId
* @param wareId
* @param pageable
* @return
*/
Page<SkuEs> findByCategoryIdAndWareId(Long categoryId, Long wareId, Pageable pageable);
/**
* 仓库id + keyword进行查询
*
* @param keyword
* @param wareId
* @param pageable
* @return
*/
Page<SkuEs> findByKeywordAndWareId(String keyword, Long wareId, Pageable pageable);
}

View File

@@ -0,0 +1,58 @@
package com.yovinchen.xlcs.search.service;
import com.yovinchen.xlcs.model.search.SkuEs;
import com.yovinchen.xlcs.vo.search.SkuEsQueryVo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* ClassName: SkuService
* Package: com.yovinchen.xlcs.search.service
*
* @author yovinchen
* @Create 2023/9/16 17:23
*/
@Service
public interface SkuService {
/**
* 上架商品列表
*
* @param skuId
*/
void upperSku(Long skuId);
/**
* 下架商品列表
*
* @param skuId
*/
void lowerSku(Long skuId);
/**
* 获取爆品商品
*
* @return
*/
List<SkuEs> findHotSkuList();
/**
* 搜索分类商品
*
* @param pageable
* @param searchParamVo
* @return
*/
Page<SkuEs> search(Pageable pageable, SkuEsQueryVo searchParamVo);
/**
* 更新商品热度
*
* @param skuId
*/
void incrHotScore(Long skuId);
}

View File

@@ -0,0 +1,187 @@
package com.yovinchen.xlcs.search.service.impl;
import com.alibaba.fastjson.JSON;
import com.yovinchen.xlcs.client.activity.ActivityFeignClient;
import com.yovinchen.xlcs.client.product.ProductFeignClient;
import com.yovinchen.xlcs.common.auth.AuthContextHolder;
import com.yovinchen.xlcs.enums.SkuType;
import com.yovinchen.xlcs.model.product.Category;
import com.yovinchen.xlcs.model.product.SkuInfo;
import com.yovinchen.xlcs.model.search.SkuEs;
import com.yovinchen.xlcs.search.repository.SkuRepository;
import com.yovinchen.xlcs.search.service.SkuService;
import com.yovinchen.xlcs.vo.search.SkuEsQueryVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* ClassName: SkuServiceImpl
* Package: com.yovinchen.xlcs.search.service.impl
*
* @author yovinchen
* @Create 2023/9/16 17:23
*/
@Slf4j
@Service
public class SkuServiceImpl implements SkuService {
@Autowired
private ProductFeignClient productFeignClient;
@Autowired
private ActivityFeignClient activityFeignClient;
@Autowired
private SkuRepository skuRepository;
@Autowired
private RedisTemplate redisTemplate;
/**
* 上架商品列表
*
* @param skuId
*/
@Override
public void upperSku(Long skuId) {
log.info("upperSku" + skuId);
//查询sku信息
SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
if (null == skuInfo) {
return;
}
// 查询分类
SkuEs skuEs = new SkuEs();
Category category = productFeignClient.getCategory(skuInfo.getCategoryId());
if (category != null) {
skuEs.setCategoryId(category.getId());
skuEs.setCategoryName(category.getName());
}
skuEs.setId(skuInfo.getId());
skuEs.setKeyword(skuInfo.getSkuName() + "," + skuEs.getCategoryName());
skuEs.setWareId(skuInfo.getWareId());
skuEs.setIsNewPerson(skuInfo.getIsNewPerson());
skuEs.setImgUrl(skuInfo.getImgUrl());
skuEs.setTitle(skuInfo.getSkuName());
if (Objects.equals(skuInfo.getSkuType(), SkuType.COMMON.getCode())) {
skuEs.setSkuType(0);
skuEs.setPrice(skuInfo.getPrice()
.doubleValue());
skuEs.setStock(skuInfo.getStock());
skuEs.setSale(skuInfo.getSale());
skuEs.setPerLimit(skuInfo.getPerLimit());
} else {
//TODO 待完善-秒杀商品
}
SkuEs save = skuRepository.save(skuEs);
log.info("upperSku" + JSON.toJSONString(save));
}
/**
* 下架商品列表
*
* @param skuId
*/
@Override
public void lowerSku(Long skuId) {
skuRepository.deleteById(skuId);
}
@Override
public List<SkuEs> findHotSkuList() {
Pageable pageable = PageRequest.of(0, 10);
Page<SkuEs> page = skuRepository.findByOrderByHotScoreDesc(pageable);
List<SkuEs> skuEsList = page.getContent();
return skuEsList;
}
/**
* 搜索分类商品
*
* @param pageable
* @param skuEsQueryVo
* @return
*/
@Override
public Page<SkuEs> search(Pageable pageable, SkuEsQueryVo skuEsQueryVo) {
//1 向SkuEsQueryVo设置wareId当前登录用户的仓库id
skuEsQueryVo.setWareId(AuthContextHolder.getWareId());
Page<SkuEs> pageModel = null;
//2 调用SkuRepository方法根据springData命名规则定义方法进行条件查询
//// 判断keyword是否为空如果为空 根据仓库id + 分类id查询
String keyword = skuEsQueryVo.getKeyword();
if (StringUtils.isEmpty(keyword)) {
pageModel = skuRepository.findByCategoryIdAndWareId(skuEsQueryVo.getCategoryId(), skuEsQueryVo.getWareId(), pageable);
} else {
///如果keyword不为空根据仓库id + keyword进行查询
pageModel = skuRepository.findByKeywordAndWareId(skuEsQueryVo.getKeyword(), skuEsQueryVo.getWareId(), pageable);
}
//3 查询商品参加优惠活动
List<SkuEs> skuEsList = pageModel.getContent();
if (!CollectionUtils.isEmpty(skuEsList)) {
//遍历skuEsList得到所有skuId
List<Long> skuIdList = skuEsList.stream()
.map(SkuEs::getId)
.collect(Collectors.toList());
//根据skuId列表远程调用调用service-activity里面的接口得到数据
//返回Map<Long,List<String>>
//// map集合key就是skuId值Long类型
//// map集合value是List集合sku参与活动里面多个规则名称列表
///// 一个商品参加一个活动,一个活动里面可以有多个规则
////// 比如有活动:中秋节满减活动
////// 一个活动可以有多个规则:
////// 中秋节满减活动有两个规则满20元减1元满58元减5元
Map<Long, List<String>> skuIdToRuleListMap = activityFeignClient.findActivity(skuIdList);
//封装获取数据到skuEs里面 ruleList属性里面
if (skuIdToRuleListMap != null) {
skuEsList.forEach(skuEs -> {
skuEs.setRuleList(skuIdToRuleListMap.get(skuEs.getId()));
});
}
}
return pageModel;
}
/**
* 更新商品热度
*
* @param skuId
*/
@Override
public void incrHotScore(Long skuId) {
String key = "hotScore";
//redis保存数据每次+1
Double hotScore = redisTemplate.opsForZSet()
.incrementScore(key, "skuId:" + skuId, 1);
//规则
if (hotScore % 10 == 0) {
//更新es
Optional<SkuEs> optional = skuRepository.findById(skuId);
SkuEs skuEs = optional.get();
skuEs.setHotScore(Math.round(hotScore));
skuRepository.save(skuEs);
}
}
}

View File

@@ -0,0 +1,11 @@
server:
port: 8204
spring:
application:
name: service-search
cloud:
nacos:
discovery:
server-addr: 82.157.68.223:8848
username: nacos
password: nacos

View File

@@ -0,0 +1,31 @@
spring:
cloud:
nacos:
config:
namespace: dd5265c5-8290-45bc-9d07-395c14c977d3
server-addr: 82.157.68.223:8848
group: service
username: nacos
password: nacos
enabled: true
file-extension: yml
extension-configs:
- data-id: common.yml
group: common
refresh: true
- data-id: service-redis.yml
group: common
refresh: true
- data-id: service-rabbitmq.yml
group: common
refresh: true
- data-id: config-rabbitmq.yml
group: config
refresh: true
- data-id: service-openfeign.yml
group: common
refresh: true
- data-id: service-elasticsearch.yml
group: common
refresh: true