Compare commits
11 Commits
mx-communi
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 5db789dffd | |||
| 56aea528ca | |||
| 76fabdb461 | |||
| 6c225308c3 | |||
| 33de72c9df | |||
| a08e17ad9c | |||
| eda3f11ca2 | |||
| 35de2ad9ca | |||
| c94bee58ae | |||
|
|
28e7e8d97c | ||
|
|
a14767d48b |
21
.drone.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: mx-community
|
||||
steps:
|
||||
- name: build
|
||||
image: maven:3-jdk-8
|
||||
pull: if-not-exists
|
||||
volumes:
|
||||
- name: maven
|
||||
path: /root/.m2
|
||||
commands:
|
||||
- mvn clean package -DskipTests
|
||||
- ls -h
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
|
||||
volumes:
|
||||
- name: maven
|
||||
host:
|
||||
path: /opt/ci/maven/
|
||||
14
.gitignore
vendored
@ -1,10 +1,12 @@
|
||||
HELP.md
|
||||
target/
|
||||
log/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
!**/src/main/**
|
||||
!**/src/test/**
|
||||
*.class
|
||||
### STS ###
|
||||
*.log
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
@ -18,10 +20,6 @@ target/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
.gradle
|
||||
gradlew
|
||||
gradlew.bat
|
||||
gradle
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
@ -30,8 +28,6 @@ gradle
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
4
Dockerfile
Normal file
@ -0,0 +1,4 @@
|
||||
FROM hub.c.163.com/library/java:latest
|
||||
VOLUME /tmp
|
||||
ADD target/blog-1.0.1-SNAPSHOT.jar blog.jar
|
||||
ENTRYPOINT ["java","-jar","/blog.jar"]
|
||||
22
README.md
@ -1,6 +1,8 @@
|
||||
|
||||
|
||||
**项目名称:** 沐雪博客DDD版本
|
||||
## 浅枫沐雪:
|
||||
|
||||
**项目名称:** 浅枫沐雪开源版
|
||||
|
||||
**项目描述:**
|
||||
|
||||
@ -10,12 +12,12 @@
|
||||
|
||||
```java
|
||||
前端: Semantic-UI框架
|
||||
后端: JDK1.8+SpringBoot2.4.5
|
||||
后端: JDK1.8+SpringBoot+ Spring Data JPA +MySQL5.7
|
||||
```
|
||||
|
||||
**项目介绍:**
|
||||
|
||||
整个项目前端采用 Semantic-UI,后端基于 SpringBoot,分为:
|
||||
1、整个项目前端采用 Semantic-UI,后端基于 SpringBoot,分为:
|
||||
|
||||
- 前台展示
|
||||
|
||||
@ -31,4 +33,16 @@
|
||||
|
||||
4、使用 CommentUtil 工具类以及 Semantic-UI 中自带的留言组件实现评论功能,让评论显示为层级
|
||||
|
||||
5、采用 SpringData JAP 连接数据库,简化 SQL 编写方式。
|
||||
5、采用 SpringData JAP 连接数据库,简化 SQL 编写方式。
|
||||
|
||||
**项目收获:**
|
||||
|
||||
整个项目部署和测试阶段的调试 通过该项目的开发,让我对项目开发的整体流程有了一个全面的了解,加深了我对前后
|
||||
|
||||
端的技术栈的 掌握,以及使我能够独立部署项目,Linux 服务器相关操作更佳熟练。对自己的代码有了更佳严格的要求、 有了不同的
|
||||
|
||||
代码和业务思想,巩固了后端技术栈的知识,对代程序编写有更加深刻的认识!
|
||||
|
||||
## 感谢
|
||||
|
||||
原作者Github:https://github.com/yerenping/blog
|
||||
203
pom.xml
@ -1,59 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.4.5</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>cn.allms.community</groupId>
|
||||
<artifactId>mx-community</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>mx-community</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
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>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<groupId>cn.allms</groupId>
|
||||
<artifactId>blog</artifactId>
|
||||
<version>1.0.0-RELEASE</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<name>blog</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.3.0.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>public</id>
|
||||
<name>aliyun nexus</name>
|
||||
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>public</id>
|
||||
<name>aliyun nexus</name>
|
||||
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!--jpa-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<!--thymeleaf-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<!--web-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!--devtools-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!--mysql-->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!--lombok-->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!--test-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!--aop-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<!--引入Markdown转HTML的插件-->
|
||||
<dependency>
|
||||
<groupId>com.atlassian.commonmark</groupId>
|
||||
<artifactId>commonmark</artifactId>
|
||||
<version>0.10.0</version>
|
||||
</dependency>
|
||||
<!--扩展 标题-->
|
||||
<dependency>
|
||||
<groupId>com.atlassian.commonmark</groupId>
|
||||
<artifactId>commonmark-ext-heading-anchor</artifactId>
|
||||
<version>0.10.0</version>
|
||||
</dependency>
|
||||
<!--扩展 表格-->
|
||||
<dependency>
|
||||
<groupId>com.atlassian.commonmark</groupId>
|
||||
<artifactId>commonmark-ext-gfm-tables</artifactId>
|
||||
<version>0.10.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>5.3.5.Final</version>
|
||||
</dependency>
|
||||
<!--配置文件:注解-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
</dependency>
|
||||
<!--服务监控-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<!--fastjson-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.35</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>2.3.0.RELEASE</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
15
src/main/java/cn/allms/MxBlogApplication.java
Normal file
@ -0,0 +1,15 @@
|
||||
package cn.allms;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* springboot启动器
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class MxBlogApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MxBlogApplication.class, args);
|
||||
}
|
||||
}
|
||||
98
src/main/java/cn/allms/aspect/LogAspectOld.java
Normal file
@ -0,0 +1,98 @@
|
||||
package cn.allms.aspect;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author josxy
|
||||
*/
|
||||
@Component
|
||||
public class LogAspectOld {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* 切点:cn.allms.controller
|
||||
*/
|
||||
//@Pointcut("execution(* cn.allms.controller.*.*(..))")
|
||||
public void log() {
|
||||
}
|
||||
|
||||
|
||||
// @Before("log()")
|
||||
public void doBefore(JoinPoint joinPoint) {
|
||||
// 获取request对象
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
assert attributes != null;
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
// URL
|
||||
String url = request.getRequestURL().toString();
|
||||
// IP
|
||||
String ip = request.getRemoteAddr();
|
||||
// 方法全名 = 类名.方法名
|
||||
String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
|
||||
// 请求对象
|
||||
Object[] args = joinPoint.getArgs();
|
||||
RequestLog requestLog = new RequestLog(url, ip, classMethod, args);
|
||||
|
||||
logger.info("Request : {}", requestLog);
|
||||
}
|
||||
|
||||
//@After("log()")
|
||||
public void doAfter() {
|
||||
// logger.info("-------doafter-----------");
|
||||
}
|
||||
|
||||
public void doAfterReturn(Object result) {
|
||||
logger.info("控制器方法名称Result : {}", result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部类:用于存放请求信息,用日志的方式将其记录下来
|
||||
*/
|
||||
private class RequestLog {
|
||||
/**
|
||||
* 请求地址
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 请求ip
|
||||
*/
|
||||
private String ip;
|
||||
/**
|
||||
* 请求方法
|
||||
*/
|
||||
private String classMethod;
|
||||
/**
|
||||
* 请求参数集合
|
||||
*/
|
||||
private Object[] args;
|
||||
|
||||
public RequestLog(String url, String ip, String classMethod, Object[] args) {
|
||||
this.url = url;
|
||||
this.ip = ip;
|
||||
this.classMethod = classMethod;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RequestLog{" +
|
||||
"url='" + url + '\'' +
|
||||
", ip='" + ip + '\'' +
|
||||
", classMethod='" + classMethod + '\'' +
|
||||
", args=" + Arrays.toString(args) +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
package cn.allms.community;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* 啓動入口
|
||||
* @author josxy
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class MxCommunityApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MxCommunityApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,99 +0,0 @@
|
||||
package cn.allms.community.domain.model.post;
|
||||
|
||||
import cn.allms.community.domain.model.topic.TopicPost;
|
||||
import cn.allms.community.infrastructure.constant.CommonConstants;
|
||||
import cn.allms.community.infrastructure.constant.ExceptionCodeConstant;
|
||||
import cn.allms.community.infrastructure.exception.BusinessException;
|
||||
import lombok.Data;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 帖子对象
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 11:50
|
||||
*/
|
||||
@Data
|
||||
public class Post {
|
||||
/**
|
||||
* 帖子ID
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 帖子作者ID
|
||||
*/
|
||||
private Long authorId;
|
||||
|
||||
/**
|
||||
* 帖子标题
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 帖子内容
|
||||
*/
|
||||
private String sourceContent;
|
||||
|
||||
/**
|
||||
* 发帖时间戳
|
||||
*/
|
||||
private Long postingTime;
|
||||
|
||||
/**
|
||||
* 最后修改时间
|
||||
*/
|
||||
private Long lastModifyTime;
|
||||
|
||||
/**
|
||||
* 加入的话题
|
||||
*/
|
||||
private Set<TopicPost> topics = new HashSet<>();
|
||||
|
||||
/**
|
||||
* 最多加入的主题数
|
||||
*/
|
||||
public static final Integer MAX_JOINED_TOPICS_NUM = 5;
|
||||
|
||||
/**
|
||||
* 自定义的setter,优先会调用此set方法,而不是lombok自带的
|
||||
* @param authorId 作者Id
|
||||
*/
|
||||
public void setAuthorId(Long authorId) {
|
||||
Assert.isTrue(authorId > 0, "帖子作者Id必须大于0");
|
||||
this.authorId = authorId;
|
||||
}
|
||||
|
||||
public void setSourceContent(String sourceContent) {
|
||||
Assert.isTrue(Objects.nonNull(sourceContent), "帖子内容不能为空");
|
||||
Assert.isTrue(sourceContent.length() >= 16, "帖子内容必须大于16");
|
||||
this.sourceContent = sourceContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将帖子关联话题 | 加入话题
|
||||
*
|
||||
* @param topicIds 话题集合
|
||||
*/
|
||||
public void joinTopics(String topicIds) throws BusinessException {
|
||||
if (Objects.isNull(topicIds)) {
|
||||
return;
|
||||
}
|
||||
String[] topicIdArray = topicIds.split(CommonConstants.TOPIC_SPLIT_COMMA);
|
||||
for (String s : topicIdArray) {
|
||||
TopicPost topicPost = new TopicPost(Long.valueOf(s), this.getId());
|
||||
this.topics.add(topicPost);
|
||||
if (topicSize() > MAX_JOINED_TOPICS_NUM) {
|
||||
throw new BusinessException(ExceptionCodeConstant.ONE_POST_MOST_JOIN_INTO_FIVE_TOPICS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int topicSize(){
|
||||
return this.topics.size();
|
||||
}
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
package cn.allms.community.domain.model.post;
|
||||
|
||||
import cn.allms.community.infrastructure.constant.ExceptionCodeConstant;
|
||||
import cn.allms.community.infrastructure.exception.BusinessException;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 帖子作者对象
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 11:51
|
||||
*/
|
||||
@Data
|
||||
public class PostAuthor {
|
||||
/**
|
||||
* 帖子内容最小长度
|
||||
*/
|
||||
private final static int MIN_LENGTH_POST_SOURCE_CONTENT = 16;
|
||||
|
||||
/**
|
||||
* 作者ID
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 作者账号
|
||||
*/
|
||||
private String account;
|
||||
/**
|
||||
* 作者昵称
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
/**
|
||||
* 发布帖子
|
||||
*
|
||||
* @param title 帖子标题
|
||||
* @param sourceContent 帖子内容
|
||||
* @return
|
||||
*/
|
||||
public Post posting(String title, String sourceContent) throws BusinessException {
|
||||
long currentTimeMillis = System.currentTimeMillis();
|
||||
if (sourceContent.length() < MIN_LENGTH_POST_SOURCE_CONTENT) {
|
||||
throw new BusinessException(ExceptionCodeConstant.POST_SOURCE_CONTENT_AT_LEAST_SIXTEEN_WORDS);
|
||||
}
|
||||
Post post = new Post();
|
||||
post.setAuthorId(this.id);
|
||||
post.setSourceContent(sourceContent);
|
||||
post.setTitle(title);
|
||||
post.setPostingTime(currentTimeMillis);
|
||||
post.setLastModifyTime(currentTimeMillis);
|
||||
return post;
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
package cn.allms.community.domain.model.topic;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 话题对象
|
||||
*
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 14:31
|
||||
*/
|
||||
@Data
|
||||
public class Topic {
|
||||
/**
|
||||
* 话题id
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 话题标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 话题描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 话题创建时间
|
||||
*/
|
||||
private Timestamp createTime;
|
||||
/**
|
||||
* 话题下的帖子列表
|
||||
*/
|
||||
private Set<TopicPost> posts;
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
package cn.allms.community.domain.model.topic;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 话题文章对象
|
||||
*
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 14:31
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class TopicPost {
|
||||
private Long topicId;
|
||||
private Long postId;
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
package cn.allms.community.domain.service.contentfilter;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 内容过滤器
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 15:09
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
public abstract class ContentFilter {
|
||||
/**
|
||||
* 下一个内容过滤器
|
||||
*/
|
||||
private ContentFilter nextContentFilter;
|
||||
|
||||
/**
|
||||
* 过滤内容
|
||||
* @param object 过滤对象
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean filterContent(Object object);
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
package cn.allms.community.domain.service.contentfilter;
|
||||
|
||||
/**
|
||||
* 图片过滤器
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 15:17
|
||||
*/
|
||||
public class ImageContentFilter extends ContentFilter{
|
||||
@Override
|
||||
public boolean filterContent(Object object) {
|
||||
// TODO 调用第三方接口实现图片过滤
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
package cn.allms.community.domain.service.contentfilter;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 本地文本内容过滤器
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 15:24
|
||||
*/
|
||||
public class LocalTextContentFilter extends TextContentFilter {
|
||||
/**
|
||||
* 本地敏感词
|
||||
*/
|
||||
private Set<String> sensitiveWords = new HashSet<>();
|
||||
|
||||
public LocalTextContentFilter() {
|
||||
sensitiveWords.add("NND");
|
||||
sensitiveWords.add("奶奶个熊");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean filterContent(Object content) {
|
||||
Assert.isTrue(content instanceof String, "本地文本过滤对象必须为 String 类型");
|
||||
for (String sensitiveWord : sensitiveWords) {
|
||||
if (((String) content).contains(sensitiveWord)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
package cn.allms.community.domain.service.contentfilter;
|
||||
|
||||
import cn.allms.community.domain.model.post.Post;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 帖子内容过滤:包含文本过滤,图片过滤
|
||||
* 责任链模式
|
||||
*
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 15:33
|
||||
*/
|
||||
public class PostMainBodyContentFilterChain {
|
||||
/**
|
||||
* 内容过滤器
|
||||
*/
|
||||
private Set<ContentFilter> contentFilters;
|
||||
|
||||
public PostMainBodyContentFilterChain() {
|
||||
TextContentFilter localTextContentFilter = new LocalTextContentFilter();
|
||||
TextContentFilter remoteTextContentFilter = new RemoteTextContentFilter();
|
||||
ImageContentFilter imageContentFilter = new ImageContentFilter();
|
||||
// 优先校验本地的敏感词
|
||||
contentFilters.add(localTextContentFilter);
|
||||
// 第三方文本敏感词过滤
|
||||
contentFilters.add(remoteTextContentFilter);
|
||||
// 第三方图片过滤
|
||||
contentFilters.add(imageContentFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤标题
|
||||
*
|
||||
* @param post 帖子信息
|
||||
* @return true —— 通过, false —— 未通过
|
||||
*/
|
||||
public boolean filterMainBody(Post post) {
|
||||
for (ContentFilter contentFilter : contentFilters) {
|
||||
if (!contentFilter.filterContent(post.getSourceContent())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
package cn.allms.community.domain.service.contentfilter;
|
||||
|
||||
import cn.allms.community.domain.model.post.Post;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 帖子标题过滤:文本过滤
|
||||
* 责任链模式
|
||||
*
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 15:40
|
||||
*/
|
||||
public class PostTitleContentFilterChain {
|
||||
/**
|
||||
* 内容过滤器
|
||||
*/
|
||||
private Set<ContentFilter> contentFilters;
|
||||
|
||||
public PostTitleContentFilterChain() {
|
||||
LocalTextContentFilter localTextContentFilter = new LocalTextContentFilter();
|
||||
RemoteTextContentFilter remoteTextContentFilter = new RemoteTextContentFilter();
|
||||
// 本地文本敏感词校验
|
||||
contentFilters.add(localTextContentFilter);
|
||||
// 第三方文本敏感词校验
|
||||
contentFilters.add(remoteTextContentFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤标题
|
||||
*
|
||||
* @param post 帖子信息
|
||||
* @return true —— 通过,false —— 未通过
|
||||
*/
|
||||
public boolean filterTitle(Post post) {
|
||||
for (ContentFilter contentFilter : contentFilters) {
|
||||
if (!contentFilter.filterContent(post.getTitle())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
package cn.allms.community.domain.service.contentfilter;
|
||||
|
||||
/**
|
||||
* 远程文本内容过滤器
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 15:22
|
||||
*/
|
||||
public class RemoteTextContentFilter extends TextContentFilter{
|
||||
@Override
|
||||
public boolean filterContent(Object object) {
|
||||
// TODO 需要调用第三方服务才能实现
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
package cn.allms.community.domain.service.contentfilter;
|
||||
|
||||
/**
|
||||
* 文本过滤器
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 15:18
|
||||
*/
|
||||
public abstract class TextContentFilter extends ContentFilter{
|
||||
/**
|
||||
* 文本过滤器,抽象
|
||||
* @param object 过滤对象
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public abstract boolean filterContent(Object object);
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
package cn.allms.community.infrastructure.constant;
|
||||
|
||||
/**
|
||||
* 公共常量
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 14:56
|
||||
*/
|
||||
public interface CommonConstants {
|
||||
String TOPIC_SPLIT_COMMA = ",";
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
package cn.allms.community.infrastructure.constant;
|
||||
|
||||
/**
|
||||
* 异常码状态常量
|
||||
*
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 14:17
|
||||
*/
|
||||
public interface ExceptionCodeConstant {
|
||||
String POST_SOURCE_CONTENT_AT_LEAST_SIXTEEN_WORDS = "2001";
|
||||
String ONE_POST_MOST_JOIN_INTO_FIVE_TOPICS = "2002";
|
||||
}
|
||||
@ -1,84 +0,0 @@
|
||||
package cn.allms.community.infrastructure.exception;
|
||||
|
||||
/**
|
||||
* @author xieYj
|
||||
* @date 2021/5/11 13:59
|
||||
*/
|
||||
public class BusinessException extends Exception {
|
||||
/**
|
||||
* 业务异常码
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 业务异常参数
|
||||
*/
|
||||
private Object[] arguments;
|
||||
|
||||
public BusinessException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public BusinessException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public BusinessException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public BusinessException(String code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public BusinessException(String message, Object[] arguments) {
|
||||
super(message);
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
public BusinessException(String code, String message, Object[] arguments) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
public BusinessException(String message, Object[] arguments, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
public BusinessException(String code, String message, Object[] arguments, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.code = code;
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
public BusinessException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
|
||||
public BusinessException(String code, String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
public BusinessException(String message,
|
||||
Throwable cause,
|
||||
boolean enableSuppression,
|
||||
boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
|
||||
public BusinessException(String code,
|
||||
String message,
|
||||
Throwable cause,
|
||||
boolean enableSuppression,
|
||||
boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
}
|
||||
62
src/main/java/cn/allms/config/LogAspect.java
Normal file
@ -0,0 +1,62 @@
|
||||
package cn.allms.config;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 日志
|
||||
*
|
||||
* @author rainerosion
|
||||
* @date 2021/4/9 19:11
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@Aspect
|
||||
public class LogAspect {
|
||||
@Pointcut("execution(* cn.allms.controller.*.*(..))")
|
||||
public void webLog() {
|
||||
}
|
||||
|
||||
@Before("webLog()")
|
||||
public void doBefore(JoinPoint joinPoint) {
|
||||
// 开始打印请求日志
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
|
||||
// 打印请求相关参数
|
||||
log.info("========================================== Start ==========================================");
|
||||
// 打印请求 url
|
||||
log.info("[请求URL] : {}", request.getRequestURL().toString());
|
||||
// 打印 Http method
|
||||
log.info("[请求方法] : {}", request.getMethod());
|
||||
// 打印调用 controller 的全路径以及执行方法
|
||||
log.info("[请求类名] : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
|
||||
// 打印请求的 IP
|
||||
log.info("[请求IP] : {}", request.getRemoteAddr());
|
||||
// 打印请求入参
|
||||
log.info("[请求参数] : {}", JSONObject.toJSONString(joinPoint.getArgs()));
|
||||
}
|
||||
|
||||
@Around("webLog()")
|
||||
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
|
||||
long startTime = System.currentTimeMillis();
|
||||
Object result = proceedingJoinPoint.proceed();
|
||||
// 打印出参
|
||||
log.info("[响应结果] : {}", JSONObject.toJSONString(result));
|
||||
// 执行耗时
|
||||
log.info("[请求耗时] : {} ms", System.currentTimeMillis() - startTime);
|
||||
log.info("=========================================== End ===========================================");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
22
src/main/java/cn/allms/config/MyConfig.java
Normal file
@ -0,0 +1,22 @@
|
||||
package cn.allms.config;
|
||||
|
||||
import cn.allms.interceptor.LoginInterceptor;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
/**
|
||||
* 配置类
|
||||
*/
|
||||
@Configuration
|
||||
public class MyConfig extends WebMvcConfigurerAdapter {
|
||||
|
||||
//重写拦截器
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new LoginInterceptor())
|
||||
.addPathPatterns("/admin/**")
|
||||
.excludePathPatterns("/admin")
|
||||
.excludePathPatterns("/admin/login");
|
||||
}
|
||||
}
|
||||
32
src/main/java/cn/allms/config/RandomPicturesConfig.java
Normal file
@ -0,0 +1,32 @@
|
||||
package cn.allms.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
/**
|
||||
* 随机图片配置类
|
||||
*
|
||||
* @author josxy
|
||||
*/
|
||||
@Data
|
||||
public class RandomPicturesConfig {
|
||||
private List<String> pictures;
|
||||
private final static String DEFAULT = "https://tva1.sinaimg.cn/large/0072Vf1pgy1foxk3rxvthj31kw0w0x3c";
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* 随机获取一种图片
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getRandomPicAddr() {
|
||||
Random random = new Random();
|
||||
System.out.println(this.pictures);
|
||||
System.out.println(this.pictures.get(random.nextInt(2)) + System.currentTimeMillis());
|
||||
return this.pictures.size() > 0 ?
|
||||
this.pictures.get(random.nextInt(2)) + System.currentTimeMillis() : DEFAULT;
|
||||
}
|
||||
}
|
||||
18
src/main/java/cn/allms/controller/AboutShowController.java
Normal file
@ -0,0 +1,18 @@
|
||||
package cn.allms.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/10/12
|
||||
* @Description: com.yrp.controller
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Controller
|
||||
public class AboutShowController {
|
||||
@GetMapping("/about")
|
||||
public String about() {
|
||||
return "about";
|
||||
}
|
||||
}
|
||||
27
src/main/java/cn/allms/controller/ArchiveShowController.java
Normal file
@ -0,0 +1,27 @@
|
||||
package cn.allms.controller;
|
||||
|
||||
import cn.allms.service.BlogService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/10/15
|
||||
* @Description: com.yrp.controller.admin
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Controller
|
||||
public class ArchiveShowController {
|
||||
@Autowired
|
||||
private BlogService blogServiceImpl;
|
||||
|
||||
|
||||
@GetMapping("/archives")
|
||||
public String archives(Model model) {
|
||||
model.addAttribute("archiveMap", blogServiceImpl.archiveBlog());
|
||||
model.addAttribute("blogCount", blogServiceImpl.countBlog());
|
||||
return "archives";
|
||||
}
|
||||
}
|
||||
76
src/main/java/cn/allms/controller/CommentController.java
Normal file
@ -0,0 +1,76 @@
|
||||
package cn.allms.controller;
|
||||
|
||||
import cn.allms.po.User;
|
||||
import cn.allms.po.Comment;
|
||||
import cn.allms.service.BlogService;
|
||||
import cn.allms.service.CommentService;
|
||||
import cn.allms.util.MD5Utils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* 评论
|
||||
*/
|
||||
@Controller
|
||||
public class CommentController {
|
||||
|
||||
@Autowired
|
||||
private CommentService commentServiceImpl;
|
||||
|
||||
@Autowired
|
||||
private BlogService blogServiceImpl;
|
||||
|
||||
@Value("${comment.avatar}")
|
||||
private String avatar;
|
||||
|
||||
@Value("${comment.v2exUrl}")
|
||||
private String v2exUrl;
|
||||
|
||||
/**
|
||||
* 显示评论列表
|
||||
*
|
||||
* @param blogId
|
||||
* @param model
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/comments/{blogId}")
|
||||
public String comments(@PathVariable Long blogId, Model model) {
|
||||
model.addAttribute("comments", commentServiceImpl.listCommentByBlogId(blogId));
|
||||
return "blog :: commentList";
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交评论
|
||||
*
|
||||
* @param comment
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/comments")
|
||||
public String post(Comment comment, HttpSession session) {
|
||||
Long blogId = comment.getBlog().getId();
|
||||
//处理评论和博客之间的关系
|
||||
comment.setBlog(blogServiceImpl.getBlog(blogId));
|
||||
User user = (User) session.getAttribute("user");
|
||||
//管理员发
|
||||
if (user != null) {
|
||||
comment.setAvatar(user.getAvatar());
|
||||
comment.setAdminComment(true);
|
||||
comment.setNickname(user.getNickname());
|
||||
comment.setEmail(user.getEmail());
|
||||
//普通用户
|
||||
} else {
|
||||
comment.setAvatar(v2exUrl + MD5Utils.code(comment.getEmail()));
|
||||
}
|
||||
commentServiceImpl.saveComment(comment);
|
||||
return "redirect:/comments/" + blogId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
80
src/main/java/cn/allms/controller/IndexController.java
Normal file
@ -0,0 +1,80 @@
|
||||
package cn.allms.controller;
|
||||
|
||||
import cn.allms.service.BlogService;
|
||||
import cn.allms.service.TagService;
|
||||
import cn.allms.service.TypeService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.web.PageableDefault;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
/**
|
||||
* 首页index.html
|
||||
*/
|
||||
@Controller
|
||||
public class IndexController {
|
||||
|
||||
@Autowired
|
||||
private BlogService blogServiceImpl;
|
||||
|
||||
@Autowired
|
||||
private TypeService typeServiceImpl;
|
||||
|
||||
@Autowired
|
||||
private TagService tagServiceImpl;
|
||||
|
||||
/**
|
||||
* 首页面显示
|
||||
*
|
||||
* @param model
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/")
|
||||
public String index(Model model, @PageableDefault(size = 8, sort = {"updateTime"}, direction = Sort.Direction.DESC)
|
||||
Pageable pageable) {
|
||||
//1. 获取分页的博客列表
|
||||
model.addAttribute("page", blogServiceImpl.ListBlog(pageable));
|
||||
//2. 获取分类的内容(显示6条)
|
||||
model.addAttribute("types", typeServiceImpl.listTypeTop(6));
|
||||
//3. 获取标签的内容
|
||||
model.addAttribute("tags", tagServiceImpl.ListTagTop(10));
|
||||
//4. 显示推荐博客列表
|
||||
model.addAttribute("recommendBlogs", blogServiceImpl.listRecommendBlogTop(8));
|
||||
return "index";
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航栏中的搜索功能实现
|
||||
*
|
||||
* @param pageable
|
||||
* @param model
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/search")
|
||||
public String search(@PageableDefault(size = 8, sort = {"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable,
|
||||
@RequestParam String query, Model model) {
|
||||
model.addAttribute("page", blogServiceImpl.ListBlog(pageable, "%" + query + "%"));
|
||||
model.addAttribute("query", query);
|
||||
return "search";
|
||||
}
|
||||
|
||||
@GetMapping("/blog/{id}")
|
||||
public String blog(@PathVariable("id") Long id, Model model) {
|
||||
model.addAttribute("blog", blogServiceImpl.getAadConvertBlog(id));
|
||||
return "blog";
|
||||
}
|
||||
|
||||
@GetMapping("/footer/newblog")
|
||||
public String newblos(Model model) {
|
||||
model.addAttribute("newblogs", blogServiceImpl.listRecommendBlogTop(3));
|
||||
return "_fragments :: newblogList";
|
||||
}
|
||||
|
||||
}
|
||||
50
src/main/java/cn/allms/controller/TagShowController.java
Normal file
@ -0,0 +1,50 @@
|
||||
package cn.allms.controller;
|
||||
|
||||
|
||||
import cn.allms.po.Tag;
|
||||
import cn.allms.service.TagService;
|
||||
import cn.allms.vo.BlogQuery;
|
||||
import cn.allms.service.BlogService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.web.PageableDefault;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/10/12
|
||||
* @Description: com.yrp.controller
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Controller
|
||||
public class TagShowController {
|
||||
@Autowired
|
||||
private TagService tagServiceImpl;
|
||||
|
||||
|
||||
@Autowired
|
||||
private BlogService blogServiceImpl;
|
||||
|
||||
|
||||
@GetMapping("/tags/{id}")
|
||||
public String tags(Model model, @PageableDefault(size = 8, sort = {"updateTime"}, direction = Sort.Direction.DESC)
|
||||
@PathVariable Long id, Pageable pageable) {
|
||||
|
||||
List<Tag> tags = tagServiceImpl.ListTagTop(10000);
|
||||
if (id == -1 && tags.size() > 0) {
|
||||
id = tags.get(0).getId();
|
||||
}
|
||||
BlogQuery blogQuery = new BlogQuery();
|
||||
model.addAttribute("tags", tags);
|
||||
model.addAttribute("page", blogServiceImpl.ListBlog(id, pageable));
|
||||
model.addAttribute("avtiveTagId", id);
|
||||
return "tags";
|
||||
}
|
||||
|
||||
}
|
||||
50
src/main/java/cn/allms/controller/TypeShowController.java
Normal file
@ -0,0 +1,50 @@
|
||||
package cn.allms.controller;
|
||||
|
||||
import cn.allms.po.Type;
|
||||
import cn.allms.service.TypeService;
|
||||
import cn.allms.vo.BlogQuery;
|
||||
import cn.allms.service.BlogService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.web.PageableDefault;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/10/12
|
||||
* @Description: com.yrp.controller
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Controller
|
||||
public class TypeShowController {
|
||||
@Autowired
|
||||
private TypeService typeServiceImpl;
|
||||
|
||||
|
||||
@Autowired
|
||||
private BlogService blogServiceImpl;
|
||||
|
||||
|
||||
@GetMapping("/types/{id}")
|
||||
public String types(Model model, @PageableDefault(size = 8, sort = {"updateTime"}, direction = Sort.Direction.DESC)
|
||||
@PathVariable Long id, Pageable pageable) {
|
||||
|
||||
List<Type> types = typeServiceImpl.listTypeTop(10000);
|
||||
if (id == -1 && types.size() > 0) {
|
||||
id = types.get(0).getId();
|
||||
}
|
||||
BlogQuery blogQuery = new BlogQuery();
|
||||
blogQuery.setTypeId(id);
|
||||
model.addAttribute("types", types);
|
||||
model.addAttribute("page", blogServiceImpl.ListBlog(pageable, blogQuery));
|
||||
model.addAttribute("avtiveTypeId", id);
|
||||
return "types";
|
||||
}
|
||||
|
||||
}
|
||||
175
src/main/java/cn/allms/controller/admin/BlogController.java
Normal file
@ -0,0 +1,175 @@
|
||||
package cn.allms.controller.admin;
|
||||
|
||||
import cn.allms.config.RandomPicturesConfig;
|
||||
import cn.allms.po.Blog;
|
||||
import cn.allms.po.User;
|
||||
import cn.allms.vo.BlogQuery;
|
||||
import cn.allms.service.BlogService;
|
||||
import cn.allms.service.TagService;
|
||||
import cn.allms.service.TypeService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.web.PageableDefault;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/10/3
|
||||
* @Description: com.yrp.controller.admin
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("admin")
|
||||
public class BlogController {
|
||||
|
||||
|
||||
/**
|
||||
* 博客发布页面url
|
||||
*/
|
||||
private static final String INPUT = "admin/blogs-input";
|
||||
private static final String HEAD_URL = "https://api.rainss.cn/random.php?t=";
|
||||
private static final String HEAD_URL_1 = "https://api.rainss.cn/acgimgurl/acgurl.php?t=";
|
||||
|
||||
/**
|
||||
* 显示分页查询到的博客列表页面url
|
||||
*/
|
||||
private static final String LIST = "admin/blogs";
|
||||
|
||||
/**
|
||||
* 局部刷新表格查询到的数据url
|
||||
*/
|
||||
private static final String REDIRECT_LIST = "redirect:/admin/blogs";
|
||||
|
||||
@Autowired
|
||||
private BlogService blogServiceImpl;
|
||||
|
||||
@Autowired
|
||||
private TypeService typeServiceImpl;
|
||||
|
||||
@Autowired
|
||||
private TagService tagServiceImpl;
|
||||
|
||||
/**
|
||||
* 分页显示博客列表
|
||||
*
|
||||
* @param model
|
||||
* @param pageable
|
||||
* @param blog
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/blogs")
|
||||
public String showBlogs(Model model, @PageableDefault(size = 8, sort = {"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable, BlogQuery blog) {
|
||||
model.addAttribute("page", blogServiceImpl.ListBlog(pageable, blog));
|
||||
model.addAttribute("types", typeServiceImpl.listType());
|
||||
return LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* 联合查询博客列表
|
||||
*
|
||||
* @param model
|
||||
* @param pageable
|
||||
* @param blog
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/blogs/search")
|
||||
public String searchBlogs(Model model, @PageableDefault(size = 8, sort = {"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable,
|
||||
BlogQuery blog) {
|
||||
model.addAttribute("page", blogServiceImpl.ListBlog(pageable, blog));
|
||||
return "admin/blogs :: blogList";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增博客页面
|
||||
*
|
||||
* @param model
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/blogs/input")
|
||||
public String inputBlog(Model model) {
|
||||
model.addAttribute("firstPicture", HEAD_URL_1 + System.currentTimeMillis());
|
||||
setTypeAadTag(model);
|
||||
return INPUT;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提交博客
|
||||
*
|
||||
* @param blog
|
||||
* @param attributes
|
||||
* @param session
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/blogs")
|
||||
public String post(Blog blog, RedirectAttributes attributes, HttpSession session) {
|
||||
blog.setUser((User) session.getAttribute("user"));
|
||||
blog.setType(typeServiceImpl.getType(blog.getType().getId()));
|
||||
blog.setTags(tagServiceImpl.ListTag(blog.getTagIds()));
|
||||
Blog b;
|
||||
Date date = new Date();
|
||||
//新增博客
|
||||
if (blog.getId() == null) {
|
||||
blog.setUpdateTime(date);
|
||||
blog.setCreateTime(date);
|
||||
blog.setViews(0);
|
||||
b = blogServiceImpl.saveBlog(blog);
|
||||
} else {//更新博客
|
||||
b = blogServiceImpl.updateBlog(blog.getId(), blog);
|
||||
}
|
||||
if (b == null) {
|
||||
attributes.addFlashAttribute("message", "操作失败");
|
||||
} else {
|
||||
attributes.addFlashAttribute("message", "操作成功");
|
||||
}
|
||||
return REDIRECT_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除博客
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/blogs/{id}/delete")
|
||||
public String deleteBlog(@PathVariable("id") Long id) {
|
||||
blogServiceImpl.deleteBlog(id);
|
||||
return REDIRECT_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改博客页面
|
||||
*
|
||||
* @param model
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/blogs/{id}/input")
|
||||
public String editBlog(@PathVariable("id") Long id, Model model) {
|
||||
setTypeAadTag(model);
|
||||
Blog blog = blogServiceImpl.getBlog(id);
|
||||
//处理tagIds
|
||||
blog.init();
|
||||
model.addAttribute("firstPicture", HEAD_URL_1 + System.currentTimeMillis());
|
||||
model.addAttribute("blog", blog);
|
||||
return INPUT;
|
||||
}
|
||||
|
||||
private void setTypeAadTag(Model model) {
|
||||
/*博客查询,为后面的编辑博客做准备*/
|
||||
model.addAttribute("blog", new Blog());
|
||||
/*分类查询*/
|
||||
model.addAttribute("types", typeServiceImpl.listType());
|
||||
/*标签查询*/
|
||||
model.addAttribute("tags", tagServiceImpl.ListTag());
|
||||
}
|
||||
}
|
||||
75
src/main/java/cn/allms/controller/admin/LoginController.java
Normal file
@ -0,0 +1,75 @@
|
||||
package cn.allms.controller.admin;
|
||||
|
||||
import cn.allms.po.User;
|
||||
import cn.allms.service.Userservice;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/9/28
|
||||
* @Description: com.yrp.controller.admin
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/admin")
|
||||
public class LoginController {
|
||||
|
||||
@Autowired
|
||||
private Userservice userservice;
|
||||
|
||||
/**
|
||||
* 显示用户登录页面
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping
|
||||
public String loginPage() {
|
||||
return "admin/login";
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @param session
|
||||
* @param attributes
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/login")
|
||||
public String login(@RequestParam String username,
|
||||
@RequestParam String password,
|
||||
HttpSession session,
|
||||
RedirectAttributes attributes) {
|
||||
User user = userservice.checkUser(username, password);
|
||||
if (user != null) {
|
||||
user.setPassword(null);
|
||||
session.setAttribute("user", user);
|
||||
return "admin/index";
|
||||
} else {
|
||||
attributes.addFlashAttribute("message", "用户名和密码错误");
|
||||
return "redirect:/admin";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户注销
|
||||
*
|
||||
* @param session
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/logout")
|
||||
public String logout(HttpSession session) {
|
||||
session.removeAttribute("user");
|
||||
return "redirect:/admin";
|
||||
}
|
||||
|
||||
}
|
||||
134
src/main/java/cn/allms/controller/admin/TagController.java
Normal file
@ -0,0 +1,134 @@
|
||||
package cn.allms.controller.admin;
|
||||
|
||||
|
||||
import cn.allms.po.Tag;
|
||||
import cn.allms.service.TagService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.web.PageableDefault;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 标签
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/admin")
|
||||
public class TagController {
|
||||
|
||||
@Autowired
|
||||
private TagService tagServiceImpl;
|
||||
|
||||
/**
|
||||
* 分页查询标签列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/tags")
|
||||
public String types(@PageableDefault(size = 8, sort = {"id"}, direction = Sort.Direction.DESC)
|
||||
Pageable pageable, Model model) {
|
||||
model.addAttribute("page", tagServiceImpl.ListTag(pageable));
|
||||
return "admin/tags";
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示添加标签页面
|
||||
*
|
||||
* @param model
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/tags/input")
|
||||
public String showInput(Model model) {
|
||||
model.addAttribute("tag", new Tag());
|
||||
return "admin/tags-input";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增标签
|
||||
*
|
||||
* @param tag
|
||||
* @param result
|
||||
* @param attributes
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/tags")
|
||||
public String post(@Valid Tag tag, BindingResult result, RedirectAttributes attributes) {
|
||||
Tag tag1 = tagServiceImpl.getTagByName(tag.getName());
|
||||
if (tag1 != null) {
|
||||
result.rejectValue("name", "nameError", "不能添加重复的标签");
|
||||
}
|
||||
if (result.hasErrors()) {
|
||||
return "admin/tags-input";
|
||||
}
|
||||
Tag t = tagServiceImpl.saveTag(tag);
|
||||
if (t == null) {
|
||||
attributes.addFlashAttribute("新增失败");
|
||||
} else {
|
||||
attributes.addFlashAttribute("新增成功");
|
||||
}
|
||||
return "redirect:/admin/tags";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示添加标签页面
|
||||
*
|
||||
* @param model
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/tags/{id}/input")
|
||||
public String editInput(@PathVariable("id") Long id, Model model) {
|
||||
model.addAttribute("tag", tagServiceImpl.getTag(id));
|
||||
return "admin/tags-input";
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改标签名
|
||||
*
|
||||
* @param tag
|
||||
* @param result
|
||||
* @param id
|
||||
* @param attributes
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/tags/{id}")
|
||||
public String editPost(@Valid Tag tag, BindingResult result, @PathVariable("id") Long id, RedirectAttributes attributes) {
|
||||
Tag tag1 = tagServiceImpl.getTagByName(tag.getName());
|
||||
if (tag1 != null) {
|
||||
result.rejectValue("name", "nameError", "不能添加重复的分类");
|
||||
}
|
||||
if (result.hasErrors()) {
|
||||
return "admin/tags-input";
|
||||
}
|
||||
Tag t = tagServiceImpl.updateTag(id, tag);
|
||||
if (t == null) {
|
||||
attributes.addFlashAttribute("message", "更新失败");
|
||||
} else {
|
||||
attributes.addFlashAttribute("message", "更新成功");
|
||||
}
|
||||
return "redirect:/admin/tags";
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除功能
|
||||
*
|
||||
* @param id
|
||||
* @param attributes
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/tags/{id}/delete")
|
||||
public String deleteById(@PathVariable("id") Long id, RedirectAttributes attributes) {
|
||||
tagServiceImpl.deleteTag(id);
|
||||
attributes.addFlashAttribute("message", "删除成功");
|
||||
return "redirect:/admin/tags";
|
||||
}
|
||||
}
|
||||
127
src/main/java/cn/allms/controller/admin/TypeController.java
Normal file
@ -0,0 +1,127 @@
|
||||
package cn.allms.controller.admin;
|
||||
|
||||
import cn.allms.po.Type;
|
||||
import cn.allms.service.TypeService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.web.PageableDefault;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/9/29
|
||||
* @Description: com.yrp.controller.admin
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/admin")
|
||||
public class TypeController {
|
||||
|
||||
@Autowired
|
||||
private TypeService typeServiceImpl;
|
||||
|
||||
/**
|
||||
* 分页查询分类列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/types")
|
||||
public String types(@PageableDefault(size = 8, sort = {"id"}, direction = Sort.Direction.DESC)
|
||||
Pageable pageable, Model model) {
|
||||
model.addAttribute("page", typeServiceImpl.ListType(pageable));
|
||||
return "admin/types";
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示新增页面
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/types/input")
|
||||
public String showInput(Model model) {
|
||||
model.addAttribute("type", new Type());
|
||||
return "admin/types-input";
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增分类
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
||||
@PostMapping("/types")
|
||||
public String post(@Valid Type type, BindingResult result, RedirectAttributes attributes) {
|
||||
//1.判断用户名是有重复
|
||||
Type type1 = typeServiceImpl.getTypeByName(type.getName());
|
||||
if (type1 != null) {
|
||||
result.rejectValue("name", "nameError", "不能添加重复的分类");
|
||||
}
|
||||
//2. 后端校验用户名是否为空
|
||||
if (result.hasErrors()) {
|
||||
return "admin/types-input";
|
||||
}
|
||||
Type t = typeServiceImpl.saveType(type);
|
||||
if (t == null) {
|
||||
attributes.addFlashAttribute("message", "新增失败");
|
||||
} else {
|
||||
attributes.addFlashAttribute("message", "新增成功");
|
||||
}
|
||||
return "redirect:/admin/types";
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到修改分类页面
|
||||
*
|
||||
* @param id
|
||||
* @param model
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/types/{id}/input")
|
||||
public String editInput(@PathVariable("id") Long id, Model model) {
|
||||
model.addAttribute("type", typeServiceImpl.getType(id));
|
||||
return "admin/types-input";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改分类
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
||||
@PostMapping("/types/{id}")
|
||||
public String editPost(@Valid Type type, BindingResult result, @PathVariable Long id, RedirectAttributes attributes) {
|
||||
Type type1 = typeServiceImpl.getTypeByName(type.getName());
|
||||
if (type1 != null) {
|
||||
result.rejectValue("name", "nameError", "不能添加重复的分类");
|
||||
}
|
||||
|
||||
if (result.hasErrors()) {
|
||||
return "admin/types-input";
|
||||
}
|
||||
Type t = typeServiceImpl.updateType(id, type);
|
||||
if (t == null) {
|
||||
attributes.addFlashAttribute("message", "更新失败");
|
||||
} else {
|
||||
attributes.addFlashAttribute("message", "更新成功");
|
||||
}
|
||||
return "redirect:/admin/types";
|
||||
}
|
||||
|
||||
@GetMapping("/types/{id}/delete")
|
||||
public String deleteTypeById(@PathVariable("id") Long id, RedirectAttributes attributes) {
|
||||
typeServiceImpl.deleteType(id);
|
||||
attributes.addFlashAttribute("message", "删除成功");
|
||||
return "redirect:/admin/types";
|
||||
}
|
||||
}
|
||||
39
src/main/java/cn/allms/dao/BlogRepository.java
Normal file
@ -0,0 +1,39 @@
|
||||
package cn.allms.dao;
|
||||
|
||||
import cn.allms.po.Blog;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/10/3
|
||||
* @Description: com.yrp.dao
|
||||
* @version: 1.0
|
||||
*/
|
||||
|
||||
public interface BlogRepository extends JpaRepository<Blog, Long>, JpaSpecificationExecutor<Blog> {
|
||||
|
||||
@Query("select b from Blog b where b.recommend = true")
|
||||
List<Blog> findTop(Pageable pageable);
|
||||
|
||||
@Query("select b from Blog b where b.title like ?1 or b.content like ?1")
|
||||
Page<Blog> findByQuery(String query, Pageable pageable);
|
||||
|
||||
@Transactional
|
||||
@Modifying
|
||||
@Query("update Blog b set b.views= b.views+1 where b.id = ?1")
|
||||
int updateViews(Long id);
|
||||
|
||||
@Query("select function('date_format',b.updateTime,'%Y') as year from Blog b group by function('date_format',b.updateTime,'%Y') order by year desc ")
|
||||
List<String> findGroupYear();
|
||||
|
||||
@Query("select b from Blog b where function('date_format',b.updateTime,'%Y') = ?1")
|
||||
List<Blog> findByYear(String year);
|
||||
}
|
||||
20
src/main/java/cn/allms/dao/CommentRepository.java
Normal file
@ -0,0 +1,20 @@
|
||||
package cn.allms.dao;
|
||||
|
||||
|
||||
import cn.allms.po.Comment;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/9/28
|
||||
* @Description: com.yrp.dao
|
||||
* @version: 1.0
|
||||
*/
|
||||
public interface CommentRepository extends JpaRepository<Comment, Long> {
|
||||
|
||||
List<Comment> findByBlogIdAndParentCommentNull(Long blogId, Sort sort);
|
||||
|
||||
}
|
||||
20
src/main/java/cn/allms/dao/TagRepository.java
Normal file
@ -0,0 +1,20 @@
|
||||
package cn.allms.dao;
|
||||
|
||||
import cn.allms.po.Tag;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 标签
|
||||
*/
|
||||
public interface TagRepository extends JpaRepository<Tag, Long> {
|
||||
Tag findByName(String name);
|
||||
|
||||
|
||||
@Query("select t from Tag t")
|
||||
List<Tag> findTop(Pageable pageable);
|
||||
|
||||
}
|
||||
30
src/main/java/cn/allms/dao/TypeRepository.java
Normal file
@ -0,0 +1,30 @@
|
||||
package cn.allms.dao;
|
||||
|
||||
import cn.allms.po.Type;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/9/29
|
||||
* @Description: com.yrp.dao
|
||||
* @version: 1.0
|
||||
*/
|
||||
public interface TypeRepository extends JpaRepository<Type, Long> {
|
||||
|
||||
Type findByName(String name);
|
||||
|
||||
|
||||
/**
|
||||
* 查询type按照分页的方式
|
||||
*
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
@Query("select t from Type t")
|
||||
List<Type> findTop(Pageable pageable);
|
||||
|
||||
}
|
||||
21
src/main/java/cn/allms/dao/UserRepository.java
Normal file
@ -0,0 +1,21 @@
|
||||
package cn.allms.dao;
|
||||
|
||||
import cn.allms.po.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/9/28
|
||||
* @Description: com.yrp.dao
|
||||
* @version: 1.0
|
||||
*/
|
||||
public interface UserRepository extends JpaRepository<User, Long> {
|
||||
/**
|
||||
* 通过用户名和密码查询用户
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @return
|
||||
*/
|
||||
User findByUsernameAndPassword(String username, String password);
|
||||
}
|
||||
22
src/main/java/cn/allms/exception/NotFoundException.java
Normal file
@ -0,0 +1,22 @@
|
||||
package cn.allms.exception;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
/**
|
||||
* 博客为空的异常
|
||||
*/
|
||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||
public class NotFoundException extends RuntimeException {
|
||||
public NotFoundException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public NotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NotFoundException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package cn.allms.handler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@ControllerAdvice
|
||||
public class ControllerExceptionHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ControllerExceptionHandler.class);
|
||||
|
||||
/**
|
||||
* 异常处理
|
||||
*
|
||||
* @param request
|
||||
* @param e
|
||||
* @return
|
||||
*/
|
||||
@ExceptionHandler({Exception.class})
|
||||
public ModelAndView handleException(HttpServletRequest request, Exception e) throws Exception {
|
||||
|
||||
logger.error("Request URL : {} , Exception : {}", request.getRequestURL(), e);
|
||||
|
||||
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
|
||||
throw e;
|
||||
}
|
||||
ModelAndView mav = new ModelAndView();
|
||||
mav.addObject("url", request.getRequestURL());
|
||||
mav.addObject("exception", e);
|
||||
mav.setViewName("error/error");
|
||||
|
||||
return mav;
|
||||
}
|
||||
}
|
||||
23
src/main/java/cn/allms/interceptor/LoginInterceptor.java
Normal file
@ -0,0 +1,23 @@
|
||||
package cn.allms.interceptor;
|
||||
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 登录拦截器
|
||||
*/
|
||||
public class LoginInterceptor extends HandlerInterceptorAdapter {
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
Object handler) throws Exception {
|
||||
//1. 用户未登录
|
||||
if (request.getSession().getAttribute("user") == null) {
|
||||
response.sendRedirect("/admin");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
250
src/main/java/cn/allms/po/Blog.java
Normal file
@ -0,0 +1,250 @@
|
||||
package cn.allms.po;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(name = "t_blog")
|
||||
public class Blog {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
private String title;
|
||||
@Basic(fetch = FetchType.LAZY)
|
||||
@Lob
|
||||
private String content;
|
||||
private String firstPicture;
|
||||
private String flag;
|
||||
private Integer views;
|
||||
private boolean appreciation;
|
||||
private boolean shareStatement;
|
||||
private boolean commentabled;
|
||||
private boolean published;
|
||||
private boolean recommend;
|
||||
private String description;
|
||||
@Transient
|
||||
private String tagIds;
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date createTime;
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date updateTime;
|
||||
|
||||
@ManyToOne
|
||||
private Type type;
|
||||
|
||||
@ManyToMany(cascade = {CascadeType.PERSIST})
|
||||
private List<Tag> tags = new ArrayList<>();
|
||||
|
||||
|
||||
@ManyToOne
|
||||
private User user;
|
||||
|
||||
@OneToMany(mappedBy = "blog")
|
||||
private List<Comment> comments = new ArrayList<>();
|
||||
|
||||
|
||||
public void init() {
|
||||
this.tagIds = tagsToIds(this.getTags());
|
||||
}
|
||||
|
||||
//1,2,3
|
||||
private String tagsToIds(List<Tag> tags) {
|
||||
if (!tags.isEmpty()) {
|
||||
StringBuffer ids = new StringBuffer();
|
||||
boolean flag = false;
|
||||
for (Tag tag : tags) {
|
||||
if (flag) {
|
||||
ids.append(",");
|
||||
} else {
|
||||
flag = true;
|
||||
}
|
||||
ids.append(tag.getId());
|
||||
}
|
||||
return ids.toString();
|
||||
} else {
|
||||
return tagIds;
|
||||
}
|
||||
}
|
||||
|
||||
public Blog() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getFirstPicture() {
|
||||
return firstPicture;
|
||||
}
|
||||
|
||||
public void setFirstPicture(String firstPicture) {
|
||||
this.firstPicture = firstPicture;
|
||||
}
|
||||
|
||||
public String getFlag() {
|
||||
return flag;
|
||||
}
|
||||
|
||||
public void setFlag(String flag) {
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
public Integer getViews() {
|
||||
return views;
|
||||
}
|
||||
|
||||
public void setViews(Integer views) {
|
||||
this.views = views;
|
||||
}
|
||||
|
||||
public boolean isAppreciation() {
|
||||
return appreciation;
|
||||
}
|
||||
|
||||
public void setAppreciation(boolean appreciation) {
|
||||
this.appreciation = appreciation;
|
||||
}
|
||||
|
||||
public boolean isShareStatement() {
|
||||
return shareStatement;
|
||||
}
|
||||
|
||||
public void setShareStatement(boolean shareStatement) {
|
||||
this.shareStatement = shareStatement;
|
||||
}
|
||||
|
||||
public boolean isCommentabled() {
|
||||
return commentabled;
|
||||
}
|
||||
|
||||
public void setCommentabled(boolean commentabled) {
|
||||
this.commentabled = commentabled;
|
||||
}
|
||||
|
||||
public boolean isPublished() {
|
||||
return published;
|
||||
}
|
||||
|
||||
public void setPublished(boolean published) {
|
||||
this.published = published;
|
||||
}
|
||||
|
||||
public boolean isRecommend() {
|
||||
return recommend;
|
||||
}
|
||||
|
||||
public void setRecommend(boolean recommend) {
|
||||
this.recommend = recommend;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public List<Tag> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(List<Tag> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public List<Comment> getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(List<Comment> comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public String getTagIds() {
|
||||
return tagIds;
|
||||
}
|
||||
|
||||
public void setTagIds(String tagIds) {
|
||||
this.tagIds = tagIds;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Blog{" +
|
||||
"id=" + id +
|
||||
", title='" + title + '\'' +
|
||||
", content='" + content + '\'' +
|
||||
", firstPicture='" + firstPicture + '\'' +
|
||||
", flag='" + flag + '\'' +
|
||||
", views=" + views +
|
||||
", appreciation=" + appreciation +
|
||||
", shareStatement=" + shareStatement +
|
||||
", commentabled=" + commentabled +
|
||||
", published=" + published +
|
||||
", recommend=" + recommend +
|
||||
", description='" + description + '\'' +
|
||||
", tagIds='" + tagIds + '\'' +
|
||||
", createTime=" + createTime +
|
||||
", updateTime=" + updateTime +
|
||||
", type=" + type +
|
||||
", tags=" + tags +
|
||||
", user=" + user +
|
||||
", comments=" + comments +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
133
src/main/java/cn/allms/po/Comment.java
Normal file
@ -0,0 +1,133 @@
|
||||
package cn.allms.po;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(name = "t_comment")
|
||||
public class Comment {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
private String nickname;
|
||||
private String email;
|
||||
private String content;
|
||||
private String avatar;
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date createTime;
|
||||
|
||||
@ManyToOne
|
||||
private Blog blog;
|
||||
|
||||
@OneToMany(mappedBy = "parentComment")
|
||||
private List<Comment> replyComments = new ArrayList<>();
|
||||
|
||||
@ManyToOne
|
||||
private Comment parentComment;
|
||||
|
||||
|
||||
private boolean adminComment;
|
||||
|
||||
|
||||
public Comment() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getAvatar() {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public void setAvatar(String avatar) {
|
||||
this.avatar = avatar;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Blog getBlog() {
|
||||
return blog;
|
||||
}
|
||||
|
||||
public void setBlog(Blog blog) {
|
||||
this.blog = blog;
|
||||
}
|
||||
|
||||
public List<Comment> getReplyComments() {
|
||||
return replyComments;
|
||||
}
|
||||
|
||||
public void setReplyComments(List<Comment> replyComments) {
|
||||
this.replyComments = replyComments;
|
||||
}
|
||||
|
||||
public Comment getParentComment() {
|
||||
return parentComment;
|
||||
}
|
||||
|
||||
public void setParentComment(Comment parentComment) {
|
||||
this.parentComment = parentComment;
|
||||
}
|
||||
|
||||
public boolean isAdminComment() {
|
||||
return adminComment;
|
||||
}
|
||||
|
||||
public void setAdminComment(boolean adminComment) {
|
||||
this.adminComment = adminComment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Comment{" +
|
||||
"id=" + id +
|
||||
", nickname='" + nickname + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", content='" + content + '\'' +
|
||||
", avatar='" + avatar + '\'' +
|
||||
", createTime=" + createTime +
|
||||
", blog=" + blog +
|
||||
", replyComments=" + replyComments +
|
||||
", parentComment=" + parentComment +
|
||||
", adminComment=" + adminComment +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
59
src/main/java/cn/allms/po/Tag.java
Normal file
@ -0,0 +1,59 @@
|
||||
package cn.allms.po;
|
||||
|
||||
import org.hibernate.validator.constraints.NotBlank;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by limi on 2017/10/14.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "t_tag")
|
||||
public class Tag {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
@NotBlank(message = "标签名不能为空")
|
||||
private String name;
|
||||
|
||||
@ManyToMany(mappedBy = "tags")
|
||||
private List<Blog> blogs = new ArrayList<>();
|
||||
|
||||
public Tag() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<Blog> getBlogs() {
|
||||
return blogs;
|
||||
}
|
||||
|
||||
public void setBlogs(List<Blog> blogs) {
|
||||
this.blogs = blogs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Tag{" +
|
||||
"id=" + id +
|
||||
", name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
56
src/main/java/cn/allms/po/Type.java
Normal file
@ -0,0 +1,56 @@
|
||||
package cn.allms.po;
|
||||
|
||||
import org.hibernate.validator.constraints.NotBlank;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(name = "t_type")
|
||||
public class Type {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
@NotBlank(message = "分类名不能为空")
|
||||
private String name;
|
||||
|
||||
@OneToMany(mappedBy = "type")
|
||||
private List<Blog> blogs = new ArrayList<>();
|
||||
|
||||
public Type() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<Blog> getBlogs() {
|
||||
return blogs;
|
||||
}
|
||||
|
||||
public void setBlogs(List<Blog> blogs) {
|
||||
this.blogs = blogs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Type{" +
|
||||
"id=" + id +
|
||||
", name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
127
src/main/java/cn/allms/po/User.java
Normal file
@ -0,0 +1,127 @@
|
||||
package cn.allms.po;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(name = "t_user")
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
private String nickname;
|
||||
private String username;
|
||||
private String password;
|
||||
private String email;
|
||||
private String avatar;
|
||||
private Integer type;
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date createTime;
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date updateTime;
|
||||
|
||||
@OneToMany(mappedBy = "user")
|
||||
private List<Blog> blogs = new ArrayList<>();
|
||||
|
||||
public User() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getAvatar() {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public void setAvatar(String avatar) {
|
||||
this.avatar = avatar;
|
||||
}
|
||||
|
||||
public Integer getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Integer type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
|
||||
public List<Blog> getBlogs() {
|
||||
return blogs;
|
||||
}
|
||||
|
||||
public void setBlogs(List<Blog> blogs) {
|
||||
this.blogs = blogs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User{" +
|
||||
"id=" + id +
|
||||
", nickname='" + nickname + '\'' +
|
||||
", username='" + username + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", avatar='" + avatar + '\'' +
|
||||
", type=" + type +
|
||||
", createTime=" + createTime +
|
||||
", updateTime=" + updateTime +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
106
src/main/java/cn/allms/service/BlogService.java
Normal file
@ -0,0 +1,106 @@
|
||||
package cn.allms.service;
|
||||
|
||||
import cn.allms.po.Blog;
|
||||
import cn.allms.vo.BlogQuery;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/10/3
|
||||
* @Description: com.yrp.po
|
||||
* @version: 1.0
|
||||
*/
|
||||
public interface BlogService {
|
||||
/**
|
||||
* 通过id查询单条博客
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
Blog getBlog(Long id);
|
||||
|
||||
/**
|
||||
* 通过id查询单条博客(前端使用)
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
Blog getAadConvertBlog(Long id);
|
||||
|
||||
|
||||
/**
|
||||
* 分页查询博客
|
||||
*
|
||||
* @param pageable
|
||||
* @param blog
|
||||
* @return
|
||||
*/
|
||||
Page<Blog> ListBlog(Pageable pageable, BlogQuery blog);
|
||||
|
||||
/**
|
||||
* 分页查询显示博客列表
|
||||
*
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
Page<Blog> ListBlog(Pageable pageable);
|
||||
|
||||
|
||||
Page<Blog> ListBlog(Long tagId, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 模糊查询分页显示博客列表
|
||||
*
|
||||
* @param pageable
|
||||
* @param query
|
||||
* @return
|
||||
*/
|
||||
Page<Blog> ListBlog(Pageable pageable, String query);
|
||||
|
||||
/**
|
||||
* 显示推荐的博客列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Blog> listRecommendBlogTop(Integer size);
|
||||
|
||||
/**
|
||||
* 显示归档信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Map<String, List<Blog>> archiveBlog();
|
||||
|
||||
|
||||
Long countBlog();
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*
|
||||
* @param blog
|
||||
* @return
|
||||
*/
|
||||
Blog saveBlog(Blog blog);
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*
|
||||
* @param id
|
||||
* @param blog
|
||||
* @return
|
||||
*/
|
||||
Blog updateBlog(Long id, Blog blog);
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
void deleteBlog(Long id);
|
||||
|
||||
|
||||
}
|
||||
29
src/main/java/cn/allms/service/CommentService.java
Normal file
@ -0,0 +1,29 @@
|
||||
package cn.allms.service;
|
||||
|
||||
|
||||
import cn.allms.po.Comment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 评论
|
||||
*/
|
||||
public interface CommentService {
|
||||
|
||||
/**
|
||||
* 通过id查询评论列表
|
||||
*
|
||||
* @param blogId
|
||||
* @return
|
||||
*/
|
||||
List<Comment> listCommentByBlogId(Long blogId);
|
||||
|
||||
/**
|
||||
* 保存评论信息
|
||||
*
|
||||
* @param comment
|
||||
* @return
|
||||
*/
|
||||
Comment saveComment(Comment comment);
|
||||
|
||||
}
|
||||
73
src/main/java/cn/allms/service/TagService.java
Normal file
@ -0,0 +1,73 @@
|
||||
package cn.allms.service;
|
||||
|
||||
import cn.allms.po.Tag;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分类管理接口
|
||||
*/
|
||||
public interface TagService {
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Tag saveTag(Tag tag);
|
||||
|
||||
|
||||
/**
|
||||
* 单个查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
Tag getTag(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
Page<Tag> ListTag(Pageable pageable);
|
||||
|
||||
|
||||
List<Tag> ListTagTop(Integer size);
|
||||
|
||||
/**
|
||||
* 查询所有标签
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Tag> ListTag();
|
||||
|
||||
List<Tag> ListTag(String ids);
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*
|
||||
* @param id
|
||||
* @param tag
|
||||
* @return
|
||||
*/
|
||||
Tag updateTag(Long id, Tag tag);
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
void deleteTag(Long id);
|
||||
|
||||
/**
|
||||
* 通过分类名称
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Tag getTagByName(String name);
|
||||
|
||||
}
|
||||
71
src/main/java/cn/allms/service/TypeService.java
Normal file
@ -0,0 +1,71 @@
|
||||
package cn.allms.service;
|
||||
|
||||
import cn.allms.po.Type;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分类管理接口
|
||||
*/
|
||||
public interface TypeService {
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Type saveType(Type type);
|
||||
|
||||
|
||||
/**
|
||||
* 单个查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
Type getType(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
Page<Type> ListType(Pageable pageable);
|
||||
|
||||
/**
|
||||
* 查询所有分类
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Type> listType();
|
||||
|
||||
|
||||
List<Type> listTypeTop(Integer size);
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*
|
||||
* @param id
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
Type updateType(Long id, Type type);
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
void deleteType(Long id);
|
||||
|
||||
/**
|
||||
* 通过分类名称查询分类
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Type getTypeByName(String name);
|
||||
|
||||
}
|
||||
21
src/main/java/cn/allms/service/Userservice.java
Normal file
@ -0,0 +1,21 @@
|
||||
package cn.allms.service;
|
||||
|
||||
import cn.allms.po.User;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/9/28
|
||||
* @Description: com.yrp.service
|
||||
* @version: 1.0
|
||||
*/
|
||||
public interface Userservice {
|
||||
|
||||
/**
|
||||
* 用户登录检测
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
User checkUser(String username, String password);
|
||||
|
||||
}
|
||||
168
src/main/java/cn/allms/service/impl/BlogServiceImpl.java
Normal file
@ -0,0 +1,168 @@
|
||||
package cn.allms.service.impl;
|
||||
|
||||
import cn.allms.po.Blog;
|
||||
import cn.allms.vo.BlogQuery;
|
||||
import cn.allms.exception.NotFoundException;
|
||||
import cn.allms.dao.BlogRepository;
|
||||
import cn.allms.service.BlogService;
|
||||
import cn.allms.po.Type;
|
||||
import cn.allms.util.MarkdownUtils;
|
||||
import cn.allms.util.MyBeanUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
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.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.persistence.criteria.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/10/3
|
||||
* @Description: com.yrp.service.impl
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Service
|
||||
public class BlogServiceImpl implements BlogService {
|
||||
|
||||
@Autowired
|
||||
private BlogRepository blogRepository;
|
||||
|
||||
|
||||
@Override
|
||||
public Blog getBlog(Long id) {
|
||||
return blogRepository.findById(id).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blog getAadConvertBlog(Long id) {
|
||||
Blog blog = blogRepository.findById(id).orElse(null);
|
||||
if (blog == null) {
|
||||
throw new NotFoundException("该博客不存在!");
|
||||
}
|
||||
Blog b = new Blog();
|
||||
BeanUtils.copyProperties(blog, b);
|
||||
b.setContent(MarkdownUtils.markdownToHtmlExtensions(b.getContent()));
|
||||
blogRepository.updateViews(id);
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Blog> ListBlog(Pageable pageable, BlogQuery blog) {
|
||||
return blogRepository.findAll(new Specification<Blog>() {
|
||||
/**
|
||||
*
|
||||
* @param root 要查询的对象
|
||||
* @param cq 查询的一个条件容器
|
||||
* @param cb 设置具体某一个条件的表达式(模糊查询)
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Predicate toPredicate(Root<Blog> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
if (!"".equals(blog.getTitle()) && blog.getTitle() != null) {
|
||||
predicates.add(cb.like(root.<String>get("title"), "%" + blog.getTitle() + "%"));
|
||||
}
|
||||
if (blog.getTypeId() != null) {
|
||||
predicates.add(cb.equal(root.<Type>get("type").get("id"), blog.getTypeId()));
|
||||
}
|
||||
if (blog.isRecommend()) {
|
||||
predicates.add(cb.equal(root.<Boolean>get("recommend"), blog.isRecommend()));
|
||||
}
|
||||
cq.where(predicates.toArray(new Predicate[predicates.size()]));
|
||||
return null;
|
||||
}
|
||||
}, pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Blog> ListBlog(Pageable pageable) {
|
||||
return blogRepository.findAll(pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Blog> ListBlog(Long tagId, Pageable pageable) {
|
||||
|
||||
return blogRepository.findAll(new Specification<Blog>() {
|
||||
@Override
|
||||
public Predicate toPredicate(Root<Blog> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
|
||||
Join join = root.join("tags");
|
||||
return cb.equal(join.get("id"), tagId);
|
||||
}
|
||||
}, pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Blog> ListBlog(Pageable pageable, String query) {
|
||||
return blogRepository.findByQuery(query, pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Blog> listRecommendBlogTop(Integer size) {
|
||||
Sort sort = Sort.by(Sort.Direction.DESC, "updateTime");
|
||||
Pageable pageable = PageRequest.of(0, size, sort);
|
||||
return blogRepository.findTop(pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<Blog>> archiveBlog() {
|
||||
List<String> years = blogRepository.findGroupYear();
|
||||
Map<String, List<Blog>> map = new HashMap<>();
|
||||
for (String year : years) {
|
||||
map.put(year, blogRepository.findByYear(year));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long countBlog() {
|
||||
return blogRepository.count();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布博客
|
||||
* (如何是新增博客,需要添加创建时间和修改时间、以及初始化浏览量view = 0)
|
||||
* (如果是修改博客,需要添加修改时间)
|
||||
*
|
||||
* @param blog
|
||||
* @return
|
||||
*/
|
||||
@Transactional
|
||||
@Override
|
||||
public Blog saveBlog(Blog blog) {
|
||||
//博客新增
|
||||
return blogRepository.save(blog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 所谓的修改其实是查询+保存
|
||||
*
|
||||
* @param id
|
||||
* @param blog
|
||||
* @return
|
||||
*/
|
||||
@Transactional
|
||||
@Override
|
||||
public Blog updateBlog(Long id, Blog blog) {
|
||||
Blog b = blogRepository.findById(id).orElse(null);
|
||||
//判断是否存在这条数据
|
||||
if (b == null) {
|
||||
throw new NotFoundException("该博客不存在");
|
||||
}
|
||||
b.setUpdateTime(new Date());
|
||||
//copy有值属性 不覆盖
|
||||
BeanUtils.copyProperties(blog, b, MyBeanUtils.getNullPropertyNames(blog));
|
||||
return blogRepository.save(b);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void deleteBlog(Long id) {
|
||||
blogRepository.deleteById(id);
|
||||
}
|
||||
}
|
||||
50
src/main/java/cn/allms/service/impl/CommentServiceImpl.java
Normal file
@ -0,0 +1,50 @@
|
||||
package cn.allms.service.impl;
|
||||
|
||||
import cn.allms.util.CommentUtil;
|
||||
import cn.allms.dao.CommentRepository;
|
||||
import cn.allms.po.Comment;
|
||||
import cn.allms.service.CommentService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/10/10
|
||||
* @Description: com.yrp.service.impl
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Service
|
||||
public class CommentServiceImpl implements CommentService {
|
||||
|
||||
@Autowired
|
||||
private CommentRepository commentRepository;
|
||||
|
||||
@Override
|
||||
public List<Comment> listCommentByBlogId(Long blogId) {
|
||||
Sort sort = Sort.by("createTime");
|
||||
List<Comment> comments = commentRepository.findByBlogIdAndParentCommentNull(blogId, sort);
|
||||
return CommentUtil.eachComment(comments);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Comment saveComment(Comment comment) {
|
||||
//回复: 如果有父级,需要将父级set进来,之后在保存
|
||||
Long parentCommentId = comment.getParentComment().getId();
|
||||
System.out.println(parentCommentId);
|
||||
if (parentCommentId != -1) {
|
||||
comment.setParentComment(commentRepository.findById(parentCommentId).orElse(null));
|
||||
} else {
|
||||
//发布评论:
|
||||
comment.setParentComment(null);
|
||||
}
|
||||
comment.setCreateTime(new Date());
|
||||
return commentRepository.save(comment);
|
||||
}
|
||||
|
||||
}
|
||||
96
src/main/java/cn/allms/service/impl/TagServiceImpl.java
Normal file
@ -0,0 +1,96 @@
|
||||
package cn.allms.service.impl;
|
||||
|
||||
|
||||
import cn.allms.po.Tag;
|
||||
import cn.allms.service.TagService;
|
||||
import cn.allms.exception.NotFoundException;
|
||||
import cn.allms.dao.TagRepository;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
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.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 标签实现
|
||||
*/
|
||||
@Service
|
||||
public class TagServiceImpl implements TagService {
|
||||
|
||||
@Autowired
|
||||
private TagRepository tagRepository;
|
||||
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Tag saveTag(Tag tag) {
|
||||
return tagRepository.save(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getTag(Long id) {
|
||||
return tagRepository.findById(id).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<Tag> ListTag(Pageable pageable) {
|
||||
return tagRepository.findAll(pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tag> ListTagTop(Integer size) {
|
||||
Sort sort = Sort.by(Sort.Direction.DESC, "blogs.size");
|
||||
Pageable pageable = PageRequest.of(0, size, sort);
|
||||
return tagRepository.findTop(pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tag> ListTag() {
|
||||
return tagRepository.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Tag> ListTag(String ids) {
|
||||
// todo
|
||||
return tagRepository.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag updateTag(Long id, Tag tag) {
|
||||
Tag t = tagRepository.findById(id).orElse(null);
|
||||
if (t == null) {
|
||||
throw new NotFoundException("不存在该标签");
|
||||
}
|
||||
|
||||
BeanUtils.copyProperties(tag, t);
|
||||
return tagRepository.save(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTag(Long id) {
|
||||
tagRepository.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag getTagByName(String name) {
|
||||
return tagRepository.findByName(name);
|
||||
}
|
||||
|
||||
/*将字符串转化为集合*/
|
||||
private List<Long> convertToList(String ids) {
|
||||
List<Long> list = new ArrayList<>();
|
||||
if (!"".equals(ids) && ids != null) {
|
||||
String[] idarray = ids.split(",");
|
||||
for (int i = 0; i < idarray.length; i++) {
|
||||
list.add(new Long(idarray[i]));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
83
src/main/java/cn/allms/service/impl/TypeServiceImpl.java
Normal file
@ -0,0 +1,83 @@
|
||||
package cn.allms.service.impl;
|
||||
|
||||
import cn.allms.exception.NotFoundException;
|
||||
import cn.allms.dao.TypeRepository;
|
||||
import cn.allms.po.Type;
|
||||
import cn.allms.service.TypeService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
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.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/9/29
|
||||
* @Description: com.yrp.service.impl
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Service
|
||||
public class TypeServiceImpl implements TypeService {
|
||||
|
||||
@Autowired
|
||||
private TypeRepository typeRepository;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Type saveType(Type type) {
|
||||
|
||||
return typeRepository.save(type);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Type getType(Long id) {
|
||||
return typeRepository.findById(id).orElse(null);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Page<Type> ListType(Pageable pageable) {
|
||||
return typeRepository.findAll(pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Type> listType() {
|
||||
return typeRepository.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Type> listTypeTop(Integer size) {
|
||||
Sort sort = Sort.by(Sort.Direction.DESC, "blogs.size");
|
||||
Pageable pageable = PageRequest.of(0, size, sort);
|
||||
return typeRepository.findTop(pageable);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Type updateType(Long id, Type type) {
|
||||
Type t = typeRepository.findById(id).orElse(null);
|
||||
if (t == null) {
|
||||
throw new NotFoundException("不存在该类型");
|
||||
}
|
||||
BeanUtils.copyProperties(type, t);
|
||||
return typeRepository.save(t);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void deleteType(Long id) {
|
||||
typeRepository.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getTypeByName(String name) {
|
||||
return typeRepository.findByName(name);
|
||||
}
|
||||
}
|
||||
30
src/main/java/cn/allms/service/impl/UserServiceImpl.java
Normal file
@ -0,0 +1,30 @@
|
||||
package cn.allms.service.impl;
|
||||
|
||||
import cn.allms.po.User;
|
||||
import cn.allms.dao.UserRepository;
|
||||
import cn.allms.service.Userservice;
|
||||
import cn.allms.util.MD5Utils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/9/28
|
||||
* @Description: com.yrp.service.serviceimpl
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Service
|
||||
public class UserServiceImpl implements Userservice {
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
@Override
|
||||
public User checkUser(String username, String password) {
|
||||
System.out.println(username);
|
||||
System.out.println(password);
|
||||
User user = userRepository.findByUsernameAndPassword(username, MD5Utils.code(password));
|
||||
System.out.println(MD5Utils.code(password));
|
||||
return user;
|
||||
}
|
||||
}
|
||||
71
src/main/java/cn/allms/util/CommentUtil.java
Normal file
@ -0,0 +1,71 @@
|
||||
package cn.allms.util;
|
||||
|
||||
import cn.allms.po.Comment;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 评论格式化工具
|
||||
*/
|
||||
public class CommentUtil {
|
||||
/**
|
||||
* 循环每个顶级的评论节点
|
||||
*
|
||||
* @param comments
|
||||
* @return
|
||||
*/
|
||||
public static List<Comment> eachComment(List<Comment> comments) {
|
||||
List<Comment> commentsView = new ArrayList<>();
|
||||
for (Comment comment : comments) {
|
||||
Comment c = new Comment();
|
||||
BeanUtils.copyProperties(comment, c);
|
||||
commentsView.add(c);
|
||||
}
|
||||
//合并评论的各层子代到第一级子代集合中
|
||||
combineChildren(commentsView);
|
||||
return commentsView;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param comments root根节点,blog不为空的对象集合
|
||||
* @return
|
||||
*/
|
||||
public static void combineChildren(List<Comment> comments) {
|
||||
|
||||
for (Comment comment : comments) {
|
||||
List<Comment> replys1 = comment.getReplyComments();
|
||||
for (Comment reply1 : replys1) {
|
||||
//循环迭代,找出子代,存放在tempReplys中
|
||||
recursively(reply1);
|
||||
}
|
||||
//修改顶级节点的reply集合为迭代处理后的集合
|
||||
comment.setReplyComments(tempReplys);
|
||||
//清除临时存放区
|
||||
tempReplys = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
//存放迭代找出的所有子代的集合
|
||||
public static List<Comment> tempReplys = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 递归迭代,剥洋葱
|
||||
*
|
||||
* @param comment 被迭代的对象
|
||||
* @return
|
||||
*/
|
||||
public static void recursively(Comment comment) {
|
||||
tempReplys.add(comment);//顶节点添加到临时存放集合
|
||||
if (comment.getReplyComments().size() > 0) {
|
||||
List<Comment> replys = comment.getReplyComments();
|
||||
for (Comment reply : replys) {
|
||||
tempReplys.add(reply);
|
||||
if (reply.getReplyComments().size() > 0) {
|
||||
recursively(reply);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/main/java/cn/allms/util/MD5Utils.java
Normal file
@ -0,0 +1,47 @@
|
||||
package cn.allms.util;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* Created by limi on 2017/10/15.
|
||||
*/
|
||||
public class MD5Utils {
|
||||
|
||||
/**
|
||||
* MD5加密类
|
||||
*
|
||||
* @param str 要加密的字符串
|
||||
* @return 加密后的字符串
|
||||
*/
|
||||
public static String code(String str) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(str.getBytes());
|
||||
byte[] byteDigest = md.digest();
|
||||
int i;
|
||||
StringBuffer buf = new StringBuffer("");
|
||||
for (int offset = 0; offset < byteDigest.length; offset++) {
|
||||
i = byteDigest[offset];
|
||||
if (i < 0)
|
||||
i += 256;
|
||||
if (i < 16)
|
||||
buf.append("0");
|
||||
buf.append(Integer.toHexString(i));
|
||||
}
|
||||
//32位加密
|
||||
return buf.toString();
|
||||
// 16位的加密
|
||||
//return buf.toString().substring(8, 24);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(code("123"));
|
||||
}
|
||||
}
|
||||
89
src/main/java/cn/allms/util/MarkdownUtils.java
Normal file
@ -0,0 +1,89 @@
|
||||
package cn.allms.util;
|
||||
|
||||
import org.commonmark.Extension;
|
||||
import org.commonmark.ext.gfm.tables.TableBlock;
|
||||
import org.commonmark.ext.gfm.tables.TablesExtension;
|
||||
import org.commonmark.ext.heading.anchor.HeadingAnchorExtension;
|
||||
import org.commonmark.node.Link;
|
||||
import org.commonmark.node.Node;
|
||||
import org.commonmark.parser.Parser;
|
||||
import org.commonmark.renderer.html.AttributeProvider;
|
||||
import org.commonmark.renderer.html.AttributeProviderContext;
|
||||
import org.commonmark.renderer.html.AttributeProviderFactory;
|
||||
import org.commonmark.renderer.html.HtmlRenderer;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by limi on 2017/10/22.
|
||||
*/
|
||||
public class MarkdownUtils {
|
||||
|
||||
/**
|
||||
* markdown格式转换成HTML格式
|
||||
*
|
||||
* @param markdown
|
||||
* @return
|
||||
*/
|
||||
public static String markdownToHtml(String markdown) {
|
||||
Parser parser = Parser.builder().build();
|
||||
Node document = parser.parse(markdown);
|
||||
HtmlRenderer renderer = HtmlRenderer.builder().build();
|
||||
return renderer.render(document);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加扩展[标题锚点,表格生成]
|
||||
* Markdown转换成HTML
|
||||
*
|
||||
* @param markdown
|
||||
* @return
|
||||
*/
|
||||
public static String markdownToHtmlExtensions(String markdown) {
|
||||
//h标题生成id
|
||||
Set<Extension> headingAnchorExtensions = Collections.singleton(HeadingAnchorExtension.create());
|
||||
//转换table的HTML
|
||||
List<Extension> tableExtension = Arrays.asList(TablesExtension.create());
|
||||
Parser parser = Parser.builder()
|
||||
.extensions(tableExtension)
|
||||
.build();
|
||||
Node document = parser.parse(markdown);
|
||||
HtmlRenderer renderer = HtmlRenderer.builder()
|
||||
.extensions(headingAnchorExtensions)
|
||||
.extensions(tableExtension)
|
||||
.attributeProviderFactory(new AttributeProviderFactory() {
|
||||
public AttributeProvider create(AttributeProviderContext context) {
|
||||
return new CustomAttributeProvider();
|
||||
}
|
||||
})
|
||||
.build();
|
||||
return renderer.render(document);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理标签的属性
|
||||
*/
|
||||
static class CustomAttributeProvider implements AttributeProvider {
|
||||
@Override
|
||||
public void setAttributes(Node node, String tagName, Map<String, String> attributes) {
|
||||
//改变a标签的target属性为_blank
|
||||
if (node instanceof Link) {
|
||||
attributes.put("target", "_blank");
|
||||
}
|
||||
if (node instanceof TableBlock) {
|
||||
attributes.put("class", "ui celled table");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
String table = "| hello | hi | 哈哈哈 |\n" +
|
||||
"| ----- | ---- | ----- |\n" +
|
||||
"| 斯维尔多 | 士大夫 | f啊 |\n" +
|
||||
"| 阿什顿发 | 非固定杆 | 撒阿什顿发 |\n" +
|
||||
"\n";
|
||||
String a = "[imCoding 爱编程](http://www.lirenmi.cn)";
|
||||
System.out.println(markdownToHtmlExtensions(a));
|
||||
}
|
||||
}
|
||||
35
src/main/java/cn/allms/util/MyBeanUtils.java
Normal file
@ -0,0 +1,35 @@
|
||||
package cn.allms.util;
|
||||
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by limi on 2017/10/21.
|
||||
*/
|
||||
public class MyBeanUtils {
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有的属性值为空属性名数组
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static String[] getNullPropertyNames(Object source) {
|
||||
BeanWrapper beanWrapper = new BeanWrapperImpl(source);
|
||||
PropertyDescriptor[] pds = beanWrapper.getPropertyDescriptors();
|
||||
List<String> nullPropertyNames = new ArrayList<>();
|
||||
for (PropertyDescriptor pd : pds) {
|
||||
String propertyName = pd.getName();
|
||||
if (beanWrapper.getPropertyValue(propertyName) == null) {
|
||||
nullPropertyNames.add(propertyName);
|
||||
}
|
||||
}
|
||||
return nullPropertyNames.toArray(new String[nullPropertyNames.size()]);
|
||||
}
|
||||
|
||||
}
|
||||
49
src/main/java/cn/allms/vo/BlogQuery.java
Normal file
@ -0,0 +1,49 @@
|
||||
package cn.allms.vo;
|
||||
|
||||
/**
|
||||
* @Auther: 南迪叶先生:https://www.cnblogs.com/ye888/
|
||||
* @Date: 2019/10/3
|
||||
* @Description: com.yrp.vo
|
||||
* @version: 1.0
|
||||
*/
|
||||
public class BlogQuery {
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 分类ID
|
||||
*/
|
||||
private Long typeId;
|
||||
/**
|
||||
* 是否提交
|
||||
*/
|
||||
private boolean recommend;
|
||||
|
||||
public BlogQuery() {
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Long getTypeId() {
|
||||
return typeId;
|
||||
}
|
||||
|
||||
public void setTypeId(Long typeId) {
|
||||
this.typeId = typeId;
|
||||
}
|
||||
|
||||
public boolean isRecommend() {
|
||||
return recommend;
|
||||
}
|
||||
|
||||
public void setRecommend(boolean recommend) {
|
||||
this.recommend = recommend;
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,24 @@
|
||||
# 项目端口
|
||||
server:
|
||||
port: 9420
|
||||
servlet:
|
||||
context-path: /api
|
||||
|
||||
#数据库驱动mysql
|
||||
spring:
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/mx-blog?useUnicode=true&characterEncoding=utf-8&useSSL=false
|
||||
username: root
|
||||
password: 123456
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: create
|
||||
show-sql: false
|
||||
|
||||
#日志打印
|
||||
logging:
|
||||
level:
|
||||
root: info
|
||||
cn.allms: debug
|
||||
file:
|
||||
name: log/blog-dev.log
|
||||
path: classpath:logback/logback-spring.xml
|
||||
23
src/main/resources/application-pro.yml
Normal file
@ -0,0 +1,23 @@
|
||||
#thymeleaf模板
|
||||
spring:
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=utf-8
|
||||
username: root
|
||||
password: 123456
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: none
|
||||
show-sql: true
|
||||
|
||||
#日志打印
|
||||
logging:
|
||||
level:
|
||||
root: warn
|
||||
com.yrp: info
|
||||
file:
|
||||
name: log/-blogpro.log
|
||||
|
||||
# 服务端口
|
||||
server:
|
||||
port: 9420
|
||||
@ -1,4 +0,0 @@
|
||||
server:
|
||||
port: 9420
|
||||
servlet:
|
||||
context-path: /server
|
||||
@ -1,3 +1,19 @@
|
||||
#thymeleaf模板
|
||||
spring:
|
||||
thymeleaf:
|
||||
mode: HTML
|
||||
profiles:
|
||||
active: dev
|
||||
messages:
|
||||
basename: i18n/message
|
||||
|
||||
#博客头像
|
||||
comment:
|
||||
v2exUrl: https://sdn.geekzu.org/avatar/
|
||||
avatar: /images/avatar.png
|
||||
|
||||
# 随机图片
|
||||
random:
|
||||
pictures:
|
||||
- "https://api.rainss.cn/random.php?t="
|
||||
- "https://api.rainss.cn/acgimgurl/acgurl.php?t="
|
||||
14
src/main/resources/i18n/message.properties
Normal file
@ -0,0 +1,14 @@
|
||||
###########################\u524D\u53F0\u9875\u9762########################
|
||||
# \u9876\u90E8\u5BFC\u822A\u680F\u4FE1\u606F
|
||||
index.home=\u9996\u9875
|
||||
index.type=\u5206\u7C7B
|
||||
index.tag=\u6807\u7B7E
|
||||
index.archive=\u5F52\u6863
|
||||
index.aboutme=\u7AD9\u957F\u4FE1\u606F
|
||||
#\u5E95\u90E8\u5BFC\u822A\u680F\u4FE1\u606F
|
||||
index.email=\u90AE\u7BB1:qfmx520@163.com
|
||||
index.qq=QQ:745719461
|
||||
index.about=\u4F5C\u8005\u662F\u4E00\u540Dspringboot\u7231\u597D\u8005,\u662F\u4E00\u540D\u6B63\u5728\u52AA\u529B\u594B\u6597\u7684\u5B66\u751F,\u4E3B\u8981\u5B66\u4E60JavaEE\u5F00\u53D1,Web\u524D\u7AEF\u7B49\u6280\u672F.\u4F5C\u8005\u662F\u4E2A\u559C\u6B22\u65C5\u884C\u7684\u5B69\u5B50,\u76EE\u6807\u662F\u6E38\u904D\u5168\u4E16\u754C\uFF01
|
||||
index.copyright=copy @ 2020 - 2021 \u4f5c\u8005:\u6d45\u67ab\u6c90\u96ea \u6b64\u7ad9\u4ec5\u4f9b\u4e2a\u4eba\u6240\u6709 \u5982\u6709\u7591\u95ee\u8054\u7cfb\u4f5c\u8005
|
||||
#\u4E8C\u7EF4\u7801\u626B\u7801\u9605\u8BFB\u5730\u5740
|
||||
blog.serurl=127.0.0.1:80
|
||||
14
src/main/resources/i18n/message_en_US.properties
Normal file
@ -0,0 +1,14 @@
|
||||
###########################\u524D\u53F0\u9875\u9762########################
|
||||
# \u9876\u90E8\u5BFC\u822A\u680F\u4FE1\u606F
|
||||
index.home=Home
|
||||
index.type=Type
|
||||
index.tag=Tag
|
||||
index.archive=Archive
|
||||
index.aboutme=About Me
|
||||
#\u5E95\u90E8\u5BFC\u822A\u680F\u4FE1\u606F
|
||||
index.email=Email:qfmx520@163.com
|
||||
index.qq=QQ:745719461
|
||||
index.about=The author is a springboot enthusiast, a struggling student who mainly studies JavaEE development,Web front end and other technologies.
|
||||
index.copyright=copy @ 2020 - 2021 \u4f5c\u8005:\u6d45\u67ab\u6c90\u96ea \u6b64\u7ad9\u4ec5\u4f9b\u4e2a\u4eba\u6240\u6709 \u5982\u6709\u7591\u95ee\u8054\u7cfb\u4f5c\u8005
|
||||
#\u4E8C\u7EF4\u7801\u626B\u7801\u9605\u8BFB\u5730\u5740
|
||||
blog.serurl=172.20.10.6:8080
|
||||
14
src/main/resources/i18n/message_zh_CN.properties
Normal file
@ -0,0 +1,14 @@
|
||||
###########################\u524D\u53F0\u9875\u9762########################
|
||||
# \u9876\u90E8\u5BFC\u822A\u680F\u4FE1\u606F
|
||||
index.home=\u9996\u9875
|
||||
index.type=\u5206\u7C7B
|
||||
index.tag=\u6807\u7B7E
|
||||
index.archive=\u5F52\u6863
|
||||
index.aboutme=\u7AD9\u957F\u4FE1\u606F
|
||||
#\u5E95\u90E8\u5BFC\u822A\u680F\u4FE1\u606F
|
||||
index.email=\u90AE\u7BB1:qfmx520@163.com
|
||||
index.qq=QQ:745719461
|
||||
index.about=\u4F5C\u8005\u662F\u4E00\u540Dspringboot\u7231\u597D\u8005,\u662F\u4E00\u540D\u6B63\u5728\u52AA\u529B\u594B\u6597\u7684\u5B66\u751F,\u4E3B\u8981\u5B66\u4E60JavaEE\u5F00\u53D1,Web\u524D\u7AEF\u7B49\u6280\u672F.\u4F5C\u8005\u662F\u4E2A\u559C\u6B22\u65C5\u884C\u7684\u5B69\u5B50,\u76EE\u6807\u662F\u6E38\u904D\u5168\u4E16\u754C\uFF01
|
||||
index.copyright=copy @ 2020 - 2021 \u4f5c\u8005:\u6d45\u67ab\u6c90\u96ea \u6b64\u7ad9\u4ec5\u4f9b\u4e2a\u4eba\u6240\u6709 \u5982\u6709\u7591\u95ee\u8054\u7cfb\u4f5c\u8005
|
||||
#\u4E8C\u7EF4\u7801\u626B\u7801\u9605\u8BFB\u5730\u5740
|
||||
blog.serurl=172.20.10.6:8080
|
||||
44
src/main/resources/logback/logback-spring.xml
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<configuration>
|
||||
<!--包含Spring boot对logback日志的默认配置-->
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
|
||||
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
|
||||
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
|
||||
|
||||
<!--重写了Spring Boot框架 org/springframework/boot/logging/logback/file-appender.xml 配置-->
|
||||
<appender name="TIME_FILE"
|
||||
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<encoder>
|
||||
<pattern>${FILE_LOG_PATTERN}</pattern>
|
||||
</encoder>
|
||||
<file>${LOG_FILE}</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||
<!--保留历史日志一个月的时间-->
|
||||
<maxHistory>30</maxHistory>
|
||||
<!--
|
||||
Spring Boot默认情况下,日志文件10M时,会切分日志文件,这样设置日志文件会在100M时切分日志
|
||||
-->
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>10MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
<appender-ref ref="TIME_FILE" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
<!--
|
||||
1、继承Spring boot logback设置(可以在appliaction.yml或者application.properties设置logging.*属性)
|
||||
2、重写了默认配置,设置日志文件大小在100MB时,按日期切分日志,切分后目录:
|
||||
|
||||
my.2017-08-01.0 80MB
|
||||
my.2017-08-01.1 10MB
|
||||
my.2017-08-02.0 56MB
|
||||
my.2017-08-03.0 53MB
|
||||
......
|
||||
-->
|
||||
3625
src/main/resources/static/css/animate.css
vendored
Normal file
196
src/main/resources/static/css/me.css
Normal file
@ -0,0 +1,196 @@
|
||||
body{
|
||||
/*background: url("../images/leaves.png");*/
|
||||
background: url("../images/bg.png");
|
||||
/*background: url("../images/green_dust_scratch_@2X.png");*/
|
||||
/*background: url("../images/dust_scratches.png");*/
|
||||
/*background: url("../images/gravel.png");*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********内边距5个级别*********/
|
||||
.m-padding-lr-responsive{
|
||||
padding-left: 4em !important;
|
||||
padding-right: 4em !important;
|
||||
}
|
||||
|
||||
.m-padded-mini{
|
||||
padding:0.2em !important;
|
||||
}
|
||||
.m-padded-tiny{
|
||||
padding:0.3em !important;
|
||||
}
|
||||
.m-padded{
|
||||
padding:1em !important;
|
||||
}
|
||||
.m-padded-tb-mini{
|
||||
padding-top: 0.2em !important;
|
||||
padding-bottom: 0.2em !important;
|
||||
}
|
||||
.m-padded-tb-tiny{
|
||||
padding-top: 0.3em !important;
|
||||
padding-bottom: 0.3em !important;
|
||||
}
|
||||
.m-padded-tb-small{
|
||||
padding-top: 0.5em !important;
|
||||
padding-bottom: 0.5em !important;
|
||||
}
|
||||
.m-padded-tb{
|
||||
padding-top: 1em !important;
|
||||
padding-bottom: 1em !important;
|
||||
}
|
||||
.m-padded-tb-large{
|
||||
padding-top: 2em !important;
|
||||
padding-bottom: 2em !important;
|
||||
}
|
||||
.m-padded-tb-big{
|
||||
padding-top: 3em !important;
|
||||
padding-bottom: 3em !important;
|
||||
}
|
||||
.m-padded-tb-huge{
|
||||
padding-top: 4em !important;
|
||||
padding-bottom: 4em !important;
|
||||
}
|
||||
.m-padded-tb-massive{
|
||||
padding-top: 5em !important;
|
||||
padding-bottom: 5em !important;
|
||||
}
|
||||
|
||||
/**********外边距5个级别*********/
|
||||
.m-margin-tb-tiny{
|
||||
margin-top: 0.3em !important;
|
||||
margin-bottom: 0.3em !important;
|
||||
}
|
||||
|
||||
.m-margin-top-small{
|
||||
margin-top: 0.5em !important;
|
||||
}
|
||||
.m-margin-top{
|
||||
maring-top: 1em !important;
|
||||
}
|
||||
.m-margin-right{
|
||||
margin-right: 1em !important;
|
||||
}
|
||||
.m-margin-left{
|
||||
margin-left: 1em !important;
|
||||
}
|
||||
.m-margin-left-big{
|
||||
margin-left: 3em !important;
|
||||
}
|
||||
.m-margin-top-large{
|
||||
margin-top: 2em !important;
|
||||
}
|
||||
.m-margin{
|
||||
margin: 1em 1em !important;
|
||||
}
|
||||
.m-margin-bottom-mini{
|
||||
margin-bottom: 0.2em !important;
|
||||
}
|
||||
.m-margin-bottom-small{
|
||||
margin-bottom: 0.5em !important;
|
||||
}
|
||||
/**********Test**********/
|
||||
|
||||
/*字体粗细*/
|
||||
.m-text-thin{
|
||||
font-weight: 300 !important;
|
||||
}
|
||||
/*字间距*/
|
||||
.m-text-spaced{
|
||||
letter-spacing: 1px !important;
|
||||
}
|
||||
/*行间距*/
|
||||
.m-text-lined{
|
||||
line-height: 1.8 !important;
|
||||
}
|
||||
/*字体样式组合*/
|
||||
.m-text{
|
||||
font-weight: 300 !important;
|
||||
letter-spacing: 1px !important;
|
||||
line-height: 1.8 !important;
|
||||
}
|
||||
/*设置字体颜色*/
|
||||
.m-black{
|
||||
color: #333 !important;
|
||||
}
|
||||
.m-teal{
|
||||
color: #00B5AD !important;
|
||||
}
|
||||
/*透明度*/
|
||||
.m-opacity-min{
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
/*透明度*/
|
||||
.m-opacity-tiny{
|
||||
opacity: 0.6 !important;
|
||||
}
|
||||
/******* display*******/
|
||||
.m-inline-blok{
|
||||
display: inline-block !important;
|
||||
}
|
||||
/********position****/
|
||||
.m-right-top{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
.m-fixed{
|
||||
/*绝对定位*/
|
||||
position: fixed !important;
|
||||
z-index: 10 !important;
|
||||
}
|
||||
.m-right-button{
|
||||
bottom: 0 !important;
|
||||
right: 0 !important;
|
||||
}
|
||||
.m-container{
|
||||
max-width: 72em !important;
|
||||
margin: auto !important;
|
||||
}
|
||||
|
||||
.m-container-small{
|
||||
max-width: 60em !important;
|
||||
margin: auto !important;
|
||||
}
|
||||
/***mobile***/
|
||||
|
||||
.m-mobile-show{
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.m-mobile-wide{
|
||||
|
||||
}
|
||||
/***shadow****/
|
||||
.m-shadow-small{
|
||||
/*适配浏览器*/
|
||||
-webkit-box-shadow:0 4px 8px rgba(0,0,0,0.2)!important;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.2)!important;
|
||||
|
||||
}
|
||||
/*手机端*/
|
||||
@media screen and (max-width:768px){
|
||||
.m-mobile-hide{
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.m-mobile-show{
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.m-padding-lr-responsive{
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.m-mobile-clear{
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.m-mobile-wide{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
11
src/main/resources/static/css/semantic.min.css
vendored
Normal file
335
src/main/resources/static/css/typo.css
Normal file
@ -0,0 +1,335 @@
|
||||
@charset "utf-8";
|
||||
|
||||
.typo p {
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
line-height: 1.8;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.typo li {
|
||||
font-weight: 300;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
/* 重设 HTML5 标签, IE 需要在 js 中 createElement(TAG) */
|
||||
.typo article, aside, details, figcaption, figure, footer, header, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* HTML5 媒体文件跟 img 保持一致 */
|
||||
.typo audio, canvas, video {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* 要注意表单元素并不继承父级 font 的问题 */
|
||||
.typo button, input, select, textarea {
|
||||
font: 300 1em/1.8 PingFang SC, Lantinghei SC, Microsoft Yahei, Hiragino Sans GB, Microsoft Sans Serif, WenQuanYi Micro Hei, sans-serif;
|
||||
}
|
||||
|
||||
.typo button::-moz-focus-inner,
|
||||
.typo input::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* 去掉各Table cell 的边距并让其边重合 */
|
||||
.typo table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
/* 去除默认边框 */
|
||||
.typo fieldset, img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* 块/段落引用 */
|
||||
.typo blockquote {
|
||||
position: relative;
|
||||
color: #999;
|
||||
font-weight: 400;
|
||||
border-left: 1px solid #1abc9c;
|
||||
padding-left: 1em;
|
||||
margin: 1em 3em 1em 2em;
|
||||
}
|
||||
|
||||
@media only screen and ( max-width: 640px ) {
|
||||
.typo blockquote {
|
||||
margin: 1em 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Firefox 以外,元素没有下划线,需添加 */
|
||||
.typo acronym, abbr {
|
||||
border-bottom: 1px dotted;
|
||||
font-variant: normal;
|
||||
}
|
||||
|
||||
/* 添加鼠标问号,进一步确保应用的语义是正确的(要知道,交互他们也有洁癖,如果你不去掉,那得多花点口舌) */
|
||||
.typo abbr {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
/* 一致的 del 样式 */
|
||||
.typo del {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.typo address, caption, cite, code, dfn, em, th, var {
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* 去掉列表前的标识, li 会继承,大部分网站通常用列表来很多内容,所以应该当去 */
|
||||
.typo ul, ol {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* 对齐是排版最重要的因素, 别让什么都居中 */
|
||||
.typo caption, th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.typo q:before,.typo q:after {
|
||||
content: '';
|
||||
}
|
||||
|
||||
/* 统一上标和下标 */
|
||||
.typo sub,.typo sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.typo :root sub,.typo :root sup {
|
||||
vertical-align: baseline; /* for ie9 and other modern browsers */
|
||||
}
|
||||
|
||||
.typo sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
.typo sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
/* 让链接在 hover 状态下显示下划线 */
|
||||
.typo a {
|
||||
color: #1abc9c;
|
||||
}
|
||||
|
||||
.typo a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.typo a {
|
||||
border-bottom: 1px solid #1abc9c;
|
||||
}
|
||||
|
||||
.typo a:hover {
|
||||
border-bottom-color: #555;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* 默认不显示下划线,保持页面简洁 */
|
||||
.typo ins,.typo a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* 专名号:虽然 u 已经重回 html5 Draft,但在所有浏览器中都是可以使用的,
|
||||
* 要做到更好,向后兼容的话,添加 class="typo-u" 来显示专名号
|
||||
* 关于 <u> 标签:http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-u-element
|
||||
* 被放弃的是 4,之前一直搞错 http://www.w3.org/TR/html401/appendix/changes.html#idx-deprecated
|
||||
* 一篇关于 <u> 标签的很好文章:http://html5doctor.com/u-element/
|
||||
*/
|
||||
.typo u,.typo .typo-u {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 标记,类似于手写的荧光笔的作用 */
|
||||
.typo mark {
|
||||
background: #fffdd1;
|
||||
border-bottom: 1px solid #ffedce;
|
||||
padding: 2px;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
/* 代码片断 */
|
||||
.typo pre,.typo code,.typo pre tt {
|
||||
font-family: Courier, 'Courier New', monospace;
|
||||
}
|
||||
|
||||
.typo pre {
|
||||
background: #f8f8f8;
|
||||
border: 1px solid #ddd;
|
||||
padding: 1em 1.5em;
|
||||
display: block;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
/* 一致化 horizontal rule */
|
||||
.typo hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid #cfcfcf;
|
||||
margin-bottom: 0.8em;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
/* 底部印刷体、版本等标记 */
|
||||
.typo small,.typo .typo-small,
|
||||
/* 图片说明 */
|
||||
.typo figcaption {
|
||||
font-size: 0.9em;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.typo strong,.typo b {
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/* 可拖动文件添加拖动手势 */
|
||||
.typo [draggable] {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.typo .clearfix:before,.typo .clearfix:after {
|
||||
content: "";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.typo .clearfix:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.typo .clearfix {
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
/* 强制文本换行 */
|
||||
.typo .textwrap,.typo .textwrap td,.typo .textwrap th {
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.typo .textwrap-table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
/* 提供 serif 版本的字体设置: iOS 下中文自动 fallback 到 sans-serif */
|
||||
.typo .serif {
|
||||
font-family: Palatino, Optima, Georgia, serif;
|
||||
}
|
||||
|
||||
/* 保证块/段落之间的空白隔行 */
|
||||
.typo p, .typo pre, .typo ul, .typo ol, .typo dl, .typo form, .typo hr, .typo table,
|
||||
.typo-p, .typo-pre, .typo-ul, .typo-ol, .typo-dl, .typo-form, .typo-hr, .typo-table, blockquote {
|
||||
margin-bottom: 1.2em
|
||||
}
|
||||
|
||||
.typo h1,.typo h2,.typo h3,.typo h4,.typo h5,.typo h6 {
|
||||
font-family: PingFang SC, Verdana, Helvetica Neue, Microsoft Yahei, Hiragino Sans GB, Microsoft Sans Serif, WenQuanYi Micro Hei, sans-serif;
|
||||
font-weight: 100;
|
||||
color: #000;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
/* 标题应该更贴紧内容,并与其他块区分,margin 值要相应做优化 */
|
||||
.typo h1, .typo h2, .typo h3, .typo h4, .typo h5, .typo h6,
|
||||
.typo-h1, .typo-h2, .typo-h3, .typo-h4, .typo-h5, .typo-h6 {
|
||||
margin-top: 1.2em;
|
||||
margin-bottom: 0.6em;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.typo h1, .typo-h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.typo h2, .typo-h2 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
.typo h3, .typo-h3 {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
|
||||
.typo h4, .typo-h4 {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
.typo h5, .typo h6, .typo-h5, .typo-h6 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
/* 在文章中,应该还原 ul 和 ol 的样式 */
|
||||
.typo ul, .typo-ul {
|
||||
margin-left: 1.3em;
|
||||
list-style: disc;
|
||||
}
|
||||
|
||||
.typo ol, .typo-ol {
|
||||
list-style: decimal;
|
||||
margin-left: 1.9em;
|
||||
}
|
||||
|
||||
.typo li ul, .typo li ol, .typo-ul ul, .typo-ul ol, .typo-ol ul, .typo-ol ol {
|
||||
margin-bottom: 0.8em;
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
.typo li ul, .typo-ul ul, .typo-ol ul {
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
/* 同 ul/ol,在文章中应用 table 基本格式 */
|
||||
.typo table th, .typo table td, .typo-table th, .typo-table td, .typo table caption {
|
||||
border: 1px solid #ddd;
|
||||
padding: 0.5em 1em;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.typo table th, .typo-table th {
|
||||
background: #fbfbfb;
|
||||
}
|
||||
|
||||
.typo table thead th, .typo-table thead th {
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
.typo table caption {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* 去除 webkit 中 input 和 textarea 的默认样式 */
|
||||
.typo-input, .typo-textarea {
|
||||
-webkit-appearance: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.typo-em, .typo em, legend, caption {
|
||||
color: #000;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/* 着重号,只能在少量(少于100个字符)且全是全角字符的情况下使用 */
|
||||
.typo-em {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.typo-em:after {
|
||||
position: absolute;
|
||||
top: 0.65em;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
content: "・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・";
|
||||
}
|
||||
|
||||
/* Responsive images */
|
||||
.typo img {
|
||||
max-width: 100%;
|
||||
}
|
||||
BIN
src/main/resources/static/favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
src/main/resources/static/images/QQ.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
src/main/resources/static/images/WeChat.jpg
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/main/resources/static/images/avatar.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
src/main/resources/static/images/bg.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
src/main/resources/static/images/forever.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
src/main/resources/static/images/me.jpg
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
src/main/resources/static/images/me2.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/main/resources/static/images/mvp.jpg
Normal file
|
After Width: | Height: | Size: 425 KiB |
BIN
src/main/resources/static/images/pay_baby.jpg
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
src/main/resources/static/images/pay_wechat.jpg
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
src/main/resources/static/images/pay_wechat02.jpg
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
src/main/resources/static/images/tp.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
4450
src/main/resources/static/lib/editormd/css/editormd.css
Normal file
98
src/main/resources/static/lib/editormd/css/editormd.logo.css
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Editor.md
|
||||
*
|
||||
* @file editormd.logo.css
|
||||
* @version v1.5.0
|
||||
* @description Open source online markdown editor.
|
||||
* @license MIT License
|
||||
* @author Pandao
|
||||
* {@link https://github.com/pandao/editor.md}
|
||||
* @updateTime 2015-06-09
|
||||
*/
|
||||
|
||||
/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */
|
||||
@font-face {
|
||||
font-family: 'editormd-logo';
|
||||
src: url("../fonts/editormd-logo.eot?-5y8q6h");
|
||||
src: url(".../fonts/editormd-logo.eot?#iefix-5y8q6h") format("embedded-opentype"), url("../fonts/editormd-logo.woff?-5y8q6h") format("woff"), url("../fonts/editormd-logo.ttf?-5y8q6h") format("truetype"), url("../fonts/editormd-logo.svg?-5y8q6h#icomoon") format("svg");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
.editormd-logo,
|
||||
.editormd-logo-1x,
|
||||
.editormd-logo-2x,
|
||||
.editormd-logo-3x,
|
||||
.editormd-logo-4x,
|
||||
.editormd-logo-5x,
|
||||
.editormd-logo-6x,
|
||||
.editormd-logo-7x,
|
||||
.editormd-logo-8x {
|
||||
font-family: 'editormd-logo';
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
font-size: inherit;
|
||||
line-height: 1;
|
||||
display: inline-block;
|
||||
text-rendering: auto;
|
||||
vertical-align: inherit;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
.editormd-logo:before,
|
||||
.editormd-logo-1x:before,
|
||||
.editormd-logo-2x:before,
|
||||
.editormd-logo-3x:before,
|
||||
.editormd-logo-4x:before,
|
||||
.editormd-logo-5x:before,
|
||||
.editormd-logo-6x:before,
|
||||
.editormd-logo-7x:before,
|
||||
.editormd-logo-8x:before {
|
||||
content: "\e1987";
|
||||
/*
|
||||
HTML Entity 󡦇
|
||||
example: <span class="editormd-logo">󡦇</span>
|
||||
*/
|
||||
}
|
||||
|
||||
.editormd-logo-1x {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.editormd-logo-lg {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.editormd-logo-2x {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.editormd-logo-3x {
|
||||
font-size: 3em;
|
||||
}
|
||||
|
||||
.editormd-logo-4x {
|
||||
font-size: 4em;
|
||||
}
|
||||
|
||||
.editormd-logo-5x {
|
||||
font-size: 5em;
|
||||
}
|
||||
|
||||
.editormd-logo-6x {
|
||||
font-size: 6em;
|
||||
}
|
||||
|
||||
.editormd-logo-7x {
|
||||
font-size: 7em;
|
||||
}
|
||||
|
||||
.editormd-logo-8x {
|
||||
font-size: 8em;
|
||||
}
|
||||
|
||||
.editormd-logo-color {
|
||||
color: #2196F3;
|
||||
}
|
||||
2
src/main/resources/static/lib/editormd/css/editormd.logo.min.css
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/*! Editor.md v1.5.0 | editormd.logo.min.css | Open source online markdown editor. | MIT License | By: Pandao | https://github.com/pandao/editor.md | 2015-06-09 */
|
||||
/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */@font-face{font-family:editormd-logo;src:url(../fonts/editormd-logo.eot?-5y8q6h);src:url(.../fonts/editormd-logo.eot?#iefix-5y8q6h)format("embedded-opentype"),url(../fonts/editormd-logo.woff?-5y8q6h)format("woff"),url(../fonts/editormd-logo.ttf?-5y8q6h)format("truetype"),url(../fonts/editormd-logo.svg?-5y8q6h#icomoon)format("svg");font-weight:400;font-style:normal}.editormd-logo,.editormd-logo-1x,.editormd-logo-2x,.editormd-logo-3x,.editormd-logo-4x,.editormd-logo-5x,.editormd-logo-6x,.editormd-logo-7x,.editormd-logo-8x{font-family:editormd-logo;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;font-size:inherit;line-height:1;display:inline-block;text-rendering:auto;vertical-align:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.editormd-logo-1x:before,.editormd-logo-2x:before,.editormd-logo-3x:before,.editormd-logo-4x:before,.editormd-logo-5x:before,.editormd-logo-6x:before,.editormd-logo-7x:before,.editormd-logo-8x:before,.editormd-logo:before{content:"\e1987"}.editormd-logo-1x{font-size:1em}.editormd-logo-lg{font-size:1.2em}.editormd-logo-2x{font-size:2em}.editormd-logo-3x{font-size:3em}.editormd-logo-4x{font-size:4em}.editormd-logo-5x{font-size:5em}.editormd-logo-6x{font-size:6em}.editormd-logo-7x{font-size:7em}.editormd-logo-8x{font-size:8em}.editormd-logo-color{color:#2196F3}
|
||||
5
src/main/resources/static/lib/editormd/css/editormd.min.css
vendored
Normal file
3554
src/main/resources/static/lib/editormd/css/editormd.preview.css
Normal file
5
src/main/resources/static/lib/editormd/css/editormd.preview.min.css
vendored
Normal file
4598
src/main/resources/static/lib/editormd/editormd.js
Normal file
3
src/main/resources/static/lib/editormd/editormd.min.js
vendored
Normal file
BIN
src/main/resources/static/lib/editormd/fonts/FontAwesome.otf
Normal file
BIN
src/main/resources/static/lib/editormd/fonts/editormd-logo.eot
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Generated by IcoMoon</metadata>
|
||||
<defs>
|
||||
<font id="icomoon" horiz-adv-x="1024">
|
||||
<font-face units-per-em="1024" ascent="960" descent="-64" />
|
||||
<missing-glyph horiz-adv-x="1024" />
|
||||
<glyph unicode=" " d="" horiz-adv-x="512" />
|
||||
<glyph unicode="󡦇" d="M726.954 68.236l-91.855-56.319-21.517 106.748 113.371-50.43zM876.293 709.493l12.502 28.106c6.469 14.545 23.659 21.147 38.201 14.681l60.652-26.984c14.546-6.468 21.149-23.661 14.68-38.201l-12.502-28.106-113.536 50.505zM720.236 424.478l116.041 260.86-7.209 69.019h-130.248l-233.736-522.358-245.476 522.358h-133.528l-71.266-742.442h82.462l47.785 562.498 264.047-562.498h43.141l252.85 562.498 15.14-149.939zM761.891 11.915l-6.068 60.094 117.030 263.097 33.757-323.192-144.719 0.001zM621.638 137.007l113.54-50.503 246.486 554.111-113.536 50.506-246.489-554.114z" horiz-adv-x="1017" />
|
||||
</font></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |