Merge pull request #17 from linhaojun857/dev

merge dev
master
花未眠 3 years ago committed by GitHub
commit 5ebea15045
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1 @@
群号338371628

@ -1,4 +0,0 @@
## 交流群
| ![Communication group](https://github.com/linhaojun857/readme-images/blob/master/6c149c9bd586ee0cb9d3d41df605e40f.png) |
| ------------------------------------------------------------ |

@ -8,11 +8,7 @@
**后台链接:**[admin.linhaojun.top](https://admin.linhaojun.top)
演示账号test@163.com ,密码:123456 ,欢迎大家来到后台,如有不足,欢迎指正
Github地址[linhaojun857/aurora-public: aurora博客系统 (github.com)](https://github.com/linhaojun857/aurora-public)
Gitee地址[aurora-public-github: aurora博客系统 (gitee.com)](https://gitee.com/linhaojun/aurora-public-github) (readme图片展示不了)
演示账号test@163.com ,密码:123456
## 相关技术
@ -26,49 +22,9 @@ Gitee地址[aurora-public-github: aurora博客系统 (gitee.com)](https://git
springboot + springsecurity + mysql + redis + mybatisplus + quartz + rabbitmq + maxwell + elasticsearch + minio + docker + nginx
## 前台截图
![前台1](https://github.com/linhaojun857/readme-images/blob/master/7232dc518bfed9755c6266fdf5243e0d.png)
![前台2](https://github.com/linhaojun857/readme-images/blob/master/4d5d41fe49c2a42d6d756bde6a09d86c.png)
![前台3](https://github.com/linhaojun857/readme-images/blob/master/5e50616e20e1c9a9ea24bcb9cd25f428.png)
![前台4](https://github.com/linhaojun857/readme-images/blob/master/368d2b5787db9151286e079126e9f0bb.png)
![前台5](https://github.com/linhaojun857/readme-images/blob/master/a9db098405ead1bef9536a49187eef73.png)
## 后台截图
![后台1](https://github.com/linhaojun857/readme-images/blob/master/613edc1e2be6d21594add5a7549e1b16.png)
![后台2](https://github.com/linhaojun857/readme-images/blob/master/49a945612cb4f9fa92a11ba786e251bc.png)
![后台3](https://github.com/linhaojun857/readme-images/blob/master/d927b064ef199cabc9deb66b912d6e8d.png)
![后台4](https://github.com/linhaojun857/readme-images/blob/master/ea9a83ef3c79ca77587752205af0283a.png)
![后台5](https://github.com/linhaojun857/readme-images/blob/master/13ad9fc5299c095841101c9f24a06b9b.png)
## 将来的更新计划
1. 不断对此项目进行完善
2. 推出不同的前端主题
## 赞助
| Wechat 微信支付 | Alipay 支付宝支付 |
| :----------------------------------------------------------: | :----------------------------------------------------------: |
| <img src="https://github.com/linhaojun857/readme-images/blob/master/ed47edae605f74306f751c6fba9f14bd.png" alt="Buy Me A Coffee" width="150"> | <img src="https://github.com/linhaojun857/readme-images/blob/master/da4c6d8c13f66a8dd6716ddb48d73299.jpg" alt="Buy Me A Coffee" width="150"> |
## 鸣谢
感谢[网盾星球-SCDN](https://cdn.netdun.net/)提供的CDN支持
## 交流群
| ![Communication group](https://github.com/linhaojun857/readme-images/blob/master/6c149c9bd586ee0cb9d3d41df605e40f.png) |
| ------------------------------------------------------------ |

@ -44,6 +44,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>

@ -29,13 +29,11 @@ public class CommonConst {
/**
*
*/
// public static final String PRE_TAG = "<span style='color:#f47466'>";
public static final String PRE_TAG = "<mark>";
/**
*
*/
// public static final String POST_TAG = "</span>";
public static final String POST_TAG = "</mark>";
/**
@ -63,26 +61,11 @@ public class CommonConst {
*/
public static final String DEFAULT_NICKNAME = "用户";
/**
*
*/
public static String ARTICLE_SET = "articleSet";
/**
*
*/
public static String COMPONENT = "Layout";
/**
*
*/
public static final String PROVINCE = "省";
/**
*
*/
public static final String CITY = "市";
/**
*
*/
@ -109,4 +92,19 @@ public class CommonConst {
*/
public final static Integer TWENTY_MINUTES = 20;
/**
*
*/
public static final String CAPTCHA = "验证码";
/**
*
*/
public static final String CHECK_REMIND = "审核提醒";
/**
*
*/
public static final String COMMENT_REMIND = "评论提醒";
}

@ -2,15 +2,14 @@ package com.aurora.consumer;
import com.alibaba.fastjson.JSON;
import com.aurora.model.dto.EmailDTO;
import com.aurora.utils.EmailUtils;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
import static com.aurora.constant.CommonConst.*;
import static com.aurora.constant.MQPrefixConst.EMAIL_QUEUE;
/**
@ -21,23 +20,17 @@ import static com.aurora.constant.MQPrefixConst.EMAIL_QUEUE;
@RabbitListener(queues = EMAIL_QUEUE)
public class CommentNoticeConsumer {
/**
*
*/
@Value("${spring.mail.username}")
private String email;
@Autowired
private JavaMailSender javaMailSender;
private EmailUtils emailUtils;
@RabbitHandler
public void process(byte[] data) {
EmailDTO emailDTO = JSON.parseObject(new String(data), EmailDTO.class);
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(email);
message.setTo(emailDTO.getEmail());
message.setSubject(emailDTO.getSubject());
message.setText(emailDTO.getContent());
javaMailSender.send(message);
EmailDTO mailDTO = JSON.parseObject(new String(data), EmailDTO.class);
if (CAPTCHA.equals(mailDTO.getSubject()) || CHECK_REMIND.equals(mailDTO.getSubject())) {
emailUtils.sendSimpleMail(mailDTO);
}
if (COMMENT_REMIND.equals(mailDTO.getSubject())) {
emailUtils.sendHtmlMail(mailDTO);
}
}
}

@ -12,9 +12,9 @@ import lombok.Getter;
public enum CommentTypeEnum {
/**
*
*
*/
ARTICLE(1, "文章评论", "/articles/"),
ARTICLE(1, "文章", "/articles/"),
/**
*
@ -27,14 +27,14 @@ public enum CommentTypeEnum {
ABOUT(3, "关于我", "/about/"),
/**
*
*
*/
LINK(4, "友链评论", "/friends/"),
LINK(4, "友链", "/friends/"),
/**
*
*
*/
TALK(5, "说说评论", "/talks/");
TALK(5, "说说", "/talks/");
/**
*

@ -5,6 +5,8 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* @author
*
@ -30,4 +32,14 @@ public class EmailDTO {
*/
private String content;
/**
*
*/
private Map<String, Object> commentMap;
/**
*
*/
private String template;
}

@ -34,6 +34,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@ -92,8 +93,9 @@ public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> impl
.isReview(isCommentReview == TRUE ? FALSE : TRUE)
.build();
commentMapper.insert(comment);
String fromNickname = UserUtils.getUserDetailsDTO().getNickname();
if (websiteConfig.getIsEmailNotice().equals(TRUE)) {
CompletableFuture.runAsync(() -> notice(comment));
CompletableFuture.runAsync(() -> notice(comment, fromNickname));
}
}
@ -215,10 +217,19 @@ public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> impl
}
}
public void notice(Comment comment) {
private void notice(Comment comment, String fromNickname) {
// 评论自己不发邮件提醒
if (comment.getUserId().equals(comment.getReplyUserId())) {
return;
}
// 博主自己发评论不发邮件提醒
if (comment.getUserId().equals(BLOGGER_ID) && Objects.isNull(comment.getParentId())) {
return;
}
// 查询回复用户邮箱号
String title;
Integer userId = BLOGGER_ID;
String id = Objects.nonNull(comment.getTopicId()) ? comment.getTopicId().toString() : "";
String topicId = Objects.nonNull(comment.getTopicId()) ? comment.getTopicId().toString() : "";
if (Objects.nonNull(comment.getReplyUserId())) {
userId = comment.getReplyUserId();
} else {
@ -232,26 +243,54 @@ public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> impl
break;
}
}
String email = userInfoMapper.selectById(userId).getEmail();
if (StringUtils.isNotBlank(email)) {
// 发送消息
EmailDTO emailDTO = new EmailDTO();
if (comment.getIsReview().equals(TRUE)) {
// 评论提醒
emailDTO.setEmail(email);
if (Objects.requireNonNull(getCommentEnum(comment.getType())).equals(ARTICLE)) {
title = articleMapper.selectById(comment.getTopicId()).getArticleTitle();
} else {
title = Objects.requireNonNull(getCommentEnum(comment.getType())).getDesc();
}
UserInfo user = userInfoMapper.selectById(userId);
if (StringUtils.isNotBlank(user.getEmail())) {
EmailDTO emailDTO = getEmailDTO(comment, user, fromNickname, topicId, title, userId);
rabbitTemplate.convertAndSend(EMAIL_EXCHANGE, "*", new Message(JSON.toJSONBytes(emailDTO), new MessageProperties()));
}
}
private EmailDTO getEmailDTO(Comment comment, UserInfo user, String fromNickname, String topicId, String title, Integer userId) {
EmailDTO emailDTO = new EmailDTO();
if (comment.getIsReview().equals(TRUE)) {
Map<String, Object> map = new HashMap<>();
String url = websiteUrl + getCommentPath(comment.getType()) + topicId;
if (Objects.isNull(comment.getParentId())) {
emailDTO.setEmail(user.getEmail());
emailDTO.setSubject("评论提醒");
// 获取评论路径
String url = websiteUrl + getCommentPath(comment.getType()) + id;
emailDTO.setContent("您收到了一条新的回复,请前往" + url + "页面查看");
emailDTO.setTemplate("owner.html");
String createTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(comment.getCreateTime());
map.put("time", createTime);
map.put("url", url);
map.put("title", title);
map.put("nickname", fromNickname);
map.put("content", comment.getCommentContent());
} else {
// 管理员审核提醒
String adminEmail = userInfoMapper.selectById(BLOGGER_ID).getEmail();
emailDTO.setEmail(adminEmail);
emailDTO.setSubject("审核提醒");
emailDTO.setContent("您收到了一条新的回复,请前往后台管理页面审核");
Comment parentComment = commentMapper.selectOne(new LambdaQueryWrapper<Comment>().select(Comment::getCommentContent, Comment::getCreateTime).eq(Comment::getId, comment.getParentId()));
emailDTO.setEmail(user.getEmail());
emailDTO.setSubject("评论提醒");
emailDTO.setTemplate("user.html");
map.put("url", url);
map.put("title", title);
String createTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(parentComment.getCreateTime());
map.put("time", createTime);
map.put("toUser", user.getNickname());
map.put("fromUser", fromNickname);
map.put("parentComment", parentComment.getCommentContent());
map.put("replyComment", comment.getCommentContent());
}
System.out.println(emailDTO);
rabbitTemplate.convertAndSend(EMAIL_EXCHANGE, "*", new Message(JSON.toJSONBytes(emailDTO), new MessageProperties()));
emailDTO.setCommentMap(map);
} else {
String adminEmail = userInfoMapper.selectById(BLOGGER_ID).getEmail();
emailDTO.setEmail(adminEmail);
emailDTO.setSubject("审核提醒");
emailDTO.setContent("您收到了一条新的回复,请前往后台管理页面审核");
}
return emailDTO;
}
}

@ -75,7 +75,7 @@ public class EsSearchStrategyImpl implements SearchStrategy {
HighlightBuilder.Field contentField = new HighlightBuilder.Field("articleContent");
contentField.preTags(PRE_TAG);
contentField.postTags(POST_TAG);
contentField.fragmentSize(80);
contentField.fragmentSize(50);
nativeSearchQueryBuilder.withHighlightFields(titleField, contentField);
// 搜索
try {

@ -0,0 +1,98 @@
package com.aurora.strategy.impl;
import com.aurora.entity.Article;
import com.aurora.mapper.ArticleMapper;
import com.aurora.model.dto.ArticleSearchDTO;
import com.aurora.strategy.SearchStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.aurora.constant.CommonConst.*;
import static com.aurora.enums.ArticleStatusEnum.PUBLIC;
/**
* @author
* mysql
*/
@Service("mySqlSearchStrategyImpl")
public class MySqlSearchStrategyImpl implements SearchStrategy {
@Autowired
private ArticleMapper articleMapper;
@Override
public List<ArticleSearchDTO> searchArticle(String keywords) {
// 判空
if (StringUtils.isBlank(keywords)) {
return new ArrayList<>();
}
// 搜索文章
List<Article> articles = articleMapper.selectList(new LambdaQueryWrapper<Article>()
.eq(Article::getIsDelete, FALSE)
.eq(Article::getStatus, PUBLIC.getStatus())
.and(i -> i.like(Article::getArticleTitle, keywords)
.or()
.like(Article::getArticleContent, keywords)));
// 高亮处理
return articles.stream().map(item -> {
// 文章内容高亮
boolean isLowerCase = true;
String articleContent = item.getArticleContent();
int contentIndex = item.getArticleContent().indexOf(keywords.toLowerCase());
if (contentIndex == -1) {
contentIndex = item.getArticleContent().indexOf(keywords.toUpperCase());
if (contentIndex != -1) {
isLowerCase = false;
}
}
if (contentIndex != -1) {
// 获取关键词前面的文字
int preIndex = contentIndex > 15 ? contentIndex - 15 : 0;
String preText = item.getArticleContent().substring(preIndex, contentIndex);
// 获取关键词到后面的文字
int last = contentIndex + keywords.length();
int postLength = item.getArticleContent().length() - last;
int postIndex = postLength > 35 ? last + 35 : last + postLength;
String postText = item.getArticleContent().substring(contentIndex, postIndex);
// 文章内容高亮
if (isLowerCase) {
articleContent = (preText + postText).replaceAll(keywords.toLowerCase(), PRE_TAG + keywords.toLowerCase() + POST_TAG);
} else {
articleContent = (preText + postText).replaceAll(keywords.toUpperCase(), PRE_TAG + keywords.toUpperCase() + POST_TAG);
}
} else {
return null;
}
isLowerCase = true;
int titleIndex = item.getArticleTitle().indexOf(keywords.toLowerCase());
if (titleIndex == -1) {
titleIndex = item.getArticleTitle().indexOf(keywords.toUpperCase());
if (titleIndex != -1) {
isLowerCase = false;
}
}
// 文章标题高亮
String articleTitle;
if (isLowerCase) {
articleTitle = item.getArticleTitle().replaceAll(keywords.toLowerCase(), PRE_TAG + keywords.toLowerCase() + POST_TAG);
} else {
articleTitle = item.getArticleTitle().replaceAll(keywords.toUpperCase(), PRE_TAG + keywords.toUpperCase() + POST_TAG);
}
return ArticleSearchDTO.builder()
.id(item.getId())
.articleTitle(articleTitle)
.articleContent(articleContent)
.build();
}).filter(Objects::nonNull)
.collect(Collectors.toList());
}
}

@ -0,0 +1,61 @@
package com.aurora.utils;
import com.aurora.model.dto.EmailDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
/**
*
*
* @author ican
*/
@Component
public class EmailUtils {
/**
*
*/
@Value("${spring.mail.username}")
private String email;
@Autowired
private JavaMailSender javaMailSender;
@Autowired
private TemplateEngine templateEngine;
public void sendSimpleMail(EmailDTO emailDTO) {
SimpleMailMessage simpleMail = new SimpleMailMessage();
simpleMail.setFrom(email);
simpleMail.setTo(emailDTO.getEmail());
simpleMail.setSubject(emailDTO.getSubject());
simpleMail.setText(emailDTO.getContent());
javaMailSender.send(simpleMail);
}
public void sendHtmlMail(EmailDTO emailDTO) {
try {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage);
Context context = new Context();
context.setVariables(emailDTO.getCommentMap());
String process = templateEngine.process(emailDTO.getTemplate(), context);
mimeMessageHelper.setFrom(email);
mimeMessageHelper.setTo(emailDTO.getEmail());
mimeMessageHelper.setSubject(emailDTO.getSubject());
mimeMessageHelper.setText(process, true);
javaMailSender.send(mimeMessage);
} catch (MessagingException e) {
e.printStackTrace();
}
}
}

@ -29,7 +29,7 @@ public class HTMLUtils {
*/
public static String filter(String source) {
// 敏感词过滤
source = sensitiveWordBs.replace(source);
// source = sensitiveWordBs.replace(source);
// 保留图片标签
source = source.replaceAll("(?!<(img).*?>)<.*?>", "")
.replaceAll("(onload(.*?)=)", "")

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="
border-radius: 10px 10px 10px 10px;
font-size: 13px;
color: #555555;
width: 666px;
margin: 50px auto;
border: 1px solid #eee;
max-width: 100%;
background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);
box-shadow: 0 1px 5px rgb(0 0 0 / 15%);">
<div style="
background:#49BDAD;
color:#ffffff;
border-radius: 10px 10px 0 0;
background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));
background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));
height: 66px;">
<p style="font-size:15px;
word-break:break-all;
padding: 23px 32px;
margin:0;
background-color: hsla(0,0%,100%,.4);
border-radius: 10px 10px 0 0;">
您的<a style="text-decoration:none;
color: #ffffff;" th:text="|《${title}》|" target="_blank"></a>有的新评论啦!
</p>
</div>
<div style="margin:20px auto;width:90%">
<p>时间:<span th:text="${time}"></span></p>
<p><strong th:text="${nickname}"></strong> 同学 给您的评论如下:</p>
<div style="background: #f5f5f5;
margin:20px 0;
padding:15px;
border-radius:5px;
font-size:14px;">
<p th:utext="${content}"></p>
</div>
<p>
您可以点击<a style="text-decoration:none;
color:#12addb" th:href="@{${url}}" target="_blank">查看回复的完整內容</a>
</p>
<div style="color: #8c8c8c; font-size: 10px;width: 100%;text-align: center;word-wrap: break-word;">
<p style="padding: 20px">什么都无法舍弃的人,什么都改变不了。——《进击的巨人》</p>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="
border-radius: 10px 10px 10px 10px;
font-size: 13px;
color: #555555;
width: 666px;
margin: 50px auto;
border: 1px solid #eee;
max-width: 100%;
background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);
box-shadow: 0 1px 5px rgb(0 0 0 / 15%);">
<div style="
background:#49BDAD;
color:#ffffff;
border-radius: 10px 10px 0 0;
background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));
background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));
height: 66px;">
<p style="font-size:15px;
word-break:break-all;
padding: 23px 32px;
margin:0;
background-color: hsla(0,0%,100%,.4);
border-radius: 10px 10px 0 0;">
您在<a style="text-decoration:none;
color: #ffffff;" href="https://www.ttkwsd.top/" target="_blank">花未眠的个人博客</a>上的留言有新回复啦!
</p>
</div>
<div style="margin:20px auto;width:90%">
<p>时间:<span th:text="${time}"></span></p>
<p><strong th:text="${toUser}"></strong> 同学,您曾在<a th:text="|《${title}》|" style="text-decoration: none;
color:#12addb"></a>上发表评论:</p>
<div style="background: #f5f5f5;
margin:20px 0;
padding:15px;
border-radius:5px;
font-size:14px;">
<p th:utext="${parentComment}"></p>
</div>
<p><strong th:text="${fromUser}"></strong> 给您的回复如下:</p>
<div style="background: #f5f5f5;
margin:20px 0;
padding:15px;
border-radius:5px;
font-size:14px;">
<p th:utext="${replyComment}"></p>
</div>
<p>
您可以点击<a style="text-decoration:none;
color:#12addb" target="_blank" th:href="@{${url}}">查看回复的完整內容</a>
,欢迎再次光临<a style="text-decoration:none;
color:#12addb" href="https://www.linhaojun.top/" target="_blank">花未眠的个人博客</a>
</p>
<div style="color: #8c8c8c; font-size: 10px;width: 100%;text-align: center;word-wrap: break-word;">
<p style="padding: 20px">不管当下的境遇如何,提瓦特大陆的星空永远会有你的位置。——《原神》</p>
</div>
</div>
</div>
</body>
</html>

@ -26,7 +26,6 @@ export function generaMenu() {
// 添加侧边栏菜单
store.commit('saveUserMenus', userMenus)
// 添加菜单到路由
// router.addRoutes(userMenus)
userMenus.forEach((item) => {
router.addRoute(item)
})

@ -8,7 +8,7 @@
</div>
<!-- 面包屑导航 -->
<el-breadcrumb>
<el-breadcrumb-item v-for="item of breadcrumbList" :key="item.path">
<el-breadcrumb-item v-for="item of breadcrumbs" :key="item.path">
<span v-if="item.redirect">{{ item.name }}</span>
<router-link v-else :to="item.path">{{ item.name }}</router-link>
</el-breadcrumb-item>
@ -55,7 +55,7 @@ export default {
if (first && first.name !== '首页') {
matched = [{ path: '/', name: '首页' }].concat(matched)
}
this.breadcrumbList = matched
this.breadcrumbs = matched
//
this.$store.commit('saveTab', this.$route)
},
@ -63,7 +63,7 @@ export default {
return {
isSearch: false,
fullscreen: false,
breadcrumbList: []
breadcrumbs: []
}
},
methods: {

@ -8,7 +8,7 @@
background-color="#304156"
text-color="#BFCBD9"
active-text-color="#409EFF">
<template v-for="route of this.$store.state.userMenuList">
<template v-for="route of this.$store.state.userMenus">
<!-- 二级菜单 -->
<template v-if="route.name && route.children && !route.hidden">
<el-submenu :key="route.path" :index="route.path">

@ -9,7 +9,7 @@ export default new Vuex.Store({
collapse: false,
tabList: [{ name: '首页', path: '/' }],
userInfo: null,
userMenuList: []
userMenus: []
},
mutations: {
saveTab(state, tab) {
@ -31,13 +31,13 @@ export default new Vuex.Store({
sessionStorage.setItem('token', user.token)
state.userInfo = user
},
saveUserMenus(state, userMenuList) {
state.userMenuList = userMenuList
saveUserMenus(state, userMenus) {
state.userMenus = userMenus
},
logout(state) {
state.userInfo = null
sessionStorage.removeItem('token')
state.userMenuList = []
state.userMenus = []
},
updateAvatar(state, avatar) {
state.userInfo.avatar = avatar

File diff suppressed because one or more lines are too long

@ -1,4 +1,14 @@
## 1.docker的安装
## 1.服务器要求
1. 核心数和内存大小有两种方案:
- 2核4G使用ES搜索策略
- 2核2G使用MySQL搜素策略
2. 带宽大小有两种方案:
- 使用oss对带宽没有要求本人亲测1M带宽+oss 访问速度很快)
- 使用minio需要大一点的带宽小带宽也可以但需要使用cdn加速
## 2.docker的安装
> 以下命令基于CentOS环境。
@ -40,9 +50,9 @@
****
## 2.安装mysql
## 3.安装mysql
### 2.1 无挂载模式
### 方式1: 无挂载模式
> 这种方式直接运行mysql之后所有关于mysql的内容都在容器中后续如果需要修改mysql的内容需要手动进入容器内进行操作。且在宿主机上无备份一旦容器被删除数据也会被删除。
@ -51,7 +61,7 @@ docker pull mysql //下载MySQL镜像
docker run --name mysql --restart=always -p 3306:3306 -e MYSQL_ROOT_PASSWORD=密码 -d mysql //启动MySQL
```
### 2.2 数据卷挂载模式
### 方式2: 数据卷挂载模式
> 和**无挂载模式相对**,通过数据卷挂载的方式运行容器,将容器内的部分重要文件映射到宿主机上。直接操作宿主机对应的映射文件就能和容器内作同步,方便操作的同时还能保证容器内的数据在宿主机上有一个备份。
>
@ -63,21 +73,21 @@ docker run -d -p 3306:3306 --restart=always -v /auroras/mysql/log:/var/log/mysql
****
## 3.安装redis
## 4.安装redis
```shell
docker pull redis //下载Redis镜像
docker run --name redis --restart=always -p 6379:6379 -d redis --requirepass "密码" //启动Redis
```
## 4.安装rabbitmq
## 5.安装rabbitmq
```shell
docker pull rabbitmq:management //下载RabbitMQ镜像
docker run --name rabbit --restart=always -p 15672:15672 -p 5672:5672 -d rabbitmq:management //启动RabbitMQ,默认guest用户密码也是guest。
```
## 5.安装elasticsearch
## 6.安装elasticsearch
```shell
docker pull elasticsearch:7.9.2
@ -88,33 +98,33 @@ mkdir -p /home/elasticsearch/data/
mkdir -p /home/elasticsearch/config/
```
### 5.1 编写配置文件
1. 编写配置文件
```shell
echo 'http.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: "*" '>>/home/elasticsearch/config/elasticsearch.yml
```
```shell
echo 'http.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: "*" '>>/home/elasticsearch/config/elasticsearch.yml
```
### 5.2 修改文件夹权限
2. 修改文件夹权限
```shell
chmod -R 777 /home/elasticsearch/
ls -l # 查看文件权限
```
```shell
chmod -R 777 /home/elasticsearch/
ls -l # 查看文件权限
```
### 5.3 启动elasticseach镜像
3. 启动elasticseach镜像
```shell
docker run --name elasticsearch -p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx128m" \
-v /home/elasticsearch/config/elasticsearch.yml:/usr/shellare/elasticsearch/config/elasticsearch.yml \
-v /home/elasticsearch/data:/usr/shellare/elasticsearch/data \
-v /home/elasticsearch/plugins:/usr/shellare/elasticsearch/plugins \
-d elasticsearch:7.9.2
```
```shell
docker run --name elasticsearch -p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx128m" \
-v /home/elasticsearch/config/elasticsearch.yml:/usr/shellare/elasticsearch/config/elasticsearch.yml \
-v /home/elasticsearch/data:/usr/shellare/elasticsearch/data \
-v /home/elasticsearch/plugins:/usr/shellare/elasticsearch/plugins \
-d elasticsearch:7.9.2
```
接下来我们就是拿浏览器访问啦。
@ -201,7 +211,7 @@ postman post请求分词测试`http://服务器IP地址:9200/_analyze`
}
```
## 6.安装MaxWell(ElasticSearch同步数据
## 7.安装MaxWell(ElasticSearch同步数据
```sh
docker pull zendesk/maxwell //下载MaxWell镜像
@ -212,7 +222,7 @@ docker run --name maxwell --restart=always -d zendesk/maxwell bin/maxwell --u
****
## 7.填写aurora-springboot中的yml文件
## 8.填写aurora-springboot中的yml文件
此处省略操作比较简单就是配置一些简单的ip+端口+用户名+密码,前提是服务器上对应的端口已经打开
@ -222,7 +232,7 @@ QQ互联具体情况详见百度
这里就不赘述了
## 8.打包运行后端项目
## 9.打包运行后端项目
1. 使用idea右侧Maven的package命令
@ -297,7 +307,7 @@ docker run --name aurora-springboot-0.0.1.jar -d -p 8080:8080 aurora-springboot
****
## 9.打包运行前端项目
## 10.打包运行前端项目
1. aurora-blog项目中更改src/config/config.ts
@ -330,7 +340,7 @@ docker run --name aurora-springboot-0.0.1.jar -d -p 8080:8080 aurora-springboot
如果下列命令执行报错,可以尝试替换版本,参考版本如下,如果替换版本还是报错,加群询问已经部署完的兄弟!
参考版本npm版本为8.3.1 vue-cli的版本为5.0.6
参考版本npm版本为8.3.1 vue-cli的版本为5.0.6
```shell
npm install
@ -343,198 +353,200 @@ docker run --name aurora-springboot-0.0.1.jar -d -p 8080:8080 aurora-springboot
7. 将打包好的后台代码重命名为admin, 并传输到服务器的/usr/local/vue下面
## 10.安装并启动nginx(没有开启https)
tip: 在这之前需要到域名提供商那里配置好域名个人认为没有必要开启https,http完全够并且省事儿。当然如果想开启https的话后面也有相应的教程。
### 10.1 拉取nginx镜像
```shell
docker pull nginx
```
### 10.2 在/usr/local/nginx下创建nginx.conf文件格式如下
```shell
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
client_max_body_size 50m;
client_body_buffer_size 10m;
client_header_timeout 1m;
client_body_timeout 1m;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 4;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
server {
listen 80;
server_name 前台域名;
location / {
root /usr/local/vue/blog;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location ^~ /api/ {
proxy_pass http://你的ip:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name 后台子域名;
location / {
root /usr/local/vue/admin;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location ^~ /api/ {
proxy_pass http://你的ip:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
```
### 10.3 启动nginx
```shell
docker run --name nginx --restart=always -p 80:80 -d -v /usr/local/nginx/nginx.conf:/etc/nginx/nginx.conf -v /usr/local/vue:/usr/local/vue nginx
```
****
## 11.安装并启动nginx(开启https)
## 11.安装并启动nginx
### 11.1 修改配置文件
### 方式1: http
> 要配置https只需要对上面的配置文件`nginx.conf`的内容作如下修改即可。
1. 拉取nginx镜像
```bash
events {
worker_connections 1024;
}
```shell
docker pull nginx
```
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
client_max_body_size 50m;
client_body_buffer_size 10m;
client_header_timeout 1m;
client_body_timeout 1m;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 4;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
server {
listen 443 ssl;
server_name 你的前台域名(如www.baidu.com);
ssl on;
ssl_certificate ssl证书文件位置;
ssl_certificate_key ssl证书文件位置;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
root /usr/local/vue/blog;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location ^~ /api/ {
proxy_pass http://你的服务器公网IP:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
2. 在/usr/local/nginx下创建nginx.conf文件格式如下
```shell
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
client_max_body_size 50m;
client_body_buffer_size 10m;
client_header_timeout 1m;
client_body_timeout 1m;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 4;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
server {
listen 80;
server_name 前台域名;
location / {
root /usr/local/vue/blog;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location ^~ /api/ {
proxy_pass http://你的ip:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name 后台子域名;
location / {
root /usr/local/vue/admin;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location ^~ /api/ {
proxy_pass http://你的ip:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
```
server {
3. 启动nginx
listen 443 ssl;
server_name 你的后台域名(如admin.baidu.com);
```shell
docker run --name nginx --restart=always -p 80:80 -d -v /usr/local/nginx/nginx.conf:/etc/nginx/nginx.conf -v /usr/local/vue:/usr/local/vue nginx
```
ssl on;
ssl_certificate ssl证书文件位置;
ssl_certificate_key ssl文件位置;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
### 方式2: https
location / {
root /usr/local/vue/admin;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location ^~ /api/ {
proxy_pass http://你的服务器公网IP:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
1. 拉取nginx镜像
```shell
docker pull nginx
```
2. 修改配置文件
server {
listen 80;
server_name 前台域名;
rewrite ^(.*)$ https://$host$1 permanent;
}
server {
listen 80;
server_name 后台域名;
rewrite ^(.*)$ https://$host$1 permanent;
}
}
```
```shell
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
client_max_body_size 50m;
client_body_buffer_size 10m;
client_header_timeout 1m;
client_body_timeout 1m;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 4;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
server {
listen 443 ssl;
server_name 你的前台域名(如www.baidu.com);
ssl on;
ssl_certificate ssl证书文件位置;
ssl_certificate_key ssl证书文件位置;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
root /usr/local/vue/blog;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location ^~ /api/ {
proxy_pass http://你的服务器公网IP:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 443 ssl;
server_name 你的后台域名(如admin.baidu.com);
ssl on;
ssl_certificate ssl证书文件位置;
ssl_certificate_key ssl文件位置;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
root /usr/local/vue/admin;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location ^~ /api/ {
proxy_pass http://你的服务器公网IP:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name 前台域名;
rewrite ^(.*)$ https://$host$1 permanent;
}
server {
listen 80;
server_name 后台域名;
rewrite ^(.*)$ https://$host$1 permanent;
}
}
```
### 11.2 重新运行nginx
3. 启动nginx
> 由于开启https需要启用443端口所以在前面(非https)的基础上下面的运行命令新增了数据卷挂载的方式并打开了443端口。
```shell
docker run --name nginx --restart=always -p 443:443 -p 80:80 -d -v /usr/local/nginx/nginx.conf:/etc/nginx/nginx.conf -v /usr/local/nginx/cert:/etc/nginx/cert -v /usr/local/vue:/usr/local/vue --privileged=true nginx
```
```bash
docker run --name nginx --restart=always -p 443:443 -p 80:80 -d -v /usr/local/nginx/nginx.conf:/etc/nginx/nginx.conf -v /usr/local/nginx/cert:/etc/nginx/cert -v /usr/local/vue:/usr/local/vue --privileged=true nginx
```

Loading…
Cancel
Save