Commit d4953360 by 段启岩

Merge remote-tracking branch 'origin/add-elastic-search'

parents 8a0c2571 153b9d8b
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version> <version>2.2.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<groupId>cn.meteor</groupId> <groupId>cn.meteor</groupId>
...@@ -133,6 +133,16 @@ ...@@ -133,6 +133,16 @@
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
<exclusions> <exclusions>
......
...@@ -2,10 +2,12 @@ package cn.meteor.beyondclouds; ...@@ -2,10 +2,12 @@ package cn.meteor.beyondclouds;
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.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
/** /**
* @author meteor * @author meteor
*/ */
@EnableElasticsearchRepositories(basePackages = "cn.meteor.beyondclouds.modules.search")
@SpringBootApplication @SpringBootApplication
public class BeyondCloudsApplication { public class BeyondCloudsApplication {
......
package cn.meteor.beyondclouds.config; package cn.meteor.beyondclouds.config;
import cn.meteor.beyondclouds.config.properties.AliyunProperties; import cn.meteor.beyondclouds.config.properties.AliyunProperties;
import cn.meteor.beyondclouds.config.properties.BeyondCloudsKafkaTopicProperties;
import cn.meteor.beyondclouds.config.properties.BeyondCloudsProperties; import cn.meteor.beyondclouds.config.properties.BeyondCloudsProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -8,6 +9,6 @@ import org.springframework.context.annotation.PropertySource; ...@@ -8,6 +9,6 @@ import org.springframework.context.annotation.PropertySource;
@Configuration @Configuration
@PropertySource("classpath:application.yml") @PropertySource("classpath:application.yml")
@EnableConfigurationProperties({BeyondCloudsProperties.class}) @EnableConfigurationProperties({BeyondCloudsProperties.class, BeyondCloudsKafkaTopicProperties.class})
public class BeyondCloudsConfig { public class BeyondCloudsConfig {
} }
package cn.meteor.beyondclouds.config;
import cn.meteor.beyondclouds.config.properties.BeyondCloudsKafkaTopicProperties;
import org.apache.kafka.clients.admin.NewTopic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author meteor
*/
@Configuration
public class KafkaInitialConfig {
private BeyondCloudsKafkaTopicProperties topicProperties;
@Autowired
public KafkaInitialConfig(BeyondCloudsKafkaTopicProperties topicProperties) {
this.topicProperties = topicProperties;
}
/**
* 创建topic
* @return
*/
@Bean
public NewTopic initialTopic() {
return new NewTopic(topicProperties.getSearchItemUpdate(),8, (short) 1 );
}
}
package cn.meteor.beyondclouds.config.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author meteor
*/
@Data
@ConfigurationProperties(prefix = "beyondclouds.kafka.topics")
public class BeyondCloudsKafkaTopicProperties {
/**
* 搜索条目更新操作所订阅的topic
*/
private String searchItemUpdate = "topic.beyondclouds.searchitem.update";
}
...@@ -12,6 +12,9 @@ import cn.meteor.beyondclouds.modules.blog.exception.BlogCategoryServiceExceptio ...@@ -12,6 +12,9 @@ import cn.meteor.beyondclouds.modules.blog.exception.BlogCategoryServiceExceptio
import cn.meteor.beyondclouds.modules.blog.exception.BlogServiceException; import cn.meteor.beyondclouds.modules.blog.exception.BlogServiceException;
import cn.meteor.beyondclouds.modules.blog.mapper.BlogMapper; import cn.meteor.beyondclouds.modules.blog.mapper.BlogMapper;
import cn.meteor.beyondclouds.modules.blog.service.*; import cn.meteor.beyondclouds.modules.blog.service.*;
import cn.meteor.beyondclouds.modules.queue.message.DataItemUpdateMessage;
import cn.meteor.beyondclouds.modules.queue.service.IMessageQueueService;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import cn.meteor.beyondclouds.modules.tag.entity.Tag; import cn.meteor.beyondclouds.modules.tag.entity.Tag;
import cn.meteor.beyondclouds.modules.tag.service.ITagService; import cn.meteor.beyondclouds.modules.tag.service.ITagService;
import cn.meteor.beyondclouds.modules.topic.entity.Topic; import cn.meteor.beyondclouds.modules.topic.entity.Topic;
...@@ -37,7 +40,6 @@ import org.springframework.util.CollectionUtils; ...@@ -37,7 +40,6 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -70,6 +72,9 @@ public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IB ...@@ -70,6 +72,9 @@ public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IB
private ITopicService topicService; private ITopicService topicService;
private IUserService userService; private IUserService userService;
private IMessageQueueService messageQueueService;
@Autowired @Autowired
public BlogServiceImpl(IBlogTagService blogTagService, ITopicReferenceService topicReferenceService, IBlogExtService blogExtService, IBlogCategoryService blogCategoryService, BlogMapper blogMapper, ITagService tagService) { public BlogServiceImpl(IBlogTagService blogTagService, ITopicReferenceService topicReferenceService, IBlogExtService blogExtService, IBlogCategoryService blogCategoryService, BlogMapper blogMapper, ITagService tagService) {
this.blogTagService = blogTagService; this.blogTagService = blogTagService;
...@@ -81,6 +86,11 @@ public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IB ...@@ -81,6 +86,11 @@ public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IB
} }
@Autowired @Autowired
public void setMessageQueueService(IMessageQueueService messageQueueService) {
this.messageQueueService = messageQueueService;
}
@Autowired
public void setTopicService(ITopicService topicService) { public void setTopicService(ITopicService topicService) {
this.topicService = topicService; this.topicService = topicService;
} }
...@@ -140,6 +150,12 @@ public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IB ...@@ -140,6 +150,12 @@ public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IB
//4.更新标签和话题的引用 //4.更新标签和话题的引用
updateTopicAndTagReference(topicIds, tagIds, blog.getBlogId(), false); updateTopicAndTagReference(topicIds, tagIds, blog.getBlogId(), false);
// 5.发送消息到消息队列
messageQueueService
.sendItemUpdateMessage(
DataItemUpdateMessage.addMessage(SearchItemType.BLOG, blog.getBlogId())
);
} }
/** /**
...@@ -184,6 +200,12 @@ public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IB ...@@ -184,6 +200,12 @@ public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IB
//6.删除博客表里的数据 //6.删除博客表里的数据
removeById(blogId); removeById(blogId);
// 5.发送消息到消息队列
messageQueueService
.sendItemUpdateMessage(
DataItemUpdateMessage.deleteMessage(SearchItemType.BLOG, blog.getBlogId())
);
} }
/** /**
...@@ -354,6 +376,12 @@ public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IB ...@@ -354,6 +376,12 @@ public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IB
//4.更新标签和话题的引用 //4.更新标签和话题的引用
updateTopicAndTagReference(topicIds, tagIds, blog.getBlogId(), true); updateTopicAndTagReference(topicIds, tagIds, blog.getBlogId(), true);
// 5.发送消息到消息队列
messageQueueService
.sendItemUpdateMessage(
DataItemUpdateMessage.updateMessage(SearchItemType.BLOG, blog.getBlogId())
);
} }
/** /**
......
...@@ -12,6 +12,9 @@ import cn.meteor.beyondclouds.modules.project.mapper.ProjectMapper; ...@@ -12,6 +12,9 @@ import cn.meteor.beyondclouds.modules.project.mapper.ProjectMapper;
import cn.meteor.beyondclouds.modules.project.service.IProjectCommentService; import cn.meteor.beyondclouds.modules.project.service.IProjectCommentService;
import cn.meteor.beyondclouds.modules.project.service.IProjectExtService; import cn.meteor.beyondclouds.modules.project.service.IProjectExtService;
import cn.meteor.beyondclouds.modules.project.service.IProjectService; import cn.meteor.beyondclouds.modules.project.service.IProjectService;
import cn.meteor.beyondclouds.modules.queue.message.DataItemUpdateMessage;
import cn.meteor.beyondclouds.modules.queue.service.IMessageQueueService;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import cn.meteor.beyondclouds.modules.user.entity.User; import cn.meteor.beyondclouds.modules.user.entity.User;
import cn.meteor.beyondclouds.modules.user.service.IUserService; import cn.meteor.beyondclouds.modules.user.service.IUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
...@@ -45,6 +48,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl ...@@ -45,6 +48,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
private IUserService userService; private IUserService userService;
private IMessageQueueService messageQueueService;
@Autowired @Autowired
public ProjectServiceImpl(IProjectExtService projectExtService, ProjectCategoryMapper projectCategoryMapper) { public ProjectServiceImpl(IProjectExtService projectExtService, ProjectCategoryMapper projectCategoryMapper) {
this.projectExtService = projectExtService; this.projectExtService = projectExtService;
...@@ -52,6 +57,11 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl ...@@ -52,6 +57,11 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
} }
@Autowired @Autowired
public void setMessageQueueService(IMessageQueueService messageQueueService) {
this.messageQueueService = messageQueueService;
}
@Autowired
public void setUserService(IUserService userService) { public void setUserService(IUserService userService) {
this.userService = userService; this.userService = userService;
} }
...@@ -88,6 +98,12 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl ...@@ -88,6 +98,12 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
projectExt.setProjectId(project.getProjectId()); projectExt.setProjectId(project.getProjectId());
projectExt.setProjectDetail(detail); projectExt.setProjectDetail(detail);
projectExtService.save(projectExt); projectExtService.save(projectExt);
// 4.发送消息到消息队列
messageQueueService
.sendItemUpdateMessage(
DataItemUpdateMessage.addMessage(SearchItemType.PROJECT, project.getProjectId())
);
} }
@Override @Override
...@@ -119,6 +135,12 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl ...@@ -119,6 +135,12 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
// 删除项目 // 删除项目
removeById(projectId); removeById(projectId);
// 4.发送消息到消息队列
messageQueueService
.sendItemUpdateMessage(
DataItemUpdateMessage.deleteMessage(SearchItemType.PROJECT, project.getProjectId())
);
} }
@Override @Override
...@@ -191,6 +213,12 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl ...@@ -191,6 +213,12 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
projectExtService.updateById(projectExt); projectExtService.updateById(projectExt);
} }
// 4.发送消息到消息队列
messageQueueService
.sendItemUpdateMessage(
DataItemUpdateMessage.updateMessage(SearchItemType.PROJECT, project.getProjectId())
);
} }
@Override @Override
......
...@@ -8,7 +8,7 @@ import cn.meteor.beyondclouds.core.api.Response; ...@@ -8,7 +8,7 @@ import cn.meteor.beyondclouds.core.api.Response;
import cn.meteor.beyondclouds.core.bean.Subject; import cn.meteor.beyondclouds.core.bean.Subject;
import cn.meteor.beyondclouds.core.validation.groups.InsertGroup; import cn.meteor.beyondclouds.core.validation.groups.InsertGroup;
import cn.meteor.beyondclouds.core.validation.groups.UpdateGroup; import cn.meteor.beyondclouds.core.validation.groups.UpdateGroup;
import cn.meteor.beyondclouds.modules.question.bean.QuestionDetails; import cn.meteor.beyondclouds.modules.question.bean.QuestionDetail;
import cn.meteor.beyondclouds.modules.question.entity.Question; import cn.meteor.beyondclouds.modules.question.entity.Question;
import cn.meteor.beyondclouds.modules.question.exception.QuestionServiceException; import cn.meteor.beyondclouds.modules.question.exception.QuestionServiceException;
import cn.meteor.beyondclouds.modules.question.exception.QuestionTagServiceException; import cn.meteor.beyondclouds.modules.question.exception.QuestionTagServiceException;
...@@ -140,11 +140,11 @@ public class QuestionApi { ...@@ -140,11 +140,11 @@ public class QuestionApi {
@Anonymous @Anonymous
@ApiOperation("问题详情") @ApiOperation("问题详情")
@GetMapping("/question/{questionId}") @GetMapping("/question/{questionId}")
public Response<QuestionDetails> questionDetails(@PathVariable("questionId") String questionId) { public Response<QuestionDetail> questionDetails(@PathVariable("questionId") String questionId) {
QuestionDetails questionDetails = null; QuestionDetail questionDetail = null;
try { try {
questionDetails = questionService.questionDetails(questionId); questionDetail = questionService.questionDetails(questionId);
return Response.success(questionDetails); return Response.success(questionDetail);
} catch (QuestionServiceException | QuestionTagServiceException e) { } catch (QuestionServiceException | QuestionTagServiceException e) {
e.printStackTrace(); e.printStackTrace();
return Response.error(e); return Response.error(e);
......
...@@ -11,7 +11,7 @@ import lombok.Data; ...@@ -11,7 +11,7 @@ import lombok.Data;
*/ */
@ApiModel("问题详情") @ApiModel("问题详情")
@Data @Data
public class QuestionDetails extends Question { public class QuestionDetail extends Question {
@ApiModelProperty("详情") @ApiModelProperty("详情")
private String questionDetail; private String questionDetail;
......
package cn.meteor.beyondclouds.modules.question.service; package cn.meteor.beyondclouds.modules.question.service;
import cn.meteor.beyondclouds.modules.question.bean.QuestionDetails; import cn.meteor.beyondclouds.modules.question.bean.QuestionDetail;
import cn.meteor.beyondclouds.modules.question.entity.Question; import cn.meteor.beyondclouds.modules.question.entity.Question;
import cn.meteor.beyondclouds.modules.question.exception.QuestionServiceException; import cn.meteor.beyondclouds.modules.question.exception.QuestionServiceException;
import cn.meteor.beyondclouds.modules.question.exception.QuestionTagServiceException; import cn.meteor.beyondclouds.modules.question.exception.QuestionTagServiceException;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import java.util.HashSet;
import java.util.List; import java.util.List;
/** /**
...@@ -57,7 +56,7 @@ public interface IQuestionService extends IService<Question> { ...@@ -57,7 +56,7 @@ public interface IQuestionService extends IService<Question> {
* @throws QuestionServiceException 问题业务异常 * @throws QuestionServiceException 问题业务异常
* @throws QuestionTagServiceException 问题标签业务异常 * @throws QuestionTagServiceException 问题标签业务异常
*/ */
QuestionDetails questionDetails(String questionId) throws QuestionServiceException, QuestionTagServiceException; QuestionDetail questionDetails(String questionId) throws QuestionServiceException, QuestionTagServiceException;
/** /**
* 获取问答列表 * 获取问答列表
......
package cn.meteor.beyondclouds.modules.question.service.impl; package cn.meteor.beyondclouds.modules.question.service.impl;
import cn.meteor.beyondclouds.modules.question.bean.QuestionDetails; import cn.meteor.beyondclouds.modules.question.bean.QuestionDetail;
import cn.meteor.beyondclouds.modules.question.entity.*; import cn.meteor.beyondclouds.modules.question.entity.*;
import cn.meteor.beyondclouds.modules.question.enums.QuestionErrorCode; import cn.meteor.beyondclouds.modules.question.enums.QuestionErrorCode;
import cn.meteor.beyondclouds.modules.question.enums.QuestionTagErrorCode; import cn.meteor.beyondclouds.modules.question.enums.QuestionTagErrorCode;
...@@ -9,6 +9,9 @@ import cn.meteor.beyondclouds.modules.question.exception.QuestionTagServiceExcep ...@@ -9,6 +9,9 @@ import cn.meteor.beyondclouds.modules.question.exception.QuestionTagServiceExcep
import cn.meteor.beyondclouds.modules.question.mapper.QuestionMapper; import cn.meteor.beyondclouds.modules.question.mapper.QuestionMapper;
import cn.meteor.beyondclouds.modules.question.service.*; import cn.meteor.beyondclouds.modules.question.service.*;
import cn.meteor.beyondclouds.modules.question.util.QuestionUtils; import cn.meteor.beyondclouds.modules.question.util.QuestionUtils;
import cn.meteor.beyondclouds.modules.queue.message.DataItemUpdateMessage;
import cn.meteor.beyondclouds.modules.queue.service.IMessageQueueService;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import cn.meteor.beyondclouds.modules.tag.entity.Tag; import cn.meteor.beyondclouds.modules.tag.entity.Tag;
import cn.meteor.beyondclouds.modules.tag.service.ITagService; import cn.meteor.beyondclouds.modules.tag.service.ITagService;
import cn.meteor.beyondclouds.modules.topic.entity.Topic; import cn.meteor.beyondclouds.modules.topic.entity.Topic;
...@@ -69,6 +72,8 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i ...@@ -69,6 +72,8 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
private IUserService userService; private IUserService userService;
private IMessageQueueService messageQueueService;
@Autowired @Autowired
public QuestionServiceImpl(IQuestionExtService questionExtService, IQuestionCategoryService questionCategoryService, ITopicService topicService, ITopicReferenceService topicReferenceService, QuestionMapper questionMapper, IUserService userService) { public QuestionServiceImpl(IQuestionExtService questionExtService, IQuestionCategoryService questionCategoryService, ITopicService topicService, ITopicReferenceService topicReferenceService, QuestionMapper questionMapper, IUserService userService) {
this.questionExtService = questionExtService; this.questionExtService = questionExtService;
...@@ -80,6 +85,11 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i ...@@ -80,6 +85,11 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
} }
@Autowired @Autowired
public void setMessageQueueService(IMessageQueueService messageQueueService) {
this.messageQueueService = messageQueueService;
}
@Autowired
public void setQuestionReplyService(IQuestionReplyService questionReplyService) { public void setQuestionReplyService(IQuestionReplyService questionReplyService) {
this.questionReplyService = questionReplyService; this.questionReplyService = questionReplyService;
} }
...@@ -134,6 +144,12 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i ...@@ -134,6 +144,12 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
// 5.处理对话题和标签的引用 // 5.处理对话题和标签的引用
updateTopicAndTagReference(topicIds, tagIds, question.getQuestionId(), false); updateTopicAndTagReference(topicIds, tagIds, question.getQuestionId(), false);
// 6.发送消息到消息队列
messageQueueService
.sendItemUpdateMessage(
DataItemUpdateMessage.addMessage(SearchItemType.QUESTION, question.getQuestionId())
);
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
...@@ -170,6 +186,12 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i ...@@ -170,6 +186,12 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
//8.删除话题引用表中的问题信息 //8.删除话题引用表中的问题信息
topicReferenceService.remove(QuestionUtils.getWrapper("referencer_id", question.getQuestionId())); topicReferenceService.remove(QuestionUtils.getWrapper("referencer_id", question.getQuestionId()));
// 9.发送消息到消息队列
messageQueueService
.sendItemUpdateMessage(
DataItemUpdateMessage.deleteMessage(SearchItemType.QUESTION, question.getQuestionId())
);
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
...@@ -212,10 +234,16 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i ...@@ -212,10 +234,16 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
// 5.处理对话题和标签的引用 // 5.处理对话题和标签的引用
updateTopicAndTagReference(topicIds, tagIds, question.getQuestionId(), true); updateTopicAndTagReference(topicIds, tagIds, question.getQuestionId(), true);
// 6.发送消息到消息队列
messageQueueService
.sendItemUpdateMessage(
DataItemUpdateMessage.updateMessage(SearchItemType.QUESTION, question.getQuestionId())
);
} }
@Override @Override
public QuestionDetails questionDetails(String questionId) throws QuestionServiceException, QuestionTagServiceException { public QuestionDetail questionDetails(String questionId) throws QuestionServiceException, QuestionTagServiceException {
//1.获取问题基本信息 //1.获取问题基本信息
Question question = getById(questionId); Question question = getById(questionId);
...@@ -259,10 +287,10 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i ...@@ -259,10 +287,10 @@ public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> i
} }
//7.生成问题详情对象 //7.生成问题详情对象
QuestionDetails questionDetails = new QuestionDetails(); QuestionDetail questionDetail = new QuestionDetail();
BeanUtils.copyProperties(question, questionDetails); BeanUtils.copyProperties(question, questionDetail);
questionDetails.setQuestionDetail(questionExt.getQuestionDetail()); questionDetail.setQuestionDetail(questionExt.getQuestionDetail());
return questionDetails; return questionDetail;
} }
......
package cn.meteor.beyondclouds.modules.queue.message;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.io.Serializable;
/**
* 条目更新消息
* @author meteor
*/
@Data
@ToString
@NoArgsConstructor
public class DataItemUpdateMessage {
public DataItemUpdateMessage(SearchItemUpdateType updateType, SearchItemType itemType, Serializable itemId) {
this.itemId = itemId;
this.itemType = itemType;
this.updateType = updateType;
}
public static DataItemUpdateMessage addMessage(SearchItemType itemType, Serializable itemId) {
return new DataItemUpdateMessage(SearchItemUpdateType.ADD, itemType, itemId);
}
public static DataItemUpdateMessage deleteMessage(SearchItemType itemType, Serializable itemId) {
return new DataItemUpdateMessage(SearchItemUpdateType.DELETE, itemType, itemId);
}
public static DataItemUpdateMessage updateMessage(SearchItemType itemType, Serializable itemId) {
return new DataItemUpdateMessage(SearchItemUpdateType.UPDATE, itemType, itemId);
}
/**
* 条目ID
*/
private Serializable itemId;
/**
* 条目类型
*/
private SearchItemType itemType;
/**
* 条目更新类型
*/
private SearchItemUpdateType updateType;
}
package cn.meteor.beyondclouds.modules.queue.message;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
/**
* 搜索条目改变操作类型
* @author meteor
*/
public enum SearchItemUpdateType {
/**
* 新增条目
*/
ADD,
/**
* 删除条目
*/
DELETE,
/**
* 更新条目
*/
UPDATE
}
package cn.meteor.beyondclouds.modules.queue.service;
import cn.meteor.beyondclouds.modules.queue.message.DataItemUpdateMessage;
/**
* @author meteor
*/
public interface IMessageQueueService {
/**
* 发送搜索条目更新消息
* @param itemUpdateMessage
*/
void sendItemUpdateMessage(DataItemUpdateMessage itemUpdateMessage);
}
package cn.meteor.beyondclouds.modules.queue.service.impl;
import cn.meteor.beyondclouds.config.properties.BeyondCloudsKafkaTopicProperties;
import cn.meteor.beyondclouds.modules.queue.message.DataItemUpdateMessage;
import cn.meteor.beyondclouds.modules.queue.service.IMessageQueueService;
import cn.meteor.beyondclouds.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
/**
* @author meteor
*/
@Service
@Slf4j
public class MessageQueueServiceImpl implements IMessageQueueService {
private KafkaTemplate<String, String> kafkaTemplate;
private BeyondCloudsKafkaTopicProperties topicProperties;
@Autowired
public MessageQueueServiceImpl(KafkaTemplate<String, String> kafkaTemplate, BeyondCloudsKafkaTopicProperties topicProperties) {
this.kafkaTemplate = kafkaTemplate;
this.topicProperties = topicProperties;
}
@Override
public void sendItemUpdateMessage(DataItemUpdateMessage itemUpdateMessage) {
try {
kafkaTemplate.send(topicProperties.getSearchItemUpdate(), JsonUtils.toJson(itemUpdateMessage));
log.debug("发送kafka消息:{}", itemUpdateMessage.toString());
} catch (Exception e) {
e.printStackTrace();
log.error("Kafka消息发送失败:{}", e.getMessage());
}
}
}
package cn.meteor.beyondclouds.modules.search.entity;
import cn.meteor.beyondclouds.modules.blog.bean.BlogDetail;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.util.Date;
/**
* @author meteor
*/
@ToString
@Data
@NoArgsConstructor
@Document(indexName = "search_item")
public class SearchItem {
/**
* 快捷构造函数
* 设置数据条目的主键,itemType和itemId
* @param itemType
* @param itemId
*/
public SearchItem(SearchItemType itemType, String itemId) {
this.id = SearchItemId.of(itemType, itemId);
this.itemType = itemType;
this.itemId = itemId;
}
@Id
private SearchItemId id;
/**
* 数据的主键
*/
@Field(index = false, type = FieldType.Text)
private String itemId;
/**
* 数据类型
*/
@Field(index = false, type = FieldType.Text)
private SearchItemType itemType;
/**
* 数据标题
*/
@Field(analyzer = "ik_max_word", type = FieldType.Text)
private String title;
/**
* 数据封面图
*/
@Field(index = false, type = FieldType.Text)
private String cover;
/**
* 数据摘要
*/
@Field(analyzer = "ik_max_word", type = FieldType.Text)
private String description;
/**
* 数据内容
*/
@Field(analyzer = "ik_max_word", type = FieldType.Text)
private String content;
/**
* 数据创建时间
*/
@Field(index = false, type = FieldType.Date)
private Date createTime;
/**
* 数据更新时间
*/
@Field(index = false, type = FieldType.Date)
private Date updateTime;
public static SearchItem of(BlogDetail blogDetail) {
return null;
}
}
package cn.meteor.beyondclouds.modules.search.entity;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author meteor
*/
@Data
@NoArgsConstructor
public class SearchItemId {
private SearchItemType itemType;
private String itemId;
public SearchItemId(SearchItemType itemType, String itemId) {
this.itemType = itemType;
this.itemId = itemId;
}
public static SearchItemId of(SearchItemType searchItemType, String itemId) {
return new SearchItemId(searchItemType, itemId);
}
@Override
public String toString() {
return itemType.name() + ":" + itemId;
}
}
package cn.meteor.beyondclouds.modules.search.enums;
import cn.meteor.beyondclouds.modules.blog.entity.Blog;
import cn.meteor.beyondclouds.modules.project.entity.Project;
import cn.meteor.beyondclouds.modules.question.entity.Question;
import cn.meteor.beyondclouds.modules.tag.entity.Tag;
import cn.meteor.beyondclouds.modules.user.entity.User;
import lombok.Data;
import lombok.Getter;
/**
* @author meteor
*/
@Getter
public enum SearchItemType {
/**
* 用户
*/
USER(User.class),
/**
* 博客
*/
BLOG(Blog.class),
/**
* 项目
*/
PROJECT(Project.class),
/**
* 问答
*/
QUESTION(Question.class);
private Class<?> classOfItem;
SearchItemType(Class<?> classOfItem) {
this.classOfItem = classOfItem;
}
}
package cn.meteor.beyondclouds.modules.search.listener;
import org.apache.kafka.clients.consumer.ConsumerRecord;
/**
* @author meteor
*/
public interface ISearchItemUpdateListener {
/**
* 搜索条目更新
* @param record
*/
void onSearchItemUpdate(ConsumerRecord<?, String> record);
}
package cn.meteor.beyondclouds.modules.search.listener.impl;
import cn.meteor.beyondclouds.modules.queue.message.DataItemUpdateMessage;
import cn.meteor.beyondclouds.modules.queue.message.SearchItemUpdateType;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import cn.meteor.beyondclouds.modules.search.listener.ISearchItemUpdateListener;
import cn.meteor.beyondclouds.modules.search.service.ISearchService;
import cn.meteor.beyondclouds.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import java.io.Serializable;
import java.util.Optional;
/**
* @author meteor
*/
@Component
@Slf4j
public class SearchItemUpdateListener implements ISearchItemUpdateListener {
private ISearchService searchService;
@Autowired
public SearchItemUpdateListener(ISearchService searchService) {
this.searchService = searchService;
}
@Override
@KafkaListener(topics = "${beyondclouds.kafka.topics.search-item-update}")
public void onSearchItemUpdate(ConsumerRecord<?, String> record) {
Optional<String> kafkaMessage = Optional.ofNullable(record.value());
if (kafkaMessage.isPresent()) {
DataItemUpdateMessage itemUpdateMessage;
try {
itemUpdateMessage = JsonUtils.toBean(kafkaMessage.get(), DataItemUpdateMessage.class);
log.debug("接收到kafka消息:{}", itemUpdateMessage.toString());
// 处理搜索条目更新
SearchItemUpdateType updateType = itemUpdateMessage.getUpdateType();
Serializable itemId = itemUpdateMessage.getItemId();
SearchItemType searchItemType = itemUpdateMessage.getItemType();
// 根据不同的更新类型调用对应的方法
switch (updateType) {
case ADD:
searchService.saveSearchItem(searchItemType, String.valueOf(itemId) );
break;
case DELETE:
searchService.deleteSearchItem(searchItemType, String.valueOf(itemId));
break;
case UPDATE:
searchService.updateSearchItem(searchItemType, String.valueOf(itemId));
break;
default:
break;
}
} catch (Exception e) {
e.printStackTrace();
log.error("searchItemUpdateMessage covert failed:{}", e.getMessage());
}
}
}
}
package cn.meteor.beyondclouds.modules.search.repository;
import cn.meteor.beyondclouds.modules.search.entity.SearchItem;
import cn.meteor.beyondclouds.modules.search.entity.SearchItemId;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
/**
* @author meteor
*/
@Repository
public interface ISearchRepository extends ElasticsearchRepository<SearchItem, SearchItemId> {
}
package cn.meteor.beyondclouds.modules.search.service;
import cn.meteor.beyondclouds.modules.search.entity.SearchItem;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import java.util.Optional;
/**
* @author meteor
*/
public interface ISearchService {
/**
* 添加搜索条目
* @param searchItemType
* @param itemId
*/
void saveSearchItem(SearchItemType searchItemType, String itemId);
/**
* 删除搜索条目
* @param searchItemType
* @param itemId
*/
void deleteSearchItem(SearchItemType searchItemType, String itemId);
/**
* 更新搜索条目
* @param searchItemType
* @param itemId
*/
void updateSearchItem(SearchItemType searchItemType, String itemId);
/**
* 查找搜索条目
* @param searchItemType
* @param itemId
* @return
*/
Optional<SearchItem> getSearchItem(SearchItemType searchItemType, String itemId);
}
package cn.meteor.beyondclouds.modules.search.service.impl;
import cn.meteor.beyondclouds.core.bean.Subject;
import cn.meteor.beyondclouds.modules.blog.bean.BlogDetail;
import cn.meteor.beyondclouds.modules.blog.exception.BlogServiceException;
import cn.meteor.beyondclouds.modules.blog.service.IBlogService;
import cn.meteor.beyondclouds.modules.project.bean.ProjectDetail;
import cn.meteor.beyondclouds.modules.project.exception.ProjectServiceException;
import cn.meteor.beyondclouds.modules.project.service.IProjectService;
import cn.meteor.beyondclouds.modules.question.bean.QuestionDetail;
import cn.meteor.beyondclouds.modules.question.exception.QuestionServiceException;
import cn.meteor.beyondclouds.modules.question.exception.QuestionTagServiceException;
import cn.meteor.beyondclouds.modules.question.service.IQuestionService;
import cn.meteor.beyondclouds.modules.queue.message.DataItemUpdateMessage;
import cn.meteor.beyondclouds.modules.queue.message.SearchItemUpdateType;
import cn.meteor.beyondclouds.modules.search.entity.SearchItem;
import cn.meteor.beyondclouds.modules.search.entity.SearchItemId;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import cn.meteor.beyondclouds.modules.search.repository.ISearchRepository;
import cn.meteor.beyondclouds.modules.search.service.ISearchService;
import cn.meteor.beyondclouds.modules.topic.service.ITopicService;
import cn.meteor.beyondclouds.modules.user.entity.User;
import cn.meteor.beyondclouds.modules.user.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Optional;
/**
* @author meteor
*/
@Service
@Slf4j
public class SearchServiceImpl implements ISearchService {
private ISearchRepository searchRepository;
private IBlogService blogService;
private IProjectService projectService;
private ITopicService topicService;
private IUserService userService;
private IQuestionService questionService;
@Autowired
public SearchServiceImpl(ISearchRepository searchRepository, IBlogService blogService, IProjectService projectService, ITopicService topicService, IUserService userService, IQuestionService questionService) {
this.searchRepository = searchRepository;
this.blogService = blogService;
this.projectService = projectService;
this.topicService = topicService;
this.userService = userService;
this.questionService = questionService;
}
@Override
public void saveSearchItem(SearchItemType itemType, String itemId) {
SearchItem searchItem = getSearchItemInDb(itemType, itemId);
if (null != searchItem) {
searchRepository.save(searchItem);
log.debug("elasticsearch-save:{}", searchItem);
}
}
@Override
public void deleteSearchItem(SearchItemType itemType, String itemId) {
searchRepository.deleteById(SearchItemId.of(itemType, itemId));
log.debug("elasticsearch-delete:{}", SearchItemId.of(itemType, itemId));
}
@Override
public void updateSearchItem(SearchItemType itemType, String itemId) {
SearchItem searchItem = getSearchItemInDb(itemType, itemId);
searchRepository.save(searchItem);
log.debug("elasticsearch-update:{}", searchItem);
}
@Override
public Optional<SearchItem> getSearchItem(SearchItemType itemType, String itemId) {
return searchRepository.findById(SearchItemId.of(itemType, itemId));
}
private SearchItem getSearchItemInDb(SearchItemType itemType, String itemId) {
SearchItem searchItem = null;
try {
switch (itemType) {
case BLOG:
searchItem = buildSearchItemFromBlog(itemId);
break;
case PROJECT:
searchItem = buildSearchItemFromProject(itemId);
break;
case USER:
searchItem = buildSearchItemFromUser(itemId);
break;
case QUESTION:
searchItem = buildSearchItemFromQuestion(itemId);
break;
default:
return null;
}
} catch (Exception e) {
e.printStackTrace();
log.error("搜索条目存储失败:{}", e.getMessage());
}
return searchItem;
}
private SearchItem buildSearchItemFromProject(String projectId) throws ProjectServiceException {
ProjectDetail projectDetail = projectService.getProject(projectId);
if (null != projectDetail) {
SearchItem searchItem = new SearchItem(SearchItemType.PROJECT, projectId);
searchItem.setTitle(projectDetail.getProjectName());
searchItem.setContent(projectDetail.getProjectDetail());
searchItem.setCover(projectDetail.getCover());
searchItem.setDescription(projectDetail.getProjectDescription());
searchItem.setCreateTime(projectDetail.getCreateTime());
searchItem.setUpdateTime(projectDetail.getUpdateTime());
return searchItem;
}
return null;
}
private SearchItem buildSearchItemFromUser(String userId) {
User user = userService.getById(userId);
if (null != user) {
SearchItem searchItem = new SearchItem(SearchItemType.USER, userId);
searchItem.setTitle(user.getNickName());
searchItem.setCover(user.getUserAvatar());
searchItem.setDescription(user.getSignature());
searchItem.setCreateTime(user.getCreateTime());
searchItem.setUpdateTime(user.getUpdateTime());
}
return null;
}
private SearchItem buildSearchItemFromQuestion(String questionId) throws QuestionServiceException, QuestionTagServiceException {
QuestionDetail questionDetail = questionService.questionDetails(questionId);
if (null != questionDetail) {
SearchItem searchItem = new SearchItem(SearchItemType.QUESTION, questionId);
searchItem.setTitle(questionDetail.getQuestionTitle());
searchItem.setContent(questionDetail.getQuestionDetail());
searchItem.setDescription(questionDetail.getQuestionAbstract());
searchItem.setCreateTime(questionDetail.getCreateTime());
searchItem.setUpdateTime(questionDetail.getUpdateTime());
return searchItem;
}
return null;
}
private SearchItem buildSearchItemFromBlog(String blogId) throws BlogServiceException {
BlogDetail blogDetail = blogService.getBlog(blogId, Subject.anonymous(this.getClass().getName()));
if (null != blogDetail) {
SearchItem searchItem = new SearchItem(SearchItemType.BLOG, blogId);
searchItem.setTitle(blogDetail.getBlogTitle());
searchItem.setContent(blogDetail.getContent());
searchItem.setCover(blogDetail.getCover());
searchItem.setDescription(blogDetail.getBlogAbstract());
searchItem.setCreateTime(blogDetail.getCreateTime());
searchItem.setUpdateTime(blogDetail.getUpdateTime());
return searchItem;
}
return null;
}
}
...@@ -14,6 +14,9 @@ import cn.meteor.beyondclouds.modules.project.entity.Project; ...@@ -14,6 +14,9 @@ import cn.meteor.beyondclouds.modules.project.entity.Project;
import cn.meteor.beyondclouds.modules.project.service.IProjectService; import cn.meteor.beyondclouds.modules.project.service.IProjectService;
import cn.meteor.beyondclouds.modules.question.entity.Question; import cn.meteor.beyondclouds.modules.question.entity.Question;
import cn.meteor.beyondclouds.modules.question.service.IQuestionService; import cn.meteor.beyondclouds.modules.question.service.IQuestionService;
import cn.meteor.beyondclouds.modules.queue.message.DataItemUpdateMessage;
import cn.meteor.beyondclouds.modules.queue.service.IMessageQueueService;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import cn.meteor.beyondclouds.modules.tag.entity.Tag; import cn.meteor.beyondclouds.modules.tag.entity.Tag;
import cn.meteor.beyondclouds.modules.tag.service.ITagService; import cn.meteor.beyondclouds.modules.tag.service.ITagService;
import cn.meteor.beyondclouds.modules.user.entity.User; import cn.meteor.beyondclouds.modules.user.entity.User;
...@@ -63,6 +66,8 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I ...@@ -63,6 +66,8 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I
private IProjectService projectService; private IProjectService projectService;
private IBlogService blogService; private IBlogService blogService;
private IMessageQueueService messageQueueService;
@Autowired @Autowired
public UserServiceImpl(IUserAuthLocalService userAuthLocalService, IRedisHelper redisHelper, IUserAuthAppService userAuthAppService, IMailService mailService) { public UserServiceImpl(IUserAuthLocalService userAuthLocalService, IRedisHelper redisHelper, IUserAuthAppService userAuthAppService, IMailService mailService) {
this.userAuthLocalService = userAuthLocalService; this.userAuthLocalService = userAuthLocalService;
...@@ -72,6 +77,11 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I ...@@ -72,6 +77,11 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I
} }
@Autowired @Autowired
public void setMessageQueueService(IMessageQueueService messageQueueService) {
this.messageQueueService = messageQueueService;
}
@Autowired
public void setUserFollowService(IUserFollowService userFollowService) { public void setUserFollowService(IUserFollowService userFollowService) {
this.userFollowService = userFollowService; this.userFollowService = userFollowService;
} }
...@@ -227,6 +237,12 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I ...@@ -227,6 +237,12 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I
@Override @Override
public void alterBaseInfo(User user) throws UserServiceException { public void alterBaseInfo(User user) throws UserServiceException {
updateById(user); updateById(user);
// 发送消息到消息队列
messageQueueService
.sendItemUpdateMessage(
DataItemUpdateMessage.updateMessage(SearchItemType.USER, user.getUserId())
);
} }
@Override @Override
......
spring: spring:
# 数据源
datasource: datasource:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/beyond_clouds?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true url: jdbc:mysql://127.0.0.1:3306/beyond_clouds?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
username: beyond username: beyond
password: Beyond2020# password: Beyond2020#
# 邮箱
mail: mail:
host: smtp.163.com host: smtp.163.com
username: 13546386889@163.com username: 13546386889@163.com
...@@ -21,10 +25,32 @@ spring: ...@@ -21,10 +25,32 @@ spring:
socketFactory: socketFactory:
fallback: false fallback: false
# elasticsearch
data:
elasticsearch:
repositories:
enabled: false
elasticsearch:
rest:
uris: http://localhost:9200
# kafka
kafka:
bootstrap-servers: 127.0.0.1:9092
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
consumer:
group-id: beyond-clouds
enable-auto-commit: true
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
# swagger
swagger: swagger:
enable: true enable: true
# 阿里云
aliyun: aliyun:
access-key-id: LTAIeHWeydaWT3ZZ access-key-id: LTAIeHWeydaWT3ZZ
access-key-secret: 2FTWlODpzEZjsBQw10NO6SUBMwYOcL access-key-secret: 2FTWlODpzEZjsBQw10NO6SUBMwYOcL
...@@ -39,9 +65,17 @@ aliyun: ...@@ -39,9 +65,17 @@ aliyun:
region-id: cn-hangzhou region-id: cn-hangzhou
sign-name: 段启岩 sign-name: 段启岩
template-code-map: {verifyCode: SMS_142384912} template-code-map: {verifyCode: SMS_142384912}
# mybatis-plus
mybatis-plus: mybatis-plus:
mapper-locations: classpath*:cn/meteor/beyondclouds/modules/**/xml/*.xml mapper-locations: classpath*:cn/meteor/beyondclouds/modules/**/xml/*.xml
logging:
level:
cn:
meteor:
beyondclouds: debug
# 云里云外
beyondclouds: beyondclouds:
debug: true debug: true
auth: auth:
...@@ -49,3 +83,6 @@ beyondclouds: ...@@ -49,3 +83,6 @@ beyondclouds:
client-id: 101846021 client-id: 101846021
client-secret: 5bc41deeb7e152e2e6aff97726bbf86a client-secret: 5bc41deeb7e152e2e6aff97726bbf86a
redirect-uri: http://meteor.natapp1.cc/auth/qq redirect-uri: http://meteor.natapp1.cc/auth/qq
kafka:
topics:
search-item-update: topic.beyondclouds.searchitem.update
\ No newline at end of file
spring: spring:
# 数据源
datasource: datasource:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/beyond_clouds?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true url: jdbc:mysql://127.0.0.1:3306/beyond_clouds?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
username: beyond username: beyond
password: Beyond2020# password: Beyond2020#
# 邮箱
mail: mail:
host: smtp.163.com host: smtp.163.com
username: 13546386889@163.com username: 13546386889@163.com
...@@ -20,10 +24,33 @@ spring: ...@@ -20,10 +24,33 @@ spring:
ssl: ssl:
socketFactory: socketFactory:
fallback: false fallback: false
# elasticsearch
data:
elasticsearch:
repositories:
enabled: false
elasticsearch:
rest:
uris: http://localhost:9200
# kafka
kafka:
bootstrap-servers: 127.0.0.1:9092
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
consumer:
group-id: beyond-clouds
enable-auto-commit: true
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
# swagger
swagger: swagger:
enable: true enable: true
# 阿里云
aliyun: aliyun:
access-key-id: LTAIeHWeydaWT3ZZ access-key-id: LTAIeHWeydaWT3ZZ
access-key-secret: 2FTWlODpzEZjsBQw10NO6SUBMwYOcL access-key-secret: 2FTWlODpzEZjsBQw10NO6SUBMwYOcL
...@@ -38,13 +65,24 @@ aliyun: ...@@ -38,13 +65,24 @@ aliyun:
region-id: cn-hangzhou region-id: cn-hangzhou
sign-name: 段启岩 sign-name: 段启岩
template-code-map: {verifyCode: SMS_142384912} template-code-map: {verifyCode: SMS_142384912}
# mybatis-plus
mybatis-plus: mybatis-plus:
mapper-locations: classpath*:cn/meteor/beyondclouds/modules/**/xml/*.xml mapper-locations: classpath*:cn/meteor/beyondclouds/modules/**/xml/*.xml
logging:
level:
cn:
meteor:
beyondclouds: debug
# 云里云外
beyondclouds: beyondclouds:
debug: false debug: true
auth: auth:
qq: qq:
client-id: 101846021 client-id: 101846021
client-secret: 5bc41deeb7e152e2e6aff97726bbf86a client-secret: 5bc41deeb7e152e2e6aff97726bbf86a
redirect-uri: http://meteor.natapp1.cc/auth/qq redirect-uri: http://meteor.natapp1.cc/auth/qq
\ No newline at end of file kafka:
topics:
search-item-update: topic.beyondclouds.searchitem.update
\ No newline at end of file
spring: spring:
# 数据源
datasource: datasource:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/beyond_clouds?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true url: jdbc:mysql://127.0.0.1:3306/beyond_clouds?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
username: root username: root
password: 197442 password: 100Centa30821%mysql
# 邮箱
mail: mail:
host: smtp.163.com host: smtp.163.com
username: 13546386889@163.com username: 13546386889@163.com
...@@ -21,11 +25,32 @@ spring: ...@@ -21,11 +25,32 @@ spring:
socketFactory: socketFactory:
fallback: false fallback: false
# elasticsearch
data:
elasticsearch:
repositories:
enabled: false
elasticsearch:
rest:
uris: http://localhost:9200
# kafka
kafka:
bootstrap-servers: 127.0.0.1:9092
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
consumer:
group-id: beyond-clouds
enable-auto-commit: true
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
# swagger
swagger: swagger:
enable: true enable: true
# 阿里云
aliyun: aliyun:
access-key-id: LTAIeHWeydaWT3ZZ access-key-id: LTAIeHWeydaWT3ZZ
access-key-secret: 2FTWlODpzEZjsBQw10NO6SUBMwYOcL access-key-secret: 2FTWlODpzEZjsBQw10NO6SUBMwYOcL
...@@ -40,6 +65,8 @@ aliyun: ...@@ -40,6 +65,8 @@ aliyun:
region-id: cn-hangzhou region-id: cn-hangzhou
sign-name: 段启岩 sign-name: 段启岩
template-code-map: {verifyCode: SMS_142384912} template-code-map: {verifyCode: SMS_142384912}
# mybatis-plus
mybatis-plus: mybatis-plus:
mapper-locations: classpath*:cn/meteor/beyondclouds/modules/**/xml/*.xml mapper-locations: classpath*:cn/meteor/beyondclouds/modules/**/xml/*.xml
logging: logging:
...@@ -47,10 +74,15 @@ logging: ...@@ -47,10 +74,15 @@ logging:
cn: cn:
meteor: meteor:
beyondclouds: debug beyondclouds: debug
# 云里云外
beyondclouds: beyondclouds:
debug: true debug: true
auth: auth:
qq: qq:
client-id: 101846021 client-id: 101846021
client-secret: 5bc41deeb7e152e2e6aff97726bbf86a client-secret: 5bc41deeb7e152e2e6aff97726bbf86a
redirect-uri: http://meteor.natapp1.cc/auth/qq redirect-uri: http://meteor.natapp1.cc/auth/qq
\ No newline at end of file kafka:
topics:
search-item-update: topic.beyondclouds.searchitem.update
\ No newline at end of file
package cn.meteor.beyondclouds.modules.queue.service.impl;
import cn.meteor.beyondclouds.modules.queue.message.DataItemUpdateMessage;
import cn.meteor.beyondclouds.modules.queue.message.SearchItemUpdateType;
import cn.meteor.beyondclouds.modules.queue.service.IMessageQueueService;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest
@RunWith(SpringRunner.class)
public class MessageQueueServiceImplTest {
@Autowired
private IMessageQueueService messageQueueService;
@Test
public void send() {
// System.out.println(messageQueueService);
// Message message = new Message();
// message.setId("111L");
// message.setMsg("hello");
// messageQueueService.send(message);
DataItemUpdateMessage itemUpdateMessage = new DataItemUpdateMessage();
itemUpdateMessage.setItemId("123");
itemUpdateMessage.setItemType(SearchItemType.PROJECT);
itemUpdateMessage.setUpdateType(SearchItemUpdateType.ADD);
messageQueueService.sendItemUpdateMessage(itemUpdateMessage);
}
}
\ No newline at end of file
package cn.meteor.beyondclouds.modules.search.repository;
import cn.meteor.beyondclouds.modules.search.entity.SearchItem;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import org.elasticsearch.index.query.DisMaxQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Date;
@SpringBootTest
@RunWith(SpringRunner.class)
public class ISearchRepositoryTest {
@Autowired
private ISearchRepository searchRepository;
@Test
public void test() {
System.out.println(searchRepository);
SearchItem searchItem = new SearchItem();
searchItem.setContent("我爱中国");
searchItem.setCover("null");
searchItem.setDescription("测试");
searchItem.setTitle("ok");
searchItem.setCreateTime(new Date());
searchItem.setItemId("aad");
searchItem.setItemType(SearchItemType.BLOG);
searchRepository.save(searchItem);
}
@Test
public void testQuery() {
QueryBuilder queryBuilder = QueryBuilders.matchQuery("content", "我们中国啊");
Iterable<SearchItem> searchItems = searchRepository.search(queryBuilder);
for (SearchItem searchItem : searchItems) {
System.out.println(searchItem);
}
}
/**
* 中文、拼音混合搜索
*
* @param content the content
* @return dis max query builder
*/
public DisMaxQueryBuilder structureQuery(String content) {
//使用dis_max直接取多个query中,分数最高的那一个query的分数即可
DisMaxQueryBuilder disMaxQueryBuilder = QueryBuilders.disMaxQuery();
//boost 设置权重,只搜索匹配name和disrector字段
QueryBuilder ikNameQuery = QueryBuilders.matchQuery("name", content).boost(2f);
QueryBuilder pinyinNameQuery = QueryBuilders.matchQuery("name.pinyin", content);
QueryBuilder ikDirectorQuery = QueryBuilders.matchQuery("director", content).boost(2f);
disMaxQueryBuilder.add(ikNameQuery);
disMaxQueryBuilder.add(pinyinNameQuery);
disMaxQueryBuilder.add(ikDirectorQuery);
return disMaxQueryBuilder;
}
}
\ No newline at end of file
package cn.meteor.beyondclouds.modules.search.service.impl;
import cn.meteor.beyondclouds.modules.search.entity.SearchItem;
import cn.meteor.beyondclouds.modules.search.enums.SearchItemType;
import cn.meteor.beyondclouds.modules.search.service.ISearchService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Optional;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class SearchServiceImplTest {
@Autowired
private ISearchService searchService;
@Test
public void saveSearchItem() {
searchService.saveSearchItem(SearchItemType.BLOG, "123");
}
@Test
public void getSearchItem() {
Optional<SearchItem> optionalSearchItem = searchService.getSearchItem(SearchItemType.BLOG, "123");
if (optionalSearchItem.isPresent()) {
System.out.println(optionalSearchItem.get());
}
}
}
\ No newline at end of file
...@@ -13,7 +13,7 @@ import static org.junit.Assert.*; ...@@ -13,7 +13,7 @@ import static org.junit.Assert.*;
@SpringBootTest @SpringBootTest
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
public class TagServiceImplTest { public class TagServiceQueueServiceImplTest {
@Autowired @Autowired
private ITagService tagService; private ITagService tagService;
......
...@@ -13,7 +13,7 @@ import static org.junit.Assert.*; ...@@ -13,7 +13,7 @@ import static org.junit.Assert.*;
@SpringBootTest @SpringBootTest
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
public class TopicServiceImplTest { public class TopicServiceQueueServiceImplTest {
@Autowired @Autowired
private ITopicService topicService; private ITopicService topicService;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment