mirror of https://github.com/halo-dev/halo
release 1.0.3 (#235)
release 1.0.3 Co-authored-by: John Niang <johnniang@riseup.net>pull/286/head^2 v1.0.3
commit
117883fc8d
148
README-en_US.md
148
README-en_US.md
|
@ -1,148 +0,0 @@
|
||||||

|
|
||||||
|
|
||||||
> Halo may be the best Java blog system.
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://ryanc.cc"><img alt="Author" src="https://img.shields.io/badge/author-ruibaby-red.svg?style=flat-square"/></a>
|
|
||||||
<a href="#"><img alt="JDK" src="https://img.shields.io/badge/JDK-1.8-yellow.svg?style=flat-square"/></a>
|
|
||||||
<a href="https://github.com/ruibaby/halo/releases"><img alt="GitHub release" src="https://img.shields.io/github/release/ruibaby/halo.svg?style=flat-square"/></a>
|
|
||||||
<a href="https://travis-ci.org/ruibaby/halo"><img alt="Travis CI" src="https://img.shields.io/travis/ruibaby/halo.svg?style=flat-square"/></a>
|
|
||||||
<a href="https://hub.docker.com/r/ruibaby/halo/"><img alt="Docker Build Status" src="https://img.shields.io/docker/build/ruibaby/halo.svg?style=flat-square"/></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
------------------------------
|
|
||||||
🇨🇳[简体中文](README.md) | 🇺🇸English
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
**Halo** [ˈheɪloʊ], Become the best blogging system using Java.
|
|
||||||
|
|
||||||
Fast, concise, and powerful blogging system developed in Java.
|
|
||||||
|
|
||||||
> QQ Group: 162747721,Telegram Group: [https://t.me/HaloBlog](https://t.me/HaloBlog) | Telegram Channel: [https://t.me/halo_dev](https://t.me/halo_dev) | [WeHalo 小程序](https://github.com/aquanlerou/WeHalo)。
|
|
||||||
|
|
||||||
## Demo
|
|
||||||
|
|
||||||
> Frontend: [https://demo.halo.run](https://demo.halo.run)
|
|
||||||
> Backend: [https://demo.halo.run/admin](https://demo.halo.run/admin)
|
|
||||||
> username: admin,password: 123456
|
|
||||||
|
|
||||||
## Quick start
|
|
||||||
|
|
||||||
Deploy with Docker:
|
|
||||||
```bash
|
|
||||||
# pull docker images
|
|
||||||
$ docker pull ruibaby/halo
|
|
||||||
|
|
||||||
# create docker container and run it
|
|
||||||
$ docker run -d --name halo -p 8090:8090 -v ~/halo:/root/halo ruibaby/halo
|
|
||||||
|
|
||||||
# Tips:DB_USER and DB_PASSWORD must be repaired and recorded
|
|
||||||
```
|
|
||||||
|
|
||||||
Deploy with Docker compose:
|
|
||||||
```bash
|
|
||||||
# Download the nginx config file template
|
|
||||||
$ curl https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl > /etc/nginx/nginx.tmpl
|
|
||||||
|
|
||||||
# Get the docker-compose.yaml
|
|
||||||
$ yum install -y wget && wget -O docker-compose.yaml https://git.io/fpS8N
|
|
||||||
|
|
||||||
# Modify docker-compose.yaml
|
|
||||||
# 1. modify VIRTUAL_HOST, LETSENCRYPT_HOST for your own domain name.
|
|
||||||
# 2. modify LETSENCRYPT_EMAIL to your own mailbox.
|
|
||||||
# 3. modify DB_USER .
|
|
||||||
# 4. modify DB_PASSWORD .
|
|
||||||
|
|
||||||
# run
|
|
||||||
$ docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
Deploy with shell script:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# install Halo
|
|
||||||
$ yum install -y wget && wget -O halo-cli.sh https://git.io/fxHqp && bash halo-cli.sh -i
|
|
||||||
|
|
||||||
# upgrade Halo
|
|
||||||
$ bash halo-cli.sh -u
|
|
||||||
```
|
|
||||||
|
|
||||||
> Tips: If you use Idea, Eclipse and other IDEs to run, you need to install the Lombok plugin, In addition, JDK10 is not supported at the moment, and there are problems with themes scanning and uploading.
|
|
||||||
> See the [Halo documentation](https://halo-doc.ryanc.cc/installation/) or [ Wiki](https://github.com/halo-dev/halo/wiki) for more details.
|
|
||||||
|
|
||||||
## Blogs with Halo
|
|
||||||
|
|
||||||
[Ryan0up'S Blog](https://ryanc.cc)
|
|
||||||
|
|
||||||
[SNAIL BLOG](https://slogc.cc)
|
|
||||||
|
|
||||||
[宋浩志博客](http://songhaozhi.com)
|
|
||||||
|
|
||||||
[KingYiFan'S Blog](https://blog.cnbuilder.cn)
|
|
||||||
|
|
||||||
[AquanBlog](https://blog.eunji.cn/)
|
|
||||||
|
|
||||||
## Themes
|
|
||||||
|
|
||||||
In addition to the built-in [Anatole](https://github.com/hi-caicai/farbox-theme-Anatole) and [Material](https://github.com/viosey/hexo-theme-material), there are the following The theme is not integrated in the project. If you need it, please download it and upload it through the background.
|
|
||||||
|
|
||||||
- [Vno](https://github.com/halo-dev/vno-halo) - From Jekyll,Author [Wei Wang](https://onevcat.com/).
|
|
||||||
- [Hux](https://github.com/halo-dev/hux-halo) - From Jekyll,Author [Xuan Huang](https://huangxuan.me/).
|
|
||||||
- [Story](https://github.com/halo-dev/story-halo) - From Typecho,Author [Trii Hsia](https://yumoe.com/).
|
|
||||||
- [NexT](https://github.com/halo-dev/next-halo) - From Hexo,Author [iissnan](https://notes.iissnan.com/).
|
|
||||||
- [Casper](https://github.com/halo-dev/casper-halo) - From Ghost,Author [Ghost](https://github.com/TryGhost).
|
|
||||||
- [Pinghsu](https://github.com/halo-dev/pinghsu-halo) - From Typecho,Author [Chakhsu.Lau](https://github.com/chakhsu).
|
|
||||||
|
|
||||||
> Disclaimer: Do not accept any comments or suggestions on the functionality of the **Porting Theme**.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
[](https://github.com/halo-dev/halo/blob/master/LICENSE)
|
|
||||||
|
|
||||||
> Halo uses the GPL-v3.0 protocol to open source.
|
|
||||||
|
|
||||||
## Thanks
|
|
||||||
|
|
||||||
The birth of Halo is inseparable from the following projects:
|
|
||||||
|
|
||||||
- [Spring Boot](https://github.com/spring-projects/spring-boot): Spring's rapid development framework
|
|
||||||
- [Freemarker](https://freemarker.apache.org/): Template engine to make pages static
|
|
||||||
- [H2 Database](https://github.com/h2database/h2database): Embedded database, no need to install
|
|
||||||
- [Spring-data-jpa](https://github.com/spring-projects/spring-data-jpa.git): a persistence layer framework that does not require writing sql statements
|
|
||||||
- [Ehcache](http://www.ehcache.org/): Cache Framework
|
|
||||||
- [Lombok](https://www.projectlombok.org/): Make the code simpler
|
|
||||||
- [oh-my-email](https://github.com/biezhi/oh-my-email): Probably the smallest Java mailing library, support for CC, attachments, templates, etc.
|
|
||||||
- [Hutool](https://github.com/looly/hutool): A Java Foundation Tools library
|
|
||||||
- [Thumbnailator](https://github.com/coobird/thumbnailator): thumbnail generation library
|
|
||||||
- [AdminLTE](https://github.com/almasaeed2010/AdminLTE): Bootstrap-based background template
|
|
||||||
- [Bootstrap](https://github.com/twbs/bootstrap.git): The most widely used front-end ui framework
|
|
||||||
- [Animate](https://github.com/daneden/animate.css.git): Very easy to use css effects library
|
|
||||||
- [SimpleMDE - Markdown Editor](https://github.com/sparksuite/simplemde-markdown-editor): Simple, functional, and lightweight Markdown editor
|
|
||||||
- [Bootstrap-FileInput](https://github.com/kartik-v/bootstrap-fileinput.git): Bootstrap-based file upload component
|
|
||||||
- [Font-awesome](https://github.com/FortAwesome/Font-Awesome.git): the most widely used font icon library
|
|
||||||
- [JQuery](https://github.com/jquery/jquery.git): The most widely used JavaScript framework
|
|
||||||
- [Layer](https://github.com/sentsin/layer.git): Personally think that the most practical and best-looking pop-up layer component, no one
|
|
||||||
- [JQuery-Toast](https://github.com/kamranahmedse/jquery-toast-plugin)
|
|
||||||
: message prompt component
|
|
||||||
- [Pjax](https://github.com/defunkt/jquery-pjax.git): pushState + ajax = pjax
|
|
||||||
|
|
||||||
## Donate
|
|
||||||
|
|
||||||
> If Halo is helpful to you, ask the author to have a ☕.
|
|
||||||
|
|
||||||
| AliPay/WeChat/QQ/PayPal |
|
|
||||||
| :------------: |
|
|
||||||
| <img src="https://i.loli.net/2018/12/23/5c1f68ce9b884.png" width="200"/> |
|
|
||||||
|
|
||||||
## Interface display
|
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
|
@ -26,13 +26,13 @@
|
||||||
### 下载最新的 Halo 安装包
|
### 下载最新的 Halo 安装包
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -L https://github.com/halo-dev/halo/releases/download/v1.0.2/halo-1.0.2.jar --output halo-latest.jar
|
curl -L https://github.com/halo-dev/halo/releases/download/v1.0.3/halo-1.0.3.jar --output halo-latest.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
或者
|
或者
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget https://github.com/halo-dev/halo/releases/download/v1.0.2/halo-1.0.2.jar -O halo-latest.jar
|
wget https://github.com/halo-dev/halo/releases/download/v1.0.3/halo-1.0.3.jar -O halo-latest.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
### 启动 Halo
|
### 启动 Halo
|
||||||
|
|
23
build.gradle
23
build.gradle
|
@ -9,7 +9,7 @@ apply plugin: 'io.spring.dependency-management'
|
||||||
|
|
||||||
group = 'run.halo.app'
|
group = 'run.halo.app'
|
||||||
archivesBaseName = 'halo'
|
archivesBaseName = 'halo'
|
||||||
version = '1.0.2'
|
version = '1.0.3'
|
||||||
sourceCompatibility = '1.8'
|
sourceCompatibility = '1.8'
|
||||||
description = 'Halo, personal blog system developed in Java.'
|
description = 'Halo, personal blog system developed in Java.'
|
||||||
|
|
||||||
|
@ -55,13 +55,6 @@ dependencies {
|
||||||
implementation 'com.qiniu:qiniu-java-sdk:7.2.18'
|
implementation 'com.qiniu:qiniu-java-sdk:7.2.18'
|
||||||
implementation 'com.aliyun.oss:aliyun-sdk-oss:3.4.2'
|
implementation 'com.aliyun.oss:aliyun-sdk-oss:3.4.2'
|
||||||
implementation 'net.coobird:thumbnailator:0.4.8'
|
implementation 'net.coobird:thumbnailator:0.4.8'
|
||||||
implementation 'com.atlassian.commonmark:commonmark:0.12.1'
|
|
||||||
implementation 'com.atlassian.commonmark:commonmark-ext-gfm-tables:0.12.1'
|
|
||||||
implementation 'com.atlassian.commonmark:commonmark-ext-yaml-front-matter:0.12.1'
|
|
||||||
implementation 'com.atlassian.commonmark:commonmark-ext-autolink:0.12.1'
|
|
||||||
implementation 'com.atlassian.commonmark:commonmark-ext-gfm-strikethrough:0.12.1'
|
|
||||||
implementation 'com.atlassian.commonmark:commonmark-ext-heading-anchor:0.12.1'
|
|
||||||
implementation 'com.atlassian.commonmark:commonmark-ext-ins:0.12.1'
|
|
||||||
implementation 'io.springfox:springfox-swagger2:2.9.2'
|
implementation 'io.springfox:springfox-swagger2:2.9.2'
|
||||||
implementation 'io.springfox:springfox-swagger-ui:2.9.2'
|
implementation 'io.springfox:springfox-swagger-ui:2.9.2'
|
||||||
implementation 'org.apache.commons:commons-lang3:3.8.1'
|
implementation 'org.apache.commons:commons-lang3:3.8.1'
|
||||||
|
@ -69,6 +62,20 @@ dependencies {
|
||||||
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.9.2'
|
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.9.2'
|
||||||
implementation 'org.eclipse.jgit:org.eclipse.jgit:5.3.0.201903130848-r'
|
implementation 'org.eclipse.jgit:org.eclipse.jgit:5.3.0.201903130848-r'
|
||||||
|
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark:0.42.12'
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark-ext-attributes:0.42.12'
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark-ext-autolink:0.42.12'
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark-ext-emoji:0.42.12'
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark-ext-escaped-character:0.42.12'
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark-ext-gfm-strikethrough:0.42.12'
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark-ext-gfm-tasklist:0.42.12'
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark-ext-ins:0.42.12'
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark-ext-media-tags:0.42.12'
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark-ext-tables:0.42.12'
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark-ext-toc:0.42.12'
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark-ext-yaml-front-matter:0.42.12'
|
||||||
|
implementation 'com.vladsch.flexmark:flexmark-html-parser:0.42.12'
|
||||||
|
|
||||||
runtimeOnly 'com.h2database:h2'
|
runtimeOnly 'com.h2database:h2'
|
||||||
runtimeOnly 'mysql:mysql-connector-java'
|
runtimeOnly 'mysql:mysql-connector-java'
|
||||||
|
|
||||||
|
|
|
@ -147,18 +147,24 @@ public class SwaggerConfiguration {
|
||||||
private List<SecurityContext> contentSecurityContext() {
|
private List<SecurityContext> contentSecurityContext() {
|
||||||
return Collections.singletonList(
|
return Collections.singletonList(
|
||||||
SecurityContext.builder()
|
SecurityContext.builder()
|
||||||
.securityReferences(defaultAuth())
|
.securityReferences(contentApiAuth())
|
||||||
.forPaths(PathSelectors.regex("/api/content/.*"))
|
.forPaths(PathSelectors.regex("/api/content/.*"))
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SecurityReference> defaultAuth() {
|
private List<SecurityReference> defaultAuth() {
|
||||||
AuthorizationScope[] authorizationScopes = {new AuthorizationScope("global", "accessEverything")};
|
AuthorizationScope[] authorizationScopes = {new AuthorizationScope("Admin api", "Access admin api")};
|
||||||
return Arrays.asList(new SecurityReference("Token from header", authorizationScopes),
|
return Arrays.asList(new SecurityReference("Token from header", authorizationScopes),
|
||||||
new SecurityReference("Token from query", authorizationScopes));
|
new SecurityReference("Token from query", authorizationScopes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<SecurityReference> contentApiAuth() {
|
||||||
|
AuthorizationScope[] authorizationScopes = {new AuthorizationScope("content api", "Access content api")};
|
||||||
|
return Arrays.asList(new SecurityReference("Access key from header", authorizationScopes),
|
||||||
|
new SecurityReference("Access key from query", authorizationScopes));
|
||||||
|
}
|
||||||
|
|
||||||
private ApiInfo apiInfo() {
|
private ApiInfo apiInfo() {
|
||||||
return new ApiInfoBuilder()
|
return new ApiInfoBuilder()
|
||||||
.title("Halo API Documentation")
|
.title("Halo API Documentation")
|
||||||
|
|
|
@ -81,13 +81,11 @@ public class WebMvcAutoConfiguration implements WebMvcConfigurer {
|
||||||
@Override
|
@Override
|
||||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
String workDir = FILE_PROTOCOL + haloProperties.getWorkDir();
|
String workDir = FILE_PROTOCOL + haloProperties.getWorkDir();
|
||||||
registry.addResourceHandler("/static/**")
|
|
||||||
.addResourceLocations("classpath:/static/")
|
|
||||||
.addResourceLocations(workDir + "static/");
|
|
||||||
registry.addResourceHandler("/**")
|
registry.addResourceHandler("/**")
|
||||||
.addResourceLocations(workDir + "templates/themes/")
|
.addResourceLocations(workDir + "templates/themes/")
|
||||||
.addResourceLocations(workDir + "templates/admin/")
|
.addResourceLocations(workDir + "templates/admin/")
|
||||||
.addResourceLocations("classpath:/admin/");
|
.addResourceLocations("classpath:/admin/")
|
||||||
|
.addResourceLocations(workDir + "static/");
|
||||||
registry.addResourceHandler("/upload/**")
|
registry.addResourceHandler("/upload/**")
|
||||||
.addResourceLocations(workDir + "upload/");
|
.addResourceLocations(workDir + "upload/");
|
||||||
registry.addResourceHandler("/backup/**")
|
registry.addResourceHandler("/backup/**")
|
||||||
|
@ -122,7 +120,7 @@ public class WebMvcAutoConfiguration implements WebMvcConfigurer {
|
||||||
configurer.setDefaultEncoding("UTF-8");
|
configurer.setDefaultEncoding("UTF-8");
|
||||||
|
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.setProperty("auto_import", "/common/macro/common_macro.ftl as common");
|
properties.setProperty("auto_import", "/common/macro/common_macro.ftl as common,/common/macro/global_macro.ftl as global");
|
||||||
|
|
||||||
configurer.setFreemarkerSettings(properties);
|
configurer.setFreemarkerSettings(properties);
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,13 @@ package run.halo.app.controller.admin.api;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import run.halo.app.cache.lock.CacheLock;
|
import run.halo.app.cache.lock.CacheLock;
|
||||||
import run.halo.app.model.dto.EnvironmentDTO;
|
import run.halo.app.model.dto.EnvironmentDTO;
|
||||||
import run.halo.app.model.dto.StatisticDTO;
|
import run.halo.app.model.dto.StatisticDTO;
|
||||||
import run.halo.app.model.params.LoginParam;
|
import run.halo.app.model.params.LoginParam;
|
||||||
|
import run.halo.app.model.support.BaseResponse;
|
||||||
import run.halo.app.security.token.AuthToken;
|
import run.halo.app.security.token.AuthToken;
|
||||||
import run.halo.app.service.AdminService;
|
import run.halo.app.service.AdminService;
|
||||||
|
|
||||||
|
@ -16,6 +18,7 @@ import javax.validation.Valid;
|
||||||
* Admin controller.
|
* Admin controller.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @author ryanwang
|
||||||
* @date 3/19/19
|
* @date 3/19/19
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -73,4 +76,9 @@ public class AdminController {
|
||||||
adminService.updateAdminAssets();
|
adminService.updateAdminAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("spring/logs")
|
||||||
|
@ApiOperation("Get application logs")
|
||||||
|
public BaseResponse<String> getSpringLogs() {
|
||||||
|
return BaseResponse.ok(HttpStatus.OK.getReasonPhrase(),adminService.getSpringLogs());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ public class RecoveryController {
|
||||||
@ApiParam("This file content type should be json")
|
@ApiParam("This file content type should be json")
|
||||||
@RequestPart("file") MultipartFile file) {
|
@RequestPart("file") MultipartFile file) {
|
||||||
if (optionService.getByPropertyOrDefault(PrimaryProperties.IS_INSTALLED, Boolean.class, false)) {
|
if (optionService.getByPropertyOrDefault(PrimaryProperties.IS_INSTALLED, Boolean.class, false)) {
|
||||||
throw new BadRequestException("不能在博客初始化完成之后迁移数据");
|
throw new BadRequestException("无法在博客初始化完成之后迁移数据");
|
||||||
}
|
}
|
||||||
|
|
||||||
recoveryService.migrateFromV0_4_3(file);
|
recoveryService.migrateFromV0_4_3(file);
|
||||||
|
|
|
@ -13,12 +13,15 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import run.halo.app.model.entity.Category;
|
import run.halo.app.model.entity.Category;
|
||||||
import run.halo.app.model.entity.Post;
|
import run.halo.app.model.entity.Post;
|
||||||
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.model.vo.PostListVO;
|
import run.halo.app.model.vo.PostListVO;
|
||||||
import run.halo.app.service.*;
|
import run.halo.app.service.*;
|
||||||
|
|
||||||
import static org.springframework.data.domain.Sort.Direction.DESC;
|
import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Category controller.
|
||||||
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019/3/20
|
* @date : 2019/3/20
|
||||||
*/
|
*/
|
||||||
|
@ -85,10 +88,10 @@ public class ContentCategoryController {
|
||||||
@PathVariable("page") Integer page,
|
@PathVariable("page") Integer page,
|
||||||
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
|
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
|
||||||
// Get category by slug name
|
// Get category by slug name
|
||||||
final Category category = categoryService.getBySlugName(slugName);
|
final Category category = categoryService.getBySlugNameOfNonNull(slugName);
|
||||||
|
|
||||||
final Pageable pageable = PageRequest.of(page - 1, optionService.getPostPageSize(), sort);
|
final Pageable pageable = PageRequest.of(page - 1, optionService.getPostPageSize(), sort);
|
||||||
Page<Post> postPage = postCategoryService.pagePostBy(category.getId(), pageable);
|
Page<Post> postPage = postCategoryService.pagePostBy(category.getId(), PostStatus.PUBLISHED, pageable);
|
||||||
Page<PostListVO> posts = postService.convertToListVo(postPage);
|
Page<PostListVO> posts = postService.convertToListVo(postPage);
|
||||||
final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
|
final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ import run.halo.app.service.ThemeService;
|
||||||
import static org.springframework.data.domain.Sort.Direction.DESC;
|
import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search Controller
|
* Search controller.
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-04-21
|
* @date : 2019-04-21
|
||||||
|
|
|
@ -13,13 +13,14 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import run.halo.app.model.entity.Post;
|
import run.halo.app.model.entity.Post;
|
||||||
import run.halo.app.model.entity.Tag;
|
import run.halo.app.model.entity.Tag;
|
||||||
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.model.vo.PostListVO;
|
import run.halo.app.model.vo.PostListVO;
|
||||||
import run.halo.app.service.*;
|
import run.halo.app.service.*;
|
||||||
|
|
||||||
import static org.springframework.data.domain.Sort.Direction.DESC;
|
import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tag Controller
|
* Tag controller.
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-03-21
|
* @date : 2019-03-21
|
||||||
|
@ -91,7 +92,7 @@ public class ContentTagController {
|
||||||
final Tag tag = tagService.getBySlugNameOfNonNull(slugName);
|
final Tag tag = tagService.getBySlugNameOfNonNull(slugName);
|
||||||
|
|
||||||
final Pageable pageable = PageRequest.of(page - 1, optionService.getPostPageSize(), sort);
|
final Pageable pageable = PageRequest.of(page - 1, optionService.getPostPageSize(), sort);
|
||||||
Page<Post> postPage = postTagService.pagePostsBy(tag.getId(), pageable);
|
Page<Post> postPage = postTagService.pagePostsBy(tag.getId(), PostStatus.PUBLISHED, pageable);
|
||||||
Page<PostListVO> posts = postService.convertToListVo(postPage);
|
Page<PostListVO> posts = postService.convertToListVo(postPage);
|
||||||
final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
|
final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Admin page.
|
* Main controller.
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-04-23
|
* @date : 2019-04-23
|
||||||
|
|
|
@ -11,6 +11,7 @@ import run.halo.app.model.dto.CategoryDTO;
|
||||||
import run.halo.app.model.dto.post.BasePostSimpleDTO;
|
import run.halo.app.model.dto.post.BasePostSimpleDTO;
|
||||||
import run.halo.app.model.entity.Category;
|
import run.halo.app.model.entity.Category;
|
||||||
import run.halo.app.model.entity.Post;
|
import run.halo.app.model.entity.Post;
|
||||||
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.service.CategoryService;
|
import run.halo.app.service.CategoryService;
|
||||||
import run.halo.app.service.PostCategoryService;
|
import run.halo.app.service.PostCategoryService;
|
||||||
import run.halo.app.service.PostService;
|
import run.halo.app.service.PostService;
|
||||||
|
@ -58,9 +59,9 @@ public class CategoryController {
|
||||||
public Page<BasePostSimpleDTO> listPostsBy(@PathVariable("slugName") String slugName,
|
public Page<BasePostSimpleDTO> listPostsBy(@PathVariable("slugName") String slugName,
|
||||||
@PageableDefault(sort = "updateTime", direction = DESC) Pageable pageable) {
|
@PageableDefault(sort = "updateTime", direction = DESC) Pageable pageable) {
|
||||||
// Get category by slug name
|
// Get category by slug name
|
||||||
Category category = categoryService.getBySlugName(slugName);
|
Category category = categoryService.getBySlugNameOfNonNull(slugName);
|
||||||
|
|
||||||
Page<Post> postPage = postCategoryService.pagePostBy(category.getId(), pageable);
|
Page<Post> postPage = postCategoryService.pagePostBy(category.getId(), PostStatus.PUBLISHED, pageable);
|
||||||
return postService.convertToSimple(postPage);
|
return postService.convertToSimple(postPage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import run.halo.app.model.dto.TagDTO;
|
||||||
import run.halo.app.model.dto.post.BasePostSimpleDTO;
|
import run.halo.app.model.dto.post.BasePostSimpleDTO;
|
||||||
import run.halo.app.model.entity.Post;
|
import run.halo.app.model.entity.Post;
|
||||||
import run.halo.app.model.entity.Tag;
|
import run.halo.app.model.entity.Tag;
|
||||||
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.service.PostService;
|
import run.halo.app.service.PostService;
|
||||||
import run.halo.app.service.PostTagService;
|
import run.halo.app.service.PostTagService;
|
||||||
import run.halo.app.service.TagService;
|
import run.halo.app.service.TagService;
|
||||||
|
@ -24,6 +25,7 @@ import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||||
* Portal tag controller.
|
* Portal tag controller.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @author ryanwang
|
||||||
* @date 4/2/19
|
* @date 4/2/19
|
||||||
*/
|
*/
|
||||||
@RestController("ApiContentTagController")
|
@RestController("ApiContentTagController")
|
||||||
|
@ -63,7 +65,7 @@ public class TagController {
|
||||||
Tag tag = tagService.getBySlugNameOfNonNull(slugName);
|
Tag tag = tagService.getBySlugNameOfNonNull(slugName);
|
||||||
|
|
||||||
// Get posts, convert and return
|
// Get posts, convert and return
|
||||||
Page<Post> postPage = postTagService.pagePostsBy(tag.getId(), pageable);
|
Page<Post> postPage = postTagService.pagePostsBy(tag.getId(), PostStatus.PUBLISHED, pageable);
|
||||||
return postService.convertToSimple(postPage);
|
return postService.convertToSimple(postPage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import static run.halo.app.utils.BeanUtils.updateProperties;
|
||||||
* <b>The implementation type must be equal to DTO type</b>
|
* <b>The implementation type must be equal to DTO type</b>
|
||||||
*
|
*
|
||||||
* @param <DTO> the implementation class type
|
* @param <DTO> the implementation class type
|
||||||
* @param <DOMAIN> doamin type
|
* @param <DOMAIN> domain type
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
*/
|
*/
|
||||||
public interface OutputConverter<DTO extends OutputConverter<DTO, DOMAIN>, DOMAIN> {
|
public interface OutputConverter<DTO extends OutputConverter<DTO, DOMAIN>, DOMAIN> {
|
||||||
|
|
|
@ -5,7 +5,6 @@ import lombok.EqualsAndHashCode;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import run.halo.app.model.enums.PostCreateFrom;
|
import run.halo.app.model.enums.PostCreateFrom;
|
||||||
import run.halo.app.model.enums.PostStatus;
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.utils.MarkdownUtils;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -54,7 +53,7 @@ public class BasePost extends BaseEntity {
|
||||||
/**
|
/**
|
||||||
* Rendered content.
|
* Rendered content.
|
||||||
*
|
*
|
||||||
* @see MarkdownUtils#renderMarkdown(String)
|
* @see run.halo.app.utils.MarkdownUtils#renderHtml(String)
|
||||||
*/
|
*/
|
||||||
@Column(name = "format_content", columnDefinition = "text not null")
|
@Column(name = "format_content", columnDefinition = "text not null")
|
||||||
private String formatContent;
|
private String formatContent;
|
||||||
|
|
|
@ -45,6 +45,7 @@ public class CategoryTagDirective implements TemplateDirectiveModel {
|
||||||
case "listByPostId":
|
case "listByPostId":
|
||||||
Integer postId = Integer.parseInt(params.get("postId").toString());
|
Integer postId = Integer.parseInt(params.get("postId").toString());
|
||||||
env.setVariable("categories", builder.build().wrap(postCategoryService.listCategoryBy(postId)));
|
env.setVariable("categories", builder.build().wrap(postCategoryService.listCategoryBy(postId)));
|
||||||
|
break;
|
||||||
case "count":
|
case "count":
|
||||||
env.setVariable("count", builder.build().wrap(categoryService.count()));
|
env.setVariable("count", builder.build().wrap(categoryService.count()));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -3,6 +3,7 @@ package run.halo.app.model.freemarker.tag;
|
||||||
import freemarker.core.Environment;
|
import freemarker.core.Environment;
|
||||||
import freemarker.template.*;
|
import freemarker.template.*;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.model.support.HaloConst;
|
import run.halo.app.model.support.HaloConst;
|
||||||
import run.halo.app.service.PostCategoryService;
|
import run.halo.app.service.PostCategoryService;
|
||||||
import run.halo.app.service.PostService;
|
import run.halo.app.service.PostService;
|
||||||
|
@ -57,11 +58,11 @@ public class PostTagDirective implements TemplateDirectiveModel {
|
||||||
break;
|
break;
|
||||||
case "listByCategoryId":
|
case "listByCategoryId":
|
||||||
Integer categoryId = Integer.parseInt(params.get("categoryId").toString());
|
Integer categoryId = Integer.parseInt(params.get("categoryId").toString());
|
||||||
env.setVariable("posts", builder.build().wrap(postCategoryService.listPostBy(categoryId)));
|
env.setVariable("posts", builder.build().wrap(postCategoryService.listPostBy(categoryId, PostStatus.PUBLISHED)));
|
||||||
break;
|
break;
|
||||||
case "listByTagId":
|
case "listByTagId":
|
||||||
Integer tagId = Integer.parseInt(params.get("tagId").toString());
|
Integer tagId = Integer.parseInt(params.get("tagId").toString());
|
||||||
env.setVariable("posts", builder.build().wrap(postTagService.listPostsBy(tagId)));
|
env.setVariable("posts", builder.build().wrap(postTagService.listPostsBy(tagId, PostStatus.PUBLISHED)));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package run.halo.app.model.properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Api properties.
|
||||||
|
*
|
||||||
|
* @author ryanwang
|
||||||
|
* @date 2019-06-25
|
||||||
|
*/
|
||||||
|
public enum ApiProperties implements PropertyEnum {
|
||||||
|
|
||||||
|
API_ENABLED("api_enabled", Boolean.class, "false"),
|
||||||
|
|
||||||
|
API_ACCESS_KEY("api_access_key", String.class, "");
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
private final Class<?> type;
|
||||||
|
|
||||||
|
private final String defaultValue;
|
||||||
|
|
||||||
|
ApiProperties(String value, Class<?> type, String defaultValue) {
|
||||||
|
this.value = value;
|
||||||
|
this.type = type;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String defaultValue() {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,22 +4,14 @@ package run.halo.app.model.properties;
|
||||||
* Other properties.
|
* Other properties.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @author ryanwang
|
||||||
* @date 4/1/19
|
* @date 4/1/19
|
||||||
*/
|
*/
|
||||||
public enum OtherProperties implements PropertyEnum {
|
public enum OtherProperties implements PropertyEnum {
|
||||||
|
|
||||||
API_ENABLED("api_enabled", Boolean.class, "false"),
|
|
||||||
|
|
||||||
API_ACCESS_KEY("api_access_key", String.class, ""),
|
|
||||||
|
|
||||||
CUSTOM_HEAD("blog_custom_head",String.class,""),
|
CUSTOM_HEAD("blog_custom_head",String.class,""),
|
||||||
|
|
||||||
STATISTICS_CODE("blog_statistics_code", String.class, ""),
|
STATISTICS_CODE("blog_statistics_code", String.class, "");
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否禁止爬虫
|
|
||||||
*/
|
|
||||||
SPIDER_DISABLED("spider_disabled", Boolean.class, "false");
|
|
||||||
|
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,7 @@ public interface PropertyEnum extends ValueEnum<String> {
|
||||||
propertyEnumClasses.add(QnYunProperties.class);
|
propertyEnumClasses.add(QnYunProperties.class);
|
||||||
propertyEnumClasses.add(SeoProperties.class);
|
propertyEnumClasses.add(SeoProperties.class);
|
||||||
propertyEnumClasses.add(UpYunProperties.class);
|
propertyEnumClasses.add(UpYunProperties.class);
|
||||||
|
propertyEnumClasses.add(ApiProperties.class);
|
||||||
|
|
||||||
Map<String, PropertyEnum> result = new HashMap<>();
|
Map<String, PropertyEnum> result = new HashMap<>();
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ package run.halo.app.model.properties;
|
||||||
* SEO properties.
|
* SEO properties.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @author ryanwang
|
||||||
* @date 4/1/19
|
* @date 4/1/19
|
||||||
*/
|
*/
|
||||||
public enum SeoProperties implements PropertyEnum {
|
public enum SeoProperties implements PropertyEnum {
|
||||||
|
@ -14,13 +15,10 @@ public enum SeoProperties implements PropertyEnum {
|
||||||
|
|
||||||
BAIDU_TOKEN("seo_baidu_token", String.class, ""),
|
BAIDU_TOKEN("seo_baidu_token", String.class, ""),
|
||||||
|
|
||||||
VERIFICATION_BAIDU("seo_verification_baidu", String.class, ""),
|
/**
|
||||||
|
* 是否禁止爬虫
|
||||||
VERIFICATION_GOOGLE("seo_verification_google", String.class, ""),
|
*/
|
||||||
|
SPIDER_DISABLED("seo_spider_disabled", Boolean.class, "false");
|
||||||
VERIFICATION_BING("seo_verification_bing", String.class, ""),
|
|
||||||
|
|
||||||
VERIFICATION_QIHU("seo_verification_qihu", String.class, "");
|
|
||||||
|
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
package run.halo.app.model.support;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <pre>
|
|
||||||
* 日志常量
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author ryanwang
|
|
||||||
* @date : 2018/1/19
|
|
||||||
*/
|
|
||||||
public interface LogsRecord {
|
|
||||||
|
|
||||||
String INSTALL = "初始化博客";
|
|
||||||
|
|
||||||
String LOGIN = "登录后台";
|
|
||||||
|
|
||||||
String LOGIN_SUCCESS = "登录成功";
|
|
||||||
|
|
||||||
String LOGIN_ERROR = "登录失败";
|
|
||||||
|
|
||||||
String LOGOUT = "退出登录";
|
|
||||||
|
|
||||||
String PUSH_POST = "发表文章";
|
|
||||||
|
|
||||||
String PUSH_PAGE = "发表页面";
|
|
||||||
|
|
||||||
String REMOVE_POST = "删除文章";
|
|
||||||
|
|
||||||
String CHANGE_THEME = "更换主题";
|
|
||||||
|
|
||||||
String UPLOAD_THEME = "上传主题";
|
|
||||||
|
|
||||||
String UPLOAD_FILE = "上传附件";
|
|
||||||
|
|
||||||
String REMOVE_FILE = "移除附件";
|
|
||||||
}
|
|
|
@ -17,6 +17,7 @@ public class QiNiuPutSet {
|
||||||
* 文件hash值
|
* 文件hash值
|
||||||
*/
|
*/
|
||||||
public String hash;
|
public String hash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件名
|
* 文件名
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,6 +3,7 @@ package run.halo.app.repository;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import run.halo.app.model.entity.PostCategory;
|
import run.halo.app.model.entity.PostCategory;
|
||||||
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.model.projection.CategoryPostCountProjection;
|
import run.halo.app.model.projection.CategoryPostCountProjection;
|
||||||
import run.halo.app.repository.base.BaseRepository;
|
import run.halo.app.repository.base.BaseRepository;
|
||||||
|
|
||||||
|
@ -14,6 +15,8 @@ import java.util.Set;
|
||||||
* Post category repository.
|
* Post category repository.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @author ryanwang
|
||||||
|
* @date 2019-03-19
|
||||||
*/
|
*/
|
||||||
public interface PostCategoryRepository extends BaseRepository<PostCategory, Integer> {
|
public interface PostCategoryRepository extends BaseRepository<PostCategory, Integer> {
|
||||||
|
|
||||||
|
@ -37,6 +40,17 @@ public interface PostCategoryRepository extends BaseRepository<PostCategory, Int
|
||||||
@Query("select postCategory.postId from PostCategory postCategory where postCategory.categoryId = ?1")
|
@Query("select postCategory.postId from PostCategory postCategory where postCategory.categoryId = ?1")
|
||||||
Set<Integer> findAllPostIdsByCategoryId(@NonNull Integer categoryId);
|
Set<Integer> findAllPostIdsByCategoryId(@NonNull Integer categoryId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all post ids by category id and post status.
|
||||||
|
*
|
||||||
|
* @param categoryId category id must not be null
|
||||||
|
* @param status post status must not be null
|
||||||
|
* @return a set of post id
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
@Query("select postCategory.postId from PostCategory postCategory, Post post where postCategory.categoryId = ?1 and post.id = postCategory.postId and post.status = ?2")
|
||||||
|
Set<Integer> findAllPostIdsByCategoryId(@NonNull Integer categoryId, @NonNull PostStatus status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds all post categories by post id in.
|
* Finds all post categories by post id in.
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,6 +3,7 @@ package run.halo.app.repository;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import run.halo.app.model.entity.PostTag;
|
import run.halo.app.model.entity.PostTag;
|
||||||
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.model.projection.TagPostPostCountProjection;
|
import run.halo.app.model.projection.TagPostPostCountProjection;
|
||||||
import run.halo.app.repository.base.BaseRepository;
|
import run.halo.app.repository.base.BaseRepository;
|
||||||
|
|
||||||
|
@ -14,6 +15,8 @@ import java.util.Set;
|
||||||
* Post tag repository.
|
* Post tag repository.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @author ryanwang
|
||||||
|
* @date 2019-03-19
|
||||||
*/
|
*/
|
||||||
public interface PostTagRepository extends BaseRepository<PostTag, Integer> {
|
public interface PostTagRepository extends BaseRepository<PostTag, Integer> {
|
||||||
|
|
||||||
|
@ -55,6 +58,17 @@ public interface PostTagRepository extends BaseRepository<PostTag, Integer> {
|
||||||
@NonNull
|
@NonNull
|
||||||
Set<Integer> findAllPostIdsByTagId(@NonNull Integer tagId);
|
Set<Integer> findAllPostIdsByTagId(@NonNull Integer tagId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all post id by tag id and post status.
|
||||||
|
*
|
||||||
|
* @param tagId tag id must not be null
|
||||||
|
* @param status post status
|
||||||
|
* @return a set of post id
|
||||||
|
*/
|
||||||
|
@Query("select postTag.postId from PostTag postTag,Post post where postTag.tagId = ?1 and post.id = postTag.postId and post.status = ?2")
|
||||||
|
@NonNull
|
||||||
|
Set<Integer> findAllPostIdsByTagId(@NonNull Integer tagId, @NonNull PostStatus status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds all tags by post id in.
|
* Finds all tags by post id in.
|
||||||
*
|
*
|
||||||
|
|
|
@ -8,8 +8,8 @@ import org.springframework.util.Assert;
|
||||||
import run.halo.app.config.properties.HaloProperties;
|
import run.halo.app.config.properties.HaloProperties;
|
||||||
import run.halo.app.exception.AuthenticationException;
|
import run.halo.app.exception.AuthenticationException;
|
||||||
import run.halo.app.exception.ForbiddenException;
|
import run.halo.app.exception.ForbiddenException;
|
||||||
|
import run.halo.app.model.properties.ApiProperties;
|
||||||
import run.halo.app.model.properties.CommentProperties;
|
import run.halo.app.model.properties.CommentProperties;
|
||||||
import run.halo.app.model.properties.OtherProperties;
|
|
||||||
import run.halo.app.service.OptionService;
|
import run.halo.app.service.OptionService;
|
||||||
|
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
|
@ -48,7 +48,7 @@ public class ApiAuthenticationFilter extends AbstractAuthenticationFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get api_enable from option
|
// Get api_enable from option
|
||||||
Boolean apiEnabled = optionService.getByPropertyOrDefault(OtherProperties.API_ENABLED, Boolean.class, false);
|
Boolean apiEnabled = optionService.getByPropertyOrDefault(ApiProperties.API_ENABLED, Boolean.class, false);
|
||||||
|
|
||||||
if (!apiEnabled) {
|
if (!apiEnabled) {
|
||||||
getFailureHandler().onFailure(request, response, new ForbiddenException("API has been disabled by blogger currently"));
|
getFailureHandler().onFailure(request, response, new ForbiddenException("API has been disabled by blogger currently"));
|
||||||
|
@ -65,7 +65,7 @@ public class ApiAuthenticationFilter extends AbstractAuthenticationFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get access key from option
|
// Get access key from option
|
||||||
Optional<String> optionalAccessKey = optionService.getByProperty(OtherProperties.API_ACCESS_KEY, String.class);
|
Optional<String> optionalAccessKey = optionService.getByProperty(ApiProperties.API_ACCESS_KEY, String.class);
|
||||||
|
|
||||||
if (!optionalAccessKey.isPresent()) {
|
if (!optionalAccessKey.isPresent()) {
|
||||||
// If the access key is not set
|
// If the access key is not set
|
||||||
|
|
|
@ -7,11 +7,11 @@ import run.halo.app.model.params.LoginParam;
|
||||||
import run.halo.app.security.token.AuthToken;
|
import run.halo.app.security.token.AuthToken;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Admin service.
|
* Admin service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date 19-4-29
|
* @date 2019-04-29
|
||||||
*/
|
*/
|
||||||
public interface AdminService {
|
public interface AdminService {
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ public interface AdminService {
|
||||||
|
|
||||||
String REFRESH_TOKEN_CACHE_PREFIX = "halo.admin.refresh_token.";
|
String REFRESH_TOKEN_CACHE_PREFIX = "halo.admin.refresh_token.";
|
||||||
|
|
||||||
|
String LOGS_PATH = "logs/spring.log";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticates.
|
* Authenticates.
|
||||||
*
|
*
|
||||||
|
@ -69,4 +71,10 @@ public interface AdminService {
|
||||||
* Updates halo admin assets.
|
* Updates halo admin assets.
|
||||||
*/
|
*/
|
||||||
void updateAdminAssets();
|
void updateAdminAssets();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get spring logs.
|
||||||
|
* @return recently logs.
|
||||||
|
*/
|
||||||
|
String getSpringLogs();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import java.util.List;
|
||||||
* Attachment service.
|
* Attachment service.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @date : 2019-03-14
|
||||||
*/
|
*/
|
||||||
public interface AttachmentService extends CrudService<Attachment, Integer> {
|
public interface AttachmentService extends CrudService<Attachment, Integer> {
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.io.IOException;
|
||||||
* Backup service interface.
|
* Backup service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-4-26
|
* @date 2019-04-26
|
||||||
*/
|
*/
|
||||||
public interface BackupService {
|
public interface BackupService {
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,10 @@ import java.util.List;
|
||||||
* Category service.
|
* Category service.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @author ryanwang
|
||||||
|
* @date : 2019-03-14
|
||||||
*/
|
*/
|
||||||
|
@Transactional(readOnly = true)
|
||||||
public interface CategoryService extends CrudService<Category, Integer> {
|
public interface CategoryService extends CrudService<Category, Integer> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,6 +39,15 @@ public interface CategoryService extends CrudService<Category, Integer> {
|
||||||
@NonNull
|
@NonNull
|
||||||
Category getBySlugName(@NonNull String slugName);
|
Category getBySlugName(@NonNull String slugName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get category by slug name
|
||||||
|
*
|
||||||
|
* @param slugName slug name
|
||||||
|
* @return Category
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
Category getBySlugNameOfNonNull(String slugName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Category by name.
|
* Get Category by name.
|
||||||
*
|
*
|
||||||
|
|
|
@ -13,7 +13,7 @@ import java.util.List;
|
||||||
* Journal comment service interface.
|
* Journal comment service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-4-25
|
* @date 2019-04-25
|
||||||
*/
|
*/
|
||||||
public interface JournalCommentService extends BaseCommentService<JournalComment> {
|
public interface JournalCommentService extends BaseCommentService<JournalComment> {
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ import java.util.List;
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date 19-4-24
|
* @date 2019-04-24
|
||||||
*/
|
*/
|
||||||
public interface JournalService extends CrudService<Journal, Integer> {
|
public interface JournalService extends CrudService<Journal, Integer> {
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,10 @@ import run.halo.app.service.base.CrudService;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link service.
|
* Link service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
public interface LinkService extends CrudService<Link, Integer> {
|
public interface LinkService extends CrudService<Link, Integer> {
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,10 @@ import run.halo.app.model.entity.Log;
|
||||||
import run.halo.app.service.base.CrudService;
|
import run.halo.app.service.base.CrudService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log service.
|
* Log service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
public interface LogService extends CrudService<Log, Long> {
|
public interface LogService extends CrudService<Log, Long> {
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ package run.halo.app.service;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mail server
|
* Mail service interface.
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-03-17
|
* @date 2019-03-17
|
||||||
*/
|
*/
|
||||||
public interface MailService {
|
public interface MailService {
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,11 @@ import run.halo.app.service.base.CrudService;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Menu service.
|
* Menu service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
public interface MenuService extends CrudService<Menu, Integer> {
|
public interface MenuService extends CrudService<Menu, Integer> {
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,10 @@ import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Option service.
|
* Option service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
public interface OptionService extends CrudService<Option, Integer> {
|
public interface OptionService extends CrudService<Option, Integer> {
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,10 @@ import run.halo.app.service.base.CrudService;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Photo service.
|
* Photo service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
public interface PhotoService extends CrudService<Photo, Integer> {
|
public interface PhotoService extends CrudService<Photo, Integer> {
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import run.halo.app.model.dto.CategoryWithPostCountDTO;
|
||||||
import run.halo.app.model.entity.Category;
|
import run.halo.app.model.entity.Category;
|
||||||
import run.halo.app.model.entity.Post;
|
import run.halo.app.model.entity.Post;
|
||||||
import run.halo.app.model.entity.PostCategory;
|
import run.halo.app.model.entity.PostCategory;
|
||||||
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.service.base.CrudService;
|
import run.halo.app.service.base.CrudService;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -21,7 +22,8 @@ import java.util.Set;
|
||||||
* Post category service interface.
|
* Post category service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 3/19/19
|
* @author ryanwang
|
||||||
|
* @date 2019-03-19
|
||||||
*/
|
*/
|
||||||
public interface PostCategoryService extends CrudService<PostCategory, Integer> {
|
public interface PostCategoryService extends CrudService<PostCategory, Integer> {
|
||||||
|
|
||||||
|
@ -52,6 +54,16 @@ public interface PostCategoryService extends CrudService<PostCategory, Integer>
|
||||||
@NonNull
|
@NonNull
|
||||||
List<Post> listPostBy(@NonNull Integer categoryId);
|
List<Post> listPostBy(@NonNull Integer categoryId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists post by category id and post status.
|
||||||
|
*
|
||||||
|
* @param categoryId category id must not be null
|
||||||
|
* @param status post status
|
||||||
|
* @return a list of post
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
List<Post> listPostBy(@NonNull Integer categoryId, @NonNull PostStatus status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pages post by category slug name.
|
* Pages post by category slug name.
|
||||||
*
|
*
|
||||||
|
@ -62,6 +74,17 @@ public interface PostCategoryService extends CrudService<PostCategory, Integer>
|
||||||
@NonNull
|
@NonNull
|
||||||
Page<Post> pagePostBy(@NonNull Integer categoryId, Pageable pageable);
|
Page<Post> pagePostBy(@NonNull Integer categoryId, Pageable pageable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pages post by category slug name and post status.
|
||||||
|
*
|
||||||
|
* @param categoryId category id must not be null
|
||||||
|
* @param status post status
|
||||||
|
* @param pageable pageable
|
||||||
|
* @return page of post
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
Page<Post> pagePostBy(@NonNull Integer categoryId, @NonNull PostStatus status, Pageable pageable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges or creates post categories by post id and category id set if absent.
|
* Merges or creates post categories by post id and category id set if absent.
|
||||||
*
|
*
|
||||||
|
|
|
@ -12,9 +12,10 @@ import run.halo.app.service.base.BaseCommentService;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PostComment service.
|
* Post comment service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
public interface PostCommentService extends BaseCommentService<PostComment> {
|
public interface PostCommentService extends BaseCommentService<PostComment> {
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,11 @@ import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post service.
|
* Post service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
public interface PostService extends BasePostService<Post> {
|
public interface PostService extends BasePostService<Post> {
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import run.halo.app.model.dto.TagWithPostCountDTO;
|
||||||
import run.halo.app.model.entity.Post;
|
import run.halo.app.model.entity.Post;
|
||||||
import run.halo.app.model.entity.PostTag;
|
import run.halo.app.model.entity.PostTag;
|
||||||
import run.halo.app.model.entity.Tag;
|
import run.halo.app.model.entity.Tag;
|
||||||
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.service.base.CrudService;
|
import run.halo.app.service.base.CrudService;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -21,7 +22,8 @@ import java.util.Set;
|
||||||
* Post tag service interface.
|
* Post tag service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 3/19/19
|
* @author ryanwang
|
||||||
|
* @date 2019-03-19
|
||||||
*/
|
*/
|
||||||
public interface PostTagService extends CrudService<PostTag, Integer> {
|
public interface PostTagService extends CrudService<PostTag, Integer> {
|
||||||
|
|
||||||
|
@ -61,6 +63,16 @@ public interface PostTagService extends CrudService<PostTag, Integer> {
|
||||||
@NonNull
|
@NonNull
|
||||||
List<Post> listPostsBy(@NonNull Integer tagId);
|
List<Post> listPostsBy(@NonNull Integer tagId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists posts by tag id and post status.
|
||||||
|
*
|
||||||
|
* @param tagId tag id must not be null
|
||||||
|
* @param status post status
|
||||||
|
* @return a list of post
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
List<Post> listPostsBy(@NonNull Integer tagId, @NonNull PostStatus status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pages posts by tag id.
|
* Pages posts by tag id.
|
||||||
*
|
*
|
||||||
|
@ -70,6 +82,16 @@ public interface PostTagService extends CrudService<PostTag, Integer> {
|
||||||
*/
|
*/
|
||||||
Page<Post> pagePostsBy(@NonNull Integer tagId, Pageable pageable);
|
Page<Post> pagePostsBy(@NonNull Integer tagId, Pageable pageable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pages posts by tag id and post status.
|
||||||
|
*
|
||||||
|
* @param tagId must not be null
|
||||||
|
* @param status post status
|
||||||
|
* @param pageable must not be null
|
||||||
|
* @return a page of post
|
||||||
|
*/
|
||||||
|
Page<Post> pagePostsBy(@NonNull Integer tagId, @NonNull PostStatus status, Pageable pageable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges or creates post tags by post id and tag id set if absent.
|
* Merges or creates post tags by post id and tag id set if absent.
|
||||||
*
|
*
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||||
* Recovery service interface.
|
* Recovery service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-4-26
|
* @date 2019-04-26
|
||||||
*/
|
*/
|
||||||
public interface RecoveryService {
|
public interface RecoveryService {
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import java.util.List;
|
||||||
* Sheet comment service interface.
|
* Sheet comment service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-4-24
|
* @date 2019-04-24
|
||||||
*/
|
*/
|
||||||
public interface SheetCommentService extends BaseCommentService<SheetComment> {
|
public interface SheetCommentService extends BaseCommentService<SheetComment> {
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import java.util.List;
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date 19-4-24
|
* @date 2019-04-24
|
||||||
*/
|
*/
|
||||||
public interface SheetService extends BasePostService<Sheet> {
|
public interface SheetService extends BasePostService<Sheet> {
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,12 @@ import run.halo.app.service.base.CrudService;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tag service.
|
* Tag service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @author ryanwang
|
||||||
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
public interface TagService extends CrudService<Tag, Integer> {
|
public interface TagService extends CrudService<Tag, Integer> {
|
||||||
|
|
||||||
|
@ -25,6 +26,15 @@ public interface TagService extends CrudService<Tag, Integer> {
|
||||||
@NonNull
|
@NonNull
|
||||||
Tag getBySlugNameOfNonNull(@NonNull String slugName);
|
Tag getBySlugNameOfNonNull(@NonNull String slugName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get tag by slug name
|
||||||
|
*
|
||||||
|
* @param slugName slug name
|
||||||
|
* @return tag
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
Tag getBySlugName(@NonNull String slugName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get tag by tag name.
|
* Get tag by tag name.
|
||||||
*
|
*
|
||||||
|
|
|
@ -14,8 +14,10 @@ import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Theme service interface.
|
||||||
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019/3/26
|
* @date 2019-03-26
|
||||||
*/
|
*/
|
||||||
public interface ThemeService {
|
public interface ThemeService {
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import java.util.Map;
|
||||||
* Theme setting service interface.
|
* Theme setting service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 4/8/19
|
* @date 2019-04-08
|
||||||
*/
|
*/
|
||||||
public interface ThemeSettingService {
|
public interface ThemeSettingService {
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.util.List;
|
||||||
* Trace service interface.
|
* Trace service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-6-18
|
* @date 2019-06-18
|
||||||
*/
|
*/
|
||||||
public interface TraceService {
|
public interface TraceService {
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,10 @@ import run.halo.app.service.base.CrudService;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User service.
|
* User service interface.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
public interface UserService extends CrudService<User, Integer> {
|
public interface UserService extends CrudService<User, Integer> {
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package run.halo.app.service.impl;
|
package run.halo.app.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.file.FileReader;
|
||||||
import cn.hutool.core.lang.Validator;
|
import cn.hutool.core.lang.Validator;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
@ -10,6 +12,7 @@ import org.springframework.util.Assert;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
import run.halo.app.cache.StringCacheStore;
|
import run.halo.app.cache.StringCacheStore;
|
||||||
import run.halo.app.config.properties.HaloProperties;
|
import run.halo.app.config.properties.HaloProperties;
|
||||||
|
import run.halo.app.event.logger.LogEvent;
|
||||||
import run.halo.app.exception.BadRequestException;
|
import run.halo.app.exception.BadRequestException;
|
||||||
import run.halo.app.exception.NotFoundException;
|
import run.halo.app.exception.NotFoundException;
|
||||||
import run.halo.app.exception.ServiceException;
|
import run.halo.app.exception.ServiceException;
|
||||||
|
@ -17,6 +20,7 @@ import run.halo.app.model.dto.EnvironmentDTO;
|
||||||
import run.halo.app.model.dto.StatisticDTO;
|
import run.halo.app.model.dto.StatisticDTO;
|
||||||
import run.halo.app.model.entity.User;
|
import run.halo.app.model.entity.User;
|
||||||
import run.halo.app.model.enums.CommentStatus;
|
import run.halo.app.model.enums.CommentStatus;
|
||||||
|
import run.halo.app.model.enums.LogType;
|
||||||
import run.halo.app.model.enums.Mode;
|
import run.halo.app.model.enums.Mode;
|
||||||
import run.halo.app.model.enums.PostStatus;
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.model.params.LoginParam;
|
import run.halo.app.model.params.LoginParam;
|
||||||
|
@ -29,6 +33,7 @@ import run.halo.app.service.*;
|
||||||
import run.halo.app.utils.FileUtils;
|
import run.halo.app.utils.FileUtils;
|
||||||
import run.halo.app.utils.HaloUtils;
|
import run.halo.app.utils.HaloUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
import java.lang.management.RuntimeMXBean;
|
import java.lang.management.RuntimeMXBean;
|
||||||
|
@ -46,7 +51,7 @@ import static run.halo.app.model.support.HaloConst.*;
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date 19-4-29
|
* @date 2019-04-29
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@ -76,6 +81,8 @@ public class AdminServiceImpl implements AdminService {
|
||||||
|
|
||||||
private final HaloProperties haloProperties;
|
private final HaloProperties haloProperties;
|
||||||
|
|
||||||
|
private final ApplicationEventPublisher eventPublisher;
|
||||||
|
|
||||||
private final String driverClassName;
|
private final String driverClassName;
|
||||||
|
|
||||||
private final String mode;
|
private final String mode;
|
||||||
|
@ -92,6 +99,7 @@ public class AdminServiceImpl implements AdminService {
|
||||||
StringCacheStore cacheStore,
|
StringCacheStore cacheStore,
|
||||||
RestTemplate restTemplate,
|
RestTemplate restTemplate,
|
||||||
HaloProperties haloProperties,
|
HaloProperties haloProperties,
|
||||||
|
ApplicationEventPublisher eventPublisher,
|
||||||
@Value("${spring.datasource.driver-class-name}") String driverClassName,
|
@Value("${spring.datasource.driver-class-name}") String driverClassName,
|
||||||
@Value("${spring.profiles.active:prod}") String mode) {
|
@Value("${spring.profiles.active:prod}") String mode) {
|
||||||
this.postService = postService;
|
this.postService = postService;
|
||||||
|
@ -106,6 +114,7 @@ public class AdminServiceImpl implements AdminService {
|
||||||
this.cacheStore = cacheStore;
|
this.cacheStore = cacheStore;
|
||||||
this.restTemplate = restTemplate;
|
this.restTemplate = restTemplate;
|
||||||
this.haloProperties = haloProperties;
|
this.haloProperties = haloProperties;
|
||||||
|
this.eventPublisher = eventPublisher;
|
||||||
this.driverClassName = driverClassName;
|
this.driverClassName = driverClassName;
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
@ -126,6 +135,8 @@ public class AdminServiceImpl implements AdminService {
|
||||||
userService.getByEmailOfNonNull(username) : userService.getByUsernameOfNonNull(username);
|
userService.getByEmailOfNonNull(username) : userService.getByUsernameOfNonNull(username);
|
||||||
} catch (NotFoundException e) {
|
} catch (NotFoundException e) {
|
||||||
log.error("Failed to find user by name: " + username, e);
|
log.error("Failed to find user by name: " + username, e);
|
||||||
|
eventPublisher.publishEvent(new LogEvent(this, loginParam.getUsername(), LogType.LOGIN_FAILED, loginParam.getUsername()));
|
||||||
|
|
||||||
throw new BadRequestException(mismatchTip);
|
throw new BadRequestException(mismatchTip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +144,8 @@ public class AdminServiceImpl implements AdminService {
|
||||||
|
|
||||||
if (!userService.passwordMatch(user, loginParam.getPassword())) {
|
if (!userService.passwordMatch(user, loginParam.getPassword())) {
|
||||||
// If the password is mismatch
|
// If the password is mismatch
|
||||||
|
eventPublisher.publishEvent(new LogEvent(this, loginParam.getUsername(), LogType.LOGIN_FAILED, loginParam.getUsername()));
|
||||||
|
|
||||||
throw new BadRequestException(mismatchTip);
|
throw new BadRequestException(mismatchTip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +154,9 @@ public class AdminServiceImpl implements AdminService {
|
||||||
throw new BadRequestException("您已登录,请不要重复登录");
|
throw new BadRequestException("您已登录,请不要重复登录");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log it then login successful
|
||||||
|
eventPublisher.publishEvent(new LogEvent(this, user.getUsername(), LogType.LOGGED_IN, user.getNickname()));
|
||||||
|
|
||||||
// Generate new token
|
// Generate new token
|
||||||
return buildAuthToken(user);
|
return buildAuthToken(user);
|
||||||
}
|
}
|
||||||
|
@ -170,6 +186,8 @@ public class AdminServiceImpl implements AdminService {
|
||||||
cacheStore.delete(SecurityUtils.buildRefreshTokenKey(user));
|
cacheStore.delete(SecurityUtils.buildRefreshTokenKey(user));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
eventPublisher.publishEvent(new LogEvent(this, user.getUsername(), LogType.LOGGED_OUT, user.getNickname()));
|
||||||
|
|
||||||
log.info("You have been logged out, looking forward to your next visit!");
|
log.info("You have been logged out, looking forward to your next visit!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,4 +375,14 @@ public class AdminServiceImpl implements AdminService {
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSpringLogs() {
|
||||||
|
File file = new File(haloProperties.getWorkDir(), LOGS_PATH);
|
||||||
|
if (!file.exists()) {
|
||||||
|
return "暂无日志";
|
||||||
|
}
|
||||||
|
FileReader reader = new FileReader(file);
|
||||||
|
return reader.readString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.util.Objects;
|
||||||
* AttachmentService implementation
|
* AttachmentService implementation
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
|
* @author johnniang
|
||||||
* @date : 2019-03-14
|
* @date : 2019-03-14
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|
|
@ -14,7 +14,7 @@ import java.nio.charset.StandardCharsets;
|
||||||
* Backup service implementation.
|
* Backup service implementation.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-4-26
|
* @date 2019-04-26
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class BackupServiceImpl implements BackupService {
|
public class BackupServiceImpl implements BackupService {
|
||||||
|
|
|
@ -51,7 +51,7 @@ import java.util.stream.Collectors;
|
||||||
* Base comment service implementation.
|
* Base comment service implementation.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-4-24
|
* @date 2019-04-24
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment> extends AbstractCrudService<COMMENT, Long> implements BaseCommentService<COMMENT> {
|
public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment> extends AbstractCrudService<COMMENT, Long> implements BaseCommentService<COMMENT> {
|
||||||
|
|
|
@ -7,7 +7,6 @@ import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import run.halo.app.exception.AlreadyExistsException;
|
import run.halo.app.exception.AlreadyExistsException;
|
||||||
|
@ -24,6 +23,7 @@ import run.halo.app.service.OptionService;
|
||||||
import run.halo.app.service.base.AbstractCrudService;
|
import run.halo.app.service.base.AbstractCrudService;
|
||||||
import run.halo.app.service.base.BasePostService;
|
import run.halo.app.service.base.BasePostService;
|
||||||
import run.halo.app.utils.DateUtils;
|
import run.halo.app.utils.DateUtils;
|
||||||
|
import run.halo.app.utils.HaloUtils;
|
||||||
import run.halo.app.utils.MarkdownUtils;
|
import run.halo.app.utils.MarkdownUtils;
|
||||||
import run.halo.app.utils.ServiceUtils;
|
import run.halo.app.utils.ServiceUtils;
|
||||||
|
|
||||||
|
@ -40,7 +40,8 @@ import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||||
* Base post service implementation.
|
* Base post service implementation.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-4-24
|
* @author ryanwang
|
||||||
|
* @date 2019-04-24
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public abstract class BasePostServiceImpl<POST extends BasePost> extends AbstractCrudService<POST, Integer> implements BasePostService<POST> {
|
public abstract class BasePostServiceImpl<POST extends BasePost> extends AbstractCrudService<POST, Integer> implements BasePostService<POST> {
|
||||||
|
@ -212,7 +213,7 @@ public abstract class BasePostServiceImpl<POST extends BasePost> extends Abstrac
|
||||||
Assert.notNull(post, "Post must not be null");
|
Assert.notNull(post, "Post must not be null");
|
||||||
|
|
||||||
// Render content
|
// Render content
|
||||||
post.setFormatContent(MarkdownUtils.renderMarkdown(post.getOriginalContent()));
|
post.setFormatContent(MarkdownUtils.renderHtml(post.getOriginalContent()));
|
||||||
|
|
||||||
// Create or update post
|
// Create or update post
|
||||||
if (ServiceUtils.isEmptyId(post.getId())) {
|
if (ServiceUtils.isEmptyId(post.getId())) {
|
||||||
|
@ -275,7 +276,7 @@ public abstract class BasePostServiceImpl<POST extends BasePost> extends Abstrac
|
||||||
|
|
||||||
// Set summary
|
// Set summary
|
||||||
if (StringUtils.isBlank(basePostSimpleDTO.getSummary())) {
|
if (StringUtils.isBlank(basePostSimpleDTO.getSummary())) {
|
||||||
basePostSimpleDTO.setSummary(convertToSummary(post.getOriginalContent()));
|
basePostSimpleDTO.setSummary(generateSummary(post.getFormatContent()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return basePostSimpleDTO;
|
return basePostSimpleDTO;
|
||||||
|
@ -347,15 +348,14 @@ public abstract class BasePostServiceImpl<POST extends BasePost> extends Abstrac
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
protected String convertToSummary(@Nullable String markdownContent) {
|
protected String generateSummary(@NonNull String htmlContent) {
|
||||||
// Render text content
|
Assert.notNull(htmlContent, "html content must not be null");
|
||||||
String textContent = MarkdownUtils.renderText(markdownContent);
|
|
||||||
|
String text = HaloUtils.cleanHtmlTag(htmlContent);
|
||||||
|
|
||||||
// Get summary length
|
// Get summary length
|
||||||
Integer summaryLength = optionService.getByPropertyOrDefault(PostProperties.SUMMARY_LENGTH, Integer.class, 150);
|
Integer summaryLength = optionService.getByPropertyOrDefault(PostProperties.SUMMARY_LENGTH, Integer.class, 150);
|
||||||
|
|
||||||
// Set summary
|
return StringUtils.substring(text, 0, summaryLength);
|
||||||
return StringUtils.substring(textContent, 0, summaryLength);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import run.halo.app.exception.AlreadyExistsException;
|
import run.halo.app.exception.AlreadyExistsException;
|
||||||
|
@ -24,9 +25,10 @@ import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CategoryService implementation class
|
* CategoryService implementation class.
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
|
* @author johnniang
|
||||||
* @date : 2019-03-14
|
* @date : 2019-03-14
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -45,6 +47,7 @@ public class CategoryServiceImpl extends AbstractCrudService<Category, Integer>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public Category create(Category category) {
|
public Category create(Category category) {
|
||||||
Assert.notNull(category, "Category to create must not be null");
|
Assert.notNull(category, "Category to create must not be null");
|
||||||
|
|
||||||
|
@ -144,15 +147,14 @@ public class CategoryServiceImpl extends AbstractCrudService<Category, Integer>
|
||||||
return topCategory;
|
return topCategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get category by slug name
|
|
||||||
*
|
|
||||||
* @param slugName slug name
|
|
||||||
* @return Category
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Category getBySlugName(String slugName) {
|
public Category getBySlugName(String slugName) {
|
||||||
return categoryRepository.getBySlugName(slugName).orElseThrow(() -> new NotFoundException("该分类已存在").setErrorData(slugName));
|
return categoryRepository.getBySlugName(slugName).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Category getBySlugNameOfNonNull(String slugName) {
|
||||||
|
return categoryRepository.getBySlugName(slugName).orElseThrow(() -> new NotFoundException("该分类不存在").setErrorData(slugName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -161,6 +163,7 @@ public class CategoryServiceImpl extends AbstractCrudService<Category, Integer>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public void removeCategoryAndPostCategoryBy(Integer categoryId) {
|
public void removeCategoryAndPostCategoryBy(Integer categoryId) {
|
||||||
// Remove category
|
// Remove category
|
||||||
removeById(categoryId);
|
removeById(categoryId);
|
||||||
|
|
|
@ -28,7 +28,7 @@ import java.util.stream.Collectors;
|
||||||
* Journal comment service implementation.
|
* Journal comment service implementation.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-4-25
|
* @date 2019-04-25
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class JournalCommentServiceImpl extends BaseCommentServiceImpl<JournalComment> implements JournalCommentService {
|
public class JournalCommentServiceImpl extends BaseCommentServiceImpl<JournalComment> implements JournalCommentService {
|
||||||
|
|
|
@ -29,7 +29,7 @@ import java.util.stream.Collectors;
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date 19-4-24
|
* @date 2019-04-24
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class JournalServiceImpl extends AbstractCrudService<Journal, Integer> implements JournalService {
|
public class JournalServiceImpl extends AbstractCrudService<Journal, Integer> implements JournalService {
|
||||||
|
|
|
@ -24,7 +24,7 @@ import java.util.stream.Collectors;
|
||||||
* LinkService implementation class
|
* LinkService implementation class
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-03-14
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class LinkServiceImpl extends AbstractCrudService<Link, Integer> implements LinkService {
|
public class LinkServiceImpl extends AbstractCrudService<Link, Integer> implements LinkService {
|
||||||
|
@ -36,12 +36,6 @@ public class LinkServiceImpl extends AbstractCrudService<Link, Integer> implemen
|
||||||
this.linkRepository = linkRepository;
|
this.linkRepository = linkRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* List link dtos.
|
|
||||||
*
|
|
||||||
* @param sort sort
|
|
||||||
* @return all links
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public List<LinkDTO> listDtos(Sort sort) {
|
public List<LinkDTO> listDtos(Sort sort) {
|
||||||
Assert.notNull(sort, "Sort info must not be null");
|
Assert.notNull(sort, "Sort info must not be null");
|
||||||
|
|
|
@ -15,7 +15,7 @@ import run.halo.app.service.base.AbstractCrudService;
|
||||||
* LogService implementation class
|
* LogService implementation class
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-03-14
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class LogServiceImpl extends AbstractCrudService<Log, Long> implements LogService {
|
public class LogServiceImpl extends AbstractCrudService<Log, Long> implements LogService {
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.util.Properties;
|
||||||
* Mail service implementation.
|
* Mail service implementation.
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-03-17
|
* @date 2019-03-17
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@ -37,13 +37,6 @@ public class MailServiceImpl implements MailService {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a simple email
|
|
||||||
*
|
|
||||||
* @param to recipient
|
|
||||||
* @param subject subject
|
|
||||||
* @param content content
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMail(String to, String subject, String content) {
|
public void sendMail(String to, String subject, String content) {
|
||||||
loadConfig();
|
loadConfig();
|
||||||
|
@ -63,14 +56,6 @@ public class MailServiceImpl implements MailService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends template mail
|
|
||||||
*
|
|
||||||
* @param to recipient
|
|
||||||
* @param subject subject
|
|
||||||
* @param content content
|
|
||||||
* @param templateName template name
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void sendTemplateMail(String to, String subject, Map<String, Object> content, String templateName) {
|
public void sendTemplateMail(String to, String subject, Map<String, Object> content, String templateName) {
|
||||||
loadConfig();
|
loadConfig();
|
||||||
|
@ -93,15 +78,6 @@ public class MailServiceImpl implements MailService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends mail with attachments
|
|
||||||
*
|
|
||||||
* @param to recipient
|
|
||||||
* @param subject subject
|
|
||||||
* @param content content
|
|
||||||
* @param templateName template name
|
|
||||||
* @param attachFilename attachment path
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void sendAttachMail(String to, String subject, Map<String, Object> content, String templateName, String attachFilename) {
|
public void sendAttachMail(String to, String subject, Map<String, Object> content, String templateName, String attachFilename) {
|
||||||
loadConfig();
|
loadConfig();
|
||||||
|
|
|
@ -21,10 +21,10 @@ import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MenuService implementation class
|
* MenuService implementation class.
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-03-14
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class MenuServiceImpl extends AbstractCrudService<Menu, Integer> implements MenuService {
|
public class MenuServiceImpl extends AbstractCrudService<Menu, Integer> implements MenuService {
|
||||||
|
@ -51,12 +51,6 @@ public class MenuServiceImpl extends AbstractCrudService<Menu, Integer> implemen
|
||||||
return create(menuParam.convertTo());
|
return create(menuParam.convertTo());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Lists as menu tree.
|
|
||||||
*
|
|
||||||
* @param sort sort info must not be null
|
|
||||||
* @return a menu tree
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public List<MenuVO> listAsTree(Sort sort) {
|
public List<MenuVO> listAsTree(Sort sort) {
|
||||||
Assert.notNull(sort, "Sort info must not be null");
|
Assert.notNull(sort, "Sort info must not be null");
|
||||||
|
|
|
@ -30,7 +30,7 @@ import java.util.*;
|
||||||
* OptionService implementation class
|
* OptionService implementation class
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-03-14
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
|
|
@ -29,7 +29,7 @@ import java.util.stream.Collectors;
|
||||||
* PhotoService implementation class
|
* PhotoService implementation class
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-03-14
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class PhotoServiceImpl extends AbstractCrudService<Photo, Integer> implements PhotoService {
|
public class PhotoServiceImpl extends AbstractCrudService<Photo, Integer> implements PhotoService {
|
||||||
|
@ -41,12 +41,6 @@ public class PhotoServiceImpl extends AbstractCrudService<Photo, Integer> implem
|
||||||
this.photoRepository = photoRepository;
|
this.photoRepository = photoRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* List photo dtos.
|
|
||||||
*
|
|
||||||
* @param sort sort
|
|
||||||
* @return all photos
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public List<PhotoDTO> listDtos(Sort sort) {
|
public List<PhotoDTO> listDtos(Sort sort) {
|
||||||
Assert.notNull(sort, "Sort info must not be null");
|
Assert.notNull(sort, "Sort info must not be null");
|
||||||
|
@ -54,12 +48,6 @@ public class PhotoServiceImpl extends AbstractCrudService<Photo, Integer> implem
|
||||||
return listAll(sort).stream().map(photo -> (PhotoDTO) new PhotoDTO().convertFrom(photo)).collect(Collectors.toList());
|
return listAll(sort).stream().map(photo -> (PhotoDTO) new PhotoDTO().convertFrom(photo)).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Lists photo team vos.
|
|
||||||
*
|
|
||||||
* @param sort must not be null
|
|
||||||
* @return a list of photo team vo
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public List<PhotoTeamVO> listTeamVos(Sort sort) {
|
public List<PhotoTeamVO> listTeamVos(Sort sort) {
|
||||||
Assert.notNull(sort, "Sort info must not be null");
|
Assert.notNull(sort, "Sort info must not be null");
|
||||||
|
@ -88,13 +76,6 @@ public class PhotoServiceImpl extends AbstractCrudService<Photo, Integer> implem
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* List photos by team.
|
|
||||||
*
|
|
||||||
* @param team team
|
|
||||||
* @param sort sort
|
|
||||||
* @return list of photos
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public List<PhotoDTO> listByTeam(String team, Sort sort) {
|
public List<PhotoDTO> listByTeam(String team, Sort sort) {
|
||||||
List<Photo> photos = photoRepository.findByTeam(team, sort);
|
List<Photo> photos = photoRepository.findByTeam(team, sort);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import run.halo.app.model.dto.CategoryWithPostCountDTO;
|
||||||
import run.halo.app.model.entity.Category;
|
import run.halo.app.model.entity.Category;
|
||||||
import run.halo.app.model.entity.Post;
|
import run.halo.app.model.entity.Post;
|
||||||
import run.halo.app.model.entity.PostCategory;
|
import run.halo.app.model.entity.PostCategory;
|
||||||
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.model.projection.CategoryPostCountProjection;
|
import run.halo.app.model.projection.CategoryPostCountProjection;
|
||||||
import run.halo.app.repository.CategoryRepository;
|
import run.halo.app.repository.CategoryRepository;
|
||||||
import run.halo.app.repository.PostCategoryRepository;
|
import run.halo.app.repository.PostCategoryRepository;
|
||||||
|
@ -25,7 +26,8 @@ import java.util.stream.Collectors;
|
||||||
* Post category service implementation.
|
* Post category service implementation.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 3/19/19
|
* @author ryanwang
|
||||||
|
* @date 2019-03-19
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class PostCategoryServiceImpl extends AbstractCrudService<PostCategory, Integer> implements PostCategoryService {
|
public class PostCategoryServiceImpl extends AbstractCrudService<PostCategory, Integer> implements PostCategoryService {
|
||||||
|
@ -93,6 +95,17 @@ public class PostCategoryServiceImpl extends AbstractCrudService<PostCategory, I
|
||||||
return postRepository.findAllById(postIds);
|
return postRepository.findAllById(postIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Post> listPostBy(Integer categoryId, PostStatus status) {
|
||||||
|
Assert.notNull(categoryId, "Category id must not be null");
|
||||||
|
Assert.notNull(categoryId, "Post status must not be null");
|
||||||
|
|
||||||
|
// Find all post ids
|
||||||
|
Set<Integer> postIds = postCategoryRepository.findAllPostIdsByCategoryId(categoryId, status);
|
||||||
|
|
||||||
|
return postRepository.findAllById(postIds);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<Post> pagePostBy(Integer categoryId, Pageable pageable) {
|
public Page<Post> pagePostBy(Integer categoryId, Pageable pageable) {
|
||||||
Assert.notNull(categoryId, "Category id must not be null");
|
Assert.notNull(categoryId, "Category id must not be null");
|
||||||
|
@ -104,6 +117,18 @@ public class PostCategoryServiceImpl extends AbstractCrudService<PostCategory, I
|
||||||
return postRepository.findAllByIdIn(postIds, pageable);
|
return postRepository.findAllByIdIn(postIds, pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<Post> pagePostBy(Integer categoryId, PostStatus status, Pageable pageable) {
|
||||||
|
Assert.notNull(categoryId, "Category id must not be null");
|
||||||
|
Assert.notNull(categoryId, "Post status must not be null");
|
||||||
|
Assert.notNull(pageable, "Page info must not be null");
|
||||||
|
|
||||||
|
// Find all post ids
|
||||||
|
Set<Integer> postIds = postCategoryRepository.findAllPostIdsByCategoryId(categoryId, status);
|
||||||
|
|
||||||
|
return postRepository.findAllByIdIn(postIds, pageable);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PostCategory> mergeOrCreateByIfAbsent(Integer postId, Set<Integer> categoryIds) {
|
public List<PostCategory> mergeOrCreateByIfAbsent(Integer postId, Set<Integer> categoryIds) {
|
||||||
Assert.notNull(postId, "Post id must not be null");
|
Assert.notNull(postId, "Post id must not be null");
|
||||||
|
|
|
@ -32,7 +32,8 @@ import java.util.stream.Collectors;
|
||||||
* PostCommentService implementation class
|
* PostCommentService implementation class
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-03-14
|
* @author johnniang
|
||||||
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
|
|
@ -45,6 +45,7 @@ import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@ -280,7 +281,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
Assert.notNull(markdown, "Markdown document must not be null");
|
Assert.notNull(markdown, "Markdown document must not be null");
|
||||||
|
|
||||||
// Render markdown to html document.
|
// Render markdown to html document.
|
||||||
String content = MarkdownUtils.renderMarkdown(markdown);
|
String content = MarkdownUtils.renderHtml(markdown);
|
||||||
|
|
||||||
// Gets frontMatter
|
// Gets frontMatter
|
||||||
Map<String, List<String>> frontMatter = MarkdownUtils.getFrontMatter(markdown);
|
Map<String, List<String>> frontMatter = MarkdownUtils.getFrontMatter(markdown);
|
||||||
|
@ -462,8 +463,7 @@ public class PostServiceImpl extends BasePostServiceImpl<Post> implements PostSe
|
||||||
PostListVO postListVO = new PostListVO().convertFrom(post);
|
PostListVO postListVO = new PostListVO().convertFrom(post);
|
||||||
|
|
||||||
if (StringUtils.isBlank(postListVO.getSummary())) {
|
if (StringUtils.isBlank(postListVO.getSummary())) {
|
||||||
// Set summary
|
postListVO.setSummary(generateSummary(post.getFormatContent()));
|
||||||
postListVO.setSummary(convertToSummary(post.getOriginalContent()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional.ofNullable(tagListMap.get(post.getId())).orElseGet(LinkedList::new);
|
Optional.ofNullable(tagListMap.get(post.getId())).orElseGet(LinkedList::new);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import run.halo.app.model.dto.TagWithPostCountDTO;
|
||||||
import run.halo.app.model.entity.Post;
|
import run.halo.app.model.entity.Post;
|
||||||
import run.halo.app.model.entity.PostTag;
|
import run.halo.app.model.entity.PostTag;
|
||||||
import run.halo.app.model.entity.Tag;
|
import run.halo.app.model.entity.Tag;
|
||||||
|
import run.halo.app.model.enums.PostStatus;
|
||||||
import run.halo.app.model.projection.TagPostPostCountProjection;
|
import run.halo.app.model.projection.TagPostPostCountProjection;
|
||||||
import run.halo.app.repository.PostRepository;
|
import run.halo.app.repository.PostRepository;
|
||||||
import run.halo.app.repository.PostTagRepository;
|
import run.halo.app.repository.PostTagRepository;
|
||||||
|
@ -25,7 +26,8 @@ import java.util.stream.Collectors;
|
||||||
* Post tag service implementation.
|
* Post tag service implementation.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 3/19/19
|
* @author ryanwang
|
||||||
|
* @date 2019-03-19
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class PostTagServiceImpl extends AbstractCrudService<PostTag, Integer> implements PostTagService {
|
public class PostTagServiceImpl extends AbstractCrudService<PostTag, Integer> implements PostTagService {
|
||||||
|
@ -113,6 +115,17 @@ public class PostTagServiceImpl extends AbstractCrudService<PostTag, Integer> im
|
||||||
return postRepository.findAllById(postIds);
|
return postRepository.findAllById(postIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Post> listPostsBy(Integer tagId, PostStatus status) {
|
||||||
|
Assert.notNull(tagId, "Tag id must not be null");
|
||||||
|
Assert.notNull(tagId, "Post status must not be null");
|
||||||
|
|
||||||
|
// Find all post ids
|
||||||
|
Set<Integer> postIds = postTagRepository.findAllPostIdsByTagId(tagId, status);
|
||||||
|
|
||||||
|
return postRepository.findAllById(postIds);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<Post> pagePostsBy(Integer tagId, Pageable pageable) {
|
public Page<Post> pagePostsBy(Integer tagId, Pageable pageable) {
|
||||||
Assert.notNull(tagId, "Tag id must not be null");
|
Assert.notNull(tagId, "Tag id must not be null");
|
||||||
|
@ -124,6 +137,18 @@ public class PostTagServiceImpl extends AbstractCrudService<PostTag, Integer> im
|
||||||
return postRepository.findAllByIdIn(postIds, pageable);
|
return postRepository.findAllByIdIn(postIds, pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<Post> pagePostsBy(Integer tagId, PostStatus status, Pageable pageable) {
|
||||||
|
Assert.notNull(tagId, "Tag id must not be null");
|
||||||
|
Assert.notNull(tagId, "Post status must not be null");
|
||||||
|
Assert.notNull(pageable, "Page info must not be null");
|
||||||
|
|
||||||
|
// Find all post ids
|
||||||
|
Set<Integer> postIds = postTagRepository.findAllPostIdsByTagId(tagId, status);
|
||||||
|
|
||||||
|
return postRepository.findAllByIdIn(postIds, pageable);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PostTag> mergeOrCreateByIfAbsent(Integer postId, Set<Integer> tagIds) {
|
public List<PostTag> mergeOrCreateByIfAbsent(Integer postId, Set<Integer> tagIds) {
|
||||||
Assert.notNull(postId, "Post id must not be null");
|
Assert.notNull(postId, "Post id must not be null");
|
||||||
|
|
|
@ -33,7 +33,8 @@ import java.util.stream.Collectors;
|
||||||
* Recovery service implementation.
|
* Recovery service implementation.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-4-26
|
* @author ryanwang
|
||||||
|
* @date 2019-04-26
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@ -64,6 +65,10 @@ public class RecoveryServiceImpl implements RecoveryService {
|
||||||
|
|
||||||
private final PhotoService photoService;
|
private final PhotoService photoService;
|
||||||
|
|
||||||
|
private final PostCategoryService postCategoryService;
|
||||||
|
|
||||||
|
private final PostTagService postTagService;
|
||||||
|
|
||||||
public RecoveryServiceImpl(AttachmentService attachmentService,
|
public RecoveryServiceImpl(AttachmentService attachmentService,
|
||||||
PostService postService,
|
PostService postService,
|
||||||
LinkService linkService,
|
LinkService linkService,
|
||||||
|
@ -75,7 +80,9 @@ public class RecoveryServiceImpl implements RecoveryService {
|
||||||
SheetCommentService sheetCommentService,
|
SheetCommentService sheetCommentService,
|
||||||
SheetCommentRepository sheetCommentRepository,
|
SheetCommentRepository sheetCommentRepository,
|
||||||
SheetService sheetService,
|
SheetService sheetService,
|
||||||
PhotoService photoService) {
|
PhotoService photoService,
|
||||||
|
PostCategoryService postCategoryService,
|
||||||
|
PostTagService postTagService) {
|
||||||
this.attachmentService = attachmentService;
|
this.attachmentService = attachmentService;
|
||||||
this.postService = postService;
|
this.postService = postService;
|
||||||
this.linkService = linkService;
|
this.linkService = linkService;
|
||||||
|
@ -88,6 +95,8 @@ public class RecoveryServiceImpl implements RecoveryService {
|
||||||
this.sheetCommentRepository = sheetCommentRepository;
|
this.sheetCommentRepository = sheetCommentRepository;
|
||||||
this.sheetService = sheetService;
|
this.sheetService = sheetService;
|
||||||
this.photoService = photoService;
|
this.photoService = photoService;
|
||||||
|
this.postCategoryService = postCategoryService;
|
||||||
|
this.postTagService = postTagService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -215,9 +224,21 @@ public class RecoveryServiceImpl implements RecoveryService {
|
||||||
Post createdPost = postService.createOrUpdateBy(post);
|
Post createdPost = postService.createOrUpdateBy(post);
|
||||||
|
|
||||||
Object commentsObject = postMap.get("comments");
|
Object commentsObject = postMap.get("comments");
|
||||||
|
Object categoriesObject = postMap.get("categories");
|
||||||
|
Object tagsObject = postMap.get("tags");
|
||||||
// Handle comments
|
// Handle comments
|
||||||
List<BaseComment> baseComments = handleComment(commentsObject, createdPost.getId());
|
List<BaseComment> baseComments = handleComment(commentsObject, createdPost.getId());
|
||||||
|
|
||||||
|
// Handle categories
|
||||||
|
List<Category> categories = handleCategories(categoriesObject, createdPost.getId());
|
||||||
|
|
||||||
|
log.debug("Migrated categories of post [{}]: [{}]", categories, createdPost.getId());
|
||||||
|
|
||||||
|
// Handle tags
|
||||||
|
List<Tag> tags = handleTags(tagsObject, createdPost.getId());
|
||||||
|
|
||||||
|
log.debug("Migrated tags of post [{}]: [{}]", tags, createdPost.getId());
|
||||||
|
|
||||||
List<PostComment> postComments = baseComments.stream()
|
List<PostComment> postComments = baseComments.stream()
|
||||||
.map(baseComment -> BeanUtils.transformFrom(baseComment, PostComment.class))
|
.map(baseComment -> BeanUtils.transformFrom(baseComment, PostComment.class))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
@ -372,6 +393,96 @@ public class RecoveryServiceImpl implements RecoveryService {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private List<Category> handleCategories(@Nullable Object categoriesObject, @NonNull Integer postId) {
|
||||||
|
Assert.notNull(postId, "Post id must not be null");
|
||||||
|
|
||||||
|
if (!(categoriesObject instanceof List)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Object> categoryObjectList = (List<Object>) categoriesObject;
|
||||||
|
|
||||||
|
List<Category> result = new LinkedList<>();
|
||||||
|
|
||||||
|
categoryObjectList.forEach(categoryObject -> {
|
||||||
|
if (!(categoryObject instanceof Map)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> categoryMap = (Map<String, Object>) categoryObject;
|
||||||
|
|
||||||
|
String slugName = categoryMap.getOrDefault("cateUrl", "").toString();
|
||||||
|
|
||||||
|
Category category = categoryService.getBySlugName(slugName);
|
||||||
|
|
||||||
|
if (null == category) {
|
||||||
|
category = new Category();
|
||||||
|
category.setName(categoryMap.getOrDefault("cateName", "").toString());
|
||||||
|
category.setSlugName(slugName);
|
||||||
|
category.setDescription(categoryMap.getOrDefault("cateDesc", "").toString());
|
||||||
|
category = categoryService.create(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
PostCategory postCategory = new PostCategory();
|
||||||
|
postCategory.setCategoryId(category.getId());
|
||||||
|
postCategory.setPostId(postId);
|
||||||
|
postCategoryService.create(postCategory);
|
||||||
|
|
||||||
|
try {
|
||||||
|
result.add(category);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Failed to migrate a category", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private List<Tag> handleTags(@Nullable Object tagsObject, @NonNull Integer postId) {
|
||||||
|
Assert.notNull(postId, "Post id must not be null");
|
||||||
|
|
||||||
|
if (!(tagsObject instanceof List)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Object> tagObjectList = (List<Object>) tagsObject;
|
||||||
|
|
||||||
|
List<Tag> result = new LinkedList<>();
|
||||||
|
|
||||||
|
tagObjectList.forEach(tagObject -> {
|
||||||
|
if (!(tagObject instanceof Map)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> tagMap = (Map<String, Object>) tagObject;
|
||||||
|
|
||||||
|
String slugName = tagMap.getOrDefault("tagUrl", "").toString();
|
||||||
|
|
||||||
|
Tag tag = tagService.getBySlugName(slugName);
|
||||||
|
|
||||||
|
if (null == tag) {
|
||||||
|
tag = new Tag();
|
||||||
|
tag.setName(tagMap.getOrDefault("tagName", "").toString());
|
||||||
|
tag.setSlugName(slugName);
|
||||||
|
tag = tagService.create(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
PostTag postTag = new PostTag();
|
||||||
|
postTag.setTagId(tag.getId());
|
||||||
|
postTag.setPostId(postId);
|
||||||
|
postTagService.create(postTag);
|
||||||
|
|
||||||
|
try {
|
||||||
|
result.add(tag);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Failed to migrate a tag", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private List<Menu> handleMenus(@Nullable Object menusObject) {
|
private List<Menu> handleMenus(@Nullable Object menusObject) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ import java.util.stream.Collectors;
|
||||||
* Sheet comment service implementation.
|
* Sheet comment service implementation.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-4-24
|
* @date 2019-04-24
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class SheetCommentServiceImpl extends BaseCommentServiceImpl<SheetComment> implements SheetCommentService {
|
public class SheetCommentServiceImpl extends BaseCommentServiceImpl<SheetComment> implements SheetCommentService {
|
||||||
|
|
|
@ -31,7 +31,7 @@ import java.util.Set;
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date 19-4-24
|
* @date 2019-04-24
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class SheetServiceImpl extends BasePostServiceImpl<Sheet> implements SheetService {
|
public class SheetServiceImpl extends BasePostServiceImpl<Sheet> implements SheetService {
|
||||||
|
@ -85,13 +85,6 @@ public class SheetServiceImpl extends BasePostServiceImpl<Sheet> implements Shee
|
||||||
return listAll(pageable);
|
return listAll(pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets sheet by post status and url.
|
|
||||||
*
|
|
||||||
* @param status post status must not be null
|
|
||||||
* @param url sheet url must not be blank
|
|
||||||
* @return sheet info
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Sheet getBy(PostStatus status, String url) {
|
public Sheet getBy(PostStatus status, String url) {
|
||||||
Sheet sheet = super.getBy(status, url);
|
Sheet sheet = super.getBy(status, url);
|
||||||
|
@ -109,11 +102,12 @@ public class SheetServiceImpl extends BasePostServiceImpl<Sheet> implements Shee
|
||||||
Assert.notNull(markdown, "Markdown document must not be null");
|
Assert.notNull(markdown, "Markdown document must not be null");
|
||||||
|
|
||||||
// Render markdown to html document.
|
// Render markdown to html document.
|
||||||
String content = MarkdownUtils.renderMarkdown(markdown);
|
String content = MarkdownUtils.renderHtml(markdown);
|
||||||
|
|
||||||
// Gets frontMatter
|
// Gets frontMatter
|
||||||
Map<String, List<String>> frontMatter = MarkdownUtils.getFrontMatter(markdown);
|
Map<String, List<String>> frontMatter = MarkdownUtils.getFrontMatter(markdown);
|
||||||
|
|
||||||
|
// TODO
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package run.halo.app.service.impl;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import run.halo.app.exception.AlreadyExistsException;
|
import run.halo.app.exception.AlreadyExistsException;
|
||||||
|
@ -17,10 +18,11 @@ import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TagService implementation class
|
* TagService implementation class.
|
||||||
*
|
*
|
||||||
|
* @author johnniang
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-03-14
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@ -34,6 +36,7 @@ public class TagServiceImpl extends AbstractCrudService<Tag, Integer> implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public Tag create(Tag tag) {
|
public Tag create(Tag tag) {
|
||||||
// Check if the tag is exist
|
// Check if the tag is exist
|
||||||
long count = tagRepository.countByNameOrSlugName(tag.getName(), tag.getSlugName());
|
long count = tagRepository.countByNameOrSlugName(tag.getName(), tag.getSlugName());
|
||||||
|
@ -49,17 +52,15 @@ public class TagServiceImpl extends AbstractCrudService<Tag, Integer> implements
|
||||||
return super.create(tag);
|
return super.create(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get tag by slug name
|
|
||||||
*
|
|
||||||
* @param slugName slug name
|
|
||||||
* @return Tag
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Tag getBySlugNameOfNonNull(String slugName) {
|
public Tag getBySlugNameOfNonNull(String slugName) {
|
||||||
return tagRepository.getBySlugName(slugName).orElseThrow(() -> new NotFoundException("该标签已存在").setErrorData(slugName));
|
return tagRepository.getBySlugName(slugName).orElseThrow(() -> new NotFoundException("该标签不存在").setErrorData(slugName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tag getBySlugName(String slugName) {
|
||||||
|
return tagRepository.getBySlugName(slugName).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag getByName(String name) {
|
public Tag getByName(String name) {
|
||||||
|
|
|
@ -53,7 +53,7 @@ import static run.halo.app.model.support.HaloConst.DEFAULT_THEME_ID;
|
||||||
* Theme service implementation.
|
* Theme service implementation.
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019/3/26
|
* @date 2019-03-26
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
|
|
@ -24,7 +24,7 @@ import java.util.*;
|
||||||
* Theme setting service implementation.
|
* Theme setting service implementation.
|
||||||
*
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 4/8/19
|
* @date 2019-04-08
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
|
|
@ -2,18 +2,16 @@ package run.halo.app.service.impl;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.trace.http.HttpTrace;
|
import org.springframework.boot.actuate.trace.http.HttpTrace;
|
||||||
import org.springframework.boot.actuate.trace.http.HttpTraceRepository;
|
import org.springframework.boot.actuate.trace.http.HttpTraceRepository;
|
||||||
import org.springframework.data.domain.Page;
|
|
||||||
import org.springframework.data.domain.PageImpl;
|
|
||||||
import org.springframework.data.domain.Pageable;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import run.halo.app.service.TraceService;
|
import run.halo.app.service.TraceService;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TraceService implementation class.
|
||||||
|
*
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 19-6-18
|
* @date 2019-06-18
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class TraceServiceImpl implements TraceService {
|
public class TraceServiceImpl implements TraceService {
|
||||||
|
|
|
@ -31,10 +31,11 @@ import java.util.Optional;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UserService implementation class
|
* UserService implementation class.
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2019-03-14
|
* @author johnniang
|
||||||
|
* @date 2019-03-14
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class UserServiceImpl extends AbstractCrudService<User, Integer> implements UserService {
|
public class UserServiceImpl extends AbstractCrudService<User, Integer> implements UserService {
|
||||||
|
@ -78,24 +79,11 @@ public class UserServiceImpl extends AbstractCrudService<User, Integer> implemen
|
||||||
return getByUsername(username).orElseThrow(() -> new NotFoundException("The username dose not exist").setErrorData(username));
|
return getByUsername(username).orElseThrow(() -> new NotFoundException("The username dose not exist").setErrorData(username));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets user by email.
|
|
||||||
*
|
|
||||||
* @param email email must not be blank
|
|
||||||
* @return an optional user
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<User> getByEmail(String email) {
|
public Optional<User> getByEmail(String email) {
|
||||||
return userRepository.findByEmail(email);
|
return userRepository.findByEmail(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets non null user by email.
|
|
||||||
*
|
|
||||||
* @param email email
|
|
||||||
* @return user info
|
|
||||||
* @throws NotFoundException throws when the username does not exist
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public User getByEmailOfNonNull(String email) {
|
public User getByEmailOfNonNull(String email) {
|
||||||
return getByEmail(email).orElseThrow(() -> new NotFoundException("The email dose not exist").setErrorData(email));
|
return getByEmail(email).orElseThrow(() -> new NotFoundException("The email dose not exist").setErrorData(email));
|
||||||
|
|
|
@ -8,7 +8,6 @@ import org.springframework.util.Assert;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static run.halo.app.model.support.HaloConst.FILE_SEPARATOR;
|
import static run.halo.app.model.support.HaloConst.FILE_SEPARATOR;
|
||||||
|
@ -17,11 +16,14 @@ import static run.halo.app.model.support.HaloConst.FILE_SEPARATOR;
|
||||||
* Common utils
|
* Common utils
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
|
* @author johnniang
|
||||||
* @date : 2017/12/22
|
* @date : 2017/12/22
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class HaloUtils {
|
public class HaloUtils {
|
||||||
|
|
||||||
|
private static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Desensitizes the plain text.
|
* Desensitizes the plain text.
|
||||||
*
|
*
|
||||||
|
@ -192,4 +194,14 @@ public class HaloUtils {
|
||||||
}
|
}
|
||||||
return machineAddress.getHostAddress();
|
return machineAddress.getHostAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean all html tag
|
||||||
|
*
|
||||||
|
* @param content html document
|
||||||
|
* @return text before cleaned
|
||||||
|
*/
|
||||||
|
public static String cleanHtmlTag(String content) {
|
||||||
|
return content.replaceAll(RE_HTML_MARK, "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,147 +1,107 @@
|
||||||
package run.halo.app.utils;
|
package run.halo.app.utils;
|
||||||
|
|
||||||
|
import com.vladsch.flexmark.convert.html.FlexmarkHtmlParser;
|
||||||
|
import com.vladsch.flexmark.ext.attributes.AttributesExtension;
|
||||||
|
import com.vladsch.flexmark.ext.autolink.AutolinkExtension;
|
||||||
|
import com.vladsch.flexmark.ext.emoji.EmojiExtension;
|
||||||
|
import com.vladsch.flexmark.ext.emoji.EmojiImageType;
|
||||||
|
import com.vladsch.flexmark.ext.emoji.EmojiShortcutType;
|
||||||
|
import com.vladsch.flexmark.ext.escaped.character.EscapedCharacterExtension;
|
||||||
|
import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension;
|
||||||
|
import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension;
|
||||||
|
import com.vladsch.flexmark.ext.ins.InsExtension;
|
||||||
|
import com.vladsch.flexmark.ext.media.tags.MediaTagsExtension;
|
||||||
|
import com.vladsch.flexmark.ext.tables.TablesExtension;
|
||||||
|
import com.vladsch.flexmark.ext.toc.TocExtension;
|
||||||
|
import com.vladsch.flexmark.ext.yaml.front.matter.AbstractYamlFrontMatterVisitor;
|
||||||
|
import com.vladsch.flexmark.ext.yaml.front.matter.YamlFrontMatterExtension;
|
||||||
|
import com.vladsch.flexmark.html.HtmlRenderer;
|
||||||
|
import com.vladsch.flexmark.parser.Parser;
|
||||||
|
import com.vladsch.flexmark.util.ast.Node;
|
||||||
|
import com.vladsch.flexmark.util.options.DataHolder;
|
||||||
|
import com.vladsch.flexmark.util.options.MutableDataSet;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.commonmark.Extension;
|
|
||||||
import org.commonmark.ext.autolink.AutolinkExtension;
|
|
||||||
import org.commonmark.ext.front.matter.YamlFrontMatterExtension;
|
|
||||||
import org.commonmark.ext.front.matter.YamlFrontMatterVisitor;
|
|
||||||
import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension;
|
|
||||||
import org.commonmark.ext.gfm.tables.TablesExtension;
|
|
||||||
import org.commonmark.ext.heading.anchor.HeadingAnchorExtension;
|
|
||||||
import org.commonmark.ext.ins.InsExtension;
|
|
||||||
import org.commonmark.node.Node;
|
|
||||||
import org.commonmark.parser.Parser;
|
|
||||||
import org.commonmark.renderer.html.HtmlRenderer;
|
|
||||||
import org.commonmark.renderer.text.TextContentRenderer;
|
|
||||||
import org.springframework.lang.NonNull;
|
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
import run.halo.app.model.support.HaloConst;
|
import run.halo.app.model.support.HaloConst;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Markdown utils
|
* Markdown utils.
|
||||||
*
|
*
|
||||||
* @author ryanwang
|
* @author ryanwang
|
||||||
* @date : 2018/11/14
|
* @date : 2019/06/27
|
||||||
*/
|
*/
|
||||||
public class MarkdownUtils {
|
public class MarkdownUtils {
|
||||||
|
|
||||||
|
private static final DataHolder OPTIONS = new MutableDataSet()
|
||||||
|
.set(Parser.EXTENSIONS, Arrays.asList(
|
||||||
|
AttributesExtension.create(),
|
||||||
|
AutolinkExtension.create(),
|
||||||
|
EmojiExtension.create(),
|
||||||
|
EscapedCharacterExtension.create(),
|
||||||
|
StrikethroughExtension.create(),
|
||||||
|
TaskListExtension.create(),
|
||||||
|
InsExtension.create(),
|
||||||
|
MediaTagsExtension.create(),
|
||||||
|
TablesExtension.create(),
|
||||||
|
TocExtension.create(),
|
||||||
|
YamlFrontMatterExtension.create())
|
||||||
|
)
|
||||||
|
.set(TablesExtension.WITH_CAPTION, false)
|
||||||
|
.set(TablesExtension.COLUMN_SPANS, false)
|
||||||
|
.set(TablesExtension.MIN_HEADER_ROWS, 1)
|
||||||
|
.set(TablesExtension.MAX_HEADER_ROWS, 1)
|
||||||
|
.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
|
||||||
|
.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
|
||||||
|
.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
|
||||||
|
.set(EmojiExtension.USE_SHORTCUT_TYPE, EmojiShortcutType.GITHUB)
|
||||||
|
.set(EmojiExtension.USE_IMAGE_TYPE, EmojiImageType.IMAGE_ONLY);
|
||||||
|
|
||||||
/**
|
private static final Parser PARSER = Parser.builder(OPTIONS).build();
|
||||||
* commonmark-java extension for autolinking
|
|
||||||
*/
|
|
||||||
private static final Set<Extension> EXTENSIONS_AUTO_LINK = Collections.singleton(AutolinkExtension.create());
|
|
||||||
|
|
||||||
/**
|
private static final HtmlRenderer RENDERER = HtmlRenderer.builder(OPTIONS).build();
|
||||||
* commonmark-java extension for strikethrough
|
|
||||||
*/
|
|
||||||
private static final Set<Extension> EXTENSIONS_STRIKETHROUGH = Collections.singleton(StrikethroughExtension.create());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* commonmark-java extension for tables
|
|
||||||
*/
|
|
||||||
private static final Set<Extension> EXTENSIONS_TABLES = Collections.singleton(TablesExtension.create());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* commonmark-java extension for adding id attributes to h tags
|
|
||||||
*/
|
|
||||||
private static final Set<Extension> EXTENSIONS_HEADING_ANCHOR = Collections.singleton(HeadingAnchorExtension.create());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* commonmark-java extension for <ins> (underline)
|
|
||||||
*/
|
|
||||||
private static final Set<Extension> EXTENSIONS_INS = Collections.singleton(InsExtension.create());
|
|
||||||
|
|
||||||
/**
|
|
||||||
* commonmark-java extension for YAML front matter
|
|
||||||
*/
|
|
||||||
private static final Set<Extension> EXTENSIONS_YAML_FRONT_MATTER = Collections.singleton(YamlFrontMatterExtension.create());
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse Markdown content
|
|
||||||
*/
|
|
||||||
private static final Parser PARSER = Parser.builder()
|
|
||||||
.extensions(EXTENSIONS_AUTO_LINK)
|
|
||||||
.extensions(EXTENSIONS_STRIKETHROUGH)
|
|
||||||
.extensions(EXTENSIONS_TABLES)
|
|
||||||
.extensions(EXTENSIONS_HEADING_ANCHOR)
|
|
||||||
.extensions(EXTENSIONS_INS)
|
|
||||||
.extensions(EXTENSIONS_YAML_FRONT_MATTER)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render HTML content
|
|
||||||
*/
|
|
||||||
private static final HtmlRenderer RENDERER = HtmlRenderer.builder()
|
|
||||||
.extensions(EXTENSIONS_AUTO_LINK)
|
|
||||||
.extensions(EXTENSIONS_STRIKETHROUGH)
|
|
||||||
.extensions(EXTENSIONS_TABLES)
|
|
||||||
.extensions(EXTENSIONS_HEADING_ANCHOR)
|
|
||||||
.extensions(EXTENSIONS_INS)
|
|
||||||
.extensions(EXTENSIONS_YAML_FRONT_MATTER)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render text content
|
|
||||||
*/
|
|
||||||
private static final TextContentRenderer TEXT_CONTENT_RENDERER = TextContentRenderer.builder()
|
|
||||||
.extensions(EXTENSIONS_AUTO_LINK)
|
|
||||||
.extensions(EXTENSIONS_STRIKETHROUGH)
|
|
||||||
.extensions(EXTENSIONS_TABLES)
|
|
||||||
.extensions(EXTENSIONS_HEADING_ANCHOR)
|
|
||||||
.extensions(EXTENSIONS_INS)
|
|
||||||
.extensions(EXTENSIONS_YAML_FRONT_MATTER)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render Markdown content
|
* Render Markdown content
|
||||||
*
|
*
|
||||||
* @param content content
|
* @param content content
|
||||||
* @return String
|
* @return String
|
||||||
* @see <a href="https://github.com/otale/tale/blob/master/src/main/java/com/tale/utils/TaleUtils.java">TaleUtils.java</a>
|
|
||||||
*/
|
*/
|
||||||
public static String renderMarkdown(String content) {
|
public static String renderHtml(String markdown) {
|
||||||
|
if (StringUtils.isBlank(markdown)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
Node document = PARSER.parse(markdown);
|
||||||
|
String renderedContent = RENDERER.render(document);
|
||||||
|
|
||||||
final Node document = PARSER.parse(content);
|
// Render netease music short url.
|
||||||
String renderContent = RENDERER.render(document);
|
if (markdown.contains(HaloConst.NETEASE_MUSIC_PREFIX)) {
|
||||||
|
renderedContent = markdown.replaceAll(HaloConst.NETEASE_MUSIC_REG_PATTERN, HaloConst.NETEASE_MUSIC_IFRAME);
|
||||||
// render netease music short url
|
|
||||||
if (content.contains(HaloConst.NETEASE_MUSIC_PREFIX)) {
|
|
||||||
renderContent = content.replaceAll(HaloConst.NETEASE_MUSIC_REG_PATTERN, HaloConst.NETEASE_MUSIC_IFRAME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// render bilibili video short url
|
// Render bilibili video short url.
|
||||||
if (content.contains(HaloConst.BILIBILI_VIDEO_PREFIX)) {
|
if (markdown.contains(HaloConst.BILIBILI_VIDEO_PREFIX)) {
|
||||||
renderContent = content.replaceAll(HaloConst.BILIBILI_VIDEO_REG_PATTERN, HaloConst.BILIBILI_VIDEO_IFRAME);
|
renderedContent = markdown.replaceAll(HaloConst.BILIBILI_VIDEO_REG_PATTERN, HaloConst.BILIBILI_VIDEO_IFRAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
// render youtube video short url
|
// Render youtube video short url.
|
||||||
if (content.contains(HaloConst.YOUTUBE_VIDEO_PREFIX)) {
|
if (markdown.contains(HaloConst.YOUTUBE_VIDEO_PREFIX)) {
|
||||||
renderContent = content.replaceAll(HaloConst.YOUTUBE_VIDEO_REG_PATTERN, HaloConst.YOUTUBE_VIDEO_IFRAME);
|
renderedContent = markdown.replaceAll(HaloConst.YOUTUBE_VIDEO_REG_PATTERN, HaloConst.YOUTUBE_VIDEO_IFRAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderContent;
|
return renderedContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render text content.
|
* Render html document to markdown document.
|
||||||
*
|
*
|
||||||
* @param markdownContent markdown content
|
* @param html html document
|
||||||
* @return text content or empty string if markdown content is blank
|
* @return markdown document
|
||||||
*/
|
*/
|
||||||
@NonNull
|
public static String renderMarkdown(String html) {
|
||||||
public static String renderText(@Nullable String markdownContent) {
|
return FlexmarkHtmlParser.parse(html);
|
||||||
|
|
||||||
if (StringUtils.isBlank(markdownContent)) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return TEXT_CONTENT_RENDERER.render(PARSER.parse(markdownContent));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -150,10 +110,10 @@ public class MarkdownUtils {
|
||||||
* @param content content
|
* @param content content
|
||||||
* @return Map
|
* @return Map
|
||||||
*/
|
*/
|
||||||
public static Map<String, List<String>> getFrontMatter(String content) {
|
public static Map<String, List<String>> getFrontMatter(String markdown) {
|
||||||
final YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor();
|
AbstractYamlFrontMatterVisitor visitor = new AbstractYamlFrontMatterVisitor();
|
||||||
final Node document = PARSER.parse(content);
|
Node document = PARSER.parse(markdown);
|
||||||
document.accept(visitor);
|
visitor.visit(document);
|
||||||
return visitor.getData();
|
return visitor.getData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
||||||
|
body{height:100%;background-color:#f5f5f5}.container{background:#f7f7f7;position:absolute;top:45%;left:50%;margin:-160px 0 0 -160px;width:320px;padding:16px 32px 32px 32px;-webkit-box-shadow:-4px 7px 46px 2px rgba(0,0,0,.1);box-shadow:-4px 7px 46px 2px rgba(0,0,0,.1)}.container .tip{cursor:pointer;margin-top:.5rem;float:right}.loginLogo{margin-bottom:20px;text-align:center}.loginLogo span{vertical-align:text-bottom;font-size:36px;display:inline-block;font-weight:600;color:#1790fe;background-image:-webkit-gradient(linear,37.219838% 34.532506%,36.425669% 93.178216%,from(#36c8f5),to(#1790fe),color-stop(.37,#1790fe));-webkit-text-fill-color:transparent;-webkit-background-clip:text}
|
|
@ -0,0 +1 @@
|
||||||
|
a[data-v-4b6b2ba0]{text-decoration:none}.sheet-title[data-v-4b6b2ba0]{max-width:300px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
@ -0,0 +1 @@
|
||||||
|
.ant-upload-select-picture-card i{font-size:32px;color:#999}.ant-upload-select-picture-card .ant-upload-text{margin-top:8px;color:#666}.ant-upload-list-picture-card{float:none}.more-options-btn[data-v-7111bbfe]{margin-left:15px;text-decoration:none}.photo-card[data-v-7111bbfe]{width:104px;display:inline-block;margin-right:5px}
|
|
@ -1 +0,0 @@
|
||||||
.attach-detail-img img{width:100%}.attach-item{width:50%;margin:0 auto;position:relative;padding-bottom:28%;overflow:hidden;float:left;cursor:pointer}.attach-item img{width:100%;height:100%;position:absolute;top:0;left:0}@-webkit-keyframes scaleDraw-data-v-0ce6900e{0%{-webkit-transform:scale(1);transform:scale(1)}25%{-webkit-transform:scale(1.3);transform:scale(1.3)}50%{-webkit-transform:scale(1);transform:scale(1)}75%{-webkit-transform:scale(1.3);transform:scale(1.3)}}@keyframes scaleDraw-data-v-0ce6900e{0%{-webkit-transform:scale(1);transform:scale(1)}25%{-webkit-transform:scale(1.3);transform:scale(1.3)}50%{-webkit-transform:scale(1);transform:scale(1)}75%{-webkit-transform:scale(1.3);transform:scale(1.3)}}.upload-button[data-v-0ce6900e]{-webkit-animation:scaleDraw-data-v-0ce6900e 4s ease-in-out infinite;position:fixed;bottom:30px;right:30px}.theme-thumb[data-v-0ce6900e]{width:100%;margin:0 auto;position:relative;padding-bottom:56%;overflow:hidden}.theme-thumb img[data-v-0ce6900e]{width:100%;height:100%;position:absolute;top:0;left:0}
|
|
|
@ -1 +1 @@
|
||||||
.analysis-card-container[data-v-698a5e37]{position:relative;overflow:hidden;width:100%}.analysis-card-container .meta[data-v-698a5e37]{position:relative;overflow:hidden;width:100%;color:rgba(0,0,0,.45);font-size:14px;line-height:22px}.analysis-card-container .meta .analysis-card-action[data-v-698a5e37]{cursor:pointer;position:absolute;top:0;right:0}.number[data-v-698a5e37]{overflow:hidden;text-overflow:ellipsis;word-break:break-all;white-space:nowrap;color:#000;margin-top:4px;margin-bottom:0;font-size:32px;line-height:38px;height:38px}
|
.analysis-card-container[data-v-698a5e37]{position:relative;overflow:hidden;width:100%}.analysis-card-container .meta[data-v-698a5e37]{position:relative;overflow:hidden;width:100%;color:rgba(0,0,0,.45);font-size:14px;line-height:22px}.analysis-card-container .meta .analysis-card-action[data-v-698a5e37]{cursor:pointer;position:absolute;top:0;right:0}.number[data-v-698a5e37]{overflow:hidden;text-overflow:ellipsis;word-break:break-all;white-space:nowrap;color:#000;margin-top:4px;margin-bottom:0;font-size:32px;line-height:38px;height:38px}.ant-upload-select-picture-card i{font-size:32px;color:#999}.ant-upload-select-picture-card .ant-upload-text{margin-top:8px;color:#666}.ant-upload-list-picture-card{float:none}.more-options-btn[data-v-77a18f66]{margin-left:15px;text-decoration:none}a[data-v-77a18f66]{text-decoration:none}
|
|
@ -0,0 +1 @@
|
||||||
|
.ant-divider-horizontal[data-v-604cba98]{margin:24px 0 12px 0}.search-box[data-v-604cba98]{padding-bottom:12px}.attach-thumb[data-v-604cba98]{width:100%;margin:0 auto;position:relative;padding-bottom:56%;overflow:hidden}.attach-thumb img[data-v-604cba98],.attach-thumb span[data-v-604cba98]{width:100%;height:100%;position:absolute;top:0;left:0}.attach-thumb span[data-v-604cba98]{display:-webkit-box;display:-ms-flexbox;display:flex;font-size:12px;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;color:#9b9ea0}.ant-card-meta[data-v-604cba98]{padding:.8rem}.attach-detail-img img[data-v-604cba98]{width:100%}.table-operator[data-v-604cba98]{margin-bottom:0}
|
|
@ -0,0 +1 @@
|
||||||
|
.attach-item{width:50%;margin:0 auto;position:relative;padding-bottom:28%;overflow:hidden;float:left;cursor:pointer}.attach-item img{width:100%;height:100%;position:absolute;top:0;left:0}a[data-v-a379d92e]{text-decoration:none}.post-title[data-v-a379d92e]{max-width:150px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
@ -0,0 +1 @@
|
||||||
|
.v-note-wrapper[data-v-6a7e5dfd]{z-index:1000;min-height:580px}
|
|
@ -0,0 +1 @@
|
||||||
|
.attach-item{width:50%;margin:0 auto;position:relative;padding-bottom:28%;overflow:hidden;float:left;cursor:pointer}.attach-item img{width:100%;height:100%;position:absolute;top:0;left:0}@font-face{font-family:fontello;src:url(../fonts/fontello.e73a0647.eot);src:url(../fonts/fontello.e73a0647.eot#iefix) format("embedded-opentype"),url(../fonts/fontello.8d4a4e6f.woff2) format("woff2"),url(../fonts/fontello.a782baa8.woff) format("woff"),url(../fonts/fontello.068ca2b3.ttf) format("truetype"),url(../assets/fontello.9354499c.svg#fontello) format("svg");font-weight:400;font-style:normal}[class*=" fa-mavon-"]:before,[class^=fa-mavon-]:before{font-family:fontello;font-style:normal;font-weight:400;speak:none;display:inline-block;text-decoration:inherit;width:1em;margin-right:.2em;text-align:center;font-variant:normal;text-transform:none;line-height:1em;margin-left:.2em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-mavon-bold:before{content:"\E800"}.fa-mavon-italic:before{content:"\E801"}.fa-mavon-thumb-tack:before{content:"\E802"}.fa-mavon-link:before{content:"\E803"}.fa-mavon-picture-o:before{content:"\E804"}.fa-mavon-repeat:before{content:"\E805"}.fa-mavon-undo:before{content:"\E806"}.fa-mavon-trash-o:before{content:"\E807"}.fa-mavon-floppy-o:before{content:"\E808"}.fa-mavon-compress:before{content:"\E809"}.fa-mavon-eye:before{content:"\E80A"}.fa-mavon-eye-slash:before{content:"\E80B"}.fa-mavon-question-circle:before{content:"\E80C"}.fa-mavon-times:before{content:"\E80D"}.fa-mavon-align-left:before{content:"\E80F"}.fa-mavon-align-center:before{content:"\E810"}.fa-mavon-align-right:before{content:"\E811"}.fa-mavon-arrows-alt:before{content:"\F0B2"}.fa-mavon-bars:before{content:"\F0C9"}.fa-mavon-list-ul:before{content:"\F0CA"}.fa-mavon-list-ol:before{content:"\F0CB"}.fa-mavon-strikethrough:before{content:"\F0CC"}.fa-mavon-underline:before{content:"\F0CD"}.fa-mavon-table:before{content:"\F0CE"}.fa-mavon-columns:before{content:"\F0DB"}.fa-mavon-quote-left:before{content:"\F10D"}.fa-mavon-code:before{content:"\F121"}.fa-mavon-superscript:before{content:"\F12B"}.fa-mavon-subscript:before{content:"\F12C"}.fa-mavon-header:before{content:"\F1DC"}.fa-mavon-window-maximize:before{content:"\F2D0"}.markdown-body strong{font-weight:bolder}.markdown-body .hljs-center{text-align:center}.markdown-body .hljs-right{text-align:right}.markdown-body .hljs-left{text-align:left}
|
|
@ -1 +0,0 @@
|
||||||
.attach-detail-img img{width:100%}.ant-divider-horizontal[data-v-18d41aa9]{margin:24px 0 12px 0}.search-box[data-v-18d41aa9]{padding-bottom:12px}.attach-thumb[data-v-18d41aa9]{width:100%;margin:0 auto;position:relative;padding-bottom:56%;overflow:hidden}.attach-thumb img[data-v-18d41aa9]{width:100%;height:100%;position:absolute;top:0;left:0}.ant-card-meta[data-v-18d41aa9]{padding:.8rem}.attach-detail-img img[data-v-18d41aa9]{width:100%}.table-operator[data-v-18d41aa9]{margin-bottom:0}
|
|
|
@ -0,0 +1 @@
|
||||||
|
.attach-item{width:50%;margin:0 auto;position:relative;padding-bottom:28%;overflow:hidden;float:left;cursor:pointer}.attach-item img{width:100%;height:100%;position:absolute;top:0;left:0}@-webkit-keyframes scaleDraw-data-v-290ad9ab{0%{-webkit-transform:scale(1);transform:scale(1)}25%{-webkit-transform:scale(1.3);transform:scale(1.3)}50%{-webkit-transform:scale(1);transform:scale(1)}75%{-webkit-transform:scale(1.3);transform:scale(1.3)}}@keyframes scaleDraw-data-v-290ad9ab{0%{-webkit-transform:scale(1);transform:scale(1)}25%{-webkit-transform:scale(1.3);transform:scale(1.3)}50%{-webkit-transform:scale(1);transform:scale(1)}75%{-webkit-transform:scale(1.3);transform:scale(1.3)}}.upload-button[data-v-290ad9ab]{-webkit-animation:scaleDraw-data-v-290ad9ab 4s ease-in-out infinite;position:fixed;bottom:30px;right:30px}.theme-thumb[data-v-290ad9ab]{width:100%;margin:0 auto;position:relative;padding-bottom:56%;overflow:hidden}.theme-thumb img[data-v-290ad9ab]{width:100%;height:100%;position:absolute;top:0;left:0}
|
|
@ -1 +1 @@
|
||||||
.attach-item{width:50%;margin:0 auto;position:relative;padding-bottom:28%;overflow:hidden;float:left;cursor:pointer}.attach-item img{width:100%;height:100%;position:absolute;top:0;left:0}.page-header-wrapper-grid-content-main[data-v-69ef61d6]{width:100%;height:100%;min-height:100%;-webkit-transition:.3s;transition:.3s}.page-header-wrapper-grid-content-main .profile-center-avatarHolder[data-v-69ef61d6]{text-align:center;margin-bottom:24px}.page-header-wrapper-grid-content-main .profile-center-avatarHolder>.avatar[data-v-69ef61d6]{margin:0 auto;width:104px;height:104px;margin-bottom:20px;border-radius:50%;overflow:hidden;cursor:pointer}.page-header-wrapper-grid-content-main .profile-center-avatarHolder>.avatar img[data-v-69ef61d6]{height:100%;width:100%}.page-header-wrapper-grid-content-main .profile-center-avatarHolder .username[data-v-69ef61d6]{color:rgba(0,0,0,.85);font-size:20px;line-height:28px;font-weight:500;margin-bottom:4px}.page-header-wrapper-grid-content-main .profile-center-detail p[data-v-69ef61d6]{margin-bottom:8px;padding-left:26px;position:relative}.page-header-wrapper-grid-content-main .profile-center-detail i[data-v-69ef61d6]{position:absolute;height:14px;width:14px;left:0;top:4px}
|
.attach-item{width:50%;margin:0 auto;position:relative;padding-bottom:28%;overflow:hidden;float:left;cursor:pointer}.attach-item img{width:100%;height:100%;position:absolute;top:0;left:0}.page-header-wrapper-grid-content-main[data-v-7e8f2146]{width:100%;height:100%;min-height:100%;-webkit-transition:.3s;transition:.3s}.page-header-wrapper-grid-content-main .profile-center-avatarHolder[data-v-7e8f2146]{text-align:center;margin-bottom:24px}.page-header-wrapper-grid-content-main .profile-center-avatarHolder>.avatar[data-v-7e8f2146]{margin:0 auto;width:104px;height:104px;margin-bottom:20px;border-radius:50%;overflow:hidden;cursor:pointer}.page-header-wrapper-grid-content-main .profile-center-avatarHolder>.avatar img[data-v-7e8f2146]{height:100%;width:100%}.page-header-wrapper-grid-content-main .profile-center-avatarHolder .username[data-v-7e8f2146]{color:rgba(0,0,0,.85);font-size:20px;line-height:28px;font-weight:500;margin-bottom:4px}.page-header-wrapper-grid-content-main .profile-center-detail p[data-v-7e8f2146]{margin-bottom:8px;padding-left:26px;position:relative}.page-header-wrapper-grid-content-main .profile-center-detail i[data-v-7e8f2146]{position:absolute;height:14px;width:14px;left:0;top:4px}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
||||||
.v-note-wrapper[data-v-348cd59e]{z-index:1000;min-height:580px}.post-thum .img[data-v-348cd59e]{width:100%;cursor:pointer;border-radius:4px}.post-thum .post-thum-remove[data-v-348cd59e]{margin-top:16px}
|
|
|
@ -1 +0,0 @@
|
||||||
.attach-detail-img img{width:100%}.attach-item{width:50%;margin:0 auto;position:relative;padding-bottom:28%;overflow:hidden;float:left;cursor:pointer}.attach-item img{width:100%;height:100%;position:absolute;top:0;left:0}@font-face{font-family:fontello;src:url(../fonts/fontello.e73a0647.eot);src:url(../fonts/fontello.e73a0647.eot#iefix) format("embedded-opentype"),url(../fonts/fontello.8d4a4e6f.woff2) format("woff2"),url(../fonts/fontello.a782baa8.woff) format("woff"),url(../fonts/fontello.068ca2b3.ttf) format("truetype"),url(../assets/fontello.9354499c.svg#fontello) format("svg");font-weight:400;font-style:normal}[class*=" fa-mavon-"]:before,[class^=fa-mavon-]:before{font-family:fontello;font-style:normal;font-weight:400;speak:none;display:inline-block;text-decoration:inherit;width:1em;margin-right:.2em;text-align:center;font-variant:normal;text-transform:none;line-height:1em;margin-left:.2em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-mavon-bold:before{content:"\E800"}.fa-mavon-italic:before{content:"\E801"}.fa-mavon-thumb-tack:before{content:"\E802"}.fa-mavon-link:before{content:"\E803"}.fa-mavon-picture-o:before{content:"\E804"}.fa-mavon-repeat:before{content:"\E805"}.fa-mavon-undo:before{content:"\E806"}.fa-mavon-trash-o:before{content:"\E807"}.fa-mavon-floppy-o:before{content:"\E808"}.fa-mavon-compress:before{content:"\E809"}.fa-mavon-eye:before{content:"\E80A"}.fa-mavon-eye-slash:before{content:"\E80B"}.fa-mavon-question-circle:before{content:"\E80C"}.fa-mavon-times:before{content:"\E80D"}.fa-mavon-align-left:before{content:"\E80F"}.fa-mavon-align-center:before{content:"\E810"}.fa-mavon-align-right:before{content:"\E811"}.fa-mavon-arrows-alt:before{content:"\F0B2"}.fa-mavon-bars:before{content:"\F0C9"}.fa-mavon-list-ul:before{content:"\F0CA"}.fa-mavon-list-ol:before{content:"\F0CB"}.fa-mavon-strikethrough:before{content:"\F0CC"}.fa-mavon-underline:before{content:"\F0CD"}.fa-mavon-table:before{content:"\F0CE"}.fa-mavon-columns:before{content:"\F0DB"}.fa-mavon-quote-left:before{content:"\F10D"}.fa-mavon-code:before{content:"\F121"}.fa-mavon-superscript:before{content:"\F12B"}.fa-mavon-subscript:before{content:"\F12C"}.fa-mavon-header:before{content:"\F1DC"}.fa-mavon-window-maximize:before{content:"\F2D0"}.markdown-body strong{font-weight:bolder}.markdown-body .hljs-center{text-align:center}.markdown-body .hljs-right{text-align:right}.markdown-body .hljs-left{text-align:left}
|
|
|
@ -1 +0,0 @@
|
||||||
body{height:100%;background-color:#f5f5f5}.container{background:#f7f7f7;position:absolute;top:45%;left:50%;margin:-160px 0 0 -160px;width:320px;padding:16px 32px 32px 32px;-webkit-box-shadow:-4px 7px 46px 2px rgba(0,0,0,.1);box-shadow:-4px 7px 46px 2px rgba(0,0,0,.1)}.loginLogo{margin-bottom:20px;text-align:center}.loginLogo span{vertical-align:text-bottom;font-size:36px;display:inline-block;font-weight:600;color:#1790fe;background-image:-webkit-gradient(linear,37.219838% 34.532506%,36.425669% 93.178216%,from(#36c8f5),to(#1790fe),color-stop(.37,#1790fe));-webkit-text-fill-color:transparent;-webkit-background-clip:text}
|
|
|
@ -1 +1 @@
|
||||||
<!DOCTYPE html><html lang=zh-cmn-Hans><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><meta name=robots content=noindex,nofllow><meta name=generator content=Halo><link rel=icon href=/logo.png><title>Halo Dashboard</title><link href=/css/chunk-0337f7a6.4c6b622f.css rel=prefetch><link href=/css/chunk-1079f749.94b473ad.css rel=prefetch><link href=/css/chunk-14e0b302.32f796a8.css rel=prefetch><link href=/css/chunk-161dc990.5ac5144c.css rel=prefetch><link href=/css/chunk-1be69b35.43c1fc12.css rel=prefetch><link href=/css/chunk-31c8ea42.4a090118.css rel=prefetch><link href=/css/chunk-5000e55c.7fb9bc61.css rel=prefetch><link href=/css/chunk-6d8b31f6.ad8d17b2.css rel=prefetch><link href=/css/chunk-81d936d8.05888d95.css rel=prefetch><link href=/css/chunk-b2d0b040.389eca76.css rel=prefetch><link href=/css/chunk-bb4f0d4a.c1990d7c.css rel=prefetch><link href=/css/chunk-bfd5bbcc.6a83ae7d.css rel=prefetch><link href=/css/chunk-c0a1d3c4.09186be6.css rel=prefetch><link href=/css/chunk-cec31564.6f053d75.css rel=prefetch><link href=/css/fail.809a6bc5.css rel=prefetch><link href=/js/chunk-0337f7a6.11326d77.js rel=prefetch><link href=/js/chunk-0ba750a2.b786c9db.js rel=prefetch><link href=/js/chunk-1079f749.ec67c7db.js rel=prefetch><link href=/js/chunk-142c8832.0f8270b3.js rel=prefetch><link href=/js/chunk-14e0b302.a86d1254.js rel=prefetch><link href=/js/chunk-161dc990.5de9313f.js rel=prefetch><link href=/js/chunk-1be69b35.81559bfc.js rel=prefetch><link href=/js/chunk-2d0b64bf.61d5d7c3.js rel=prefetch><link href=/js/chunk-2d0d65a2.2249765a.js rel=prefetch><link href=/js/chunk-2d21a35c.eda7a11a.js rel=prefetch><link href=/js/chunk-2d228d13.85b46532.js rel=prefetch><link href=/js/chunk-31c8ea42.0b2feab9.js rel=prefetch><link href=/js/chunk-5000e55c.3bd9ce3a.js rel=prefetch><link href=/js/chunk-5bf599cc.6555f060.js rel=prefetch><link href=/js/chunk-6d8b31f6.b64e5366.js rel=prefetch><link href=/js/chunk-81d936d8.8bec77ac.js rel=prefetch><link href=/js/chunk-87e2df70.0ada7d4e.js rel=prefetch><link href=/js/chunk-b2d0b040.b0d70d07.js rel=prefetch><link href=/js/chunk-bb4f0d4a.ef7d1ded.js rel=prefetch><link href=/js/chunk-bfd5bbcc.d2ca1e80.js rel=prefetch><link href=/js/chunk-c0a1d3c4.41d0d3f8.js rel=prefetch><link href=/js/chunk-cec31564.cfe3fd85.js rel=prefetch><link href=/js/fail.61f30b0f.js rel=prefetch><link href=/css/app.852293da.css rel=preload as=style><link href=/css/chunk-vendors.ee4e8dbf.css rel=preload as=style><link href=/js/app.29b04043.js rel=preload as=script><link href=/js/chunk-vendors.2f7bce79.js rel=preload as=script><link href=/css/chunk-vendors.ee4e8dbf.css rel=stylesheet><link href=/css/app.852293da.css rel=stylesheet></head><body><noscript><strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.2f7bce79.js></script><script src=/js/app.29b04043.js></script></body></html>
|
<!DOCTYPE html><html lang=zh-cmn-Hans><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><meta name=robots content=noindex,nofllow><meta name=generator content=Halo><link rel=icon href=/logo.png><title>Halo Dashboard</title><link href=/css/chunk-0337f7a6.4c6b622f.css rel=prefetch><link href=/css/chunk-0a078271.3df10fb3.css rel=prefetch><link href=/css/chunk-0d3fb064.5797d58a.css rel=prefetch><link href=/css/chunk-1021dac6.d511bd53.css rel=prefetch><link href=/css/chunk-14ae239d.e9de712a.css rel=prefetch><link href=/css/chunk-14e0b302.32f796a8.css rel=prefetch><link href=/css/chunk-1be69b35.43c1fc12.css rel=prefetch><link href=/css/chunk-2430dc8c.3592751a.css rel=prefetch><link href=/css/chunk-31c8ea42.4a090118.css rel=prefetch><link href=/css/chunk-3939e374.206f7b3f.css rel=prefetch><link href=/css/chunk-3b51c5ec.8e8c628e.css rel=prefetch><link href=/css/chunk-423b6722.dc42f304.css rel=prefetch><link href=/css/chunk-6d8b31f6.ad8d17b2.css rel=prefetch><link href=/css/chunk-71df32ec.5ac5144c.css rel=prefetch><link href=/css/chunk-7af5ef16.684c5100.css rel=prefetch><link href=/css/chunk-aa61da20.bb28474a.css rel=prefetch><link href=/css/chunk-b2e922b4.35a0ae16.css rel=prefetch><link href=/css/chunk-bb4f0d4a.c1990d7c.css rel=prefetch><link href=/css/fail.809a6bc5.css rel=prefetch><link href=/js/chunk-0337f7a6.363f14d6.js rel=prefetch><link href=/js/chunk-0a078271.82e60fe7.js rel=prefetch><link href=/js/chunk-0ba750a2.43dc1b14.js rel=prefetch><link href=/js/chunk-0d3fb064.5a2b4eaa.js rel=prefetch><link href=/js/chunk-1021dac6.8b7c9616.js rel=prefetch><link href=/js/chunk-14ae239d.d15f85b1.js rel=prefetch><link href=/js/chunk-14e0b302.f32c7cb3.js rel=prefetch><link href=/js/chunk-1be69b35.399a467a.js rel=prefetch><link href=/js/chunk-2430dc8c.9c9f8538.js rel=prefetch><link href=/js/chunk-2d0b64bf.ed671024.js rel=prefetch><link href=/js/chunk-2d0d65a2.2f8a16de.js rel=prefetch><link href=/js/chunk-2d21a35c.69287534.js rel=prefetch><link href=/js/chunk-2d228d13.75eca9d7.js rel=prefetch><link href=/js/chunk-31c8ea42.7133cb21.js rel=prefetch><link href=/js/chunk-3939e374.cb5da37a.js rel=prefetch><link href=/js/chunk-3b51c5ec.80a40c78.js rel=prefetch><link href=/js/chunk-423b6722.af6d6aaa.js rel=prefetch><link href=/js/chunk-6d8b31f6.db21019b.js rel=prefetch><link href=/js/chunk-71df32ec.a5429fe8.js rel=prefetch><link href=/js/chunk-7af5ef16.6ad0d11c.js rel=prefetch><link href=/js/chunk-aa61da20.c3df7494.js rel=prefetch><link href=/js/chunk-b2e922b4.32665c80.js rel=prefetch><link href=/js/chunk-bb4f0d4a.4e789394.js rel=prefetch><link href=/js/fail.e23b7151.js rel=prefetch><link href=/css/app.05b5cd85.css rel=preload as=style><link href=/css/chunk-vendors.ee4e8dbf.css rel=preload as=style><link href=/js/app.f0c2e6d9.js rel=preload as=script><link href=/js/chunk-vendors.2f7bce79.js rel=preload as=script><link href=/css/chunk-vendors.ee4e8dbf.css rel=stylesheet><link href=/css/app.05b5cd85.css rel=stylesheet></head><body><noscript><strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.2f7bce79.js></script><script src=/js/app.f0c2e6d9.js></script></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue