Merge pull request #2 from ruibaby/dev

Merge dev branch of upstream
pull/87/head
John Niang 2019-01-30 16:59:42 +08:00 committed by GitHub
commit c06fcf4f0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
653 changed files with 12558 additions and 20572 deletions

18
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,18 @@
<!--
如果你不认真勾选下面的内容,我可能会直接关闭你的 Issue。
提问之前,建议先阅读 https://github.com/ruby-china/How-To-Ask-Questions-The-Smart-Way
-->
**我确定我已经查看了** (标注`[ ]`为`[x]`)
- [ ] [Halo 使用文档](https://docs.halo.run/)
- [ ] [Github Wiki 常见问题](https://github.com/ruibaby/halo/wiki/4.-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98)
- [ ] [其他 Issues](https://github.com/ruibaby/halo/issues)
----
**我要申请** (标注`[ ]`为`[x]`)
- [ ] BUG 反馈
- [ ] 添加新的特性或者功能
- [ ] 请求技术支持

View File

@ -1,12 +1,17 @@
FROM maven:3
FROM maven:3-jdk-8-alpine
LABEL maintainer="Ryan Wang<i@ryanc.cc>"
WORKDIR /opt/halo
ADD . /tmp
ENV TZ=Asia/Shanghai \
DB_USER="admin" \
DB_PASSWORD="123456"
RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} > /etc/timezone
RUN cd /tmp && mvn package -Pci && mv target/dist/halo/* /opt/halo/ \
&& rm -rf /tmp/* && rm -rf ~/.m2
EXPOSE 8090
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/opt/halo/halo-latest.jar","--spring.profiles.active=docker"]
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/opt/halo/halo-latest.jar","--spring.datasource.username=${DB_USER}","--spring.datasource.password=${DB_PASSWORD}"]

149
README-en_US.md Normal file
View File

@ -0,0 +1,149 @@
![](https://i.loli.net/2018/12/21/5c1cd34849751.png)
> 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: 162747721Telegram 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 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
```
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
# TipsDB_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
```
> 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/ruibaby/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/ruibaby/vno-halo) - From Jekyll,Author [Wei Wang](https://onevcat.com/).
- [Hux](https://github.com/ruibaby/hux-halo) - From Jekyll,Author [Xuan Huang](https://huangxuan.me/).
- [Story](https://github.com/ruibaby/story-halo) - From Typecho,Author [Trii Hsia](https://yumoe.com/).
- [NexT](https://github.com/ruibaby/next-halo) - From Hexo,Author [iissnan](https://notes.iissnan.com/).
- [Casper](https://github.com/ruibaby/casper-halo) - From Ghost,Author [Ghost](https://github.com/TryGhost).
- [Pinghsu](https://github.com/ruibaby/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
[![license](https://img.shields.io/github/license/ruibaby/halo.svg?style=flat-square)](https://github.com/ruibaby/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
- [OwO](https://github.com/DIYgod/OwO): front-end expression library
## 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
![](https://i.loli.net/2018/12/16/5c15b6edb9a49.png)
![](https://i.loli.net/2018/12/16/5c15b6ee08333.png)
![](https://i.loli.net/2018/12/16/5c15b6ec853af.png)
![](https://i.loli.net/2018/12/16/5c15b6ec50238.png)
![](https://i.loli.net/2018/12/16/5c15b6ed4057a.png)
![](https://i.loli.net/2018/12/16/5c15b6eb01f2d.png)
![](https://i.loli.net/2018/12/16/5c15b6eb98898.png)
![](https://i.loli.net/2018/12/16/5c15b6eb3b506.png)
![](https://i.loli.net/2018/12/16/5c15b6ebf29fd.png)

164
README.md
View File

@ -1,70 +1,77 @@
<h1>
<a href="#" target="_blank">Halo</a>
</h1>
![](https://i.loli.net/2018/12/21/5c1cd34849751.png)
> Halo可能是最好的Java博客系统。
> Halo 可能是最好的 Java 博客系统。
[![JDK](https://img.shields.io/badge/JDK-1.8-yellow.svg)](#)
[![GitHub release](https://img.shields.io/github/release/ruibaby/halo.svg)](https://github.com/ruibaby/halo/releases)
[![Travis CI](https://img.shields.io/travis/ruibaby/halo.svg)](https://travis-ci.org/ruibaby/halo)
[![Docker Build Status](https://img.shields.io/docker/build/ruibaby/halo.svg)](https://hub.docker.com/r/ruibaby/halo/)
<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>
------------------------------
🇨🇳简体中文 | 🇺🇸[English](./docs/README-en-US.md) | <img src="https://lipis.github.io/flag-icon-css/flags/4x3/tr.svg" alt="Turkish" height="14"/> [Türkçe](./docs/README-tr.md)
## 目录
- [简介](#简介)
- [快速开始](#快速开始)
- [演示](#演示)
- [下载部署](#下载部署)
- [文档](#文档)
- [主题](#主题)
- [许可证](#许可证)
- [后续功能](#后续功能)
- [感谢](#感谢)
- [捐赠](#捐赠)
🇨🇳简体中文 | 🇺🇸[English](README-en_US.md)
## 简介
**Halo** [ˈheɪloʊ],意为光环。当然,你也可以当成拼音读(哈喽)。
轻快简洁功能强大使用Java开发的博客系统。
轻快,简洁,功能强大,使用 Java 开发的博客系统。
> QQ交流群: 162747721Telegram交流群[https://t.me/HaloBlog](https://t.me/HaloBlog)
> QQ 交流群: 162747721 | Telegram 交流群:[https://t.me/HaloBlog](https://t.me/HaloBlog) | Telegram 频道:[https://t.me/halo_dev](https://t.me/halo_dev) | [WeHalo 小程序](https://github.com/aquanlerou/WeHalo)。
## 演示站点
> 前台地址:[https://demo.halo.run](https://demo.halo.run)
> 后台地址:[https://demo.halo.run/admin](https://demo.halo.run/admin)
> 用户名admin密码123456
## 快速开始
```bash
git clone https://github.com/ruibaby/halo.git
cd halo
mvn clean package -Pprod
java -jar target/dist/halo/halo-latest.jar
```
服务器快速部署:
```bash
# 安装Halo
yum install -y wget && wget https://git.io/fxHqp && bash halo-cli.sh -i
# 更新Halo
bash halo-cli.sh -u
# 安装 Halo
$ yum install -y wget && wget -O halo-cli.sh https://git.io/fxHqp && bash halo-cli.sh -i
# 更新 Halo
$ bash halo-cli.sh -u
```
Docker 部署:
```bash
# 拉取镜像
docker pull ruibaby/halo
$ docker pull ruibaby/halo
# 运行
docker run -d --name halo -p 8090:8090 -v ~/halo:/root/halo ruibaby/halo
$ docker run -d --name halo -p 8090:8090 -v ~/halo:/root/halo -e DB_USER=root -e DB_PASSWORD=123456 ruibaby/halo
# 注意DB_USER 和 DB_PASSWORD 务必修改并记下
```
> 注意如使用IdeaEclipse等IDE运行的话需要安装Lombok插件另外暂不支持JDK10主题扫描和上传会有问题。
Docker Compose 部署:
```bash
# 下载 Nginx 配置文件模板
$ curl https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl > /etc/nginx/nginx.tmpl
Let's start: http://localhost:8090
# 获取 docker-compose.yaml 文件
$ yum install -y wget && wget -O docker-compose.yaml https://git.io/fpS8N
## 演示
# 修改 docker-compose.yaml
# 1. 修改 VIRTUAL_HOST,LETSENCRYPT_HOST 为自己的域名。
# 2. 修改 LETSENCRYPT_EMAIL 为自己的邮箱。
# 3. 修改 DB_USER 数据库用户名,注意:这是自定义的,请不要使用默认的!下面数据库密码同理。
# 4. 修改 DB_PASSWORD 数据库密码。
# 运行
$ docker-compose up -d
```
> 注意:如使用 IdeaEclipse 等IDE运行的话需要安装Lombok插件另外暂不支持JDK10主题管理和主题上传会有问题。
> 更多请参考[ Halo 使用文档 ](https://halo-doc.ryanc.cc/installation/)或者[ Wiki](https://github.com/ruibaby/halo/wiki)。
## 博客示例
[Ryan0up'S Blog](https://ryanc.cc)
@ -74,73 +81,68 @@ Let's start: http://localhost:8090
[KingYiFan'S Blog](https://blog.cnbuilder.cn)
## 下载部署
> 如需部署到服务器,请参考[Halo部署教程](https://halo-doc.ryanc.cc/installation/)或者[Wiki](https://github.com/ruibaby/halo/wiki)。
## 文档
[Halo Document](https://halo-doc.ryanc.cc)
> 文档正在不断完善中。
[AquanBlog](https://blog.eunji.cn/)
## 主题
除了内置的[Anatole](https://github.com/hi-caicai/farbox-theme-Anatole)和[Material](https://github.com/viosey/hexo-theme-material),还有下列主题没有集成在项目里,如有需要,请自行下载之后通过后台上传上去使用。
除了内置的 [Anatole](https://github.com/hi-caicai/farbox-theme-Anatole) 和 [Material](https://github.com/viosey/hexo-theme-material) ,还有下列主题没有集成在项目里,如有需要,请自行下载之后通过后台上传上去使用。
- [Vno](https://github.com/ruibaby/vno-halo) - 来自Jekyll的一款主题作者[Wei Wang](https://onevcat.com/)。
- [Hux](https://github.com/ruibaby/hux-halo) - 来自Jekyll的一款主题作者[Xuan Huang](https://huangxuan.me/)。
- [Story](https://github.com/ruibaby/story-halo) - 来自Typecho的一款主题作者[Trii Hsia](https://yumoe.com/)。
- [NexT](https://github.com/ruibaby/next-halo) - 来自Hexo的一款主题作者[iissnan](https://notes.iissnan.com/)。
- [Casper](https://github.com/ruibaby/casper-halo) - 来自Ghost的一款主题作者[Ghost](https://github.com/TryGhost)。
- [Vno](https://github.com/ruibaby/vno-halo) - 来自 Jekyll 的一款主题,作者 [Wei Wang](https://onevcat.com/)。
- [Hux](https://github.com/ruibaby/hux-halo) - 来自 Jekyll 的一款主题,作者 [Xuan Huang](https://huangxuan.me/)。
- [Story](https://github.com/ruibaby/story-halo) - 来自 Typecho 的一款主题,作者 [Trii Hsia](https://yumoe.com/)。
- [NexT](https://github.com/ruibaby/next-halo) - 来自 Hexo 的一款主题,作者 [iissnan](https://notes.iissnan.com/)。
- [Casper](https://github.com/ruibaby/casper-halo) - 来自 Ghost 的一款主题,作者 [Ghost](https://github.com/TryGhost)。
- [Pinghsu](https://github.com/ruibaby/pinghsu-halo) - 来自 Typecho 的一款主题,作者 [Chakhsu.Lau](https://github.com/chakhsu)。
> 声明:不接受任何对**移植主题**功能上的意见和建议。
## 许可证
[![license](https://img.shields.io/github/license/ruibaby/halo.svg)](https://github.com/ruibaby/halo/blob/master/LICENSE)
[![license](https://img.shields.io/github/license/ruibaby/halo.svg?style=flat-square)](https://github.com/ruibaby/halo/blob/master/LICENSE)
> Halo使用GPL-v3.0协议开源,请尽量遵守开源协议,即便是在中国。
## 后续功能
- [x] 文章阅读统计
- [ ] 文章顶置
- [ ] 集成又拍云,七牛云等云服务
> Halo 使用 GPL-v3.0 协议开源,请尽量遵守开源协议,即便是在中国。
## 感谢
Halo的诞生离不开下面这些项目
Halo 的诞生离不开下面这些项目:
- [IntelliJ IDEA](https://www.jetbrains.com/idea/)个人认为最强大的Java IDE没有之一
- [Spring Boot](https://github.com/spring-projects/spring-boot)Spring的微服务框架
- [Spring Boot](https://github.com/spring-projects/spring-boot)Spring 的快速开发框架
- [Freemarker](https://freemarker.apache.org/):模板引擎,使页面静态化
- [H2 Database](https://github.com/h2database/h2database):嵌入式数据库,无需安装
- [Druid](https://github.com/alibaba/druid):阿里开发的连接池
- [Spring-data-jpa](https://github.com/spring-projects/spring-data-jpa.git)不需要写sql语句的持久层框架
- [Spring-data-jpa](https://github.com/spring-projects/spring-data-jpa.git):不需要写 sql 语句的持久层框架
- [Ehcache](http://www.ehcache.org/):缓存框架
- [Lombok](https://www.projectlombok.org/):让代码更简洁
- [oh-my-email](https://github.com/biezhi/oh-my-email)可能是最小的Java邮件发送库了支持抄送、附件、模板等
- [Hutool](https://github.com/looly/hutool)一个Java基础工具类库
- [oh-my-email](https://github.com/biezhi/oh-my-email):可能是最小的 Java 邮件发送库了,支持抄送、附件、模板等
- [Hutool](https://github.com/looly/hutool):一个 Java 基础工具类库
- [Thumbnailator](https://github.com/coobird/thumbnailator):缩略图生成库
- [AdminLTE](https://github.com/almasaeed2010/AdminLTE)基于Bootstrap的后台模板
- [Bootstrap](https://github.com/twbs/bootstrap.git)使用最广泛的前端ui框架
- [Animate](https://github.com/daneden/animate.css.git)非常好用的css动效库
- [SimpleMDE - Markdown Editor](https://github.com/sparksuite/simplemde-markdown-editor)简洁功能够用且轻量级的Markdown编辑器
- [Bootstrap-FileInput](https://github.com/kartik-v/bootstrap-fileinput.git)个人认为最好用的上传组件,没有之一
- [AdminLTE](https://github.com/almasaeed2010/AdminLTE):基于 Bootstrap 的后台模板
- [Bootstrap](https://github.com/twbs/bootstrap.git):使用最广泛的前端 ui 框架
- [Animate](https://github.com/daneden/animate.css.git):非常好用的 css 动效库
- [SimpleMDE - Markdown Editor](https://github.com/sparksuite/simplemde-markdown-editor):简洁,功能够用,且轻量级的 Markdown 编辑器
- [Bootstrap-FileInput](https://github.com/kartik-v/bootstrap-fileinput.git)基于 Bootstrap 的文件上传组件
- [Font-awesome](https://github.com/FortAwesome/Font-Awesome.git):使用最广泛的字体图标库
- [Jquery](https://github.com/jquery/jquery.git)使用最广泛的JavaScript框架
- [JQuery](https://github.com/jquery/jquery.git):使用最广泛的 JavaScript 框架
- [Layer](https://github.com/sentsin/layer.git):个人认为最实用最好看的弹出层组件,没有之一
- [Jquery-Toast](https://github.com/kamranahmedse/jquery-toast-plugin):消息提示组件
- [JQuery-Toast](https://github.com/kamranahmedse/jquery-toast-plugin):消息提示组件
- [Pjax](https://github.com/defunkt/jquery-pjax.git)pushState + ajax = pjax
- [OwO](https://github.com/DIYgod/OwO):前端表情库
## 捐赠
> 如果Halo对你有帮助可以请作者喝瓶娃哈哈哈哈哈哈哈哈哈哈
> 如果 Halo 对你有帮助,可以请作者喝杯☕️
| 支付宝 | 微信 | 支付宝红包 |
| :------------: | :------------: | :------------: |
| <img src="https://cdn.ryanc.cc/img/github/donate/alipay.png" width="150"/> | <img src="https://cdn.ryanc.cc/img/github/donate/wechat.png" width="150" /> | <img src="https://cdn.ryanc.cc/img/github/donate/hongbao.png" width="150" /> |
| 支付宝/微信/QQ |
| :------------: |
| <img src="https://i.loli.net/2018/12/23/5c1f68ce9b884.png" width="200"/> |
## 界面展示
![](https://i.loli.net/2018/12/16/5c15b6edb9a49.png)
![](https://i.loli.net/2018/12/16/5c15b6ee08333.png)
![](https://i.loli.net/2018/12/16/5c15b6ec853af.png)
![](https://i.loli.net/2018/12/16/5c15b6ec50238.png)
![](https://i.loli.net/2018/12/16/5c15b6ed4057a.png)
![](https://i.loli.net/2018/12/16/5c15b6eb01f2d.png)
![](https://i.loli.net/2018/12/16/5c15b6eb98898.png)
![](https://i.loli.net/2018/12/16/5c15b6eb3b506.png)
![](https://i.loli.net/2018/12/16/5c15b6ebf29fd.png)

View File

@ -1 +0,0 @@
theme: jekyll-theme-architect

View File

@ -19,6 +19,6 @@ mvn package -Pprod
cd $HALO_DIR/target/dist/halo
# 运行Halo
nohup java -server -Xms256m -Xmx512m -jar `find ./ -name "halo*.jar"` > /dev/null 2>&1 &
nohup java -server -jar `find ./ -name "halo*.jar"` > /dev/null 2>&1 &
echo "Halo部署完毕Enjoy"

55
docker-compose.yaml Normal file
View File

@ -0,0 +1,55 @@
version: '2'
services:
nginx:
restart: always
image: nginx
container_name: nginx
ports:
- 80:80
- 443:443
volumes:
- /etc/nginx/conf.d:/etc/nginx/conf.d
- /etc/nginx/vhost.d:/etc/nginx/vhost.d
- /usr/share/nginx/html:/usr/share/nginx/html
- /etc/nginx/certs:/etc/nginx/certs:ro
halo:
restart: always
image: ruibaby/halo
container_name: halo
ports:
- 8090:8090
environment:
- VIRTUAL_PORT=8090
- VIRTUAL_HOST=localhost # 监听的地址(务必修改)
- LETSENCRYPT_HOST=localhost # 证书的域名 (务必修改)
- LETSENCRYPT_EMAIL=i@example.com # 证书所有者的邮箱,快过期时会提醒(务必修改)
- DB_USER=admin # h2数据库用户名自定义务必修改
- DB_PASSWORD=123456 # h2数据库密码自定义务必修改
volumes:
- ~/halo:/root/halo
docker-gen:
restart: always
image: jwilder/docker-gen
container_name: docker-gen
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- /etc/nginx/nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro
volumes_from:
- nginx
entrypoint: /usr/local/bin/docker-gen -notify-sighup nginx -watch -wait 5s:30s
/etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
letsencrypt-nginx-proxy-companion:
restart: always
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: letsencrypt-nginx-proxy-companion
volumes_from:
- nginx
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /etc/nginx/certs:/etc/nginx/certs:rw
environment:
- NGINX_DOCKER_GEN_CONTAINER=docker-gen

View File

@ -1,141 +0,0 @@
<h1>
<a href="#" target="_blank">Halo</a>
</h1>
> Halo may be the best Java blog system.
[![JDK](https://img.shields.io/badge/JDK-1.8-yellow.svg)](#)
[![GitHub release](https://img.shields.io/github/release/ruibaby/halo.svg)](https://github.com/ruibaby/halo/releases)
[![Travis CI](https://img.shields.io/travis/ruibaby/halo.svg)](https://travis-ci.org/ruibaby/halo)
[![Docker Build Status](https://img.shields.io/docker/build/ruibaby/halo.svg)](https://hub.docker.com/r/ruibaby/halo/)
------------------------------
🇨🇳[简体中文](../README.md) | 🇺🇸English | <img src="https://lipis.github.io/flag-icon-css/flags/4x3/tr.svg" alt="Turkish" height="14"/> [Türkçe](./README-tr.md)
## Catalog
- [Introduction](#introduction)
- [Quickstart](#quickstart)
- [Demo](#demo)
- [Download](#download)
- [Docs](#docs)
- [Themes](#themes)
- [License](#license)
- [Todo](#todo)
- [Thanks](#thanks)
- [Donate](#donate)
## Introduction
**Halo** [ˈheɪloʊ],Become the best blogging system using Java.
Fast, concise, and powerful blogging system developed in Java.
> QQ Group: 162747721Telegram Group[https://t.me/HaloBlog](https://t.me/HaloBlog)
## Quickstart
```bash
git clone https://github.com/ruibaby/halo.git
cd halo
mvn clean package -Pprod
java -jar target/dist/halo/halo-latest.jar
```
Rapid server deployment:
```bash
# Install Halo
yum install -y wget && wget https://git.io/fxHqp && bash halo-cli.sh -i
# Upgrade Halo
bash halo-cli.sh -u
```
Docker
```bash
# Pull image
docker pull ruibaby/halo
# run
docker run -d --name halo -p 8090:8090 -v ~/halo:/root/halo ruibaby/halo
```
> Note: 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.
Let's start: http://localhost:8090
## Demo
[Ryan0up'S Blog](https://ryanc.cc)
[SNAIL BLOG](https://slogc.cc)
[宋浩志博客](http://songhaozhi.com)
[KingYiFan'S Blog](https://blog.cnbuilder.cn)
## Download
> For deployment to the server, please refer to [Halo部署教程](https://halo-doc.ryanc.cc/installation/) or [Wiki](https://github.com/ruibaby/halo/wiki).
## Docs
[Halo Document](https://halo-doc.ryanc.cc)
> The documentation is constantly being improved.
## 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/ruibaby/vno-halo) - From Jekyll,Author [Wei Wang](https://onevcat.com/)。
- [Hux](https://github.com/ruibaby/hux-halo) - From Jekyll,Author [Xuan Huang](https://huangxuan.me/)。
- [Story](https://github.com/ruibaby/story-halo) - From Typecho,Author [Trii Hsia](https://yumoe.com/)。
- [NexT](https://github.com/ruibaby/next-halo) - From Hexo,Author [iissnan](https://notes.iissnan.com/)。
- [Casper](https://github.com/ruibaby/casper-halo) - From Ghost,Author [Ghost](https://github.com/TryGhost)。
> Disclaimer: Do not accept any comments or suggestions on the functionality of the **Porting Theme**.
## License
[![license](https://img.shields.io/github/license/ruibaby/halo.svg)](https://github.com/ruibaby/halo/blob/master/LICENSE)
> Halo uses the GPL-v3.0 protocol to open source.
## Todo
- [x] Article reading statistics
- [ ] Article overhead
- [ ] Integrate cloud services such as Qiniu yun or Upyun
## Thanks
The birth of Halo is inseparable from the following projects:
- [IntelliJ IDEA](https://www.jetbrains.com/idea/)Personally think that the most powerful Java IDE.
- [Spring Boot](https://github.com/spring-projects/spring-boot)Spring's microservices framework.
- [Freemarker](https://freemarker.apache.org/)Template engine to make the page static.
- [H2 Database](https://github.com/h2database/h2database)Embedded database, no need to install.
- [Druid](https://github.com/alibaba/druid)Database connection pool developed by Alibaba.
- [Spring-data-jpa](https://github.com/spring-projects/spring-data-jpa.git)Do not need to write a sql script persistence layer framework.
- [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 base tool library.
- [Thumbnailator](https://github.com/coobird/thumbnailator)Thumbnail generation library.
- [AdminLTE](https://github.com/almasaeed2010/AdminLTE)Background template based on Bootstrap.
- [Bootstrap](https://github.com/twbs/bootstrap.git)Use the most extensive front-end ui framework.
- [Animate](https://github.com/daneden/animate.css.git)Very easy to use css motion 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)Personally think that the best 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)Use the widest range of JavaScript frameworks.
- [Layer](https://github.com/sentsin/layer.git)Personally think that the most practical and best-looking pop-up layer components.
- [Jquery-Toast](https://github.com/kamranahmedse/jquery-toast-plugin)Message prompt component.
- [Pjax](https://github.com/defunkt/jquery-pjax.git)pushState + ajax = pjax.****
- [OwO](https://github.com/DIYgod/OwO)Front-end expression library.
## Donate
| Alipay | Wechat | Alipay Red envelope |
| :------------: | :------------: | :------------: |
| <img src="https://cdn.ryanc.cc/img/github/donate/alipay.png" width="150"/> | <img src="https://cdn.ryanc.cc/img/github/donate/wechat.png" width="150" /> | <img src="https://cdn.ryanc.cc/img/github/donate/hongbao.png" width="150" /> |

View File

@ -1,142 +0,0 @@
<h1>
<a href="#" target="_blank">Halo</a>
</h1>
> Halo, bir Java blog sistemidir.
[![JDK](https://img.shields.io/badge/JDK-1.8-yellow.svg)](#)
[![GitHub release](https://img.shields.io/github/release/ruibaby/halo.svg)](https://github.com/ruibaby/halo/releases)
[![Travis CI](https://img.shields.io/travis/ruibaby/halo.svg)](https://travis-ci.org/ruibaby/halo)
[![Docker Build Status](https://img.shields.io/docker/build/ruibaby/halo.svg)](https://hub.docker.com/r/ruibaby/halo/)
------------------------------
🇨🇳[简体中文](../README.md) | 🇺🇸[English](./README-en-US.md) | <img src="https://lipis.github.io/flag-icon-css/flags/4x3/tr.svg" alt="Turkish" height="14"/> Türkçe
## Katalog
- [Giriş](#giris)
- [Hemen Başla](#hemen-başla)
- [Demo](#demo)
- [İndir](#İndir)
- [Dökümanlar](#dökümanlar)
- [Temalar](#temalar)
- [Lisans](#lisans)
- [Yapılacaklar Listesi](#yapılacaklar-listesi)
- [Teşekkür](#teşekkür)
- [Bağışlar](#bağışlar)
## Giriş
**Halo** [ˈheɪloʊ], Java kullanan en iyi blog sistemi olma yolunda.
Hızlı, öz ve güçlü bir blog sistemi.
> QQ Grup: 162747721Telegram Grup[https://t.me/HaloBlog](https://t.me/HaloBlog)
## Hemen Başla
```bash
git clone https://github.com/ruibaby/halo.git
cd halo
mvn clean package -Pprod
java -jar target/dist/halo/halo-latest.jar
```
Rapid server deploy etme:
```bash
# Install Halo
yum install -y wget && wget https://git.io/fxHqp && bash halo-cli.sh -i
# Upgrade Halo
bash halo-cli.sh -u
```
Docker
```bash
# Pull image
docker pull ruibaby/halo
# run
docker run -d --name halo -p 8090:8090 -v ~/halo:/root/halo ruibaby/halo
```
> Not: Eğer çalıştırmak için Idea, Eclipse ve diğer IDE leri kullanırsanız, Lombok eklentisini yüklemeniz gerekir. Ayrıca JDK 10 şu anda desteklenmiyor ve temaların taranması ve yüklenmesi ile ilgili sorunlar var.
Hadi başlayalım: http://localhost:8090
## Demo
[Ryan0up'nın Bloğu](https://ryanc.cc)
[SNAIL'in Bloğu](https://slogc.cc)
[宋浩志博客](http://songhaozhi.com)
[KingYiFan'ın Bloğu](https://blog.cnbuilder.cn)
## İndir
> Sunucuya deploy etmek için gözat: [Halo部署教程](https://halo-doc.ryanc.cc/installation/) veya [Wiki](https://github.com/ruibaby/halo/wiki).
## Dökümanlar
[Halo Dökümanları](https://halo-doc.ryanc.cc)
> Dökümanlar sürekli geliştirilme aşamasındadır.
## Temalar
Ön bilgi olarak [Anatole](https://github.com/hi-caicai/farbox-theme-Anatole) ve [Material](https://github.com/viosey/hexo-theme-material) temları projeye entegre edilmedi. Eğer kullanmak isterseniz indirip arkaplanda yükleyebilirsiniz.
- [Vno](https://github.com/ruibaby/vno-halo) - Jekyll, Geliştirici [Wei Wang](https://onevcat.com/)。
- [Hux](https://github.com/ruibaby/hux-halo) - Jekyll, Geliştirici [Xuan Huang](https://huangxuan.me/)。
- [Story](https://github.com/ruibaby/story-halo) - Typecho, Geliştirici [Trii Hsia](https://yumoe.com/)。
- [NexT](https://github.com/ruibaby/next-halo) - Hexo, Geliştirici [iissnan](https://notes.iissnan.com/)。
- [Casper](https://github.com/ruibaby/casper-halo) - Ghost, Geliştirici [Ghost](https://github.com/TryGhost)。
> **Porting Theme**'nın işlevselliği ile ilgili yorum ve öneri kabul edilmemektedir.
## Lisans
[![license](https://img.shields.io/github/license/ruibaby/halo.svg)](https://github.com/ruibaby/halo/blob/master/LICENSE)
> Halo, açık kaynak kod olarak GPL-v3.0 kullanmaktadır.
## Yapılacaklar Listesi
- [x] Makale okunma istatistikleri
- [ ] Makale üstü
- [ ] Qiniu ve Upyun gibi bulut servisleri entegresi
## Teşekkür
Halo'nun ortaya çıkışı aşağıdaki projelerle olmuştur:
- [IntelliJ IDEA](https://www.jetbrains.com/idea/)Kişisel görüş olarak en güçlü Java IDE si.
- [Spring Boot](https://github.com/spring-projects/spring-boot)Spring'in microservis frameworkü.
- [Freemarker](https://freemarker.apache.org/)Statik sayfa yapmak için şablon motoru.
- [H2 Database](https://github.com/h2database/h2database)Gömülü veritabanı, kurulum gerekmez.
- [Druid](https://github.com/alibaba/druid): Alibaba tarafından geliştirilen veritabanı bağlantı havuzu.
- [Spring-data-jpa](https://github.com/spring-projects/spring-data-jpa.git)Bir sql script katmanı yazmaya gerek yok.
- [Ehcache](http://www.ehcache.org/)Cache sistemi.
- [Lombok](https://www.projectlombok.org/)Kod basitleştirme.
- [oh-my-email](https://github.com/biezhi/oh-my-email)Belkide en küçük java e-posta kütüphanesi. (CC, Ek, şablon desteği).
- [Hutool](https://github.com/looly/hutool)Java tabanlı bir araç kütüphanesi.
- [Thumbnailator](https://github.com/coobird/thumbnailator)Küçük resim oluşturma kütüphanesi.
- [AdminLTE](https://github.com/almasaeed2010/AdminLTE)Bootstrap alt yapılı arka plan şablonu.
- [Bootstrap](https://github.com/twbs/bootstrap.git)En kapsamlı front-end ui çatısı.
- [Animate](https://github.com/daneden/animate.css.git)Kolay kullanımlı css kütüphanesi.
- [SimpleMDE - Markdown Editor](https://github.com/sparksuite/simplemde-markdown-editor)Markdown editor.
- [Bootstrap-FileInput](https://github.com/kartik-v/bootstrap-fileinput.git)Şahsen en iyi yükleme bileşeni olduğunu düşünyorum.
- [Font-awesome](https://github.com/FortAwesome/Font-Awesome.git)En çok kullanılan font simgesi kütüphanesi.
- [Jquery](https://github.com/jquery/jquery.git)Javascrip kullanımınızı genişletin.
- [Layer](https://github.com/sentsin/layer.git)Kişisel görüşüm en pratik ve en iyi görünen pop-up katman bileşeni.
- [Jquery-Toast](https://github.com/kamranahmedse/jquery-toast-plugin)Mesaj istemi bileşeni.
- [Pjax](https://github.com/defunkt/jquery-pjax.git)pushState + ajax = pjax.****
- [OwO](https://github.com/DIYgod/OwO)Front-end ifade kütüphanesi.
## Bağışlar
| Alipay | Wechat | Alipay Red envelope |
| :------------: | :------------: | :------------: |
| <img src="https://cdn.ryanc.cc/img/github/donate/alipay.png" width="150"/> | <img src="https://cdn.ryanc.cc/img/github/donate/wechat.png" width="150" /> | <img src="https://cdn.ryanc.cc/img/github/donate/hongbao.png" width="150" /> |

55
pom.xml
View File

@ -23,7 +23,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<version>2.1.2.RELEASE</version>
<relativePath/>
</parent>
@ -31,15 +31,15 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<oh-my-email.version>0.0.3</oh-my-email.version>
<lombok.version>1.18.2</lombok.version>
<ehcache.version>3.6.0</ehcache.version>
<oh-my-email.version>0.0.4</oh-my-email.version>
<lombok.version>1.18.4</lombok.version>
<ehcache.version>3.6.3</ehcache.version>
<rome.version>1.0</rome.version>
<hutool-all.version>4.1.19</hutool-all.version>
<hutool-all.version>4.4.2</hutool-all.version>
<upyun-java-sdk.version>4.0.1</upyun-java-sdk.version>
<qiniu-java-sdk.version>7.2.14</qiniu-java-sdk.version>
<qiniu-java-sdk.version>7.2.18</qiniu-java-sdk.version>
<thumbnailator.version>0.4.8</thumbnailator.version>
<jaxb-api.version>2.3.0</jaxb-api.version>
<commonmark.version>0.12.1</commonmark.version>
</properties>
<dependencies>
@ -55,12 +55,6 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
@ -152,6 +146,12 @@
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>${qiniu-java-sdk.version}</version>
<exclusions>
<exclusion>
<artifactId>okhttp</artifactId>
<groupId>com.squareup.okhttp3</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 图片操作 -->
@ -161,11 +161,21 @@
<version>${thumbnailator.version}</version>
</dependency>
<!-- jaxb-api-->
<!-- Markdown渲染 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb-api.version}</version>
<groupId>com.atlassian.commonmark</groupId>
<artifactId>commonmark</artifactId>
<version>${commonmark.version}</version>
</dependency>
<dependency>
<groupId>com.atlassian.commonmark</groupId>
<artifactId>commonmark-ext-gfm-tables</artifactId>
<version>${commonmark.version}</version>
</dependency>
<dependency>
<groupId>com.atlassian.commonmark</groupId>
<artifactId>commonmark-ext-yaml-front-matter</artifactId>
<version>${commonmark.version}</version>
</dependency>
</dependencies>
@ -198,7 +208,6 @@
</resource>
</resources>
<plugins>
<!-- 跳过单元测试不然打包的时候会因为加载不了application.yaml报错 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
@ -235,8 +244,6 @@
</execution>
</executions>
</plugin>
<!-- 打包成jar文件并指定lib文件夹以及resources资源文件夹 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
@ -273,7 +280,6 @@
</resource>
</resources>
<plugins>
<!-- 跳过单元测试不然打包的时候会因为加载不了application.yaml报错 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
@ -310,8 +316,6 @@
</execution>
</executions>
</plugin>
<!-- 打包成jar文件并指定lib文件夹以及resources资源文件夹 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
@ -345,6 +349,11 @@
<fork>true</fork>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</build>
</profile>

View File

@ -5,6 +5,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
/**
* <pre>
@ -17,6 +18,7 @@ import org.springframework.context.ApplicationContext;
@Slf4j
@SpringBootApplication
@EnableCaching
@EnableJpaAuditing
public class Application {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(Application.class, args);

View File

@ -1,7 +1,10 @@
package cc.ryanc.halo.config;
import cc.ryanc.halo.model.tag.ArticleTagDirective;
import cc.ryanc.halo.model.tag.CommonTagDirective;
import cc.ryanc.halo.model.freemarker.method.RandomMethod;
import cc.ryanc.halo.model.freemarker.method.RecentCommentsMethod;
import cc.ryanc.halo.model.freemarker.method.RecentPostsMethod;
import cc.ryanc.halo.model.freemarker.tag.ArticleTagDirective;
import cc.ryanc.halo.model.freemarker.tag.CommonTagDirective;
import cc.ryanc.halo.service.OptionsService;
import cc.ryanc.halo.service.UserService;
import freemarker.template.TemplateModelException;
@ -21,7 +24,7 @@ import javax.annotation.PostConstruct;
*/
@Slf4j
@Configuration
public class FreeMarkerConfig {
public class FreeMarkerAutoConfiguration {
@Autowired
private freemarker.template.Configuration configuration;
@ -38,6 +41,15 @@ public class FreeMarkerConfig {
@Autowired
private ArticleTagDirective articleTagDirective;
@Autowired
private RandomMethod randomMethod;
@Autowired
private RecentPostsMethod recentPostsMethod;
@Autowired
private RecentCommentsMethod recentCommentsMethod;
@PostConstruct
public void setSharedVariable() {
try {
@ -46,6 +58,9 @@ public class FreeMarkerConfig {
configuration.setSharedVariable("articleTag", articleTagDirective);
configuration.setSharedVariable("options", optionsService.findAllOptions());
configuration.setSharedVariable("user", userService.findUser());
configuration.setSharedVariable("randomMethod", randomMethod);
configuration.setSharedVariable("recentPostsMethod", recentPostsMethod);
configuration.setSharedVariable("recentCommentsMethod", recentCommentsMethod);
} catch (TemplateModelException e) {
log.error("Custom tags failed to load{}", e.getMessage());
}

View File

@ -1,243 +0,0 @@
package cc.ryanc.halo.config;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.Theme;
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.model.enums.TrueFalseEnum;
import cc.ryanc.halo.service.OptionsService;
import cc.ryanc.halo.utils.HaloUtils;
import cc.ryanc.halo.web.controller.core.BaseController;
import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.CronUtil;
import freemarker.template.TemplateModelException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <pre>
*
* </pre>
*
* @author : RYAN0UP
* @date : 2017/12/22
*/
@Slf4j
@Configuration
public class StartupConfig implements ApplicationListener<ApplicationStartedEvent> {
@Autowired
private OptionsService optionsService;
@Autowired
private freemarker.template.Configuration configuration;
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
try {
this.loadActiveTheme();
} catch (TemplateModelException e) {
e.printStackTrace();
}
this.loadOptions();
this.loadThemes();
this.loadOwo();
this.autoBackup();
}
/**
*
*/
private void loadActiveTheme() throws TemplateModelException {
String themeValue = optionsService.findOneOption(BlogPropertiesEnum.THEME.getProp());
if (StrUtil.isNotEmpty(themeValue) && !StrUtil.equals(themeValue, null)) {
BaseController.THEME = themeValue;
} else {
//以防万一
BaseController.THEME = "anatole";
}
configuration.setSharedVariable("themeName", BaseController.THEME);
}
/**
*
*/
private void loadOptions() {
Map<String, String> options = optionsService.findAllOptions();
if (options != null && !options.isEmpty()) {
HaloConst.OPTIONS = options;
}
}
/**
*
*/
private void loadThemes() {
HaloConst.THEMES.clear();
List<Theme> themes = HaloUtils.getThemes();
if (null != themes) {
HaloConst.THEMES = themes;
}
}
/**
*
*/
private void autoBackup() {
String autoBackup = optionsService.findOneOption(BlogPropertiesEnum.AUTO_BACKUP.getProp());
if (StrUtil.isNotEmpty(autoBackup) && StrUtil.equals(autoBackup, TrueFalseEnum.TRUE.getDesc())) {
//启动定时任务
CronUtil.start();
log.info("The scheduled task starts successfully!");
}
}
/**
* OwO
*/
private void loadOwo() {
Map<String, String> map = new HashMap<>(135);
map.put("@[nico]", "<img src='/static/plugins/OwO/paopao/nico.png' alt='nico.png' style='vertical-align: middle;'>");
map.put("@[OK]", "<img src='/static/plugins/OwO/paopao/OK.png' alt='OK.png' style='vertical-align: middle;'>");
map.put("@[what]", "<img src='/static/plugins/OwO/paopao/what.png' alt='what.png' style='vertical-align: middle;'>");
map.put("@[三道杠]", "<img src='/static/plugins/OwO/paopao/三道杠.png' alt='三道杠.png' style='vertical-align: middle;'>");
map.put("@[不高兴]", "<img src='/static/plugins/OwO/paopao/不高兴.png' alt='不高兴.png' style='vertical-align: middle;'>");
map.put("@[乖]", "<img src='/static/plugins/OwO/paopao/乖.png' alt='乖.png' style='vertical-align: middle;'>");
map.put("@[你懂的]", "<img src='/static/plugins/OwO/paopao/你懂的.png' alt='你懂的.png' style='vertical-align: middle;'>");
map.put("@[便便]", "<img src='/static/plugins/OwO/paopao/便便.png' alt='便便.png' style='vertical-align: middle;'>");
map.put("@[冷]", "<img src='/static/plugins/OwO/paopao/冷.png' alt='冷.png' style='vertical-align: middle;'>");
map.put("@[勉强]", "<img src='/static/plugins/OwO/paopao/勉强.png' alt='勉强.png' style='vertical-align: middle;'>");
map.put("@[吃瓜]", "<img src='/static/plugins/OwO/paopao/吃瓜.png' alt='吃瓜.png' style='vertical-align: middle;'>");
map.put("@[吃翔]", "<img src='/static/plugins/OwO/paopao/吃翔.png' alt='吃翔.png' style='vertical-align: middle;'>");
map.put("@[吐]", "<img src='/static/plugins/OwO/paopao/吐.png' alt='吐.png' style='vertical-align: middle;'>");
map.put("@[吐舌]", "<img src='/static/plugins/OwO/paopao/吐舌.png' alt='吐舌.png' style='vertical-align: middle;'>");
map.put("@[呀咩爹]", "<img src='/static/plugins/OwO/paopao/呀咩爹.png' alt='呀咩爹.png' style='vertical-align: middle;'>");
map.put("@[呵呵]", "<img src='/static/plugins/OwO/paopao/呵呵.png' alt='呵呵.png' style='vertical-align: middle;'>");
map.put("@[呼]", "<img src='/static/plugins/OwO/paopao/呼.png' alt='呼.png' style='vertical-align: middle;'>");
map.put("@[咦]", "<img src='/static/plugins/OwO/paopao/咦.png' alt='咦.png' style='vertical-align: middle;'>");
map.put("@[哈哈]", "<img src='/static/plugins/OwO/paopao/哈哈.png' alt='哈哈.png' style='vertical-align: middle;'>");
map.put("@[啊]", "<img src='/static/plugins/OwO/paopao/啊.png' alt='啊.png' style='vertical-align: middle;'>");
map.put("@[喷]", "<img src='/static/plugins/OwO/paopao/喷.png' alt='喷.png' style='vertical-align: middle;'>");
map.put("@[嘚瑟]", "<img src='/static/plugins/OwO/paopao/嘚瑟.png' alt='嘚瑟.png' style='vertical-align: middle;'>");
map.put("@[大拇指]", "<img src='/static/plugins/OwO/paopao/大拇指.png' alt='大拇指.png' style='vertical-align: middle;'>");
map.put("@[太开心]", "<img src='/static/plugins/OwO/paopao/太开心.png' alt='太开心.png' style='vertical-align: middle;'>");
map.put("@[太阳]", "<img src='/static/plugins/OwO/paopao/太阳.png' alt='太阳.png' style='vertical-align: middle;'>");
map.put("@[委屈]", "<img src='/static/plugins/OwO/paopao/委屈.png' alt='委屈.png' style='vertical-align: middle;'>");
map.put("@[小乖]", "<img src='/static/plugins/OwO/paopao/小乖.png' alt='小乖.png' style='vertical-align: middle;'>");
map.put("@[小红脸]", "<img src='/static/plugins/OwO/paopao/小红脸.png' alt='小红脸.png' style='vertical-align: middle;'>");
map.put("@[开心]", "<img src='/static/plugins/OwO/paopao/开心.png' alt='开心.png' style='vertical-align: middle;'>");
map.put("@[弱]", "<img src='/static/plugins/OwO/paopao/弱.png' alt='弱.png' style='vertical-align: middle;'>");
map.put("@[彩虹]", "<img src='/static/plugins/OwO/paopao/彩虹.png' alt='彩虹.png' style='vertical-align: middle;'>");
map.put("@[心碎]", "<img src='/static/plugins/OwO/paopao/心碎.png' alt='心碎.png' style='vertical-align: middle;'>");
map.put("@[怒]", "<img src='/static/plugins/OwO/paopao/怒.png' alt='怒.png' style='vertical-align: middle;'>");
map.put("@[惊哭]", "<img src='/static/plugins/OwO/paopao/惊哭.png' alt='惊哭.png' style='vertical-align: middle;'>");
map.put("@[惊恐]", "<img src='/static/plugins/OwO/paopao/惊恐.png' alt='惊恐.png' style='vertical-align: middle;'>");
map.put("@[惊讶]", "<img src='/static/plugins/OwO/paopao/惊讶.png' alt='惊讶.png' style='vertical-align: middle;'>");
map.put("@[懒得理]", "<img src='/static/plugins/OwO/paopao/懒得理.png' alt='懒得理.png' style='vertical-align: middle;'>");
map.put("@[手纸]", "<img src='/static/plugins/OwO/paopao/手纸.png' alt='手纸.png' style='vertical-align: middle;'>");
map.put("@[挖鼻]", "<img src='/static/plugins/OwO/paopao/挖鼻.png' alt='挖鼻.png' style='vertical-align: middle;'>");
map.put("@[捂嘴笑]", "<img src='/static/plugins/OwO/paopao/捂嘴笑.png' alt='捂嘴笑.png' style='vertical-align: middle;'>");
map.put("@[星星月亮]", "<img src='/static/plugins/OwO/paopao/星星月亮.png' alt='星星月亮.png' style='vertical-align: middle;'>");
map.put("@[汗]", "<img src='/static/plugins/OwO/paopao/汗.png' alt='汗.png' style='vertical-align: middle;'>");
map.put("@[沙发]", "<img src='/static/plugins/OwO/paopao/沙发.png' alt='沙发.png' style='vertical-align: middle;'>");
map.put("@[泪]", "<img src='/static/plugins/OwO/paopao/泪.png' alt='泪.png' style='vertical-align: middle;'>");
map.put("@[滑稽]", "<img src='/static/plugins/OwO/paopao/滑稽.png' alt='滑稽.png' style='vertical-align: middle;'>");
map.put("@[灯泡]", "<img src='/static/plugins/OwO/paopao/灯泡.png' alt='灯泡.png' style='vertical-align: middle;'>");
map.put("@[爱心]", "<img src='/static/plugins/OwO/paopao/爱心.png' alt='爱心.png' style='vertical-align: middle;'>");
map.put("@[犀利]", "<img src='/static/plugins/OwO/paopao/犀利.png' alt='犀利.png' style='vertical-align: middle;'>");
map.put("@[狂汗]", "<img src='/static/plugins/OwO/paopao/狂汗.png' alt='狂汗.png' style='vertical-align: middle;'>");
map.put("@[玫瑰]", "<img src='/static/plugins/OwO/paopao/玫瑰.png' alt='玫瑰.png' style='vertical-align: middle;'>");
map.put("@[生气]", "<img src='/static/plugins/OwO/paopao/生气.png' alt='生气.png' style='vertical-align: middle;'>");
map.put("@[疑问]", "<img src='/static/plugins/OwO/paopao/疑问.png' alt='疑问.png' style='vertical-align: middle;'>");
map.put("@[真棒]", "<img src='/static/plugins/OwO/paopao/真棒.png' alt='真棒.png' style='vertical-align: middle;'>");
map.put("@[睡觉]", "<img src='/static/plugins/OwO/paopao/睡觉.png' alt='睡觉.png' style='vertical-align: middle;'>");
map.put("@[礼物]", "<img src='/static/plugins/OwO/paopao/礼物.png' alt='礼物.png' style='vertical-align: middle;'>");
map.put("@[笑尿]", "<img src='/static/plugins/OwO/paopao/笑尿.png' alt='笑尿.png' style='vertical-align: middle;'>");
map.put("@[笑眼]", "<img src='/static/plugins/OwO/paopao/笑眼.png' alt='笑眼.png' style='vertical-align: middle;'>");
map.put("@[红领巾]", "<img src='/static/plugins/OwO/paopao/红领巾.png' alt='红领巾.png' style='vertical-align: middle;'>");
map.put("@[胜利]", "<img src='/static/plugins/OwO/paopao/胜利.png' alt='胜利.png' style='vertical-align: middle;'>");
map.put("@[花心]", "<img src='/static/plugins/OwO/paopao/花心.png' alt='花心.png' style='vertical-align: middle;'>");
map.put("@[茶杯]", "<img src='/static/plugins/OwO/paopao/茶杯.png' alt='茶杯.png' style='vertical-align: middle;'>");
map.put("@[药丸]", "<img src='/static/plugins/OwO/paopao/药丸.png' alt='药丸.png' style='vertical-align: middle;'>");
map.put("@[蛋糕]", "<img src='/static/plugins/OwO/paopao/蛋糕.png' alt='蛋糕.png' style='vertical-align: middle;'>");
map.put("@[蜡烛]", "<img src='/static/plugins/OwO/paopao/蜡烛.png' alt='蜡烛.png' style='vertical-align: middle;'>");
map.put("@[鄙视]", "<img src='/static/plugins/OwO/paopao/鄙视.png' alt='鄙视.png' style='vertical-align: middle;'>");
map.put("@[酷]", "<img src='/static/plugins/OwO/paopao/酷.png' alt='酷.png' style='vertical-align: middle;'>");
map.put("@[酸爽]", "<img src='/static/plugins/OwO/paopao/酸爽.png' alt='酸爽.png' style='vertical-align: middle;'>");
map.put("@[钱]", "<img src='/static/plugins/OwO/paopao/钱.png' alt='钱.png' style='vertical-align: middle;'>");
map.put("@[钱币]", "<img src='/static/plugins/OwO/paopao/钱币.png' alt='钱币.png' style='vertical-align: middle;'>");
map.put("@[阴险]", "<img src='/static/plugins/OwO/paopao/阴险.png' alt='阴险.png' style='vertical-align: middle;'>");
map.put("@[音乐]", "<img src='/static/plugins/OwO/paopao/音乐.png' alt='音乐.png' style='vertical-align: middle;'>");
map.put("@[香蕉]", "<img src='/static/plugins/OwO/paopao/香蕉.png' alt='香蕉.png' style='vertical-align: middle;'>");
map.put("@[黑线]", "<img src='/static/plugins/OwO/paopao/黑线.png' alt='黑线.png' style='vertical-align: middle;'>");
map.put("@(不出所料)", "<img src='/static/plugins/OwO/alu/不出所料.png' alt='不出所料.png' style='vertical-align: middle;'>");
map.put("@(不说话)", "<img src='/static/plugins/OwO/alu/不说话.png' alt='不说话.png' style='vertical-align: middle;'>");
map.put("@(不高兴)", "<img src='/static/plugins/OwO/alu/不高兴.png' alt='不高兴.png' style='vertical-align: middle;'>");
map.put("@(中刀)", "<img src='/static/plugins/OwO/alu/中刀.png' alt='中刀.png' style='vertical-align: middle;'>");
map.put("@(中指)", "<img src='/static/plugins/OwO/alu/中指.png' alt='中指.png' style='vertical-align: middle;'>");
map.put("@(中枪)", "<img src='/static/plugins/OwO/alu/中枪.png' alt='中枪.png' style='vertical-align: middle;'>");
map.put("@(亲亲)", "<img src='/static/plugins/OwO/alu/亲亲.png' alt='亲亲.png' style='vertical-align: middle;'>");
map.put("@(便便)", "<img src='/static/plugins/OwO/alu/便便.png' alt='便便.png' style='vertical-align: middle;'>");
map.put("@(傻笑)", "<img src='/static/plugins/OwO/alu/傻笑.png' alt='傻笑.png' style='vertical-align: middle;'>");
map.put("@(内伤)", "<img src='/static/plugins/OwO/alu/内伤.png' alt='内伤.png' style='vertical-align: middle;'>");
map.put("@(击掌)", "<img src='/static/plugins/OwO/alu/击掌.png' alt='击掌.png' style='vertical-align: middle;'>");
map.put("@(口水)", "<img src='/static/plugins/OwO/alu/口水.png' alt='口水.png' style='vertical-align: middle;'>");
map.put("@(吐)", "<img src='/static/plugins/OwO/alu/吐.png' alt='吐.png' style='vertical-align: middle;'>");
map.put("@(吐舌)", "<img src='/static/plugins/OwO/alu/吐舌.png' alt='吐舌.png' style='vertical-align: middle;'>");
map.put("@(吐血倒地)", "<img src='/static/plugins/OwO/alu/吐血倒地.png' alt='吐血倒地.png' style='vertical-align: middle;'>");
map.put("@(呲牙)", "<img src='/static/plugins/OwO/alu/呲牙.png' alt='呲牙.png' style='vertical-align: middle;'>");
map.put("@(咽气)", "<img src='/static/plugins/OwO/alu/咽气.png' alt='咽气.png' style='vertical-align: middle;'>");
map.put("@(哭泣)", "<img src='/static/plugins/OwO/alu/哭泣.png' alt='哭泣.png' style='vertical-align: middle;'>");
map.put("@(喜极而泣)", "<img src='/static/plugins/OwO/alu/喜极而泣.png' alt='喜极而泣.png' style='vertical-align: middle;'>");
map.put("@(喷水)", "<img src='/static/plugins/OwO/alu/喷水.png' alt='喷水.png' style='vertical-align: middle;'>");
map.put("@(喷血)", "<img src='/static/plugins/OwO/alu/喷血.png' alt='喷血.png' style='vertical-align: middle;'>");
map.put("@(坐等)", "<img src='/static/plugins/OwO/alu/坐等.png' alt='坐等.png' style='vertical-align: middle;'>");
map.put("@(大囧)", "<img src='/static/plugins/OwO/alu/大囧.png' alt='大囧.png' style='vertical-align: middle;'>");
map.put("@(害羞)", "<img src='/static/plugins/OwO/alu/害羞.png' alt='害羞.png' style='vertical-align: middle;'>");
map.put("@(小怒)", "<img src='/static/plugins/OwO/alu/小怒.png' alt='小怒.png' style='vertical-align: middle;'>");
map.put("@(小眼睛)", "<img src='/static/plugins/OwO/alu/小眼睛.png' alt='小眼睛.png' style='vertical-align: middle;'>");
map.put("@(尴尬)", "<img src='/static/plugins/OwO/alu/尴尬.png' alt='尴尬.png' style='vertical-align: middle;'>");
map.put("@(得意)", "<img src='/static/plugins/OwO/alu/得意.png' alt='得意.png' style='vertical-align: middle;'>");
map.put("@(惊喜)", "<img src='/static/plugins/OwO/alu/惊喜.png' alt='惊喜.png' style='vertical-align: middle;'>");
map.put("@(想一想)", "<img src='/static/plugins/OwO/alu/想一想.png' alt='想一想.png' style='vertical-align: middle;'>");
map.put("@(愤怒)", "<img src='/static/plugins/OwO/alu/愤怒.png' alt='愤怒.png' style='vertical-align: middle;'>");
map.put("@(扇耳光)", "<img src='/static/plugins/OwO/alu/扇耳光.png' alt='扇耳光.png' style='vertical-align: middle;'>");
map.put("@(投降)", "<img src='/static/plugins/OwO/alu/投降.png' alt='投降.png' style='vertical-align: middle;'>");
map.put("@(抠鼻)", "<img src='/static/plugins/OwO/alu/抠鼻.png' alt='抠鼻.png' style='vertical-align: middle;'>");
map.put("@(抽烟)", "<img src='/static/plugins/OwO/alu/抽烟.png' alt='抽烟.png' style='vertical-align: middle;'>");
map.put("@(无奈)", "<img src='/static/plugins/OwO/alu/无奈.png' alt='无奈.png' style='vertical-align: middle;'>");
map.put("@(无所谓)", "<img src='/static/plugins/OwO/alu/无所谓.png' alt='无所谓.png' style='vertical-align: middle;'>");
map.put("@(无语)", "<img src='/static/plugins/OwO/alu/无语.png' alt='无语.png' style='vertical-align: middle;'>");
map.put("@(暗地观察)", "<img src='/static/plugins/OwO/alu/暗地观察.png' alt='暗地观察.png' style='vertical-align: middle;'>");
map.put("@(期待)", "<img src='/static/plugins/OwO/alu/期待.png' alt='期待.png' style='vertical-align: middle;'>");
map.put("@(欢呼)", "<img src='/static/plugins/OwO/alu/欢呼.png' alt='欢呼.png' style='vertical-align: middle;'>");
map.put("@(汗)", "<img src='/static/plugins/OwO/alu/汗.png' alt='汗.png' style='vertical-align: middle;'>");
map.put("@(深思)", "<img src='/static/plugins/OwO/alu/深思.png' alt='深思.png' style='vertical-align: middle;'>");
map.put("@(狂汗)", "<img src='/static/plugins/OwO/alu/狂汗.png' alt='狂汗.png' style='vertical-align: middle;'>");
map.put("@(献花)", "<img src='/static/plugins/OwO/alu/献花.png' alt='献花.png' style='vertical-align: middle;'>");
map.put("@(献黄瓜)", "<img src='/static/plugins/OwO/alu/献黄瓜.png' alt='献黄瓜.png' style='vertical-align: middle;'>");
map.put("@(皱眉)", "<img src='/static/plugins/OwO/alu/皱眉.png' alt='皱眉.png' style='vertical-align: middle;'>");
map.put("@(看不见)", "<img src='/static/plugins/OwO/alu/看不见.png' alt='看不见.png' style='vertical-align: middle;'>");
map.put("@(看热闹)", "<img src='/static/plugins/OwO/alu/看热闹.png' alt='看热闹.png' style='vertical-align: middle;'>");
map.put("@(肿包)", "<img src='/static/plugins/OwO/alu/肿包.png' alt='肿包.png' style='vertical-align: middle;'>");
map.put("@(脸红)", "<img src='/static/plugins/OwO/alu/脸红.png' alt='脸红.png' style='vertical-align: middle;'>");
map.put("@(蜡烛)", "<img src='/static/plugins/OwO/alu/蜡烛.png' alt='蜡烛.png' style='vertical-align: middle;'>");
map.put("@(装大款)", "<img src='/static/plugins/OwO/alu/装大款.png' alt='装大款.png' style='vertical-align: middle;'>");
map.put("@(观察)", "<img src='/static/plugins/OwO/alu/观察.png' alt='观察.png' style='vertical-align: middle;'>");
map.put("@(赞一个)", "<img src='/static/plugins/OwO/alu/赞一个.png' alt='赞一个.png' style='vertical-align: middle;'>");
map.put("@(邪恶)", "<img src='/static/plugins/OwO/alu/邪恶.png' alt='邪恶.png' style='vertical-align: middle;'>");
map.put("@(锁眉)", "<img src='/static/plugins/OwO/alu/锁眉.png' alt='锁眉.png' style='vertical-align: middle;'>");
map.put("@(长草)", "<img src='/static/plugins/OwO/alu/长草.png' alt='长草.png' style='vertical-align: middle;'>");
map.put("@(阴暗)", "<img src='/static/plugins/OwO/alu/阴暗.png' alt='阴暗.png' style='vertical-align: middle;'>");
map.put("@(高兴)", "<img src='/static/plugins/OwO/alu/高兴.png' alt='高兴.png' style='vertical-align: middle;'>");
map.put("@(黑线)", "<img src='/static/plugins/OwO/alu/黑线.png' alt='黑线.png' style='vertical-align: middle;'>");
map.put("@(鼓掌)", "<img src='/static/plugins/OwO/alu/鼓掌.png' alt='鼓掌.png' style='vertical-align: middle;'>");
HaloConst.OWO = map;
}
}

View File

@ -30,7 +30,7 @@ import java.util.Locale;
@EnableWebMvc
@ComponentScan(basePackages = "cc.ryanc.halo.web.controller")
@PropertySource(value = "classpath:application.yaml", ignoreResourceNotFound = true, encoding = "UTF-8")
public class MvcConfig implements WebMvcConfigurer {
public class WebMvcAutoConfiguration implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@ -52,6 +52,7 @@ public class MvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/admin.*")
.addPathPatterns("/admin/**")
.addPathPatterns("/backup/**")
.excludePathPatterns("/admin/login")
@ -65,6 +66,7 @@ public class MvcConfig implements WebMvcConfigurer {
registry.addInterceptor(apiInterceptor)
.addPathPatterns("/api/**");
registry.addInterceptor(localeInterceptor)
.addPathPatterns("/admin.*")
.addPathPatterns("/admin/**")
.addPathPatterns("/install");
registry.addInterceptor(localeChangeInterceptor())
@ -86,7 +88,7 @@ public class MvcConfig implements WebMvcConfigurer {
registry.addResourceHandler("/upload/**")
.addResourceLocations("file:///" + System.getProperties().getProperty("user.home") + "/halo/upload/");
registry.addResourceHandler("/favicon.ico")
.addResourceLocations("classpath:/static/images/favicon.ico");
.addResourceLocations("classpath:/static/halo-backend/images/favicon.ico");
registry.addResourceHandler("/backup/**")
.addResourceLocations("file:///" + System.getProperties().getProperty("user.home") + "/halo/backup/");
}
@ -98,11 +100,17 @@ public class MvcConfig implements WebMvcConfigurer {
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
registry.addMapping("/api/**")
.allowedHeaders("*")
.allowedOrigins("*")
.allowedMethods("*");
.allowedMethods("GET", "POST")
.exposedHeaders("access-control-allow-headers",
"access-control-allow-methods",
"access-control-allow-origin",
"access-control-max-age",
"X-Frame-Options",
"token")
.allowCredentials(false).maxAge(3600);
}
/**
@ -112,7 +120,7 @@ public class MvcConfig implements WebMvcConfigurer {
*/
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
final SessionLocaleResolver slr = new SessionLocaleResolver();
slr.setDefaultLocale(Locale.CHINA);
return slr;
}
@ -124,7 +132,7 @@ public class MvcConfig implements WebMvcConfigurer {
*/
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
final LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}

View File

@ -0,0 +1,232 @@
package cc.ryanc.halo.listener;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.Theme;
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.service.OptionsService;
import cc.ryanc.halo.utils.HaloUtils;
import cc.ryanc.halo.web.controller.core.BaseController;
import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.CronUtil;
import freemarker.template.TemplateModelException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <pre>
*
* </pre>
*
* @author : RYAN0UP
* @date : 2018/12/5
*/
@Slf4j
@Configuration
public class StartedListener implements ApplicationListener<ApplicationStartedEvent> {
@Autowired
private OptionsService optionsService;
@Autowired
private freemarker.template.Configuration configuration;
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
try {
this.loadActiveTheme();
} catch (TemplateModelException e) {
e.printStackTrace();
}
this.loadOptions();
this.loadThemes();
this.loadOwo();
//启动定时任务
CronUtil.start();
log.info("The scheduled task starts successfully!");
}
/**
*
*/
private void loadActiveTheme() throws TemplateModelException {
final String themeValue = optionsService.findOneOption(BlogPropertiesEnum.THEME.getProp());
if (StrUtil.isNotEmpty(themeValue) && !StrUtil.equals(themeValue, null)) {
BaseController.THEME = themeValue;
} else {
//如果没有设置主题,则默认
BaseController.THEME = "anatole";
}
configuration.setSharedVariable("themeName", BaseController.THEME);
}
/**
*
*/
private void loadOptions() {
final Map<String, String> options = optionsService.findAllOptions();
if (options != null && !options.isEmpty()) {
HaloConst.OPTIONS = options;
}
}
/**
*
*/
private void loadThemes() {
HaloConst.THEMES.clear();
final List<Theme> themes = HaloUtils.getThemes();
if (null != themes) {
HaloConst.THEMES = themes;
}
}
/**
* OwO
*/
private void loadOwo() {
final Map<String, String> map = new HashMap<>(135);
map.put("@[nico]", "<img src='/static/halo-common/OwO/paopao/nico.png' alt='nico.png' style='vertical-align: middle;'>");
map.put("@[OK]", "<img src='/static/halo-common/OwO/paopao/OK.png' alt='OK.png' style='vertical-align: middle;'>");
map.put("@[what]", "<img src='/static/halo-common/OwO/paopao/what.png' alt='what.png' style='vertical-align: middle;'>");
map.put("@[三道杠]", "<img src='/static/halo-common/OwO/paopao/三道杠.png' alt='三道杠.png' style='vertical-align: middle;'>");
map.put("@[不高兴]", "<img src='/static/halo-common/OwO/paopao/不高兴.png' alt='不高兴.png' style='vertical-align: middle;'>");
map.put("@[乖]", "<img src='/static/halo-common/OwO/paopao/乖.png' alt='乖.png' style='vertical-align: middle;'>");
map.put("@[你懂的]", "<img src='/static/halo-common/OwO/paopao/你懂的.png' alt='你懂的.png' style='vertical-align: middle;'>");
map.put("@[便便]", "<img src='/static/halo-common/OwO/paopao/便便.png' alt='便便.png' style='vertical-align: middle;'>");
map.put("@[冷]", "<img src='/static/halo-common/OwO/paopao/冷.png' alt='冷.png' style='vertical-align: middle;'>");
map.put("@[勉强]", "<img src='/static/halo-common/OwO/paopao/勉强.png' alt='勉强.png' style='vertical-align: middle;'>");
map.put("@[吃瓜]", "<img src='/static/halo-common/OwO/paopao/吃瓜.png' alt='吃瓜.png' style='vertical-align: middle;'>");
map.put("@[吃翔]", "<img src='/static/halo-common/OwO/paopao/吃翔.png' alt='吃翔.png' style='vertical-align: middle;'>");
map.put("@[吐]", "<img src='/static/halo-common/OwO/paopao/吐.png' alt='吐.png' style='vertical-align: middle;'>");
map.put("@[吐舌]", "<img src='/static/halo-common/OwO/paopao/吐舌.png' alt='吐舌.png' style='vertical-align: middle;'>");
map.put("@[呀咩爹]", "<img src='/static/halo-common/OwO/paopao/呀咩爹.png' alt='呀咩爹.png' style='vertical-align: middle;'>");
map.put("@[呵呵]", "<img src='/static/halo-common/OwO/paopao/呵呵.png' alt='呵呵.png' style='vertical-align: middle;'>");
map.put("@[呼]", "<img src='/static/halo-common/OwO/paopao/呼.png' alt='呼.png' style='vertical-align: middle;'>");
map.put("@[咦]", "<img src='/static/halo-common/OwO/paopao/咦.png' alt='咦.png' style='vertical-align: middle;'>");
map.put("@[哈哈]", "<img src='/static/halo-common/OwO/paopao/哈哈.png' alt='哈哈.png' style='vertical-align: middle;'>");
map.put("@[啊]", "<img src='/static/halo-common/OwO/paopao/啊.png' alt='啊.png' style='vertical-align: middle;'>");
map.put("@[喷]", "<img src='/static/halo-common/OwO/paopao/喷.png' alt='喷.png' style='vertical-align: middle;'>");
map.put("@[嘚瑟]", "<img src='/static/halo-common/OwO/paopao/嘚瑟.png' alt='嘚瑟.png' style='vertical-align: middle;'>");
map.put("@[大拇指]", "<img src='/static/halo-common/OwO/paopao/大拇指.png' alt='大拇指.png' style='vertical-align: middle;'>");
map.put("@[太开心]", "<img src='/static/halo-common/OwO/paopao/太开心.png' alt='太开心.png' style='vertical-align: middle;'>");
map.put("@[太阳]", "<img src='/static/halo-common/OwO/paopao/太阳.png' alt='太阳.png' style='vertical-align: middle;'>");
map.put("@[委屈]", "<img src='/static/halo-common/OwO/paopao/委屈.png' alt='委屈.png' style='vertical-align: middle;'>");
map.put("@[小乖]", "<img src='/static/halo-common/OwO/paopao/小乖.png' alt='小乖.png' style='vertical-align: middle;'>");
map.put("@[小红脸]", "<img src='/static/halo-common/OwO/paopao/小红脸.png' alt='小红脸.png' style='vertical-align: middle;'>");
map.put("@[开心]", "<img src='/static/halo-common/OwO/paopao/开心.png' alt='开心.png' style='vertical-align: middle;'>");
map.put("@[弱]", "<img src='/static/halo-common/OwO/paopao/弱.png' alt='弱.png' style='vertical-align: middle;'>");
map.put("@[彩虹]", "<img src='/static/halo-common/OwO/paopao/彩虹.png' alt='彩虹.png' style='vertical-align: middle;'>");
map.put("@[心碎]", "<img src='/static/halo-common/OwO/paopao/心碎.png' alt='心碎.png' style='vertical-align: middle;'>");
map.put("@[怒]", "<img src='/static/halo-common/OwO/paopao/怒.png' alt='怒.png' style='vertical-align: middle;'>");
map.put("@[惊哭]", "<img src='/static/halo-common/OwO/paopao/惊哭.png' alt='惊哭.png' style='vertical-align: middle;'>");
map.put("@[惊恐]", "<img src='/static/halo-common/OwO/paopao/惊恐.png' alt='惊恐.png' style='vertical-align: middle;'>");
map.put("@[惊讶]", "<img src='/static/halo-common/OwO/paopao/惊讶.png' alt='惊讶.png' style='vertical-align: middle;'>");
map.put("@[懒得理]", "<img src='/static/halo-common/OwO/paopao/懒得理.png' alt='懒得理.png' style='vertical-align: middle;'>");
map.put("@[手纸]", "<img src='/static/halo-common/OwO/paopao/手纸.png' alt='手纸.png' style='vertical-align: middle;'>");
map.put("@[挖鼻]", "<img src='/static/halo-common/OwO/paopao/挖鼻.png' alt='挖鼻.png' style='vertical-align: middle;'>");
map.put("@[捂嘴笑]", "<img src='/static/halo-common/OwO/paopao/捂嘴笑.png' alt='捂嘴笑.png' style='vertical-align: middle;'>");
map.put("@[星星月亮]", "<img src='/static/halo-common/OwO/paopao/星星月亮.png' alt='星星月亮.png' style='vertical-align: middle;'>");
map.put("@[汗]", "<img src='/static/halo-common/OwO/paopao/汗.png' alt='汗.png' style='vertical-align: middle;'>");
map.put("@[沙发]", "<img src='/static/halo-common/OwO/paopao/沙发.png' alt='沙发.png' style='vertical-align: middle;'>");
map.put("@[泪]", "<img src='/static/halo-common/OwO/paopao/泪.png' alt='泪.png' style='vertical-align: middle;'>");
map.put("@[滑稽]", "<img src='/static/halo-common/OwO/paopao/滑稽.png' alt='滑稽.png' style='vertical-align: middle;'>");
map.put("@[灯泡]", "<img src='/static/halo-common/OwO/paopao/灯泡.png' alt='灯泡.png' style='vertical-align: middle;'>");
map.put("@[爱心]", "<img src='/static/halo-common/OwO/paopao/爱心.png' alt='爱心.png' style='vertical-align: middle;'>");
map.put("@[犀利]", "<img src='/static/halo-common/OwO/paopao/犀利.png' alt='犀利.png' style='vertical-align: middle;'>");
map.put("@[狂汗]", "<img src='/static/halo-common/OwO/paopao/狂汗.png' alt='狂汗.png' style='vertical-align: middle;'>");
map.put("@[玫瑰]", "<img src='/static/halo-common/OwO/paopao/玫瑰.png' alt='玫瑰.png' style='vertical-align: middle;'>");
map.put("@[生气]", "<img src='/static/halo-common/OwO/paopao/生气.png' alt='生气.png' style='vertical-align: middle;'>");
map.put("@[疑问]", "<img src='/static/halo-common/OwO/paopao/疑问.png' alt='疑问.png' style='vertical-align: middle;'>");
map.put("@[真棒]", "<img src='/static/halo-common/OwO/paopao/真棒.png' alt='真棒.png' style='vertical-align: middle;'>");
map.put("@[睡觉]", "<img src='/static/halo-common/OwO/paopao/睡觉.png' alt='睡觉.png' style='vertical-align: middle;'>");
map.put("@[礼物]", "<img src='/static/halo-common/OwO/paopao/礼物.png' alt='礼物.png' style='vertical-align: middle;'>");
map.put("@[笑尿]", "<img src='/static/halo-common/OwO/paopao/笑尿.png' alt='笑尿.png' style='vertical-align: middle;'>");
map.put("@[笑眼]", "<img src='/static/halo-common/OwO/paopao/笑眼.png' alt='笑眼.png' style='vertical-align: middle;'>");
map.put("@[红领巾]", "<img src='/static/halo-common/OwO/paopao/红领巾.png' alt='红领巾.png' style='vertical-align: middle;'>");
map.put("@[胜利]", "<img src='/static/halo-common/OwO/paopao/胜利.png' alt='胜利.png' style='vertical-align: middle;'>");
map.put("@[花心]", "<img src='/static/halo-common/OwO/paopao/花心.png' alt='花心.png' style='vertical-align: middle;'>");
map.put("@[茶杯]", "<img src='/static/halo-common/OwO/paopao/茶杯.png' alt='茶杯.png' style='vertical-align: middle;'>");
map.put("@[药丸]", "<img src='/static/halo-common/OwO/paopao/药丸.png' alt='药丸.png' style='vertical-align: middle;'>");
map.put("@[蛋糕]", "<img src='/static/halo-common/OwO/paopao/蛋糕.png' alt='蛋糕.png' style='vertical-align: middle;'>");
map.put("@[蜡烛]", "<img src='/static/halo-common/OwO/paopao/蜡烛.png' alt='蜡烛.png' style='vertical-align: middle;'>");
map.put("@[鄙视]", "<img src='/static/halo-common/OwO/paopao/鄙视.png' alt='鄙视.png' style='vertical-align: middle;'>");
map.put("@[酷]", "<img src='/static/halo-common/OwO/paopao/酷.png' alt='酷.png' style='vertical-align: middle;'>");
map.put("@[酸爽]", "<img src='/static/halo-common/OwO/paopao/酸爽.png' alt='酸爽.png' style='vertical-align: middle;'>");
map.put("@[钱]", "<img src='/static/halo-common/OwO/paopao/钱.png' alt='钱.png' style='vertical-align: middle;'>");
map.put("@[钱币]", "<img src='/static/halo-common/OwO/paopao/钱币.png' alt='钱币.png' style='vertical-align: middle;'>");
map.put("@[阴险]", "<img src='/static/halo-common/OwO/paopao/阴险.png' alt='阴险.png' style='vertical-align: middle;'>");
map.put("@[音乐]", "<img src='/static/halo-common/OwO/paopao/音乐.png' alt='音乐.png' style='vertical-align: middle;'>");
map.put("@[香蕉]", "<img src='/static/halo-common/OwO/paopao/香蕉.png' alt='香蕉.png' style='vertical-align: middle;'>");
map.put("@[黑线]", "<img src='/static/halo-common/OwO/paopao/黑线.png' alt='黑线.png' style='vertical-align: middle;'>");
map.put("@(不出所料)", "<img src='/static/halo-common/OwO/alu/不出所料.png' alt='不出所料.png' style='vertical-align: middle;'>");
map.put("@(不说话)", "<img src='/static/halo-common/OwO/alu/不说话.png' alt='不说话.png' style='vertical-align: middle;'>");
map.put("@(不高兴)", "<img src='/static/halo-common/OwO/alu/不高兴.png' alt='不高兴.png' style='vertical-align: middle;'>");
map.put("@(中刀)", "<img src='/static/halo-common/OwO/alu/中刀.png' alt='中刀.png' style='vertical-align: middle;'>");
map.put("@(中指)", "<img src='/static/halo-common/OwO/alu/中指.png' alt='中指.png' style='vertical-align: middle;'>");
map.put("@(中枪)", "<img src='/static/halo-common/OwO/alu/中枪.png' alt='中枪.png' style='vertical-align: middle;'>");
map.put("@(亲亲)", "<img src='/static/halo-common/OwO/alu/亲亲.png' alt='亲亲.png' style='vertical-align: middle;'>");
map.put("@(便便)", "<img src='/static/halo-common/OwO/alu/便便.png' alt='便便.png' style='vertical-align: middle;'>");
map.put("@(傻笑)", "<img src='/static/halo-common/OwO/alu/傻笑.png' alt='傻笑.png' style='vertical-align: middle;'>");
map.put("@(内伤)", "<img src='/static/halo-common/OwO/alu/内伤.png' alt='内伤.png' style='vertical-align: middle;'>");
map.put("@(击掌)", "<img src='/static/halo-common/OwO/alu/击掌.png' alt='击掌.png' style='vertical-align: middle;'>");
map.put("@(口水)", "<img src='/static/halo-common/OwO/alu/口水.png' alt='口水.png' style='vertical-align: middle;'>");
map.put("@(吐)", "<img src='/static/halo-common/OwO/alu/吐.png' alt='吐.png' style='vertical-align: middle;'>");
map.put("@(吐舌)", "<img src='/static/halo-common/OwO/alu/吐舌.png' alt='吐舌.png' style='vertical-align: middle;'>");
map.put("@(吐血倒地)", "<img src='/static/halo-common/OwO/alu/吐血倒地.png' alt='吐血倒地.png' style='vertical-align: middle;'>");
map.put("@(呲牙)", "<img src='/static/halo-common/OwO/alu/呲牙.png' alt='呲牙.png' style='vertical-align: middle;'>");
map.put("@(咽气)", "<img src='/static/halo-common/OwO/alu/咽气.png' alt='咽气.png' style='vertical-align: middle;'>");
map.put("@(哭泣)", "<img src='/static/halo-common/OwO/alu/哭泣.png' alt='哭泣.png' style='vertical-align: middle;'>");
map.put("@(喜极而泣)", "<img src='/static/halo-common/OwO/alu/喜极而泣.png' alt='喜极而泣.png' style='vertical-align: middle;'>");
map.put("@(喷水)", "<img src='/static/halo-common/OwO/alu/喷水.png' alt='喷水.png' style='vertical-align: middle;'>");
map.put("@(喷血)", "<img src='/static/halo-common/OwO/alu/喷血.png' alt='喷血.png' style='vertical-align: middle;'>");
map.put("@(坐等)", "<img src='/static/halo-common/OwO/alu/坐等.png' alt='坐等.png' style='vertical-align: middle;'>");
map.put("@(大囧)", "<img src='/static/halo-common/OwO/alu/大囧.png' alt='大囧.png' style='vertical-align: middle;'>");
map.put("@(害羞)", "<img src='/static/halo-common/OwO/alu/害羞.png' alt='害羞.png' style='vertical-align: middle;'>");
map.put("@(小怒)", "<img src='/static/halo-common/OwO/alu/小怒.png' alt='小怒.png' style='vertical-align: middle;'>");
map.put("@(小眼睛)", "<img src='/static/halo-common/OwO/alu/小眼睛.png' alt='小眼睛.png' style='vertical-align: middle;'>");
map.put("@(尴尬)", "<img src='/static/halo-common/OwO/alu/尴尬.png' alt='尴尬.png' style='vertical-align: middle;'>");
map.put("@(得意)", "<img src='/static/halo-common/OwO/alu/得意.png' alt='得意.png' style='vertical-align: middle;'>");
map.put("@(惊喜)", "<img src='/static/halo-common/OwO/alu/惊喜.png' alt='惊喜.png' style='vertical-align: middle;'>");
map.put("@(想一想)", "<img src='/static/halo-common/OwO/alu/想一想.png' alt='想一想.png' style='vertical-align: middle;'>");
map.put("@(愤怒)", "<img src='/static/halo-common/OwO/alu/愤怒.png' alt='愤怒.png' style='vertical-align: middle;'>");
map.put("@(扇耳光)", "<img src='/static/halo-common/OwO/alu/扇耳光.png' alt='扇耳光.png' style='vertical-align: middle;'>");
map.put("@(投降)", "<img src='/static/halo-common/OwO/alu/投降.png' alt='投降.png' style='vertical-align: middle;'>");
map.put("@(抠鼻)", "<img src='/static/halo-common/OwO/alu/抠鼻.png' alt='抠鼻.png' style='vertical-align: middle;'>");
map.put("@(抽烟)", "<img src='/static/halo-common/OwO/alu/抽烟.png' alt='抽烟.png' style='vertical-align: middle;'>");
map.put("@(无奈)", "<img src='/static/halo-common/OwO/alu/无奈.png' alt='无奈.png' style='vertical-align: middle;'>");
map.put("@(无所谓)", "<img src='/static/halo-common/OwO/alu/无所谓.png' alt='无所谓.png' style='vertical-align: middle;'>");
map.put("@(无语)", "<img src='/static/halo-common/OwO/alu/无语.png' alt='无语.png' style='vertical-align: middle;'>");
map.put("@(暗地观察)", "<img src='/static/halo-common/OwO/alu/暗地观察.png' alt='暗地观察.png' style='vertical-align: middle;'>");
map.put("@(期待)", "<img src='/static/halo-common/OwO/alu/期待.png' alt='期待.png' style='vertical-align: middle;'>");
map.put("@(欢呼)", "<img src='/static/halo-common/OwO/alu/欢呼.png' alt='欢呼.png' style='vertical-align: middle;'>");
map.put("@(汗)", "<img src='/static/halo-common/OwO/alu/汗.png' alt='汗.png' style='vertical-align: middle;'>");
map.put("@(深思)", "<img src='/static/halo-common/OwO/alu/深思.png' alt='深思.png' style='vertical-align: middle;'>");
map.put("@(狂汗)", "<img src='/static/halo-common/OwO/alu/狂汗.png' alt='狂汗.png' style='vertical-align: middle;'>");
map.put("@(献花)", "<img src='/static/halo-common/OwO/alu/献花.png' alt='献花.png' style='vertical-align: middle;'>");
map.put("@(献黄瓜)", "<img src='/static/halo-common/OwO/alu/献黄瓜.png' alt='献黄瓜.png' style='vertical-align: middle;'>");
map.put("@(皱眉)", "<img src='/static/halo-common/OwO/alu/皱眉.png' alt='皱眉.png' style='vertical-align: middle;'>");
map.put("@(看不见)", "<img src='/static/halo-common/OwO/alu/看不见.png' alt='看不见.png' style='vertical-align: middle;'>");
map.put("@(看热闹)", "<img src='/static/halo-common/OwO/alu/看热闹.png' alt='看热闹.png' style='vertical-align: middle;'>");
map.put("@(肿包)", "<img src='/static/halo-common/OwO/alu/肿包.png' alt='肿包.png' style='vertical-align: middle;'>");
map.put("@(脸红)", "<img src='/static/halo-common/OwO/alu/脸红.png' alt='脸红.png' style='vertical-align: middle;'>");
map.put("@(蜡烛)", "<img src='/static/halo-common/OwO/alu/蜡烛.png' alt='蜡烛.png' style='vertical-align: middle;'>");
map.put("@(装大款)", "<img src='/static/halo-common/OwO/alu/装大款.png' alt='装大款.png' style='vertical-align: middle;'>");
map.put("@(观察)", "<img src='/static/halo-common/OwO/alu/观察.png' alt='观察.png' style='vertical-align: middle;'>");
map.put("@(赞一个)", "<img src='/static/halo-common/OwO/alu/赞一个.png' alt='赞一个.png' style='vertical-align: middle;'>");
map.put("@(邪恶)", "<img src='/static/halo-common/OwO/alu/邪恶.png' alt='邪恶.png' style='vertical-align: middle;'>");
map.put("@(锁眉)", "<img src='/static/halo-common/OwO/alu/锁眉.png' alt='锁眉.png' style='vertical-align: middle;'>");
map.put("@(长草)", "<img src='/static/halo-common/OwO/alu/长草.png' alt='长草.png' style='vertical-align: middle;'>");
map.put("@(阴暗)", "<img src='/static/halo-common/OwO/alu/阴暗.png' alt='阴暗.png' style='vertical-align: middle;'>");
map.put("@(高兴)", "<img src='/static/halo-common/OwO/alu/高兴.png' alt='高兴.png' style='vertical-align: middle;'>");
map.put("@(黑线)", "<img src='/static/halo-common/OwO/alu/黑线.png' alt='黑线.png' style='vertical-align: middle;'>");
map.put("@(鼓掌)", "<img src='/static/halo-common/OwO/alu/鼓掌.png' alt='鼓掌.png' style='vertical-align: middle;'>");
HaloConst.OWO = map;
}
}

View File

@ -1,11 +1,10 @@
package cc.ryanc.halo.model.domain;
import lombok.Data;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
@ -20,6 +19,7 @@ import java.util.Date;
@Data
@Entity
@Table(name = "halo_attachment")
@EntityListeners(AuditingEntityListener.class)
public class Attachment implements Serializable {
private static final long serialVersionUID = 3060117944880138064L;
@ -59,6 +59,7 @@ public class Attachment implements Serializable {
/**
*
*/
@CreatedDate
private Date attachCreated;
/**
@ -70,4 +71,14 @@ public class Attachment implements Serializable {
*
*/
private String attachWh;
/**
*
*/
private String attachLocation;
/**
* 01
*/
private Integer attachOrigin = 0;
}

View File

@ -2,6 +2,8 @@ package cc.ryanc.halo.model.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import javax.validation.constraints.Email;
@ -21,6 +23,7 @@ import java.util.List;
@Data
@Entity
@Table(name = "halo_comment")
@EntityListeners(AuditingEntityListener.class)
public class Comment implements Serializable {
private static final long serialVersionUID = -6639021627094260505L;
@ -72,6 +75,7 @@ public class Comment implements Serializable {
/**
*
*/
@CreatedDate
private Date commentDate;
/**
@ -84,6 +88,7 @@ public class Comment implements Serializable {
/**
* ua
*/
@Column(length = 512)
private String commentAgent;
/**

View File

@ -6,6 +6,7 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
/**
@ -33,11 +34,13 @@ public class Link implements Serializable {
/**
*
*/
@NotEmpty(message = "友情链接名称不能为空!")
private String linkName;
/**
*
*/
@NotEmpty(message = "友情链接地址不能为空!")
private String linkUrl;
/**

View File

@ -1,11 +1,10 @@
package cc.ryanc.halo.model.domain;
import lombok.Data;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
@ -20,6 +19,7 @@ import java.util.Date;
@Data
@Entity
@Table(name = "halo_logs")
@EntityListeners(AuditingEntityListener.class)
public class Logs implements Serializable {
private static final long serialVersionUID = -2571815432301283171L;
@ -49,6 +49,7 @@ public class Logs implements Serializable {
/**
*
*/
@CreatedDate
private Date logCreated;
public Logs() {

View File

@ -6,6 +6,8 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
@ -33,16 +35,19 @@ public class Menu implements Serializable {
/**
*
*/
@NotEmpty(message = "菜单名称不能为空!")
private String menuName;
/**
*
*/
@NotEmpty(message = "菜单路径不能为空!")
private String menuUrl;
/**
*
*/
@NotNull(message = "排序编号不能为空!")
private Integer menuSort;
/**

View File

@ -1,8 +1,10 @@
package cc.ryanc.halo.model.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.io.Serializable;
@ -21,6 +23,7 @@ import java.util.List;
@Data
@Entity
@Table(name = "halo_post")
@EntityListeners(AuditingEntityListener.class)
public class Post implements Serializable {
private static final long serialVersionUID = -6019684584665869629L;
@ -106,11 +109,13 @@ public class Post implements Serializable {
/**
*
*/
@CreatedDate
private Date postDate;
/**
*
*/
@LastModifiedDate
private Date postUpdate;
/**
@ -130,6 +135,11 @@ public class Post implements Serializable {
*/
private Integer allowComment = 0;
/**
* 访
*/
private String postPassword;
/**
*
*/

View File

@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@ -33,11 +34,13 @@ public class Tag implements Serializable {
/**
*
*/
@NotEmpty(message = "标签名称不能为空!")
private String tagName;
/**
*
*/
@NotEmpty(message = "标签路径不能为空!")
private String tagUrl;
@ManyToMany(mappedBy = "tags")

View File

@ -34,4 +34,9 @@ public class HaloConst {
* user_session
*/
public static String USER_SESSION_KEY = "user_session";
/**
*
*/
public static Map<Long,Long> POSTS_VIEWS = new HashMap<>();
}

View File

@ -0,0 +1,30 @@
package cc.ryanc.halo.model.dto;
import lombok.Data;
/**
* <pre>
*
* </pre>
*
* @author : Yawn
* @date : 2018/12/3
*/
@Data
public class QiNiuPutSet {
/**
*
*/
private Long size;
/**
*
*/
private Integer w;
/**
*
*/
private Integer h;
}

View File

@ -0,0 +1,43 @@
package cc.ryanc.halo.model.enums;
/**
* <pre>
* enum
* </pre>
*
* @author : Yawn
* @date : 2018/12/4
*/
public enum AttachLocationEnum {
/**
*
*/
SERVER(0,"server"),
/**
*
*/
QINIU(1,"qiniu"),
/**
*
*/
UPYUN(2,"upyun");
private Integer code;
private String desc;
AttachLocationEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public Integer getCode() {
return code;
}
public String getDesc() {
return desc;
}
}

View File

@ -138,7 +138,7 @@ public enum BlogPropertiesEnum {
/**
*
*/
DEFAULT_THUMBNAIL("/static/images/thumbnail/thumbnail.png"),
DEFAULT_THUMBNAIL("/static/halo-frontend/images/thumbnail/thumbnail.png"),
/**
*
@ -148,7 +148,12 @@ public enum BlogPropertiesEnum {
/**
* API Token
*/
API_TOKEN("api_token");
API_TOKEN("api_token"),
/**
*
*/
ATTACH_LOC("attach_loc");
private String prop;

View File

@ -0,0 +1,33 @@
package cc.ryanc.halo.model.freemarker.method;
import cn.hutool.core.util.RandomUtil;
import freemarker.template.SimpleNumber;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author : RYAN0UP
* @date : 2018/12/21
*/
@Component
public class RandomMethod implements TemplateMethodModelEx {
/**
*
*
* @param arguments
* @return Object
* @throws TemplateModelException TemplateModelException
*/
@Override
public Object exec(List arguments) throws TemplateModelException {
SimpleNumber argOne = (SimpleNumber) arguments.get(0);
SimpleNumber argTwo = (SimpleNumber) arguments.get(1);
int start = argOne.getAsNumber().intValue();
int end = argTwo.getAsNumber().intValue();
return RandomUtil.randomInt(start, end);
}
}

View File

@ -0,0 +1,35 @@
package cc.ryanc.halo.model.freemarker.method;
import cc.ryanc.halo.service.CommentService;
import freemarker.template.SimpleNumber;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author : RYAN0UP
* @date : 2018/12/31
*/
@Component
public class RecentCommentsMethod implements TemplateMethodModelEx {
@Autowired
private CommentService commentService;
/**
*
*
* @param arguments
* @return Object
* @throws TemplateModelException TemplateModelException
*/
@Override
public Object exec(List arguments) throws TemplateModelException {
SimpleNumber argOne = (SimpleNumber) arguments.get(0);
int limit = argOne.getAsNumber().intValue();
return commentService.getRecentComments(limit);
}
}

View File

@ -0,0 +1,35 @@
package cc.ryanc.halo.model.freemarker.method;
import cc.ryanc.halo.service.PostService;
import freemarker.template.SimpleNumber;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author : RYAN0UP
* @date : 2018/12/31
*/
@Component
public class RecentPostsMethod implements TemplateMethodModelEx {
@Autowired
private PostService postService;
/**
*
*
* @param arguments
* @return Object
* @throws TemplateModelException TemplateModelException
*/
@Override
public Object exec(List arguments) throws TemplateModelException {
SimpleNumber argOne = (SimpleNumber) arguments.get(0);
int limit = argOne.getAsNumber().intValue();
return postService.getRecentPosts(limit);
}
}

View File

@ -1,4 +1,4 @@
package cc.ryanc.halo.model.tag;
package cc.ryanc.halo.model.freemarker.tag;
import cc.ryanc.halo.model.enums.PostStatusEnum;
import cc.ryanc.halo.model.enums.PostTypeEnum;
@ -29,7 +29,7 @@ public class ArticleTagDirective implements TemplateDirectiveModel {
@Override
public void execute(Environment environment, Map map, TemplateModel[] templateModels, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException {
DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25);
final DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25);
if (map.containsKey(METHOD_KEY)) {
String method = map.get(METHOD_KEY).toString();
switch (method) {

View File

@ -1,7 +1,5 @@
package cc.ryanc.halo.model.tag;
package cc.ryanc.halo.model.freemarker.tag;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.service.*;
import freemarker.core.Environment;
import freemarker.template.*;
@ -41,24 +39,24 @@ public class CommonTagDirective implements TemplateDirectiveModel {
@Override
public void execute(Environment environment, Map map, TemplateModel[] templateModels, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException {
DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25);
final DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25);
if (map.containsKey(METHOD_KEY)) {
String method = map.get(METHOD_KEY).toString();
switch (method) {
case "menus":
environment.setVariable("menus", builder.build().wrap(menuService.findAllMenus()));
environment.setVariable("menus", builder.build().wrap(menuService.findAll()));
break;
case "categories":
environment.setVariable("categories", builder.build().wrap(categoryService.findAllCategories()));
environment.setVariable("categories", builder.build().wrap(categoryService.findAll()));
break;
case "tags":
environment.setVariable("tags", builder.build().wrap(tagService.findAllTags()));
environment.setVariable("tags", builder.build().wrap(tagService.findAll()));
break;
case "links":
environment.setVariable("links", builder.build().wrap(linkService.findAllLinks()));
environment.setVariable("links", builder.build().wrap(linkService.findAll()));
break;
case "newComments":
environment.setVariable("newComments", builder.build().wrap(commentService.findAllComments(1)));
environment.setVariable("newComments", builder.build().wrap(commentService.findAll(1)));
break;
default:
break;

View File

@ -20,4 +20,12 @@ public interface CategoryRepository extends JpaRepository<Category, Long> {
* @return Category
*/
Category findCategoryByCateUrl(String cateUrl);
/**
*
*
* @param cateName
* @return Category
*/
Category findCategoryByCateName(String cateName);
}

View File

@ -6,6 +6,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
@ -88,4 +89,13 @@ public interface CommentRepository extends JpaRepository<Comment, Long> {
* @return
*/
Integer countAllByCommentStatus(Integer status);
/**
*
*
* @param limit
* @return List
*/
@Query(value = "SELECT * FROM halo_comment WHERE comment_status = 0 ORDER BY comment_date DESC LIMIT :limit",nativeQuery = true)
List<Comment> getCommentsByLimit(@Param(value = "limit") int limit);
}

View File

@ -27,7 +27,7 @@ public interface PostRepository extends JpaRepository<Post, Long> {
*
* @return List
*/
@Query(value = "SELECT * FROM halo_post where post_type='post' ORDER BY post_date DESC LIMIT 5", nativeQuery = true)
@Query(value = "SELECT * FROM halo_post WHERE post_type='post' ORDER BY post_date DESC LIMIT 5", nativeQuery = true)
List<Post> findTopFive();
/**
@ -38,23 +38,27 @@ public interface PostRepository extends JpaRepository<Post, Long> {
*/
List<Post> findPostsByPostType(String postType);
/**
*
*
* @param postType post or page
* @param pageable
* @return Page
*/
Page<Post> findPostsByPostType(String postType, Pageable pageable);
/**
*
*
* @param keyWord keyword
* @param pageable pageable
* @return List
* @param postType0 postType0
* @param postStatus0 postStatus0
* @param postTitle postTitle
* @param postType1 postType1
* @param postStatus1 postStatus1
* @param postContent postContent
* @param pageable pageable
* @return Page
*/
List<Post> findByPostTitleLike(String keyWord, Pageable pageable);
Page<Post> findByPostTypeAndPostStatusAndPostTitleLikeOrPostTypeAndPostStatusAndPostContentLike(
String postType0,
Integer postStatus0,
String postTitle,
String postType1,
Integer postStatus1,
String postContent,
Pageable pageable
);
/**
*
@ -94,32 +98,29 @@ public interface PostRepository extends JpaRepository<Post, Long> {
Post findPostByPostIdAndPostType(Long postId, String postType);
/**
*
*
*
* @param postDate
* @param postStatus 012
* @param postType post or page
* @return List
* @param postDate
* @return Post
*/
List<Post> findByPostDateAfterAndPostStatusAndPostTypeOrderByPostDateDesc(Date postDate, Integer postStatus, String postType);
@Query(value = "SELECT * FROM halo_post WHERE post_status = 0 AND post_type='post' AND post_date < :postDate ORDER BY post_date DESC LIMIT 1", nativeQuery = true)
Post queryPrePost(@Param("postDate") Date postDate);
/**
*
*
*
* @param postDate
* @param postStatus 012
* @param postType post or page
* @return List
* @param postDate
* @return Post
*/
List<Post> findByPostDateBeforeAndPostStatusAndPostTypeOrderByPostDateAsc(Date postDate, Integer postStatus, String postType);
@Query(value = "SELECT * FROM halo_post WHERE post_status = 0 AND post_type='post' AND post_date > :postDate ORDER BY post_date ASC LIMIT 1", nativeQuery = true)
Post queryNextPost(@Param("postDate") Date postDate);
/**
*
*
* @return List
*/
@Query(value = "select year(post_date) as year,month(post_date) as month,count(*) as count from halo_post where post_status=0 and post_type='post' group by year(post_date),month(post_date) order by year desc,month desc", nativeQuery = true)
@Query(value = "SELECT YEAR(post_date) AS YEAR,MONTH(post_date) AS MONTH,COUNT(*) AS COUNT FROM halo_post WHERE post_status=0 and post_type='post' GROUP BY YEAR(post_date),MONTH(post_date) ORDER BY YEAR DESC,MONTH DESC", nativeQuery = true)
List<Object[]> findPostGroupByYearAndMonth();
/**
@ -127,9 +128,31 @@ public interface PostRepository extends JpaRepository<Post, Long> {
*
* @return List
*/
@Query(value = "select year(post_date) as year,count(*) as count from halo_post where post_status=0 and post_type='post' group by year(post_date) order by year desc", nativeQuery = true)
@Query(value = "SELECT YEAR(post_date) AS YEAR,COUNT(*) AS COUNT FROM halo_post WHERE post_status=0 AND post_type='post' GROUP BY YEAR(post_date) ORDER BY YEAR DESC", nativeQuery = true)
List<Object[]> findPostGroupByYear();
/**
* @return List
* @Author Aquan
* @Description
* @Date 2019.1.4 11:19
* @Param
**/
@Query(value = "SELECT *,YEAR(post_date) AS YEAR FROM halo_post WHERE post_status=0 AND post_type='post' ORDER BY post_date DESC", nativeQuery = true)
List<Post> findAllPost();
/**
* @return Integer
* @Author Aquan
* @Description
* @Date 2019.1.4 15:03
* @Param
**/
@Query(value = "SELECT count(1) AS COUNT FROM halo_post WHERE post_status=0 AND post_type='post'", nativeQuery = true)
Integer totalAllPostCount();
/**
*
*
@ -137,7 +160,7 @@ public interface PostRepository extends JpaRepository<Post, Long> {
* @param month month
* @return List
*/
@Query(value = "select *,year(post_date) as year,month(post_date) as month from halo_post where post_status=0 and post_type='post' and year(post_date)=:year and month(post_date)=:month order by post_date desc", nativeQuery = true)
@Query(value = "SELECT *,YEAR(post_date) AS YEAR,MONTH(post_date) AS MONTH FROM halo_post WHERE post_status=0 and post_type='post' AND YEAR(post_date)=:year AND MONTH(post_date)=:month ORDER BY post_date DESC", nativeQuery = true)
List<Post> findPostByYearAndMonth(@Param("year") String year, @Param("month") String month);
/**
@ -146,7 +169,7 @@ public interface PostRepository extends JpaRepository<Post, Long> {
* @param year year
* @return List
*/
@Query(value = "select *,year(post_date) as year from halo_post where post_status=0 and post_type='post' and year(post_date)=:year order by post_date desc", nativeQuery = true)
@Query(value = "SELECT *,YEAR(post_date) AS YEAR FROM halo_post WHERE post_status=0 AND post_type='post' AND YEAR(post_date)=:year ORDER BY post_date DESC", nativeQuery = true)
List<Post> findPostByYear(@Param("year") String year);
/**
@ -157,7 +180,7 @@ public interface PostRepository extends JpaRepository<Post, Long> {
* @param pageable pageable
* @return Page
*/
@Query(value = "select * from halo_post where post_status=0 and post_type='post' and year(post_date)=:year and month(post_date)=:month order by post_date desc", countQuery = "select count(*) from halo_post where post_status=0 and year(post_date)=:year and month(post_date)=:month", nativeQuery = true)
@Query(value = "SELECT * FROM halo_post WHERE post_status=0 and post_type='post' AND YEAR(post_date)=:year AND MONTH(post_date)=:month ORDER BY post_date DESC", countQuery = "SELECT COUNT(*) FROM halo_post WHERE post_status=0 AND YEAR(post_date)=:year AND MONTH(post_date)=:month", nativeQuery = true)
Page<Post> findPostByYearAndMonth(@Param("year") String year, @Param("month") String month, Pageable pageable);
/**
@ -188,16 +211,6 @@ public interface PostRepository extends JpaRepository<Post, Long> {
*/
List<Post> findPostsByTags(Tag tag);
/**
*
*
* @param keyword
* @param pageable
* @return Page
*/
@Query(value = "select * from halo_post where post_status = 0 and post_type='post' and post_title like '%=:keyword%' or post_content like '%=:keyword%'", nativeQuery = true)
Page<Post> findPostByPostTitleLikeOrPostContentLikeAndPostTypeAndPostStatus(String keyword, Pageable pageable);
/**
*
*
@ -211,7 +224,7 @@ public interface PostRepository extends JpaRepository<Post, Long> {
*
* @return Long
*/
@Query(value = "select sum(post_views) from halo_post", nativeQuery = true)
@Query(value = "SELECT SUM(post_views) FROM halo_post", nativeQuery = true)
Long getPostViewsSum();
/**
@ -222,4 +235,13 @@ public interface PostRepository extends JpaRepository<Post, Long> {
* @return
*/
Integer countAllByPostStatusAndPostType(Integer status, String postType);
/**
*
*
* @param limit
* @return List
*/
@Query(value = "SELECT * FROM halo_post WHERE post_status = 0 AND post_type = 'post' ORDER BY post_date DESC LIMIT :limit", nativeQuery = true)
List<Post> getPostsByLimit(@Param(value = "limit") int limit);
}

View File

@ -3,8 +3,11 @@ package cc.ryanc.halo.service;
import cc.ryanc.halo.model.domain.Attachment;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
@ -23,14 +26,14 @@ public interface AttachmentService {
* @param attachment attachment
* @return Attachment
*/
Attachment saveByAttachment(Attachment attachment);
Attachment save(Attachment attachment);
/**
*
*
* @return List
*/
List<Attachment> findAllAttachments();
List<Attachment> findAll();
/**
*
@ -38,7 +41,7 @@ public interface AttachmentService {
* @param pageable pageable
* @return Page
*/
Page<Attachment> findAllAttachments(Pageable pageable);
Page<Attachment> findAll(Pageable pageable);
/**
*
@ -54,5 +57,64 @@ public interface AttachmentService {
* @param attachId attachId
* @return Attachment
*/
Attachment removeByAttachId(Long attachId);
Attachment remove(Long attachId);
/**
*
*
* @param file file
* @param request request
* @return Map
*/
Map<String, String> upload(MultipartFile file, HttpServletRequest request);
/**
*
*
* @param file file
* @param request request
* @return Map
*/
Map<String, String> attachUpload(MultipartFile file, HttpServletRequest request);
/**
*
*
* @param file file
* @param request request
* @return Map
*/
Map<String, String> attachQiNiuUpload(MultipartFile file, HttpServletRequest request);
/**
*
*
* @param file file
* @param request request
* @return Map
*/
Map<String, String> attachUpYunUpload(MultipartFile file, HttpServletRequest request);
/**
*
*
* @param key key
* @return boolean
*/
boolean deleteQiNiuAttachment(String key);
/**
*
*
* @param fileName fileName
* @return boolean
*/
boolean deleteUpYunAttachment(String fileName);
/**
*
*
* @return Long
*/
Long getCount();
}

View File

@ -21,7 +21,7 @@ public interface CategoryService {
* @param category
* @return
*/
Category saveByCategory(Category category);
Category save(Category category);
/**
*
@ -29,14 +29,14 @@ public interface CategoryService {
* @param cateId
* @return category
*/
Category removeByCateId(Long cateId);
Category remove(Long cateId);
/**
*
*
* @return List
*/
List<Category> findAllCategories();
List<Category> findAll();
/**
*
@ -54,6 +54,14 @@ public interface CategoryService {
*/
Category findByCateUrl(String cateUrl);
/**
*
*
* @param cateName
* @return Category
*/
Category findByCateName(String cateName);
/**
* Category
*

View File

@ -23,7 +23,7 @@ public interface CommentService {
*
* @param comment comment
*/
void saveByComment(Comment comment);
void save(Comment comment);
/**
*
@ -31,7 +31,7 @@ public interface CommentService {
* @param commentId commentId
* @return Optional
*/
Optional<Comment> removeByCommentId(Long commentId);
Optional<Comment> remove(Long commentId);
/**
*
@ -40,7 +40,7 @@ public interface CommentService {
* @param pageable pageable
* @return Page
*/
Page<Comment> findAllComments(Integer status, Pageable pageable);
Page<Comment> findAll(Integer status, Pageable pageable);
/**
*
@ -48,14 +48,14 @@ public interface CommentService {
* @param status
* @return List
*/
List<Comment> findAllComments(Integer status);
List<Comment> findAll(Integer status);
/**
*
*
* @return List
*/
List<Comment> findAllComments();
List<Comment> findAll();
/**
*
@ -125,4 +125,19 @@ public interface CommentService {
* @return
*/
Integer getCountByStatus(Integer status);
/**
*
*
* @return Long
*/
Long getCount();
/**
*
*
* @param limit limit
* @return List
*/
List<Comment> getRecentComments(int limit);
}

View File

@ -23,7 +23,7 @@ public interface GalleryService {
* @param gallery gallery
* @return Gallery
*/
Gallery saveByGallery(Gallery gallery);
Gallery save(Gallery gallery);
/**
*
@ -31,15 +31,7 @@ public interface GalleryService {
* @param galleryId galleryId
* @return Gallery
*/
Gallery removeByGalleryId(Long galleryId);
/**
*
*
* @param gallery gallery
* @return Gallery
*/
Gallery updateByGallery(Gallery gallery);
Gallery remove(Long galleryId);
/**
*
@ -47,14 +39,14 @@ public interface GalleryService {
* @param pageable pageable
* @return Page
*/
Page<Gallery> findAllGalleries(Pageable pageable);
Page<Gallery> findAll(Pageable pageable);
/**
*
*
* @return List
*/
List<Gallery> findAllGalleries();
List<Gallery> findAll();
/**
*

View File

@ -21,7 +21,7 @@ public interface LinkService {
* @param link link
* @return Link
*/
Link saveByLink(Link link);
Link save(Link link);
/**
*
@ -29,14 +29,14 @@ public interface LinkService {
* @param linkId linkId
* @return Link
*/
Link removeByLinkId(Long linkId);
Link remove(Long linkId);
/**
*
*
* @return List
*/
List<Link> findAllLinks();
List<Link> findAll();
/**
*

View File

@ -4,8 +4,8 @@ import cc.ryanc.halo.model.domain.Logs;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Optional;
/**
* <pre>
@ -20,22 +20,16 @@ public interface LogsService {
/**
*
*
* @param logs logs
* @return Logs
* @param logTitle logTitle
* @param logContent logContent
* @param request request
*/
Logs saveByLogs(Logs logs);
/**
*
*
* @param logsId logsId
*/
void removeByLogsId(Long logsId);
void save(String logTitle, String logContent, HttpServletRequest request);
/**
*
*/
void removeAllLogs();
void removeAll();
/**
*
@ -43,7 +37,7 @@ public interface LogsService {
* @param pageable pageable
* @return Page
*/
Page<Logs> findAllLogs(Pageable pageable);
Page<Logs> findAll(Pageable pageable);
/**
*
@ -51,12 +45,4 @@ public interface LogsService {
* @return List
*/
List<Logs> findLogsLatest();
/**
*
*
* @param logsId logsId
* @return Optional
*/
Optional<Logs> findLogsByLogsId(Long logsId);
}

View File

@ -21,14 +21,14 @@ public interface MenuService {
* @param menu menu
* @return Menu
*/
Menu saveByMenu(Menu menu);
Menu save(Menu menu);
/**
*
*
* @return List
*/
List<Menu> findAllMenus();
List<Menu> findAll();
/**
*
@ -36,7 +36,7 @@ public interface MenuService {
* @param menuId menuId
* @return Menu
*/
Menu removeByMenuId(Long menuId);
Menu remove(Long menuId);
/**
*

View File

@ -6,6 +6,7 @@ import cc.ryanc.halo.model.domain.Tag;
import cc.ryanc.halo.model.dto.Archive;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Date;
import java.util.List;
@ -27,7 +28,7 @@ public interface PostService {
* @param post Post
* @return Post
*/
Post saveByPost(Post post);
Post save(Post post);
/**
*
@ -35,7 +36,7 @@ public interface PostService {
* @param postId postId
* @return Post
*/
Post removeByPostId(Long postId);
Post remove(Long postId);
/**
*
@ -46,13 +47,6 @@ public interface PostService {
*/
Post updatePostStatus(Long postId, Integer status);
/**
*
*
* @param post post
*/
void updatePostView(Post post);
/**
*
*
@ -60,31 +54,24 @@ public interface PostService {
*/
void updateAllSummary(Integer postSummary);
/**
*
*
* @param postType post or page
* @param pageable
* @return Page
*/
Page<Post> findAllPosts(String postType, Pageable pageable);
/**
*
*
* @param postType post or page
* @return List
*/
List<Post> findAllPosts(String postType);
List<Post> findAll(String postType);
/**
*
*
* @param keyWord keyword
* @param pageable pageable
* @return List
* @param keyword
* @param postType
* @param postStatus
* @param pageable
* @return Page
*/
List<Post> searchPosts(String keyWord, Pageable pageable);
Page<Post> searchPosts(String keyword, String postType, Integer postStatus, Pageable pageable);
/**
*
@ -147,20 +134,20 @@ public interface PostService {
List<Post> findPostLatest();
/**
* Id
*
*
* @param postDate postDate
* @return List
* @return Post
*/
List<Post> findByPostDateAfter(Date postDate);
Post getNextPost(Date postDate);
/**
* Id
*
*
* @param postDate postDate
* @return List
* @return Post
*/
List<Post> findByPostDateBefore(Date postDate);
Post getPrePost(Date postDate);
/**
*
@ -176,6 +163,16 @@ public interface PostService {
*/
List<Archive> findPostGroupByYear();
/**
* @return List
* @Author Aquan
* @Description
* @Date 2019.1.4 11:14
* @Param
**/
List<Archive> findAllPost();
/**
*
*
@ -221,15 +218,6 @@ public interface PostService {
*/
Page<Post> findPostsByTags(Tag tag, Pageable pageable);
/**
*
*
* @param keyword
* @param pageable
* @return Page
*/
Page<Post> searchByKeywords(String keyword, Pageable pageable);
/**
*
*
@ -275,4 +263,29 @@ public interface PostService {
* @return String
*/
String buildSiteMap(List<Post> posts);
/**
*
*
* @param postId postId
*/
void cacheViews(Long postId);
/**
*
*
* @param post post
* @param cateList cateList
* @param tagList tagList
* @return Post Post
*/
Post buildCategoriesAndTags(Post post, List<String> cateList, @RequestParam("tagList") String tagList);
/**
*
*
* @param limit
* @return List
*/
List<Post> getRecentPosts(int limit);
}

View File

@ -21,7 +21,7 @@ public interface TagService {
* @param tag tag
* @return Tag
*/
Tag saveByTag(Tag tag);
Tag save(Tag tag);
/**
*
@ -29,14 +29,14 @@ public interface TagService {
* @param tagId tagId
* @return Tag
*/
Tag removeByTagId(Long tagId);
Tag remove(Long tagId);
/**
*
*
* @return List
*/
List<Tag> findAllTags();
List<Tag> findAll();
/**
*

View File

@ -19,7 +19,7 @@ public interface UserService {
*
* @param user user
*/
void saveByUser(User user);
void save(User user);
/**
*

View File

@ -1,17 +1,46 @@
package cc.ryanc.halo.service.impl;
import cc.ryanc.halo.model.domain.Attachment;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.QiNiuPutSet;
import cc.ryanc.halo.model.enums.AttachLocationEnum;
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.repository.AttachmentRepository;
import cc.ryanc.halo.service.AttachmentService;
import cc.ryanc.halo.utils.HaloUtils;
import cc.ryanc.halo.utils.Md5Util;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import com.UpYun;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.persistent.FileRecorder;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import com.upyun.UpException;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Optional;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.*;
/**
* <pre>
@ -37,7 +66,7 @@ public class AttachmentServiceImpl implements AttachmentService {
*/
@Override
@CacheEvict(value = ATTACHMENTS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Attachment saveByAttachment(Attachment attachment) {
public Attachment save(Attachment attachment) {
return attachmentRepository.save(attachment);
}
@ -48,7 +77,7 @@ public class AttachmentServiceImpl implements AttachmentService {
*/
@Override
@Cacheable(value = ATTACHMENTS_CACHE_NAME, key = "'attachment'")
public List<Attachment> findAllAttachments() {
public List<Attachment> findAll() {
return attachmentRepository.findAll();
}
@ -59,7 +88,7 @@ public class AttachmentServiceImpl implements AttachmentService {
* @return Page
*/
@Override
public Page<Attachment> findAllAttachments(Pageable pageable) {
public Page<Attachment> findAll(Pageable pageable) {
return attachmentRepository.findAll(pageable);
}
@ -82,9 +111,307 @@ public class AttachmentServiceImpl implements AttachmentService {
*/
@Override
@CacheEvict(value = ATTACHMENTS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Attachment removeByAttachId(Long attachId) {
public Attachment remove(Long attachId) {
Optional<Attachment> attachment = this.findByAttachId(attachId);
attachmentRepository.delete(attachment.get());
return attachment.get();
attachmentRepository.delete(attachment.orElse(null));
return attachment.orElse(null);
}
/**
*
*
* @param file file
* @param request request
* @return Map
*/
@Override
public Map<String, String> upload(MultipartFile file, HttpServletRequest request) {
Map<String, String> resultMap;
String attachLoc = HaloConst.OPTIONS.get(BlogPropertiesEnum.ATTACH_LOC.getProp());
if (StrUtil.isEmpty(attachLoc)) {
attachLoc = "server";
}
switch (attachLoc) {
case "server":
resultMap = this.attachUpload(file, request);
break;
case "qiniu":
resultMap = this.attachQiNiuUpload(file, request);
break;
case "upyun":
resultMap = this.attachUpYunUpload(file, request);
break;
default:
resultMap = this.attachUpload(file, request);
break;
}
return resultMap;
}
/**
*
*
* @param file file
* @param request request
* @return Map
*/
@Override
public Map<String, String> attachUpload(MultipartFile file, HttpServletRequest request) {
final Map<String, String> resultMap = new HashMap<>(6);
final String dateString = DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss");
try {
//用户目录
final StrBuilder uploadPath = new StrBuilder(System.getProperties().getProperty("user.home"));
uploadPath.append("/halo/");
uploadPath.append("upload/");
//获取当前年月以创建目录,如果没有该目录则创建
uploadPath.append(DateUtil.thisYear()).append("/").append(DateUtil.thisMonth()).append("/");
final File mediaPath = new File(uploadPath.toString());
if (!mediaPath.exists()) {
if (!mediaPath.mkdirs()) {
resultMap.put("success", "0");
return resultMap;
}
}
//不带后缀
final StrBuilder nameWithOutSuffix = new StrBuilder(file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf('.')).replaceAll(" ", "_").replaceAll(",", ""));
nameWithOutSuffix.append(dateString);
nameWithOutSuffix.append(new Random().nextInt(1000));
//文件后缀
final String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.') + 1);
//带后缀
final StrBuilder fileName = new StrBuilder(nameWithOutSuffix);
fileName.append(".");
fileName.append(fileSuffix);
file.transferTo(new File(mediaPath.getAbsoluteFile(), fileName.toString()));
//文件原路径
final StrBuilder fullPath = new StrBuilder(mediaPath.getAbsolutePath());
fullPath.append("/");
fullPath.append(fileName);
//压缩文件路径
final StrBuilder fullSmallPath = new StrBuilder(mediaPath.getAbsolutePath());
fullSmallPath.append("/");
fullSmallPath.append(nameWithOutSuffix);
fullSmallPath.append("_small.");
fullSmallPath.append(fileSuffix);
//压缩图片
Thumbnails.of(fullPath.toString()).size(256, 256).keepAspectRatio(false).toFile(fullSmallPath.toString());
//映射路径
final StrBuilder filePath = new StrBuilder("/upload/");
filePath.append(DateUtil.thisYear());
filePath.append("/");
filePath.append(DateUtil.thisMonth());
filePath.append("/");
filePath.append(fileName);
//缩略图映射路径
final StrBuilder fileSmallPath = new StrBuilder("/upload/");
fileSmallPath.append(DateUtil.thisYear());
fileSmallPath.append("/");
fileSmallPath.append(DateUtil.thisMonth());
fileSmallPath.append("/");
fileSmallPath.append(nameWithOutSuffix);
fileSmallPath.append("_small.");
fileSmallPath.append(fileSuffix);
final String size = HaloUtils.parseSize(new File(fullPath.toString()).length());
final String wh = HaloUtils.getImageWh(new File(fullPath.toString()));
resultMap.put("fileName", fileName.toString());
resultMap.put("filePath", filePath.toString());
resultMap.put("smallPath", fileSmallPath.toString());
resultMap.put("suffix", fileSuffix);
resultMap.put("size", size);
resultMap.put("wh", wh);
resultMap.put("location", AttachLocationEnum.SERVER.getDesc());
} catch (IOException e) {
e.printStackTrace();
}
return resultMap;
}
/**
*
*
* @param file file
* @param request request
* @return Map
*/
@Override
public Map<String, String> attachQiNiuUpload(MultipartFile file, HttpServletRequest request) {
final Map<String, String> resultMap = new HashMap<>(6);
try {
final Configuration cfg = new Configuration(Zone.zone0());
final String key = Md5Util.getMD5Checksum(file);
final String accessKey = HaloConst.OPTIONS.get("qiniu_access_key");
final String secretKey = HaloConst.OPTIONS.get("qiniu_secret_key");
final String domain = HaloConst.OPTIONS.get("qiniu_domain");
final String bucket = HaloConst.OPTIONS.get("qiniu_bucket");
final String smallUrl = HaloConst.OPTIONS.get("qiniu_small_url");
if (StrUtil.isEmpty(accessKey) || StrUtil.isEmpty(secretKey) || StrUtil.isEmpty(domain) || StrUtil.isEmpty(bucket)) {
return resultMap;
}
final Auth auth = Auth.create(accessKey, secretKey);
final StringMap putPolicy = new StringMap();
putPolicy.put("returnBody", "{\"size\":$(fsize),\"w\":$(imageInfo.width),\"h\":$(imageInfo.height)}");
final String upToken = auth.uploadToken(bucket, null, 3600, putPolicy);
final String localTempDir = Paths.get(System.getenv("java.io.tmpdir"), bucket).toString();
QiNiuPutSet putSet = new QiNiuPutSet();
try {
final FileRecorder fileRecorder = new FileRecorder(localTempDir);
final UploadManager uploadManager = new UploadManager(cfg, fileRecorder);
final Response response = uploadManager.put(file.getInputStream(), key, upToken, null, null);
//解析上传成功的结果
putSet = new Gson().fromJson(response.bodyString(), QiNiuPutSet.class);
} catch (QiniuException e) {
final Response r = e.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
} catch (JsonSyntaxException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
final String filePath = domain.trim() + "/" + key;
resultMap.put("fileName", file.getOriginalFilename());
resultMap.put("filePath", filePath.trim());
resultMap.put("smallPath", smallUrl == null ? filePath.trim() : (filePath + smallUrl).trim());
resultMap.put("suffix", file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')));
resultMap.put("size", HaloUtils.parseSize(file.getSize()));
resultMap.put("wh", putSet.getW() + "x" + putSet.getH());
resultMap.put("location", AttachLocationEnum.QINIU.getDesc());
} catch (Exception e) {
e.printStackTrace();
}
return resultMap;
}
/**
*
*
* @param file file
* @param request request
* @return Map
*/
@Override
public Map<String, String> attachUpYunUpload(MultipartFile file, HttpServletRequest request) {
final Map<String, String> resultMap = new HashMap<>(6);
try {
final String key = Md5Util.getMD5Checksum(file);
final String ossSrc = HaloConst.OPTIONS.get("upyun_oss_src");
final String ossPwd = HaloConst.OPTIONS.get("upyun_oss_pwd");
final String bucket = HaloConst.OPTIONS.get("upyun_oss_bucket");
final String domain = HaloConst.OPTIONS.get("upyun_oss_domain");
final String operator = HaloConst.OPTIONS.get("upyun_oss_operator");
final String smallUrl = HaloConst.OPTIONS.get("upyun_oss_small");
if (StrUtil.isEmpty(ossSrc) || StrUtil.isEmpty(ossPwd) || StrUtil.isEmpty(domain) || StrUtil.isEmpty(bucket) || StrUtil.isEmpty(operator)) {
return resultMap;
}
final String fileName = file.getOriginalFilename();
final String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.'));
final UpYun upYun = new UpYun(bucket, operator, ossPwd);
upYun.setTimeout(60);
upYun.setApiDomain(UpYun.ED_AUTO);
upYun.setDebug(true);
upYun.writeFile(ossSrc + key + fileSuffix, file.getBytes(), true, null);
final String filePath = domain.trim() + ossSrc + key + fileSuffix;
String smallPath = filePath;
if (smallUrl != null) {
smallPath += smallUrl;
}
final BufferedImage image = ImageIO.read(file.getInputStream());
if (image != null) {
resultMap.put("wh", image.getWidth() + "x" + image.getHeight());
}
resultMap.put("fileName", fileName);
resultMap.put("filePath", filePath.trim());
resultMap.put("smallPath", smallPath.trim());
resultMap.put("suffix", fileSuffix);
resultMap.put("size", HaloUtils.parseSize(file.getSize()));
resultMap.put("location", AttachLocationEnum.UPYUN.getDesc());
} catch (Exception e) {
e.printStackTrace();
}
return resultMap;
}
/**
*
*
* @param key key
* @return boolean
*/
@Override
public boolean deleteQiNiuAttachment(String key) {
boolean flag = true;
final Configuration cfg = new Configuration(Zone.zone0());
final String accessKey = HaloConst.OPTIONS.get("qiniu_access_key");
final String secretKey = HaloConst.OPTIONS.get("qiniu_secret_key");
final String bucket = HaloConst.OPTIONS.get("qiniu_bucket");
if (StrUtil.isEmpty(accessKey) || StrUtil.isEmpty(secretKey) || StrUtil.isEmpty(bucket)) {
return false;
}
final Auth auth = Auth.create(accessKey, secretKey);
final BucketManager bucketManager = new BucketManager(auth, cfg);
try {
bucketManager.delete(bucket, key);
} catch (QiniuException ex) {
System.err.println(ex.code());
System.err.println(ex.response.toString());
flag = false;
}
return flag;
}
/**
*
*
* @param fileName fileName
* @return boolean
*/
@Override
public boolean deleteUpYunAttachment(String fileName) {
boolean flag = true;
final String ossSrc = HaloConst.OPTIONS.get("upyun_oss_src");
final String ossPwd = HaloConst.OPTIONS.get("upyun_oss_pwd");
final String bucket = HaloConst.OPTIONS.get("upyun_oss_bucket");
final String operator = HaloConst.OPTIONS.get("upyun_oss_operator");
if (StrUtil.isEmpty(ossSrc) || StrUtil.isEmpty(ossPwd) || StrUtil.isEmpty(bucket) || StrUtil.isEmpty(operator)) {
return false;
}
final UpYun upYun = new UpYun(bucket, operator, ossPwd);
upYun.setApiDomain(UpYun.ED_AUTO);
try {
flag = upYun.deleteFile(ossSrc + fileName);
} catch (IOException e) {
e.printStackTrace();
} catch (UpException e) {
e.printStackTrace();
}
return flag;
}
/**
*
*
* @return Long
*/
@Override
public Long getCount() {
return attachmentRepository.count();
}
}

View File

@ -4,6 +4,7 @@ import cc.ryanc.halo.model.domain.Category;
import cc.ryanc.halo.repository.CategoryRepository;
import cc.ryanc.halo.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@ -21,6 +22,8 @@ import java.util.Optional;
@Service
public class CategoryServiceImpl implements CategoryService {
private static final String POSTS_CACHE_NAME = "posts";
@Autowired
private CategoryRepository categoryRepository;
@ -31,7 +34,8 @@ public class CategoryServiceImpl implements CategoryService {
* @return Category
*/
@Override
public Category saveByCategory(Category category) {
@CacheEvict(value = POSTS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Category save(Category category) {
return categoryRepository.save(category);
}
@ -42,10 +46,11 @@ public class CategoryServiceImpl implements CategoryService {
* @return Category
*/
@Override
public Category removeByCateId(Long cateId) {
Optional<Category> category = this.findByCateId(cateId);
categoryRepository.delete(category.get());
return category.get();
@CacheEvict(value = POSTS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Category remove(Long cateId) {
final Optional<Category> category = this.findByCateId(cateId);
categoryRepository.delete(category.orElse(null));
return category.orElse(null);
}
/**
@ -54,7 +59,7 @@ public class CategoryServiceImpl implements CategoryService {
* @return List
*/
@Override
public List<Category> findAllCategories() {
public List<Category> findAll() {
return categoryRepository.findAll();
}
@ -80,6 +85,17 @@ public class CategoryServiceImpl implements CategoryService {
return categoryRepository.findCategoryByCateUrl(cateUrl);
}
/**
*
*
* @param cateName
* @return Category
*/
@Override
public Category findByCateName(String cateName) {
return categoryRepository.findCategoryByCateName(cateName);
}
/**
* Category
*
@ -91,7 +107,7 @@ public class CategoryServiceImpl implements CategoryService {
if (null == strings) {
return null;
}
List<Category> categories = new ArrayList<>();
final List<Category> categories = new ArrayList<>();
Optional<Category> category = null;
for (String str : strings) {
category = findByCateId(Long.parseLong(str));

View File

@ -40,7 +40,7 @@ public class CommentServiceImpl implements CommentService {
*/
@Override
@CacheEvict(value = {COMMENTS_CACHE_NAME, POSTS_CACHE_NAME}, allEntries = true, beforeInvocation = true)
public void saveByComment(Comment comment) {
public void save(Comment comment) {
commentRepository.save(comment);
}
@ -52,9 +52,9 @@ public class CommentServiceImpl implements CommentService {
*/
@Override
@CacheEvict(value = {COMMENTS_CACHE_NAME, POSTS_CACHE_NAME}, allEntries = true, beforeInvocation = true)
public Optional<Comment> removeByCommentId(Long commentId) {
Optional<Comment> comment = this.findCommentById(commentId);
commentRepository.delete(comment.get());
public Optional<Comment> remove(Long commentId) {
final Optional<Comment> comment = this.findCommentById(commentId);
commentRepository.delete(comment.orElse(null));
return comment;
}
@ -65,7 +65,7 @@ public class CommentServiceImpl implements CommentService {
* @return Page
*/
@Override
public Page<Comment> findAllComments(Integer status, Pageable pageable) {
public Page<Comment> findAll(Integer status, Pageable pageable) {
return commentRepository.findCommentsByCommentStatus(status, pageable);
}
@ -77,7 +77,7 @@ public class CommentServiceImpl implements CommentService {
*/
@Override
@CachePut(value = COMMENTS_CACHE_NAME, key = "'comments_status_'+#status")
public List<Comment> findAllComments(Integer status) {
public List<Comment> findAll(Integer status) {
return commentRepository.findCommentsByCommentStatus(status);
}
@ -88,7 +88,7 @@ public class CommentServiceImpl implements CommentService {
*/
@Override
@Cacheable(value = COMMENTS_CACHE_NAME, key = "'comment'")
public List<Comment> findAllComments() {
public List<Comment> findAll() {
return commentRepository.findAll();
}
@ -102,7 +102,7 @@ public class CommentServiceImpl implements CommentService {
@Override
@CacheEvict(value = COMMENTS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Comment updateCommentStatus(Long commentId, Integer status) {
Optional<Comment> comment = findCommentById(commentId);
final Optional<Comment> comment = findCommentById(commentId);
comment.get().setCommentStatus(status);
return commentRepository.save(comment.get());
}
@ -188,4 +188,25 @@ public class CommentServiceImpl implements CommentService {
public Integer getCountByStatus(Integer status) {
return commentRepository.countAllByCommentStatus(status);
}
/**
*
*
* @return Long
*/
@Override
public Long getCount() {
return commentRepository.count();
}
/**
*
*
* @param limit limit
* @return List
*/
@Override
public List<Comment> getRecentComments(int limit) {
return commentRepository.getCommentsByLimit(limit);
}
}

View File

@ -37,7 +37,7 @@ public class GalleryServiceImpl implements GalleryService {
*/
@Override
@CacheEvict(value = GALLERIES_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Gallery saveByGallery(Gallery gallery) {
public Gallery save(Gallery gallery) {
return galleryRepository.save(gallery);
}
@ -49,24 +49,12 @@ public class GalleryServiceImpl implements GalleryService {
*/
@Override
@CacheEvict(value = GALLERIES_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Gallery removeByGalleryId(Long galleryId) {
Optional<Gallery> gallery = this.findByGalleryId(galleryId);
public Gallery remove(Long galleryId) {
final Optional<Gallery> gallery = this.findByGalleryId(galleryId);
galleryRepository.delete(gallery.get());
return gallery.get();
}
/**
*
*
* @param gallery gallery
* @return Gallery
*/
@Override
@CacheEvict(value = GALLERIES_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Gallery updateByGallery(Gallery gallery) {
return galleryRepository.save(gallery);
}
/**
*
*
@ -74,7 +62,7 @@ public class GalleryServiceImpl implements GalleryService {
* @return Page
*/
@Override
public Page<Gallery> findAllGalleries(Pageable pageable) {
public Page<Gallery> findAll(Pageable pageable) {
return galleryRepository.findAll(pageable);
}
@ -85,7 +73,7 @@ public class GalleryServiceImpl implements GalleryService {
*/
@Override
@Cacheable(value = GALLERIES_CACHE_NAME, key = "'gallery'")
public List<Gallery> findAllGalleries() {
public List<Gallery> findAll() {
return galleryRepository.findAll();
}

View File

@ -37,7 +37,7 @@ public class LinkServiceImpl implements LinkService {
*/
@Override
@CacheEvict(value = LINKS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Link saveByLink(Link link) {
public Link save(Link link) {
return linkRepository.save(link);
}
@ -49,8 +49,8 @@ public class LinkServiceImpl implements LinkService {
*/
@Override
@CacheEvict(value = LINKS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Link removeByLinkId(Long linkId) {
Optional<Link> link = this.findByLinkId(linkId);
public Link remove(Long linkId) {
final Optional<Link> link = this.findByLinkId(linkId);
linkRepository.delete(link.get());
return link.get();
}
@ -62,7 +62,7 @@ public class LinkServiceImpl implements LinkService {
*/
@Override
@Cacheable(value = LINKS_CACHE_NAME, key = LINKS_CACHE_KEY)
public List<Link> findAllLinks() {
public List<Link> findAll() {
return linkRepository.findAll();
}

View File

@ -3,13 +3,15 @@ package cc.ryanc.halo.service.impl;
import cc.ryanc.halo.model.domain.Logs;
import cc.ryanc.halo.repository.LogsRepository;
import cc.ryanc.halo.service.LogsService;
import cn.hutool.extra.servlet.ServletUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Optional;
/**
* <pre>
@ -28,30 +30,24 @@ public class LogsServiceImpl implements LogsService {
/**
*
*
* @param logs logs
* @return Logs
* @param logTitle logTitle
* @param logContent logContent
* @param request request
*/
@Override
public Logs saveByLogs(Logs logs) {
return logsRepository.save(logs);
}
/**
*
*
* @param logsId logsId
*/
@Override
public void removeByLogsId(Long logsId) {
Optional<Logs> logs = this.findLogsByLogsId(logsId);
logsRepository.delete(logs.get());
public void save(String logTitle, String logContent, HttpServletRequest request) {
final Logs logs = new Logs();
logs.setLogTitle(logTitle);
logs.setLogContent(logContent);
logs.setLogIp(ServletUtil.getClientIP(request));
logsRepository.save(logs);
}
/**
*
*/
@Override
public void removeAllLogs() {
public void removeAll() {
logsRepository.deleteAll();
}
@ -62,7 +58,7 @@ public class LogsServiceImpl implements LogsService {
* @return Page
*/
@Override
public Page<Logs> findAllLogs(Pageable pageable) {
public Page<Logs> findAll(Pageable pageable) {
return logsRepository.findAll(pageable);
}
@ -75,15 +71,4 @@ public class LogsServiceImpl implements LogsService {
public List<Logs> findLogsLatest() {
return logsRepository.findTopFive();
}
/**
*
*
* @param logsId logsId
* @return Optional
*/
@Override
public Optional<Logs> findLogsByLogsId(Long logsId) {
return logsRepository.findById(logsId);
}
}

View File

@ -4,6 +4,7 @@ import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.service.MailService;
import cc.ryanc.halo.utils.HaloUtils;
import cn.hutool.core.text.StrBuilder;
import freemarker.template.Template;
import io.github.biezhi.ome.OhMyEmail;
import org.springframework.beans.factory.annotation.Autowired;
@ -68,14 +69,14 @@ public class MailServiceImpl implements MailService {
HaloConst.OPTIONS.get(BlogPropertiesEnum.MAIL_SMTP_HOST.getProp()),
HaloConst.OPTIONS.get(BlogPropertiesEnum.MAIL_SMTP_USERNAME.getProp()),
HaloConst.OPTIONS.get(BlogPropertiesEnum.MAIL_SMTP_PASSWORD.getProp()));
String text = "";
StrBuilder text = new StrBuilder();
try {
Template template = freeMarker.getConfiguration().getTemplate(templateName);
text = FreeMarkerTemplateUtils.processTemplateIntoString(template, content);
final Template template = freeMarker.getConfiguration().getTemplate(templateName);
text.append(FreeMarkerTemplateUtils.processTemplateIntoString(template, content));
OhMyEmail.subject(subject)
.from(HaloConst.OPTIONS.get(BlogPropertiesEnum.MAIL_FROM_NAME.getProp()))
.to(to)
.html(text)
.html(text.toString())
.send();
} catch (Exception e) {
e.printStackTrace();
@ -99,14 +100,14 @@ public class MailServiceImpl implements MailService {
HaloConst.OPTIONS.get(BlogPropertiesEnum.MAIL_SMTP_USERNAME.getProp()),
HaloConst.OPTIONS.get(BlogPropertiesEnum.MAIL_SMTP_PASSWORD.getProp()));
File file = new File(attachSrc);
String text = "";
StrBuilder text = new StrBuilder();
try {
Template template = freeMarker.getConfiguration().getTemplate(templateName);
text = FreeMarkerTemplateUtils.processTemplateIntoString(template, content);
final Template template = freeMarker.getConfiguration().getTemplate(templateName);
text.append(FreeMarkerTemplateUtils.processTemplateIntoString(template, content));
OhMyEmail.subject(subject)
.from(HaloConst.OPTIONS.get(BlogPropertiesEnum.MAIL_FROM_NAME.getProp()))
.to(to)
.html(text)
.html(text.toString())
.attach(file, file.getName())
.send();
} catch (Exception e) {

View File

@ -36,7 +36,7 @@ public class MenuServiceImpl implements MenuService {
*/
@Override
@Cacheable(value = MENUS_CACHE_NAME, key = MENUS_CACHE_KEY)
public List<Menu> findAllMenus() {
public List<Menu> findAll() {
return menuRepository.findAll();
}
@ -48,7 +48,7 @@ public class MenuServiceImpl implements MenuService {
*/
@Override
@CacheEvict(value = MENUS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Menu saveByMenu(Menu menu) {
public Menu save(Menu menu) {
return menuRepository.save(menu);
}
@ -60,10 +60,10 @@ public class MenuServiceImpl implements MenuService {
*/
@Override
@CacheEvict(value = MENUS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Menu removeByMenuId(Long menuId) {
Optional<Menu> menu = this.findByMenuId(menuId);
menuRepository.delete(menu.get());
return menu.get();
public Menu remove(Long menuId) {
final Optional<Menu> menu = this.findByMenuId(menuId);
menuRepository.delete(menu.orElse(null));
return menu.orElse(null);
}
/**

View File

@ -5,6 +5,7 @@ import cc.ryanc.halo.repository.OptionsRepository;
import cc.ryanc.halo.service.OptionsService;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import java.util.HashMap;
@ -25,12 +26,15 @@ public class OptionsServiceImpl implements OptionsService {
@Autowired
private OptionsRepository optionsRepository;
private static final String POSTS_CACHE_NAME = "posts";
/**
*
*
* @param options options
*/
@Override
@CacheEvict(value = POSTS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public void saveOptions(Map<String, String> options) {
if (null != options && !options.isEmpty()) {
options.forEach((k, v) -> saveOption(k, v));
@ -84,8 +88,8 @@ public class OptionsServiceImpl implements OptionsService {
*/
@Override
public Map<String, String> findAllOptions() {
Map<String, String> options = new HashMap<>();
List<Options> optionsList = optionsRepository.findAll();
final Map<String, String> options = new HashMap<>();
final List<Options> optionsList = optionsRepository.findAll();
if (null != optionsList) {
optionsList.forEach(option -> options.put(option.getOptionName(), option.getOptionValue()));
}
@ -100,7 +104,7 @@ public class OptionsServiceImpl implements OptionsService {
*/
@Override
public String findOneOption(String key) {
Options options = optionsRepository.findOptionsByOptionName(key);
final Options options = optionsRepository.findOptionsByOptionName(key);
if (null != options) {
return options.getOptionValue();
}

View File

@ -4,11 +4,16 @@ import cc.ryanc.halo.model.domain.Category;
import cc.ryanc.halo.model.domain.Post;
import cc.ryanc.halo.model.domain.Tag;
import cc.ryanc.halo.model.dto.Archive;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.model.enums.PostStatusEnum;
import cc.ryanc.halo.model.enums.PostTypeEnum;
import cc.ryanc.halo.repository.PostRepository;
import cc.ryanc.halo.service.CategoryService;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.service.TagService;
import cc.ryanc.halo.utils.HaloUtils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import org.springframework.beans.factory.annotation.Autowired;
@ -42,6 +47,12 @@ public class PostServiceImpl implements PostService {
@Autowired
private PostRepository postRepository;
@Autowired
private CategoryService categoryService;
@Autowired
private TagService tagService;
/**
*
*
@ -50,7 +61,18 @@ public class PostServiceImpl implements PostService {
*/
@Override
@CacheEvict(value = {POSTS_CACHE_NAME, COMMENTS_CACHE_NAME}, allEntries = true, beforeInvocation = true)
public Post saveByPost(Post post) {
public Post save(Post post) {
int postSummary = 50;
if (StrUtil.isNotEmpty(HaloConst.OPTIONS.get(BlogPropertiesEnum.POST_SUMMARY.getProp()))) {
postSummary = Integer.parseInt(HaloConst.OPTIONS.get(BlogPropertiesEnum.POST_SUMMARY.getProp()));
}
final String summaryText = StrUtil.cleanBlank(HtmlUtil.cleanHtmlTag(post.getPostContent()));
if (summaryText.length() > postSummary) {
final String summary = summaryText.substring(0, postSummary);
post.setPostSummary(summary);
} else {
post.setPostSummary(summaryText);
}
return postRepository.save(post);
}
@ -62,8 +84,8 @@ public class PostServiceImpl implements PostService {
*/
@Override
@CacheEvict(value = {POSTS_CACHE_NAME, COMMENTS_CACHE_NAME}, allEntries = true, beforeInvocation = true)
public Post removeByPostId(Long postId) {
Optional<Post> post = this.findByPostId(postId);
public Post remove(Long postId) {
final Optional<Post> post = this.findByPostId(postId);
postRepository.delete(post.get());
return post.get();
}
@ -78,22 +100,11 @@ public class PostServiceImpl implements PostService {
@Override
@CacheEvict(value = POSTS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Post updatePostStatus(Long postId, Integer status) {
Optional<Post> post = this.findByPostId(postId);
final Optional<Post> post = this.findByPostId(postId);
post.get().setPostStatus(status);
return postRepository.save(post.get());
}
/**
*
*
* @param post post
*/
@Override
public void updatePostView(Post post) {
post.setPostViews(post.getPostViews() + 1);
postRepository.save(post);
}
/**
*
*
@ -102,9 +113,9 @@ public class PostServiceImpl implements PostService {
@Override
@CacheEvict(value = POSTS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public void updateAllSummary(Integer postSummary) {
List<Post> posts = this.findAllPosts(PostTypeEnum.POST_TYPE_POST.getDesc());
final List<Post> posts = this.findAll(PostTypeEnum.POST_TYPE_POST.getDesc());
for (Post post : posts) {
String text = StrUtil.trim(HtmlUtil.cleanHtmlTag(post.getPostContent()));
String text = StrUtil.cleanBlank(HtmlUtil.cleanHtmlTag(post.getPostContent()));
if (text.length() > postSummary) {
post.setPostSummary(text.substring(0, postSummary));
} else {
@ -114,18 +125,6 @@ public class PostServiceImpl implements PostService {
}
}
/**
*
*
* @param postType post or page
* @param pageable
* @return Page
*/
@Override
public Page<Post> findAllPosts(String postType, Pageable pageable) {
return postRepository.findPostsByPostType(postType, pageable);
}
/**
*
*
@ -134,20 +133,36 @@ public class PostServiceImpl implements PostService {
*/
@Override
@Cacheable(value = POSTS_CACHE_NAME, key = "'posts_type_'+#postType")
public List<Post> findAllPosts(String postType) {
public List<Post> findAll(String postType) {
return postRepository.findPostsByPostType(postType);
}
/**
*
*
* @param keyWord keyword
* @param pageable pageable
* @return List
* @param keyword
* @param postType
* @param postStatus
* @param pageable
* @return Page
*/
@Override
public List<Post> searchPosts(String keyWord, Pageable pageable) {
return postRepository.findByPostTitleLike(keyWord, pageable);
public Page<Post> searchPosts(String keyword, String postType, Integer postStatus, Pageable pageable) {
Page<Post> posts = postRepository.findByPostTypeAndPostStatusAndPostTitleLikeOrPostTypeAndPostStatusAndPostContentLike(
postType,
postStatus,
"%" + keyword + "%",
postType,
postStatus,
"%" + keyword + "%",
pageable
);
for (Post post : posts.getContent()) {
if (StrUtil.isNotEmpty(post.getPostPassword())) {
post.setPostSummary("该文章为加密文章");
}
}
return posts;
}
/**
@ -160,7 +175,13 @@ public class PostServiceImpl implements PostService {
*/
@Override
public Page<Post> findPostByStatus(Integer status, String postType, Pageable pageable) {
return postRepository.findPostsByPostStatusAndPostType(status, postType, pageable);
Page<Post> posts = postRepository.findPostsByPostStatusAndPostType(status, postType, pageable);
for (Post post : posts.getContent()) {
if (StrUtil.isNotEmpty(post.getPostPassword())) {
post.setPostSummary("该文章为加密文章");
}
}
return posts;
}
/**
@ -172,7 +193,13 @@ public class PostServiceImpl implements PostService {
@Override
@Cacheable(value = POSTS_CACHE_NAME, key = "'posts_page_'+#pageable.pageNumber")
public Page<Post> findPostByStatus(Pageable pageable) {
return postRepository.findPostsByPostStatusAndPostType(PostStatusEnum.PUBLISHED.getCode(), PostTypeEnum.POST_TYPE_POST.getDesc(), pageable);
Page<Post> posts = postRepository.findPostsByPostStatusAndPostType(PostStatusEnum.PUBLISHED.getCode(), PostTypeEnum.POST_TYPE_POST.getDesc(), pageable);
for (Post post : posts.getContent()) {
if (StrUtil.isNotEmpty(post.getPostPassword())) {
post.setPostSummary("该文章为加密文章");
}
}
return posts;
}
/**
@ -235,28 +262,27 @@ public class PostServiceImpl implements PostService {
}
/**
*
*
*
* @param postDate
* @return List
* @param postDate postDate
* @return Post
*/
@Override
public List<Post> findByPostDateAfter(Date postDate) {
return postRepository.findByPostDateAfterAndPostStatusAndPostTypeOrderByPostDateDesc(postDate, PostStatusEnum.PUBLISHED.getCode(), PostTypeEnum.POST_TYPE_POST.getDesc());
public Post getNextPost(Date postDate) {
return postRepository.queryNextPost(postDate);
}
/**
* Id
*
*
* @param postDate
* @return List
* @param postDate postDate
* @return Post
*/
@Override
public List<Post> findByPostDateBefore(Date postDate) {
return postRepository.findByPostDateBeforeAndPostStatusAndPostTypeOrderByPostDateAsc(postDate, PostStatusEnum.PUBLISHED.getCode(), PostTypeEnum.POST_TYPE_POST.getDesc());
public Post getPrePost(Date postDate) {
return postRepository.queryPrePost(postDate);
}
/**
*
*
@ -265,8 +291,8 @@ public class PostServiceImpl implements PostService {
@Override
@Cacheable(value = POSTS_CACHE_NAME, key = "'archives_year_month'")
public List<Archive> findPostGroupByYearAndMonth() {
List<Object[]> objects = postRepository.findPostGroupByYearAndMonth();
List<Archive> archives = new ArrayList<>();
final List<Object[]> objects = postRepository.findPostGroupByYearAndMonth();
final List<Archive> archives = new ArrayList<>();
Archive archive = null;
for (Object[] obj : objects) {
archive = new Archive();
@ -287,8 +313,8 @@ public class PostServiceImpl implements PostService {
@Override
@Cacheable(value = POSTS_CACHE_NAME, key = "'archives_year'")
public List<Archive> findPostGroupByYear() {
List<Object[]> objects = postRepository.findPostGroupByYear();
List<Archive> archives = new ArrayList<>();
final List<Object[]> objects = postRepository.findPostGroupByYear();
final List<Archive> archives = new ArrayList<>();
Archive archive = null;
for (Object[] obj : objects) {
archive = new Archive();
@ -300,6 +326,29 @@ public class PostServiceImpl implements PostService {
return archives;
}
/**
* @return List
* @Author Aquan
* @Description
* @Date 2019.1.4 11:16
* @Param
**/
@Override
@Cacheable(value = POSTS_CACHE_NAME, key = "'archives_all'")
public List<Archive> findAllPost() {
final List<Post> posts = postRepository.findAllPost();
final Integer count = postRepository.totalAllPostCount();
final List<Archive> archives = new ArrayList<>();
Archive archive = null;
archive = new Archive();
archive.setCount(String.valueOf(count));
archive.setPosts(posts);
archives.add(archive);
return archives;
}
/**
*
*
@ -335,7 +384,13 @@ public class PostServiceImpl implements PostService {
*/
@Override
public Page<Post> findPostByYearAndMonth(String year, String month, Pageable pageable) {
return postRepository.findPostByYearAndMonth(year, month, null);
Page<Post> posts = postRepository.findPostByYearAndMonth(year, month, null);
for (Post post : posts.getContent()) {
if (StrUtil.isNotEmpty(post.getPostPassword())) {
post.setPostSummary("该文章为加密文章");
}
}
return posts;
}
/**
@ -349,7 +404,13 @@ public class PostServiceImpl implements PostService {
@Override
@CachePut(value = POSTS_CACHE_NAME, key = "'posts_category_'+#category.cateId+'_'+#pageable.pageNumber")
public Page<Post> findPostByCategories(Category category, Pageable pageable) {
return postRepository.findPostByCategoriesAndPostStatus(category, PostStatusEnum.PUBLISHED.getCode(), pageable);
Page<Post> posts = postRepository.findPostByCategoriesAndPostStatus(category, PostStatusEnum.PUBLISHED.getCode(), pageable);
for (Post post : posts.getContent()) {
if (StrUtil.isNotEmpty(post.getPostPassword())) {
post.setPostSummary("该文章为加密文章");
}
}
return posts;
}
/**
@ -363,19 +424,13 @@ public class PostServiceImpl implements PostService {
@Override
@CachePut(value = POSTS_CACHE_NAME, key = "'posts_tag_'+#tag.tagId+'_'+#pageable.pageNumber")
public Page<Post> findPostsByTags(Tag tag, Pageable pageable) {
return postRepository.findPostsByTagsAndPostStatus(tag, PostStatusEnum.PUBLISHED.getCode(), pageable);
}
/**
*
*
* @param keyword
* @param pageable
* @return Page
*/
@Override
public Page<Post> searchByKeywords(String keyword, Pageable pageable) {
return postRepository.findPostByPostTitleLikeOrPostContentLikeAndPostTypeAndPostStatus(keyword, pageable);
Page<Post> posts = postRepository.findPostsByTagsAndPostStatus(tag, PostStatusEnum.PUBLISHED.getCode(), pageable);
for (Post post : posts.getContent()) {
if (StrUtil.isNotEmpty(post.getPostPassword())) {
post.setPostSummary("该文章为加密文章");
}
}
return posts;
}
/**
@ -399,15 +454,15 @@ public class PostServiceImpl implements PostService {
@CachePut(value = POSTS_CACHE_NAME, key = "'posts_related_'+#post.getPostId()")
public List<Post> relatedPosts(Post post) {
//获取当前文章的所有标签
List<Tag> tags = post.getTags();
List<Post> tempPosts = new ArrayList<>();
final List<Tag> tags = post.getTags();
final List<Post> tempPosts = new ArrayList<>();
for (Tag tag : tags) {
tempPosts.addAll(postRepository.findPostsByTags(tag));
}
//去掉当前的文章
tempPosts.remove(post);
//去掉重复的文章
List<Post> allPosts = new ArrayList<>();
final List<Post> allPosts = new ArrayList<>();
for (int i = 0; i < tempPosts.size(); i++) {
if (!allPosts.contains(tempPosts.get(i))) {
allPosts.add(tempPosts.get(i));
@ -464,4 +519,48 @@ public class PostServiceImpl implements PostService {
public String buildSiteMap(List<Post> posts) {
return HaloUtils.getSiteMap(posts);
}
/**
*
*
* @param postId postId
*/
@Override
public void cacheViews(Long postId) {
if (null != HaloConst.POSTS_VIEWS.get(postId)) {
HaloConst.POSTS_VIEWS.put(postId, HaloConst.POSTS_VIEWS.get(postId) + 1);
} else {
HaloConst.POSTS_VIEWS.put(postId, 1L);
}
}
/**
*
*
* @param post post
* @param cateList cateList
* @param tagList tagList
* @return Post Post
*/
@Override
public Post buildCategoriesAndTags(Post post, List<String> cateList, String tagList) {
final List<Category> categories = categoryService.strListToCateList(cateList);
post.setCategories(categories);
if (StrUtil.isNotEmpty(tagList)) {
final List<Tag> tags = tagService.strListToTagList(StrUtil.trim(tagList));
post.setTags(tags);
}
return post;
}
/**
*
*
* @param limit
* @return List
*/
@Override
public List<Post> getRecentPosts(int limit) {
return postRepository.getPostsByLimit(limit);
}
}

View File

@ -4,6 +4,7 @@ import cc.ryanc.halo.model.domain.Tag;
import cc.ryanc.halo.repository.TagRepository;
import cc.ryanc.halo.service.TagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@ -21,6 +22,8 @@ import java.util.Optional;
@Service
public class TagServiceImpl implements TagService {
private static final String POSTS_CACHE_NAME = "posts";
@Autowired
private TagRepository tagRepository;
@ -31,7 +34,8 @@ public class TagServiceImpl implements TagService {
* @return Tag
*/
@Override
public Tag saveByTag(Tag tag) {
@CacheEvict(value = POSTS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Tag save(Tag tag) {
return tagRepository.save(tag);
}
@ -42,8 +46,9 @@ public class TagServiceImpl implements TagService {
* @return Tag
*/
@Override
public Tag removeByTagId(Long tagId) {
Optional<Tag> tag = findByTagId(tagId);
@CacheEvict(value = POSTS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public Tag remove(Long tagId) {
final Optional<Tag> tag = findByTagId(tagId);
tagRepository.delete(tag.get());
return tag.get();
}
@ -54,7 +59,7 @@ public class TagServiceImpl implements TagService {
* @return List
*/
@Override
public List<Tag> findAllTags() {
public List<Tag> findAll() {
return tagRepository.findAll();
}
@ -99,10 +104,10 @@ public class TagServiceImpl implements TagService {
*/
@Override
public List<Tag> strListToTagList(String tagList) {
String[] tags = tagList.split(",");
List<Tag> tagsList = new ArrayList<>();
final String[] tags = tagList.split(",");
final List<Tag> tagsList = new ArrayList<>();
for (String tag : tags) {
Tag t = findTagByTagName(tag);
final Tag t = findTagByTagName(tag);
Tag nt = null;
if (null != t) {
tagsList.add(t);
@ -110,7 +115,7 @@ public class TagServiceImpl implements TagService {
nt = new Tag();
nt.setTagName(tag);
nt.setTagUrl(tag);
tagsList.add(saveByTag(nt));
tagsList.add(save(nt));
}
}
return tagsList;

View File

@ -30,7 +30,7 @@ public class UserServiceImpl implements UserService {
* @param user user
*/
@Override
public void saveByUser(User user) {
public void save(User user) {
userRepository.save(user);
}
@ -65,7 +65,7 @@ public class UserServiceImpl implements UserService {
*/
@Override
public User findUser() {
List<User> users = userRepository.findAll();
final List<User> users = userRepository.findAll();
if (users != null && users.size() > 0) {
return users.get(0);
} else {
@ -92,7 +92,8 @@ public class UserServiceImpl implements UserService {
*/
@Override
public void updateUserLoginEnable(String enable) {
User user = this.findUser();
final User user = this.findUser();
user.setLoginError(0);
user.setLoginEnable(enable);
userRepository.save(user);
}
@ -105,7 +106,7 @@ public class UserServiceImpl implements UserService {
*/
@Override
public User updateUserLoginLast(Date lastDate) {
User user = this.findUser();
final User user = this.findUser();
user.setLoginLast(lastDate);
userRepository.save(user);
return user;
@ -118,7 +119,7 @@ public class UserServiceImpl implements UserService {
*/
@Override
public Integer updateUserLoginError() {
User user = this.findUser();
final User user = this.findUser();
user.setLoginError((user.getLoginError() == null ? 0 : user.getLoginError()) + 1);
userRepository.save(user);
return user.getLoginError();
@ -131,7 +132,7 @@ public class UserServiceImpl implements UserService {
*/
@Override
public User updateUserNormal() {
User user = this.findUser();
final User user = this.findUser();
user.setLoginEnable(TrueFalseEnum.TRUE.getDesc());
user.setLoginError(0);
user.setLoginLast(new Date());

View File

@ -0,0 +1,34 @@
package cc.ryanc.halo.task;
import cc.ryanc.halo.model.domain.Post;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.utils.SpringUtil;
import lombok.extern.slf4j.Slf4j;
/**
* @author : RYAN0UP
* @date : 2018/12/5
*/
@Slf4j
public class PostSyncTask {
/**
*
*/
public void postSync() {
final PostService postService = SpringUtil.getBean(PostService.class);
Post post = null;
int count = 0;
for (Long key : HaloConst.POSTS_VIEWS.keySet()) {
post = postService.findByPostId(key).orElse(null);
if (null != post) {
post.setPostViews(post.getPostViews() + HaloConst.POSTS_VIEWS.get(key));
postService.save(post);
count++;
}
}
log.info("The number of visits to {} posts has been updated", count);
HaloConst.POSTS_VIEWS.clear();
}
}

View File

@ -1,14 +1,13 @@
package cc.ryanc.halo.utils;
import cc.ryanc.halo.model.domain.Comment;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import cc.ryanc.halo.model.domain.Comment;
/**
* <pre>
*
@ -30,7 +29,7 @@ public class CommentUtil {
return Collections.emptyList();
}
List<Comment> commentsResult = new ArrayList<>();
final List<Comment> commentsResult = new ArrayList<>();
for (Comment comment : commentsRoot) {
if (comment.getCommentParent() == 0) {
@ -60,7 +59,7 @@ public class CommentUtil {
return null;
}
List<Comment> commentsChild = new ArrayList<>();
final List<Comment> commentsChild = new ArrayList<>();
for (Comment comment : commentsRoot) {
if (comment.getCommentParent() != 0) {
if (comment.getCommentParent().equals(id)) {

View File

@ -8,6 +8,7 @@ import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.model.enums.CommonParamsEnum;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import com.sun.syndication.feed.rss.Channel;
import com.sun.syndication.feed.rss.Content;
@ -16,14 +17,12 @@ import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.WireFeedOutput;
import io.github.biezhi.ome.OhMyEmail;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
@ -49,13 +48,16 @@ public class HaloUtils {
*
*
* @param dir dir
*
* @return List
*/
public static List<BackupDto> getBackUps(String dir) {
String srcPathStr = System.getProperties().getProperty("user.home") + "/halo/backup/" + dir;
File srcPath = new File(srcPathStr);
File[] files = srcPath.listFiles();
List<BackupDto> backupDtos = new ArrayList<>();
final StrBuilder srcPathStr = new StrBuilder(System.getProperties().getProperty("user.home"));
srcPathStr.append("/halo/backup/");
srcPathStr.append(dir);
final File srcPath = new File(srcPathStr.toString());
final File[] files = srcPath.listFiles();
final List<BackupDto> backupDtos = new ArrayList<>();
BackupDto backupDto = null;
// 遍历文件
if (null != files) {
@ -81,25 +83,26 @@ public class HaloUtils {
*
*
* @param size size
*
* @return String
*/
public static String parseSize(long size) {
if (size < CommonParamsEnum.NOT_FOUND.getValue()) {
return String.valueOf(size) + "B";
if (size < CommonParamsEnum.BYTE.getValue()) {
return size + "B";
} else {
size = size / 1024;
}
if (size < CommonParamsEnum.NOT_FOUND.getValue()) {
return String.valueOf(size) + "KB";
if (size < CommonParamsEnum.BYTE.getValue()) {
return size + "KB";
} else {
size = size / 1024;
}
if (size < CommonParamsEnum.NOT_FOUND.getValue()) {
if (size < CommonParamsEnum.BYTE.getValue()) {
size = size * 100;
return String.valueOf((size / 100)) + "." + String.valueOf((size % 100)) + "MB";
return size / 100 + "." + size % 100 + "MB";
} else {
size = size * 100 / 1024;
return String.valueOf((size / 100)) + "." + String.valueOf((size % 100)) + "GB";
return size / 100 + "." + size % 100 + "GB";
}
}
@ -107,21 +110,21 @@ public class HaloUtils {
*
*
* @param srcPath
*
* @return
*/
public static Date getCreateTime(String srcPath) {
Path path = Paths.get(srcPath);
BasicFileAttributeView basicview = Files.getFileAttributeView(path, BasicFileAttributeView.class,
LinkOption.NOFOLLOW_LINKS);
final Path path = Paths.get(srcPath);
final BasicFileAttributeView basicview = Files.getFileAttributeView(path, BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
BasicFileAttributes attr;
try {
attr = basicview.readAttributes();
Date createDate = new Date(attr.creationTime().toMillis());
final Date createDate = new Date(attr.creationTime().toMillis());
return createDate;
} catch (Exception e) {
e.printStackTrace();
}
Calendar cal = Calendar.getInstance();
final Calendar cal = Calendar.getInstance();
cal.set(1970, 0, 1, 0, 0, 0);
return cal.getTime();
}
@ -130,11 +133,12 @@ public class HaloUtils {
*
*
* @param file file
*
* @return String
*/
public static String getImageWh(File file) {
try {
BufferedImage image = ImageIO.read(new FileInputStream(file));
final BufferedImage image = ImageIO.read(new FileInputStream(file));
return image.getWidth() + "x" + image.getHeight();
} catch (Exception e) {
e.printStackTrace();
@ -148,13 +152,13 @@ public class HaloUtils {
* @return List
*/
public static List<Theme> getThemes() {
List<Theme> themes = new ArrayList<>();
final List<Theme> themes = new ArrayList<>();
try {
// 获取项目根路径
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
final File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
// 获取主题路径
File themesPath = new File(basePath.getAbsolutePath(), "templates/themes");
File[] files = themesPath.listFiles();
final File themesPath = new File(basePath.getAbsolutePath(), "templates/themes");
final File[] files = themesPath.listFiles();
if (null != files) {
Theme theme = null;
for (File file : files) {
@ -191,18 +195,19 @@ public class HaloUtils {
*
*
* @param theme theme
*
* @return List
*/
public static List<String> getTplName(String theme) {
List<String> tpls = new ArrayList<>();
final List<String> tpls = new ArrayList<>();
try {
// 获取项目根路径
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
final File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
// 获取主题路径
File themesPath = new File(basePath.getAbsolutePath(), "templates/themes/" + theme);
File modulePath = new File(themesPath.getAbsolutePath(), "module");
File[] baseFiles = themesPath.listFiles();
File[] moduleFiles = modulePath.listFiles();
final File themesPath = new File(basePath.getAbsolutePath(), "templates/themes/" + theme);
final File modulePath = new File(themesPath.getAbsolutePath(), "module");
final File[] baseFiles = themesPath.listFiles();
final File[] moduleFiles = modulePath.listFiles();
if (null != moduleFiles) {
for (File file : moduleFiles) {
if (file.isFile() && file.getName().endsWith(".ftl")) {
@ -229,12 +234,12 @@ public class HaloUtils {
* @return List
*/
public static List<String> getCustomTpl(String theme) {
List<String> tpls = new ArrayList<>();
final List<String> tpls = new ArrayList<>();
try {
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
final File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
// 获取主题路径
File themePath = new File(basePath.getAbsolutePath(), "templates/themes/" + theme);
File[] themeFiles = themePath.listFiles();
final File themePath = new File(basePath.getAbsolutePath(), "templates/themes/" + theme);
final File[] themeFiles = themePath.listFiles();
if (null != themeFiles && themeFiles.length > 0) {
for (File file : themeFiles) {
String[] split = StrUtil.removeSuffix(file.getName(), ".ftl").split("_");
@ -260,7 +265,7 @@ public class HaloUtils {
FileWriter fileWriter = null;
BufferedWriter bufferedWriter = null;
try {
File file = new File(filePath);
final File file = new File(filePath);
if (!file.exists()) {
file.mkdirs();
}
@ -283,13 +288,15 @@ public class HaloUtils {
* rss
*
* @param posts posts
*
* @return String
* @throws FeedException
*
* @throws FeedException FeedException
*/
public static String getRss(List<Post> posts) throws FeedException {
Assert.notEmpty(posts, "posts must not be empty");
Channel channel = new Channel("rss_2.0");
final Channel channel = new Channel("rss_2.0");
if (null == HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_TITLE.getProp())) {
channel.setTitle("");
} else {
@ -306,13 +313,13 @@ public class HaloUtils {
channel.setDescription(HaloConst.OPTIONS.get(BlogPropertiesEnum.SEO_DESC.getProp()));
}
channel.setLanguage("zh-CN");
List<Item> items = new ArrayList<>();
final List<Item> items = new ArrayList<>();
for (Post post : posts) {
Item item = new Item();
final Item item = new Item();
item.setTitle(post.getPostTitle());
Content content = new Content();
final Content content = new Content();
String value = post.getPostContent();
char[] xmlChar = value.toCharArray();
final char[] xmlChar = value.toCharArray();
for (int i = 0; i < xmlChar.length; ++i) {
if (xmlChar[i] > 0xFFFD) {
xmlChar[i] = ' ';
@ -323,13 +330,12 @@ public class HaloUtils {
value = new String(xmlChar);
content.setValue(value);
item.setContent(content);
item.setLink(
HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/" + post.getPostUrl());
item.setLink(HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/" + post.getPostUrl());
item.setPubDate(post.getPostDate());
items.add(item);
}
channel.setItems(items);
WireFeedOutput out = new WireFeedOutput();
final WireFeedOutput out = new WireFeedOutput();
return out.outputString(channel);
}
@ -337,21 +343,23 @@ public class HaloUtils {
* sitemap
*
* @param posts posts
*
* @return String
*/
public static String getSiteMap(List<Post> posts) {
Assert.notEmpty(posts, "post mut not be empty");
String head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">";
String urlBody = "";
String urlItem;
String urlPath = HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/";
final StrBuilder head = new StrBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">");
final StrBuilder urlBody = new StrBuilder();
final String urlPath = HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/";
for (Post post : posts) {
urlItem = "<url><loc>" + urlPath + post.getPostUrl() + "</loc><lastmod>"
+ DateUtil.format(post.getPostDate(), "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") + "</lastmod>" + "</url>";
urlBody += urlItem;
urlBody.append("<url><loc>");
urlBody.append(urlPath);
urlBody.append(post.getPostUrl());
urlBody.append("</loc><lastmod>");
urlBody.append(DateUtil.format(post.getPostDate(), "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"));
urlBody.append("</lastmod></url>");
}
return head + urlBody + "</urlset>";
return head.append(urlBody).append("</urlset>").toString();
}
/**
@ -362,57 +370,18 @@ public class HaloUtils {
* @param password password
*/
public static void configMail(String smtpHost, String userName, String password) {
Properties properties = OhMyEmail.defaultConfig(false);
final Properties properties = OhMyEmail.defaultConfig(false);
properties.setProperty("mail.smtp.host", smtpHost);
OhMyEmail.config(properties, userName, password);
}
/**
* 访json
*
* @param enterUrl
* @return String
*/
public static String getHttpResponse(String enterUrl) {
Assert.hasText(enterUrl, "enter url must not be blank");
BufferedReader in = null;
StringBuffer result = null;
try {
URI uri = new URI(enterUrl);
URL url = uri.toURL();
URLConnection connection = url.openConnection();
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Charset", "utf-8");
connection.connect();
result = new StringBuffer();
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
return result.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return null;
}
/**
*
*
* @param blogUrl
* @param token token
* @param urls
*
* @return String
*/
public static String baiduPost(String blogUrl, String token, String urls) {
@ -420,13 +389,17 @@ public class HaloUtils {
Assert.hasText(token, "token must not be blank");
Assert.hasText(urls, "urls must not be blank");
String url = "http://data.zz.baidu.com/urls?site=" + blogUrl + "&token=" + token;
String result = "";
final StrBuilder url = new StrBuilder("http://data.zz.baidu.com/urls?site=");
url.append(blogUrl);
url.append("&token=");
url.append(token);
final StrBuilder result = new StrBuilder();
PrintWriter out = null;
BufferedReader in = null;
try {
// 建立URL之间的连接
URLConnection conn = new URL(url).openConnection();
final URLConnection conn = new URL(url.toString()).openConnection();
// 设置通用的请求属性
conn.setRequestProperty("Host", "data.zz.baidu.com");
conn.setRequestProperty("User-Agent", "curl/7.12.1");
@ -446,7 +419,7 @@ public class HaloUtils {
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
result.append(line);
}
} catch (Exception e) {
e.printStackTrace();
@ -462,7 +435,7 @@ public class HaloUtils {
ex.printStackTrace();
}
}
return result;
return result.toString();
}
}

View File

@ -0,0 +1,67 @@
package cc.ryanc.halo.utils;
import org.commonmark.Extension;
import org.commonmark.ext.front.matter.YamlFrontMatterExtension;
import org.commonmark.ext.front.matter.YamlFrontMatterVisitor;
import org.commonmark.ext.gfm.tables.TablesExtension;
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.HtmlRenderer;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author : RYAN0UP
* @date : 2018/11/14
*/
public class MarkdownUtils {
/**
* Front-matter
*/
private static final Set<Extension> EXTENSIONS_YAML = Collections.singleton(YamlFrontMatterExtension.create());
/**
* Table
*/
private static final Set<Extension> EXTENSIONS_TABLE = Collections.singleton(TablesExtension.create());
/**
* Markdown
*/
private static final Parser PARSER = Parser.builder().extensions(EXTENSIONS_YAML).extensions(EXTENSIONS_TABLE).build();
/**
* HTML
*/
private static final HtmlRenderer RENDERER = HtmlRenderer.builder().extensions(EXTENSIONS_YAML).extensions(EXTENSIONS_TABLE).build();
/**
* Markdown
*
* @param content content
*
* @return String
*/
public static String renderMarkdown(String content) {
final Node document = PARSER.parse(content);
return RENDERER.render(document);
}
/**
*
*
* @param content content
*
* @return Map
*/
public static Map<String, List<String>> getFrontMatter(String content) {
final YamlFrontMatterVisitor visitor = new YamlFrontMatterVisitor();
final Node document = PARSER.parse(content);
document.accept(visitor);
return visitor.getData();
}
}

View File

@ -0,0 +1,64 @@
package cc.ryanc.halo.utils;
import cn.hutool.core.text.StrBuilder;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.security.MessageDigest;
/**
* <pre>
* hash
* </pre>
*
* @author : Yawn
* @date : 2018/12/04
*/
public class Md5Util {
/**
* MD5
*
* @param file file
*
* @return byte
*
* @throws Exception Exception
*/
private static byte[] createChecksum(MultipartFile file) throws Exception {
final InputStream fis = file.getInputStream();
final byte[] buffer = new byte[1024];
final MessageDigest complete = MessageDigest.getInstance("MD5");
int numRead;
do {
numRead = fis.read(buffer);
if (numRead > 0) {
complete.update(buffer, 0, numRead);
}
} while (numRead != -1);
fis.close();
return complete.digest();
}
/**
* hash
*
* @param file file
*
* @return String
*
* @throws Exception Exception
*/
public static String getMD5Checksum(MultipartFile file) throws Exception {
final byte[] b = createChecksum(file);
StrBuilder result = new StrBuilder();
for (int i = 0; i < b.length; i++) {
result.append(Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1));
}
return result.toString();
}
}

View File

@ -0,0 +1,53 @@
package cc.ryanc.halo.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @author : RYAN0UP
* @date : 2018/12/5
*/
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
/**
* applicationContext
*
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
/**
* name Bean.
*
* @param name name
* @return Object
*/
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
/**
* classBean
*
* @param clazz clazz
* @param <T> <T>
* @return T
*/
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
}

View File

@ -1,26 +1,21 @@
package cc.ryanc.halo.web.controller.admin;
import cc.ryanc.halo.model.domain.Comment;
import cc.ryanc.halo.model.domain.Logs;
import cc.ryanc.halo.model.domain.Post;
import cc.ryanc.halo.model.domain.User;
import cc.ryanc.halo.model.domain.*;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.dto.LogsRecord;
import cc.ryanc.halo.model.enums.CommonParamsEnum;
import cc.ryanc.halo.model.enums.ResponseStatusEnum;
import cc.ryanc.halo.model.enums.ResultCodeEnum;
import cc.ryanc.halo.model.enums.TrueFalseEnum;
import cc.ryanc.halo.model.enums.*;
import cc.ryanc.halo.service.*;
import cc.ryanc.halo.utils.LocaleMessageUtil;
import cc.ryanc.halo.utils.MarkdownUtils;
import cc.ryanc.halo.web.controller.core.BaseController;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.HtmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -31,12 +26,12 @@ import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.io.IOException;
import java.util.*;
/**
* <pre>
@ -69,6 +64,12 @@ public class AdminController extends BaseController {
@Autowired
private AttachmentService attachmentService;
@Autowired
private CategoryService categoryService;
@Autowired
private TagService tagService;
@Autowired
private LocaleMessageUtil localeMessageUtil;
@ -83,27 +84,32 @@ public class AdminController extends BaseController {
public String index(Model model) {
//查询评论的条数
Integer commentCount = commentService.findAllComments().size();
final Long commentCount = commentService.getCount();
model.addAttribute("commentCount", commentCount);
//查询最新的文章
List<Post> postsLatest = postService.findPostLatest();
final List<Post> postsLatest = postService.findPostLatest();
model.addAttribute("postTopFive", postsLatest);
//查询最新的日志
List<Logs> logsLatest = logsService.findLogsLatest();
final List<Logs> logsLatest = logsService.findLogsLatest();
model.addAttribute("logs", logsLatest);
//查询最新的评论
List<Comment> comments = commentService.findCommentsLatest();
final List<Comment> comments = commentService.findCommentsLatest();
model.addAttribute("comments", comments);
//附件数量
model.addAttribute("mediaCount", attachmentService.findAllAttachments().size());
model.addAttribute("mediaCount", attachmentService.getCount());
//文章阅读总数
Long postViewsSum = postService.getPostViews();
final Long postViewsSum = postService.getPostViews();
model.addAttribute("postViewsSum", postViewsSum);
//成立天数
final Date blogStart = DateUtil.parse(HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_START.getProp()));
final long hadDays = DateUtil.between(blogStart, DateUtil.date(), DateUnit.DAY);
model.addAttribute("hadDays", hadDays);
return "admin/admin_index";
}
@ -115,7 +121,7 @@ public class AdminController extends BaseController {
*/
@GetMapping(value = "/login")
public String login(HttpSession session) {
User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
final User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
//如果session存在跳转到后台首页
if (null != user) {
return "redirect:/admin";
@ -137,13 +143,13 @@ public class AdminController extends BaseController {
@ModelAttribute("loginPwd") String loginPwd,
HttpSession session) {
//已注册账号,单用户,只有一个
User aUser = userService.findUser();
final User aUser = userService.findUser();
//首先判断是否已经被禁用已经是否已经过了10分钟
Date loginLast = DateUtil.date();
if (null != aUser.getLoginLast()) {
loginLast = aUser.getLoginLast();
}
Long between = DateUtil.between(loginLast, DateUtil.date(), DateUnit.MINUTE);
final Long between = DateUtil.between(loginLast, DateUtil.date(), DateUnit.MINUTE);
if (StrUtil.equals(aUser.getLoginEnable(), TrueFalseEnum.FALSE.getDesc()) && (between < CommonParamsEnum.TEN.getValue())) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.login.disabled"));
}
@ -160,25 +166,18 @@ public class AdminController extends BaseController {
session.setAttribute(HaloConst.USER_SESSION_KEY, aUser);
//重置用户的登录状态为正常
userService.updateUserNormal();
logsService.saveByLogs(new Logs(LogsRecord.LOGIN, LogsRecord.LOGIN_SUCCESS, ServletUtil.getClientIP(request), DateUtil.date()));
logsService.save(LogsRecord.LOGIN, LogsRecord.LOGIN_SUCCESS, request);
log.info("User {} login succeeded.", aUser.getUserDisplayName());
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.login.success"));
} else {
//更新失败次数
Integer errorCount = userService.updateUserLoginError();
final Integer errorCount = userService.updateUserLoginError();
//超过五次禁用账户
if (errorCount >= CommonParamsEnum.FIVE.getValue()) {
userService.updateUserLoginEnable(TrueFalseEnum.FALSE.getDesc());
}
logsService.saveByLogs(
new Logs(
LogsRecord.LOGIN,
LogsRecord.LOGIN_ERROR + "[" + HtmlUtil.escape(loginName) + "," + HtmlUtil.escape(loginPwd) + "]",
ServletUtil.getClientIP(request),
DateUtil.date()
)
);
Object[] args = {(5 - errorCount)};
logsService.save(LogsRecord.LOGIN, LogsRecord.LOGIN_ERROR + "[" + HtmlUtil.escape(loginName) + "," + HtmlUtil.escape(loginPwd) + "]", request);
final Object[] args = {(5 - errorCount)};
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.login.failed", args));
}
}
@ -191,9 +190,9 @@ public class AdminController extends BaseController {
*/
@GetMapping(value = "/logOut")
public String logOut(HttpSession session) {
User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
final User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
session.removeAttribute(HaloConst.USER_SESSION_KEY);
logsService.saveByLogs(new Logs(LogsRecord.LOGOUT, user.getUserName(), ServletUtil.getClientIP(request), DateUtil.date()));
logsService.save(LogsRecord.LOGOUT, user.getUserName(), request);
log.info("User {} has logged out", user.getUserName());
return "redirect:/admin/login";
}
@ -210,9 +209,9 @@ public class AdminController extends BaseController {
public String logs(Model model,
@RequestParam(value = "page", defaultValue = "0") Integer page,
@RequestParam(value = "size", defaultValue = "10") Integer size) {
Sort sort = new Sort(Sort.Direction.DESC, "logId");
Pageable pageable = PageRequest.of(page, size, sort);
Page<Logs> logs = logsService.findAllLogs(pageable);
final Sort sort = new Sort(Sort.Direction.DESC, "logId");
final Pageable pageable = PageRequest.of(page, size, sort);
final Page<Logs> logs = logsService.findAll(pageable);
model.addAttribute("logs", logs);
return "admin/widget/_logs-all";
}
@ -225,7 +224,7 @@ public class AdminController extends BaseController {
@GetMapping(value = "/logs/clear")
public String logsClear() {
try {
logsService.removeAllLogs();
logsService.removeAll();
} catch (Exception e) {
log.error("Clear log failed:{}" + e.getMessage());
}
@ -233,7 +232,7 @@ public class AdminController extends BaseController {
}
/**
*
* Halo
*
* @return admin/admin_halo
*/
@ -250,7 +249,105 @@ public class AdminController extends BaseController {
@GetMapping(value = "/getToken")
@ResponseBody
public JsonResult getToken() {
String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
final String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), SecureUtil.md5(token));
}
/**
*
*
* @return String
*/
@GetMapping(value = "/tools")
public String tools() {
return "admin/admin_tools";
}
/**
* Markdown
*
* @return String
*/
@GetMapping(value = "/tools/markdownImport")
public String markdownImport() {
return "admin/widget/_markdown_import";
}
/**
* Markdown
*
* @param file file
* @param request request
* @return JsonResult
*/
@PostMapping(value = "/tools/markdownImport")
@ResponseBody
public JsonResult markdownImport(@RequestParam("file") MultipartFile file,
HttpServletRequest request,
HttpSession session) throws IOException {
final User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
final String markdown = IoUtil.read(file.getInputStream(), "UTF-8");
final String content = MarkdownUtils.renderMarkdown(markdown);
final Map<String, List<String>> frontMatters = MarkdownUtils.getFrontMatter(markdown);
final Post post = new Post();
List<String> elementValue = null;
final List<Tag> tags = new ArrayList<>();
final List<Category> categories = new ArrayList<>();
Tag tag = null;
Category category = null;
if (frontMatters.size() > 0) {
for (String key : frontMatters.keySet()) {
elementValue = frontMatters.get(key);
for (String ele : elementValue) {
if ("title".equals(key)) {
post.setPostTitle(ele);
} else if ("date".equals(key)) {
post.setPostDate(DateUtil.parse(ele));
} else if ("updated".equals(key)) {
post.setPostUpdate(DateUtil.parse(ele));
} else if ("tags".equals(key)) {
tag = tagService.findTagByTagName(ele);
if (null == tag) {
tag = new Tag();
tag.setTagName(ele);
tag.setTagUrl(ele);
tag = tagService.save(tag);
}
tags.add(tag);
} else if ("categories".equals(key)) {
category = categoryService.findByCateName(ele);
if (null == category) {
category = new Category();
category.setCateName(ele);
category.setCateUrl(ele);
category.setCateDesc(ele);
category = categoryService.save(category);
}
categories.add(category);
}
}
}
} else {
post.setPostDate(new Date());
post.setPostUpdate(new Date());
post.setPostTitle(file.getOriginalFilename());
}
post.setPostContentMd(markdown);
post.setPostContent(content);
post.setPostType(PostTypeEnum.POST_TYPE_POST.getDesc());
post.setAllowComment(AllowCommentEnum.ALLOW.getCode());
post.setUser(user);
post.setTags(tags);
post.setCategories(categories);
post.setPostUrl(StrUtil.removeSuffix(file.getOriginalFilename(), ".md"));
if (null == post.getPostDate()) {
post.setPostDate(new Date());
}
if (null == post.getPostUpdate()) {
post.setPostUpdate(new Date());
}
postService.save(post);
return new JsonResult(ResultCodeEnum.SUCCESS.getCode());
}
}

View File

@ -1,20 +1,16 @@
package cc.ryanc.halo.web.controller.admin;
import cc.ryanc.halo.model.domain.Attachment;
import cc.ryanc.halo.model.domain.Logs;
import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.dto.LogsRecord;
import cc.ryanc.halo.model.enums.PostTypeEnum;
import cc.ryanc.halo.model.enums.ResultCodeEnum;
import cc.ryanc.halo.service.AttachmentService;
import cc.ryanc.halo.service.LogsService;
import cc.ryanc.halo.utils.HaloUtils;
import cc.ryanc.halo.utils.LocaleMessageUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
@ -27,11 +23,11 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import static cc.ryanc.halo.model.enums.AttachLocationEnum.*;
/**
* <pre>
@ -56,18 +52,19 @@ public class AttachmentController {
private LocaleMessageUtil localeMessageUtil;
/**
* upload
*
*
* @param model model
*
* @return admin/admin_attachment
*/
@GetMapping
public String attachments(Model model,
@RequestParam(value = "page", defaultValue = "0") Integer page,
@RequestParam(value = "size", defaultValue = "18") Integer size) {
Sort sort = new Sort(Sort.Direction.DESC, "attachId");
Pageable pageable = PageRequest.of(page, size, sort);
Page<Attachment> attachments = attachmentService.findAllAttachments(pageable);
final Sort sort = new Sort(Sort.Direction.DESC, "attachId");
final Pageable pageable = PageRequest.of(page, size, sort);
final Page<Attachment> attachments = attachmentService.findAll(pageable);
model.addAttribute("attachments", attachments);
return "admin/admin_attachment";
}
@ -77,6 +74,7 @@ public class AttachmentController {
*
* @param model model
* @param page page
*
* @return admin/widget/_attachment-select
*/
@GetMapping(value = "/select")
@ -84,9 +82,9 @@ public class AttachmentController {
@RequestParam(value = "page", defaultValue = "0") Integer page,
@RequestParam(value = "id", defaultValue = "none") String id,
@RequestParam(value = "type", defaultValue = "normal") String type) {
Sort sort = new Sort(Sort.Direction.DESC, "attachId");
Pageable pageable = PageRequest.of(page, 18, sort);
Page<Attachment> attachments = attachmentService.findAllAttachments(pageable);
final Sort sort = new Sort(Sort.Direction.DESC, "attachId");
final Pageable pageable = PageRequest.of(page, 18, sort);
final Page<Attachment> attachments = attachmentService.findAll(pageable);
model.addAttribute("attachments", attachments);
model.addAttribute("id", id);
if (StrUtil.equals(type, PostTypeEnum.POST_TYPE_POST.getDesc())) {
@ -95,88 +93,59 @@ public class AttachmentController {
return "admin/widget/_attachment-select";
}
/**
*
*
* @return String
*/
@GetMapping(value = "/uploadModal")
public String uploadModal() {
return "admin/widget/_attachment-upload";
}
/**
*
*
* @param file file
* @param request request
*
* @return Map
*/
@PostMapping(value = "/upload", produces = {"application/json;charset=UTF-8"})
@ResponseBody
public Map<String, Object> upload(@RequestParam("file") MultipartFile file,
HttpServletRequest request) {
return uploadAttachment(file, request);
}
/**
* editor.md
*
* @param file file
* @param request request
* @return Map
*/
@PostMapping(value = "/upload/editor", produces = {"application/json;charset=UTF-8"})
@ResponseBody
public Map<String, Object> editorUpload(@RequestParam("editormd-image-file") MultipartFile file,
HttpServletRequest request) {
return uploadAttachment(file, request);
}
/**
*
*
* @param file file
* @param request request
* @return Map
*/
private Map<String, Object> uploadAttachment(MultipartFile file, HttpServletRequest request) {
Map<String, Object> result = new HashMap<>(3);
final Map<String, Object> result = new HashMap<>(3);
if (!file.isEmpty()) {
try {
//用户目录
String userPath = System.getProperties().getProperty("user.home") + "/halo";
//upload的路径
StringBuffer sbMedia = new StringBuffer("upload/");
//获取当前年月以创建目录,如果没有该目录则创建
sbMedia.append(DateUtil.thisYear()).append("/").append(DateUtil.thisMonth()).append("/");
File mediaPath = new File(userPath, sbMedia.toString());
if (!mediaPath.exists()) {
mediaPath.mkdirs();
final Map<String, String> resultMap = attachmentService.upload(file, request);
if (resultMap == null || resultMap.isEmpty()) {
log.error("File upload failed");
result.put("success", ResultCodeEnum.FAIL.getCode());
result.put("message", localeMessageUtil.getMessage("code.admin.attachment.upload-failed"));
return result;
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String nameWithOutSuffix = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf('.')).replaceAll(" ", "_").replaceAll(",", "") + dateFormat.format(DateUtil.date()) + new Random().nextInt(1000);
String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.') + 1);
String fileName = nameWithOutSuffix + "." + fileSuffix;
file.transferTo(new File(mediaPath.getAbsoluteFile(), fileName));
//压缩图片
Thumbnails.of(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(fileName).toString()).size(256, 256).keepAspectRatio(false).toFile(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(nameWithOutSuffix).append("_small.").append(fileSuffix).toString());
String filePath = new StringBuffer("/upload/").append(DateUtil.thisYear()).append("/").append(DateUtil.thisMonth()).append("/").append(fileName).toString();
//保存在数据库
Attachment attachment = new Attachment();
attachment.setAttachName(fileName);
attachment.setAttachPath(filePath);
attachment.setAttachSmallPath(new StringBuffer("/upload/").append(DateUtil.thisYear()).append("/").append(DateUtil.thisMonth()).append("/").append(nameWithOutSuffix).append("_small.").append(fileSuffix).toString());
attachment.setAttachName(resultMap.get("fileName"));
attachment.setAttachPath(resultMap.get("filePath"));
attachment.setAttachSmallPath(resultMap.get("smallPath"));
attachment.setAttachType(file.getContentType());
attachment.setAttachSuffix(new StringBuffer(".").append(fileSuffix).toString());
attachment.setAttachCreated(DateUtil.date());
attachment.setAttachSize(HaloUtils.parseSize(new File(mediaPath, fileName).length()));
attachment.setAttachWh(HaloUtils.getImageWh(new File(mediaPath, fileName)));
attachmentService.saveByAttachment(attachment);
log.info("Upload file {} to {} successfully", fileName, mediaPath.getAbsolutePath());
logsService.saveByLogs(
new Logs(LogsRecord.UPLOAD_FILE, fileName, ServletUtil.getClientIP(request), DateUtil.date())
);
result.put("success", 1);
attachment.setAttachSuffix(resultMap.get("suffix"));
attachment.setAttachSize(resultMap.get("size"));
attachment.setAttachWh(resultMap.get("wh"));
attachment.setAttachLocation(resultMap.get("location"));
attachmentService.save(attachment);
log.info("Upload file {} to {} successfully", resultMap.get("fileName"), resultMap.get("filePath"));
result.put("success", ResultCodeEnum.SUCCESS.getCode());
result.put("message", localeMessageUtil.getMessage("code.admin.attachment.upload-success"));
result.put("url", attachment.getAttachPath());
result.put("filename", filePath);
result.put("filename", resultMap.get("filePath"));
logsService.save(LogsRecord.UPLOAD_FILE, resultMap.get("fileName"), request);
} catch (Exception e) {
log.error("Upload file failed:{}", e.getMessage());
result.put("success", 0);
result.put("success", ResultCodeEnum.FAIL.getCode());
result.put("message", localeMessageUtil.getMessage("code.admin.attachment.upload-failed"));
}
} else {
@ -190,12 +159,13 @@ public class AttachmentController {
*
* @param model model
* @param attachId
*
* @return admin/widget/_attachment-detail
*/
@GetMapping(value = "/attachment")
public String attachmentDetail(Model model, @RequestParam("attachId") Long attachId) {
Optional<Attachment> attachment = attachmentService.findByAttachId(attachId);
model.addAttribute("attachment", attachment.get());
final Optional<Attachment> attachment = attachmentService.findByAttachId(attachId);
model.addAttribute("attachment", attachment.orElse(new Attachment()));
return "admin/widget/_attachment-detail";
}
@ -204,6 +174,7 @@ public class AttachmentController {
*
* @param attachId
* @param request request
*
* @return JsonResult
*/
@GetMapping(value = "/remove")
@ -211,28 +182,46 @@ public class AttachmentController {
public JsonResult removeAttachment(@RequestParam("attachId") Long attachId,
HttpServletRequest request) {
Optional<Attachment> attachment = attachmentService.findByAttachId(attachId);
String attachLocation = attachment.get().getAttachLocation();
String delFileName = attachment.get().getAttachName();
String delSmallFileName = delFileName.substring(0, delFileName.lastIndexOf('.')) + "_small" + attachment.get().getAttachSuffix();
boolean flag = true;
try {
//删除数据库中的内容
attachmentService.removeByAttachId(attachId);
//删除文件
String userPath = System.getProperties().getProperty("user.home") + "/halo";
File mediaPath = new File(userPath, attachment.get().getAttachPath().substring(0, attachment.get().getAttachPath().lastIndexOf('/')));
File delFile = new File(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(delFileName).toString());
File delSmallFile = new File(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(delSmallFileName).toString());
if (delFile.exists() && delFile.isFile()) {
if (delFile.delete() && delSmallFile.delete()) {
log.info("Delete file {} successfully!", delFileName);
logsService.saveByLogs(
new Logs(LogsRecord.REMOVE_FILE, delFileName, ServletUtil.getClientIP(request), DateUtil.date())
);
attachmentService.remove(attachId);
if (attachLocation != null) {
if (attachLocation.equals(SERVER.getDesc())) {
String delSmallFileName = delFileName.substring(0, delFileName.lastIndexOf('.')) + "_small" + attachment.get().getAttachSuffix();
//删除文件
String userPath = System.getProperties().getProperty("user.home") + "/halo";
File mediaPath = new File(userPath, attachment.get().getAttachPath().substring(0, attachment.get().getAttachPath().lastIndexOf('/')));
File delFile = new File(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(delFileName).toString());
File delSmallFile = new File(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(delSmallFileName).toString());
if (delFile.exists() && delFile.isFile()) {
flag = delFile.delete() && delSmallFile.delete();
}
} else if (attachLocation.equals(QINIU.getDesc())) {
//七牛删除
String attachPath = attachment.get().getAttachPath();
String key = attachPath.substring(attachPath.lastIndexOf("/") + 1);
flag = attachmentService.deleteQiNiuAttachment(key);
} else if (attachLocation.equals(UPYUN.getDesc())) {
//又拍删除
String attachPath = attachment.get().getAttachPath();
String fileName = attachPath.substring(attachPath.lastIndexOf("/") + 1);
flag = attachmentService.deleteUpYunAttachment(fileName);
} else {
log.error("Deleting attachment {} failed!", delFileName);
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.delete-failed"));
//..
}
}
if (flag) {
log.info("Delete file {} successfully!", delFileName);
logsService.save(LogsRecord.REMOVE_FILE, delFileName, request);
} else {
log.error("Deleting attachment {} failed!", delFileName);
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.delete-failed"));
}
} catch (Exception e) {
e.printStackTrace();
log.error("Deleting attachment {} failed: {}", delFileName, e.getMessage());
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.delete-failed"));
}

View File

@ -1,29 +1,31 @@
package cc.ryanc.halo.web.controller.admin;
import cc.ryanc.halo.model.domain.Category;
import cc.ryanc.halo.model.domain.Post;
import cc.ryanc.halo.model.domain.Tag;
import cc.ryanc.halo.model.domain.User;
import cc.ryanc.halo.model.dto.BackupDto;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.enums.*;
import cc.ryanc.halo.service.MailService;
import cc.ryanc.halo.service.OptionsService;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.utils.HaloUtils;
import cc.ryanc.halo.utils.LocaleMessageUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.cron.CronUtil;
import freemarker.template.Configuration;
import freemarker.template.TemplateModelException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
import java.io.File;
@ -54,16 +56,11 @@ public class BackupController {
@Autowired
private LocaleMessageUtil localeMessageUtil;
@Autowired
private OptionsService optionsService;
@Autowired
private Configuration configuration;
/**
*
*
* @param model model
*
* @return admin/admin_backup
*/
@GetMapping
@ -87,6 +84,7 @@ public class BackupController {
*
*
* @param type
*
* @return JsonResult
*/
@GetMapping(value = "doBackup")
@ -108,13 +106,13 @@ public class BackupController {
*
* @return /admin/backup
*/
public JsonResult backupDatabase() {
private JsonResult backupDatabase() {
try {
if (HaloUtils.getBackUps(BackupTypeEnum.DATABASES.getDesc()).size() > CommonParamsEnum.TEN.getValue()) {
FileUtil.del(System.getProperties().getProperty("user.home") + "/halo/backup/databases/");
}
String srcPath = System.getProperties().getProperty("user.home") + "/halo/";
String distName = "databases_backup_" + DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss");
final String srcPath = System.getProperties().getProperty("user.home") + "/halo/";
final String distName = "databases_backup_" + DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss");
//压缩文件
ZipUtil.zip(srcPath + "halo.mv.db", System.getProperties().getProperty("user.home") + "/halo/backup/databases/" + distName + ".zip");
log.info("Current time: {}, database backup was performed.", DateUtil.now());
@ -126,18 +124,18 @@ public class BackupController {
}
/**
*
*
*
* @return JsonResult
*/
public JsonResult backupResources() {
private JsonResult backupResources() {
try {
if (HaloUtils.getBackUps(BackupTypeEnum.RESOURCES.getDesc()).size() > CommonParamsEnum.TEN.getValue()) {
FileUtil.del(System.getProperties().getProperty("user.home") + "/halo/backup/resources/");
}
File path = new File(ResourceUtils.getURL("classpath:").getPath());
String srcPath = path.getAbsolutePath();
String distName = "resources_backup_" + DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss");
final File path = new File(ResourceUtils.getURL("classpath:").getPath());
final String srcPath = path.getAbsolutePath();
final String distName = "resources_backup_" + DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss");
//执行打包
ZipUtil.zip(srcPath, System.getProperties().getProperty("user.home") + "/halo/backup/resources/" + distName + ".zip");
log.info("Current time: {}, the resource file backup was performed.", DateUtil.now());
@ -153,22 +151,48 @@ public class BackupController {
*
* @return JsonResult
*/
public JsonResult backupPosts() {
List<Post> posts = postService.findAllPosts(PostTypeEnum.POST_TYPE_POST.getDesc());
posts.addAll(postService.findAllPosts(PostTypeEnum.POST_TYPE_PAGE.getDesc()));
private JsonResult backupPosts() {
final List<Post> posts = postService.findAll(PostTypeEnum.POST_TYPE_POST.getDesc());
posts.addAll(postService.findAll(PostTypeEnum.POST_TYPE_PAGE.getDesc()));
try {
final StrBuilder rootDir = new StrBuilder(System.getProperties().getProperty("user.home"));
rootDir.append("/halo/backup/posts/");
if (HaloUtils.getBackUps(BackupTypeEnum.POSTS.getDesc()).size() > CommonParamsEnum.TEN.getValue()) {
FileUtil.del(System.getProperties().getProperty("user.home") + "/halo/backup/posts/");
FileUtil.del(rootDir.toString());
}
//打包好的文件名
String distName = "posts_backup_" + DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss");
String srcPath = System.getProperties().getProperty("user.home") + "/halo/backup/posts/" + distName;
final StrBuilder distName = new StrBuilder("posts_backup_");
distName.append(DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss"));
final StrBuilder srcPath = rootDir.append(distName);
final StrBuilder content = new StrBuilder("---\n");
for (Post post : posts) {
HaloUtils.postToFile(post.getPostContentMd(), srcPath, post.getPostTitle() + ".md");
content.append("title: ").append(post.getPostTitle()).append("\n");
content.append("date: ").append(post.getPostDate()).append("\n");
content.append("updated: ").append(post.getPostUpdate()).append("\n");
content.append("thumbnail: ").append(post.getPostThumbnail()).append("\n");
if(post.getTags().size()>0){
content.append("tags:").append("\n");
final List<Tag> tags = post.getTags();
for (Tag tag : tags) {
content.append(" - ").append(tag.getTagName()).append("\n");
}
}
if(post.getCategories().size()>0){
content.append("categories:").append("\n");
final List<Category> categories = post.getCategories();
for (Category category : categories) {
content.append(" - ").append(category.getCateName()).append("\n");
}
}
content.append("---\n\n");
content.append(post.getPostContentMd());
HaloUtils.postToFile(content.toString(), srcPath.toString(), post.getPostTitle() + ".md");
content.clear();
content.append("---\n");
}
//打包导出好的文章
ZipUtil.zip(srcPath, srcPath + ".zip");
FileUtil.del(srcPath);
ZipUtil.zip(srcPath.toString(), srcPath.toString() + ".zip");
FileUtil.del(srcPath.toString());
log.info("Current time: {}, performed an article backup.", DateUtil.now());
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.backup.backup-success"));
} catch (Exception e) {
@ -182,13 +206,14 @@ public class BackupController {
*
* @param fileName
* @param type
*
* @return JsonResult
*/
@GetMapping(value = "delBackup")
@ResponseBody
public JsonResult delBackup(@RequestParam("fileName") String fileName,
@RequestParam("type") String type) {
String srcPath = System.getProperties().getProperty("user.home") + "/halo/backup/" + type + "/" + fileName;
final String srcPath = System.getProperties().getProperty("user.home") + "/halo/backup/" + type + "/" + fileName;
try {
FileUtil.del(srcPath);
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.common.delete-success"));
@ -197,38 +222,12 @@ public class BackupController {
}
}
/**
*
*
* @param autoBackup autoBackup
* @return /admin/backup
*/
@PostMapping(value = "backupOption")
public String backupOption(@RequestParam("auto_backup") String autoBackup) throws TemplateModelException {
if (StrUtil.equals(autoBackup, TrueFalseEnum.TRUE.getDesc())) {
if (StrUtil.equals(HaloConst.OPTIONS.get(BlogPropertiesEnum.AUTO_BACKUP.getProp()), TrueFalseEnum.FALSE.getDesc())) {
CronUtil.start();
log.info("The scheduled task starts successfully!");
}
optionsService.saveOption("auto_backup", TrueFalseEnum.TRUE.getDesc());
} else {
if (StrUtil.equals(HaloConst.OPTIONS.get(BlogPropertiesEnum.AUTO_BACKUP.getProp()), TrueFalseEnum.TRUE.getDesc())) {
CronUtil.stop();
log.info("The scheduled task stops successfully!");
}
optionsService.saveOption("auto_backup", TrueFalseEnum.FALSE.getDesc());
}
configuration.setSharedVariable("options", optionsService.findAllOptions());
HaloConst.OPTIONS.clear();
HaloConst.OPTIONS = optionsService.findAllOptions();
return "redirect:/admin/backup";
}
/**
*
*
* @param fileName
* @param type
*
* @return JsonResult
*/
@GetMapping(value = "sendToEmail")
@ -236,9 +235,9 @@ public class BackupController {
public JsonResult sendToEmail(@RequestParam("fileName") String fileName,
@RequestParam("type") String type,
HttpSession session) {
String srcPath = System.getProperties().getProperty("user.home") + "/halo/backup/" + type + "/" + fileName;
User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
if (null == user.getUserEmail() || StrUtil.equals(user.getUserEmail(), "")) {
final String srcPath = System.getProperties().getProperty("user.home") + "/halo/backup/" + type + "/" + fileName;
final User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
if (null == user.getUserEmail() || StrUtil.isEmpty(user.getUserEmail())) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.backup.no-email"));
}
if (StrUtil.equals(HaloConst.OPTIONS.get(BlogPropertiesEnum.SMTP_EMAIL_ENABLE.getProp()), TrueFalseEnum.FALSE.getDesc())) {
@ -262,8 +261,8 @@ public class BackupController {
@Override
public void run() {
File file = new File(srcPath);
Map<String, Object> content = new HashMap<>(3);
final File file = new File(srcPath);
final Map<String, Object> content = new HashMap<>(3);
try {
content.put("fileName", file.getName());
content.put("createAt", HaloUtils.getCreateTime(srcPath));

View File

@ -9,8 +9,11 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Optional;
/**
@ -46,45 +49,45 @@ public class CategoryController {
* /
*
* @param category category
* @return /admin/category
*/
@PostMapping(value = "/save")
public String saveCategory(@ModelAttribute Category category) {
try {
categoryService.saveByCategory(category);
} catch (Exception e) {
log.error("Modify category failed: {}", e.getMessage());
}
return "redirect:/admin/category";
}
/**
*
*
* @param cateUrl
* @return JsonResult
*/
@GetMapping(value = "/checkUrl")
@PostMapping(value = "/save")
@ResponseBody
public JsonResult checkCateUrlExists(@RequestParam("cateUrl") String cateUrl) {
Category category = categoryService.findByCateUrl(cateUrl);
if (null != category) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.url-is-exists"));
public JsonResult saveCategory(@Valid Category category, BindingResult result) {
if (result.hasErrors()) {
for (ObjectError error : result.getAllErrors()) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), error.getDefaultMessage());
}
}
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), "");
final Category tempCategory = categoryService.findByCateUrl(category.getCateUrl());
if (null != category.getCateId()) {
if (null != tempCategory && !category.getCateId().equals(tempCategory.getCateId())) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.url-is-exists"));
}
} else {
if (null != tempCategory) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.url-is-exists"));
}
}
category = categoryService.save(category);
if (null == category) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.save-failed"));
}
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.common.save-success"));
}
/**
*
*
* @param cateId cateId
*
* @return /admin/category
*/
@GetMapping(value = "/remove")
public String removeCategory(@RequestParam("cateId") Long cateId) {
try {
categoryService.removeByCateId(cateId);
categoryService.remove(cateId);
} catch (Exception e) {
log.error("Delete category failed: {}", e.getMessage());
}
@ -96,12 +99,13 @@ public class CategoryController {
*
* @param cateId cateId
* @param model model
*
* @return admin/admin_category
*/
@GetMapping(value = "/edit")
public String toEditCategory(Model model, @RequestParam("cateId") Long cateId) {
Optional<Category> category = categoryService.findByCateId(cateId);
model.addAttribute("updateCategory", category.get());
final Optional<Category> category = categoryService.findByCateId(cateId);
model.addAttribute("updateCategory", category.orElse(new Category()));
return "admin/admin_category";
}
}

View File

@ -13,6 +13,7 @@ import cc.ryanc.halo.utils.OwoUtil;
import cc.ryanc.halo.web.controller.core.BaseController;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.servlet.ServletUtil;
@ -61,6 +62,7 @@ public class CommentController extends BaseController {
* @param status status
* @param page page
* @param size size
*
* @return admin/admin_comment
*/
@GetMapping
@ -68,9 +70,9 @@ public class CommentController extends BaseController {
@RequestParam(value = "status", defaultValue = "0") Integer status,
@RequestParam(value = "page", defaultValue = "0") Integer page,
@RequestParam(value = "size", defaultValue = "10") Integer size) {
Sort sort = new Sort(Sort.Direction.DESC, "commentDate");
Pageable pageable = PageRequest.of(page, size, sort);
Page<Comment> comments = commentService.findAllComments(status, pageable);
final Sort sort = new Sort(Sort.Direction.DESC, "commentDate");
final Pageable pageable = PageRequest.of(page, size, sort);
final Page<Comment> comments = commentService.findAll(status, pageable);
model.addAttribute("comments", comments);
model.addAttribute("publicCount", commentService.getCountByStatus(CommentStatusEnum.PUBLISHED.getCode()));
model.addAttribute("checkCount", commentService.getCountByStatus(CommentStatusEnum.CHECKING.getCode()));
@ -84,6 +86,7 @@ public class CommentController extends BaseController {
*
* @param commentId
* @param status
*
* @return /admin/comments
*/
@GetMapping(value = "/throw")
@ -104,15 +107,16 @@ public class CommentController extends BaseController {
* @param commentId
* @param status
* @param session session
*
* @return /admin/comments
*/
@GetMapping(value = "/revert")
public String moveToPublish(@RequestParam("commentId") Long commentId,
@RequestParam("status") Integer status,
HttpSession session) {
Comment comment = commentService.updateCommentStatus(commentId, CommentStatusEnum.PUBLISHED.getCode());
Post post = comment.getPost();
User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
final Comment comment = commentService.updateCommentStatus(commentId, CommentStatusEnum.PUBLISHED.getCode());
final Post post = comment.getPost();
final User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
//判断是否启用邮件服务
new NoticeToAuthor(comment, post, user, status).start();
@ -125,6 +129,7 @@ public class CommentController extends BaseController {
* @param commentId commentId
* @param status status
* @param page
*
* @return string /admin/comments
*/
@GetMapping(value = "/remove")
@ -132,7 +137,7 @@ public class CommentController extends BaseController {
@RequestParam("status") Integer status,
@RequestParam(value = "page", defaultValue = "0") Integer page) {
try {
commentService.removeByCommentId(commentId);
commentService.remove(commentId);
} catch (Exception e) {
log.error("Delete comment failed: {}", e.getMessage());
}
@ -145,45 +150,52 @@ public class CommentController extends BaseController {
*
* @param commentId
* @param commentContent
*
* @return JsonResult
*/
@PostMapping(value = "/reply")
@ResponseBody
public JsonResult replyComment(@RequestParam("commentId") Long commentId,
@RequestParam("postId") Long postId,
@RequestParam("commentContent") String commentContent,
@RequestParam("userAgent") String userAgent,
HttpServletRequest request,
HttpSession session) {
@RequestParam("postId") Long postId,
@RequestParam("commentContent") String commentContent,
@RequestParam("userAgent") String userAgent,
HttpServletRequest request,
HttpSession session) {
try {
Post post = postService.findByPostId(postId).get();
final Post post = postService.findByPostId(postId).orElse(new Post());
//博主信息
User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
final User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
//被回复的评论
Comment lastComment = commentService.findCommentById(commentId).get();
final Comment lastComment = commentService.findCommentById(commentId).orElse(new Comment());
//修改被回复的评论的状态
lastComment.setCommentStatus(CommentStatusEnum.PUBLISHED.getCode());
commentService.saveByComment(lastComment);
commentService.save(lastComment);
//保存评论
Comment comment = new Comment();
final Comment comment = new Comment();
comment.setPost(post);
comment.setCommentAuthor(user.getUserDisplayName());
comment.setCommentAuthorEmail(user.getUserEmail());
comment.setCommentAuthorUrl(HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()));
comment.setCommentAuthorIp(ServletUtil.getClientIP(request));
comment.setCommentAuthorAvatarMd5(SecureUtil.md5(user.getUserEmail()));
comment.setCommentDate(DateUtil.date());
String lastContent = "<a href='#comment-id-" + lastComment.getCommentId() + "'>@" + lastComment.getCommentAuthor() + "</a> ";
comment.setCommentContent(lastContent + OwoUtil.markToImg(HtmlUtil.escape(commentContent).replace("&lt;br/&gt;", "<br/>")));
final StrBuilder buildContent = new StrBuilder("<a href='#comment-id-");
buildContent.append(lastComment.getCommentId());
buildContent.append("'>@");
buildContent.append(lastComment.getCommentAuthor());
buildContent.append("</a> ");
buildContent.append(OwoUtil.markToImg(HtmlUtil.escape(commentContent).replace("&lt;br/&gt;", "<br/>")));
comment.setCommentContent(buildContent.toString());
comment.setCommentAgent(userAgent);
comment.setCommentParent(commentId);
comment.setCommentStatus(CommentStatusEnum.PUBLISHED.getCode());
comment.setIsAdmin(1);
commentService.saveByComment(comment);
commentService.save(comment);
//邮件通知
new EmailToAuthor(comment, lastComment, post, user, commentContent).start();
@ -217,15 +229,22 @@ public class CommentController extends BaseController {
public void run() {
if (StrUtil.equals(HaloConst.OPTIONS.get(BlogPropertiesEnum.SMTP_EMAIL_ENABLE.getProp()), TrueFalseEnum.TRUE.getDesc()) && StrUtil.equals(HaloConst.OPTIONS.get(BlogPropertiesEnum.COMMENT_REPLY_NOTICE.getProp()), TrueFalseEnum.TRUE.getDesc())) {
if (Validator.isEmail(lastComment.getCommentAuthorEmail())) {
Map<String, Object> map = new HashMap<>(8);
final Map<String, Object> map = new HashMap<>(8);
map.put("blogTitle", HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_TITLE.getProp()));
map.put("commentAuthor", lastComment.getCommentAuthor());
map.put("pageName", lastComment.getPost().getPostTitle());
final StrBuilder pageUrl = new StrBuilder(HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()));
if (StrUtil.equals(post.getPostType(), PostTypeEnum.POST_TYPE_POST.getDesc())) {
map.put("pageUrl", HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
pageUrl.append("/archives/");
} else {
map.put("pageUrl", HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/p/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
pageUrl.append("/p/");
}
pageUrl.append(post.getPostUrl());
pageUrl.append("#comment-id-");
pageUrl.append(comment.getCommentId());
map.put("pageUrl", pageUrl.toString());
map.put("commentContent", lastComment.getCommentContent());
map.put("replyAuthor", user.getUserDisplayName());
map.put("replyContent", commentContent);
@ -259,12 +278,19 @@ public class CommentController extends BaseController {
if (StrUtil.equals(HaloConst.OPTIONS.get(BlogPropertiesEnum.SMTP_EMAIL_ENABLE.getProp()), TrueFalseEnum.TRUE.getDesc()) && StrUtil.equals(HaloConst.OPTIONS.get(BlogPropertiesEnum.COMMENT_REPLY_NOTICE.getProp()), TrueFalseEnum.TRUE.getDesc())) {
try {
if (status == 1 && Validator.isEmail(comment.getCommentAuthorEmail())) {
Map<String, Object> map = new HashMap<>(6);
final Map<String, Object> map = new HashMap<>(6);
final StrBuilder pageUrl = new StrBuilder(HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()));
if (StrUtil.equals(post.getPostType(), PostTypeEnum.POST_TYPE_POST.getDesc())) {
map.put("pageUrl", HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
pageUrl.append("/archives/");
} else {
map.put("pageUrl", HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/p/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
pageUrl.append("/p/");
}
pageUrl.append(post.getPostUrl());
pageUrl.append("#comment-id-");
pageUrl.append(comment.getCommentId());
map.put("pageUrl", pageUrl.toString());
map.put("pageName", post.getPostTitle());
map.put("commentContent", comment.getCommentContent());
map.put("blogUrl", HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()));

View File

@ -1,13 +1,19 @@
package cc.ryanc.halo.web.controller.admin;
import cc.ryanc.halo.model.domain.Menu;
import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.enums.ResultCodeEnum;
import cc.ryanc.halo.service.MenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* <pre>
*
@ -28,6 +34,7 @@ public class MenuController {
*
*
* @param model model
*
* @return /admin/admin_menu
*/
@GetMapping
@ -39,16 +46,23 @@ public class MenuController {
* /
*
* @param menu menu
*
* @return /admin/menus
*/
@PostMapping(value = "/save")
public String saveMenu(@ModelAttribute Menu menu) {
try {
menuService.saveByMenu(menu);
} catch (Exception e) {
log.error("Saving menu failed: {}" + e.getMessage());
@ResponseBody
public JsonResult saveMenu(@Valid Menu menu, BindingResult result) {
if (result.hasErrors()) {
for (ObjectError error : result.getAllErrors()) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), error.getDefaultMessage());
}
}
menu = menuService.save(menu);
if (null != menu) {
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), "菜单保存成功!");
} else {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), "菜单保存成功!");
}
return "redirect:/admin/menus";
}
/**
@ -56,11 +70,12 @@ public class MenuController {
*
* @param menuId
* @param model model
*
* @return /admin/admin_menu
*/
@GetMapping(value = "/edit")
public String updateMenu(@RequestParam("menuId") Long menuId, Model model) {
Menu menu = menuService.findByMenuId(menuId).get();
final Menu menu = menuService.findByMenuId(menuId).orElse(new Menu());
model.addAttribute("updateMenu", menu);
return "/admin/admin_menu";
}
@ -69,12 +84,13 @@ public class MenuController {
*
*
* @param menuId
*
* @return /admin/menus
*/
@GetMapping(value = "/remove")
public String removeMenu(@RequestParam("menuId") Long menuId) {
try {
menuService.removeByMenuId(menuId);
menuService.remove(menuId);
} catch (Exception e) {
log.error("Deleting menu failed: {}", e.getMessage());
}

View File

@ -10,7 +10,9 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import javax.servlet.http.HttpSession;
import java.util.Map;
/**
@ -49,17 +51,19 @@ public class OptionController {
*
*
* @param options options
*
* @return JsonResult
*/
@PostMapping(value = "/save")
@ResponseBody
public JsonResult saveOptions(@RequestParam Map<String, String> options) {
public JsonResult saveOptions(@RequestParam Map<String, String> options, HttpSession session) {
try {
optionsService.saveOptions(options);
//刷新options
configuration.setSharedVariable("options", optionsService.findAllOptions());
HaloConst.OPTIONS.clear();
HaloConst.OPTIONS = optionsService.findAllOptions();
session.removeAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);
log.info("List of saved options: " + options);
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.common.save-success"));
} catch (Exception e) {

View File

@ -1,6 +1,9 @@
package cc.ryanc.halo.web.controller.admin;
import cc.ryanc.halo.model.domain.*;
import cc.ryanc.halo.model.domain.Gallery;
import cc.ryanc.halo.model.domain.Link;
import cc.ryanc.halo.model.domain.Post;
import cc.ryanc.halo.model.domain.User;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.dto.LogsRecord;
@ -13,22 +16,29 @@ import cc.ryanc.halo.service.LogsService;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.utils.HaloUtils;
import cc.ryanc.halo.utils.LocaleMessageUtil;
import cc.ryanc.halo.utils.MarkdownUtils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;
@ -47,14 +57,19 @@ public class PageController {
@Autowired
LocaleMessageUtil localeMessageUtil;
@Autowired
private LinkService linkService;
@Autowired
private GalleryService galleryService;
@Autowired
private PostService postService;
@Autowired
private LogsService logsService;
@Autowired
private HttpServletRequest request;
@ -62,11 +77,12 @@ public class PageController {
*
*
* @param model model
*
* @return admin/admin_page
*/
@GetMapping
public String pages(Model model) {
List<Post> posts = postService.findAllPosts(PostTypeEnum.POST_TYPE_PAGE.getDesc());
final List<Post> posts = postService.findAll(PostTypeEnum.POST_TYPE_PAGE.getDesc());
model.addAttribute("pages", posts);
return "admin/admin_page";
}
@ -86,12 +102,13 @@ public class PageController {
*
* @param model model
* @param linkId linkId
*
* @return String admin/admin_page_link
*/
@GetMapping(value = "/links/edit")
public String toEditLink(Model model, @RequestParam("linkId") Long linkId) {
Optional<Link> link = linkService.findByLinkId(linkId);
model.addAttribute("updateLink", link.get());
final Optional<Link> link = linkService.findByLinkId(linkId);
model.addAttribute("updateLink", link.orElse(new Link()));
return "admin/admin_page_link";
}
@ -99,28 +116,35 @@ public class PageController {
* /
*
* @param link Link
* @return /admin/page/links
*
* @return JsonResult
*/
@PostMapping(value = "/links/save")
public String saveLink(@ModelAttribute Link link) {
try {
linkService.saveByLink(link);
} catch (Exception e) {
log.error("Save/modify friendship link failed: {}", e.getMessage());
@ResponseBody
public JsonResult saveLink(@Valid Link link, BindingResult result) {
if (result.hasErrors()) {
for (ObjectError error : result.getAllErrors()) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), error.getDefaultMessage());
}
}
return "redirect:/admin/page/links";
link = linkService.save(link);
if (null == link) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.save-failed"));
}
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.common.save-success"));
}
/**
*
*
* @param linkId
*
* @return /admin/page/links
*/
@GetMapping(value = "/links/remove")
public String removeLink(@RequestParam("linkId") Long linkId) {
try {
linkService.removeByLinkId(linkId);
linkService.remove(linkId);
} catch (Exception e) {
log.error("Deleting a friendship link failed: {}", e.getMessage());
}
@ -133,15 +157,16 @@ public class PageController {
* @param model model
* @param page
* @param size
*
* @return admin/admin_page_gallery
*/
@GetMapping(value = "/galleries")
public String gallery(Model model,
@RequestParam(value = "page", defaultValue = "0") Integer page,
@RequestParam(value = "size", defaultValue = "18") Integer size) {
Sort sort = new Sort(Sort.Direction.DESC, "galleryId");
Pageable pageable = PageRequest.of(page, size, sort);
Page<Gallery> galleries = galleryService.findAllGalleries(pageable);
final Sort sort = new Sort(Sort.Direction.DESC, "galleryId");
final Pageable pageable = PageRequest.of(page, size, sort);
final Page<Gallery> galleries = galleryService.findAll(pageable);
model.addAttribute("galleries", galleries);
return "admin/admin_page_gallery";
}
@ -150,6 +175,7 @@ public class PageController {
*
*
* @param gallery gallery
*
* @return /admin/page/gallery
*/
@PostMapping(value = "/gallery/save")
@ -158,7 +184,7 @@ public class PageController {
if (StrUtil.isEmpty(gallery.getGalleryThumbnailUrl())) {
gallery.setGalleryThumbnailUrl(gallery.getGalleryUrl());
}
galleryService.saveByGallery(gallery);
galleryService.save(gallery);
} catch (Exception e) {
e.printStackTrace();
}
@ -170,12 +196,13 @@ public class PageController {
*
* @param model model
* @param galleryId
*
* @return admin/widget/_gallery-detail
*/
@GetMapping(value = "/gallery")
public String gallery(Model model, @RequestParam("galleryId") Long galleryId) {
Optional<Gallery> gallery = galleryService.findByGalleryId(galleryId);
model.addAttribute("gallery", gallery.get());
final Optional<Gallery> gallery = galleryService.findByGalleryId(galleryId);
model.addAttribute("gallery", gallery.orElse(new Gallery()));
return "admin/widget/_gallery-detail";
}
@ -183,13 +210,14 @@ public class PageController {
*
*
* @param galleryId
*
* @return JsonResult
*/
@GetMapping(value = "/gallery/remove")
@ResponseBody
public JsonResult removeGallery(@RequestParam("galleryId") Long galleryId) {
try {
galleryService.removeByGalleryId(galleryId);
galleryService.remove(galleryId);
} catch (Exception e) {
log.error("Failed to delete image: {}", e.getMessage());
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.delete-failed"));
@ -201,12 +229,13 @@ public class PageController {
*
*
* @param model model
*
* @return admin/admin_page_md_editor
*/
@GetMapping(value = "/new")
public String newPage(Model model) {
List<String> customTpls = HaloUtils.getCustomTpl(HaloConst.OPTIONS.get(BlogPropertiesEnum.THEME.getProp()));
model.addAttribute("customTpls",customTpls);
final List<String> customTpls = HaloUtils.getCustomTpl(HaloConst.OPTIONS.get(BlogPropertiesEnum.THEME.getProp()));
model.addAttribute("customTpls", customTpls);
return "admin/admin_page_md_editor";
}
@ -221,26 +250,25 @@ public class PageController {
public JsonResult pushPage(@ModelAttribute Post post, HttpSession session) {
String msg = localeMessageUtil.getMessage("code.admin.common.save-success");
try {
post.setPostDate(DateUtil.date());
//发表用户
User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
final User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
post.setUser(user);
post.setPostType(PostTypeEnum.POST_TYPE_PAGE.getDesc());
if (null != post.getPostId()) {
post.setPostViews(postService.findByPostId(post.getPostId()).get().getPostViews());
post.setPostDate(postService.findByPostId(post.getPostId()).get().getPostDate());
post.setPostUpdate(DateUtil.date());
final Post oldPost = postService.findByPostId(post.getPostId()).get();
if (null == post.getPostDate()) {
post.setPostDate(DateUtil.date());
}
post.setPostViews(oldPost.getPostViews());
msg = localeMessageUtil.getMessage("code.admin.common.update-success");
} else {
post.setPostDate(DateUtil.date());
post.setPostUpdate(DateUtil.date());
}
post.setPostContent(MarkdownUtils.renderMarkdown(post.getPostContentMd()));
//当没有选择文章缩略图的时候,自动分配一张内置的缩略图
if (StrUtil.equals(post.getPostThumbnail(), BlogPropertiesEnum.DEFAULT_THUMBNAIL.getProp())) {
post.setPostThumbnail("/static/images/thumbnail/thumbnail-" + RandomUtil.randomInt(1, 10) + ".jpg");
post.setPostThumbnail("/static/halo-frontend/images/thumbnail/thumbnail-" + RandomUtil.randomInt(1, 10) + ".jpg");
}
postService.saveByPost(post);
logsService.saveByLogs(new Logs(LogsRecord.PUSH_PAGE, post.getPostTitle(), ServletUtil.getClientIP(request), DateUtil.date()));
postService.save(post);
logsService.save(LogsRecord.PUSH_PAGE, post.getPostTitle(), request);
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), msg);
} catch (Exception e) {
log.error("Save page failed: {}", e.getMessage());
@ -253,14 +281,15 @@ public class PageController {
*
* @param pageId
* @param model model
*
* @return admin/admin_page_md_editor
*/
@GetMapping(value = "/edit")
public String editPage(@RequestParam("pageId") Long pageId, Model model) {
Optional<Post> post = postService.findByPostId(pageId);
List<String> customTpls = HaloUtils.getCustomTpl(HaloConst.OPTIONS.get(BlogPropertiesEnum.THEME.getProp()));
model.addAttribute("post", post.get());
model.addAttribute("customTpls",customTpls);
final Optional<Post> post = postService.findByPostId(pageId);
final List<String> customTpls = HaloUtils.getCustomTpl(HaloConst.OPTIONS.get(BlogPropertiesEnum.THEME.getProp()));
model.addAttribute("post", post.orElse(new Post()));
model.addAttribute("customTpls", customTpls);
return "admin/admin_page_md_editor";
}
@ -268,15 +297,22 @@ public class PageController {
*
*
* @param postUrl postUrl
*
* @return JsonResult
*/
@GetMapping(value = "/checkUrl")
@ResponseBody
public JsonResult checkUrlExists(@RequestParam("postUrl") String postUrl) {
Post post = postService.findByPostUrl(postUrl, PostTypeEnum.POST_TYPE_PAGE.getDesc());
final Post post = postService.findByPostUrl(postUrl, PostTypeEnum.POST_TYPE_PAGE.getDesc());
if (null != post) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.url-is-exists"));
}
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), "");
}
@InitBinder
public void initBinder(ServletRequestDataBinder binder) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true));
}
}

View File

@ -1,6 +1,7 @@
package cc.ryanc.halo.web.controller.admin;
import cc.ryanc.halo.model.domain.*;
import cc.ryanc.halo.model.domain.Post;
import cc.ryanc.halo.model.domain.User;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.dto.LogsRecord;
@ -8,30 +9,32 @@ import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.model.enums.PostStatusEnum;
import cc.ryanc.halo.model.enums.PostTypeEnum;
import cc.ryanc.halo.model.enums.ResultCodeEnum;
import cc.ryanc.halo.service.CategoryService;
import cc.ryanc.halo.service.LogsService;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.service.TagService;
import cc.ryanc.halo.utils.HaloUtils;
import cc.ryanc.halo.utils.LocaleMessageUtil;
import cc.ryanc.halo.utils.MarkdownUtils;
import cc.ryanc.halo.web.controller.core.BaseController;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.HtmlUtil;
import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;
@ -51,12 +54,6 @@ public class PostController extends BaseController {
@Autowired
private PostService postService;
@Autowired
private CategoryService categoryService;
@Autowired
private TagService tagService;
@Autowired
private LogsService logsService;
@ -95,9 +92,9 @@ public class PostController extends BaseController {
@RequestParam(value = "status", defaultValue = "0") Integer status,
@RequestParam(value = "page", defaultValue = "0") Integer page,
@RequestParam(value = "size", defaultValue = "10") Integer size) {
Sort sort = new Sort(Sort.Direction.DESC, "postDate");
Pageable pageable = PageRequest.of(page, size, sort);
Page<Post> posts = postService.findPostByStatus(status, PostTypeEnum.POST_TYPE_POST.getDesc(), pageable);
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
final Pageable pageable = PageRequest.of(page, size, sort);
final Page<Post> posts = postService.findPostByStatus(status, PostTypeEnum.POST_TYPE_POST.getDesc(), pageable);
model.addAttribute("posts", posts);
model.addAttribute("publishCount", postService.getCountByStatus(PostStatusEnum.PUBLISHED.getCode()));
model.addAttribute("draftCount", postService.getCountByStatus(PostStatusEnum.DRAFT.getCode()));
@ -122,9 +119,9 @@ public class PostController extends BaseController {
@RequestParam(value = "size", defaultValue = "10") Integer size) {
try {
//排序规则
Sort sort = new Sort(Sort.Direction.DESC, "postId");
Pageable pageable = PageRequest.of(page, size, sort);
model.addAttribute("posts", postService.searchPosts(keyword, pageable));
final Sort sort = new Sort(Sort.Direction.DESC, "postId");
final Pageable pageable = PageRequest.of(page, size, sort);
model.addAttribute("posts", postService.searchPosts(keyword, PostTypeEnum.POST_TYPE_POST.getDesc(), PostStatusEnum.PUBLISHED.getCode(), pageable));
} catch (Exception e) {
log.error("未知错误:{}", e.getMessage());
}
@ -140,8 +137,8 @@ public class PostController extends BaseController {
*/
@GetMapping(value = "/view")
public String viewPost(@RequestParam("postId") Long postId, Model model) {
Optional<Post> post = postService.findByPostId(postId);
model.addAttribute("post", post.get());
final Optional<Post> post = postService.findByPostId(postId);
model.addAttribute("post", post.orElse(new Post()));
return this.render("post");
}
@ -150,70 +147,100 @@ public class PostController extends BaseController {
*
* @return admin/admin_editor
*/
@GetMapping(value = "/new")
public String newPost() {
return "admin/admin_post_md_editor";
@GetMapping(value = "/write")
public String writePost() {
return "admin/admin_post_new";
}
/**
*
*
* @param postId
* @param model model
* @return admin/admin_editor
*/
@GetMapping(value = "/edit")
public String editPost(@RequestParam("postId") Long postId, Model model) {
final Optional<Post> post = postService.findByPostId(postId);
model.addAttribute("post", post.orElse(new Post()));
return "admin/admin_post_edit";
}
/**
*
*
* @param post Post
* @param post post
* @param cateList
* @param tagList
* @param tagList
* @param session session
*/
@PostMapping(value = "/new/push")
@PostMapping(value = "/save")
@ResponseBody
public JsonResult pushPost(@ModelAttribute Post post, @RequestParam("cateList") List<String> cateList, @RequestParam("tagList") String tagList, HttpSession session) {
User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
String msg = localeMessageUtil.getMessage("code.admin.common.save-success");
public JsonResult save(@ModelAttribute Post post,
@RequestParam("cateList") List<String> cateList,
@RequestParam("tagList") String tagList,
HttpSession session) {
final User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
try {
//提取摘要
int postSummary = 50;
if (StrUtil.isNotEmpty(HaloConst.OPTIONS.get(BlogPropertiesEnum.POST_SUMMARY.getProp()))) {
postSummary = Integer.parseInt(HaloConst.OPTIONS.get(BlogPropertiesEnum.POST_SUMMARY.getProp()));
}
//文章摘要
String summaryText = StrUtil.trim(HtmlUtil.cleanHtmlTag(post.getPostContent()));
if (summaryText.length() > postSummary) {
String summary = summaryText.substring(0, postSummary);
post.setPostSummary(summary);
} else {
post.setPostSummary(summaryText);
}
//添加文章时,添加文章时间和修改文章时间为当前时间,修改文章时,只更新修改文章时间
if (null != post.getPostId()) {
Post oldPost = postService.findByPostId(post.getPostId()).get();
post.setPostDate(oldPost.getPostDate());
post.setPostUpdate(DateUtil.date());
post.setPostViews(oldPost.getPostViews());
msg = localeMessageUtil.getMessage("code.admin.common.update-success");
} else {
post.setPostDate(DateUtil.date());
post.setPostUpdate(DateUtil.date());
}
post.setPostContent(MarkdownUtils.renderMarkdown(post.getPostContentMd()));
post.setUser(user);
List<Category> categories = categoryService.strListToCateList(cateList);
post.setCategories(categories);
if (StrUtil.isNotEmpty(tagList)) {
List<Tag> tags = tagService.strListToTagList(StrUtil.trim(tagList));
post.setTags(tags);
}
post = postService.buildCategoriesAndTags(post, cateList, tagList);
post.setPostUrl(urlFilter(post.getPostUrl()));
if (StrUtil.isNotEmpty(post.getPostPassword())) {
post.setPostPassword(SecureUtil.md5(post.getPostPassword()));
}
//当没有选择文章缩略图的时候,自动分配一张内置的缩略图
if (StrUtil.equals(post.getPostThumbnail(), BlogPropertiesEnum.DEFAULT_THUMBNAIL.getProp())) {
post.setPostThumbnail("/static/images/thumbnail/thumbnail-" + RandomUtil.randomInt(1, 10) + ".jpg");
post.setPostThumbnail("/static/halo-frontend/images/thumbnail/thumbnail-" + RandomUtil.randomInt(1, 10) + ".jpg");
}
postService.saveByPost(post);
logsService.saveByLogs(new Logs(LogsRecord.PUSH_POST, post.getPostTitle(), ServletUtil.getClientIP(request), DateUtil.date()));
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), msg);
postService.save(post);
logsService.save(LogsRecord.PUSH_POST, post.getPostTitle(), request);
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.common.save-success"));
} catch (Exception e) {
log.error("Save article failed: {}", e.getMessage());
e.printStackTrace();
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.save-failed"));
}
}
/**
*
*
* @param post post
* @param cateList
* @param tagList
* @param session session
* @return JsonResult
*/
@PostMapping(value = "/update")
@ResponseBody
public JsonResult update(@ModelAttribute Post post,
@RequestParam("cateList") List<String> cateList,
@RequestParam("tagList") String tagList) {
//old data
final Post oldPost = postService.findByPostId(post.getPostId()).orElse(new Post());
post.setPostViews(oldPost.getPostViews());
post.setPostContent(MarkdownUtils.renderMarkdown(post.getPostContentMd()));
post.setUser(oldPost.getUser());
if (null == post.getPostDate()) {
post.setPostDate(new Date());
}
post = postService.buildCategoriesAndTags(post, cateList, tagList);
if (StrUtil.isNotEmpty(post.getPostPassword())) {
post.setPostPassword(SecureUtil.md5(post.getPostPassword()));
}
//当没有选择文章缩略图的时候,自动分配一张内置的缩略图
if (StrUtil.equals(post.getPostThumbnail(), BlogPropertiesEnum.DEFAULT_THUMBNAIL.getProp())) {
post.setPostThumbnail("/static/halo-frontend/images/thumbnail/thumbnail-" + RandomUtil.randomInt(1, 10) + ".jpg");
}
post = postService.save(post);
if (null != post) {
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.common.update-success"));
} else {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.update-failed"));
}
}
/**
*
*
@ -258,9 +285,9 @@ public class PostController extends BaseController {
@GetMapping(value = "/remove")
public String removePost(@RequestParam("postId") Long postId, @RequestParam("postType") String postType) {
try {
Optional<Post> post = postService.findByPostId(postId);
postService.removeByPostId(postId);
logsService.saveByLogs(new Logs(LogsRecord.REMOVE_POST, post.get().getPostTitle(), ServletUtil.getClientIP(request), DateUtil.date()));
final Optional<Post> post = postService.findByPostId(postId);
postService.remove(postId);
logsService.save(LogsRecord.REMOVE_POST, post.get().getPostTitle(), request);
} catch (Exception e) {
log.error("Delete article failed: {}", e.getMessage());
}
@ -270,20 +297,6 @@ public class PostController extends BaseController {
return "redirect:/admin/page";
}
/**
*
*
* @param postId
* @param model model
* @return admin/admin_editor
*/
@GetMapping(value = "/edit")
public String editPost(@RequestParam("postId") Long postId, Model model) {
Optional<Post> post = postService.findByPostId(postId);
model.addAttribute("post", post.get());
return "admin/admin_post_md_editor";
}
/**
*
*
@ -313,7 +326,7 @@ public class PostController extends BaseController {
@ResponseBody
public JsonResult checkUrlExists(@RequestParam("postUrl") String postUrl) {
postUrl = urlFilter(postUrl);
Post post = postService.findByPostUrl(postUrl, PostTypeEnum.POST_TYPE_POST.getDesc());
final Post post = postService.findByPostUrl(postUrl, PostTypeEnum.POST_TYPE_POST.getDesc());
if (null != post) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.url-is-exists"));
}
@ -332,19 +345,25 @@ public class PostController extends BaseController {
if (StrUtil.isBlank(baiduToken)) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.post.no-baidu-token"));
}
String blogUrl = HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp());
List<Post> posts = postService.findAllPosts(PostTypeEnum.POST_TYPE_POST.getDesc());
StringBuilder urls = new StringBuilder();
final String blogUrl = HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp());
final List<Post> posts = postService.findAll(PostTypeEnum.POST_TYPE_POST.getDesc());
final StringBuilder urls = new StringBuilder();
for (Post post : posts) {
urls.append(blogUrl);
urls.append("/archives/");
urls.append(post.getPostUrl());
urls.append("\n");
}
String result = HaloUtils.baiduPost(blogUrl, baiduToken, urls.toString());
final String result = HaloUtils.baiduPost(blogUrl, baiduToken, urls.toString());
if (StrUtil.isEmpty(result)) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.post.push-to-baidu-failed"));
}
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.post.push-to-baidu-success"));
}
@InitBinder
public void initBinder(ServletRequestDataBinder binder) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true));
}
}

View File

@ -9,8 +9,12 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
/**
* <pre>
*
@ -44,44 +48,45 @@ public class TagController {
* /
*
* @param tag tag
* @return /admin/tag
*
* @return JsonResult
*/
@PostMapping(value = "/save")
public String saveTag(@ModelAttribute Tag tag) {
try {
tagService.saveByTag(tag);
} catch (Exception e) {
log.error("Add/modify tag failed: {}", e.getMessage());
}
return "redirect:/admin/tag";
}
/**
*
*
* @param tagUrl
* @return truefalse
*/
@GetMapping(value = "/checkUrl")
@ResponseBody
public JsonResult checkTagUrlExists(@RequestParam("tagUrl") String tagUrl) {
Tag tag = tagService.findByTagUrl(tagUrl);
if (null != tag) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.url-is-exists"));
public JsonResult saveTag(@Valid Tag tag, BindingResult result) {
if (result.hasErrors()) {
for (ObjectError error : result.getAllErrors()) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), error.getDefaultMessage());
}
}
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), "");
final Tag tempTag = tagService.findByTagUrl(tag.getTagUrl());
if (null != tag.getTagId()) {
if (null != tempTag && !tag.getTagId().equals(tempTag.getTagId())) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.url-is-exists"));
}
} else {
if (null != tempTag) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.url-is-exists"));
}
}
tag = tagService.save(tag);
if (null == tag) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.save-failed"));
}
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.common.save-success"));
}
/**
*
*
* @param tagId
*
* @return /admin/tag
*/
@GetMapping(value = "/remove")
public String removeTag(@RequestParam("tagId") Long tagId) {
try {
tagService.removeByTagId(tagId);
tagService.remove(tagId);
} catch (Exception e) {
log.error("Failed to delete tag: {}", e.getMessage());
}
@ -93,11 +98,12 @@ public class TagController {
*
* @param model model
* @param tagId
*
* @return admin/admin_tag
*/
@GetMapping(value = "/edit")
public String toEditTag(Model model, @RequestParam("tagId") Long tagId) {
Tag tag = tagService.findByTagId(tagId).get();
final Tag tag = tagService.findByTagId(tagId).orElse(new Tag());
model.addAttribute("updateTag", tag);
return "admin/admin_tag";
}

View File

@ -1,6 +1,5 @@
package cc.ryanc.halo.web.controller.admin;
import cc.ryanc.halo.model.domain.Logs;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.dto.LogsRecord;
@ -12,14 +11,13 @@ import cc.ryanc.halo.service.OptionsService;
import cc.ryanc.halo.utils.HaloUtils;
import cc.ryanc.halo.utils.LocaleMessageUtil;
import cc.ryanc.halo.web.controller.core.BaseController;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.extra.servlet.ServletUtil;
import freemarker.template.Configuration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -66,6 +64,7 @@ public class ThemeController extends BaseController {
*
*
* @param model model
*
* @return admin/admin_theme
*/
@GetMapping
@ -82,6 +81,7 @@ public class ThemeController extends BaseController {
*
* @param siteTheme
* @param request request
*
* @return JsonResult
*/
@GetMapping(value = "/set")
@ -99,9 +99,7 @@ public class ThemeController extends BaseController {
configuration.setSharedVariable("themeName", siteTheme);
configuration.setSharedVariable("options", HaloConst.OPTIONS);
log.info("Changed theme to {}", siteTheme);
logsService.saveByLogs(
new Logs(LogsRecord.CHANGE_THEME, "更换为" + siteTheme, ServletUtil.getClientIP(request), DateUtil.date())
);
logsService.save(LogsRecord.CHANGE_THEME, "更换为" + siteTheme, request);
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.theme.change-success", new Object[]{siteTheme}));
} catch (Exception e) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.theme.change-failed"));
@ -113,6 +111,7 @@ public class ThemeController extends BaseController {
*
*
* @param file
*
* @return JsonResult
*/
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ -122,13 +121,11 @@ public class ThemeController extends BaseController {
try {
if (!file.isEmpty()) {
//获取项目根路径
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
File themePath = new File(basePath.getAbsolutePath(), new StringBuffer("templates/themes/").append(file.getOriginalFilename()).toString());
final File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
final File themePath = new File(basePath.getAbsolutePath(), new StringBuffer("templates/themes/").append(file.getOriginalFilename()).toString());
file.transferTo(themePath);
log.info("Upload topic success, path is " + themePath.getAbsolutePath());
logsService.saveByLogs(
new Logs(LogsRecord.UPLOAD_THEME, file.getOriginalFilename(), ServletUtil.getClientIP(request), DateUtil.date())
);
logsService.save(LogsRecord.UPLOAD_THEME, file.getOriginalFilename(), request);
ZipUtil.unzip(themePath, new File(basePath.getAbsolutePath(), "templates/themes/"));
FileUtil.del(themePath);
HaloConst.THEMES.clear();
@ -148,13 +145,14 @@ public class ThemeController extends BaseController {
*
*
* @param themeName
*
* @return string /admin/themes
*/
@GetMapping(value = "/remove")
public String removeTheme(@RequestParam("themeName") String themeName) {
try {
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
File themePath = new File(basePath.getAbsolutePath(), "templates/themes/" + themeName);
final File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
final File themePath = new File(basePath.getAbsolutePath(), "templates/themes/" + themeName);
FileUtil.del(themePath);
HaloConst.THEMES.clear();
HaloConst.THEMES = HaloUtils.getThemes();
@ -179,6 +177,7 @@ public class ThemeController extends BaseController {
*
* @param remoteAddr
* @param themeName
*
* @return JsonResult
*/
@PostMapping(value = "/clone")
@ -189,9 +188,9 @@ public class ThemeController extends BaseController {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.info-no-complete"));
}
try {
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
File themePath = new File(basePath.getAbsolutePath(), "templates/themes");
String cmdResult = RuntimeUtil.execForStr("git clone " + remoteAddr + " " + themePath.getAbsolutePath() + "/" + themeName);
final File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
final File themePath = new File(basePath.getAbsolutePath(), "templates/themes");
final String cmdResult = RuntimeUtil.execForStr("git clone " + remoteAddr + " " + themePath.getAbsolutePath() + "/" + themeName);
if (NOT_FOUND_GIT.equals(cmdResult)) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.theme.no-git"));
}
@ -208,15 +207,16 @@ public class ThemeController extends BaseController {
*
*
* @param themeName
*
* @return JsonResult
*/
@GetMapping(value = "/pull")
@ResponseBody
public JsonResult pullFromRemote(@RequestParam(value = "themeName") String themeName) {
try {
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
File themePath = new File(basePath.getAbsolutePath(), "templates/themes");
String cmdResult = RuntimeUtil.execForStr("cd " + themePath.getAbsolutePath() + "/" + themeName + " && git pull");
final File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
final File themePath = new File(basePath.getAbsolutePath(), "templates/themes");
final String cmdResult = RuntimeUtil.execForStr("cd " + themePath.getAbsolutePath() + "/" + themeName + " && git pull");
if (NOT_FOUND_GIT.equals(cmdResult)) {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.theme.no-git"));
}
@ -251,11 +251,12 @@ public class ThemeController extends BaseController {
*
*
* @param model model
*
* @return admin/admin_theme-editor
*/
@GetMapping(value = "/editor")
public String editor(Model model) {
List<String> tpls = HaloUtils.getTplName(BaseController.THEME);
final List<String> tpls = HaloUtils.getTplName(BaseController.THEME);
model.addAttribute("tpls", tpls);
return "admin/admin_theme-editor";
}
@ -264,6 +265,7 @@ public class ThemeController extends BaseController {
*
*
* @param tplName
*
* @return
*/
@GetMapping(value = "/getTpl", produces = "text/text;charset=UTF-8")
@ -272,10 +274,14 @@ public class ThemeController extends BaseController {
String tplContent = "";
try {
//获取项目根路径
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
final File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
//获取主题路径
File themesPath = new File(basePath.getAbsolutePath(), new StringBuffer("templates/themes/").append(BaseController.THEME).append("/").append(tplName).toString());
FileReader fileReader = new FileReader(themesPath);
final StrBuilder themePath = new StrBuilder("templates/themes/");
themePath.append(BaseController.THEME);
themePath.append("/");
themePath.append(tplName);
final File themesPath = new File(basePath.getAbsolutePath(), themePath.toString());
final FileReader fileReader = new FileReader(themesPath);
tplContent = fileReader.readString();
} catch (Exception e) {
log.error("Get template file error: {}", e.getMessage());
@ -288,6 +294,7 @@ public class ThemeController extends BaseController {
*
* @param tplName
* @param tplContent
*
* @return JsonResult
*/
@PostMapping(value = "/editor/save")
@ -299,10 +306,14 @@ public class ThemeController extends BaseController {
}
try {
//获取项目根路径
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
final File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
//获取主题路径
File tplPath = new File(basePath.getAbsolutePath(), new StringBuffer("templates/themes/").append(BaseController.THEME).append("/").append(tplName).toString());
FileWriter fileWriter = new FileWriter(tplPath);
final StrBuilder themePath = new StrBuilder("templates/themes/");
themePath.append(BaseController.THEME);
themePath.append("/");
themePath.append(tplName);
final File tplPath = new File(basePath.getAbsolutePath(), themePath.toString());
final FileWriter fileWriter = new FileWriter(tplPath);
fileWriter.write(tplContent);
} catch (Exception e) {
log.error("Template save failed: {}", e.getMessage());

View File

@ -66,7 +66,7 @@ public class UserController {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), error.getDefaultMessage());
}
}
userService.saveByUser(user);
userService.save(user);
configuration.setSharedVariable("user", userService.findUser());
session.removeAttribute(HaloConst.USER_SESSION_KEY);
} catch (Exception e) {
@ -92,10 +92,10 @@ public class UserController {
@ModelAttribute("userId") Long userId,
HttpSession session) {
try {
User user = userService.findByUserIdAndUserPass(userId, SecureUtil.md5(beforePass));
final User user = userService.findByUserIdAndUserPass(userId, SecureUtil.md5(beforePass));
if (null != user) {
user.setUserPass(SecureUtil.md5(newPass));
userService.saveByUser(user);
userService.save(user);
session.removeAttribute(HaloConst.USER_SESSION_KEY);
} else {
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.user.old-password-error"));

View File

@ -5,6 +5,7 @@ import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.enums.ResponseStatusEnum;
import cc.ryanc.halo.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -19,6 +20,7 @@ import java.util.List;
* @author : RYAN0UP
* @date : 2018/6/6
*/
@CrossOrigin
@RestController
@RequestMapping(value = "/api/archives")
public class ApiArchivesController {
@ -29,11 +31,50 @@ public class ApiArchivesController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": [
* {
* "year": "",
* "month": "",
* "count": "",
* "posts": [
* {
* "postId": "",
* "user": {},
* "postTitle": "",
* "postType": "",
* "postContentMd": "",
* "postContent": "",
* "postUrl": "",
* "postSummary": "",
* "categories": [],
* "tags": [],
* "comments": [],
* "postThumbnail": "",
* "postDate": "",
* "postUpdate": "",
* "postStatus": 0,
* "postViews": 0,
* "allowComment": 1,
* "customTpl": ""
* }
* ]
* }
* ]
* }
* </pre>
* </p>
*
* @return JsonResult
*/
@GetMapping(value = "/year")
public JsonResult archivesYear() {
List<Archive> archives = postService.findPostGroupByYear();
final List<Archive> archives = postService.findPostGroupByYear();
if (null != archives && archives.size() > 0) {
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), archives);
} else {
@ -44,15 +85,73 @@ public class ApiArchivesController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": [
* {
* "year": "",
* "month": "",
* "count": "",
* "posts": [
* {
* "postId": "",
* "user": {},
* "postTitle": "",
* "postType": "",
* "postContentMd": "",
* "postContent": "",
* "postUrl": "",
* "postSummary": "",
* "categories": [],
* "tags": [],
* "comments": [],
* "postThumbnail": "",
* "postDate": "",
* "postUpdate": "",
* "postStatus": 0,
* "postViews": 0,
* "allowComment": 1,
* "customTpl": ""
* }
* ]
* }
* ]
* }
* </pre>
* </p>
*
* @return JsonResult
*/
@GetMapping(value = "/year/month")
public JsonResult archivesYearAndMonth() {
List<Archive> archives = postService.findPostGroupByYearAndMonth();
final List<Archive> archives = postService.findPostGroupByYearAndMonth();
if (null != archives && archives.size() > 0) {
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), archives);
} else {
return new JsonResult(ResponseStatusEnum.EMPTY.getCode(), ResponseStatusEnum.EMPTY.getMsg());
}
}
/**
* @Author Aquan
* @Description
* @Date 2019.1.4 11:06
* @Param
* @return JsonResult
**/
@GetMapping(value = "/all")
public JsonResult archivesAllPost() {
final List<Archive> archive = postService.findAllPost();
if (null != archive && archive.size() > 0) {
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), archive);
} else {
return new JsonResult(ResponseStatusEnum.EMPTY.getCode(), ResponseStatusEnum.EMPTY.getMsg());
}
}
}

View File

@ -5,10 +5,7 @@ import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.enums.ResponseStatusEnum;
import cc.ryanc.halo.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ -20,6 +17,7 @@ import java.util.List;
* @author : RYAN0UP
* @date : 2018/6/6
*/
@CrossOrigin
@RestController
@RequestMapping(value = "/api/categories")
public class ApiCategoryController {
@ -30,11 +28,29 @@ public class ApiCategoryController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": [
* {
* "cateId": "",
* "cateName": "",
* "cateUrl": "",
* "cateDesc": ""
* }
* ]
* }
* </pre>
* </p>
*
* @return JsonResult
*/
@GetMapping
public JsonResult categories() {
List<Category> categories = categoryService.findAllCategories();
List<Category> categories = categoryService.findAll();
if (null != categories && categories.size() > 0) {
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), categories);
} else {
@ -45,12 +61,28 @@ public class ApiCategoryController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": {
* "cateId": "",
* "cateName": "",
* "cateUrl": "",
* "cateDesc": ""
* }
* }
* </pre>
* </p>
*
* @param cateUrl
* @return JsonResult
*/
@GetMapping(value = "/{cateUrl}")
public JsonResult categories(@PathVariable("cateUrl") String cateUrl) {
Category category = categoryService.findByCateUrl(cateUrl);
final Category category = categoryService.findByCateUrl(cateUrl);
if (null != category) {
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), category);
} else {

View File

@ -2,6 +2,7 @@ package cc.ryanc.halo.web.controller.api;
import cc.ryanc.halo.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
* @author : RYAN0UP
* @date : 2018/6/6
*/
@CrossOrigin
@RestController
@RequestMapping(value = "/api/comments")
public class ApiCommentController {

View File

@ -5,10 +5,7 @@ import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.enums.ResponseStatusEnum;
import cc.ryanc.halo.service.GalleryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@ -21,6 +18,7 @@ import java.util.Optional;
* @author : RYAN0UP
* @date : 2018/6/6
*/
@CrossOrigin
@RestController
@RequestMapping(value = "/api/galleries")
public class ApiGalleryController {
@ -31,11 +29,32 @@ public class ApiGalleryController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": [
* {
* "galleryId": ,
* "galleryName": "",
* "galleryDesc": "",
* "galleryDate": "",
* "galleryLocation": "",
* "galleryThumbnailUrl": "",
* "galleryUrl": ""
* }
* ]
* }
* </pre>
* </p>
*
* @return JsonResult
*/
@GetMapping
public JsonResult galleries() {
List<Gallery> galleries = galleryService.findAllGalleries();
final List<Gallery> galleries = galleryService.findAll();
if (null != galleries && galleries.size() > 0) {
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), galleries);
} else {
@ -46,12 +65,33 @@ public class ApiGalleryController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": [
* {
* "galleryId": ,
* "galleryName": "",
* "galleryDesc": "",
* "galleryDate": "",
* "galleryLocation": "",
* "galleryThumbnailUrl": "",
* "galleryUrl": ""
* }
* ]
* }
* </pre>
* </p>
*
* @param id id
* @return JsonResult
*/
@GetMapping(value = "/{id}")
public JsonResult galleries(@PathVariable("id") Long id) {
Optional<Gallery> gallery = galleryService.findByGalleryId(id);
final Optional<Gallery> gallery = galleryService.findByGalleryId(id);
if (gallery.isPresent()) {
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), gallery.get());
} else {

View File

@ -5,6 +5,7 @@ import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.enums.ResponseStatusEnum;
import cc.ryanc.halo.service.LinkService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -19,6 +20,7 @@ import java.util.List;
* @author : RYAN0UP
* @date : 2018/6/6
*/
@CrossOrigin
@RestController
@RequestMapping(value = "/api/links")
public class ApiLinkController {
@ -29,11 +31,30 @@ public class ApiLinkController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": [
* {
* "linkId": ,
* "linkName": "",
* "linkUrl": "",
* "linkPic": "",
* "linkDesc": ""
* }
* ]
* }
* </pre>
* </p>
*
* @return JsonResult
*/
@GetMapping
public JsonResult links() {
List<Link> links = linkService.findAllLinks();
final List<Link> links = linkService.findAll();
if (null != links && links.size() > 0) {
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), links);
} else {

View File

@ -5,6 +5,7 @@ import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.enums.ResponseStatusEnum;
import cc.ryanc.halo.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -19,6 +20,7 @@ import java.util.List;
* @author : RYAN0UP
* @date : 2018/6/6
*/
@CrossOrigin
@RestController
@RequestMapping(value = "/api/menus")
public class ApiMenuController {
@ -29,11 +31,31 @@ public class ApiMenuController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": [
* {
* "menuId": ,
* "menuName": "",
* "menuUrl": "",
* "menuSort": ,
* "menuIcon": "",
* "menuTarget":
* }
* ]
* }
* </pre>
* </p>
*
* @return JsonResult
*/
@GetMapping
public JsonResult menus() {
List<Menu> menus = menuService.findAllMenus();
final List<Menu> menus = menuService.findAll();
if (null != menus && menus.size() > 0) {
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), menus);
} else {

View File

@ -0,0 +1,279 @@
package cc.ryanc.halo.web.controller.api;
import cc.ryanc.halo.model.domain.Category;
import cc.ryanc.halo.model.domain.Post;
import cc.ryanc.halo.model.domain.User;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.service.CategoryService;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.service.UserService;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.XML;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
/**
* @author : RYAN0UP
* @date : 2018/12/11
*/
@Slf4j
@RestController
@RequestMapping(value = "/apis/metaweblog", produces = "text/xml;charset=UTF-8")
public class ApiMetaWeBlog {
@Autowired
private UserService userService;
@Autowired
private CategoryService categoryService;
@Autowired
private PostService postService;
/**
* @param request request
* @return String
*/
@PostMapping
public String metaWeBlog(HttpServletRequest request) {
String responseContent = "";
String xml;
try {
final ServletInputStream inputStream = request.getInputStream();
xml = IoUtil.read(inputStream, "utf-8");
final JSONObject requestJSONObject = XML.toJSONObject(xml);
final JSONObject methodCall = requestJSONObject.getJSONObject("methodCall");
final String methodName = methodCall.getString("methodName");
log.info("MetaWeblog[methodName={}]", methodName);
final JSONArray params = methodCall.getJSONObject("params").getJSONArray("param");
final String userEmail = params.getJSONObject(1).getJSONObject("value").optString("string");
final String userPwd = params.getJSONObject(2).getJSONObject("value").get("string").toString();
final User user = userService.userLoginByEmail(userEmail, SecureUtil.md5(userPwd));
if (null == user) {
throw new Exception("用户密码错误!");
}
if ("blogger.getUsersBlogs".equals(methodName)) {
log.info("获取用户博客");
responseContent = getUserBlogs();
} else if ("metaWeblog.getCategories".equals(methodName)) {
log.info("获取分类");
responseContent = getCategories();
} else if ("metaWeblog.getRecentPosts".equals(methodName)) {
} else if ("metaWeblog.newPost".equals(methodName)) {
Post post = parsetPost(methodCall);
post.setUser(user);
post = postService.save(post);
final StrBuilder strBuilder = new StrBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse>");
strBuilder.append("<params><param><value><string>");
strBuilder.append(post.getPostId());
strBuilder.append("</string></value></param></params></methodResponse>");
responseContent = strBuilder.toString();
} else if ("metaWeblog.getPost".equals(methodName)) {
final Long postId = Long.parseLong(params.getJSONObject(0).getJSONObject("value").optString("string"));
responseContent = getPost(postId);
} else if ("metaWeblog.editPost".equals(methodName)) {
Post post = parsetPost(methodCall);
final Long postId = Long.parseLong(params.getJSONObject(0).getJSONObject("value").optString("string"));
post.setPostId(postId);
post.setUser(user);
postService.save(post);
final StrBuilder strBuilder = new StrBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse>");
strBuilder.append("<params><param><value><string>");
strBuilder.append(postId);
strBuilder.append("</string></value></param></params></methodResponse>");
responseContent = strBuilder.toString();
} else if ("blogger.deletePost".equals(methodName)) {
final Long postId = Long.parseLong(params.getJSONObject(0).getJSONObject("value").optString("string"));
postService.remove(postId);
final StrBuilder strBuilder = new StrBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse>");
strBuilder.append("<params><param><value><boolean>");
strBuilder.append(true);
strBuilder.append("</boolean></value></param></params></methodResponse>");
responseContent = strBuilder.toString();
}
} catch (final Exception e) {
e.printStackTrace();
}
return responseContent;
}
/**
* @param methodCall
* @return
* @throws Exception
*/
private Post parsetPost(final JSONObject methodCall) throws Exception {
final Post ret = new Post();
final JSONArray params = methodCall.getJSONObject("params").getJSONArray("param");
final JSONObject post = params.getJSONObject(3).getJSONObject("value").getJSONObject("struct");
final JSONArray members = post.getJSONArray("member");
for (int i = 0; i < members.length(); i++) {
final JSONObject member = members.getJSONObject(i);
final String name = member.getString("name");
if("dateCreated".equals(name)){
final String dateString = member.getJSONObject("value").getString("dateTime.iso8601");
Date date = DateUtil.parseDate(dateString);
ret.setPostDate(date);
}else if ("title".equals(name)){
ret.setPostTitle(member.getJSONObject("value").getString("string"));
}else if("description".equals(name)){
final String content = member.getJSONObject("value").optString("string");
ret.setPostContent(content);
ret.setPostContentMd(content);
}else if("categories".equals(name)){
final StrBuilder cateBuilder = new StrBuilder();
final JSONObject data = member.getJSONObject("value").getJSONObject("array").getJSONObject("data");
if(0==data.length()){
throw new Exception("At least one category");
}
}
}
return ret;
}
/**
*
*
* @param postId
* @return xml
*/
private String getPost(Long postId) {
final StrBuilder strBuilder = new StrBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse><params><param><value>");
final String posts = buildPost(postId);
strBuilder.append(posts);
strBuilder.append("</value></param></params></methodResponse>");
return strBuilder.toString();
}
/**
*
*
* @param postId
* @return xml
*/
private String buildPost(final Long postId) {
final StrBuilder strBuilder = new StrBuilder();
final Post post = postService.findByPostId(postId).orElse(new Post());
strBuilder.append("<struct>");
strBuilder.append("<member><name>dateCreated</name>");
strBuilder.append("<value><dateTime.iso8601>");
strBuilder.append(DateUtil.format(post.getPostDate(), "yyyy-MM-dd'T'HH:mm:ssZZ"));
strBuilder.append("</dateTime.iso8601></value></member>");
strBuilder.append("<member><name>description</name>");
strBuilder.append("<value>");
strBuilder.append(post.getPostSummary());
strBuilder.append("</value></member>");
strBuilder.append("<member><name>title</name>");
strBuilder.append("<value>");
strBuilder.append(post.getPostTitle());
strBuilder.append("</value></member>");
strBuilder.append("<member><name>categories</name>");
strBuilder.append("<value><array><data>");
List<Category> categories = post.getCategories();
for (Category category : categories) {
strBuilder.append("<value>").append(category.getCateName()).append("</value>");
}
strBuilder.append("</data></array></value></member></struct>");
return strBuilder.toString();
}
/**
*
*
* @return xml
*/
private String getUserBlogs() {
final StrBuilder strBuilder = new StrBuilder(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse><params><param><value><array><data><value><struct>");
final String blogInfo = buildBlogInfo();
strBuilder.append(blogInfo);
strBuilder.append("</struct></value></data></array></value></param></params></methodResponse>");
return strBuilder.toString();
}
/**
*
*
* @return xml
*/
private String buildBlogInfo() {
final String blogId = HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp());
final String blogTitle = HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_TITLE.getProp());
final StrBuilder strBuilder = new StrBuilder("<member><name>blogid</name><value>");
strBuilder.append(blogId);
strBuilder.append("</value></member>");
strBuilder.append("<member><name>url</name><value>");
strBuilder.append(HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()));
strBuilder.append("</value></member>");
strBuilder.append("<member><name>blogName</name><value>");
strBuilder.append(blogTitle);
strBuilder.append("</value></member>");
return strBuilder.toString();
}
/**
*
*
* @return xml
* @throws Exception Exception
*/
private String getCategories() throws Exception {
final StrBuilder strBuilder = new StrBuilder(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><methodResponse><params><param><value><array><data>");
final String categories = buildCategories();
strBuilder.append(categories);
strBuilder.append("</data></array></value></param></params></methodResponse>");
return strBuilder.toString();
}
/**
*
*
* @return xml
* @throws Exception Exception
*/
private String buildCategories() throws Exception {
final StrBuilder strBuilder = new StrBuilder();
final List<Category> categories = categoryService.findAll();
for (Category category : categories) {
final String cateName = category.getCateName();
final Long cateId = category.getCateId();
strBuilder.append("<value><struct>");
strBuilder.append("<member><name>description</name>").append("<value>").append(cateName).append("</value></member>");
strBuilder.append("<member><name>title</name>").append("<value>").append(cateName).append("</value></member>");
strBuilder.append("<member><name>categoryid</name>").append("<value>").append(cateId).append("</value></member>");
strBuilder.append("<member><name>htmlUrl</name>").append("<value>").append(HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp())).append("/categories/").append(cateName).append("</value></member>");
strBuilder.append("</struct></value>");
}
return strBuilder.toString();
}
}

View File

@ -5,10 +5,7 @@ import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.model.enums.ResponseStatusEnum;
import cc.ryanc.halo.service.OptionsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@ -20,6 +17,7 @@ import java.util.Map;
* @author : RYAN0UP
* @date : 2018/7/19
*/
@CrossOrigin
@RestController
@RequestMapping(value = "/api/options")
public class ApiOptionController {
@ -30,11 +28,36 @@ public class ApiOptionController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": {
* "blog_start": "",
* "blog_locale": "",
* "blog_url": "",
* "api_token": "",
* "api_status": "",
* "blog_title": "",
* "new_comment_notice": "",
* "smtp_email_enable": "",
* "attach_loc": "",
* "theme": "",
* "comment_reply_notice": "",
* "is_install": "",
* "comment_pass_notice": ""
* }
* }
* </pre>
* </p>
*
* @return JsonResult
*/
@GetMapping
public JsonResult options() {
Map<String, String> options = optionsService.findAllOptions();
final Map<String, String> options = optionsService.findAllOptions();
//去掉隐私元素
options.remove(BlogPropertiesEnum.MAIL_SMTP_HOST.getProp());
options.remove(BlogPropertiesEnum.MAIL_FROM_NAME.getProp());
@ -47,12 +70,24 @@ public class ApiOptionController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": ""
* }
* </pre>
* </p>
*
* @param optionName
*
* @return JsonResult
*/
@GetMapping(value = "/{optionName}")
public JsonResult option(@PathVariable(value = "optionName") String optionName) {
String optionValue = optionsService.findOneOption(optionName);
final String optionValue = optionsService.findOneOption(optionName);
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), optionValue);
}
}

View File

@ -6,10 +6,7 @@ import cc.ryanc.halo.model.enums.PostTypeEnum;
import cc.ryanc.halo.model.enums.ResponseStatusEnum;
import cc.ryanc.halo.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
/**
* <pre>
@ -19,6 +16,7 @@ import org.springframework.web.bind.annotation.RestController;
* @author : RYAN0UP
* @date : 2018/6/6
*/
@CrossOrigin
@RestController
@RequestMapping(value = "/api/pages")
public class ApiPageController {
@ -29,13 +27,45 @@ public class ApiPageController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": {
* "postId": ,
* "user": {},
* "postTitle": "",
* "postType": "",
* "postContentMd": "",
* "postContent": "",
* "postUrl": "",
* "postSummary": ,
* "categories": [],
* "tags": [],
* "comments": [],
* "postThumbnail": "",
* "postDate": "",
* "postUpdate": "",
* "postStatus": 0,
* "postViews": 0,
* "allowComment": 1,
* "customTpl": ""
* }
* }
* </pre>
* </p>
*
* @param postId postId
*
* @return JsonResult
*/
@GetMapping(value = "/{postId}")
public JsonResult pages(@PathVariable(value = "postId") Long postId) {
Post post = postService.findByPostId(postId, PostTypeEnum.POST_TYPE_PAGE.getDesc());
final Post post = postService.findByPostId(postId, PostTypeEnum.POST_TYPE_PAGE.getDesc());
if (null != post) {
postService.cacheViews(post.getPostId());
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), post);
} else {
return new JsonResult(ResponseStatusEnum.NOTFOUND.getCode(), ResponseStatusEnum.NOTFOUND.getMsg());

View File

@ -14,12 +14,7 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import org.springframework.web.bind.annotation.*;
/**
* <pre>
@ -29,6 +24,7 @@ import java.util.List;
* @author : RYAN0UP
* @date : 2018/6/6
*/
@CrossOrigin
@RestController
@RequestMapping(value = "/api/posts")
public class ApiPostController {
@ -39,44 +35,126 @@ public class ApiPostController {
/**
*
*
* <p>
* result api
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": {
* "content": [
* {
* "postId": ,
* "user": {},
* "postTitle": "",
* "postType": "",
* "postContentMd": "",
* "postContent": "",
* "postUrl": "",
* "postSummary": "",
* "categories": [],
* "tags": [],
* "comments": [],
* "postThumbnail": "",
* "postDate": "",
* "postUpdate": "",
* "postStatus": 0,
* "postViews": 0,
* "allowComment": 1,
* "customTpl": ""
* }
* ],
* "pageable": {
* "sort": {
* "sorted": true,
* "unsorted": false,
* "empty": false
* },
* "offset": 0,
* "pageSize": 10,
* "pageNumber": 0,
* "unpaged": false,
* "paged": true
* },
* "last": true,
* "totalElements": 1,
* "totalPages": 1,
* "size": 10,
* "number": 0,
* "first": true,
* "numberOfElements": 1,
* "sort": {
* "sorted": true,
* "unsorted": false,
* "empty": false
* },
* "empty": false
* }
* }
* </pre>
* </p>
*
* @param page
*
* @return JsonResult
*/
@GetMapping(value = "/page/{page}")
public JsonResult posts(@PathVariable(value = "page") Integer page) {
Sort sort = new Sort(Sort.Direction.DESC, "postDate");
Integer size = 10;
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
int size = 10;
if (StrUtil.isNotBlank(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()))) {
size = Integer.parseInt(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()));
}
Pageable pageable = PageRequest.of(page - 1, size, sort);
Page<Post> posts = postService.findPostByStatus(PostStatusEnum.PUBLISHED.getCode(), PostTypeEnum.POST_TYPE_POST.getDesc(), pageable);
final Pageable pageable = PageRequest.of(page - 1, size, sort);
final Page<Post> posts = postService.findPostByStatus(PostStatusEnum.PUBLISHED.getCode(), PostTypeEnum.POST_TYPE_POST.getDesc(), pageable);
if (null == posts) {
return new JsonResult(ResponseStatusEnum.EMPTY.getCode(), ResponseStatusEnum.EMPTY.getMsg());
}
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), posts);
}
@GetMapping(value = "/hot")
public JsonResult hotPosts() {
List<Post> posts = postService.hotPosts();
if (null != posts && posts.size() > 0) {
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), posts);
} else {
return new JsonResult(ResponseStatusEnum.EMPTY.getCode(), ResponseStatusEnum.EMPTY.getMsg());
}
}
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": {
* "postId": ,
* "user": {},
* "postTitle": "",
* "postType": "",
* "postContentMd": "",
* "postContent": "",
* "postUrl": "",
* "postSummary": "",
* "categories": [],
* "tags": [],
* "comments": [],
* "postThumbnail": "",
* "postDate": "",
* "postUpdate": "",
* "postStatus": 0,
* "postViews": 0,
* "allowComment": 1,
* "customTpl": ""
* }
* }
* </pre>
* </p>
*
* @param postId
*
* @return JsonResult
*/
@GetMapping(value = "/{postId}")
public JsonResult posts(@PathVariable(value = "postId") Long postId) {
Post post = postService.findByPostId(postId, PostTypeEnum.POST_TYPE_POST.getDesc());
final Post post = postService.findByPostId(postId, PostTypeEnum.POST_TYPE_POST.getDesc());
if (null != post) {
postService.cacheViews(post.getPostId());
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), post);
} else {
return new JsonResult(ResponseStatusEnum.NOTFOUND.getCode(), ResponseStatusEnum.NOTFOUND.getMsg());

View File

@ -5,10 +5,7 @@ import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.enums.ResponseStatusEnum;
import cc.ryanc.halo.service.TagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ -20,6 +17,7 @@ import java.util.List;
* @author : RYAN0UP
* @date : 2018/6/6
*/
@CrossOrigin
@RestController
@RequestMapping(value = "/api/tags")
public class ApiTagController {
@ -30,11 +28,28 @@ public class ApiTagController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": [
* {
* "tagId": ,
* "tagName": "",
* "tagUrl": ""
* }
* ]
* }
* </pre>
* </p>
*
* @return JsonResult
*/
@GetMapping
public JsonResult tags() {
List<Tag> tags = tagService.findAllTags();
final List<Tag> tags = tagService.findAll();
if (null != tags && tags.size() > 0) {
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), tags);
} else {
@ -45,12 +60,27 @@ public class ApiTagController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": {
* "tagId": ,
* "tagName": "",
* "tagUrl": ""
* }
* }
* </pre>
* </p>
*
* @param tagUrl tagUrl
* @return JsonResult
*/
@GetMapping(value = "/{tagUrl}")
public JsonResult tags(@PathVariable("tagUrl") String tagUrl) {
Tag tag = tagService.findByTagUrl(tagUrl);
final Tag tag = tagService.findByTagUrl(tagUrl);
if (null != tag) {
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), tag);
} else {

View File

@ -5,6 +5,7 @@ import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.enums.ResponseStatusEnum;
import cc.ryanc.halo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -17,6 +18,7 @@ import org.springframework.web.bind.annotation.RestController;
* @author : RYAN0UP
* @date : 2018/6/6
*/
@CrossOrigin
@RestController
@RequestMapping(value = "/api/user")
public class ApiUserController {
@ -27,11 +29,28 @@ public class ApiUserController {
/**
*
*
* <p>
* result json:
* <pre>
* {
* "code": 200,
* "msg": "OK",
* "result": {
* "userId": ,
* "userDisplayName": "",
* "userEmail": "",
* "userAvatar": "",
* "userDesc": ""
* }
* }
* </pre>
* </p>
*
* @return JsonResult
*/
@GetMapping
public JsonResult user() {
User user = userService.findUser();
final User user = userService.findUser();
return new JsonResult(ResponseStatusEnum.SUCCESS.getCode(), ResponseStatusEnum.SUCCESS.getMsg(), user);
}
}

View File

@ -24,7 +24,7 @@ public abstract class BaseController {
* @return
*/
public String render(String pageName) {
StrBuilder themeStr = new StrBuilder("themes/");
final StrBuilder themeStr = new StrBuilder("themes/");
themeStr.append(THEME);
themeStr.append("/");
return themeStr.append(pageName).toString();

View File

@ -30,7 +30,7 @@ public class CommonController implements ErrorController {
*/
@GetMapping(value = ERROR_PATH)
public String handleError(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
final Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if (statusCode.equals(CommonParamsEnum.NOT_FOUND.getValue())) {
return "redirect:/404";
} else {

View File

@ -2,15 +2,14 @@ package cc.ryanc.halo.web.controller.core;
import cc.ryanc.halo.model.domain.*;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.model.dto.LogsRecord;
import cc.ryanc.halo.model.enums.AllowCommentEnum;
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.model.enums.TrueFalseEnum;
import cc.ryanc.halo.model.enums.*;
import cc.ryanc.halo.service.*;
import cc.ryanc.halo.utils.MarkdownUtils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.servlet.ServletUtil;
import freemarker.template.Configuration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -20,7 +19,9 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <pre>
@ -63,6 +64,7 @@ public class InstallController {
*
*
* @param model model
*
* @return
*/
@GetMapping
@ -90,24 +92,25 @@ public class InstallController {
* @param userEmail
* @param userPwd
* @param request request
* @return truefalse
*
* @return JsonResult
*/
@PostMapping(value = "/do")
@ResponseBody
public boolean doInstall(@RequestParam("blogLocale") String blogLocale,
@RequestParam("blogTitle") String blogTitle,
@RequestParam("blogUrl") String blogUrl,
@RequestParam("userName") String userName,
@RequestParam("userDisplayName") String userDisplayName,
@RequestParam("userEmail") String userEmail,
@RequestParam("userPwd") String userPwd,
HttpServletRequest request) {
public JsonResult doInstall(@RequestParam("blogLocale") String blogLocale,
@RequestParam("blogTitle") String blogTitle,
@RequestParam("blogUrl") String blogUrl,
@RequestParam("userName") String userName,
@RequestParam("userDisplayName") String userDisplayName,
@RequestParam("userEmail") String userEmail,
@RequestParam("userPwd") String userPwd,
HttpServletRequest request) {
try {
if (StrUtil.equals(TrueFalseEnum.TRUE.getDesc(), HaloConst.OPTIONS.get(BlogPropertiesEnum.IS_INSTALL.getProp()))) {
return false;
return new JsonResult(ResultCodeEnum.FAIL.getCode(), "该博客已初始化,不能再次安装!");
}
//创建新的用户
User user = new User();
final User user = new User();
user.setUserName(userName);
if (StrUtil.isBlank(userDisplayName)) {
userDisplayName = userName;
@ -115,102 +118,84 @@ public class InstallController {
user.setUserDisplayName(userDisplayName);
user.setUserEmail(userEmail);
user.setUserPass(SecureUtil.md5(userPwd));
userService.saveByUser(user);
userService.save(user);
//默认分类
Category category = new Category();
final Category category = new Category();
category.setCateName("未分类");
category.setCateUrl("default");
category.setCateDesc("未分类");
categoryService.saveByCategory(category);
categoryService.save(category);
//第一篇文章
Post post = new Post();
List<Category> categories = new ArrayList<>();
final Post post = new Post();
final List<Category> categories = new ArrayList<>();
categories.add(category);
post.setPostTitle("Hello Halo!");
post.setPostContentMd("# Hello Halo!\n" +
"欢迎使用Halo进行创作删除这篇文章后赶紧开始吧。");
post.setPostContent("<h1 id=\"h1-hello-halo-\"><a name=\"Hello Halo!\" class=\"reference-link\"></a><span class=\"header-link octicon octicon-link\"></span>Hello Halo!</h1><p>欢迎使用Halo进行创作删除这篇文章后赶紧开始吧。</p>\n");
post.setPostContent(MarkdownUtils.renderMarkdown(post.getPostContentMd()));
post.setPostSummary("欢迎使用Halo进行创作删除这篇文章后赶紧开始吧。");
post.setPostStatus(0);
post.setPostDate(DateUtil.date());
post.setPostUrl("hello-halo");
post.setUser(user);
post.setCategories(categories);
post.setAllowComment(AllowCommentEnum.ALLOW.getCode());
postService.saveByPost(post);
postService.save(post);
//第一个评论
Comment comment = new Comment();
final Comment comment = new Comment();
comment.setPost(post);
comment.setCommentAuthor("ruibaby");
comment.setCommentAuthorEmail("i@ryanc.cc");
comment.setCommentAuthorUrl("https://ryanc.cc");
comment.setCommentAuthorIp("127.0.0.1");
comment.setCommentAuthorAvatarMd5("7cc7f29278071bd4dce995612d428834");
comment.setCommentDate(DateUtil.date());
comment.setCommentAuthorAvatarMd5(SecureUtil.md5("i@ryanc.cc"));
comment.setCommentContent("欢迎,欢迎!");
comment.setCommentStatus(0);
comment.setCommentAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36");
comment.setIsAdmin(0);
commentService.saveByComment(comment);
commentService.save(comment);
optionsService.saveOption(BlogPropertiesEnum.IS_INSTALL.getProp(), TrueFalseEnum.TRUE.getDesc());
//语言设置
optionsService.saveOption(BlogPropertiesEnum.BLOG_LOCALE.getProp(),blogLocale);
//保存博客标题和博客地址设置
optionsService.saveOption(BlogPropertiesEnum.BLOG_TITLE.getProp(), blogTitle);
optionsService.saveOption(BlogPropertiesEnum.BLOG_URL.getProp(), blogUrl);
//设置默认主题
optionsService.saveOption(BlogPropertiesEnum.THEME.getProp(), "anatole");
//建立网站时间
optionsService.saveOption(BlogPropertiesEnum.BLOG_START.getProp(), DateUtil.format(DateUtil.date(),"yyyy-MM-dd"));
//默认不配置邮件系统
optionsService.saveOption(BlogPropertiesEnum.SMTP_EMAIL_ENABLE.getProp(), TrueFalseEnum.FALSE.getDesc());
//新评论,审核通过,回复,默认不通知
optionsService.saveOption(BlogPropertiesEnum.NEW_COMMENT_NOTICE.getProp(), TrueFalseEnum.FALSE.getDesc());
optionsService.saveOption(BlogPropertiesEnum.COMMENT_PASS_NOTICE.getProp(), TrueFalseEnum.FALSE.getDesc());
optionsService.saveOption(BlogPropertiesEnum.COMMENT_REPLY_NOTICE.getProp(), TrueFalseEnum.FALSE.getDesc());
final Map<String, String> options = new HashMap<>();
options.put(BlogPropertiesEnum.IS_INSTALL.getProp(), TrueFalseEnum.TRUE.getDesc());
options.put(BlogPropertiesEnum.BLOG_LOCALE.getProp(), blogLocale);
options.put(BlogPropertiesEnum.BLOG_TITLE.getProp(), blogTitle);
options.put(BlogPropertiesEnum.BLOG_URL.getProp(), blogUrl);
options.put(BlogPropertiesEnum.THEME.getProp(), "anatole");
options.put(BlogPropertiesEnum.BLOG_START.getProp(), DateUtil.format(DateUtil.date(), "yyyy-MM-dd"));
options.put(BlogPropertiesEnum.SMTP_EMAIL_ENABLE.getProp(), TrueFalseEnum.FALSE.getDesc());
options.put(BlogPropertiesEnum.NEW_COMMENT_NOTICE.getProp(), TrueFalseEnum.FALSE.getDesc());
options.put(BlogPropertiesEnum.COMMENT_PASS_NOTICE.getProp(), TrueFalseEnum.FALSE.getDesc());
options.put(BlogPropertiesEnum.COMMENT_REPLY_NOTICE.getProp(), TrueFalseEnum.FALSE.getDesc());
options.put(BlogPropertiesEnum.ATTACH_LOC.getProp(), AttachLocationEnum.SERVER.getDesc());
optionsService.saveOptions(options);
//更新日志
logsService.saveByLogs(
new Logs(
LogsRecord.INSTALL,
"安装成功欢迎使用Halo。",
ServletUtil.getClientIP(request),
DateUtil.date()
)
);
logsService.save(LogsRecord.INSTALL, "安装成功欢迎使用Halo。", request);
Menu menuIndex = new Menu();
final Menu menuIndex = new Menu();
menuIndex.setMenuName("首页");
menuIndex.setMenuUrl("/");
menuIndex.setMenuSort(1);
menuIndex.setMenuIcon("");
menuService.saveByMenu(menuIndex);
menuIndex.setMenuIcon(" ");
menuService.save(menuIndex);
Menu menuArchive = new Menu();
final Menu menuArchive = new Menu();
menuArchive.setMenuName("归档");
menuArchive.setMenuUrl("/archives");
menuArchive.setMenuSort(2);
menuArchive.setMenuIcon("");
menuService.saveByMenu(menuArchive);
menuArchive.setMenuIcon(" ");
menuService.save(menuArchive);
HaloConst.OPTIONS.clear();
HaloConst.OPTIONS = optionsService.findAllOptions();
configuration.setSharedVariable("options", optionsService.findAllOptions());
configuration.setSharedVariable("options", HaloConst.OPTIONS);
configuration.setSharedVariable("user", userService.findUser());
} catch (Exception e) {
log.error(e.getMessage());
return false;
return new JsonResult(ResultCodeEnum.FAIL.getCode(), e.getMessage());
}
return true;
return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), "安装成功!");
}
}

View File

@ -13,19 +13,22 @@ import cc.ryanc.halo.web.controller.core.BaseController;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.servlet.ServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -43,6 +46,8 @@ import java.util.List;
@RequestMapping(value = "/archives")
public class FrontArchiveController extends BaseController {
private static final String POSTS_CACHE_NAME = "posts";
@Autowired
private PostService postService;
@ -72,13 +77,13 @@ public class FrontArchiveController extends BaseController {
@PathVariable(value = "page") Integer page) {
//所有文章数据分页material主题适用
Sort sort = new Sort(Sort.Direction.DESC, "postDate");
Pageable pageable = PageRequest.of(page - 1, 5, sort);
Page<Post> posts = postService.findPostByStatus(PostStatusEnum.PUBLISHED.getCode(), PostTypeEnum.POST_TYPE_POST.getDesc(), pageable);
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
final Pageable pageable = PageRequest.of(page - 1, 5, sort);
final Page<Post> posts = postService.findPostByStatus(PostStatusEnum.PUBLISHED.getCode(), PostTypeEnum.POST_TYPE_POST.getDesc(), pageable);
if (null == posts) {
return this.renderNotFound();
}
model.addAttribute("is_archives",true);
model.addAttribute("is_archives", true);
model.addAttribute("posts", posts);
return this.render("archives");
}
@ -95,11 +100,11 @@ public class FrontArchiveController extends BaseController {
public String archives(Model model,
@PathVariable(value = "year") String year,
@PathVariable(value = "month") String month) {
Page<Post> posts = postService.findPostByYearAndMonth(year, month, null);
final Page<Post> posts = postService.findPostByYearAndMonth(year, month, null);
if (null == posts) {
return this.renderNotFound();
}
model.addAttribute("is_archives",true);
model.addAttribute("is_archives", true);
model.addAttribute("posts", posts);
return this.render("archives");
}
@ -113,24 +118,26 @@ public class FrontArchiveController extends BaseController {
*/
@GetMapping(value = "{postUrl}")
public String getPost(@PathVariable String postUrl,
@RequestParam(value = "cp",defaultValue = "1") Integer cp,
@RequestParam(value = "cp", defaultValue = "1") Integer cp,
HttpServletRequest request,
Model model) {
Post post = postService.findByPostUrl(postUrl, PostTypeEnum.POST_TYPE_POST.getDesc());
final Post post = postService.findByPostUrl(postUrl, PostTypeEnum.POST_TYPE_POST.getDesc());
if (null == post || !post.getPostStatus().equals(PostStatusEnum.PUBLISHED.getCode())) {
return this.renderNotFound();
}
//获得当前文章的发布日期
Date postDate = post.getPostDate();
//查询当前文章日期之前的所有文章
List<Post> beforePosts = postService.findByPostDateBefore(postDate);
//查询当前文章日期之后的所有文章
List<Post> afterPosts = postService.findByPostDateAfter(postDate);
if (null != beforePosts && beforePosts.size() > 0) {
model.addAttribute("beforePost", beforePosts.get(beforePosts.size() - 1));
final Date postDate = post.getPostDate();
final Post prePost = postService.getPrePost(postDate);
final Post nextPost = postService.getNextPost(postDate);
if (null != prePost) {
//兼容老版本主题
model.addAttribute("beforePost", prePost);
model.addAttribute("prePost", prePost);
}
if (null != afterPosts && afterPosts.size() > 0) {
model.addAttribute("afterPost", afterPosts.get(afterPosts.size() - 1));
if (null != nextPost) {
//兼容老版本主题
model.addAttribute("afterPost", nextPost);
model.addAttribute("nextPost", nextPost);
}
List<Comment> comments = null;
if (StrUtil.equals(HaloConst.OPTIONS.get(BlogPropertiesEnum.NEW_COMMENT_NEED_CHECK.getProp()), TrueFalseEnum.TRUE.getDesc()) || HaloConst.OPTIONS.get(BlogPropertiesEnum.NEW_COMMENT_NEED_CHECK.getProp()) == null) {
@ -139,29 +146,61 @@ public class FrontArchiveController extends BaseController {
comments = commentService.findCommentsByPostAndCommentStatusNot(post, CommentStatusEnum.RECYCLE.getCode());
}
//获取文章的标签用作keywords
List<Tag> tags = post.getTags();
List<String> tagWords = new ArrayList<>();
final List<Tag> tags = post.getTags();
final List<String> tagWords = new ArrayList<>();
if (tags != null) {
for (Tag tag : tags) {
tagWords.add(tag.getTagName());
}
}
//默认显示10条
Integer size = 10;
int size = 10;
//获取每页评论条数
if (StrUtil.isNotBlank(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_COMMENTS.getProp()))) {
size = Integer.parseInt(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_COMMENTS.getProp()));
}
//评论分页
ListPage<Comment> commentsPage = new ListPage<Comment>(CommentUtil.getComments(comments),cp, size);
int[] rainbow = PageUtil.rainbow(cp, commentsPage.getTotalPage(), 3);
model.addAttribute("is_post",true);
model.addAttribute("post", post);
final ListPage<Comment> commentsPage = new ListPage<Comment>(CommentUtil.getComments(comments), cp, size);
final int[] rainbow = PageUtil.rainbow(cp, commentsPage.getTotalPage(), 3);
model.addAttribute("is_post", true);
model.addAttribute("comments", commentsPage);
model.addAttribute("commentsCount", comments.size());
model.addAttribute("rainbow", rainbow);
model.addAttribute("tagWords", CollUtil.join(tagWords, ","));
postService.updatePostView(post);
postService.cacheViews(post.getPostId());
//判断文章是否有加密
if (StrUtil.isNotEmpty(post.getPostPassword())) {
Cookie cookie = ServletUtil.getCookie(request, "halo-post-password-" + post.getPostId());
if (null == cookie) {
post.setPostSummary("该文章为加密文章");
post.setPostContent("<form id=\"postPasswordForm\" method=\"post\" action=\"/archives/verifyPostPassword\"><p>该文章为加密文章,输入正确的密码即可访问。</p><input type=\"hidden\" id=\"postId\" name=\"postId\" value=\"" + post.getPostId() + "\"> <input type=\"password\" id=\"postPassword\" name=\"postPassword\"> <input type=\"submit\" id=\"passwordSubmit\" value=\"提交\"></form>");
}
}
model.addAttribute("post", post);
return this.render("post");
}
/**
*
*
* @param postId postId
* @param postPassword postPassword
* @param response response
* @return String
*/
@PostMapping(value = "/verifyPostPassword")
@CacheEvict(value = POSTS_CACHE_NAME, allEntries = true, beforeInvocation = true)
public String verifyPostPassword(@RequestParam(value = "postId") Long postId,
@RequestParam(value = "postPassword") String postPassword,
HttpServletResponse response) {
final Post post = postService.findByPostId(postId, PostTypeEnum.POST_TYPE_POST.getDesc());
if (null == post) {
return this.renderNotFound();
}
if (SecureUtil.md5(postPassword).equals(post.getPostPassword())) {
ServletUtil.addCookie(response, "halo-post-password-" + post.getPostId(), SecureUtil.md5(postPassword));
}
return "redirect:/archives/" + post.getPostUrl();
}
}

View File

@ -44,11 +44,12 @@ public class FrontCategoryController extends BaseController {
*
*
* @param model model
*
* @return String
*/
@GetMapping
public String categories(Model model) {
List<Category> categories = categoryService.findAllCategories();
final List<Category> categories = categoryService.findAll();
model.addAttribute("categories", categories);
return this.render("categories");
}
@ -58,6 +59,7 @@ public class FrontCategoryController extends BaseController {
*
* @param model model
* @param cateUrl cateUrl
*
* @return string
*/
@GetMapping(value = "{cateUrl}")
@ -72,25 +74,26 @@ public class FrontCategoryController extends BaseController {
* @param model model
* @param cateUrl
* @param page
*
* @return String
*/
@GetMapping("{cateUrl}/page/{page}")
public String categories(Model model,
@PathVariable("cateUrl") String cateUrl,
@PathVariable("page") Integer page) {
Category category = categoryService.findByCateUrl(cateUrl);
final Category category = categoryService.findByCateUrl(cateUrl);
if (null == category) {
return this.renderNotFound();
}
Sort sort = new Sort(Sort.Direction.DESC, "postDate");
Integer size = 10;
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
int size = 10;
if (StrUtil.isNotBlank(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()))) {
size = Integer.parseInt(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()));
}
Pageable pageable = PageRequest.of(page - 1, size, sort);
Page<Post> posts = postService.findPostByCategories(category, pageable);
int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
model.addAttribute("is_categories",true);
final Pageable pageable = PageRequest.of(page - 1, size, sort);
final Page<Post> posts = postService.findPostByCategories(category, pageable);
final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
model.addAttribute("is_categories", true);
model.addAttribute("posts", posts);
model.addAttribute("rainbow", rainbow);
model.addAttribute("category", category);

View File

@ -13,6 +13,7 @@ import cc.ryanc.halo.utils.CommentUtil;
import cc.ryanc.halo.utils.OwoUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.crypto.SecureUtil;
@ -60,45 +61,13 @@ public class FrontCommentController {
@Autowired
private MailService mailService;
/**
*
*
* @param postId postId
* @return List
*/
@GetMapping(value = "/getComment/{postId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public List<Comment> getComment(@PathVariable Long postId) {
Optional<Post> post = postService.findByPostId(postId);
Sort sort = new Sort(Sort.Direction.DESC, "commentDate");
Pageable pageable = PageRequest.of(0, 999, sort);
List<Comment> comments = commentService.findCommentsByPostAndCommentStatus(post.get(), pageable, CommentStatusEnum.PUBLISHED.getCode()).getContent();
return CommentUtil.getComments(comments);
}
/**
*
*
* @param page
* @param post
* @return List
*/
@GetMapping(value = "/loadComment")
@ResponseBody
public List<Comment> loadComment(@RequestParam(value = "page") Integer page,
@RequestParam(value = "post") Post post) {
Sort sort = new Sort(Sort.Direction.DESC, "commentDate");
Pageable pageable = PageRequest.of(page - 1, 10, sort);
List<Comment> comments = commentService.findCommentsByPostAndCommentStatus(post, pageable, CommentStatusEnum.PUBLISHED.getCode()).getContent();
return comments;
}
/**
*
*
* @param comment comment
* @param post post
* @param request request
*
* @return JsonResult
*/
@PostMapping(value = "/newComment")
@ -114,10 +83,9 @@ public class FrontCommentController {
}
try {
Comment lastComment = null;
post = postService.findByPostId(post.getPostId()).get();
post = postService.findByPostId(post.getPostId()).orElse(new Post());
comment.setCommentAuthorEmail(HtmlUtil.escape(comment.getCommentAuthorEmail()).toLowerCase());
comment.setPost(post);
comment.setCommentDate(DateUtil.date());
comment.setCommentAuthorIp(ServletUtil.getClientIP(request));
comment.setIsAdmin(0);
comment.setCommentAuthor(HtmlUtil.escape(comment.getCommentAuthor()));
@ -125,17 +93,22 @@ public class FrontCommentController {
comment.setCommentAuthorAvatarMd5(SecureUtil.md5(comment.getCommentAuthorEmail()));
}
if (comment.getCommentParent() > 0) {
lastComment = commentService.findCommentById(comment.getCommentParent()).get();
String lastContent = "<a href='#comment-id-" + lastComment.getCommentId() + "'>@" + lastComment.getCommentAuthor() + "</a> ";
comment.setCommentContent(lastContent + OwoUtil.markToImg(HtmlUtil.escape(comment.getCommentContent()).replace("&lt;br/&gt;", "<br/>")));
lastComment = commentService.findCommentById(comment.getCommentParent()).orElse(new Comment());
final StrBuilder buildContent = new StrBuilder("<a href='#comment-id-");
buildContent.append(lastComment.getCommentId());
buildContent.append("'>@");
buildContent.append(lastComment.getCommentAuthor());
buildContent.append("</a> ");
buildContent.append(OwoUtil.markToImg(HtmlUtil.escape(comment.getCommentContent()).replace("&lt;br/&gt;", "<br/>")));
comment.setCommentContent(buildContent.toString());
} else {
//将评论内容的字符专为安全字符
comment.setCommentContent(OwoUtil.markToImg(HtmlUtil.escape(comment.getCommentContent()).replace("&lt;br/&gt;", "<br/>")));
}
if (StrUtil.isNotEmpty(comment.getCommentAuthorUrl())) {
comment.setCommentAuthorUrl(URLUtil.formatUrl(comment.getCommentAuthorUrl()));
comment.setCommentAuthorUrl(URLUtil.normalize(comment.getCommentAuthorUrl()));
}
commentService.saveByComment(comment);
commentService.save(comment);
if (comment.getCommentParent() > 0) {
new EmailToParent(comment, lastComment, post).start();
new EmailToAdmin(comment, post).start();
@ -169,14 +142,19 @@ public class FrontCommentController {
if (StrUtil.equals(HaloConst.OPTIONS.get(BlogPropertiesEnum.SMTP_EMAIL_ENABLE.getProp()), TrueFalseEnum.TRUE.getDesc()) && StrUtil.equals(HaloConst.OPTIONS.get(BlogPropertiesEnum.NEW_COMMENT_NOTICE.getProp()), TrueFalseEnum.TRUE.getDesc())) {
try {
//发送邮件到博主
Map<String, Object> map = new HashMap<>(5);
final Map<String, Object> map = new HashMap<>(5);
final StrBuilder pageUrl = new StrBuilder(HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()));
if (StrUtil.equals(post.getPostType(), PostTypeEnum.POST_TYPE_POST.getDesc())) {
pageUrl.append("/archives/");
} else {
pageUrl.append("/p/");
}
pageUrl.append(post.getPostUrl());
pageUrl.append("#comment-id-");
pageUrl.append(comment.getCommentId());
map.put("pageUrl", pageUrl.toString());
map.put("author", userService.findUser().getUserDisplayName());
map.put("pageName", post.getPostTitle());
if (StrUtil.equals(post.getPostType(), PostTypeEnum.POST_TYPE_POST.getDesc())) {
map.put("pageUrl", HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
} else {
map.put("pageUrl", HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/p/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
}
map.put("visitor", comment.getCommentAuthor());
map.put("commentContent", comment.getCommentContent());
mailService.sendTemplateMail(userService.findUser().getUserEmail(), "有新的评论", map, "common/mail_template/mail_admin.ftl");
@ -206,15 +184,21 @@ public class FrontCommentController {
//发送通知给对方
if (StrUtil.equals(HaloConst.OPTIONS.get(BlogPropertiesEnum.SMTP_EMAIL_ENABLE.getProp()), TrueFalseEnum.TRUE.getDesc()) && StrUtil.equals(HaloConst.OPTIONS.get(BlogPropertiesEnum.NEW_COMMENT_NOTICE.getProp()), TrueFalseEnum.TRUE.getDesc())) {
if (Validator.isEmail(lastComment.getCommentAuthorEmail())) {
Map<String, Object> map = new HashMap<>(8);
final Map<String, Object> map = new HashMap<>(8);
final StrBuilder pageUrl = new StrBuilder(HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()));
if (StrUtil.equals(post.getPostType(), PostTypeEnum.POST_TYPE_POST.getDesc())) {
pageUrl.append("/archives/");
} else {
pageUrl.append("/p/");
}
pageUrl.append(post.getPostUrl());
pageUrl.append("#comment-id-");
pageUrl.append(comment.getCommentId());
map.put("pageUrl", pageUrl.toString());
map.put("blogTitle", HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_TITLE.getProp()));
map.put("commentAuthor", lastComment.getCommentAuthor());
map.put("pageName", lastComment.getPost().getPostTitle());
if (StrUtil.equals(post.getPostType(), PostTypeEnum.POST_TYPE_POST.getDesc())) {
map.put("pageUrl", HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
} else {
map.put("pageUrl", HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/p/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
}
map.put("commentContent", lastComment.getCommentContent());
map.put("replyAuthor", comment.getCommentAuthor());
map.put("replyContent", comment.getCommentContent());

View File

@ -15,9 +15,9 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* <pre>
@ -44,7 +44,6 @@ public class FrontIndexController extends BaseController {
*/
@GetMapping
public String index(Model model) {
//调用方法渲染首页
return this.index(model, 1);
}
@ -59,60 +58,22 @@ public class FrontIndexController extends BaseController {
@GetMapping(value = "page/{page}")
public String index(Model model,
@PathVariable(value = "page") Integer page) {
Sort sort = new Sort(Sort.Direction.DESC, "postDate");
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
//默认显示10条
Integer size = 10;
//尝试加载设置选项,用于设置显示条数
int size = 10;
if (StrUtil.isNotBlank(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()))) {
size = Integer.parseInt(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()));
}
//所有文章数据,分页
Pageable pageable = PageRequest.of(page - 1, size, sort);
Page<Post> posts = postService.findPostByStatus(pageable);
final Pageable pageable = PageRequest.of(page - 1, size, sort);
final Page<Post> posts = postService.findPostByStatus(pageable);
if (null == posts) {
return this.renderNotFound();
}
int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
model.addAttribute("is_index",true);
final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
model.addAttribute("is_index", true);
model.addAttribute("posts", posts);
model.addAttribute("rainbow", rainbow);
return this.render("index");
}
/**
* ajax
*
* @param page page
* @return List
*/
@GetMapping(value = "next")
@ResponseBody
public List<Post> ajaxIndex(@RequestParam(value = "page") Integer page) {
Sort sort = new Sort(Sort.Direction.DESC, "postDate");
//默认显示10条
Integer size = 10;
//尝试加载设置选项,用于设置显示条数
if (StrUtil.isNotBlank(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()))) {
size = Integer.parseInt(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()));
}
//文章数据,只获取文章,没有分页
Pageable pageable = PageRequest.of(page - 1, size, sort);
List<Post> posts = postService.findPostByStatus(pageable).getContent();
return posts;
}
/**
*
*
* @param keyword keyword
* @param model model
* @return /themes/{theme}/index
*/
@GetMapping(value = "search")
public String search(@RequestParam("keyword") String keyword, Model model) {
Page<Post> posts = postService.searchByKeywords(keyword, null);
model.addAttribute("posts", posts);
return this.render("index");
}
}

View File

@ -44,10 +44,15 @@ public class FrontOthersController {
rssPosts = "20";
}
//获取文章列表并根据时间排序
Sort sort = new Sort(Sort.Direction.DESC, "postDate");
Pageable pageable = PageRequest.of(0, Integer.parseInt(rssPosts), sort);
Page<Post> postsPage = postService.findPostByStatus(0, PostTypeEnum.POST_TYPE_POST.getDesc(), pageable);
List<Post> posts = postsPage.getContent();
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
final Pageable pageable = PageRequest.of(0, Integer.parseInt(rssPosts), sort);
final Page<Post> postsPage = postService.findPostByStatus(0, PostTypeEnum.POST_TYPE_POST.getDesc(), pageable);
final List<Post> posts = postsPage.getContent();
for (Post post : posts) {
if(StrUtil.isNotEmpty(post.getPostPassword())){
post.setPostContent("该文章为加密文章");
}
}
return postService.buildRss(posts);
}
@ -60,10 +65,15 @@ public class FrontOthersController {
@ResponseBody
public String siteMap() {
//获取文章列表并根据时间排序
Sort sort = new Sort(Sort.Direction.DESC, "postDate");
Pageable pageable = PageRequest.of(0, 999, sort);
Page<Post> postsPage = postService.findPostByStatus(0, PostTypeEnum.POST_TYPE_POST.getDesc(), pageable);
List<Post> posts = postsPage.getContent();
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
final Pageable pageable = PageRequest.of(0, 999, sort);
final Page<Post> postsPage = postService.findPostByStatus(0, PostTypeEnum.POST_TYPE_POST.getDesc(), pageable);
final List<Post> posts = postsPage.getContent();
for (Post post : posts) {
if(StrUtil.isNotEmpty(post.getPostPassword())){
post.setPostContent("该文章为加密文章");
}
}
return postService.buildSiteMap(posts);
}
}

View File

@ -5,10 +5,7 @@ import cc.ryanc.halo.model.domain.Gallery;
import cc.ryanc.halo.model.domain.Post;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.dto.ListPage;
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.model.enums.CommentStatusEnum;
import cc.ryanc.halo.model.enums.PostTypeEnum;
import cc.ryanc.halo.model.enums.TrueFalseEnum;
import cc.ryanc.halo.model.enums.*;
import cc.ryanc.halo.service.CommentService;
import cc.ryanc.halo.service.GalleryService;
import cc.ryanc.halo.service.PostService;
@ -52,7 +49,7 @@ public class FrontPageController extends BaseController {
*/
@GetMapping(value = "/gallery")
public String gallery(Model model) {
List<Gallery> galleries = galleryService.findAllGalleries();
final List<Gallery> galleries = galleryService.findAll();
model.addAttribute("galleries", galleries);
return this.render("gallery");
}
@ -72,14 +69,15 @@ public class FrontPageController extends BaseController {
*
* @param postUrl
* @param model model
*
* @return /themes/{theme}/post
*/
@GetMapping(value = "/p/{postUrl}")
public String getPage(@PathVariable(value = "postUrl") String postUrl,
@RequestParam(value = "cp",defaultValue = "1") Integer cp,
@RequestParam(value = "cp", defaultValue = "1") Integer cp,
Model model) {
Post post = postService.findByPostUrl(postUrl, PostTypeEnum.POST_TYPE_PAGE.getDesc());
if (null == post) {
final Post post = postService.findByPostUrl(postUrl, PostTypeEnum.POST_TYPE_PAGE.getDesc());
if (null == post || !post.getPostStatus().equals(PostStatusEnum.PUBLISHED.getCode())) {
return this.renderNotFound();
}
List<Comment> comments = null;
@ -89,23 +87,22 @@ public class FrontPageController extends BaseController {
comments = commentService.findCommentsByPostAndCommentStatusNot(post, CommentStatusEnum.RECYCLE.getCode());
}
//默认显示10条
Integer size = 10;
//获取每页评论条数
int size = 10;
if (StrUtil.isNotBlank(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_COMMENTS.getProp()))) {
size = Integer.parseInt(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_COMMENTS.getProp()));
}
//评论分页
ListPage<Comment> commentsPage = new ListPage<Comment>(CommentUtil.getComments(comments),cp, size);
int[] rainbow = PageUtil.rainbow(cp, commentsPage.getTotalPage(), 3);
model.addAttribute("is_page",true);
final ListPage<Comment> commentsPage = new ListPage<Comment>(CommentUtil.getComments(comments), cp, size);
final int[] rainbow = PageUtil.rainbow(cp, commentsPage.getTotalPage(), 3);
model.addAttribute("is_page", true);
model.addAttribute("post", post);
model.addAttribute("comments", commentsPage);
model.addAttribute("commentsCount", comments.size());
model.addAttribute("rainbow", rainbow);
postService.updatePostView(post);
postService.cacheViews(post.getPostId());
//如果设置了自定义模板,则渲染自定义模板
if(StrUtil.isNotEmpty(post.getCustomTpl())){
if (StrUtil.isNotEmpty(post.getCustomTpl())) {
return this.render(post.getCustomTpl());
}
return this.render("page");

View File

@ -0,0 +1,81 @@
package cc.ryanc.halo.web.controller.front;
import cc.ryanc.halo.model.domain.Post;
import cc.ryanc.halo.model.dto.HaloConst;
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
import cc.ryanc.halo.model.enums.PostStatusEnum;
import cc.ryanc.halo.model.enums.PostTypeEnum;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.web.controller.core.BaseController;
import cn.hutool.core.util.PageUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* <pre>
*
* </pre>
*
* @author : RYAN0UP
* @date : 2019/1/11
*/
@Slf4j
@Controller
@RequestMapping(value = "/search")
public class FrontSearchController extends BaseController {
@Autowired
private PostService postService;
/**
*
*
* @param model model
* @param keyword
* @return /themes/{theme}/search
*/
@GetMapping
public String search(Model model,
@RequestParam(value = "keyword") String keyword) {
return this.search(model, HtmlUtil.escape(keyword), 1);
}
/**
*
*
* @param model model
* @param keyword
* @param page
* @return /themes/{theme}/search
*/
@GetMapping(value = "page/{page}")
public String search(Model model,
@RequestParam(value = "keyword") String keyword,
@PathVariable(value = "page") Integer page) {
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
int size = 10;
if (StrUtil.isNotBlank(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()))) {
size = Integer.parseInt(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()));
}
final Pageable pageable = PageRequest.of(page - 1, size, sort);
final Page<Post> posts = postService.searchPosts(HtmlUtil.escape(keyword),PostTypeEnum.POST_TYPE_POST.getDesc(),PostStatusEnum.PUBLISHED.getCode(),pageable);
final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
model.addAttribute("is_search", true);
model.addAttribute("keyword", keyword);
model.addAttribute("posts", posts);
model.addAttribute("rainbow", rainbow);
return this.render("search");
}
}

View File

@ -53,6 +53,7 @@ public class FrontTagController extends BaseController {
*
* @param tagUrl
* @param model model
*
* @return String
*/
@GetMapping(value = "{tagUrl}")
@ -67,25 +68,26 @@ public class FrontTagController extends BaseController {
* @param model model
* @param tagUrl
* @param page
*
* @return String
*/
@GetMapping(value = "{tagUrl}/page/{page}")
public String tags(Model model,
@PathVariable("tagUrl") String tagUrl,
@PathVariable("page") Integer page) {
Tag tag = tagService.findByTagUrl(tagUrl);
if(null==tag){
final Tag tag = tagService.findByTagUrl(tagUrl);
if (null == tag) {
return this.renderNotFound();
}
Sort sort = new Sort(Sort.Direction.DESC, "postDate");
Integer size = 10;
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
int size = 10;
if (StrUtil.isNotBlank(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()))) {
size = Integer.parseInt(HaloConst.OPTIONS.get(BlogPropertiesEnum.INDEX_POSTS.getProp()));
}
Pageable pageable = PageRequest.of(page - 1, size, sort);
Page<Post> posts = postService.findPostsByTags(tag, pageable);
int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
model.addAttribute("is_tags",true);
final Pageable pageable = PageRequest.of(page - 1, size, sort);
final Page<Post> posts = postService.findPostsByTags(tag, pageable);
final int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);
model.addAttribute("is_tags", true);
model.addAttribute("posts", posts);
model.addAttribute("rainbow", rainbow);
model.addAttribute("tag", tag);

View File

@ -25,10 +25,12 @@ import java.util.Map;
@Component
public class ApiInterceptor implements HandlerInterceptor {
private static final String TOKEN = "token";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (StrUtil.equals(TrueFalseEnum.TRUE.getDesc(), HaloConst.OPTIONS.get(BlogPropertiesEnum.API_STATUS.getProp()))) {
if (StrUtil.equals(request.getHeader("token"), HaloConst.OPTIONS.get(BlogPropertiesEnum.API_TOKEN.getProp()))) {
if (StrUtil.equals(request.getHeader(TOKEN), HaloConst.OPTIONS.get(BlogPropertiesEnum.API_TOKEN.getProp()))) {
return true;
} else {
response.setCharacterEncoding("UTF-8");

View File

@ -23,6 +23,10 @@ public class LocaleInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
final Object attribute = request.getSession().getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);
if (null != attribute) {
return true;
}
if (StrUtil.equals(LocaleEnum.EN_US.getValue(), HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_LOCALE.getProp()))) {
request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale("en", "US"));
} else {

View File

@ -21,7 +21,7 @@ public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object obj = request.getSession().getAttribute(HaloConst.USER_SESSION_KEY);
final Object obj = request.getSession().getAttribute(HaloConst.USER_SESSION_KEY);
//如果user不为空则放行
if (null != obj) {
return true;

Some files were not shown because too many files have changed in this diff Show More