Compare commits
77 Commits
feat-multl
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d6950fb11 | ||
| 2a3ae4a376 | |||
| 92e818e370 | |||
|
|
c8e93c45c7 | ||
|
|
32de31a21e | ||
|
|
cc20df91e6 | ||
|
|
71d79ed008 | ||
|
|
f7ff494ea4 | ||
|
|
971f48c5f9 | ||
|
|
e1522a8cc1 | ||
|
|
3cc4989960 | ||
|
|
8c751e6e76 | ||
|
|
af47631126 | ||
|
|
2107a1c100 | ||
|
|
2eac16dbe4 | ||
|
|
d248e15cea | ||
|
|
91a818d293 | ||
|
|
65c31e96b4 | ||
|
|
81b4851e42 | ||
|
|
9c580cf6d9 | ||
|
|
9eea5b3db9 | ||
|
|
eacb2e29f3 | ||
|
|
fafee4f918 | ||
|
|
30a4c11366 | ||
|
|
5632d47674 | ||
|
|
15b5d89554 | ||
|
|
79426dbe24 | ||
|
|
b3b19dbc45 | ||
|
|
87ec6d24ca | ||
|
|
0148c5e3f5 | ||
|
|
7cff3b9c08 | ||
|
|
a354f48edf | ||
|
|
2cd2dc93d7 | ||
|
|
d5fbc0fbf1 | ||
|
|
b29362eb8c | ||
|
|
d7c6cca683 | ||
|
|
8020eaeff3 | ||
|
|
aedcaf207b | ||
|
|
af9bf9ef46 | ||
|
|
b38ce4c8ce | ||
|
|
3d3548b984 | ||
|
|
4be9eda566 | ||
|
|
e5711746fb | ||
|
|
cc9cf8b1e8 | ||
|
|
ff076f8366 | ||
|
|
dd9ae0b3f9 | ||
|
|
0e7d5f2d23 | ||
|
|
1de1af2a54 | ||
|
|
857a3d9473 | ||
|
|
78efa62476 | ||
|
|
674812c5c6 | ||
|
|
14ce46c312 | ||
|
|
5f5fbadfd8 | ||
|
|
c153d9a0e3 | ||
|
|
18d35809f5 | ||
|
|
75e2424f75 | ||
|
|
b6c4251198 | ||
|
|
fc1bfa0e4f | ||
|
|
e37de0e177 | ||
|
|
082662af66 | ||
|
|
0c0e2404d0 | ||
|
|
71f82bfe32 | ||
|
|
61ce2fddad | ||
|
|
a245f259f7 | ||
|
|
aa22369b13 | ||
|
|
8c3866afe6 | ||
|
|
2c85c3eaac | ||
|
|
2559937e02 | ||
|
|
8de4be602e | ||
|
|
1f88995884 | ||
|
|
c879fbff5f | ||
|
|
f6020bf8d0 | ||
|
|
418b1d78e5 | ||
|
|
98ed489bb1 | ||
|
|
cfdd818829 | ||
|
|
3afbef009f | ||
|
|
8f4d1cd6c8 |
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
12
.github/dependabot.yml
vendored
Normal file
12
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "maven" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
open-pull-requests-limit: 10
|
||||
15
.github/workflows/build.yml
vendored
15
.github/workflows/build.yml
vendored
@@ -10,12 +10,10 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '.md')" # 如果 commit 信息包含以下关键字则跳过该任务
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
KEY: ${{ secrets.WEB_HOOK_ACCESS_KEY }}
|
||||
QINIU_ACCESSKEY: ${{ secrets.QINIU_ACCESSKEY }}
|
||||
QINIU_SECRETKEY: ${{ secrets.QINIU_SECRETKEY }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@@ -24,5 +22,16 @@ jobs:
|
||||
with:
|
||||
java-version: 1.8
|
||||
|
||||
- name: Sync repository
|
||||
uses: x-dr/sync-repo-to-gitee@v1.0
|
||||
env:
|
||||
# 在 Settings->Secrets 配置 GITEE_KEY
|
||||
SSH_KEY: ${{ secrets.GITEE_KEY }}
|
||||
with:
|
||||
# GitHub存储库的SSH URL.
|
||||
github-repo: git@github.com:xiaohai2271/blog-backEnd.git
|
||||
# Gitee存储库的SSH URL.
|
||||
gitee-repo: git@gitee.com:xiaohai2271/blog-backEnd.git
|
||||
|
||||
- name: Deploy
|
||||
run: mvn -B test --file pom.xml && curl http://bt.celess.cn:2271/hook?access_key=$KEY
|
||||
|
||||
8
.github/workflows/test.yml
vendored
8
.github/workflows/test.yml
vendored
@@ -10,11 +10,11 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '.md')" # 如果 commit 信息包含以下关键字则跳过该任务
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
QINIU_ACCESSKEY: ${{ secrets.QINIU_ACCESSKEY }}
|
||||
QINIU_SECRETKEY: ${{ secrets.QINIU_SECRETKEY }}
|
||||
# env:
|
||||
# APPLICATION_PROPERTIES_TEST: ${{ secrets.APPLICATION_PROPERTIES_TEST }}
|
||||
# APPLICATION_PROPERTIES_PROD: ${{ secrets.APPLICATION_PROPERTIES_PROD }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
299
doc/API.md
299
doc/API.md
@@ -1411,78 +1411,6 @@
|
||||
| 401 | Unauthorized ||
|
||||
| 403 | Forbidden ||
|
||||
| 404 | Not Found ||
|
||||
## fileUpload
|
||||
|
||||
|
||||
**接口描述**:
|
||||
|
||||
|
||||
**接口地址**:`/fileUpload`
|
||||
|
||||
|
||||
**请求方式**:`POST`
|
||||
|
||||
|
||||
**consumes**:`["application/json"]`
|
||||
|
||||
|
||||
**produces**:`["*/*"]`
|
||||
|
||||
|
||||
|
||||
**请求参数**:
|
||||
|
||||
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
|
||||
| ------------ | -------------------------------- |-----------|--------|----|--- |
|
||||
|file[]| file[] | formData | true |array | file |
|
||||
|
||||
**响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "",
|
||||
"result": [
|
||||
{}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**响应参数**:
|
||||
|
||||
|
||||
| 参数名称 | 参数说明 | 类型 | schema |
|
||||
| ------------ | -------------------|-------|----------- |
|
||||
|code| |integer(int32) | integer(int32) |
|
||||
|msg| |string | |
|
||||
|result| |array | Map«string,object» |
|
||||
|
||||
|
||||
|
||||
**schema属性说明**
|
||||
|
||||
|
||||
|
||||
|
||||
**Map«string,object»**
|
||||
|
||||
| 参数名称 | 参数说明 | 类型 | schema |
|
||||
| ------------ | ------------------|--------|----------- |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
**响应状态**:
|
||||
|
||||
|
||||
| 状态码 | 说明 | schema |
|
||||
| ------------ | -------------------------------- |---------------------- |
|
||||
| 200 | OK |Response«List«Map«string,object»»»|
|
||||
| 201 | Created ||
|
||||
| 401 | Unauthorized ||
|
||||
| 403 | Forbidden ||
|
||||
| 404 | Not Found ||
|
||||
## headerInfo
|
||||
|
||||
|
||||
@@ -1695,231 +1623,6 @@
|
||||
| 401 | Unauthorized ||
|
||||
| 403 | Forbidden ||
|
||||
| 404 | Not Found ||
|
||||
# config-controller
|
||||
|
||||
## getConfiguration
|
||||
|
||||
|
||||
**接口描述**:
|
||||
|
||||
|
||||
**接口地址**:`/admin/config`
|
||||
|
||||
|
||||
**请求方式**:`GET`
|
||||
|
||||
|
||||
**consumes**:``
|
||||
|
||||
|
||||
**produces**:`["*/*"]`
|
||||
|
||||
|
||||
|
||||
**请求参数**:
|
||||
暂无
|
||||
|
||||
|
||||
|
||||
**响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "",
|
||||
"result": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "",
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**响应参数**:
|
||||
|
||||
|
||||
| 参数名称 | 参数说明 | 类型 | schema |
|
||||
| ------------ | -------------------|-------|----------- |
|
||||
|code| |integer(int32) | integer(int32) |
|
||||
|msg| |string | |
|
||||
|result| |array | Config |
|
||||
|
||||
|
||||
|
||||
**schema属性说明**
|
||||
|
||||
|
||||
|
||||
|
||||
**Config**
|
||||
|
||||
| 参数名称 | 参数说明 | 类型 | schema |
|
||||
| ------------ | ------------------|--------|----------- |
|
||||
|id | |integer(int32) | |
|
||||
|name | |string | |
|
||||
|value | |string | |
|
||||
|
||||
**响应状态**:
|
||||
|
||||
|
||||
| 状态码 | 说明 | schema |
|
||||
| ------------ | -------------------------------- |---------------------- |
|
||||
| 200 | OK |Response«List«Config»»|
|
||||
| 401 | Unauthorized ||
|
||||
| 403 | Forbidden ||
|
||||
| 404 | Not Found ||
|
||||
## addConfiguration
|
||||
|
||||
|
||||
**接口描述**:
|
||||
|
||||
|
||||
**接口地址**:`/admin/config`
|
||||
|
||||
|
||||
**请求方式**:`POST`
|
||||
|
||||
|
||||
**consumes**:`["application/json"]`
|
||||
|
||||
|
||||
**produces**:`["*/*"]`
|
||||
|
||||
|
||||
|
||||
**请求参数**:
|
||||
|
||||
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
|
||||
| ------------ | -------------------------------- |-----------|--------|----|--- |
|
||||
|configs| configs | query | false |array | Config |
|
||||
|
||||
**响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "",
|
||||
"result": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "",
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**响应参数**:
|
||||
|
||||
|
||||
| 参数名称 | 参数说明 | 类型 | schema |
|
||||
| ------------ | -------------------|-------|----------- |
|
||||
|code| |integer(int32) | integer(int32) |
|
||||
|msg| |string | |
|
||||
|result| |array | Config |
|
||||
|
||||
|
||||
|
||||
**schema属性说明**
|
||||
|
||||
|
||||
|
||||
|
||||
**Config**
|
||||
|
||||
| 参数名称 | 参数说明 | 类型 | schema |
|
||||
| ------------ | ------------------|--------|----------- |
|
||||
|id | |integer(int32) | |
|
||||
|name | |string | |
|
||||
|value | |string | |
|
||||
|
||||
**响应状态**:
|
||||
|
||||
|
||||
| 状态码 | 说明 | schema |
|
||||
| ------------ | -------------------------------- |---------------------- |
|
||||
| 200 | OK |Response«List«Config»»|
|
||||
| 201 | Created ||
|
||||
| 401 | Unauthorized ||
|
||||
| 403 | Forbidden ||
|
||||
| 404 | Not Found ||
|
||||
## updateConfiguration
|
||||
|
||||
|
||||
**接口描述**:
|
||||
|
||||
|
||||
**接口地址**:`/admin/config`
|
||||
|
||||
|
||||
**请求方式**:`PUT`
|
||||
|
||||
|
||||
**consumes**:`["application/json"]`
|
||||
|
||||
|
||||
**produces**:`["*/*"]`
|
||||
|
||||
|
||||
|
||||
**请求参数**:
|
||||
|
||||
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
|
||||
| ------------ | -------------------------------- |-----------|--------|----|--- |
|
||||
|configs| configs | query | false |array | Config |
|
||||
|
||||
**响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"msg": "",
|
||||
"result": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "",
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**响应参数**:
|
||||
|
||||
|
||||
| 参数名称 | 参数说明 | 类型 | schema |
|
||||
| ------------ | -------------------|-------|----------- |
|
||||
|code| |integer(int32) | integer(int32) |
|
||||
|msg| |string | |
|
||||
|result| |array | Config |
|
||||
|
||||
|
||||
|
||||
**schema属性说明**
|
||||
|
||||
|
||||
|
||||
|
||||
**Config**
|
||||
|
||||
| 参数名称 | 参数说明 | 类型 | schema |
|
||||
| ------------ | ------------------|--------|----------- |
|
||||
|id | |integer(int32) | |
|
||||
|name | |string | |
|
||||
|value | |string | |
|
||||
|
||||
**响应状态**:
|
||||
|
||||
|
||||
| 状态码 | 说明 | schema |
|
||||
| ------------ | -------------------------------- |---------------------- |
|
||||
| 200 | OK |Response«List«Config»»|
|
||||
| 201 | Created ||
|
||||
| 401 | Unauthorized ||
|
||||
| 403 | Forbidden ||
|
||||
| 404 | Not Found ||
|
||||
# links-controller
|
||||
|
||||
## all
|
||||
@@ -1946,8 +1649,8 @@
|
||||
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
|
||||
| ------------ | -------------------------------- |-----------|--------|----|--- |
|
||||
|count| count | query | true |integer | |
|
||||
|deleted| deleted | query | false |boolean | |
|
||||
|page| page | query | true |integer | |
|
||||
|deleted| deleted | query | false |boolean | |
|
||||
|
||||
**响应示例**:
|
||||
|
||||
|
||||
34
pom.xml
34
pom.xml
@@ -6,7 +6,7 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.3.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<groupId>cn.celess</groupId>
|
||||
<artifactId>blog</artifactId>
|
||||
@@ -40,14 +40,14 @@
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.14</version>
|
||||
<version>1.2.6</version>
|
||||
</dependency>
|
||||
|
||||
<!-- lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.6</version>
|
||||
<version>1.18.20</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -67,12 +67,12 @@
|
||||
<dependency>
|
||||
<groupId>com.youbenzi</groupId>
|
||||
<artifactId>MDTool</artifactId>
|
||||
<version>1.2.3</version>
|
||||
<version>1.2.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.minidev</groupId>
|
||||
<artifactId>json-smart</artifactId>
|
||||
<version>2.3</version>
|
||||
<version>2.4.7</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -99,33 +99,33 @@
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<version>2.2.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- pageHelper -->
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- protostuff序列化依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.dyuproject.protostuff</groupId>
|
||||
<artifactId>protostuff-core</artifactId>
|
||||
<version>1.0.8</version>
|
||||
<version>1.1.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dyuproject.protostuff</groupId>
|
||||
<artifactId>protostuff-runtime</artifactId>
|
||||
<version>1.0.8</version>
|
||||
<version>1.1.6</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Ua解析-->
|
||||
<dependency>
|
||||
<groupId>eu.bitwalker</groupId>
|
||||
<artifactId>UserAgentUtils</artifactId>
|
||||
<version>1.20</version>
|
||||
<version>1.21</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -145,12 +145,12 @@
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>4.8.0</version>
|
||||
<version>4.9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
<version>1.3.72</version>
|
||||
<version>1.4.20</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<version>2.42.0</version>
|
||||
<version>2.45.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -178,17 +178,17 @@
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.3.0</version>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<version>2.3.0</version>
|
||||
<version>4.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-core</artifactId>
|
||||
<version>2.3.0</version>
|
||||
<version>2.3.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.activation</groupId>
|
||||
@@ -214,7 +214,7 @@
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>1.3.72</version>
|
||||
<version>1.5.10</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
|
||||
@@ -1,34 +1,20 @@
|
||||
package cn.celess.blog;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
/**
|
||||
* @author zheng
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableAsync
|
||||
@MapperScan("cn.celess.blog.mapper")
|
||||
public class BlogApplication {
|
||||
public static ConfigurableApplicationContext context;
|
||||
public static final Logger logger = LoggerFactory.getLogger(BlogApplication.class);
|
||||
|
||||
public static void main(String[] args) {
|
||||
context = SpringApplication.run(BlogApplication.class, args);
|
||||
}
|
||||
|
||||
public static void restart() {
|
||||
ApplicationArguments args = context.getBean(ApplicationArguments.class);
|
||||
|
||||
Thread thread = new Thread(() -> {
|
||||
context.close();
|
||||
context = SpringApplication.run(BlogApplication.class, args.getSourceArgs());
|
||||
});
|
||||
thread.setDaemon(false);
|
||||
thread.start();
|
||||
SpringApplication.run(BlogApplication.class, args);
|
||||
logger.info("启动完成!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
package cn.celess.blog.configuration;
|
||||
|
||||
import cn.celess.blog.enmu.ConfigKeyEnum;
|
||||
import cn.celess.blog.entity.Config;
|
||||
import cn.celess.blog.mapper.ConfigMapper;
|
||||
import cn.celess.blog.service.fileserviceimpl.LocalFileServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/16 16:00
|
||||
* @desc :
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ApplicationListener implements ApplicationRunner {
|
||||
|
||||
@Autowired
|
||||
ConfigMapper configMapper;
|
||||
@Autowired
|
||||
Environment env;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
log.info("博客启动!");
|
||||
// 设置初始值
|
||||
setProperty(ConfigKeyEnum.FILE_QINIU_SECRET_KEY);
|
||||
setProperty(ConfigKeyEnum.FILE_QINIU_ACCESS_KEY);
|
||||
setProperty(ConfigKeyEnum.FILE_QINIU_BUCKET);
|
||||
setProperty(ConfigKeyEnum.BLOG_FILE_PATH);
|
||||
|
||||
List<Config> configurations = configMapper.getConfigurations()
|
||||
.stream()
|
||||
.filter(config -> config.getValue() != null && !"".equals(config.getValue()))
|
||||
.collect(Collectors.toList());
|
||||
configurations.forEach(config -> System.setProperty(config.getName(), config.getValue()));
|
||||
log.debug("注入配置成功 {}", configurations.stream().map(Config::getName).collect(Collectors.toList()));
|
||||
File path = new File(LocalFileServiceImpl.getPath(System.getProperty(ConfigKeyEnum.BLOG_FILE_PATH.getKey())));
|
||||
if (!path.exists() && !path.mkdirs()) {
|
||||
throw new IllegalAccessException("创建数据目录失败==>" + path.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
private void setProperty(ConfigKeyEnum e) {
|
||||
String property = env.getProperty(e.getKey());
|
||||
if (property != null) {
|
||||
System.setProperty(e.getKey(), property);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package cn.celess.blog.configuration;
|
||||
|
||||
import cn.celess.blog.util.EnvironmentUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.env.EnvironmentPostProcessor;
|
||||
import org.springframework.boot.logging.DeferredLog;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* <p>date: 2022/12/02</P>
|
||||
* <p>desc: </p>
|
||||
* <p>mail: a@celess.cn</p>
|
||||
*
|
||||
* @author 禾几海
|
||||
*/
|
||||
|
||||
@Component
|
||||
public class CommonEnvPostProcessor implements EnvironmentPostProcessor, ApplicationListener<ApplicationEvent>, Ordered {
|
||||
public static final DeferredLog log = new DeferredLog();
|
||||
|
||||
private static final String CONFIG_PATH = "/HBlog/config/blog.properties";
|
||||
private static final String SOURCE_NAME = "localize";
|
||||
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment configurableEnvironment, SpringApplication springApplication) {
|
||||
|
||||
EnvironmentUtil.setEnvironment(configurableEnvironment);
|
||||
|
||||
log.info("加载本地配置文件--");
|
||||
//获取环境变量
|
||||
String homeEnv = EnvironmentUtil.getEnv("BLOG_HOME", EnvironmentUtil.getEnv("USERPROFILE"));
|
||||
String configPath = (homeEnv + CONFIG_PATH).replaceAll("[\\|/]+", Matcher.quoteReplacement(File.separator));
|
||||
try (InputStream input = Files.newInputStream(Paths.get(configPath))) {
|
||||
Properties properties = new Properties();
|
||||
properties.load(input);
|
||||
PropertiesPropertySource propertySource = new PropertiesPropertySource(SOURCE_NAME, properties);
|
||||
configurableEnvironment.getPropertySources().addLast(propertySource);
|
||||
log.info("成功加载本地配置文件:)");
|
||||
} catch (Exception e) {
|
||||
log.info("加载本地[" + configPath + "]的配置文件失败:(");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(@NotNull ApplicationEvent event) {
|
||||
log.replayTo(CommonEnvPostProcessor.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,81 +1,41 @@
|
||||
package cn.celess.blog.configuration;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2019/03/28 14:26
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class DruidConfig {
|
||||
@Value("${spring.datasource.url}")
|
||||
private String dbUrl;
|
||||
|
||||
@Autowired
|
||||
Environment env;
|
||||
@Value("${spring.datasource.username}")
|
||||
private String username;
|
||||
|
||||
public static final String DB_CONFIG_PATH = System.getProperty("user.home") + "/blog/application.properties";
|
||||
public static final String DB_CONFIG_URL_PREFIX = "spring.datasource.url";
|
||||
public static final String DB_CONFIG_USERNAME_PREFIX = "spring.datasource.username";
|
||||
public static final String DB_CONFIG_PASSWORD_PREFIX = "spring.datasource.password";
|
||||
public static final String DB_CONFIG_DRIVER_CLASS_NAME_PREFIX = "spring.datasource.driver-class-name";
|
||||
public static final String TEST_PROFILES = "test";
|
||||
@Value("${spring.datasource.password}")
|
||||
private String password;
|
||||
|
||||
@Value("${spring.datasource.driver-class-name}")
|
||||
private String driverClassName;
|
||||
|
||||
@Bean
|
||||
public DruidDataSource initDataSource() throws IOException {
|
||||
DruidDataSource dataSource;
|
||||
File file = new File(DB_CONFIG_PATH);
|
||||
if (file.exists() && !Arrays.asList(env.getActiveProfiles()).contains(TEST_PROFILES)) {
|
||||
log.debug("从文件中获取数据库配置");
|
||||
dataSource = readConfigFromFile(file);
|
||||
} else {
|
||||
log.debug("默认数据库配置");
|
||||
dataSource = defaultDruidSource();
|
||||
}
|
||||
public DruidDataSource druidDataSource() {
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
dataSource.setDriverClassName(driverClassName);
|
||||
// 数据库基本信息
|
||||
dataSource.setUrl(dbUrl);
|
||||
dataSource.setUsername(username);
|
||||
dataSource.setPassword(password);
|
||||
|
||||
// 数据库连接池配置
|
||||
dataSource.setInitialSize(10);
|
||||
dataSource.setMinIdle(10);
|
||||
dataSource.setMaxActive(100);
|
||||
dataSource.setValidationQuery("select 1");
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
private DruidDataSource readConfigFromFile(File file) throws IOException {
|
||||
Properties properties = new Properties();
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
properties.load(fis);
|
||||
fis.close();
|
||||
String url = properties.getProperty(DB_CONFIG_URL_PREFIX, null);
|
||||
String username = properties.getProperty(DB_CONFIG_USERNAME_PREFIX, null);
|
||||
String password = properties.getProperty(DB_CONFIG_PASSWORD_PREFIX, null);
|
||||
String className = properties.getProperty(DB_CONFIG_DRIVER_CLASS_NAME_PREFIX, null);
|
||||
if (url == null || username == null || password == null || className == null) {
|
||||
return defaultDruidSource();
|
||||
}
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
dataSource.setDriverClassName(className);
|
||||
dataSource.setUrl(url);
|
||||
dataSource.setUsername(username);
|
||||
dataSource.setPassword(password);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
|
||||
private DruidDataSource defaultDruidSource() {
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
dataSource.setDriverClassName(env.getProperty(DruidConfig.DB_CONFIG_DRIVER_CLASS_NAME_PREFIX));
|
||||
dataSource.setUrl(env.getProperty(DruidConfig.DB_CONFIG_URL_PREFIX));
|
||||
dataSource.setUsername(env.getProperty(DruidConfig.DB_CONFIG_USERNAME_PREFIX));
|
||||
dataSource.setPassword(env.getProperty(DruidConfig.DB_CONFIG_PASSWORD_PREFIX));
|
||||
return dataSource;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ package cn.celess.blog.controller;
|
||||
|
||||
import cn.celess.blog.enmu.ResponseEnum;
|
||||
import cn.celess.blog.entity.Response;
|
||||
import cn.celess.blog.entity.model.FileResponse;
|
||||
import cn.celess.blog.entity.model.QiniuResponse;
|
||||
import cn.celess.blog.exception.MyException;
|
||||
import cn.celess.blog.service.CountService;
|
||||
import cn.celess.blog.service.FileService;
|
||||
import cn.celess.blog.service.QiniuService;
|
||||
import cn.celess.blog.util.HttpUtil;
|
||||
import cn.celess.blog.util.RedisUserUtil;
|
||||
import cn.celess.blog.util.RedisUtil;
|
||||
@@ -42,7 +42,7 @@ public class CommonController {
|
||||
@Autowired
|
||||
CountService countService;
|
||||
@Autowired
|
||||
FileService fileService;
|
||||
QiniuService qiniuService;
|
||||
@Autowired
|
||||
RedisUtil redisUtil;
|
||||
@Autowired
|
||||
@@ -161,10 +161,10 @@ public class CommonController {
|
||||
String mime = fileName.substring(fileName.lastIndexOf("."));
|
||||
if (".png".equals(mime.toLowerCase()) || ".jpg".equals(mime.toLowerCase()) ||
|
||||
".jpeg".equals(mime.toLowerCase()) || ".bmp".equals(mime.toLowerCase())) {
|
||||
FileResponse fileResponse = fileService.getFileManager().uploadFile(file.getInputStream(), "img_" + System.currentTimeMillis() + mime);
|
||||
QiniuResponse qiniuResponse = qiniuService.uploadFile(file.getInputStream(), "img_" + System.currentTimeMillis() + mime);
|
||||
map.put("success", 1);
|
||||
map.put("message", "上传成功");
|
||||
map.put("url", "http://cdn.celess.cn/" + fileResponse.key);
|
||||
map.put("url", "http://cdn.celess.cn/" + qiniuResponse.key);
|
||||
response.getWriter().println(mapper.writeValueAsString(map));
|
||||
redisUtil.setEx(request.getRemoteAddr() + "-ImgUploadTimes", uploadTimes + 1 + "", 2, TimeUnit.HOURS);
|
||||
return;
|
||||
@@ -208,12 +208,12 @@ public class CommonController {
|
||||
assert fileName != null;
|
||||
String mime = fileName.substring(fileName.lastIndexOf("."));
|
||||
String name = fileName.replace(mime, "").replaceAll(" ", "");
|
||||
FileResponse fileResponse = fileService.getFileManager().uploadFile(file.getInputStream(), "file_" + name + '_' + System.currentTimeMillis() + mime);
|
||||
QiniuResponse qiniuResponse = qiniuService.uploadFile(file.getInputStream(), "file_" + name + '_' + System.currentTimeMillis() + mime);
|
||||
resp.put("originalFilename", fileName);
|
||||
resp.put("success", fileResponse != null);
|
||||
if (fileResponse != null) {
|
||||
resp.put("success", qiniuResponse != null);
|
||||
if (qiniuResponse != null) {
|
||||
resp.put("host", "http://cdn.celess.cn/");
|
||||
resp.put("path", fileResponse.key);
|
||||
resp.put("path", qiniuResponse.key);
|
||||
}
|
||||
result.add(resp);
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
package cn.celess.blog.controller;
|
||||
|
||||
import cn.celess.blog.entity.Config;
|
||||
import cn.celess.blog.entity.Response;
|
||||
import cn.celess.blog.mapper.ConfigMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/16 20:56
|
||||
* @desc : 配置管理接口
|
||||
*/
|
||||
@RestController
|
||||
public class ConfigController {
|
||||
@Autowired
|
||||
ConfigMapper configMapper;
|
||||
|
||||
@GetMapping("/admin/config")
|
||||
public Response<List<Config>> getConfiguration() {
|
||||
return Response.success(configMapper.getConfigurations());
|
||||
}
|
||||
|
||||
@PutMapping("/admin/config")
|
||||
public Response<List<Config>> updateConfiguration(@RequestBody List<Config> configs) {
|
||||
configs.forEach(config -> configMapper.updateConfiguration(config));
|
||||
configs.forEach(config -> System.setProperty(config.getName(), config.getValue()));
|
||||
return Response.success(configMapper.getConfigurations());
|
||||
}
|
||||
|
||||
@PostMapping("/admin/config")
|
||||
public Response<List<Config>> addConfiguration(@RequestBody List<Config> configs) {
|
||||
configs.forEach(config -> configMapper.addConfiguration(config));
|
||||
configs.forEach(config -> System.setProperty(config.getName(), config.getValue()));
|
||||
return Response.success(configMapper.getConfigurations());
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package cn.celess.blog.controller;
|
||||
|
||||
import cn.celess.blog.BlogApplication;
|
||||
import cn.celess.blog.enmu.ConfigKeyEnum;
|
||||
import cn.celess.blog.enmu.ResponseEnum;
|
||||
import cn.celess.blog.entity.Config;
|
||||
import cn.celess.blog.entity.InstallParam;
|
||||
import cn.celess.blog.entity.Response;
|
||||
import cn.celess.blog.exception.MyException;
|
||||
import cn.celess.blog.mapper.ConfigMapper;
|
||||
import cn.celess.blog.service.InstallService;
|
||||
import cn.celess.blog.util.RegexUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/18 15:36
|
||||
* @desc :
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@Validated
|
||||
public class InstallController {
|
||||
|
||||
@Autowired
|
||||
InstallService installService;
|
||||
@Autowired
|
||||
ConfigMapper configMapper;
|
||||
|
||||
|
||||
@GetMapping("/is_install")
|
||||
@ResponseBody
|
||||
public Response<Map<String, Object>> isInstall() {
|
||||
Map<String, Object> install = installService.isInstall();
|
||||
return Response.success(install);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/install")
|
||||
@ResponseBody
|
||||
public Response<Object> install(@Valid @RequestBody InstallParam installParam) {
|
||||
if (!RegexUtil.emailMatch(installParam.getEmail())) {
|
||||
throw new MyException(ResponseEnum.PARAMETERS_EMAIL_ERROR);
|
||||
}
|
||||
if (!RegexUtil.pwdMatch(installParam.getPassword())) {
|
||||
throw new MyException(ResponseEnum.PARAMETERS_PWD_ERROR);
|
||||
}
|
||||
return Response.success(installService.install(installParam));
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/default_config")
|
||||
@ResponseBody
|
||||
public Response<String> defaultConfig() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/install")
|
||||
public String install() {
|
||||
Config configuration = configMapper.getConfiguration(ConfigKeyEnum.BLOG_INSTALLED.getKey());
|
||||
if (Boolean.parseBoolean(configuration.getValue())) {
|
||||
return "index.html";
|
||||
}
|
||||
log.info("博客第一次运行,还未安装");
|
||||
return "install.html";
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package cn.celess.blog.enmu;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/16 16:41
|
||||
* @desc :
|
||||
*/
|
||||
public enum ConfigKeyEnum {
|
||||
|
||||
/**
|
||||
* 枚举
|
||||
*/
|
||||
FILE_TYPE("file.type"),
|
||||
FILE_QINIU_ACCESS_KEY("file.qiniu.accessKey"),
|
||||
FILE_QINIU_SECRET_KEY("file.qiniu.secretKey"),
|
||||
FILE_QINIU_BUCKET("file.qiniu.bucket"),
|
||||
FILE_LOCAL_DIRECTORY_PATH("file.local.directoryPath"),
|
||||
BLOG_FILE_PATH("blog.file.path"),
|
||||
BLOG_INSTALLED("blog.installed"),
|
||||
DB_TYPE("db.type"),
|
||||
DB_URL("spring.datasource.url"),
|
||||
DB_USERNAME("spring.datasource.username"),
|
||||
DB_PASSWORD("spring.datasource.password"),
|
||||
DB_DRIVER_CLASS_NAME("spring.datasource.driver-class-name"),
|
||||
BLOG_DB_PATH("blog.db.path");
|
||||
|
||||
|
||||
private final String key;
|
||||
|
||||
ConfigKeyEnum(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package cn.celess.blog.entity;
|
||||
|
||||
import cn.celess.blog.enmu.ConfigKeyEnum;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/16 15:24
|
||||
* @desc :
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class Config {
|
||||
private Integer id;
|
||||
private String name;
|
||||
private String value;
|
||||
|
||||
public Config(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Config(ConfigKeyEnum e) {
|
||||
this.name = e.getKey();
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package cn.celess.blog.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/18 14:52
|
||||
* @desc :
|
||||
*/
|
||||
@Data
|
||||
public class InstallParam {
|
||||
@NotBlank(message = "数据库类型不可为空")
|
||||
private String dbType;
|
||||
|
||||
@NotBlank(message = "数据库主机不可为空")
|
||||
private String dbHost;
|
||||
|
||||
@NotBlank(message = "数据库名称不可为空")
|
||||
private String dbName;
|
||||
|
||||
@NotBlank(message = "数据库用户名不可为空")
|
||||
private String dbUsername;
|
||||
|
||||
@NotBlank(message = "数据库密码不可为空")
|
||||
private String dbPassword;
|
||||
|
||||
|
||||
/**
|
||||
* user 相关
|
||||
*/
|
||||
@NotBlank(message = "用户邮箱地址不可为空")
|
||||
private String email;
|
||||
|
||||
@NotBlank(message = "用户密码不可为空")
|
||||
private String password;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package cn.celess.blog.entity.model;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/15 22:16
|
||||
* @desc :
|
||||
*/
|
||||
public class FileInfo {
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
public String key;
|
||||
/**
|
||||
* 文件hash值
|
||||
*/
|
||||
public String hash;
|
||||
/**
|
||||
* 文件大小,单位:字节
|
||||
*/
|
||||
public long size;
|
||||
/**
|
||||
* 文件上传时间,单位为:100纳秒
|
||||
*/
|
||||
public long uploadTime;
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
package cn.celess.blog.entity.model;
|
||||
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2019/04/21 22:43
|
||||
*/
|
||||
public class FileResponse {
|
||||
public String key;
|
||||
public String hash;
|
||||
public String type;
|
||||
public long size;
|
||||
}
|
||||
package cn.celess.blog.entity.model;
|
||||
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2019/04/21 22:43
|
||||
*/
|
||||
public class QiniuResponse {
|
||||
public String key;
|
||||
public String hash;
|
||||
public String bucket;
|
||||
public long fsize;
|
||||
}
|
||||
@@ -10,9 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
@@ -20,10 +18,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import javax.validation.ValidationException;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
@@ -47,32 +41,27 @@ public class ExceptionHandle {
|
||||
if (e instanceof MyException) {
|
||||
MyException exception = (MyException) e;
|
||||
logger.debug("返回了自定义的exception,[code={},msg={},result={}]", exception.getCode(), e.getMessage(), exception.getResult());
|
||||
return new Response<>(exception.getCode(), e.getMessage(), exception.getResult());
|
||||
return new Response(exception.getCode(), e.getMessage(), exception.getResult());
|
||||
}
|
||||
//请求路径不支持该方法
|
||||
if (e instanceof HttpRequestMethodNotSupportedException) {
|
||||
logger.debug("遇到请求路径与请求方法不匹配的请求,[msg={},path:{},method:{}]", e.getMessage(), request.getRequestURL(), request.getMethod());
|
||||
return new Response<>(ResponseEnum.ERROR.getCode(), e.getMessage(), null);
|
||||
return new Response(ResponseEnum.ERROR.getCode(), e.getMessage(), null);
|
||||
}
|
||||
//数据输入类型不匹配
|
||||
if (e instanceof MethodArgumentTypeMismatchException) {
|
||||
logger.debug("输入类型不匹配,[msg={}]", e.getMessage());
|
||||
return new Response<>(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入有问题,请修改后再访问", null);
|
||||
return new Response(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入有问题,请修改后再访问", null);
|
||||
}
|
||||
//数据验证失败
|
||||
if (e instanceof BindException) {
|
||||
logger.debug("数据验证失败,[msg={}]", e.getMessage());
|
||||
return new Response<>(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入有问题,请修改", null);
|
||||
return new Response(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入有问题,请修改", null);
|
||||
}
|
||||
//数据输入不完整
|
||||
if (e instanceof MissingServletRequestParameterException) {
|
||||
logger.debug("数据输入不完整,[msg={}]", e.getMessage());
|
||||
return new Response<>(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入不完整,请检查", null);
|
||||
}
|
||||
if (e instanceof MethodArgumentNotValidException) {
|
||||
logger.debug("数据验证失败,[msg: {}]", e.getMessage());
|
||||
BindingResult violations = ((MethodArgumentNotValidException) e).getBindingResult();
|
||||
return new Response<>(ResponseEnum.PARAMETERS_ERROR.getCode(), violations.getAllErrors().get(0).getDefaultMessage(), null);
|
||||
return new Response(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入不完整,请检查", null);
|
||||
}
|
||||
|
||||
// 发送错误信息到邮箱
|
||||
@@ -81,7 +70,7 @@ public class ExceptionHandle {
|
||||
sendMessage(e);
|
||||
}
|
||||
e.printStackTrace();
|
||||
return new Response<>(ResponseEnum.ERROR.getCode(), "服务器出现错误,已记录", null);
|
||||
return new Response(ResponseEnum.ERROR.getCode(), "服务器出现错误,已记录", null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cn.celess.blog.mapper;
|
||||
|
||||
import cn.celess.blog.entity.ArticleTag;
|
||||
import cn.celess.blog.entity.Tag;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -27,6 +28,8 @@ public interface ArticleTagMapper {
|
||||
|
||||
List<ArticleTag> findAllByArticleId(Long articleId);
|
||||
|
||||
List<Tag> findTagByArticleId(Long articleId);
|
||||
|
||||
int deleteMultiById(List<ArticleTag> articleTags);
|
||||
|
||||
List<ArticleTag> findArticleByTag(Long tagId);
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
package cn.celess.blog.mapper;
|
||||
|
||||
import cn.celess.blog.entity.Config;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/16 15:24
|
||||
* @desc :
|
||||
*/
|
||||
@Mapper
|
||||
@Repository
|
||||
public interface ConfigMapper {
|
||||
/**
|
||||
* 获取单个配置
|
||||
*
|
||||
* @param key 配置名
|
||||
* @return 配置
|
||||
*/
|
||||
Config getConfiguration(String key);
|
||||
|
||||
/**
|
||||
* 更新配置
|
||||
*
|
||||
* @param c 配置
|
||||
* @return 改变数据行数
|
||||
*/
|
||||
int updateConfiguration(Config c);
|
||||
|
||||
/**
|
||||
* 获取所有配置
|
||||
*
|
||||
* @return 所有配置
|
||||
*/
|
||||
List<Config> getConfigurations();
|
||||
|
||||
/**
|
||||
* 新增配置
|
||||
*
|
||||
* @param c 配置
|
||||
* @return 改变行数
|
||||
*/
|
||||
int addConfiguration(Config c);
|
||||
|
||||
/**
|
||||
* 删除配置
|
||||
*
|
||||
* @param id 主键id
|
||||
* @return 改变行数
|
||||
*/
|
||||
int deleteConfiguration(int id);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package cn.celess.blog.service;
|
||||
|
||||
import cn.celess.blog.entity.model.FileInfo;
|
||||
import cn.celess.blog.entity.model.FileResponse;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/15 18:19
|
||||
* @desc : 文件管理器 定义操作文件的方法
|
||||
*/
|
||||
@Service
|
||||
public interface FileManager {
|
||||
/**
|
||||
* 上传文件到文件存储容器中
|
||||
*
|
||||
* @param is 文件流
|
||||
* @param fileName 文件名
|
||||
* @return FileResponse
|
||||
*/
|
||||
FileResponse uploadFile(InputStream is, String fileName);
|
||||
|
||||
/**
|
||||
* 获取文件列表
|
||||
*
|
||||
* @return 文件信息
|
||||
*/
|
||||
List<FileInfo> getFileList();
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
boolean deleteFile(String fileName);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package cn.celess.blog.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2019/04/25 18:15
|
||||
*/
|
||||
@Service("fileService")
|
||||
@FunctionalInterface
|
||||
public interface FileService {
|
||||
/**
|
||||
* 获取文件管理器
|
||||
*
|
||||
* @return 文件管理器 可以操作文件
|
||||
*/
|
||||
FileManager getFileManager();
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package cn.celess.blog.service;
|
||||
|
||||
import cn.celess.blog.entity.InstallParam;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/23 16:22
|
||||
* @desc :
|
||||
*/
|
||||
@Service
|
||||
public interface InstallService {
|
||||
Map<String, Object> isInstall();
|
||||
|
||||
Map<String, Object> install(@NotNull InstallParam installParam);
|
||||
|
||||
}
|
||||
31
src/main/java/cn/celess/blog/service/QiniuService.java
Normal file
31
src/main/java/cn/celess/blog/service/QiniuService.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package cn.celess.blog.service;
|
||||
|
||||
import cn.celess.blog.entity.model.QiniuResponse;
|
||||
import com.qiniu.storage.model.FileInfo;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2019/04/25 18:15
|
||||
*/
|
||||
@Service
|
||||
public interface QiniuService {
|
||||
/**
|
||||
* 上传文件
|
||||
*
|
||||
* @param is InputStream流
|
||||
* @param fileName 文件名
|
||||
* @return 响应数据
|
||||
*/
|
||||
QiniuResponse uploadFile(InputStream is, String fileName);
|
||||
|
||||
/**
|
||||
* 获取文件列表
|
||||
*
|
||||
* @return 文件列表
|
||||
*/
|
||||
FileInfo[] getFileList();
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package cn.celess.blog.service.fileserviceimpl;
|
||||
|
||||
import cn.celess.blog.enmu.ConfigKeyEnum;
|
||||
import cn.celess.blog.service.FileManager;
|
||||
import cn.celess.blog.service.FileService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/15 18:52
|
||||
* @desc : 提供文件管理器的服务
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("fileServiceImpl")
|
||||
public class FileServiceImpl implements FileService {
|
||||
@Resource(name = "qiniuFileServiceImpl")
|
||||
FileManager qiniuFileManager;
|
||||
|
||||
@Resource(name = "localFileServiceImpl")
|
||||
FileManager localFileServiceImpl;
|
||||
|
||||
@Override
|
||||
public FileManager getFileManager() {
|
||||
String property = System.getProperty(ConfigKeyEnum.FILE_TYPE.getKey());
|
||||
log.info("获取到{}:{}", ConfigKeyEnum.FILE_TYPE.getKey(), property);
|
||||
if ("qiniu".equals(property)){
|
||||
return qiniuFileManager;
|
||||
}else if ("local".equals(property)){
|
||||
return localFileServiceImpl;
|
||||
}
|
||||
return localFileServiceImpl;
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
package cn.celess.blog.service.fileserviceimpl;
|
||||
|
||||
import cn.celess.blog.enmu.ConfigKeyEnum;
|
||||
import cn.celess.blog.entity.model.FileInfo;
|
||||
import cn.celess.blog.entity.model.FileResponse;
|
||||
import cn.celess.blog.service.FileManager;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/16 14:39
|
||||
* @desc :
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("localFileServiceImpl")
|
||||
public class LocalFileServiceImpl implements FileManager {
|
||||
private static String path = null;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public FileResponse uploadFile(InputStream is, String fileName) {
|
||||
if (path == null) {
|
||||
path = System.getProperty(ConfigKeyEnum.FILE_LOCAL_DIRECTORY_PATH.getKey());
|
||||
}
|
||||
// 判断文件夹是否存在
|
||||
File directory = new File(getPath(path));
|
||||
if (!directory.exists() && directory.mkdirs()) {
|
||||
log.info("不存在文件夹,创建文件夹=>{}", directory.getAbsolutePath());
|
||||
}
|
||||
log.info("上传文件 {}", fileName);
|
||||
// 存储文件
|
||||
File file1 = new File(getPath(path) + File.separator + fileName);
|
||||
FileOutputStream fos = new FileOutputStream(file1);
|
||||
byte[] cache = new byte[1024 * 100];
|
||||
int len = 0;
|
||||
FileResponse fileResponse = new FileResponse();
|
||||
while ((len = is.read(cache)) != -1) {
|
||||
fileResponse.size += len;
|
||||
fos.write(cache, 0, len);
|
||||
}
|
||||
fos.flush();
|
||||
fos.close();
|
||||
is.close();
|
||||
fileResponse.key = URLEncoder.encode(fileName, "UTF-8");
|
||||
fileResponse.type = "local";
|
||||
return fileResponse;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public List<FileInfo> getFileList() {
|
||||
if (path == null) {
|
||||
path = System.getProperty(ConfigKeyEnum.FILE_LOCAL_DIRECTORY_PATH.getKey());
|
||||
}
|
||||
File file = new File(getPath(path));
|
||||
File[] files = file.listFiles();
|
||||
List<FileInfo> fileInfoList = new ArrayList<>();
|
||||
if (files == null) {
|
||||
return null;
|
||||
}
|
||||
for (File file1 : files) {
|
||||
FileInfo fileInfo = new FileInfo();
|
||||
fileInfo.key = URLEncoder.encode(file1.getName(), "UTF-8");
|
||||
fileInfo.size = file1.length();
|
||||
BasicFileAttributes basicFileAttributes = Files.readAttributes(file1.toPath(), BasicFileAttributes.class);
|
||||
fileInfo.uploadTime = basicFileAttributes.creationTime().toMillis();
|
||||
fileInfoList.add(fileInfo);
|
||||
}
|
||||
return fileInfoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteFile(String fileName) {
|
||||
if (path == null) {
|
||||
path = System.getProperty(ConfigKeyEnum.FILE_LOCAL_DIRECTORY_PATH.getKey());
|
||||
}
|
||||
File file = new File(getPath(path) + File.separator + fileName);
|
||||
return file.delete();
|
||||
}
|
||||
|
||||
public static String getPath(String path) {
|
||||
if (path == null) {
|
||||
return "";
|
||||
}
|
||||
String pathCop = path.replaceAll("//", File.separator);
|
||||
if (path.startsWith("~")) {
|
||||
// 家目录
|
||||
pathCop = path.replaceFirst("~", "");
|
||||
pathCop = System.getProperty("user.home") + pathCop;
|
||||
}
|
||||
return pathCop;
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
package cn.celess.blog.service.fileserviceimpl;
|
||||
|
||||
import cn.celess.blog.enmu.ConfigKeyEnum;
|
||||
import cn.celess.blog.entity.model.FileInfo;
|
||||
import cn.celess.blog.entity.model.FileResponse;
|
||||
import cn.celess.blog.service.FileManager;
|
||||
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.util.Auth;
|
||||
import com.qiniu.util.StringMap;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2019/04/25 18:15
|
||||
*/
|
||||
@Service("qiniuFileServiceImpl")
|
||||
public class QiniuFileServiceImpl implements FileManager {
|
||||
private static final Configuration cfg = new Configuration(Zone.zone2());
|
||||
private static UploadManager uploadManager;
|
||||
private static BucketManager bucketManager;
|
||||
private static Auth auth;
|
||||
|
||||
private String bucket;
|
||||
|
||||
/**
|
||||
* todo :: 添加reload 方法 配置修改重新创建对象
|
||||
*/
|
||||
private void init() {
|
||||
String accessKey = System.getProperty(ConfigKeyEnum.FILE_QINIU_ACCESS_KEY.getKey());
|
||||
String secretKey = System.getProperty(ConfigKeyEnum.FILE_QINIU_SECRET_KEY.getKey());
|
||||
this.bucket = System.getProperty(ConfigKeyEnum.FILE_QINIU_BUCKET.getKey());
|
||||
if (auth == null || uploadManager == null || bucketManager == null) {
|
||||
auth = Auth.create(accessKey, secretKey);
|
||||
uploadManager = new UploadManager(cfg);
|
||||
bucketManager = new BucketManager(auth, cfg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileResponse uploadFile(InputStream is, String fileName) {
|
||||
init();
|
||||
//文件存在则删除文件
|
||||
if (continueFile(fileName)) {
|
||||
try {
|
||||
System.out.println(bucketManager.delete(bucket, fileName).toString());
|
||||
} catch (QiniuException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//上传
|
||||
try {
|
||||
Response response = uploadManager.put(is, fileName, auth.uploadToken(bucket), null, null);
|
||||
FileResponse fileResponse = new FileResponse();
|
||||
StringMap stringMap = response.jsonToMap();
|
||||
|
||||
fileResponse.key = (String) stringMap.get("key");
|
||||
fileResponse.type = "qiniu";
|
||||
fileResponse.size = 0;
|
||||
fileResponse.hash = (String) stringMap.get("hash");
|
||||
|
||||
return fileResponse;
|
||||
} catch (QiniuException e) {
|
||||
Response r = e.response;
|
||||
System.err.println(r.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileInfo> getFileList() {
|
||||
init();
|
||||
List<FileInfo> infoList = null;
|
||||
BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(bucket, "", 1000, "");
|
||||
while (fileListIterator.hasNext()) {
|
||||
//处理获取的file list结果
|
||||
infoList = new ArrayList<com.qiniu.storage.model.FileInfo>(Arrays.asList(fileListIterator.next()))
|
||||
.stream()
|
||||
.map(item -> {
|
||||
FileInfo fileInfo = new FileInfo();
|
||||
fileInfo.key = item.key;
|
||||
fileInfo.hash = item.hash;
|
||||
fileInfo.size = item.fsize;
|
||||
fileInfo.uploadTime = item.putTime;
|
||||
return fileInfo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return infoList;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public boolean deleteFile(String fileName) {
|
||||
init();
|
||||
Response response = bucketManager.delete(bucket, fileName);
|
||||
return "".equals(response.bodyString());
|
||||
}
|
||||
|
||||
private boolean continueFile(String key) {
|
||||
List<FileInfo> fileList = getFileList();
|
||||
for (FileInfo fileInfo : fileList) {
|
||||
if (key.equals(fileInfo.key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -279,21 +279,20 @@ public class ArticleServiceImpl implements ArticleService {
|
||||
*/
|
||||
@Override
|
||||
public PageData<ArticleModel> adminArticles(int count, int page, Boolean deleted) {
|
||||
PageHelper.startPage(page, count);
|
||||
List<Article> articleList = articleMapper.findAll();
|
||||
|
||||
PageData<ArticleModel> pageData = new PageData<>(null, 0, count, page);
|
||||
PageData<ArticleModel> pageData = new PageData<>(new PageInfo<>(articleList));
|
||||
|
||||
List<Article> collect;
|
||||
if (deleted != null) {
|
||||
collect = articleList.stream().filter(article -> article.isDeleted() == deleted).collect(Collectors.toList());
|
||||
} else {
|
||||
collect = articleList;
|
||||
}
|
||||
pageData.setTotal(collect.size());
|
||||
List<ArticleModel> articleModels = collect.stream()
|
||||
.peek(article -> article.setMdContent(null))
|
||||
.map(ModalTrans::article)
|
||||
.skip((page - 1) * count)
|
||||
.limit(count)
|
||||
.collect(Collectors.toList());
|
||||
pageData.setList(articleModels);
|
||||
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
package cn.celess.blog.service.serviceimpl;
|
||||
|
||||
import cn.celess.blog.BlogApplication;
|
||||
import cn.celess.blog.enmu.ConfigKeyEnum;
|
||||
import cn.celess.blog.enmu.ResponseEnum;
|
||||
import cn.celess.blog.entity.Config;
|
||||
import cn.celess.blog.entity.InstallParam;
|
||||
import cn.celess.blog.entity.User;
|
||||
import cn.celess.blog.exception.MyException;
|
||||
import cn.celess.blog.mapper.ConfigMapper;
|
||||
import cn.celess.blog.mapper.UserMapper;
|
||||
import cn.celess.blog.service.InstallService;
|
||||
import cn.celess.blog.service.fileserviceimpl.LocalFileServiceImpl;
|
||||
import cn.celess.blog.util.MD5Util;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2020/10/23 16:23
|
||||
* @desc :
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class InstallServiceImpl implements InstallService {
|
||||
|
||||
public static final String MYSQL_DRIVER_CLASS_NAME = "com.mysql.cj.jdbc.Driver";
|
||||
public static final String H2_DRIVER_CLASS_NAME = "org.h2.Driver";
|
||||
|
||||
@Autowired
|
||||
ConfigMapper configMapper;
|
||||
@Autowired
|
||||
UserMapper userMapper;
|
||||
|
||||
@Override
|
||||
public Map<String, Object> isInstall() {
|
||||
Config installed = configMapper.getConfiguration(ConfigKeyEnum.BLOG_INSTALLED.getKey());
|
||||
Boolean isInstall = Boolean.valueOf(installed.getValue());
|
||||
Map<String, Object> result = new HashMap<>(3);
|
||||
result.put("is_install", isInstall);
|
||||
if (isInstall) {
|
||||
Map<String, String> configMap = configMapper.getConfigurations()
|
||||
.stream()
|
||||
.filter(config -> config.getValue() != null)
|
||||
.collect(Collectors.toMap(Config::getName, Config::getValue));
|
||||
result.put(ConfigKeyEnum.FILE_TYPE.getKey(), configMap.get(ConfigKeyEnum.FILE_TYPE.getKey()));
|
||||
result.put(ConfigKeyEnum.DB_TYPE.getKey(), configMap.get(ConfigKeyEnum.DB_TYPE.getKey()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Map<String, Object> install(@NotNull InstallParam installParam) {
|
||||
User user = new User(installParam.getEmail(), MD5Util.getMD5(installParam.getPassword()));
|
||||
userMapper.addUser(user);
|
||||
userMapper.setUserRole(user.getId(), "admin");
|
||||
|
||||
|
||||
Config install = configMapper.getConfiguration(ConfigKeyEnum.BLOG_INSTALLED.getKey());
|
||||
boolean isInstall = Boolean.parseBoolean(install.getValue());
|
||||
if (isInstall) {
|
||||
throw new MyException(ResponseEnum.FAILURE, "已经安装过了");
|
||||
}
|
||||
|
||||
Config config = new Config(ConfigKeyEnum.DB_TYPE);
|
||||
config.setValue(installParam.getDbType());
|
||||
Properties properties = new Properties();
|
||||
StringBuilder urlSb = new StringBuilder();
|
||||
if ("h2".equals(installParam.getDbType())) {
|
||||
properties.setProperty(ConfigKeyEnum.DB_DRIVER_CLASS_NAME.getKey(), H2_DRIVER_CLASS_NAME);
|
||||
urlSb.append("jdbc:h2:");
|
||||
} else {
|
||||
properties.setProperty(ConfigKeyEnum.DB_DRIVER_CLASS_NAME.getKey(), MYSQL_DRIVER_CLASS_NAME);
|
||||
urlSb.append("jdbc:mysql:");
|
||||
}
|
||||
// TODO ::
|
||||
urlSb.append(installParam.getDbHost()).append('/').append(installParam.getDbName());
|
||||
properties.setProperty(ConfigKeyEnum.DB_URL.getKey(), urlSb.toString());
|
||||
properties.setProperty(ConfigKeyEnum.DB_USERNAME.getKey(), installParam.getDbUsername());
|
||||
properties.setProperty(ConfigKeyEnum.DB_PASSWORD.getKey(), installParam.getDbPassword());
|
||||
|
||||
Config configuration = configMapper.getConfiguration(ConfigKeyEnum.BLOG_DB_PATH.getKey());
|
||||
|
||||
File file = new File(LocalFileServiceImpl.getPath(configuration.getValue()));
|
||||
if (!file.exists() && file.createNewFile()) {
|
||||
log.info("创建数据库配置文件: {}", file.getAbsolutePath());
|
||||
}
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
properties.load(fis);
|
||||
|
||||
configMapper.addConfiguration(config);
|
||||
properties.store(fos, "DB CONFIG");
|
||||
|
||||
install.setValue(Boolean.valueOf(true).toString());
|
||||
configMapper.updateConfiguration(install);
|
||||
|
||||
log.info("重启...");
|
||||
|
||||
// 重启
|
||||
BlogApplication.restart();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package cn.celess.blog.service.serviceimpl;
|
||||
|
||||
import cn.celess.blog.entity.model.QiniuResponse;
|
||||
import cn.celess.blog.service.QiniuService;
|
||||
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.model.FileInfo;
|
||||
import com.qiniu.util.Auth;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
* @date : 2019/04/25 18:15
|
||||
*/
|
||||
@Service
|
||||
public class QiniuServiceImpl implements QiniuService {
|
||||
private static final Configuration cfg = new Configuration(Zone.zone2());
|
||||
private static UploadManager uploadManager;
|
||||
private static BucketManager bucketManager;
|
||||
private static Auth auth;
|
||||
|
||||
@Value("${qiniu.accessKey}")
|
||||
private String accessKey;
|
||||
@Value("${qiniu.secretKey}")
|
||||
private String secretKey;
|
||||
@Value("${qiniu.bucket}")
|
||||
private String bucket;
|
||||
|
||||
private void init() {
|
||||
if (auth == null || uploadManager == null || bucketManager == null) {
|
||||
auth = Auth.create(accessKey, secretKey);
|
||||
uploadManager = new UploadManager(cfg);
|
||||
bucketManager = new BucketManager(auth, cfg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public QiniuResponse uploadFile(InputStream is, String fileName) {
|
||||
init();
|
||||
//文件存在则删除文件
|
||||
if (continueFile(fileName)) {
|
||||
try {
|
||||
System.out.println(bucketManager.delete(bucket, fileName).toString());
|
||||
} catch (QiniuException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//上传
|
||||
try {
|
||||
Response response = uploadManager.put(is, fileName, auth.uploadToken(bucket), null, null);
|
||||
return response.jsonToObject(QiniuResponse.class);
|
||||
} catch (QiniuException e) {
|
||||
Response r = e.response;
|
||||
System.err.println(r.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileInfo[] getFileList() {
|
||||
init();
|
||||
BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(bucket, "", 1000, "");
|
||||
FileInfo[] items = null;
|
||||
while (fileListIterator.hasNext()) {
|
||||
//处理获取的file list结果
|
||||
items = fileListIterator.next();
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private boolean continueFile(String key) {
|
||||
FileInfo[] allFile = getFileList();
|
||||
for (FileInfo fileInfo : allFile) {
|
||||
if (key.equals(fileInfo.key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -5,15 +5,15 @@ import cn.celess.blog.enmu.RoleEnum;
|
||||
import cn.celess.blog.enmu.UserAccountStatusEnum;
|
||||
import cn.celess.blog.entity.Response;
|
||||
import cn.celess.blog.entity.User;
|
||||
import cn.celess.blog.entity.model.FileResponse;
|
||||
import cn.celess.blog.entity.model.PageData;
|
||||
import cn.celess.blog.entity.model.QiniuResponse;
|
||||
import cn.celess.blog.entity.model.UserModel;
|
||||
import cn.celess.blog.entity.request.LoginReq;
|
||||
import cn.celess.blog.entity.request.UserReq;
|
||||
import cn.celess.blog.exception.MyException;
|
||||
import cn.celess.blog.mapper.UserMapper;
|
||||
import cn.celess.blog.service.FileService;
|
||||
import cn.celess.blog.service.MailService;
|
||||
import cn.celess.blog.service.QiniuService;
|
||||
import cn.celess.blog.service.UserService;
|
||||
import cn.celess.blog.util.*;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
@@ -24,7 +24,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.beans.Transient;
|
||||
import java.io.InputStream;
|
||||
@@ -46,8 +45,8 @@ public class UserServiceImpl implements UserService {
|
||||
HttpServletRequest request;
|
||||
@Autowired
|
||||
MailService mailService;
|
||||
@Resource(name = "fileServiceImpl")
|
||||
FileService fileService;
|
||||
@Autowired
|
||||
QiniuService qiniuService;
|
||||
@Autowired
|
||||
RedisUtil redisUtil;
|
||||
@Autowired
|
||||
@@ -186,7 +185,7 @@ public class UserServiceImpl implements UserService {
|
||||
@Override
|
||||
public Object updateUserAavatarImg(InputStream is, String mime) {
|
||||
User user = redisUserUtil.get();
|
||||
FileResponse upload = fileService.getFileManager().uploadFile(is, user.getEmail() + "_" + user.getId() + mime.toLowerCase());
|
||||
QiniuResponse upload = qiniuService.uploadFile(is, user.getEmail() + "_" + user.getId() + mime.toLowerCase());
|
||||
user.setAvatarImgUrl(upload.key);
|
||||
userMapper.updateAvatarImgUrl(upload.key, user.getId());
|
||||
redisUserUtil.set(user);
|
||||
|
||||
51
src/main/java/cn/celess/blog/util/EnvironmentUtil.java
Normal file
51
src/main/java/cn/celess/blog/util/EnvironmentUtil.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package cn.celess.blog.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* <p>date: 2022/12/02</P>
|
||||
* <p>desc: </p>
|
||||
* <p>mail: a@celess.cn</p>
|
||||
*
|
||||
* @author 禾几海
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class EnvironmentUtil {
|
||||
|
||||
private static Environment environment;
|
||||
|
||||
public static String getEnv(String name) {
|
||||
String value = System.getenv(name);
|
||||
if (StringUtils.isBlank(value)) {
|
||||
log.error("没有找到环境变量:" + name);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static String getEnv(String name, String defaultValue) {
|
||||
String env = getEnv(name);
|
||||
if (env == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
public static String getProperties(String key) {
|
||||
String value = environment.getProperty(key);
|
||||
if (StringUtils.isBlank(value)) {
|
||||
log.error("没有找到配置项: {}", key);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static String getProperties(String key, String defaultValue) {
|
||||
return environment.getProperty(key, defaultValue);
|
||||
}
|
||||
|
||||
public static void setEnvironment(Environment environment) {
|
||||
EnvironmentUtil.environment = environment;
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,8 @@ public class JwtUtil {
|
||||
*/
|
||||
public static final long EXPIRATION_SHORT_TIME = 7200000;
|
||||
private static final String CLAIM_KEY_USERNAME = "sub";
|
||||
private static final String BEARER_PREFIX_UPPER = "Bearer";
|
||||
private static final String BEARER_PREFIX_LOWER = "bearer";
|
||||
/**
|
||||
* JWT 秘钥需自行设置不可泄露
|
||||
*/
|
||||
@@ -48,7 +50,7 @@ public class JwtUtil {
|
||||
}
|
||||
|
||||
public String updateTokenDate(String token) {
|
||||
Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
|
||||
Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(getJwtString(token)).getBody();
|
||||
return Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.setExpiration(new Date(claims.getExpiration().getTime() + EXPIRATION_SHORT_TIME))
|
||||
@@ -60,7 +62,7 @@ public class JwtUtil {
|
||||
* 获取token是否过期
|
||||
*/
|
||||
public Boolean isTokenExpired(String token) {
|
||||
Date expiration = getExpirationDateFromToken(token);
|
||||
Date expiration = getExpirationDateFromToken(getJwtString(token));
|
||||
return expiration == null || expiration.before(new Date());
|
||||
}
|
||||
|
||||
@@ -68,7 +70,7 @@ public class JwtUtil {
|
||||
* 根据token获取username
|
||||
*/
|
||||
public String getUsernameFromToken(String token) {
|
||||
Claims claims = getClaimsFromToken(token);
|
||||
Claims claims = getClaimsFromToken(getJwtString(token));
|
||||
return claims == null ? null : claims.getSubject();
|
||||
}
|
||||
|
||||
@@ -76,7 +78,7 @@ public class JwtUtil {
|
||||
* 获取token的过期时间
|
||||
*/
|
||||
public Date getExpirationDateFromToken(String token) {
|
||||
Claims claims = getClaimsFromToken(token);
|
||||
Claims claims = getClaimsFromToken(getJwtString(token));
|
||||
return claims == null ? null : claims.getExpiration();
|
||||
}
|
||||
|
||||
@@ -88,7 +90,7 @@ public class JwtUtil {
|
||||
try {
|
||||
claims = Jwts.parser()
|
||||
.setSigningKey(SECRET)
|
||||
.parseClaimsJws(token)
|
||||
.parseClaimsJws(getJwtString(token))
|
||||
.getBody();
|
||||
} catch (ExpiredJwtException e) {
|
||||
log.info("JWT令牌过期");
|
||||
@@ -107,4 +109,9 @@ public class JwtUtil {
|
||||
return claims;
|
||||
}
|
||||
|
||||
private String getJwtString(String token) {
|
||||
if (token == null) return token;
|
||||
return token.replaceFirst(BEARER_PREFIX_UPPER, "").replace(BEARER_PREFIX_LOWER, "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
2
src/main/resources/META-INF/spring.factories
Normal file
2
src/main/resources/META-INF/spring.factories
Normal file
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.env.EnvironmentPostProcessor=cn.celess.blog.configuration.CommonEnvPostProcessor
|
||||
org.springframework.context.ApplicationListener=cn.celess.blog.configuration.CommonEnvPostProcessor
|
||||
@@ -1,65 +0,0 @@
|
||||
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
|
||||
spring.datasource.url=jdbc:h2:~/blog/db
|
||||
spring.datasource.driver-class-name=org.h2.Driver
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=sa
|
||||
|
||||
spring.datasource.platform=h2
|
||||
spring.datasource.sql-script-encoding=utf-8
|
||||
spring.datasource.initialization-mode=never
|
||||
spring.datasource.schema=classpath:sql/schema-h2.sql
|
||||
spring.datasource.data=classpath:sql/data.sql
|
||||
|
||||
spring.h2.console.path=/h2-console
|
||||
spring.h2.console.enabled=true
|
||||
|
||||
# 生成JWT时候的密钥
|
||||
jwt.secret=11111222223333444455556667778888
|
||||
# sitemap 存放地址
|
||||
sitemap.path=/www/wwwroot/celess.cn/sitemap.xml
|
||||
|
||||
|
||||
############### email ##############
|
||||
spring.mail.host=smtp.163.com
|
||||
spring.mail.username=
|
||||
spring.mail.password=
|
||||
spring.mail.properties.mail.smtp.auth=true
|
||||
spring.mail.properties.mail.smtp.starttls.enable=true
|
||||
spring.mail.properties.mail.smtp.starttls.required=true
|
||||
spring.mail.default-encoding=UTF-8
|
||||
spring.mail.port=465
|
||||
spring.mail.properties.mail.smtp.socketFactory.port=465
|
||||
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
|
||||
spring.mail.properties.mail.smtp.socketFactory.fallback=false
|
||||
|
||||
################## mybatis ##################
|
||||
mybatis.mapper-locations=classpath:mapper/*.xml
|
||||
mybatis.type-aliases-package=cn.celess.blog.entity
|
||||
|
||||
|
||||
pagehelper.helper-dialect=mysql
|
||||
pagehelper.reasonable=true
|
||||
pagehelper.support-methods-arguments=true
|
||||
pagehelper.params=count=countSql
|
||||
|
||||
############### redis ##############
|
||||
# REDIS (RedisProperties)
|
||||
# Redis数据库索引(默认为0)
|
||||
spring.redis.database=1
|
||||
# Redis服务器地址
|
||||
spring.redis.host=127.0.0.1
|
||||
# Redis服务器连接端口 解决端口冲突 防止使用本地的redis
|
||||
spring.redis.port=6379
|
||||
# Redis服务器连接密码(默认为空)
|
||||
spring.redis.password=
|
||||
# 连接池最大连接数(使用负值表示没有限制)
|
||||
spring.redis.jedis.pool.max-active=-1
|
||||
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
spring.redis.jedis.pool.max-wait=-1
|
||||
# 连接池中的最大空闲连接
|
||||
spring.redis.jedis.pool.max-idle=8
|
||||
# 连接池中的最小空闲连接
|
||||
spring.redis.jedis.pool.min-idle=0
|
||||
# 连接超时时间(毫秒)
|
||||
spring.redis.timeout=5000
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
server.port=8081
|
||||
|
||||
# 七牛的密钥配置
|
||||
file.qiniu.accessKey=
|
||||
file.qiniu.secretKey=
|
||||
file.qiniu.bucket=
|
||||
# sitemap 存放地址
|
||||
# ???????
|
||||
qiniu.accessKey=
|
||||
qiniu.secretKey=
|
||||
qiniu.bucket=
|
||||
# sitemap ????
|
||||
sitemap.path=
|
||||
# 生成JWT时候的密钥
|
||||
# ??JWT?????
|
||||
jwt.secret=
|
||||
|
||||
spring.jpa.show-sql=false
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
# 上传单个文件的大小
|
||||
# ?????????
|
||||
spring.servlet.multipart.max-file-size=10MB
|
||||
# 上传文件的总大小
|
||||
# ????????
|
||||
spring.servlet.multipart.max-request-size=10MB
|
||||
##null字段不显示
|
||||
##null?????
|
||||
spring.jackson.default-property-inclusion=non_null
|
||||
|
||||
|
||||
################# 数据库 ##################
|
||||
#请先填写下面的配置
|
||||
################# ??? ##################
|
||||
#?????????
|
||||
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
|
||||
spring.datasource.url=
|
||||
spring.datasource.username=
|
||||
@@ -48,7 +48,7 @@ pagehelper.params=count=countSql
|
||||
|
||||
|
||||
################ email ##############
|
||||
#请先填写下面的配置,不然可能运行不起来
|
||||
#???????????????????
|
||||
spring.mail.host=
|
||||
spring.mail.username=
|
||||
spring.mail.password=
|
||||
@@ -62,23 +62,29 @@ spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFact
|
||||
spring.mail.properties.mail.smtp.socketFactory.fallback=false
|
||||
|
||||
|
||||
#### ??nginx??? ????ip
|
||||
server.use-forward-headers = true
|
||||
server.tomcat.remote-ip-header = X-Real-IP
|
||||
server.tomcat.protocol-header = X-Forwarded-Proto
|
||||
|
||||
|
||||
############### redis ##############
|
||||
# REDIS (RedisProperties)
|
||||
# Redis数据库索引(默认为0)
|
||||
# Redis?????????0?
|
||||
spring.redis.database=0
|
||||
# Redis服务器地址
|
||||
# Redis?????
|
||||
spring.redis.host=
|
||||
# Redis服务器连接端口
|
||||
# Redis???????
|
||||
spring.redis.port=6379
|
||||
# Redis服务器连接密码(默认为空)
|
||||
# Redis?????????????
|
||||
spring.redis.password=
|
||||
# 连接池最大连接数(使用负值表示没有限制)
|
||||
# ????????????????????
|
||||
spring.redis.jedis.pool.max-active=-1
|
||||
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
# ???????????????????????
|
||||
spring.redis.jedis.pool.max-wait=-1
|
||||
# 连接池中的最大空闲连接
|
||||
# ???????????
|
||||
spring.redis.jedis.pool.max-idle=8
|
||||
# 连接池中的最小空闲连接
|
||||
# ???????????
|
||||
spring.redis.jedis.pool.min-idle=0
|
||||
# 连接超时时间(毫秒)
|
||||
# ??????????
|
||||
spring.redis.timeout=5000
|
||||
@@ -1,12 +1,12 @@
|
||||
server.port=8081
|
||||
|
||||
# 七牛的密钥配置
|
||||
file.qiniu.accessKey=${QINIU_ACCESSKEY:null}
|
||||
file.qiniu.secretKey=${QINIU_SECRETKEY:null}
|
||||
file.qiniu.bucket=xiaohai
|
||||
# sitemap 存放地址
|
||||
# ???????
|
||||
qiniu.accessKey=
|
||||
qiniu.secretKey=
|
||||
qiniu.bucket=
|
||||
# sitemap ????
|
||||
sitemap.path=
|
||||
# 生成JWT时候的密钥
|
||||
# ??JWT?????
|
||||
jwt.secret=sdaniod213k123123ipoeqowekqwe
|
||||
|
||||
##spring.jpa.show-sql=false
|
||||
@@ -14,15 +14,15 @@ jwt.secret=sdaniod213k123123ipoeqowekqwe
|
||||
|
||||
mybatis.type-handlers-package=cn.celess.blog.mapper.typehandler
|
||||
logging.level.cn.celess.blog.mapper=debug
|
||||
# 上传单个文件的大小
|
||||
# ?????????
|
||||
spring.servlet.multipart.max-file-size=10MB
|
||||
# 上传文件的总大小
|
||||
# ????????
|
||||
spring.servlet.multipart.max-request-size=10MB
|
||||
|
||||
spring.jackson.default-property-inclusion=non_null
|
||||
|
||||
|
||||
################# 数据库 ##################
|
||||
################# ??? ##################
|
||||
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
|
||||
|
||||
#h2
|
||||
@@ -32,9 +32,10 @@ spring.datasource.username=sa
|
||||
spring.datasource.password=
|
||||
|
||||
|
||||
spring.datasource.platform=h2
|
||||
spring.datasource.sql-script-encoding=utf-8
|
||||
spring.datasource.initialization-mode=ALWAYS
|
||||
spring.datasource.schema=classpath:sql/schema-h2.sql
|
||||
spring.datasource.schema=classpath:sql/schema_h2.sql
|
||||
spring.datasource.data=classpath:sql/data.sql
|
||||
|
||||
|
||||
@@ -49,6 +50,13 @@ pagehelper.support-methods-arguments=true
|
||||
pagehelper.params=count=countSql
|
||||
|
||||
|
||||
|
||||
#### ??nginx??? ????ip
|
||||
server.use-forward-headers = true
|
||||
server.tomcat.remote-ip-header = X-Real-IP
|
||||
server.tomcat.protocol-header = X-Forwarded-Proto
|
||||
|
||||
|
||||
############### email ##############
|
||||
spring.mail.host=smtp.163.com
|
||||
spring.mail.username=
|
||||
@@ -67,22 +75,21 @@ spring.mail.properties.mail.smtp.socketFactory.fallback=false
|
||||
############### redis ##############
|
||||
|
||||
# REDIS (RedisProperties)
|
||||
# Redis数据库索引(默认为0)
|
||||
# Redis?????????0?
|
||||
spring.redis.database=1
|
||||
# Redis服务器地址
|
||||
# Redis?????
|
||||
spring.redis.host=127.0.0.1
|
||||
# Redis服务器连接端口 解决端口冲突 防止使用本地的redis
|
||||
# Redis??????? ?????? ???????redis
|
||||
spring.redis.port=6380
|
||||
# Redis服务器连接密码(默认为空)
|
||||
# Redis?????????????
|
||||
spring.redis.password=
|
||||
# 连接池最大连接数(使用负值表示没有限制)
|
||||
# ????????????????????
|
||||
spring.redis.jedis.pool.max-active=-1
|
||||
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
# ???????????????????????
|
||||
spring.redis.jedis.pool.max-wait=-1
|
||||
# 连接池中的最大空闲连接
|
||||
# ???????????
|
||||
spring.redis.jedis.pool.max-idle=8
|
||||
# 连接池中的最小空闲连接
|
||||
# ???????????
|
||||
spring.redis.jedis.pool.min-idle=0
|
||||
# 连接超时时间(毫秒)
|
||||
spring.redis.timeout=5000
|
||||
|
||||
# ??????????
|
||||
spring.redis.timeout=5000
|
||||
@@ -1,10 +1,7 @@
|
||||
spring.profiles.active=easyDeploy
|
||||
spring.profiles.active=dev
|
||||
#### ?????
|
||||
####cn.celess.blog.service.serviceimpl.QiniuServiceImpl
|
||||
logging.level.cn.celess.blog=debug
|
||||
logging.level.cn.celess.blog.mapper=info
|
||||
|
||||
#### 用于nginx的代理 获取真实ip
|
||||
server.use-forward-headers = true
|
||||
server.tomcat.remote-ip-header = X-Real-IP
|
||||
server.tomcat.protocol-header = X-Forwarded-Proto
|
||||
|
||||
## 修改openSource 添加-test 文件用于测试 -prod文件用于线上发布
|
||||
## ??openSource ??-test ?????? -prod????????
|
||||
@@ -64,6 +64,14 @@
|
||||
and article_tag.t_id = tag_category.t_id
|
||||
</select>
|
||||
|
||||
<select id="findTagByArticleId" resultMap="cn.celess.blog.mapper.TagMapper.tagResultMap">
|
||||
select tag_category.*
|
||||
from article_tag,
|
||||
tag_category
|
||||
where a_id = #{articleId}
|
||||
and article_tag.t_id = tag_category.t_id
|
||||
</select>
|
||||
|
||||
<select id="findOneById" resultMap="articleTagResultMap">
|
||||
select *
|
||||
from article_tag,
|
||||
@@ -98,4 +106,4 @@
|
||||
and article_tag.a_id = article.a_id
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
</mapper>
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.celess.blog.mapper.ConfigMapper">
|
||||
|
||||
<resultMap type="cn.celess.blog.entity.Config" id="ConfigMap">
|
||||
<result property="id" column="conf_id" jdbcType="INTEGER"/>
|
||||
<result property="name" column="conf_name" jdbcType="VARCHAR"/>
|
||||
<result property="value" column="conf_value" jdbcType="VARCHAR"/>
|
||||
</resultMap>
|
||||
|
||||
<!--查询单个-->
|
||||
<select id="getConfiguration" resultMap="ConfigMap">
|
||||
select conf_id,
|
||||
conf_name,
|
||||
conf_value
|
||||
from config
|
||||
where conf_name = #{key}
|
||||
</select>
|
||||
|
||||
<!--查询指定行数据-->
|
||||
<select id="getConfigurations" resultMap="ConfigMap">
|
||||
select conf_id,
|
||||
conf_name,
|
||||
conf_value
|
||||
from config
|
||||
</select>
|
||||
|
||||
|
||||
<!--新增所有列-->
|
||||
<insert id="addConfiguration" keyProperty="id" useGeneratedKeys="true">
|
||||
insert into config(conf_name, conf_value)
|
||||
values (#{name}, #{value})
|
||||
</insert>
|
||||
|
||||
|
||||
<!--通过主键修改数据-->
|
||||
<update id="updateConfiguration">
|
||||
update config
|
||||
set conf_value = #{value}
|
||||
where conf_id = #{id}
|
||||
</update>
|
||||
|
||||
<!--通过主键删除-->
|
||||
<delete id="deleteConfiguration">
|
||||
delete
|
||||
from config
|
||||
where conf_id = #{id}
|
||||
</delete>
|
||||
|
||||
</mapper>
|
||||
@@ -1,185 +1,242 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="cn.celess.blog.mapper.ArticleMapper">
|
||||
<resultMap id="articleResultMap" type="cn.celess.blog.entity.Article">
|
||||
<id column="a_id" property="id"/>
|
||||
<result column="a_title" property="title"/>
|
||||
<result column="a_summary" property="summary"/>
|
||||
<result column="a_md_content" property="mdContent"/>
|
||||
<result column="a_url" property="url"/>
|
||||
<result column="a_author_id" property="user.id"/>
|
||||
<result column="a_is_open" property="open"/>
|
||||
<result column="a_is_original" property="type"/>
|
||||
<!-- <result column="next_a_id" property="nextArticleId"/>-->
|
||||
<!-- <result column="pre_a_id" property="preArticleId"/>-->
|
||||
<result column="a_reading_number" property="readingNumber"/>
|
||||
<result column="a_publish_date" property="publishDate"/>
|
||||
<result column="a_update_date" property="updateDate"/>
|
||||
<result column="is_delete" property="deleted"/>
|
||||
<association property="category" column="a_category_id" javaType="cn.celess.blog.entity.TagCategory"
|
||||
resultMap="cn.celess.blog.mapper.CategoryMapper.categoryResultMap">
|
||||
</association>
|
||||
<collection property="tags" ofType="cn.celess.blog.entity.TagCategory"
|
||||
resultMap="cn.celess.blog.mapper.CategoryMapper.categoryResultMap">
|
||||
</collection>
|
||||
</resultMap>
|
||||
|
||||
|
||||
<resultMap id="articleViewResultMap" type="cn.celess.blog.entity.Article">
|
||||
<id column="articleId" property="id"/>
|
||||
<result column="title" property="title"/>
|
||||
<result column="summary" property="summary"/>
|
||||
<result column="mdContent" property="mdContent"/>
|
||||
<result column="url" property="url"/>
|
||||
<result column="isOpen" property="open"/>
|
||||
<result column="isOriginal" property="type"/>
|
||||
<result column="likeCount" property="likeCount"/>
|
||||
<result column="dislikeCount" property="dislikeCount"/>
|
||||
<result column="readingCount" property="readingNumber"/>
|
||||
<result column="publishDate" property="publishDate"/>
|
||||
<result column="updateDate" property="updateDate"/>
|
||||
<result column="isDelete" property="deleted"/>
|
||||
<association property="category" column="categoryId" javaType="cn.celess.blog.entity.Category">
|
||||
<id column="categoryId" property="id"/>
|
||||
<result column="categoryName" property="name"/>
|
||||
</association>
|
||||
<association property="user" column="authorId" javaType="cn.celess.blog.entity.User">
|
||||
<id column="authorId" property="id"/>
|
||||
<result column="userEmail" property="email"/>
|
||||
<result column="userAvatar" property="avatarImgUrl"/>
|
||||
<result column="userDisplayName" property="displayName"/>
|
||||
</association>
|
||||
<collection property="tags" ofType="cn.celess.blog.entity.Tag">
|
||||
<id column="tagId" property="id"/>
|
||||
<result column="tagName" property="name"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<insert id="insert" useGeneratedKeys="true" keyProperty="id" parameterType="cn.celess.blog.entity.Article">
|
||||
insert into article (a_author_id, a_category_id, a_md_content, a_is_original,
|
||||
a_summary, a_title, a_url)
|
||||
values (#{user.id}, #{category.id}, #{mdContent}, #{type}, #{summary}, #{title}, #{url})
|
||||
</insert>
|
||||
<update id="delete">
|
||||
update article
|
||||
set is_delete = true
|
||||
where a_id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="update">
|
||||
update article
|
||||
set a_update_date=now(),
|
||||
<if test="title!=null">a_title=#{title},</if>
|
||||
<if test="mdContent!=null">a_md_content=#{mdContent},</if>
|
||||
<if test="summary!=null">a_summary=#{summary},</if>
|
||||
<if test="type!=null">a_is_original=#{type},</if>
|
||||
<if test="url!=null">a_url=#{url},</if>
|
||||
<if test="category!=null">a_category_id=#{category.id},</if>
|
||||
<if test="open!=null">a_is_open=#{open}</if>
|
||||
where a_id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="updateReadingNumber">
|
||||
update article
|
||||
set a_reading_number=a_reading_number + 1
|
||||
where a_id = #{id}
|
||||
</update>
|
||||
|
||||
<select id="getLastestArticle" resultMap="articleViewResultMap" resultType="cn.celess.blog.entity.Article">
|
||||
select *
|
||||
from articleView
|
||||
order by articleId desc
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
|
||||
<select id="findArticleById" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where articleId = #{id}
|
||||
</select>
|
||||
|
||||
<select id="existsByTitle" resultType="boolean">
|
||||
SELECT EXISTS(SELECT * FROM article WHERE a_title = #{title})
|
||||
</select>
|
||||
|
||||
<select id="isDeletedById" resultType="boolean">
|
||||
select is_delete
|
||||
from article
|
||||
WHERE a_id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="findAllByAuthorId" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where authorId = #{authorId}
|
||||
and isDelete = false
|
||||
order by articleId desc
|
||||
</select>
|
||||
|
||||
<select id="findAllByOpen" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where isOpen = #{isOpen}
|
||||
and isDelete = false
|
||||
order by articleId desc
|
||||
</select>
|
||||
|
||||
|
||||
<select id="getTitleById" resultType="string">
|
||||
SELECT title
|
||||
from articleView
|
||||
where articleId = #{id}
|
||||
</select>
|
||||
|
||||
<select id="findAllByCategoryId" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where categoryId = #{id}
|
||||
and isDelete = false
|
||||
order by articleId desc
|
||||
</select>
|
||||
|
||||
<select id="findAllByCategoryIdAndOpen" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where categoryId = #{id}
|
||||
and isDelete = false
|
||||
and isOpen = true
|
||||
order by articleId desc
|
||||
</select>
|
||||
|
||||
|
||||
<select id="findAll" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
order by articleId desc
|
||||
</select>
|
||||
|
||||
|
||||
<select id="count" resultType="long">
|
||||
select count(*)
|
||||
from article
|
||||
where is_delete = false;
|
||||
</select>
|
||||
|
||||
<select id="getPreArticle" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where articleId = (select max(articleId)
|
||||
from articleView
|
||||
where articleId < #{id}
|
||||
)
|
||||
</select>
|
||||
<select id="getNextArticle" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where articleId = (select min(articleId)
|
||||
from articleView
|
||||
where articleId > #{id}
|
||||
)
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="cn.celess.blog.mapper.ArticleMapper">
|
||||
<resultMap id="articleResultMap" type="cn.celess.blog.entity.Article">
|
||||
<id column="a_id" property="id"/>
|
||||
<result column="a_title" property="title"/>
|
||||
<result column="a_summary" property="summary"/>
|
||||
<result column="a_md_content" property="mdContent"/>
|
||||
<result column="a_url" property="url"/>
|
||||
<result column="a_author_id" property="user.id"/>
|
||||
<result column="a_is_open" property="open"/>
|
||||
<result column="a_is_original" property="type"/>
|
||||
<!-- <result column="next_a_id" property="nextArticleId"/>-->
|
||||
<!-- <result column="pre_a_id" property="preArticleId"/>-->
|
||||
<result column="a_reading_number" property="readingNumber"/>
|
||||
<result column="a_publish_date" property="publishDate"/>
|
||||
<result column="a_update_date" property="updateDate"/>
|
||||
<result column="is_delete" property="deleted"/>
|
||||
<association property="category" column="a_category_id" javaType="cn.celess.blog.entity.TagCategory"
|
||||
resultMap="cn.celess.blog.mapper.CategoryMapper.categoryResultMap">
|
||||
</association>
|
||||
<collection property="tags" ofType="cn.celess.blog.entity.Tag"
|
||||
select="cn.celess.blog.mapper.ArticleTagMapper.findTagByArticleId" column="a_id">
|
||||
<id column="tagId" property="id"/>
|
||||
<result column="tagName" property="name"/>
|
||||
</collection>
|
||||
</resultMap>
|
||||
|
||||
|
||||
<resultMap id="articleViewResultMap" type="cn.celess.blog.entity.Article">
|
||||
<id column="articleId" property="id"/>
|
||||
<result column="title" property="title"/>
|
||||
<result column="summary" property="summary"/>
|
||||
<result column="mdContent" property="mdContent"/>
|
||||
<result column="url" property="url"/>
|
||||
<result column="isOpen" property="open"/>
|
||||
<result column="isOriginal" property="type"/>
|
||||
<result column="likeCount" property="likeCount"/>
|
||||
<result column="dislikeCount" property="dislikeCount"/>
|
||||
<result column="readingCount" property="readingNumber"/>
|
||||
<result column="publishDate" property="publishDate"/>
|
||||
<result column="updateDate" property="updateDate"/>
|
||||
<result column="isDelete" property="deleted"/>
|
||||
<association property="category" column="categoryId" javaType="cn.celess.blog.entity.Category">
|
||||
<id column="categoryId" property="id"/>
|
||||
<result column="categoryName" property="name"/>
|
||||
</association>
|
||||
<association property="user" column="authorId" javaType="cn.celess.blog.entity.User">
|
||||
<id column="authorId" property="id"/>
|
||||
<result column="userEmail" property="email"/>
|
||||
<result column="userAvatar" property="avatarImgUrl"/>
|
||||
<result column="userDisplayName" property="displayName"/>
|
||||
</association>
|
||||
<collection property="tags" ofType="cn.celess.blog.entity.Tag"
|
||||
select="cn.celess.blog.mapper.ArticleTagMapper.findTagByArticleId" column="{articleId=articleId}">
|
||||
<id column="tagId" property="id"/>
|
||||
<result column="tagName" property="name"/>
|
||||
</collection>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<insert id="insert" useGeneratedKeys="true" keyProperty="id" parameterType="cn.celess.blog.entity.Article">
|
||||
insert into article (a_author_id, a_category_id, a_md_content, a_is_original,
|
||||
a_summary, a_title, a_url)
|
||||
values (#{user.id}, #{category.id}, #{mdContent}, #{type}, #{summary}, #{title}, #{url})
|
||||
</insert>
|
||||
<update id="delete">
|
||||
update article
|
||||
set is_delete = true
|
||||
where a_id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="update">
|
||||
update article
|
||||
set a_update_date=now(),
|
||||
<if test="title!=null">a_title=#{title},</if>
|
||||
<if test="mdContent!=null">a_md_content=#{mdContent},</if>
|
||||
<if test="summary!=null">a_summary=#{summary},</if>
|
||||
<if test="type!=null">a_is_original=#{type},</if>
|
||||
<if test="url!=null">a_url=#{url},</if>
|
||||
<if test="category!=null">a_category_id=#{category.id},</if>
|
||||
<if test="open!=null">a_is_open=#{open}</if>
|
||||
where a_id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="updateReadingNumber">
|
||||
update article
|
||||
set a_reading_number=a_reading_number + 1
|
||||
where a_id = #{id}
|
||||
</update>
|
||||
|
||||
<select id="getLastestArticle" resultMap="articleViewResultMap" resultType="cn.celess.blog.entity.Article">
|
||||
select *
|
||||
from articleView
|
||||
order by articleId desc
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
|
||||
<select id="findArticleById" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where articleId = #{id}
|
||||
</select>
|
||||
|
||||
<select id="existsByTitle" resultType="boolean">
|
||||
SELECT EXISTS(SELECT * FROM article WHERE a_title = #{title})
|
||||
</select>
|
||||
|
||||
<select id="isDeletedById" resultType="boolean">
|
||||
select is_delete
|
||||
from article
|
||||
WHERE a_id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="findAllByAuthorId" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where authorId = #{authorId}
|
||||
and isDelete = false
|
||||
order by articleId desc
|
||||
</select>
|
||||
|
||||
<select id="findAllByOpen" resultMap="articleViewResultMap">
|
||||
select article.a_id as articleId,
|
||||
article.a_title as title,
|
||||
article.a_summary as summary,
|
||||
article.a_md_content as mdContent,
|
||||
article.a_url as url,
|
||||
article.a_is_original as isOriginal,
|
||||
article.a_reading_number as readingCount,
|
||||
article.a_like as likeCount,
|
||||
article.a_dislike as dislikeCount,
|
||||
article.a_publish_date as publishDate,
|
||||
article.a_update_date as updateDate,
|
||||
article.a_is_open as isOpen,
|
||||
category.t_id as categoryId,
|
||||
category.t_name as categoryName,
|
||||
user.u_id as authorId,
|
||||
user.u_email as userEmail,
|
||||
user.u_avatar as userAvatar,
|
||||
user.u_display_name as userDisplayName,
|
||||
article.is_delete as isDelete
|
||||
from article,
|
||||
tag_category as category,
|
||||
article_tag,
|
||||
user
|
||||
where article.a_is_open = #{isOpen}
|
||||
and article.is_delete = false
|
||||
and article.a_id = article_tag.a_id
|
||||
and article.a_category_id = category.t_id
|
||||
and category.is_category = true
|
||||
and article.a_author_id = user.u_id
|
||||
group by article.a_id
|
||||
order by article.a_id desc
|
||||
</select>
|
||||
|
||||
|
||||
<select id="getTitleById" resultType="string">
|
||||
SELECT title
|
||||
from articleView
|
||||
where articleId = #{id}
|
||||
</select>
|
||||
|
||||
<select id="findAllByCategoryId" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where categoryId = #{id}
|
||||
and isDelete = false
|
||||
order by articleId desc
|
||||
</select>
|
||||
|
||||
<select id="findAllByCategoryIdAndOpen" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where categoryId = #{id}
|
||||
and isDelete = false
|
||||
and isOpen = true
|
||||
order by articleId desc
|
||||
</select>
|
||||
|
||||
|
||||
<select id="findAll" resultMap="articleViewResultMap">
|
||||
select article.a_id as articleId,
|
||||
article.a_title as title,
|
||||
article.a_summary as summary,
|
||||
article.a_md_content as mdContent,
|
||||
article.a_url as url,
|
||||
article.a_is_original as isOriginal,
|
||||
article.a_reading_number as readingCount,
|
||||
article.a_like as likeCount,
|
||||
article.a_dislike as dislikeCount,
|
||||
article.a_publish_date as publishDate,
|
||||
article.a_update_date as updateDate,
|
||||
article.a_is_open as isOpen,
|
||||
category.t_id as categoryId,
|
||||
category.t_name as categoryName,
|
||||
user.u_id as authorId,
|
||||
user.u_email as userEmail,
|
||||
user.u_avatar as userAvatar,
|
||||
user.u_display_name as userDisplayName,
|
||||
article.is_delete as isDelete
|
||||
from article,
|
||||
tag_category as category,
|
||||
article_tag,
|
||||
user
|
||||
where article.a_id = article_tag.a_id
|
||||
and article.a_category_id = category.t_id
|
||||
and category.is_category = true
|
||||
and article.a_author_id = user.u_id
|
||||
group by article.a_id
|
||||
order by article.a_id desc
|
||||
</select>
|
||||
|
||||
|
||||
<select id="count" resultType="long">
|
||||
select count(*)
|
||||
from article
|
||||
where is_delete = false;
|
||||
</select>
|
||||
|
||||
<select id="getPreArticle" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where articleId = (select max(articleId)
|
||||
from articleView
|
||||
where isOpen = true
|
||||
and articleId < #{id}
|
||||
)
|
||||
</select>
|
||||
<select id="getNextArticle" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where articleId = (select min(articleId)
|
||||
from articleView
|
||||
where isOpen = true
|
||||
and articleId > #{id}
|
||||
)
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.box {
|
||||
width: 600px;
|
||||
height: 45vh;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid rgba(50, 50, 50, .1);
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.box-inner {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.box-inner select, input, button {
|
||||
width: 90%;
|
||||
margin: 12px 5%;
|
||||
height: 40px;
|
||||
padding: 5px 10px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid rgba(50, 50, 50, .1);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
border: 1px solid rgba(0, 50, 50, .6);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.box-inner h3 {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.err-msg {
|
||||
display: none;
|
||||
color: red;
|
||||
width: 100%;
|
||||
padding-left: 30px;
|
||||
font-size: small;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
|
||||
.show-err-tip {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#first-page, #second-page {
|
||||
height: 100%;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
height: 0 !important;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.show {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
|
||||
#next-step, .button-group {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
.button-group button {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.button-group #install {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 20px;
|
||||
background: #1890ff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.loading-show {
|
||||
z-index: 10000;
|
||||
display: flex !important;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
.pacman {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
.loading {
|
||||
box-sizing: border-box;
|
||||
flex: 0 1 auto;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 0;
|
||||
flex-basis: 100%;
|
||||
max-width: 100%;
|
||||
/*height: 200px;*/
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #ececec;
|
||||
}
|
||||
|
||||
|
||||
.pacman > div:nth-child(2) {
|
||||
-webkit-animation: pacman-balls 1s 0s infinite linear;
|
||||
animation: pacman-balls 1s 0s infinite linear;
|
||||
}
|
||||
|
||||
.pacman > div:nth-child(3) {
|
||||
-webkit-animation: pacman-balls 1s 0.33s infinite linear;
|
||||
animation: pacman-balls 1s 0.33s infinite linear;
|
||||
}
|
||||
|
||||
.pacman > div:nth-child(4) {
|
||||
-webkit-animation: pacman-balls 1s 0.66s infinite linear;
|
||||
animation: pacman-balls 1s 0.66s infinite linear;
|
||||
}
|
||||
|
||||
.pacman > div:nth-child(5) {
|
||||
-webkit-animation: pacman-balls 1s 0.99s infinite linear;
|
||||
animation: pacman-balls 1s 0.99s infinite linear;
|
||||
}
|
||||
|
||||
.pacman > div:first-of-type {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
border-right: 25px solid transparent;
|
||||
border-top: 25px solid #ed5565;
|
||||
border-left: 25px solid #ed5565;
|
||||
border-bottom: 25px solid #ed5565;
|
||||
border-radius: 25px;
|
||||
-webkit-animation: rotate_pacman_half_up 0.5s 0s infinite;
|
||||
animation: rotate_pacman_half_up 0.5s 0s infinite;
|
||||
}
|
||||
|
||||
.pacman > div:nth-child(2) {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
border-right: 25px solid transparent;
|
||||
border-top: 25px solid #ed5565;
|
||||
border-left: 25px solid #ed5565;
|
||||
border-bottom: 25px solid #ed5565;
|
||||
border-radius: 25px;
|
||||
-webkit-animation: rotate_pacman_half_down 0.5s 0s infinite;
|
||||
animation: rotate_pacman_half_down 0.5s 0s infinite;
|
||||
margin-top: -50px;
|
||||
}
|
||||
|
||||
.pacman > div:nth-child(3), .pacman > div:nth-child(4), .pacman > div:nth-child(5), .pacman > div:nth-child(6) {
|
||||
background-color: #ed5565;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border-radius: 100%;
|
||||
margin: 2px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
-webkit-transform: translate(0, -6.25px);
|
||||
-ms-transform: translate(0, -6.25px);
|
||||
transform: translate(0, -6.25px);
|
||||
top: 25px;
|
||||
left: 100px;
|
||||
}
|
||||
|
||||
@-webkit-keyframes rotate_pacman_half_up {
|
||||
0% {
|
||||
-webkit-transform: rotate(270deg);
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(270deg);
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotate_pacman_half_up {
|
||||
0% {
|
||||
-webkit-transform: rotate(270deg);
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(270deg);
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes rotate_pacman_half_down {
|
||||
0% {
|
||||
-webkit-transform: rotate(90deg);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(90deg);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotate_pacman_half_down {
|
||||
0% {
|
||||
-webkit-transform: rotate(90deg);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(90deg);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes pacman-balls {
|
||||
75% {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: translate(-100px, -6.25px);
|
||||
transform: translate(-100px, -6.25px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pacman-balls {
|
||||
75% {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: translate(-100px, -6.25px);
|
||||
transform: translate(-100px, -6.25px);
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>博客安装页面</title>
|
||||
<link rel="stylesheet" href="css/install.css">
|
||||
<link rel="stylesheet" href="css/loading.css">
|
||||
<script src="//cdn.bootcdn.net/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="loading">
|
||||
<div class="loader-inner pacman">
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
<p style="margin-top: 20px;margin-left: 10px;">
|
||||
加载中....
|
||||
</p>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="box-inner">
|
||||
<div id="first-page" class="show">
|
||||
<h3>数据库配置</h3>
|
||||
<!-- 数据库-->
|
||||
<select id="db-type">
|
||||
<option value="h2">H2数据库</option>
|
||||
<option value="mysql">Mysql数据库</option>
|
||||
</select>
|
||||
|
||||
<input id="db-host" type="text" placeholder="请输入数据库的主机地址">
|
||||
<span class="err-msg" id="err-tip-db-host">数据库的主机地址不可为空</span>
|
||||
|
||||
<input id="db-name" type="text" placeholder="请输入数据库的名称">
|
||||
<span class="err-msg" id="err-tip-db-name">数据库的地址名称不可为空</span>
|
||||
|
||||
<input id="db-username" type="text" placeholder="请输入数据库用户名">
|
||||
<span class="err-msg" id="err-tip-db-username">数据库用户名不可为空</span>
|
||||
|
||||
<input id="db-password" type="password" placeholder="请输入数据库密码">
|
||||
<span class="err-msg" id="err-tip-db-password">数据库密码不可为空</span>
|
||||
|
||||
<button onclick="nextPage()" id="next-step">下一步</button>
|
||||
</div>
|
||||
<div id="second-page" class="hidden">
|
||||
<h3>新建管理员用户</h3>
|
||||
<input id="email" type="email" placeholder="请输入用户名">
|
||||
<span class="err-msg" id="err-tip-email">用户名不可为空</span>
|
||||
<input id="password" type="password" placeholder="请输入密码">
|
||||
<span class="err-msg" id="err-tip-password">密码不可为空</span>
|
||||
<div class="button-group">
|
||||
<button onclick="preStep()" id="pre-step">上一步</button>
|
||||
<button onclick="postInstallEvent()" id="install"> 安装</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
let requestData;
|
||||
let interValId;
|
||||
|
||||
function postInstallEvent() {
|
||||
requestData.email = $('#email').val()
|
||||
requestData.password = $('#password').val()
|
||||
$('#err-tip-email').removeClass("show-err-tip");
|
||||
$('#err-tip-password').removeClass("show-err-tip");
|
||||
!requestData.password && checkInput($('#password'), $('#err-tip-password'))
|
||||
!requestData.email && checkInput($('#email'), $('#err-tip-email'))
|
||||
if (!requestData.email || !requestData.password) return;
|
||||
$('.loading').addClass('loading-show');
|
||||
$.ajax('/install', {
|
||||
method: "POST",
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(requestData),
|
||||
withCredentials: true,
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
console.log("data", data);
|
||||
console.log("requestData", requestData);
|
||||
interValId = setInterval(checkConnection, 500)
|
||||
checkConnection();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function checkConnection() {
|
||||
$.ajax('/is_install', {
|
||||
method: "GET",
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
if (data.result.is_install) {
|
||||
console.log("安装成功");
|
||||
window.location.href = '/';
|
||||
} else {
|
||||
console.log("安装失败");
|
||||
}
|
||||
$('.loading').removeClass('loading-show');
|
||||
clearInterval(interValId);
|
||||
},
|
||||
error: function (err) {
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换下一页
|
||||
*/
|
||||
function nextPage() {
|
||||
requestData = {
|
||||
dbPassword: $('#db-password').val(),
|
||||
dbType: $('#db-type').val(),
|
||||
dbHost: $('#db-host').val(),
|
||||
dbName: $('#db-name').val(),
|
||||
dbUsername: $('#db-username').val(),
|
||||
email: '',
|
||||
password: '',
|
||||
}
|
||||
$('#err-tip-db-type').removeClass("show-err-tip");
|
||||
$('#err-tip-db-host').removeClass("show-err-tip");
|
||||
$('#err-tip-db-name').removeClass("show-err-tip");
|
||||
$('#err-tip-db-username').removeClass("show-err-tip");
|
||||
$('#err-tip-db-password').removeClass("show-err-tip");
|
||||
!requestData.dbType && checkInput($('#db-type'), $('#err-tip-db-type'))
|
||||
!requestData.dbHost && checkInput($('#db-host'), $('#err-tip-db-host'))
|
||||
!requestData.dbName && checkInput($('#db-name'), $('#err-tip-db-name'))
|
||||
!requestData.dbUsername && checkInput($('#db-username'), $('#err-tip-db-username'))
|
||||
!requestData.dbPassword && checkInput($('#db-password'), $('#err-tip-db-password'))
|
||||
if (!requestData.dbType || !requestData.dbUrl || !requestData.dbUsername || !requestData.dbPassword) return
|
||||
$('#first-page').addClass('hidden');
|
||||
$('#first-page').removeClass('show');
|
||||
$('#second-page').addClass('show');
|
||||
$('#second-page').removeClass('hidden');
|
||||
}
|
||||
|
||||
function preStep() {
|
||||
$('#second-page').addClass('hidden');
|
||||
$('#second-page').removeClass('show');
|
||||
$('#first-page').addClass('show');
|
||||
$('#first-page').removeClass('hidden');
|
||||
|
||||
$('#err-tip-email').removeClass("show-err-tip");
|
||||
$('#err-tip-password').removeClass("show-err-tip");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查组件的状态
|
||||
* @param component 输入框
|
||||
* @param errTipComponent 错误信息提示框
|
||||
* @returns {boolean} 是否有错误
|
||||
*/
|
||||
function checkInput(component, errTipComponent) {
|
||||
if (!component.val()) {
|
||||
errTipComponent.addClass("show-err-tip");
|
||||
component.focus();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -214,12 +214,3 @@ VALUES (1, '1.新增网站更新接口api \n2.新增友链api \n3.优化了文
|
||||
(16, '登陆处理过程变更,登陆时长修改至5天', '2019-11-22 11:39:03', 0),
|
||||
(17, '界面改版v2.0', '2020-04-06 11:00:53', 0);
|
||||
|
||||
INSERT INTO config (conf_id, conf_name, conf_value)
|
||||
VALUES (1, 'file.type', 'local'),
|
||||
(2, 'file.qiniu.accessKey', null),
|
||||
(3, 'file.qiniu.secretKey', null),
|
||||
(4, 'file.qiniu.bucket', null),
|
||||
(5, 'blog.file.path', '~/blog/'),
|
||||
(6, 'file.local.directoryPath', '~/blog/files/'),
|
||||
(8, 'blog.installed', 'false'),
|
||||
(9, 'blog.db.path', '~/blog/db.properties')
|
||||
@@ -8,7 +8,6 @@ drop table if exists tag_category;
|
||||
drop table if exists links;
|
||||
drop table if exists visitor;
|
||||
drop table if exists web_update;
|
||||
drop table if exists config;
|
||||
|
||||
|
||||
CREATE TABLE `user`
|
||||
@@ -89,7 +88,7 @@ CREATE TABLE `links`
|
||||
`l_url` varchar(255) unique not null comment '首页地址',
|
||||
`l_icon_path` varchar(255) not null comment '友链的icon地址',
|
||||
`l_desc` varchar(255) COLLATE utf8mb4_unicode_ci not null comment '友链的说明描述',
|
||||
`is_delete` boolean not null default false comment '该数据是否被删除',
|
||||
`is_delete` boolean not null default false comment '该数据是否被删除',
|
||||
`l_email` varchar(255) comment '网站管理员的邮箱',
|
||||
`l_notification` boolean default false comment '是否通知了'
|
||||
) comment '友站表';
|
||||
@@ -111,13 +110,6 @@ CREATE TABLE `web_update`
|
||||
`is_delete` boolean not null default false comment '该数据是否被删除'
|
||||
) comment '更新内容表';
|
||||
|
||||
CREATE TABLE `config`
|
||||
(
|
||||
`conf_id` int primary key auto_increment,
|
||||
`conf_name` varchar(255) unique not null comment '配置名',
|
||||
`conf_value` varchar(255) default null comment '配置值'
|
||||
);
|
||||
|
||||
CREATE VIEW articleView
|
||||
(articleId, title, summary, mdContent, url, isOriginal, readingCount, likeCount, dislikeCount,
|
||||
publishDate, updateDate, isOpen,
|
||||
|
||||
@@ -8,7 +8,6 @@ drop table if exists tag_category;
|
||||
drop table if exists links;
|
||||
drop table if exists visitor;
|
||||
drop table if exists web_update;
|
||||
drop table if exists config;
|
||||
|
||||
-- 用户表
|
||||
CREATE TABLE `user`
|
||||
@@ -116,13 +115,6 @@ CREATE TABLE `web_update`
|
||||
`is_delete` boolean not null default false comment '该数据是否被删除'
|
||||
);
|
||||
|
||||
CREATE TABLE `config`
|
||||
(
|
||||
`conf_id` int primary key auto_increment,
|
||||
`conf_name` varchar(255) unique not null comment '配置名',
|
||||
`conf_value` varchar(255) default null comment '配置值'
|
||||
);
|
||||
|
||||
CREATE VIEW articleView
|
||||
(articleId, title, summary, mdContent, url, isOriginal, readingCount, likeCount, dislikeCount,
|
||||
publishDate, updateDate, isOpen,
|
||||
@@ -2,15 +2,15 @@ package cn.celess.blog;
|
||||
|
||||
|
||||
import cn.celess.blog.entity.Response;
|
||||
import cn.celess.blog.entity.model.FileInfo;
|
||||
import cn.celess.blog.entity.model.FileResponse;
|
||||
import cn.celess.blog.entity.model.QiniuResponse;
|
||||
import cn.celess.blog.entity.model.UserModel;
|
||||
import cn.celess.blog.entity.request.LoginReq;
|
||||
import cn.celess.blog.service.MailService;
|
||||
import cn.celess.blog.service.FileManager;
|
||||
import cn.celess.blog.service.QiniuService;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.qiniu.storage.model.FileInfo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -37,8 +37,6 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -221,7 +219,7 @@ public class BaseTest {
|
||||
protected ResultActions getMockData(MockHttpServletRequestBuilder builder, String token, Object content) throws Exception {
|
||||
// MockHttpServletRequestBuilder mockHttpServletRequestBuilder = get(url);
|
||||
if (token != null) {
|
||||
builder.header("Authorization", token);
|
||||
builder.header("Authorization", "Bearer "+token);
|
||||
}
|
||||
if (content != null) {
|
||||
builder.content(mapper.writeValueAsString(content)).contentType(MediaType.APPLICATION_JSON);
|
||||
@@ -327,29 +325,23 @@ public class BaseTest {
|
||||
}
|
||||
|
||||
@Slf4j
|
||||
public static class TestFileManager implements FileManager {
|
||||
public static class TestQiNiuServiceImpl implements QiniuService {
|
||||
@Override
|
||||
public FileResponse uploadFile(InputStream is, String fileName) {
|
||||
FileResponse response = new FileResponse();
|
||||
public QiniuResponse uploadFile(InputStream is, String fileName) {
|
||||
QiniuResponse response = new QiniuResponse();
|
||||
log.debug("上传文件请求,[fileName:{}]", fileName);
|
||||
|
||||
response.key = "key";
|
||||
response.type = "test";
|
||||
response.bucket = "bucket";
|
||||
response.hash = "hash";
|
||||
response.size = 1;
|
||||
response.fsize = 1;
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileInfo> getFileList() {
|
||||
public FileInfo[] getFileList() {
|
||||
log.debug("获取文件列表请求");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteFile(String fileName) {
|
||||
log.debug("删除[{}]成功", fileName);
|
||||
return true;
|
||||
return new FileInfo[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
package cn.celess.blog.configuration;
|
||||
|
||||
import cn.celess.blog.BaseTest;
|
||||
import cn.celess.blog.enmu.ConfigKeyEnum;
|
||||
import cn.celess.blog.service.fileserviceimpl.LocalFileServiceImpl;
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class DruidConfigTest extends BaseTest {
|
||||
|
||||
@Mock
|
||||
Environment env;
|
||||
|
||||
@Autowired
|
||||
Environment globalEnvironment;
|
||||
|
||||
|
||||
private File configFile;
|
||||
private File bakConfigFile;
|
||||
|
||||
@Test
|
||||
public void initDataSource() throws IOException {
|
||||
|
||||
DruidConfig druidConfig = new DruidConfig();
|
||||
|
||||
druidConfig.env = env;
|
||||
|
||||
System.out.println(Arrays.toString(env.getActiveProfiles()));
|
||||
|
||||
// 无配置文件
|
||||
assertTrue(!configFile.exists() || configFile.delete());
|
||||
DruidDataSource druidDataSource = druidConfig.initDataSource();
|
||||
|
||||
// 加载初始化时候配置文件的数据库连接
|
||||
assertEquals(env.getProperty(DruidConfig.DB_CONFIG_URL_PREFIX), druidDataSource.getUrl());
|
||||
assertEquals(env.getProperty(DruidConfig.DB_CONFIG_DRIVER_CLASS_NAME_PREFIX), druidDataSource.getDriverClassName());
|
||||
assertEquals(env.getProperty(DruidConfig.DB_CONFIG_USERNAME_PREFIX), druidDataSource.getUsername());
|
||||
assertEquals(env.getProperty(DruidConfig.DB_CONFIG_PASSWORD_PREFIX), druidDataSource.getPassword());
|
||||
assertTrue(configFile.createNewFile());
|
||||
|
||||
// 有配置文件的测试
|
||||
Properties properties = new Properties();
|
||||
FileInputStream fileInputStream = new FileInputStream(configFile);
|
||||
properties.load(fileInputStream);
|
||||
fileInputStream.close();
|
||||
properties.setProperty(DruidConfig.DB_CONFIG_URL_PREFIX, "jdbc:mysql://localhost:3306/blog");
|
||||
properties.setProperty(DruidConfig.DB_CONFIG_DRIVER_CLASS_NAME_PREFIX, "com.mysql.cj.jdbc.Driver");
|
||||
properties.setProperty(DruidConfig.DB_CONFIG_USERNAME_PREFIX, "username");
|
||||
properties.setProperty(DruidConfig.DB_CONFIG_PASSWORD_PREFIX, "password");
|
||||
// 保存到文件
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(configFile);
|
||||
properties.store(fileOutputStream, "数据库配置");
|
||||
fileOutputStream.close();
|
||||
druidDataSource = druidConfig.initDataSource();
|
||||
assertEquals(properties.getProperty(DruidConfig.DB_CONFIG_URL_PREFIX), druidDataSource.getUrl());
|
||||
assertEquals(properties.getProperty(DruidConfig.DB_CONFIG_DRIVER_CLASS_NAME_PREFIX), druidDataSource.getDriverClassName());
|
||||
assertEquals(properties.getProperty(DruidConfig.DB_CONFIG_USERNAME_PREFIX), druidDataSource.getUsername());
|
||||
assertEquals(properties.getProperty(DruidConfig.DB_CONFIG_PASSWORD_PREFIX), druidDataSource.getPassword());
|
||||
}
|
||||
|
||||
@After
|
||||
public void setConfigBack() {
|
||||
if (bakConfigFile.exists()) {
|
||||
System.out.println("恢复配置文件成功");
|
||||
copyFile(bakConfigFile, configFile);
|
||||
assertTrue(bakConfigFile.delete());
|
||||
} else {
|
||||
configFile.deleteOnExit();
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void recordConfig() {
|
||||
File path = new File(LocalFileServiceImpl.getPath(System.getProperty(ConfigKeyEnum.BLOG_FILE_PATH.getKey())));
|
||||
if (!path.exists() && !path.mkdirs()) {
|
||||
fail("创建失败");
|
||||
}
|
||||
this.bakConfigFile = new File(DruidConfig.DB_CONFIG_PATH + ".bak");
|
||||
this.configFile = new File(DruidConfig.DB_CONFIG_PATH);
|
||||
if (configFile.exists()) {
|
||||
System.out.println("备份文件成功");
|
||||
copyFile(configFile, bakConfigFile);
|
||||
}
|
||||
when(this.env.getActiveProfiles()).thenReturn(new String[]{"dev"});
|
||||
when(this.env.getProperty(DruidConfig.DB_CONFIG_PASSWORD_PREFIX)).thenReturn(globalEnvironment.getProperty(DruidConfig.DB_CONFIG_PASSWORD_PREFIX));
|
||||
when(this.env.getProperty(DruidConfig.DB_CONFIG_URL_PREFIX)).thenReturn(globalEnvironment.getProperty(DruidConfig.DB_CONFIG_URL_PREFIX));
|
||||
when(this.env.getProperty(DruidConfig.DB_CONFIG_USERNAME_PREFIX)).thenReturn(globalEnvironment.getProperty(DruidConfig.DB_CONFIG_USERNAME_PREFIX));
|
||||
when(this.env.getProperty(DruidConfig.DB_CONFIG_DRIVER_CLASS_NAME_PREFIX)).thenReturn(globalEnvironment.getProperty(DruidConfig.DB_CONFIG_DRIVER_CLASS_NAME_PREFIX));
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制文件
|
||||
*
|
||||
* @param src
|
||||
* @param dist
|
||||
* @return
|
||||
*/
|
||||
private boolean copyFile(File src, File dist) {
|
||||
try {
|
||||
// 复制备份文件
|
||||
FileOutputStream fos = new FileOutputStream(dist);
|
||||
FileInputStream fis = new FileInputStream(src);
|
||||
int len = 0;
|
||||
byte[] bytes = new byte[1024];
|
||||
while ((len = fis.read(bytes)) != -1) {
|
||||
fos.write(bytes, 0, len);
|
||||
}
|
||||
fos.close();
|
||||
fis.close();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import cn.celess.blog.entity.request.LoginReq;
|
||||
import cn.celess.blog.entity.request.UserReq;
|
||||
import cn.celess.blog.mapper.UserMapper;
|
||||
import cn.celess.blog.service.UserService;
|
||||
import cn.celess.blog.service.FileService;
|
||||
import cn.celess.blog.util.MD5Util;
|
||||
import cn.celess.blog.util.RedisUtil;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
@@ -116,7 +115,7 @@ public class UserControllerTest extends BaseTest {
|
||||
assertNotNull(inputStream);
|
||||
|
||||
// mock 实现类
|
||||
mockInjectInstance(userService, "fileService", (FileService) TestFileManager::new);
|
||||
mockInjectInstance(userService, "qiniuService", new TestQiNiuServiceImpl());
|
||||
|
||||
MockMultipartFile file = new MockMultipartFile("file", "logo.png", MediaType.IMAGE_PNG_VALUE, inputStream);
|
||||
getMockData(multipart("/user/imgUpload").file(file), userLogin()).andDo(result -> {
|
||||
|
||||
@@ -134,4 +134,13 @@ public class ArticleTagMapperTest extends BaseTest {
|
||||
|
||||
return articleTag;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findTagByArticleId() {
|
||||
Article article = articleMapper.findAll().get(0);
|
||||
assertNotNull(article);
|
||||
|
||||
List<Tag> tagByArticleId = articleTagMapper.findTagByArticleId(article.getId());
|
||||
assertNotEquals(0, tagByArticleId.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package cn.celess.blog.mapper;
|
||||
|
||||
import cn.celess.blog.BaseTest;
|
||||
import cn.celess.blog.entity.Config;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class ConfigMapperTest extends BaseTest {
|
||||
|
||||
@Autowired
|
||||
ConfigMapper configMapper;
|
||||
|
||||
@Test
|
||||
public void getConfiguration() {
|
||||
Config file = configMapper.getConfiguration("file.type");
|
||||
assertNotNull(file);
|
||||
assertNotNull(file.getId());
|
||||
assertEquals("file.type", file.getName());
|
||||
assertEquals("local", file.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateConfiguration() {
|
||||
Config config = generateConfig();
|
||||
configMapper.addConfiguration(config);
|
||||
assertNotNull(config.getId());
|
||||
|
||||
String s = randomStr();
|
||||
config.setValue(s);
|
||||
configMapper.updateConfiguration(config);
|
||||
assertEquals(s, configMapper.getConfiguration(config.getName()).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConfigurations() {
|
||||
assertTrue(configMapper.getConfigurations().size() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addConfiguration() {
|
||||
Config config = generateConfig();
|
||||
configMapper.addConfiguration(config);
|
||||
assertNotNull(config.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteConfiguration() {
|
||||
Config config = generateConfig();
|
||||
configMapper.addConfiguration(config);
|
||||
assertNotNull(config.getId());
|
||||
assertNotEquals(0, configMapper.deleteConfiguration(config.getId()));
|
||||
assertNull(configMapper.getConfiguration(config.getName()));
|
||||
}
|
||||
|
||||
private Config generateConfig() {
|
||||
Config config = new Config();
|
||||
config.setName("test" + randomStr(4));
|
||||
config.setValue(randomStr(4));
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package cn.celess.blog.service;
|
||||
import cn.celess.blog.BaseTest;
|
||||
import cn.celess.blog.entity.model.ArticleModel;
|
||||
import cn.celess.blog.entity.model.PageData;
|
||||
import cn.celess.blog.mapper.ArticleMapper;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@@ -12,6 +14,8 @@ public class ArticleServiceTest extends BaseTest {
|
||||
|
||||
@Autowired
|
||||
ArticleService articleService;
|
||||
@Autowired
|
||||
ArticleMapper articleMapper;
|
||||
|
||||
@Test
|
||||
public void adminArticles() {
|
||||
@@ -24,4 +28,25 @@ public class ArticleServiceTest extends BaseTest {
|
||||
assertTrue(pageData.getList().stream().anyMatch(ArticleModel::isDeleted));
|
||||
assertTrue(pageData.getList().stream().anyMatch(articleModel -> !articleModel.isDeleted()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrievePageForOpen() {
|
||||
PageData<ArticleModel> articleModelPageData = articleService.retrievePageForOpen(10, 1);
|
||||
assertEquals(10, articleModelPageData.getPageSize());
|
||||
assertEquals(1, articleModelPageData.getPageNum());
|
||||
assertEquals(10, articleModelPageData.getList().size());
|
||||
articleModelPageData.getList().forEach(Assert::assertNotNull);
|
||||
|
||||
// 测试open字段
|
||||
articleModelPageData.getList().forEach(articleModel -> {
|
||||
// 当前文章
|
||||
assertTrue(articleMapper.findArticleById(articleModel.getId()).getOpen());
|
||||
if (articleModel.getPreArticle() != null) {
|
||||
assertTrue(articleMapper.findArticleById(articleModel.getPreArticle().getId()).getOpen());
|
||||
}
|
||||
if (articleModel.getNextArticle() != null) {
|
||||
assertTrue(articleMapper.findArticleById(articleModel.getNextArticle().getId()).getOpen());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
package cn.celess.blog.service.fileserviceimpl;
|
||||
|
||||
import cn.celess.blog.BaseTest;
|
||||
import cn.celess.blog.enmu.ConfigKeyEnum;
|
||||
import cn.celess.blog.entity.model.FileInfo;
|
||||
import cn.celess.blog.entity.model.FileResponse;
|
||||
import cn.celess.blog.service.FileManager;
|
||||
import cn.celess.blog.service.FileService;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@Slf4j
|
||||
public class FileManagerTest extends BaseTest {
|
||||
|
||||
@Autowired
|
||||
FileService fileService;
|
||||
|
||||
FileManager fileManager;
|
||||
|
||||
@Test
|
||||
public void testUploadFile() {
|
||||
// 测试本地的文件上传
|
||||
fileManager = null;
|
||||
System.setProperty(ConfigKeyEnum.FILE_TYPE.getKey(), "local");
|
||||
fileManager = fileService.getFileManager();
|
||||
assertTrue(fileManager instanceof LocalFileServiceImpl);
|
||||
uploadFile();
|
||||
|
||||
// 测试七牛云的文件上传
|
||||
fileManager = null;
|
||||
System.setProperty(ConfigKeyEnum.FILE_TYPE.getKey(), "qiniu");
|
||||
fileManager = fileService.getFileManager();
|
||||
assertTrue(fileManager instanceof QiniuFileServiceImpl);
|
||||
uploadFile();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFileList() {
|
||||
// 测试获取本地的文件列表
|
||||
fileManager = null;
|
||||
System.setProperty(ConfigKeyEnum.FILE_TYPE.getKey(), "local");
|
||||
fileManager = fileService.getFileManager();
|
||||
assertTrue(fileManager instanceof LocalFileServiceImpl);
|
||||
getFileList();
|
||||
|
||||
// 测试获取七牛云的文件列表
|
||||
fileManager = null;
|
||||
System.setProperty(ConfigKeyEnum.FILE_TYPE.getKey(), "qiniu");
|
||||
fileManager = fileService.getFileManager();
|
||||
assertTrue(fileManager instanceof QiniuFileServiceImpl);
|
||||
getFileList();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteFile() {
|
||||
// 测试删除本地文件
|
||||
fileManager = null;
|
||||
System.setProperty(ConfigKeyEnum.FILE_TYPE.getKey(), "local");
|
||||
fileManager = fileService.getFileManager();
|
||||
assertTrue(fileManager instanceof LocalFileServiceImpl);
|
||||
deleteFile();
|
||||
|
||||
// 测试删除七牛云文件
|
||||
fileManager = null;
|
||||
System.setProperty(ConfigKeyEnum.FILE_TYPE.getKey(), "qiniu");
|
||||
fileManager = fileService.getFileManager();
|
||||
assertTrue(fileManager instanceof QiniuFileServiceImpl);
|
||||
deleteFile();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void uploadFile() {
|
||||
String fileName = null;
|
||||
File file = createFile();
|
||||
FileResponse fileResponse = fileManager.uploadFile(new FileInputStream(file), file.getName());
|
||||
assertEquals(file.getName(), fileResponse.key);
|
||||
assertEquals(System.getProperty(ConfigKeyEnum.FILE_TYPE.getKey()), fileResponse.type);
|
||||
// assertNotNull(fileResponse.hash);
|
||||
fileName = fileResponse.key;
|
||||
|
||||
fileManager.deleteFile(fileName);
|
||||
|
||||
file.deleteOnExit();
|
||||
}
|
||||
|
||||
public void getFileList() {
|
||||
List<FileInfo> fileList = fileManager.getFileList();
|
||||
fileList.forEach(fileInfo -> {
|
||||
assertNotNull(fileInfo.key);
|
||||
// assertNotNull(fileInfo.hash);
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteFile() {
|
||||
uploadFile();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private File createFile() {
|
||||
String fileName = "test." + randomStr(3);
|
||||
File file = new File(fileName);
|
||||
if (!file.exists() && file.createNewFile()) {
|
||||
// 创建文件
|
||||
log.debug("创建文件[{}]", fileName);
|
||||
FileOutputStream outputStream = new FileOutputStream(file);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
outputStream.write(new byte[1024]);
|
||||
}
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user