Compare commits

..

142 Commits

Author SHA1 Message Date
禾几海
9d462cc876 feat: 拆分为数据库地址 2020-11-22 23:03:37 +08:00
禾几海
ec96a787ef fix(DruidConfig): validationQuery not set error 2020-11-14 21:24:23 +08:00
禾几海
91de56cb32 feat: 参数校验 2020-10-23 17:09:10 +08:00
禾几海
e2a3fb6a6c refactor: 将实现逻辑放到service中 2020-10-23 16:33:29 +08:00
禾几海
49ff1865bb feat: 安装页面布局 loading动画 2020-10-22 15:41:34 +08:00
禾几海
b920034ad6 feat: 安装页面布局 2020-10-22 14:12:01 +08:00
禾几海
76f3d16e09 feat: 安装页面 2020-10-22 00:21:23 +08:00
禾几海
9dafc6d5a7 feat: 安装功能 2020-10-18 19:49:19 +08:00
禾几海
ec693da079 fix: 设置为共有访问 2020-10-18 13:57:39 +08:00
禾几海
58498ef225 fix: 测试环境仍然使用test环境中的数据库连接 并在单元测试中mock profiles 2020-10-18 13:56:20 +08:00
禾几海
c56a3eaf83 fix: 修复测试完成后产生的测试配置文件无法删除的异常 2020-10-18 13:20:10 +08:00
禾几海
e0abfb7d70 feat: 存储博客的默认数据存储路径 2020-10-18 13:19:25 +08:00
禾几海
96cb2dcee4 feat: 启动时首选本地文件中数据库的配置进行加载 2020-10-18 11:38:05 +08:00
禾几海
e39763ad0c style: rename 'schema_h2' to 'schema-h2' 2020-10-18 11:36:12 +08:00
禾几海
a3edc00a03 feat: 从配置文件中初始化配置 2020-10-17 00:13:17 +08:00
禾几海
c0687b4776 refactor: 修改FileResponse属性bucket为type 2020-10-17 00:12:37 +08:00
禾几海
b3b3a7a908 refactor: 添加修改配置项 2020-10-16 23:30:59 +08:00
禾几海
56efdc44d7 fix: 由配置信息来初始化对象 2020-10-16 23:28:24 +08:00
禾几海
e4684e6150 fix: 配置修改后不生效的异常 2020-10-16 22:49:17 +08:00
禾几海
65d65221e8 feat: 配置管理接口 2020-10-16 22:41:55 +08:00
禾几海
47df223655 test: fileService的mock 2020-10-16 19:01:17 +08:00
禾几海
fa95f2f69e test: fileManager测试 2020-10-16 18:53:51 +08:00
禾几海
5598804ddc feat: 本地文件存储 2020-10-16 18:05:26 +08:00
禾几海
ed7d18d491 feat: 项目启动注入配置表中配置到内存中 2020-10-16 16:36:05 +08:00
禾几海
2fbe030da9 feat: 添加配置存储表及其处理类 2020-10-16 16:35:28 +08:00
禾几海
5f3cbece7b feat: 本地文件服务 2020-10-16 15:16:17 +08:00
禾几海
4942daf900 ci: 调整配置文件 2020-10-16 14:35:50 +08:00
禾几海
9f070169b4 ci: 调整配置文件 2020-10-16 14:30:58 +08:00
禾几海
4fa114eb1e test: 完善测试例 2020-10-16 14:30:35 +08:00
禾几海
431ce8ac28 feat: 修复空值异常,完善删除接口功能 2020-10-16 14:29:39 +08:00
禾几海
49000e9ee6 feat: 删除文件 2020-10-15 23:30:19 +08:00
禾几海
19068ff14d refactor(文件服务): 接口修改返回值 2020-10-15 22:46:55 +08:00
禾几海
3d0253a35a refactor(文件服务): 修改类文件包路径 2020-10-15 22:07:48 +08:00
禾几海
0283bd11dc fix(文件服务): 修复无法获取到文件服务的异常 2020-10-15 19:45:43 +08:00
禾几海
60347c7629 refactor: 重命名QiniuService ->FileService
重命名为FileService 并修改方法为获取File Manager来处理文件
2020-10-15 18:29:52 +08:00
禾几海
8de0cbded8 feat(resources): 新增简易部署配置文件 2020-10-15 18:02:53 +08:00
禾几海
0ba7e06695 Merge pull request #12 from xiaohai2271/dependabot/maven/junit-junit-4.13.1
build(deps): bump junit from 4.12 to 4.13.1
2020-10-14 07:56:21 +08:00
dependabot[bot]
512d04f3e9 build(deps): bump junit from 4.12 to 4.13.1
Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-13 17:49:19 +00:00
禾几海
ada8f67171 Merge remote-tracking branch 'origin/master' 2020-10-09 18:57:42 +08:00
禾几海
6e12331e61 feat: 添加文件上传接口 2020-10-09 18:56:59 +08:00
禾几海
81ee71adf1 Create codeql-analysis.yml 2020-10-03 18:02:48 +08:00
禾几海
7e7332694e docs: typo 2020-09-07 12:28:07 +08:00
禾几海
8db690a55f Update issue templates 2020-09-07 12:23:44 +08:00
禾几海
0b40522e93 feat: 默认返回位置信息 2020-09-05 16:35:45 +08:00
禾几海
9026ba0732 refactor: 简化代码 2020-09-05 15:43:43 +08:00
禾几海
f5f2437fa4 refactor: 简化代码 2020-09-05 15:42:03 +08:00
禾几海
0bcca091e1 refactor: 简化代码 2020-09-04 13:02:36 +08:00
禾几海
3c69baa4ad Merge branch 'feature-ip2region' 2020-09-04 12:29:18 +08:00
禾几海
baf5b1bbb7 feat: 添加对jdk8以上环境的支持 2020-09-04 12:23:15 +08:00
禾几海
38621bcfa4 refactor: 换用ip2region 2020-09-04 12:11:14 +08:00
禾几海
cf435a588f refactor: 添加ip2region 2020-09-04 09:42:55 +08:00
禾几海
feab26f4f7 docs: add some badge 2020-09-01 08:30:26 +08:00
禾几海
578dbe6cc5 docs: api参数变化
- '/admin/articles' deleted 参数   可缺省
- '/admin/users'    status  参数
可缺省
- '/admin/links'    deleted 参数   可缺省
2020-08-31 13:14:37 +08:00
禾几海
f3b03f4853 ci: 调整webhook地址 2020-08-31 13:06:35 +08:00
禾几海
ee85b1f175 Merge pull request #11 from xiaohai2271/dev
分离不同状态的数据
2020-08-31 13:01:09 +08:00
禾几海
925e816f7a fix(login): 账户不存在时引发的空值异常 2020-08-31 12:47:19 +08:00
禾几海
a59bb7f231 feat(login): 非正常账户不可登录 2020-08-31 12:45:49 +08:00
禾几海
7f17c20e01 移除无效脚本 2020-08-31 10:34:34 +08:00
禾几海
6eabb3ab22 refactor: 精简代码 2020-08-31 10:10:21 +08:00
禾几海
72674f4612 test: 补单元测试 2020-08-31 10:02:12 +08:00
禾几海
9b460ff33c feat(link): 分离不同状态的数据 2020-08-31 09:46:15 +08:00
禾几海
a26946a583 feat: 反序列化 2020-08-31 01:10:12 +08:00
禾几海
01407aba7e feat: 分离不同状态的数据 2020-08-31 00:53:48 +08:00
禾几海
a54e04abf3 feat: 序列化 2020-08-31 00:51:01 +08:00
禾几海
450b4a40bd feat(user): 修改status字段类型 2020-08-31 00:17:21 +08:00
禾几海
9f883d12df feat(article): 修改参数 2020-08-30 23:45:18 +08:00
禾几海
c17b56b436 style: 修改部分代码格式 2020-08-30 14:17:34 +08:00
禾几海
b55a50d548 fix(test): 不合理的测试例 2020-08-30 14:01:19 +08:00
禾几海
4c9b193857 Merge branch 'dev' 2020-08-15 16:08:44 +08:00
禾几海
18a8c916c3 Update README.md 2020-08-15 16:07:41 +08:00
禾几海
99f2907621 Update README.md 2020-08-15 16:07:41 +08:00
禾几海
939b06d0a9 切换到jackson(#10)
切换到jackson
2020-08-15 16:05:39 +08:00
禾几海
a7f947a017 fix: 修复部分测试异常 2020-08-15 16:03:22 +08:00
禾几海
40e1f4d6ab fix: 空值异常 2020-08-15 16:00:05 +08:00
禾几海
6b77655c16 style: optimize imports 2020-08-15 15:44:34 +08:00
禾几海
7ff44fd73e Merge branch 'dev' into feature-trans2jackson 2020-08-15 15:33:04 +08:00
禾几海
c9f91bf2c1 fix(test):外键约束引发的异常,替换随机字符串的生成 2020-08-15 15:26:41 +08:00
禾几海
03fcddb971 fix(test):外键约束引发的异常,替换随机字符串的生成 2020-08-15 15:12:07 +08:00
禾几海
dc851e84a4 fix(test): 唯一索引引发的异常 2020-08-15 15:03:16 +08:00
禾几海
b34acee733 refactor: 修改当日剩余时间的计算方法 2020-08-15 15:00:07 +08:00
禾几海
d46dada23a refactor: 替换net.sf.json为fastJson 2020-08-15 14:59:45 +08:00
禾几海
47e5030f52 refactor: 替换net.sf.json为fastJson 2020-08-15 14:39:39 +08:00
禾几海
94c9fc1c46 refactor(Test): 将测试类中随机字符串的生成提到基类中 2020-08-15 12:16:39 +08:00
禾几海
bdcfaef5f8 refactor(Test): 重构 MultipleSubmitFilter 2020-08-15 12:13:08 +08:00
禾几海
3b6439c5cf refactor(Test): 重构 AuthorizationFilter 2020-08-15 12:10:48 +08:00
禾几海
938a051487 refactor(Test): 重构 WebUpdateInfoControllerTest 2020-08-15 12:01:41 +08:00
禾几海
a04b51a82e refactor(Test): 重构 VisitorControllerTest 2020-08-15 11:49:19 +08:00
禾几海
ee4c4bd87e Update README.md 2020-08-15 09:48:19 +08:00
禾几海
e70ad72523 Update README.md 2020-08-15 09:47:34 +08:00
禾几海
c466ddddea 重新配置集成测试(#9) 2020-08-15 02:39:45 +08:00
禾几海
7257f23ef6 refactor(ci): 重新配置ci 2020-08-15 02:27:40 +08:00
禾几海
7c96151830 fix(test): 修复后台服务未开启时测试不通过的情况 2020-08-14 21:37:17 +08:00
禾几海
5a47803611 fix(test): 修改内嵌redis的启动端口 2020-08-14 21:30:40 +08:00
禾几海
af9f243a83 refactor(ci): 重新配置ci 2020-08-14 21:19:53 +08:00
禾几海
3c8abc895a fix(mvnw): 重新生成mvnw 2020-08-14 21:06:14 +08:00
禾几海
9ffa293d24 refactor(Test): 修改上传文件到图床的实现方式 2020-08-14 17:58:08 +08:00
禾几海
d13ab4e522 add(Test): 测试的配置文件 2020-08-14 17:55:36 +08:00
禾几海
2fce2d8a1c refactor(Test): 内嵌redis 2020-08-14 17:17:36 +08:00
禾几海
6eb7d01875 style:修改sql格式 2020-08-14 17:17:35 +08:00
禾几海
aa751dbba1 refactor(Test):内嵌h2 2020-08-14 17:16:49 +08:00
禾几海
14ff60ecfc Update README.md 2020-08-10 16:43:50 +08:00
禾几海
5dae647885 Merge remote-tracking branch 'origin/master' 2020-08-10 16:40:12 +08:00
禾几海
bf2abd6072 Update README.md 2020-08-10 16:39:50 +08:00
禾几海
a62b395a8a Update LICENSE 2020-08-10 16:24:06 +08:00
禾几海
5059859ae4 Update README.md 2020-08-10 16:20:28 +08:00
禾几海
ecdbf8e21c Add Build document 2020-08-10 16:15:43 +08:00
禾几海
c69eee7027 Add api document 2020-08-10 15:59:30 +08:00
禾几海
8e8a7c809d 修复id异常 2020-08-04 22:25:20 +08:00
禾几海
c6a97e4c5b 外键约束 2020-08-04 22:01:02 +08:00
禾几海
d50cd93e55 移动sql位置,开启初始化数据库的设置 2020-08-04 21:47:46 +08:00
禾几海
e32600d892 Update README.md 2020-08-02 11:45:44 +08:00
禾几海
d473b5931b Update test.yml 2020-08-02 11:40:34 +08:00
禾几海
ab6f9d894d Rename deplay.yml to build.yml 2020-08-02 11:38:34 +08:00
禾几海
49ee7c73e2 空值异常 2020-08-01 23:56:10 +08:00
禾几海
4a65df2a7d Update deplay.yml 2020-08-01 21:46:17 +08:00
禾几海
b6c6cda4ae Merge pull request #7 from xiaohai2271/dev
最近的一些修改
2020-08-01 21:26:45 +08:00
禾几海
a9efb1c04d Merge pull request #6 from xiaohai2271/feature-#5
Feature #5  申请友链时自动抓取网页信息
2020-08-01 21:24:46 +08:00
禾几海
4ac430445d remove jacoco 2020-08-01 21:09:29 +08:00
禾几海
d6cede718b null值异常 2020-07-25 12:08:44 +08:00
禾几海
7922ea558f 调整UserController的测试类 2020-07-25 11:23:03 +08:00
禾几海
f65c96fa2d 调整TagController的测试类 2020-07-24 22:02:24 +08:00
禾几海
1bfd2d713e . 2020-07-24 21:08:49 +08:00
禾几海
ffed0d5cd0 调整LinkController的测试类 2020-07-24 21:08:40 +08:00
禾几海
b9094c1345 . 2020-07-24 20:24:34 +08:00
禾几海
e9209d1852 调整CommentController的测试类 2020-07-24 20:24:13 +08:00
禾几海
9900605e1a . 2020-07-24 20:06:59 +08:00
禾几海
883a78e872 调整CategoryController的测试类 2020-07-24 20:06:01 +08:00
禾几海
c7016dcf5f 修改getResponse的类型参数 2020-07-24 20:05:17 +08:00
禾几海
66b2b26b15 注销导致token无效的bug 2020-07-24 16:46:35 +08:00
禾几海
f1d3a79919 ... 2020-07-24 13:51:44 +08:00
禾几海
003f74f5f1 调整ArticleController的测试类 2020-07-24 13:49:18 +08:00
禾几海
2f6253c175 抽离json -> Response 对象的方法 2020-07-24 13:48:50 +08:00
禾几海
aa3ee5db72 ... 2020-07-24 00:46:46 +08:00
禾几海
d340ba8218 ... 2020-07-24 00:36:13 +08:00
禾几海
7be1c9dfb0 调整ArticleController的测试类 2020-07-24 00:22:40 +08:00
禾几海
b7f26cbfdb 调整测试基类 2020-07-24 00:21:55 +08:00
禾几海
de5e40e6b8 pr进行ci测试 2020-05-27 18:30:08 +08:00
禾几海
d1f08b58c0 Merge pull request #1 from xiaohai2271/dev
调整数据库字段,优化部分接口
2020-05-27 16:45:02 +08:00
禾几海
8b255372dd Merge remote-tracking branch 'origin/master' 2020-05-19 19:56:02 +08:00
小海
f88bf105a9 Update README.md 2020-05-19 19:55:26 +08:00
禾几海
0e26eab2e6 Merge branch 'dev' 2020-05-18 08:36:19 +08:00
小海
778c2dba58 Update README.md 2020-05-03 22:32:48 +08:00
113 changed files with 8928 additions and 2281 deletions

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

28
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
# This workflow will build a package using Maven and then publish it to GitHub packages when a release is created
# For more information see: https://github.com/actions/setup-java#apache-maven-with-a-settings-path
name: Build
on:
push:
branches:
- master
jobs:
build:
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
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Deploy
run: mvn -B test --file pom.xml && curl http://bt.celess.cn:2271/hook?access_key=$KEY

71
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,71 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
name: "CodeQL"
on:
push:
branches: [master]
pull_request:
# The branches below must be a subset of the branches above
branches: [master]
schedule:
- cron: '0 14 * * 2'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Override automatic language detection by changing the below list
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
language: ['java']
# Learn more...
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View File

@@ -1,47 +0,0 @@
# This workflow will build a package using Maven and then publish it to GitHub packages when a release is created
# For more information see: https://github.com/actions/setup-java#apache-maven-with-a-settings-path
name: Deplay
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
env:
APPLICATION_PROPERTIES_TEST: ${{ secrets.APPLICATION_PROPERTIES_TEST }}
APPLICATION_PROPERTIES_PROD: ${{ secrets.APPLICATION_PROPERTIES_PROD }}
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build jar file
run: echo $APPLICATION_PROPERTIES_PROD|base64 -d> src/main/resources/application-prod.properties && mvn -B package --file pom.xml
- name: SCP
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
password: ${{ secrets.SSH_PASSWORD }}
port: ${{ secrets.SSH_PORT }}
source: "target/blog-0.0.1-SNAPSHOT.jar"
target: "/www/wwwroot/api.celess.cn"
- name: Run SSH command
uses: garygrossgarten/github-action-ssh@v0.5.0
with:
command: cd /www/wwwroot/api.celess.cn && bash build.sh
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
password: ${{ secrets.SSH_PASSWORD }}
port: ${{ secrets.SSH_PORT }}

View File

@@ -1,7 +1,7 @@
# This workflow will build a package using Maven and then publish it to GitHub packages when a release is created # This workflow will build a package using Maven and then publish it to GitHub packages when a release is created
# For more information see: https://github.com/actions/setup-java#apache-maven-with-a-settings-path # For more information see: https://github.com/actions/setup-java#apache-maven-with-a-settings-path
name: pr Test name: Test
on: on:
push: push:
@@ -13,17 +13,17 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
APPLICATION_PROPERTIES_TEST: ${{ secrets.APPLICATION_PROPERTIES_TEST }} QINIU_ACCESSKEY: ${{ secrets.QINIU_ACCESSKEY }}
APPLICATION_PROPERTIES_PROD: ${{ secrets.APPLICATION_PROPERTIES_PROD }} QINIU_SECRETKEY: ${{ secrets.QINIU_SECRETKEY }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Set up JDK 1.8 - name: Set up JDK 1.8
uses: actions/setup-java@v1 uses: actions/setup-java@v1
with: with:
java-version: 1.8 java-version: 1.8
- name: Test - name: Test
run: echo $APPLICATION_PROPERTIES_TEST|base64 -d > src/main/resources/application-test.properties && mvn -B test --file pom.xml run: mvn -B test --file pom.xml

2
.gitignore vendored
View File

@@ -4,7 +4,5 @@
target/ target/
# 本地项目的私有文件 # 本地项目的私有文件
back-end/blog-dev.sql
src/main/resources/application-dev.properties src/main/resources/application-dev.properties
src/main/resources/application-prod.properties src/main/resources/application-prod.properties
src/main/resources/application-test.properties

View File

@@ -1,11 +1,11 @@
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2007-present the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* https://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import java.net.*; import java.net.*;
import java.io.*; import java.io.*;
import java.nio.channels.*; import java.nio.channels.*;
@@ -21,12 +20,12 @@ import java.util.Properties;
public class MavenWrapperDownloader { public class MavenWrapperDownloader {
private static final String WRAPPER_VERSION = "0.5.5"; private static final String WRAPPER_VERSION = "0.5.6";
/** /**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/ */
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
/** /**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
@@ -55,7 +54,7 @@ public class MavenWrapperDownloader {
// wrapperUrl parameter. // wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL; String url = DEFAULT_DOWNLOAD_URL;
if (mavenWrapperPropertyFile.exists()) { if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null; FileInputStream mavenWrapperPropertyFileInputStream = null;
try { try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
@@ -66,7 +65,7 @@ public class MavenWrapperDownloader {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally { } finally {
try { try {
if (mavenWrapperPropertyFileInputStream != null) { if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close(); mavenWrapperPropertyFileInputStream.close();
} }
} catch (IOException e) { } catch (IOException e) {
@@ -77,8 +76,8 @@ public class MavenWrapperDownloader {
System.out.println("- Downloading from: " + url); System.out.println("- Downloading from: " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if (!outputFile.getParentFile().exists()) { if(!outputFile.getParentFile().exists()) {
if (!outputFile.getParentFile().mkdirs()) { if(!outputFile.getParentFile().mkdirs()) {
System.out.println( System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
} }

Binary file not shown.

View File

@@ -1,2 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

View File

@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2019 小 Copyright (c) 2020 禾几
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,11 +1,23 @@
# 小海博客后端管理系统 <h1 align="center">
![Build Staus](https://github.com/xiaohai2271/blog-backEnd/workflows/Blog%20backEnd%20CI/badge.svg?branch=master&event=push) ![coverage report](https://gitlab.com/xiaohai2271/blog-backEnd/badges/master/coverage.svg) ![GitHub](https://img.shields.io/github/license/xiaohai2271/blog-backEnd) [![Website](https://img.shields.io/website?up_message=%E5%B0%8F%E6%B5%B7%E5%8D%9A%E5%AE%A2&url=https%3A%2F%2Fwww.celess.cn)](https://www.celess.cn) 小海博客后端管理系统
## 基于Springboot的后端博客管理系统 </h1>
<div align="center">
基于Springboot的后端博客管理系统
[![Build](https://github.com/xiaohai2271/blog-backEnd/workflows/Build/badge.svg)](https://github.com/xiaohai2271/blog-backEnd)
[![Test](https://github.com/xiaohai2271/blog-backEnd/workflows/Test/badge.svg)](https://github.com/xiaohai2271/blog-backEnd)
[![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/xiaohai2271/blog-backEnd)](https://github.com/xiaohai2271/blog-backEnd)
[![GitHub](https://img.shields.io/github/license/xiaohai2271/blog-backEnd)](https://github.com/xiaohai2271/blog-backEnd)
[![GitHub top language](https://img.shields.io/github/languages/top/xiaohai2271/blog-backEnd)](https://github.com/xiaohai2271/blog-backEnd)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/xiaohai2271/blog-backEnd)](https://github.com/xiaohai2271/blog-backEnd)
[![GitHub last commit](https://img.shields.io/github/last-commit/xiaohai2271/blog-backEnd)](https://github.com/xiaohai2271/blog-backEnd)
[![Website](https://img.shields.io/website?up_message=%E5%B0%8F%E6%B5%B7%E5%8D%9A%E5%AE%A2&url=https%3A%2F%2Fwww.celess.cn)](https://www.celess.cn)
</div>
### 主要使用的技术 > 请配合前端项目一起食用 [https://github.com/xiaohai2271/blog-frontEnd](https://github.com/xiaohai2271/blog-frontEnd)
## 🎈主要使用的技术
| 使用的技术 | 名称 | 版本 | | 使用的技术 | 名称 | 版本 |
| :--------------: | :--------: | :-----------: | | :--------------: | :--------: | :-----------: |
@@ -18,18 +30,16 @@
| 接口文档 | Swagger | 2.6.1 | | 接口文档 | Swagger | 2.6.1 |
| 数据库连接池 | druid | 1.1.14 | | 数据库连接池 | druid | 1.1.14 |
| 缓存(线上环境) | redis | 3.0.6 | | 缓存(线上环境) | redis | 3.0.6 |
|数据库|mysql|5.7| | 数据库 |mysql |5.7 |
### 接口文档 ## 🔨如何构建
详情参照[Build](./doc/Build.md)文档
项目采用swagger2接口文档自动生成具体为 http://ip:端口/swagger-ui.html
### 📝TODO ## 📒接口文档
项目采用swagger2接口文档自动生成具体为 http://ip:port/doc.html
- [x] 密码重置 或者参照[离线API文档](./doc/API.md)
- [x] 信息修改
- [ ] 接入qq登录
### 📌FIXME ## ☀授权协议
[MIT](./LICENSE)
- [ ] `/write` 图片上传的跨域问题

View File

@@ -1,8 +0,0 @@
#!/bin/sh
echo "查询已存在进程"
pgrep -af blog-0.0.1-SNAPSHOT.jar
echo "结束已存在进程"
pkill -f blog-0.0.1-SNAPSHOT.jar
echo "开始运行小海博客"
nohup java -jar -Dfile.encoding=UTF-8 blog-0.0.1-SNAPSHOT.jar >blog.log &
echo "更新结束"

4376
doc/API.md Normal file

File diff suppressed because it is too large Load Diff

33
doc/Build.md Normal file
View File

@@ -0,0 +1,33 @@
# 如何构建
### 1. 构建前准备
- 安装jdk
- 安装maven(也可使使用项目中的maven wrapper)
- 安装mysql
- 安装redis
- 获取七牛云的AccessKey/SecretKey (个人中心-密钥管理) [七牛云官网](https://www.qiniu.com/)
### 2. 拉取项目到本地
``` shell script
git clone https://github.com/xiaohai2271/blog-backEnd.git
# 或
git clone git@github.com:xiaohai2271/blog-backEnd.git
```
### 3. maven构建
```shell script
mvn package
```
### 4. 运行
```shell script
java -jar target/blog-0.0.1-SNAPSHOT.jar
```
### 5. 其他命令
```shell script
mvn clean # 清理项目资源
mvn clean package # 清理项目资源并重新打包
mvn clean package -DskipTests # 清理项目资源,重新打包并跳过测试
mvn test # 运行测试
..... #待添加
```

256
mvnw vendored
View File

@@ -8,7 +8,7 @@
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# https://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
@@ -19,7 +19,7 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# Maven2 Start Up Batch script # Maven Start Up Batch script
# #
# Required ENV vars: # Required ENV vars:
# ------------------ # ------------------
@@ -34,135 +34,128 @@
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ]; then if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ]; then if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc . /etc/mavenrc
fi fi
if [ -f "$HOME/.mavenrc" ]; then if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc" . "$HOME/.mavenrc"
fi fi
fi fi
# OS specific support. $var _must_ be set to either true or false. # OS specific support. $var _must_ be set to either true or false.
cygwin=false cygwin=false;
darwin=false darwin=false;
mingw=false mingw=false
case "$(uname)" in case "`uname`" in
CYGWIN*) cygwin=true ;; CYGWIN*) cygwin=true ;;
MINGW*) mingw=true ;; MINGW*) mingw=true;;
Darwin*) Darwin*) darwin=true
darwin=true # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html if [ -z "$JAVA_HOME" ]; then
if [ -z "$JAVA_HOME" ]; then if [ -x "/usr/libexec/java_home" ]; then
if [ -x "/usr/libexec/java_home" ]; then export JAVA_HOME="`/usr/libexec/java_home`"
export JAVA_HOME="$(/usr/libexec/java_home)" else
else export JAVA_HOME="/Library/Java/Home"
export JAVA_HOME="/Library/Java/Home" fi
fi fi
fi ;;
;;
esac esac
if [ -z "$JAVA_HOME" ]; then if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ]; then if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=$(java-config --jre-home) JAVA_HOME=`java-config --jre-home`
fi fi
fi fi
if [ -z "$M2_HOME" ]; then if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home ## resolve links - $0 may be a link to maven's home
PRG="$0" PRG="$0"
# need this for relative symlinks # need this for relative symlinks
while [ -h "$PRG" ]; do while [ -h "$PRG" ] ; do
ls=$(ls -ld "$PRG") ls=`ls -ld "$PRG"`
link=$(expr "$ls" : '.*-> \(.*\)$') link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' >/dev/null; then if expr "$link" : '/.*' > /dev/null; then
PRG="$link" PRG="$link"
else else
PRG="$(dirname "$PRG")/$link" PRG="`dirname "$PRG"`/$link"
fi fi
done done
saveddir=$(pwd) saveddir=`pwd`
M2_HOME=$(dirname "$PRG")/.. M2_HOME=`dirname "$PRG"`/..
# make it fully qualified # make it fully qualified
M2_HOME=$(cd "$M2_HOME" && pwd) M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir" cd "$saveddir"
# echo Using m2 at $M2_HOME # echo Using m2 at $M2_HOME
fi fi
# For Cygwin, ensure paths are in UNIX format before anything is touched # For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin; then if $cygwin ; then
[ -n "$M2_HOME" ] && [ -n "$M2_HOME" ] &&
M2_HOME=$(cygpath --unix "$M2_HOME") M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] && [ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --unix "$JAVA_HOME") JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] && [ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --unix "$CLASSPATH") CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi fi
# For Mingw, ensure paths are in UNIX format before anything is touched # For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw; then if $mingw ; then
[ -n "$M2_HOME" ] && [ -n "$M2_HOME" ] &&
M2_HOME="$( ( M2_HOME="`(cd "$M2_HOME"; pwd)`"
cd "$M2_HOME"
pwd
))"
[ -n "$JAVA_HOME" ] && [ -n "$JAVA_HOME" ] &&
JAVA_HOME="$( ( JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
cd "$JAVA_HOME"
pwd
))"
fi fi
if [ -z "$JAVA_HOME" ]; then if [ -z "$JAVA_HOME" ]; then
javaExecutable="$(which javac)" javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "$(expr \"$javaExecutable\" : '\([^ ]*\)')" = "no" ]; then if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10. # readlink(1) is not available as standard on Solaris 10.
readLink=$(which readlink) readLink=`which readlink`
if [ ! $(expr "$readLink" : '\([^ ]*\)') = "no" ]; then if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin; then if $darwin ; then
javaHome="$(dirname \"$javaExecutable\")" javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="$(cd \"$javaHome\" && pwd -P)/javac" javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else else
javaExecutable="$(readlink -f \"$javaExecutable\")" javaExecutable="`readlink -f \"$javaExecutable\"`"
fi fi
javaHome="$(dirname \"$javaExecutable\")" javaHome="`dirname \"$javaExecutable\"`"
javaHome=$(expr "$javaHome" : '\(.*\)/bin') javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome" JAVA_HOME="$javaHome"
export JAVA_HOME export JAVA_HOME
fi fi
fi fi
fi fi
if [ -z "$JAVACMD" ]; then if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ]; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ]; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables # IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java" JAVACMD="$JAVA_HOME/jre/sh/java"
else else
JAVACMD="$JAVA_HOME/bin/java" JAVACMD="$JAVA_HOME/bin/java"
fi fi
else else
JAVACMD="$(which java)" JAVACMD="`which java`"
fi fi
fi fi
if [ ! -x "$JAVACMD" ]; then if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2 echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2 echo " We cannot execute $JAVACMD" >&2
exit 1 exit 1
fi fi
if [ -z "$JAVA_HOME" ]; then if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set." echo "Warning: JAVA_HOME environment variable is not set."
fi fi
@@ -172,24 +165,22 @@ CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# first directory with .mvn subdirectory is considered project base directory # first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() { find_maven_basedir() {
if [ -z "$1" ]; then if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir" echo "Path not specified to find_maven_basedir"
return 1 return 1
fi fi
basedir="$1" basedir="$1"
wdir="$1" wdir="$1"
while [ "$wdir" != '/' ]; do while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ]; then if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir basedir=$wdir
break break
fi fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc) # workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then if [ -d "${wdir}" ]; then
wdir=$( wdir=`cd "$wdir/.."; pwd`
cd "$wdir/.."
pwd
)
fi fi
# end of workaround # end of workaround
done done
@@ -199,13 +190,13 @@ find_maven_basedir() {
# concatenates all lines of a file # concatenates all lines of a file
concat_lines() { concat_lines() {
if [ -f "$1" ]; then if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' <"$1")" echo "$(tr -s '\n' ' ' < "$1")"
fi fi
} }
BASE_DIR=$(find_maven_basedir "$(pwd)") BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then if [ -z "$BASE_DIR" ]; then
exit 1 exit 1;
fi fi
########################################################################################## ##########################################################################################
@@ -213,78 +204,75 @@ fi
# This allows using the maven wrapper in projects that prohibit checking in binary data. # This allows using the maven wrapper in projects that prohibit checking in binary data.
########################################################################################## ##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar" echo "Found .mvn/wrapper/maven-wrapper.jar"
fi fi
else else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
fi
while IFS="=" read key value; do
case "$key" in wrapperUrl)
jarUrl="$value"
break
;;
esac
done <"$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
fi
if command -v wget >/dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget" echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then if [ -n "$MVNW_REPOURL" ]; then
wget "$jarUrl" -O "$wrapperJarPath" jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
else else
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
fi fi
elif command -v curl >/dev/null; then while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl" echo "Downloading from: $jarUrl"
fi fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then if $cygwin; then
javaClass=$(cygpath --path --windows "$javaClass") wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..." echo "Found wget ... using wget"
fi fi
# Compiling the Java class if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
("$JAVA_HOME/bin/javac" "$javaClass") wget "$jarUrl" -O "$wrapperJarPath"
fi else
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
# Running the downloader fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..." echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi fi
fi
fi fi
########################################################################################## ##########################################################################################
# End of extension # End of extension
@@ -299,13 +287,13 @@ MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java # For Cygwin, switch paths to Windows format before running java
if $cygwin; then if $cygwin; then
[ -n "$M2_HOME" ] && [ -n "$M2_HOME" ] &&
M2_HOME=$(cygpath --path --windows "$M2_HOME") M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] && [ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] && [ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --windows "$CLASSPATH") CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] && [ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi fi
# Provide a "standardized" way to retrieve the CLI args that will # Provide a "standardized" way to retrieve the CLI args that will

10
mvnw.cmd vendored
View File

@@ -7,7 +7,7 @@
@REM "License"); you may not use this file except in compliance @REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at @REM with the License. You may obtain a copy of the License at
@REM @REM
@REM https://www.apache.org/licenses/LICENSE-2.0 @REM http://www.apache.org/licenses/LICENSE-2.0
@REM @REM
@REM Unless required by applicable law or agreed to in writing, @REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an @REM software distributed under the License is distributed on an
@@ -18,7 +18,7 @@
@REM ---------------------------------------------------------------------------- @REM ----------------------------------------------------------------------------
@REM ---------------------------------------------------------------------------- @REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script @REM Maven Start Up Batch script
@REM @REM
@REM Required ENV vars: @REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir @REM JAVA_HOME - location of a JDK home dir
@@ -26,7 +26,7 @@
@REM Optional ENV vars @REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir @REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use @REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@@ -120,7 +120,7 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
@@ -134,7 +134,7 @@ if exist %WRAPPER_JAR% (
) )
) else ( ) else (
if not "%MVNW_REPOURL%" == "" ( if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
) )
if "%MVNW_VERBOSE%" == "true" ( if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ... echo Couldn't find %WRAPPER_JAR%, downloading it ...

70
pom.xml
View File

@@ -76,14 +76,6 @@
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<!--Json-->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<!-- 七牛云SDK --> <!-- 七牛云SDK -->
<dependency> <dependency>
<groupId>com.qiniu</groupId> <groupId>com.qiniu</groupId>
@@ -139,7 +131,7 @@
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<version>4.12</version> <version>4.13.1</version>
</dependency> </dependency>
<!-- JJwt --> <!-- JJwt -->
@@ -170,6 +162,46 @@
</dependency> </dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
</dependency>
<dependency>
<groupId>com.github.kstyrc</groupId>
<artifactId>embedded-redis</artifactId>
<version>0.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>1.7.2</version>
</dependency>
</dependencies> </dependencies>
@@ -179,26 +211,6 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
</plugin> </plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin> <plugin>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId> <artifactId>kotlin-maven-plugin</artifactId>

View File

@@ -1,20 +1,34 @@
package cn.celess.blog; package cn.celess.blog;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger; import org.springframework.boot.ApplicationArguments;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
/**
* @author zheng
*/
@SpringBootApplication @SpringBootApplication
@EnableAsync @EnableAsync
@MapperScan("cn.celess.blog.mapper") @MapperScan("cn.celess.blog.mapper")
public class BlogApplication { public class BlogApplication {
public static final Logger logger = LoggerFactory.getLogger(BlogApplication.class); public static ConfigurableApplicationContext context;
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(BlogApplication.class, args); context = SpringApplication.run(BlogApplication.class, args);
logger.info("启动完成!"); }
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();
} }
} }

View File

@@ -0,0 +1,59 @@
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);
}
}
}

View File

@@ -1,41 +1,81 @@
package cn.celess.blog.configuration; package cn.celess.blog.configuration;
import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; 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 * @author : xiaohai
* @date : 2019/03/28 14:26 * @date : 2019/03/28 14:26
*/ */
@Slf4j
@Configuration @Configuration
public class DruidConfig { public class DruidConfig {
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}") @Autowired
private String username; Environment env;
@Value("${spring.datasource.password}") public static final String DB_CONFIG_PATH = System.getProperty("user.home") + "/blog/application.properties";
private String password; public static final String DB_CONFIG_URL_PREFIX = "spring.datasource.url";
public static final String DB_CONFIG_USERNAME_PREFIX = "spring.datasource.username";
@Value("${spring.datasource.driver-class-name}") public static final String DB_CONFIG_PASSWORD_PREFIX = "spring.datasource.password";
private String driverClassName; public static final String DB_CONFIG_DRIVER_CLASS_NAME_PREFIX = "spring.datasource.driver-class-name";
public static final String TEST_PROFILES = "test";
@Bean @Bean
public DruidDataSource druidDataSource() { public DruidDataSource initDataSource() throws IOException {
DruidDataSource dataSource = new DruidDataSource(); DruidDataSource dataSource;
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); File file = new File(DB_CONFIG_PATH);
// 数据库基本信息 if (file.exists() && !Arrays.asList(env.getActiveProfiles()).contains(TEST_PROFILES)) {
dataSource.setUrl(dbUrl); log.debug("从文件中获取数据库配置");
dataSource.setUsername(username); dataSource = readConfigFromFile(file);
dataSource.setPassword(password); } else {
log.debug("默认数据库配置");
// 数据库连接池配置 dataSource = defaultDruidSource();
}
dataSource.setInitialSize(10); dataSource.setInitialSize(10);
dataSource.setMinIdle(10); dataSource.setMinIdle(10);
dataSource.setMaxActive(100); 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; return dataSource;
} }
} }

View File

@@ -31,19 +31,16 @@ public class RedisConfig extends CachingConfigurerSupport {
@Override @Override
@Bean @Bean
public KeyGenerator keyGenerator() { public KeyGenerator keyGenerator() {
return new KeyGenerator() { return (target, method, params) -> {
@Override StringBuilder sb = new StringBuilder();
public Object generate(Object target, Method method, Object... params) { String name = target.getClass().getName();
StringBuilder sb = new StringBuilder(); sb.append(name.substring(name.lastIndexOf(".") + 1));
String name = target.getClass().getName(); sb.append(":");
sb.append(name.substring(name.lastIndexOf(".") + 1)); sb.append(method.getName());
sb.append(":"); for (Object obj : params) {
sb.append(method.getName()); sb.append("-").append(obj.toString());
for (Object obj : params) {
sb.append("-").append(obj.toString());
}
return sb.toString();
} }
return sb.toString();
}; };
} }

View File

@@ -5,7 +5,7 @@ import cn.celess.blog.entity.Response;
import cn.celess.blog.service.UserService; import cn.celess.blog.service.UserService;
import cn.celess.blog.util.JwtUtil; import cn.celess.blog.util.JwtUtil;
import cn.celess.blog.util.RedisUtil; import cn.celess.blog.util.RedisUtil;
import net.sf.json.JSONObject; import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -84,7 +84,7 @@ public class AuthenticationFilter implements HandlerInterceptor {
response.setHeader("Content-Type", "application/json;charset=UTF-8"); response.setHeader("Content-Type", "application/json;charset=UTF-8");
try { try {
logger.info("鉴权失败,[code:{},msg:{},path:{}]", e.getCode(), e.getMsg(), request.getRequestURI() + "?" + request.getQueryString()); logger.info("鉴权失败,[code:{},msg:{},path:{}]", e.getCode(), e.getMsg(), request.getRequestURI() + "?" + request.getQueryString());
response.getWriter().println(JSONObject.fromObject(Response.response(e, null))); response.getWriter().println(new ObjectMapper().writeValueAsString(Response.response(e, null)));
} catch (IOException ex) { } catch (IOException ex) {
ex.printStackTrace(); ex.printStackTrace();
} }

View File

@@ -25,7 +25,6 @@ public class SessionListener implements HttpSessionListener {
@Override @Override
public void sessionCreated(HttpSessionEvent se) { public void sessionCreated(HttpSessionEvent se) {
// TODO : can move 'visit' api to here
se.getSession().setAttribute("visitDetail", new HashMap<String, Integer>()); se.getSession().setAttribute("visitDetail", new HashMap<String, Integer>());
// 10s for debug // 10s for debug
// se.getSession().setMaxInactiveInterval(10); // se.getSession().setMaxInactiveInterval(10);
@@ -44,9 +43,7 @@ public class SessionListener implements HttpSessionListener {
sb.append("\t登录情况 => "); sb.append("\t登录情况 => ");
String email = (String) se.getSession().getAttribute("email"); String email = (String) se.getSession().getAttribute("email");
sb.append(email == null ? "游客访问" : email); sb.append(email == null ? "游客访问" : email);
visitDetail.forEach((s, integer) -> { visitDetail.forEach((s, integer) -> sb.append("\n").append("Method:[").append(s.split(":")[1]).append("]\tTimes:[").append(integer).append("]\tPath:[").append(s.split(":")[0]).append("]"));
sb.append("\n").append("Method:[").append(s.split(":")[1]).append("]\tTimes:[").append(integer).append("]\tPath:[").append(s.split(":")[0]).append("]");
});
log.info(sb.toString()); log.info(sb.toString());
} }
} }

View File

@@ -3,17 +3,15 @@ package cn.celess.blog.controller;
import cn.celess.blog.enmu.ResponseEnum; import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.entity.Response; import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.model.ArticleModel; import cn.celess.blog.entity.model.ArticleModel;
import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.entity.request.ArticleReq; import cn.celess.blog.entity.request.ArticleReq;
import cn.celess.blog.service.ArticleService; import cn.celess.blog.service.ArticleService;
import cn.celess.blog.util.RedisUserUtil; import cn.celess.blog.util.RedisUserUtil;
import cn.celess.blog.util.SitemapGenerateUtil; import cn.celess.blog.util.SitemapGenerateUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author : xiaohai * @author : xiaohai
@@ -27,6 +25,8 @@ public class ArticleController {
SitemapGenerateUtil sitemapGenerateUtil; SitemapGenerateUtil sitemapGenerateUtil;
@Autowired @Autowired
RedisUserUtil redisUserUtil; RedisUserUtil redisUserUtil;
@Value("${spring.profiles.active}")
private String activeModel;
/** /**
* 新建一篇文章 * 新建一篇文章
@@ -37,7 +37,9 @@ public class ArticleController {
@PostMapping("/admin/article/create") @PostMapping("/admin/article/create")
public Response create(@RequestBody ArticleReq body) { public Response create(@RequestBody ArticleReq body) {
ArticleModel articleModel = articleService.create(body); ArticleModel articleModel = articleService.create(body);
sitemapGenerateUtil.createSitemap(); if ("prod".equals(activeModel)) {
sitemapGenerateUtil.createSitemap();
}
return Response.success(articleModel); return Response.success(articleModel);
} }
@@ -50,7 +52,9 @@ public class ArticleController {
@DeleteMapping("/admin/article/del") @DeleteMapping("/admin/article/del")
public Response delete(@RequestParam("articleID") long articleId) { public Response delete(@RequestParam("articleID") long articleId) {
boolean delete = articleService.delete(articleId); boolean delete = articleService.delete(articleId);
sitemapGenerateUtil.createSitemap(); if ("prod".equals(activeModel)) {
sitemapGenerateUtil.createSitemap();
}
return Response.success(delete); return Response.success(delete);
} }
@@ -63,7 +67,9 @@ public class ArticleController {
@PutMapping("/admin/article/update") @PutMapping("/admin/article/update")
public Response update(@RequestBody ArticleReq body) { public Response update(@RequestBody ArticleReq body) {
ArticleModel update = articleService.update(body); ArticleModel update = articleService.update(body);
sitemapGenerateUtil.createSitemap(); if ("prod".equals(activeModel)) {
sitemapGenerateUtil.createSitemap();
}
return Response.success(update); return Response.success(update);
} }
@@ -114,7 +120,7 @@ public class ArticleController {
@GetMapping("/admin/articles") @GetMapping("/admin/articles")
public Response adminArticles(@RequestParam(name = "page", defaultValue = "1") int page, public Response adminArticles(@RequestParam(name = "page", defaultValue = "1") int page,
@RequestParam(name = "count", defaultValue = "10") int count, @RequestParam(name = "count", defaultValue = "10") int count,
@RequestParam(name = "deleted", defaultValue = "false") boolean deleted) { @RequestParam(name = "deleted", required = false) Boolean deleted) {
return Response.success(articleService.adminArticles(count, page, deleted)); return Response.success(articleService.adminArticles(count, page, deleted));
} }

View File

@@ -2,15 +2,16 @@ package cn.celess.blog.controller;
import cn.celess.blog.enmu.ResponseEnum; import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.entity.Response; import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.model.QiniuResponse; import cn.celess.blog.entity.model.FileResponse;
import cn.celess.blog.exception.MyException; import cn.celess.blog.exception.MyException;
import cn.celess.blog.service.CountService; import cn.celess.blog.service.CountService;
import cn.celess.blog.service.QiniuService; import cn.celess.blog.service.FileService;
import cn.celess.blog.util.HttpUtil; import cn.celess.blog.util.HttpUtil;
import cn.celess.blog.util.RedisUserUtil;
import cn.celess.blog.util.RedisUtil; import cn.celess.blog.util.RedisUtil;
import cn.celess.blog.util.VeriCodeUtil; import cn.celess.blog.util.VeriCodeUtil;
import net.sf.json.JSONArray; import com.fasterxml.jackson.databind.JsonNode;
import net.sf.json.JSONObject; import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -27,9 +28,7 @@ import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Enumeration; import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
@@ -43,11 +42,11 @@ public class CommonController {
@Autowired @Autowired
CountService countService; CountService countService;
@Autowired @Autowired
QiniuService qiniuService; FileService fileService;
@Autowired @Autowired
RedisUtil redisUtil; RedisUtil redisUtil;
@Autowired @Autowired
HttpServletRequest request; RedisUserUtil redisUserUtil;
@GetMapping("/counts") @GetMapping("/counts")
@@ -89,7 +88,7 @@ public class CommonController {
* @throws IOException IOException * @throws IOException IOException
*/ */
@GetMapping(value = "/imgCode", produces = MediaType.IMAGE_PNG_VALUE) @GetMapping(value = "/imgCode", produces = MediaType.IMAGE_PNG_VALUE)
public void getImg(HttpServletResponse response) throws IOException { public void getImg(HttpServletRequest request, HttpServletResponse response) throws IOException {
Object[] obj = VeriCodeUtil.createImage(); Object[] obj = VeriCodeUtil.createImage();
request.getSession().setAttribute("code", obj[0]); request.getSession().setAttribute("code", obj[0]);
//将图片输出给浏览器 //将图片输出给浏览器
@@ -133,12 +132,14 @@ public class CommonController {
* FIXME :: 单张图片多次上传的问题 * FIXME :: 单张图片多次上传的问题
* editor.md图片上传的接口 * editor.md图片上传的接口
* FUCK !!! * FUCK !!!
* * !! 推荐使用 fileUpload(/fileUpload) 接口
* @param file 文件 * @param file 文件
*/ */
@Deprecated
@PostMapping("/imgUpload") @PostMapping("/imgUpload")
public void upload(HttpServletRequest request, HttpServletResponse response, @RequestParam("editormd-image-file") MultipartFile file) throws IOException { public void upload(HttpServletRequest request, HttpServletResponse response, @RequestParam("editormd-image-file") MultipartFile file) throws IOException {
JSONObject jsonObject = new JSONObject(); Map<String, Object> map = new HashMap<>();
ObjectMapper mapper = new ObjectMapper();
String uploadTimesStr = redisUtil.get(request.getRemoteAddr() + "-ImgUploadTimes"); String uploadTimesStr = redisUtil.get(request.getRemoteAddr() + "-ImgUploadTimes");
int uploadTimes = 0; int uploadTimes = 0;
if (uploadTimesStr != null) { if (uploadTimesStr != null) {
@@ -148,11 +149,11 @@ public class CommonController {
throw new MyException(ResponseEnum.FAILURE.getCode(), "上传次数已达10次请2小时后在上传"); throw new MyException(ResponseEnum.FAILURE.getCode(), "上传次数已达10次请2小时后在上传");
} }
request.setCharacterEncoding("utf-8"); request.setCharacterEncoding("utf-8");
response.setContentType("text/html"); response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
if (file.isEmpty()) { if (file.isEmpty()) {
jsonObject.put("success", 0); map.put("success", 0);
jsonObject.put("message", "上传失败,请选择文件"); map.put("message", "上传失败,请选择文件");
response.getWriter().println(jsonObject.toString()); response.getWriter().println(mapper.writeValueAsString(map));
return; return;
} }
String fileName = file.getOriginalFilename(); String fileName = file.getOriginalFilename();
@@ -160,26 +161,62 @@ public class CommonController {
String mime = fileName.substring(fileName.lastIndexOf(".")); String mime = fileName.substring(fileName.lastIndexOf("."));
if (".png".equals(mime.toLowerCase()) || ".jpg".equals(mime.toLowerCase()) || if (".png".equals(mime.toLowerCase()) || ".jpg".equals(mime.toLowerCase()) ||
".jpeg".equals(mime.toLowerCase()) || ".bmp".equals(mime.toLowerCase())) { ".jpeg".equals(mime.toLowerCase()) || ".bmp".equals(mime.toLowerCase())) {
QiniuResponse qiniuResponse = qiniuService.uploadFile(file.getInputStream(), "img_" + System.currentTimeMillis() + mime); FileResponse fileResponse = fileService.getFileManager().uploadFile(file.getInputStream(), "img_" + System.currentTimeMillis() + mime);
jsonObject.put("success", 1); map.put("success", 1);
jsonObject.put("message", "上传成功"); map.put("message", "上传成功");
jsonObject.put("url", "http://cdn.celess.cn/" + qiniuResponse.key); map.put("url", "http://cdn.celess.cn/" + fileResponse.key);
response.getWriter().println(jsonObject.toString()); response.getWriter().println(mapper.writeValueAsString(map));
redisUtil.setEx(request.getRemoteAddr() + "-ImgUploadTimes", uploadTimes + 1 + "", 2, TimeUnit.HOURS); redisUtil.setEx(request.getRemoteAddr() + "-ImgUploadTimes", uploadTimes + 1 + "", 2, TimeUnit.HOURS);
return; return;
} }
jsonObject.put("success", 0); map.put("success", 0);
jsonObject.put("message", "上传失败,请上传图片文件"); map.put("message", "上传失败,请上传图片文件");
response.getWriter().println(jsonObject.toString()); response.getWriter().println(mapper.writeValueAsString(map));
} }
@GetMapping("/bingPic") @GetMapping("/bingPic")
public Response bingPic() { public Response bingPic() {
ObjectMapper mapper = new ObjectMapper();
JsonNode root;
try {
root = mapper.readTree(HttpUtil.get("https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN"));
} catch (IOException e) {
return Response.failure(null);
}
JsonNode images = root.get("images").elements().next();
return Response.success("https://cn.bing.com" + images.get("url").asText());
}
JSONObject imageObj; @PostMapping("/fileUpload")
imageObj = JSONObject.fromObject(HttpUtil.get("https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN")); public Response<List<Map<String, Object>>> fileUpload(@RequestParam("file[]") MultipartFile[] files) throws IOException {
JSONArray jsonArray = imageObj.getJSONArray("images"); List<Map<String, Object>> result = new ArrayList<>();
String imageName = jsonArray.getJSONObject(0).getString("url"); String uploadTimesStr = redisUtil.get(redisUserUtil.get().getEmail() + "-fileUploadTimes");
return Response.success("https://cn.bing.com" + imageName); int uploadTimes = 0;
if (uploadTimesStr != null) {
uploadTimes = Integer.parseInt(uploadTimesStr);
}
if (uploadTimes == 10) {
throw new MyException(ResponseEnum.FAILURE.getCode(), "上传次数已达10次请2小时后在上传");
}
if (files.length == 0) {
throw new MyException(ResponseEnum.NO_FILE);
}
for (MultipartFile file : files) {
Map<String, Object> resp = new HashMap<>(4);
String fileName = file.getOriginalFilename();
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);
resp.put("originalFilename", fileName);
resp.put("success", fileResponse != null);
if (fileResponse != null) {
resp.put("host", "http://cdn.celess.cn/");
resp.put("path", fileResponse.key);
}
result.add(resp);
}
return Response.success(result);
} }
} }

View File

@@ -0,0 +1,39 @@
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());
}
}

View File

@@ -0,0 +1,78 @@
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";
}
}

View File

@@ -1,24 +1,18 @@
package cn.celess.blog.controller; package cn.celess.blog.controller;
import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.entity.PartnerSite; import cn.celess.blog.entity.PartnerSite;
import cn.celess.blog.entity.Response; import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.request.LinkApplyReq; import cn.celess.blog.entity.request.LinkApplyReq;
import cn.celess.blog.entity.request.LinkReq; import cn.celess.blog.entity.request.LinkReq;
import cn.celess.blog.exception.MyException;
import cn.celess.blog.service.MailService; import cn.celess.blog.service.MailService;
import cn.celess.blog.service.PartnerSiteService; import cn.celess.blog.service.PartnerSiteService;
import cn.celess.blog.util.DateFormatUtil;
import cn.celess.blog.util.RedisUtil; import cn.celess.blog.util.RedisUtil;
import cn.celess.blog.util.RegexUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.stream.Collectors;
/** /**
* @author : xiaohai * @author : xiaohai
@@ -52,21 +46,15 @@ public class LinksController {
@GetMapping("/links") @GetMapping("/links")
public Response allForOpen() { public Response allForOpen() {
List<PartnerSite> sites = new ArrayList<>(); List<PartnerSite> sites = partnerSiteService.findAll().stream().peek(partnerSite -> partnerSite.setOpen(null)).collect(Collectors.toList());
for (PartnerSite p : partnerSiteService.findAll()) {
if (p.getOpen()) {
//隐藏open字段
p.setOpen(null);
sites.add(p);
}
}
return Response.success(sites); return Response.success(sites);
} }
@GetMapping("/admin/links") @GetMapping("/admin/links")
public Response all(@RequestParam("page") int page, public Response all(@RequestParam("page") int page,
@RequestParam("count") int count) { @RequestParam("count") int count,
return Response.success(partnerSiteService.partnerSitePages(page, count)); @RequestParam(value = "deleted", required = false) Boolean deleted) {
return Response.success(partnerSiteService.partnerSitePages(page, count, deleted));
} }
@PostMapping("/apply") @PostMapping("/apply")

View File

@@ -3,12 +3,13 @@ package cn.celess.blog.controller;
import cn.celess.blog.entity.Response; import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.model.TagModel; import cn.celess.blog.entity.model.TagModel;
import cn.celess.blog.service.TagService; import cn.celess.blog.service.TagService;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @author : xiaohai * @author : xiaohai
@@ -44,13 +45,13 @@ public class TagController {
@GetMapping("/tags/nac") @GetMapping("/tags/nac")
public Response getTagNameAndCount() { public Response getTagNameAndCount() {
List<JSONObject> nameAndCount = new ArrayList<>(); List<Map<String, Object>> nameAndCount = new ArrayList<>();
List<TagModel> all = tagService.findAll(); List<TagModel> all = tagService.findAll();
for (TagModel t : all) { for (TagModel t : all) {
JSONObject jsonObject = new JSONObject(); Map<String, Object> map = new HashMap<>(2);
jsonObject.put("name", t.getName()); map.put("name", t.getName());
jsonObject.put("size", t.getArticles().size()); map.put("size", t.getArticles().size());
nameAndCount.add(jsonObject); nameAndCount.add(map);
} }
return Response.success(nameAndCount); return Response.success(nameAndCount);
} }

View File

@@ -116,8 +116,8 @@ public class UserController {
} }
@GetMapping("/admin/users") @GetMapping("/admin/users")
public Response getAllUser(@RequestParam("page") int pageNum, @RequestParam("count") int count) { public Response getAllUser(@RequestParam("page") int pageNum, @RequestParam("count") int count, @RequestParam(name = "status", required = false) Integer status) {
return Response.success(userService.getUserList(pageNum, count)); return Response.success(userService.getUserList(pageNum, count, status));
} }
@GetMapping("/emailStatus/{email}") @GetMapping("/emailStatus/{email}")

View File

@@ -27,7 +27,7 @@ public class VisitorController {
@GetMapping("/admin/visitor/page") @GetMapping("/admin/visitor/page")
public Response page(@RequestParam(value = "count", required = false, defaultValue = "10") int count, public Response page(@RequestParam(value = "count", required = false, defaultValue = "10") int count,
@RequestParam(value = "page", required = false, defaultValue = "1") int page, @RequestParam(value = "page", required = false, defaultValue = "1") int page,
@RequestParam(value = "showLocation", required = false, defaultValue = "false") boolean showLocation) { @RequestParam(value = "showLocation", required = false, defaultValue = "true") boolean showLocation) {
return Response.success(visitorService.visitorPage(page, count, showLocation)); return Response.success(visitorService.visitorPage(page, count, showLocation));
} }

View File

@@ -0,0 +1,37 @@
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;
}
}

View File

@@ -34,6 +34,7 @@ public enum ResponseEnum {
PWD_NOT_SAME(3602, "新密码与原密码不相同"), PWD_NOT_SAME(3602, "新密码与原密码不相同"),
LOGIN_EXPIRED(3700, "登陆过期"), LOGIN_EXPIRED(3700, "登陆过期"),
LOGOUT(3710, "账户已注销"), LOGOUT(3710, "账户已注销"),
CAN_NOT_USE(3711, "账户不可用"),
PWD_WRONG(3800, "密码不正确"), PWD_WRONG(3800, "密码不正确"),
JWT_EXPIRED(3810, "Token过期"), JWT_EXPIRED(3810, "Token过期"),
@@ -61,6 +62,8 @@ public enum ResponseEnum {
APPLY_LINK_NO_ADD_THIS_SITE(7200, "暂未在您的网站中抓取到本站链接"), APPLY_LINK_NO_ADD_THIS_SITE(7200, "暂未在您的网站中抓取到本站链接"),
DATA_EXPIRED(7300, "数据过期"), DATA_EXPIRED(7300, "数据过期"),
CANNOT_GET_DATA(7400, "暂无法获取到数据"), CANNOT_GET_DATA(7400, "暂无法获取到数据"),
NO_FILE(7500, "未选择文件,请重新选择"),
//提交更新之前,没有获取数据/, //提交更新之前,没有获取数据/,
DID_NOT_GET_THE_DATA(8020, "非法访问"), DID_NOT_GET_THE_DATA(8020, "非法访问"),

View File

@@ -1,5 +1,11 @@
package cn.celess.blog.enmu; package cn.celess.blog.enmu;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import java.util.HashMap;
import java.util.Map;
/** /**
* @Author: 小海 * @Author: 小海
* @Date: 2020-05-22 21:32 * @Date: 2020-05-22 21:32
@@ -36,4 +42,31 @@ public enum UserAccountStatusEnum {
public String getDesc() { public String getDesc() {
return desc; return desc;
} }
public static UserAccountStatusEnum get(int code) {
for (UserAccountStatusEnum value : UserAccountStatusEnum.values()) {
if (value.code == code) {
return value;
}
}
return null;
}
@JsonCreator
public static UserAccountStatusEnum get(Map<String, Object> map) {
for (UserAccountStatusEnum value : UserAccountStatusEnum.values()) {
if (value.code == (int) map.get("code") && value.desc.equals(map.get("desc"))) {
return value;
}
}
return null;
}
@JsonValue
public Map<String, Object> toJson() {
Map<String, Object> map = new HashMap<>(2);
map.put("code", code);
map.put("desc", desc);
return map;
}
} }

View File

@@ -0,0 +1,26 @@
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();
}
}

View File

@@ -0,0 +1,38 @@
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;
}

View File

@@ -1,8 +1,9 @@
package cn.celess.blog.entity; package cn.celess.blog.entity;
import cn.celess.blog.enmu.ResponseEnum; import cn.celess.blog.enmu.ResponseEnum;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data; import lombok.Data;
import net.sf.json.JSONObject; import lombok.SneakyThrows;
import java.io.Serializable; import java.io.Serializable;
@@ -31,8 +32,8 @@ public class Response<T> implements Serializable {
* @param result 结果 * @param result 结果
* @return Response * @return Response
*/ */
public static Response success(Object result) { public static <T> Response<T> success(T result) {
return new Response(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMsg(), result); return new Response<T>(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMsg(), result);
} }
/** /**
@@ -41,8 +42,8 @@ public class Response<T> implements Serializable {
* @param result 结果 * @param result 结果
* @return Response * @return Response
*/ */
public static Response failure(String result) { public static Response<String> failure(String result) {
return new Response(ResponseEnum.FAILURE.getCode(), ResponseEnum.FAILURE.getMsg(), result); return new Response<String>(ResponseEnum.FAILURE.getCode(), ResponseEnum.FAILURE.getMsg(), result);
} }
/** /**
@@ -52,13 +53,13 @@ public class Response<T> implements Serializable {
* @param result 结果 * @param result 结果
* @return Response * @return Response
*/ */
public static Response response(ResponseEnum r, String result) { public static <T> Response<T> response(ResponseEnum r, T result) {
return new Response(r.getCode(), r.getMsg(), result); return new Response<T>(r.getCode(), r.getMsg(), result);
} }
@SneakyThrows
@Override @Override
public String toString() { public String toString() {
JSONObject jsonObject = JSONObject.fromObject(this); return new ObjectMapper().writeValueAsString(this);
return jsonObject.toString();
} }
} }

View File

@@ -0,0 +1,25 @@
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;
}

View File

@@ -1,13 +1,13 @@
package cn.celess.blog.entity.model; package cn.celess.blog.entity.model;
/** /**
* @author : xiaohai * @author : xiaohai
* @date : 2019/04/21 22:43 * @date : 2019/04/21 22:43
*/ */
public class QiniuResponse { public class FileResponse {
public String key; public String key;
public String hash; public String hash;
public String bucket; public String type;
public long fsize; public long size;
} }

View File

@@ -1,5 +1,6 @@
package cn.celess.blog.entity.model; package cn.celess.blog.entity.model;
import cn.celess.blog.enmu.UserAccountStatusEnum;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -38,5 +39,5 @@ public class UserModel {
private String token; private String token;
private int status; private UserAccountStatusEnum status;
} }

View File

@@ -1,12 +1,16 @@
package cn.celess.blog.entity.request; package cn.celess.blog.entity.request;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
/** /**
* @author : xiaohai * @author : xiaohai
* @date : 2019/06/01 22:47 * @date : 2019/06/01 22:47
*/ */
@Data @Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginReq { public class LoginReq {
private String email; private String email;
private String password; private String password;

View File

@@ -10,7 +10,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.SimpleMailMessage;
import org.springframework.validation.BindException; import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
@@ -18,6 +20,10 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.Set;
/** /**
* @author : xiaohai * @author : xiaohai
@@ -41,27 +47,32 @@ public class ExceptionHandle {
if (e instanceof MyException) { if (e instanceof MyException) {
MyException exception = (MyException) e; MyException exception = (MyException) e;
logger.debug("返回了自定义的exception,[code={},msg={},result={}]", exception.getCode(), e.getMessage(), exception.getResult()); 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) { if (e instanceof HttpRequestMethodNotSupportedException) {
logger.debug("遇到请求路径与请求方法不匹配的请求,[msg={}path:{},method:{}]", e.getMessage(), request.getRequestURL(), request.getMethod()); 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) { if (e instanceof MethodArgumentTypeMismatchException) {
logger.debug("输入类型不匹配,[msg={}]", e.getMessage()); 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) { if (e instanceof BindException) {
logger.debug("数据验证失败,[msg={}]", e.getMessage()); 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) { if (e instanceof MissingServletRequestParameterException) {
logger.debug("数据输入不完整,[msg={}]", e.getMessage()); logger.debug("数据输入不完整,[msg={}]", e.getMessage());
return new Response(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入不完整,请检查", null); 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);
} }
// 发送错误信息到邮箱 // 发送错误信息到邮箱
@@ -70,7 +81,7 @@ public class ExceptionHandle {
sendMessage(e); sendMessage(e);
} }
e.printStackTrace(); e.printStackTrace();
return new Response(ResponseEnum.ERROR.getCode(), "服务器出现错误,已记录", null); return new Response<>(ResponseEnum.ERROR.getCode(), "服务器出现错误,已记录", null);
} }
/** /**
@@ -83,7 +94,12 @@ public class ExceptionHandle {
simpleMailMessage.setTo("a@celess.cn"); simpleMailMessage.setTo("a@celess.cn");
simpleMailMessage.setSubject("服务器出现了错误"); simpleMailMessage.setSubject("服务器出现了错误");
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
msg.append("requirePath:\n").append(request.getRequestURL().toString()).append("?").append(request.getQueryString()).append("\n\n\n"); String queryString = request.getQueryString();
msg.append("requirePath:\n").append(request.getRequestURL().toString());
if (queryString != null) {
msg.append("?").append(queryString);
}
msg.append("\n\n\n");
msg.append("msg:\n").append(e.getMessage()).append("\n\n\n"); msg.append("msg:\n").append(e.getMessage()).append("\n\n\n");
msg.append("date:\n").append(DateFormatUtil.getNow()).append("\n\n\n"); msg.append("date:\n").append(DateFormatUtil.getNow()).append("\n\n\n");
msg.append("from:\n").append(request.getHeader("User-Agent")).append("\n\n\n"); msg.append("from:\n").append(request.getHeader("User-Agent")).append("\n\n\n");

View File

@@ -22,6 +22,12 @@ public class MyException extends RuntimeException {
this.code = e.getCode(); this.code = e.getCode();
} }
public MyException(ResponseEnum e, Object result) {
super(e.getMsg());
this.code = e.getCode();
this.result = result;
}
public MyException(ResponseEnum e, String msg) { public MyException(ResponseEnum e, String msg) {
super(msg + e.getMsg()); super(msg + e.getMsg());
this.code = e.getCode(); this.code = e.getCode();

View File

@@ -0,0 +1,55 @@
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);
}

View File

@@ -36,5 +36,6 @@ public interface PartnerMapper {
List<PartnerSite> findAll(); List<PartnerSite> findAll();
List<PartnerSite> findAll(Boolean deleted);
} }

View File

@@ -53,6 +53,8 @@ public interface UserMapper {
int setUserRole(Long id, String role); int setUserRole(Long id, String role);
List<User> findAll(Integer status);
List<User> findAll(); List<User> findAll();
int update(User user); int update(User user);

View File

@@ -52,7 +52,7 @@ public interface ArticleService {
* @param page 数据页 * @param page 数据页
* @return 分页数据 * @return 分页数据
*/ */
PageData<ArticleModel> adminArticles(int count, int page, boolean deleted); PageData<ArticleModel> adminArticles(int count, int page, Boolean deleted);
/** /**
* 获取文章状态为开放的文章 * 获取文章状态为开放的文章

View File

@@ -0,0 +1,40 @@
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);
}

View File

@@ -0,0 +1,18 @@
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();
}

View File

@@ -0,0 +1,20 @@
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);
}

View File

@@ -45,7 +45,7 @@ public interface PartnerSiteService {
* @param page 数据页 * @param page 数据页
* @return 分页数据 * @return 分页数据
*/ */
PageData<PartnerSite> partnerSitePages(int page, int count); PageData<PartnerSite> partnerSitePages(int page, int count, Boolean deleted);
/** /**
* 获取全部数据 * 获取全部数据

View File

@@ -1,31 +0,0 @@
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();
}

View File

@@ -129,7 +129,7 @@ public interface UserService {
* @param page 数据页 * @param page 数据页
* @return 分页数据 * @return 分页数据
*/ */
PageData<UserModel> getUserList(Integer page, Integer count); PageData<UserModel> getUserList(Integer page, Integer count, Integer status);
/** /**
* 更改用户信息 * 更改用户信息

View File

@@ -2,10 +2,10 @@ package cn.celess.blog.service;
import cn.celess.blog.entity.model.PageData; import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.entity.model.WebUpdateModel; import cn.celess.blog.entity.model.WebUpdateModel;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @author : xiaohai * @author : xiaohai
@@ -59,5 +59,5 @@ public interface WebUpdateInfoService {
* *
* @return * @return
*/ */
JSONObject getLastestUpdateTime(); Map<String, Object> getLastestUpdateTime();
} }

View File

@@ -0,0 +1,36 @@
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;
}
}

View File

@@ -0,0 +1,104 @@
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;
}
}

View File

@@ -0,0 +1,120 @@
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;
}
}

View File

@@ -22,7 +22,6 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import sun.security.krb5.internal.PAData;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList; import java.util.ArrayList;
@@ -279,11 +278,16 @@ public class ArticleServiceImpl implements ArticleService {
* @return PageInfo * @return PageInfo
*/ */
@Override @Override
public PageData<ArticleModel> adminArticles(int count, int page, boolean deleted) { public PageData<ArticleModel> adminArticles(int count, int page, Boolean deleted) {
List<Article> articleList = articleMapper.findAll(); List<Article> articleList = articleMapper.findAll();
PageData<ArticleModel> pageData = new PageData<>(null, 0, count, page); PageData<ArticleModel> pageData = new PageData<>(null, 0, count, page);
List<Article> collect = articleList.stream().filter(article -> article.isDeleted() == deleted).collect(Collectors.toList()); List<Article> collect;
if (deleted != null) {
collect = articleList.stream().filter(article -> article.isDeleted() == deleted).collect(Collectors.toList());
} else {
collect = articleList;
}
pageData.setTotal(collect.size()); pageData.setTotal(collect.size());
List<ArticleModel> articleModels = collect.stream() List<ArticleModel> articleModels = collect.stream()
.peek(article -> article.setMdContent(null)) .peek(article -> article.setMdContent(null))
@@ -300,16 +304,12 @@ public class ArticleServiceImpl implements ArticleService {
public PageData<ArticleModel> retrievePageForOpen(int count, int page) { public PageData<ArticleModel> retrievePageForOpen(int count, int page) {
PageHelper.startPage(page, count); PageHelper.startPage(page, count);
List<Article> articleList = articleMapper.findAllByOpen(true); List<Article> articleList = articleMapper.findAllByOpen(true);
PageData<ArticleModel> pageData = new PageData<>(new PageInfo<Article>(articleList)); PageData<ArticleModel> pageData = new PageData<>(new PageInfo<>(articleList));
List<ArticleModel> articleModelList = new ArrayList<>();
articleList.forEach(article -> {
ArticleModel model = ModalTrans.article(article, true);
setPreAndNextArticle(model);
articleModelList.add(model);
});
List<ArticleModel> articleModelList = articleList
.stream()
.map(article -> setPreAndNextArticle(ModalTrans.article(article, true)))
.collect(Collectors.toList());
pageData.setList(articleModelList); pageData.setList(articleModelList);
return pageData; return pageData;
} }
@@ -323,17 +323,14 @@ public class ArticleServiceImpl implements ArticleService {
PageHelper.startPage(page, count); PageHelper.startPage(page, count);
List<Article> open = articleMapper.findAllByCategoryIdAndOpen(category.getId()); List<Article> open = articleMapper.findAllByCategoryIdAndOpen(category.getId());
List<ArticleModel> modelList = new ArrayList<>(); List<ArticleModel> modelList = open.stream()
.map(article -> ModalTrans.article(article, true))
open.forEach(article -> { .peek(articleModel -> {
ArticleModel model = ModalTrans.article(article, true); articleModel.setNextArticle(null);
model.setTags(null); articleModel.setPreArticle(null);
// setPreAndNextArticle(model); })
model.setNextArticle(null); .collect(Collectors.toList());
model.setPreArticle(null); return new PageData<>(new PageInfo<>(open), modelList);
modelList.add(model);
});
return new PageData<ArticleModel>(new PageInfo<Article>(open), modelList);
} }
@Override @Override
@@ -344,21 +341,22 @@ public class ArticleServiceImpl implements ArticleService {
} }
PageHelper.startPage(page, count); PageHelper.startPage(page, count);
List<ArticleTag> articleByTag = articleTagMapper.findArticleByTagAndOpen(tag.getId()); List<ArticleTag> articleByTag = articleTagMapper.findArticleByTagAndOpen(tag.getId());
List<ArticleModel> modelList = new ArrayList<>(); List<ArticleModel> modelList = articleByTag
articleByTag.forEach(articleTag -> { .stream()
ArticleModel model = ModalTrans.article(articleTag.getArticle(), true); .map(articleTag -> ModalTrans.article(articleTag.getArticle(), true))
model.setNextArticle(null); .peek(articleModel -> {
model.setPreArticle(null); articleModel.setNextArticle(null);
modelList.add(model); articleModel.setPreArticle(null);
}); }).collect(Collectors.toList());
return new PageData<ArticleModel>(new PageInfo<ArticleTag>(articleByTag), modelList); return new PageData<>(new PageInfo<>(articleByTag), modelList);
} }
private void setPreAndNextArticle(ArticleModel articleModel) { private ArticleModel setPreAndNextArticle(ArticleModel articleModel) {
if (articleModel == null) { if (articleModel == null) {
return; return null;
} }
articleModel.setPreArticle(ModalTrans.article(articleMapper.getPreArticle(articleModel.getId()), true)); articleModel.setPreArticle(ModalTrans.article(articleMapper.getPreArticle(articleModel.getId()), true));
articleModel.setNextArticle(ModalTrans.article(articleMapper.getNextArticle(articleModel.getId()), true)); articleModel.setNextArticle(ModalTrans.article(articleMapper.getNextArticle(articleModel.getId()), true));
return articleModel;
} }
} }

View File

@@ -17,8 +17,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author : xiaohai * @author : xiaohai
@@ -68,22 +68,25 @@ public class CategoryServiceImpl implements CategoryService {
public PageData<CategoryModel> retrievePage(int page, int count) { public PageData<CategoryModel> retrievePage(int page, int count) {
PageHelper.startPage(page, count); PageHelper.startPage(page, count);
List<Category> all = categoryMapper.findAll(); List<Category> all = categoryMapper.findAll();
List<CategoryModel> modelList = new ArrayList<>(); // 遍历没一个category
all.forEach(e -> { List<CategoryModel> modelList = all
CategoryModel model = ModalTrans.category(e); .stream()
List<Article> allByCategoryId = articleMapper.findAllByCategoryId(e.getId()); .map(ModalTrans::category)
List<ArticleModel> articleModelList = new ArrayList<>(); .peek(categoryModel -> {
allByCategoryId.forEach(article -> { // 根据category去查article并赋值给categoryModel
ArticleModel articleModel = ModalTrans.article(article, true); List<Article> allByCategoryId = articleMapper.findAllByCategoryId(categoryModel.getId());
articleModel.setPreArticle(null); List<ArticleModel> articleModelList = allByCategoryId
articleModel.setNextArticle(null); .stream()
articleModel.setTags(null); .map(article -> ModalTrans.article(article, true))
articleModelList.add(articleModel); .peek(articleModel -> {
}); // 去除不必要的字段
model.setArticles(articleModelList); articleModel.setPreArticle(null);
modelList.add(model); articleModel.setNextArticle(null);
}); articleModel.setTags(null);
})
return new PageData<CategoryModel>(new PageInfo<Category>(all), modelList); .collect(Collectors.toList());
categoryModel.setArticles(articleModelList);
}).collect(Collectors.toList());
return new PageData<>(new PageInfo<>(all), modelList);
} }
} }

View File

@@ -23,6 +23,7 @@ import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author : xiaohai * @author : xiaohai
@@ -59,7 +60,7 @@ public class CommentServiceImpl implements CommentService {
Comment comment = new Comment(); Comment comment = new Comment();
comment.setFromUser(user); comment.setFromUser(user);
User userTo = new User(); User userTo = new User();
userTo.setId(-1L); userTo.setId(null);
if (reqBody.getToUserId() != -1) { if (reqBody.getToUserId() != -1) {
userTo = userMapper.findById(reqBody.getToUserId()); userTo = userMapper.findById(reqBody.getToUserId());
comment.setToUser(userTo); comment.setToUser(userTo);
@@ -107,14 +108,11 @@ public class CommentServiceImpl implements CommentService {
@Override @Override
public List<CommentModel> retrievePageByPid(long pid) { public List<CommentModel> retrievePageByPid(long pid) {
List<Comment> allByPagePath = commentMapper.findAllByPid(pid); List<Comment> allByPagePath = commentMapper.findAllByPid(pid);
List<CommentModel> commentModels = new ArrayList<>(); return allByPagePath
allByPagePath.forEach(comment -> { .stream()
if (comment.getStatus() != CommentStatusEnum.DELETED.getCode()) { .filter(comment -> comment.getStatus() != CommentStatusEnum.DELETED.getCode())
commentModels.add(ModalTrans.comment(comment)); .map(ModalTrans::comment)
} .collect(Collectors.toList());
});
return commentModels;
} }
@Override @Override
@@ -145,14 +143,11 @@ public class CommentServiceImpl implements CommentService {
private PageData<CommentModel> pageTrans(List<Comment> commentList, boolean noResponseList) { private PageData<CommentModel> pageTrans(List<Comment> commentList, boolean noResponseList) {
PageInfo<Comment> p = PageInfo.of(commentList); PageInfo<Comment> p = PageInfo.of(commentList);
List<CommentModel> modelList = new ArrayList<>(); List<CommentModel> modelList = commentList
commentList.forEach(l -> { .stream()
CommentModel model = ModalTrans.comment(l); .map(ModalTrans::comment)
if (!noResponseList) { .peek(commentModel -> commentModel.setRespComment(this.retrievePageByPid(commentModel.getId())))
model.setRespComment(this.retrievePageByPid(model.getId())); .collect(Collectors.toList());
} return new PageData<>(p, modelList);
modelList.add(model);
});
return new PageData<CommentModel>(p, modelList);
} }
} }

View File

@@ -0,0 +1,118 @@
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;
}
}

View File

@@ -10,14 +10,13 @@ import cn.celess.blog.mapper.PartnerMapper;
import cn.celess.blog.service.MailService; import cn.celess.blog.service.MailService;
import cn.celess.blog.service.PartnerSiteService; import cn.celess.blog.service.PartnerSiteService;
import cn.celess.blog.util.HttpUtil; import cn.celess.blog.util.HttpUtil;
import cn.celess.blog.util.JwtUtil;
import cn.celess.blog.util.RedisUtil; import cn.celess.blog.util.RedisUtil;
import cn.celess.blog.util.RegexUtil; import cn.celess.blog.util.RegexUtil;
import com.alibaba.druid.util.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.SimpleMailMessage;
@@ -124,9 +123,9 @@ public class PartnerSiteServiceImpl implements PartnerSiteService {
} }
@Override @Override
public PageData<PartnerSite> partnerSitePages(int page, int count) { public PageData<PartnerSite> partnerSitePages(int page, int count, Boolean deleted) {
PageHelper.startPage(page, count); PageHelper.startPage(page, count);
List<PartnerSite> sitePage = partnerMapper.findAll(); List<PartnerSite> sitePage = partnerMapper.findAll(deleted);
PageInfo<PartnerSite> pageInfo = new PageInfo<PartnerSite>(sitePage); PageInfo<PartnerSite> pageInfo = new PageInfo<PartnerSite>(sitePage);
return new PageData<>(pageInfo, sitePage); return new PageData<>(pageInfo, sitePage);
} }

View File

@@ -1,87 +0,0 @@
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;
}
}

View File

@@ -21,6 +21,7 @@ import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author : xiaohai * @author : xiaohai
@@ -81,20 +82,22 @@ public class TagServiceImpl implements TagService {
List<Tag> tagList = tagMapper.findAll(); List<Tag> tagList = tagMapper.findAll();
List<TagModel> modelList = new ArrayList<>(); List<TagModel> modelList = new ArrayList<>();
tagList.forEach(tag -> modelList.add(ModalTrans.tag(tag))); tagList.forEach(tag -> modelList.add(ModalTrans.tag(tag)));
return new PageData<TagModel>(new PageInfo<Tag>(tagList), modelList); return new PageData<>(new PageInfo<>(tagList), modelList);
} }
@Override @Override
public List<TagModel> findAll() { public List<TagModel> findAll() {
List<TagModel> list = new ArrayList<>(); return tagMapper.findAll().stream()
tagMapper.findAll().forEach(e -> { .map(ModalTrans::tag)
TagModel model = ModalTrans.tag(e); .peek(tagModel -> {
List<ArticleTag> articleByTagAndOpen = articleTagMapper.findArticleByTagAndOpen(e.getId()); List<ArticleTag> articleByTagAndOpen = articleTagMapper.findArticleByTagAndOpen(tagModel.getId());
List<ArticleModel> articleModelList = new ArrayList<>(); tagModel.setArticles(
articleByTagAndOpen.forEach(articleTag -> articleModelList.add(ModalTrans.article(articleTag.getArticle(), true))); articleByTagAndOpen
model.setArticles(articleModelList); .stream()
list.add(model); .map(articleTag -> ModalTrans.article(articleTag.getArticle(), true))
}); .collect(Collectors.toList())
return list; );
})
.collect(Collectors.toList());
} }
} }

View File

@@ -2,36 +2,35 @@ package cn.celess.blog.service.serviceimpl;
import cn.celess.blog.enmu.ResponseEnum; import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.enmu.RoleEnum; import cn.celess.blog.enmu.RoleEnum;
import cn.celess.blog.enmu.UserAccountStatusEnum;
import cn.celess.blog.entity.Response; import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.User; 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.PageData;
import cn.celess.blog.entity.model.QiniuResponse;
import cn.celess.blog.entity.model.UserModel; import cn.celess.blog.entity.model.UserModel;
import cn.celess.blog.entity.request.LoginReq; import cn.celess.blog.entity.request.LoginReq;
import cn.celess.blog.entity.request.UserReq; import cn.celess.blog.entity.request.UserReq;
import cn.celess.blog.exception.MyException; import cn.celess.blog.exception.MyException;
import cn.celess.blog.mapper.UserMapper; import cn.celess.blog.mapper.UserMapper;
import cn.celess.blog.service.FileService;
import cn.celess.blog.service.MailService; import cn.celess.blog.service.MailService;
import cn.celess.blog.service.QiniuService;
import cn.celess.blog.service.UserService; import cn.celess.blog.service.UserService;
import cn.celess.blog.util.*; import cn.celess.blog.util.*;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.beans.Transient; import java.beans.Transient;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/** /**
* @author : xiaohai * @author : xiaohai
@@ -47,8 +46,8 @@ public class UserServiceImpl implements UserService {
HttpServletRequest request; HttpServletRequest request;
@Autowired @Autowired
MailService mailService; MailService mailService;
@Autowired @Resource(name = "fileServiceImpl")
QiniuService qiniuService; FileService fileService;
@Autowired @Autowired
RedisUtil redisUtil; RedisUtil redisUtil;
@Autowired @Autowired
@@ -102,6 +101,16 @@ public class UserServiceImpl implements UserService {
if (!RegexUtil.pwdMatch(loginReq.getPassword())) { if (!RegexUtil.pwdMatch(loginReq.getPassword())) {
throw new MyException(ResponseEnum.PARAMETERS_PWD_ERROR); throw new MyException(ResponseEnum.PARAMETERS_PWD_ERROR);
} }
User user = userMapper.findByEmail(loginReq.getEmail());
if (user == null) {
// 用户不存在
throw new MyException(ResponseEnum.USER_NOT_EXIST);
}
if (user.getStatus() != UserAccountStatusEnum.NORMAL.getCode()) {
throw new MyException(ResponseEnum.CAN_NOT_USE, UserAccountStatusEnum.get(user.getStatus()));
}
//获取redis缓存中登录失败次数 //获取redis缓存中登录失败次数
String s = redisUtil.get(loginReq.getEmail() + "-passwordWrongTime"); String s = redisUtil.get(loginReq.getEmail() + "-passwordWrongTime");
if (s != null) { if (s != null) {
@@ -109,14 +118,9 @@ public class UserServiceImpl implements UserService {
throw new MyException(ResponseEnum.LOGIN_LATER, loginReq.getEmail()); throw new MyException(ResponseEnum.LOGIN_LATER, loginReq.getEmail());
} }
} }
User user = null;
user = userMapper.findByEmail(loginReq.getEmail()); String token;
String token = null;
// 密码比对 // 密码比对
if (user == null) {
// 用户不存在
throw new MyException(ResponseEnum.USER_NOT_EXIST);
}
if (user.getPwd().equals(MD5Util.getMD5(loginReq.getPassword()))) { if (user.getPwd().equals(MD5Util.getMD5(loginReq.getPassword()))) {
logger.info("====> {} 进行权限认证 状态:登录成功 <====", loginReq.getEmail()); logger.info("====> {} 进行权限认证 状态:登录成功 <====", loginReq.getEmail());
userMapper.updateLoginTime(loginReq.getEmail()); userMapper.updateLoginTime(loginReq.getEmail());
@@ -182,7 +186,7 @@ public class UserServiceImpl implements UserService {
@Override @Override
public Object updateUserAavatarImg(InputStream is, String mime) { public Object updateUserAavatarImg(InputStream is, String mime) {
User user = redisUserUtil.get(); User user = redisUserUtil.get();
QiniuResponse upload = qiniuService.uploadFile(is, user.getEmail() + "_" + user.getId() + mime.toLowerCase()); FileResponse upload = fileService.getFileManager().uploadFile(is, user.getEmail() + "_" + user.getId() + mime.toLowerCase());
user.setAvatarImgUrl(upload.key); user.setAvatarImgUrl(upload.key);
userMapper.updateAvatarImgUrl(upload.key, user.getId()); userMapper.updateAvatarImgUrl(upload.key, user.getId());
redisUserUtil.set(user); redisUserUtil.set(user);
@@ -312,14 +316,14 @@ public class UserServiceImpl implements UserService {
@Override @Override
public Object deleteUser(Integer[] id) { public Object deleteUser(Integer[] id) {
JSONArray status = new JSONArray(); List<Map<String, Object>> status = new ArrayList<>();
if (id == null || id.length == 0) { if (id == null || id.length == 0) {
return null; return null;
} }
for (Integer integer : id) { for (Integer integer : id) {
String role = userMapper.getRoleById(integer); String role = userMapper.getRoleById(integer);
int deleteResult = 0; int deleteResult = 0;
JSONObject deleteStatus = new JSONObject(); Map<String, Object> deleteStatus = new HashMap<>(3);
deleteStatus.put("id", integer); deleteStatus.put("id", integer);
// 管理员账户不可删 // 管理员账户不可删
if ("admin".equals(role)) { if ("admin".equals(role)) {
@@ -342,12 +346,11 @@ public class UserServiceImpl implements UserService {
} }
@Override @Override
public PageData<UserModel> getUserList(Integer page, Integer count) { public PageData<UserModel> getUserList(Integer page, Integer count, Integer status) {
PageHelper.startPage(page, count); PageHelper.startPage(page, count);
List<User> all = userMapper.findAll(); List<User> all = userMapper.findAll(status);
List<UserModel> modelList = new ArrayList<>(); List<UserModel> modelList = all.stream().map(ModalTrans::userFullInfo).collect(Collectors.toList());
all.forEach(user -> modelList.add(ModalTrans.userFullInfo(user))); return new PageData<>(PageInfo.of(all), modelList);
return new PageData<UserModel>(PageInfo.of(all), modelList);
} }
@Override @Override

View File

@@ -7,6 +7,7 @@ import cn.celess.blog.entity.model.VisitorModel;
import cn.celess.blog.exception.MyException; import cn.celess.blog.exception.MyException;
import cn.celess.blog.mapper.VisitorMapper; import cn.celess.blog.mapper.VisitorMapper;
import cn.celess.blog.service.VisitorService; import cn.celess.blog.service.VisitorService;
import cn.celess.blog.util.AddressUtil;
import cn.celess.blog.util.DateFormatUtil; import cn.celess.blog.util.DateFormatUtil;
import cn.celess.blog.util.RedisUtil; import cn.celess.blog.util.RedisUtil;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
@@ -15,7 +16,6 @@ import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem; import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent; import eu.bitwalker.useragentutils.UserAgent;
import eu.bitwalker.useragentutils.Version; import eu.bitwalker.useragentutils.Version;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.json.JsonParserFactory; import org.springframework.boot.json.JsonParserFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -26,6 +26,8 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -49,7 +51,7 @@ public class VisitorServiceImpl implements VisitorService {
public PageData<VisitorModel> visitorPage(int page, int count, boolean showLocation) { public PageData<VisitorModel> visitorPage(int page, int count, boolean showLocation) {
PageHelper.startPage(page, count); PageHelper.startPage(page, count);
List<Visitor> visitorList = visitorMapper.findAll(); List<Visitor> visitorList = visitorMapper.findAll();
return new PageData<VisitorModel>(new PageInfo<Visitor>(visitorList), list2List(visitorList, showLocation)); return new PageData<>(new PageInfo<>(visitorList), list2List(visitorList, showLocation));
} }
@Override @Override
@@ -67,8 +69,9 @@ public class VisitorServiceImpl implements VisitorService {
visitor.setUa(request.getHeader("User-Agent")); visitor.setUa(request.getHeader("User-Agent"));
//记录当日的访问 //记录当日的访问
String dayVisitCount = redisUtil.get("dayVisitCount"); String dayVisitCount = redisUtil.get("dayVisitCount");
long secondsLeftToday = 86400 - DateUtils.getFragmentInSeconds(Calendar.getInstance(), Calendar.DATE);
Date date = new Date(Calendar.YEAR); LocalDateTime midnight = LocalDateTime.now().plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
long secondsLeftToday = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);
if (dayVisitCount == null) { if (dayVisitCount == null) {
redisUtil.setEx("dayVisitCount", "1", secondsLeftToday, TimeUnit.SECONDS); redisUtil.setEx("dayVisitCount", "1", secondsLeftToday, TimeUnit.SECONDS);
} else { } else {
@@ -149,60 +152,7 @@ public class VisitorServiceImpl implements VisitorService {
* @return * @return
*/ */
private String getLocation(String ip) { private String getLocation(String ip) {
StringBuilder result = new StringBuilder(); return AddressUtil.getCityInfo(ip);
URL url;
HttpURLConnection conn = null;
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
try {
url = new URL("http://ip.taobao.com/service/getIpInfo.php?ip=" + ip);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(3000);
conn.setDoInput(true);
conn.setRequestMethod("GET");
inputStream = conn.getInputStream();
inputStreamReader = new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(inputStreamReader);
String tmp;
while ((tmp = bufferedReader.readLine()) != null) {
result.append(tmp);
}
} catch (Exception e) {
// ignore
} finally {
try {
if (conn != null) {
conn.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
if (inputStreamReader != null) {
inputStreamReader.close();
}
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (Exception e) {
// ignore
}
}
StringBuilder sb = new StringBuilder();
if ("".equals(result.toString())) {
throw new MyException(ResponseEnum.FAILURE);
}
Map<String, Object> stringObjectMap = JsonParserFactory.getJsonParser().parseMap(result.toString());
if ((Integer) stringObjectMap.get("code") == 0) {
LinkedHashMap data = (LinkedHashMap) stringObjectMap.get("data");
sb.append(data.get("country"))
.append("-")
.append(data.get("region"))
.append("-")
.append(data.get("city"));
}
return sb.toString();
} }

View File

@@ -1,108 +1,114 @@
package cn.celess.blog.service.serviceimpl; package cn.celess.blog.service.serviceimpl;
import cn.celess.blog.enmu.ResponseEnum; import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.entity.WebUpdate; import cn.celess.blog.entity.WebUpdate;
import cn.celess.blog.entity.model.PageData; import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.entity.model.WebUpdateModel; import cn.celess.blog.entity.model.WebUpdateModel;
import cn.celess.blog.exception.MyException; import cn.celess.blog.exception.MyException;
import cn.celess.blog.mapper.WebUpdateInfoMapper; import cn.celess.blog.mapper.WebUpdateInfoMapper;
import cn.celess.blog.service.WebUpdateInfoService; import cn.celess.blog.service.WebUpdateInfoService;
import cn.celess.blog.util.DateFormatUtil; import cn.celess.blog.util.DateFormatUtil;
import cn.celess.blog.util.HttpUtil; import cn.celess.blog.util.HttpUtil;
import cn.celess.blog.util.ModalTrans; import cn.celess.blog.util.ModalTrans;
import com.github.pagehelper.PageHelper; import com.alibaba.druid.util.StringUtils;
import com.github.pagehelper.PageInfo; import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.slf4j.Slf4j; import com.fasterxml.jackson.databind.ObjectMapper;
import net.sf.json.JSONArray; import com.github.pagehelper.PageHelper;
import net.sf.json.JSONObject; import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.text.SimpleDateFormat; import java.io.IOException;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.*;
import java.util.Date; import java.util.stream.Collectors;
import java.util.List;
/**
/** * @author : xiaohai
* @author : xiaohai * @date : 2019/05/12 11:43
* @date : 2019/05/12 11:43 */
*/ @Service
@Service @Slf4j
@Slf4j public class WebUpdateInfoServiceImpl implements WebUpdateInfoService {
public class WebUpdateInfoServiceImpl implements WebUpdateInfoService { @Autowired
@Autowired WebUpdateInfoMapper webUpdateInfoMapper;
WebUpdateInfoMapper webUpdateInfoMapper;
@Override
@Override public WebUpdateModel create(String info) {
public WebUpdateModel create(String info) { if (info == null || info.replaceAll(" ", "").isEmpty()) {
if (info == null || info.replaceAll(" ", "").isEmpty()) { throw new MyException(ResponseEnum.PARAMETERS_ERROR);
throw new MyException(ResponseEnum.PARAMETERS_ERROR); }
} WebUpdate webUpdate = new WebUpdate(info);
WebUpdate webUpdate = new WebUpdate(info); if (webUpdateInfoMapper.insert(webUpdate) == 0) {
if (webUpdateInfoMapper.insert(webUpdate) == 0) { throw new MyException(ResponseEnum.FAILURE);
throw new MyException(ResponseEnum.FAILURE); }
} return ModalTrans.webUpdate(webUpdateInfoMapper.findById(webUpdate.getId()));
return ModalTrans.webUpdate(webUpdateInfoMapper.findById(webUpdate.getId())); }
}
@Override
@Override public Boolean del(long id) {
public Boolean del(long id) { if (!webUpdateInfoMapper.existsById(id)) {
if (!webUpdateInfoMapper.existsById(id)) { throw new MyException(ResponseEnum.DATA_NOT_EXIST);
throw new MyException(ResponseEnum.DATA_NOT_EXIST); }
} return webUpdateInfoMapper.delete(id) == 1;
return webUpdateInfoMapper.delete(id) == 1; }
}
@Override
@Override public WebUpdateModel update(long id, String info) {
public WebUpdateModel update(long id, String info) { WebUpdate webUpdate = webUpdateInfoMapper.findById(id);
WebUpdate webUpdate = webUpdateInfoMapper.findById(id); if (webUpdate == null) {
if (webUpdate == null) { throw new MyException(ResponseEnum.DATA_NOT_EXIST);
throw new MyException(ResponseEnum.DATA_NOT_EXIST); }
} if (info == null || info.replaceAll(" ", "").isEmpty()) {
if (info == null || info.replaceAll(" ", "").isEmpty()) { throw new MyException(ResponseEnum.PARAMETERS_ERROR);
throw new MyException(ResponseEnum.PARAMETERS_ERROR); }
} webUpdate.setUpdateInfo(info);
webUpdate.setUpdateInfo(info); webUpdateInfoMapper.update(id, info);
webUpdateInfoMapper.update(id, info); return ModalTrans.webUpdate(webUpdate);
return ModalTrans.webUpdate(webUpdate); }
}
@Override
@Override public PageData<WebUpdateModel> pages(int count, int page) {
public PageData<WebUpdateModel> pages(int count, int page) { PageHelper.startPage(page, count);
PageHelper.startPage(page, count); List<WebUpdate> updateList = webUpdateInfoMapper.findAll();
List<WebUpdate> updateList = webUpdateInfoMapper.findAll(); return new PageData<>(new PageInfo<>(updateList), list2List(updateList));
return new PageData<WebUpdateModel>(new PageInfo<WebUpdate>(updateList), list2List(updateList)); }
}
@Override
@Override public List<WebUpdateModel> findAll() {
public List<WebUpdateModel> findAll() { List<WebUpdate> all = webUpdateInfoMapper.findAll();
List<WebUpdate> all = webUpdateInfoMapper.findAll(); return list2List(all);
return list2List(all); }
}
@Override
@Override
public JSONObject getLastestUpdateTime() { public Map<String, Object> getLastestUpdateTime() {
JSONObject jsonObject = new JSONObject(); Map<String, Object> map = new HashMap<>();
jsonObject.put("lastUpdateTime", DateFormatUtil.get(webUpdateInfoMapper.getLastestOne().getUpdateTime())); map.put("lastUpdateTime", DateFormatUtil.get(webUpdateInfoMapper.getLastestOne().getUpdateTime()));
jsonObject.put("lastUpdateInfo", webUpdateInfoMapper.getLastestOne().getUpdateInfo()); map.put("lastUpdateInfo", webUpdateInfoMapper.getLastestOne().getUpdateInfo());
JSONArray array = JSONArray.fromObject(HttpUtil.get("https://api.github.com/repos/xiaohai2271/blog-frontEnd/commits?page=1&per_page=1")); try {
JSONObject object = array.getJSONObject(0); ObjectMapper mapper = new ObjectMapper();
JSONObject commit = object.getJSONObject("commit"); String respStr = HttpUtil.get("https://api.github.com/repos/xiaohai2271/blog-frontEnd/commits?page=1&per_page=1");
jsonObject.put("lastCommit", commit.getString("message")); if (!StringUtils.isEmpty(respStr)) {
jsonObject.put("committerAuthor", commit.getJSONObject("committer").getString("name")); JsonNode root = mapper.readTree(respStr);
SimpleDateFormat sdf = new SimpleDateFormat(); Iterator<JsonNode> elements = root.elements();
Instant parse = Instant.parse(commit.getJSONObject("committer").getString("date")); JsonNode next = elements.next();
jsonObject.put("committerDate", DateFormatUtil.get(Date.from(parse))); JsonNode commit = next.get("commit");
jsonObject.put("commitUrl", "https://github.com/xiaohai2271/blog-frontEnd/tree/" + object.getString("sha")); map.put("lastCommit", commit.get("message"));
return jsonObject; map.put("committerAuthor", commit.get("committer").get("name"));
} Instant parse = Instant.parse(commit.get("committer").get("date").asText());
map.put("committerDate", DateFormatUtil.get(Date.from(parse)));
private List<WebUpdateModel> list2List(List<WebUpdate> webUpdates) { map.put("commitUrl", "https://github.com/xiaohai2271/blog-frontEnd/tree/" + next.get("sha").asText());
List<WebUpdateModel> webUpdateModels = new ArrayList<>(); }
webUpdates.forEach(update -> webUpdateModels.add(ModalTrans.webUpdate(update))); } catch (IOException e) {
return webUpdateModels; log.info("网络请求失败{}", e.getMessage());
} }
} return map;
}
private List<WebUpdateModel> list2List(List<WebUpdate> webUpdates) {
return webUpdates.stream().map(ModalTrans::webUpdate).collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,71 @@
package cn.celess.blog.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;
import java.io.File;
import java.lang.reflect.Method;
import java.util.Objects;
/**
* @author : xiaohai
* @date : 2020/09/04 9:36
*/
@Slf4j
public class AddressUtil {
public static String getCityInfo(String ip) {
File file;
try {
//db
String dbPath = AddressUtil.class.getResource("/ip2region/ip2region.db").getPath();
file = new File(dbPath);
if (!file.exists()) {
String tmpDir = System.getProperties().getProperty("java.io.tmpdir");
dbPath = tmpDir + "ip.db";
file = new File(dbPath);
FileUtils.copyInputStreamToFile(Objects.requireNonNull(AddressUtil.class.getClassLoader().getResourceAsStream("classpath:ip2region/ip2region.db")), file);
}
//查询算法
//B-tree
int algorithm = DbSearcher.BTREE_ALGORITHM;
try {
DbConfig config = new DbConfig();
DbSearcher searcher = new DbSearcher(config, dbPath);
Method method = null;
switch (algorithm) {
case DbSearcher.BTREE_ALGORITHM:
method = searcher.getClass().getMethod("btreeSearch", String.class);
break;
case DbSearcher.BINARY_ALGORITHM:
method = searcher.getClass().getMethod("binarySearch", String.class);
break;
case DbSearcher.MEMORY_ALGORITYM:
method = searcher.getClass().getMethod("memorySearch", String.class);
break;
}
DataBlock dataBlock;
if (!Util.isIpAddress(ip)) {
System.out.println("Error: Invalid ip address");
}
dataBlock = (DataBlock) method.invoke(searcher, ip);
return dataBlock.getRegion();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -9,7 +9,6 @@ import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Objects; import java.util.Objects;
/** /**
@@ -20,41 +19,6 @@ import java.util.Objects;
public class HttpUtil { public class HttpUtil {
private static final OkHttpClient CLIENT = new OkHttpClient(); private static final OkHttpClient CLIENT = new OkHttpClient();
/*public static String get(String urlStr) throws IOException {
StringBuffer sb = new StringBuffer();
HttpURLConnection urlConnection = null;
try {
URL url = new URL(urlStr);
//打开http
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
try (
InputStream inputStream = urlConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)
) {
//将bufferReader的值给放到buffer里
String str = null;
while ((str = bufferedReader.readLine()) != null) {
sb.append(str);
}
}
} finally {
//断开连接
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return sb.toString();
}
*/
public static String get(String urlStr) { public static String get(String urlStr) {
Request request = new Request.Builder() Request request = new Request.Builder()
.url(urlStr) .url(urlStr)

View File

@@ -1,5 +1,6 @@
package cn.celess.blog.util; package cn.celess.blog.util;
import cn.celess.blog.enmu.UserAccountStatusEnum;
import cn.celess.blog.entity.*; import cn.celess.blog.entity.*;
import cn.celess.blog.entity.model.*; import cn.celess.blog.entity.model.*;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@@ -46,6 +47,7 @@ public class ModalTrans {
} }
UserModel userModel = new UserModel(); UserModel userModel = new UserModel();
BeanUtils.copyProperties(user, userModel); BeanUtils.copyProperties(user, userModel);
userModel.setStatus(UserAccountStatusEnum.get(user.getStatus()));
userModel.setAvatarImgUrl(user.getAvatarImgUrl() == null || user.getAvatarImgUrl().length() == 0 ? userModel.setAvatarImgUrl(user.getAvatarImgUrl() == null || user.getAvatarImgUrl().length() == 0 ?
null : null :
"http://cdn.celess.cn/" + user.getAvatarImgUrl()); "http://cdn.celess.cn/" + user.getAvatarImgUrl());

View File

@@ -3,7 +3,8 @@ package cn.celess.blog.util;
import cn.celess.blog.enmu.ResponseEnum; import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.entity.User; import cn.celess.blog.entity.User;
import cn.celess.blog.exception.MyException; import cn.celess.blog.exception.MyException;
import net.sf.json.JSONObject; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -31,24 +32,27 @@ public class RedisUserUtil {
return user; return user;
} }
@SneakyThrows
public User getWithOutExc() { public User getWithOutExc() {
String token = request.getHeader("Authorization"); String token = request.getHeader("Authorization");
if (token == null || token.isEmpty()) { if (token == null || token.isEmpty()) {
return null; return null;
} }
String email = jwtUtil.getUsernameFromToken(token); String email = jwtUtil.getUsernameFromToken(token);
return (User) JSONObject.toBean(JSONObject.fromObject(redisUtil.get(email + "-login")), User.class); return new ObjectMapper().readValue(redisUtil.get(email + "-login"), User.class);
} }
@SneakyThrows
public User set(User user) { public User set(User user) {
Long expire = redisUtil.getExpire(user.getEmail() + "-login"); Long expire = redisUtil.getExpire(user.getEmail() + "-login");
redisUtil.setEx(user.getEmail() + "-login", JSONObject.fromObject(user).toString(), redisUtil.setEx(user.getEmail() + "-login", new ObjectMapper().writeValueAsString(user),
expire > 0 ? expire : JwtUtil.EXPIRATION_SHORT_TIME, TimeUnit.MILLISECONDS); expire > 0 ? expire : JwtUtil.EXPIRATION_SHORT_TIME, TimeUnit.MILLISECONDS);
return user; return user;
} }
@SneakyThrows
public User set(User user, boolean isRemember) { public User set(User user, boolean isRemember) {
redisUtil.setEx(user.getEmail() + "-login", JSONObject.fromObject(user).toString(), redisUtil.setEx(user.getEmail() + "-login", new ObjectMapper().writeValueAsString(user),
isRemember ? JwtUtil.EXPIRATION_LONG_TIME : JwtUtil.EXPIRATION_SHORT_TIME, TimeUnit.MILLISECONDS); isRemember ? JwtUtil.EXPIRATION_LONG_TIME : JwtUtil.EXPIRATION_SHORT_TIME, TimeUnit.MILLISECONDS);
request.getSession().setAttribute("email", user.getEmail()); request.getSession().setAttribute("email", user.getEmail());
return user; return user;

View File

@@ -0,0 +1,65 @@
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

View File

@@ -1,9 +1,9 @@
server.port=8081 server.port=8081
# 七牛的密钥配置 # 七牛的密钥配置
qiniu.accessKey= file.qiniu.accessKey=
qiniu.secretKey= file.qiniu.secretKey=
qiniu.bucket= file.qiniu.bucket=
# sitemap 存放地址 # sitemap 存放地址
sitemap.path= sitemap.path=
# 生成JWT时候的密钥 # 生成JWT时候的密钥
@@ -26,6 +26,12 @@ spring.datasource.url=
spring.datasource.username= spring.datasource.username=
spring.datasource.password= spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.platform=mysql
# never / always / embedded
spring.datasource.initialization-mode=never
spring.datasource.sql-script-encoding=utf-8
spring.datasource.schema=classpath:sql/schema.sql
spring.datasource.data=classpath:sql/data.sql
################## mybatis ################## ################## mybatis ##################
@@ -56,12 +62,6 @@ spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFact
spring.mail.properties.mail.smtp.socketFactory.fallback=false 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 ##############
# REDIS (RedisProperties) # REDIS (RedisProperties)
# Redis数据库索引默认为0 # Redis数据库索引默认为0

View File

@@ -0,0 +1,88 @@
server.port=8081
# 七牛的密钥配置
file.qiniu.accessKey=${QINIU_ACCESSKEY:null}
file.qiniu.secretKey=${QINIU_SECRETKEY:null}
file.qiniu.bucket=xiaohai
# sitemap 存放地址
sitemap.path=
# 生成JWT时候的密钥
jwt.secret=sdaniod213k123123ipoeqowekqwe
##spring.jpa.show-sql=false
##spring.jpa.hibernate.ddl-auto=update
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
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:testdb;mode=mysql;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.sql-script-encoding=utf-8
spring.datasource.initialization-mode=ALWAYS
spring.datasource.schema=classpath:sql/schema-h2.sql
spring.datasource.data=classpath:sql/data.sql
################## 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
############### 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
############### redis ##############
# REDIS (RedisProperties)
# Redis数据库索引默认为0
spring.redis.database=1
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口 解决端口冲突 防止使用本地的redis
spring.redis.port=6380
# 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

View File

@@ -1,7 +1,10 @@
spring.profiles.active=prod spring.profiles.active=easyDeploy
####七牛的配置
####cn.celess.blog.service.serviceimpl.QiniuServiceImpl
logging.level.cn.celess.blog=debug logging.level.cn.celess.blog=debug
logging.level.cn.celess.blog.mapper=info 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文件用于线上发布

Binary file not shown.

View File

@@ -0,0 +1,50 @@
<?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>

View File

@@ -78,6 +78,9 @@
<select id="findAll" resultMap="partnerSiteResultMap"> <select id="findAll" resultMap="partnerSiteResultMap">
select * select *
from links from links
<if test="_parameter != null">
where is_delete=#{deleted}
</if>
</select> </select>

View File

@@ -130,5 +130,8 @@
<select id="findAll" resultMap="userResultMap"> <select id="findAll" resultMap="userResultMap">
select * select *
from user from user
<if test="_parameter != null">
where status=#{status}
</if>
</select> </select>
</mapper> </mapper>

View File

@@ -0,0 +1,110 @@
* {
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;
}

View File

@@ -0,0 +1,171 @@
.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);
}
}

View File

@@ -0,0 +1,164 @@
<!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>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,201 @@
drop view if exists articleView;
drop view if exists commentView;
drop table if exists article_tag;
drop table if exists comment;
drop table if exists article;
drop table if exists user;
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`
(
`u_id` int not null primary key auto_increment,
`u_email` varchar(50) not null,
`u_pwd` varchar(40) not null comment '密码',
`u_email_status` boolean default false comment '邮箱验证状态',
`u_avatar` varchar(255) default null comment '用户头像',
`u_desc` tinytext default null comment '用户的描述',
`u_recently_landed_time` datetime default null comment '最近的登录时间',
`u_display_name` varchar(30) default null comment '展示的昵称',
`u_role` varchar(40) not null default 'user' comment '权限组',
`status` tinyint(1) not null default 0 comment '账户状态',
unique key `uni_user_id` (`u_id`),
unique key `uni_user_email` (`u_email`)
);
-- 标签和分类表
CREATE TABLE `tag_category`
(
`t_id` bigint(20) primary key auto_increment,
`t_name` varchar(255) not null,
`is_category` boolean not null default true,
`is_delete` boolean not null default false comment '该数据是否被删除'
);
-- 文章表
CREATE TABLE `article`
(
`a_id` bigint(20) primary key auto_increment,
`a_title` varchar(255) not null unique comment '文章标题',
`a_summary` varchar(255) not null comment '文章摘要',
`a_md_content` longtext not null comment '文章Markdown内容',
`a_url` tinytext default null comment '转载文章的原文链接',
`a_author_id` int not null comment '作者id',
`a_is_original` boolean default true comment '文章是否原创',
`a_reading_number` int default 0 comment '文章阅读数',
`a_like` int default 0 comment '文章点赞数',
`a_dislike` int default 0 comment '文章不喜欢数',
`a_category_id` bigint not null comment '文章分类id',
`a_publish_date` datetime default CURRENT_TIMESTAMP comment '文章发布时间',
`a_update_date` datetime default null comment '文章的更新时间',
`a_is_open` boolean default true comment '文章是否可见',
`is_delete` boolean not null default false comment '该数据是否被删除',
foreign key (a_category_id) references tag_category (t_id),
foreign key (a_author_id) references user (u_id)
);
-- 文章标签表
CREATE TABLE `article_tag`
(
`at_id` bigint(20) primary key auto_increment,
`a_id` bigint(20) not null comment '文章id',
`t_id` bigint not null comment 'tag/category 的id',
foreign key (a_id) references article (a_id),
foreign key (t_id) references tag_category (t_id)
);
-- 评论/留言表
CREATE TABLE `comment`
(
`co_id` bigint(20) primary key auto_increment,
`co_page_path` varchar(255) not null comment '评论/留言的页面',
`co_content` text not null comment '评论/留言内容',
`co_date` datetime not null comment '评论/留言的日期',
`co_status` tinyint not null default 0 comment '评论的状态',
`co_pid` bigint not null default -1 comment '评论/留言的父id',
`co_from_author_id` int not null comment '留言者id',
`co_to_author_id` int default null comment '父评论的作者id',
foreign key (co_from_author_id) references user (u_id),
foreign key (co_to_author_id) references user (u_id)
);
-- 友站表
CREATE TABLE `links`
(
`l_id` bigint(20) primary key auto_increment,
`l_name` varchar(255) not null comment '友站名称',
`l_is_open` boolean default true comment '是否公开',
`l_url` varchar(255) unique not null comment '首页地址',
`l_icon_path` varchar(255) not null comment '友链的icon地址',
`l_desc` varchar(255) not null comment '友链的说明描述',
`is_delete` boolean not null default false comment '该数据是否被删除',
`l_email` varchar(255) comment '网站管理员的邮箱',
`l_notification` boolean default false comment '是否通知了'
);
-- 访客表
CREATE TABLE `visitor`
(
`v_id` bigint(20) primary key auto_increment,
`v_date` datetime not null comment '访问时间',
`v_ip` varchar(255) not null comment '访客ip',
`v_user_agent` text comment '访客ua',
`is_delete` boolean not null default false comment '该数据是否被删除'
);
-- 更新内容表
CREATE TABLE `web_update`
(
`wu_id` int primary key auto_increment,
`wu_info` varchar(255) not null comment '更新内容',
`wu_time` datetime not null comment '更新时间',
`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,
categoryId, categoryName, tagId, tagName,
authorId, userEmail, userAvatar, userDisplayName, isDelete)
as
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,
tag.t_id as tagId,
tag.t_name as tagName,
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 tag,
tag_category as category,
article_tag,
user
where article.a_id = article_tag.a_id
and article_tag.t_id = tag.t_id
and tag.is_category = false
and article.a_category_id = category.t_id
and category.is_category = true
and article.a_author_id = user.u_id;
CREATE VIEW commentView
(commentId, pagePath, content, date, status, pid, toAuthorId, toAuthorEmail, toAuthorDisplayName,
toAuthorAvatar, fromAuthorId, fromAuthorEmail, fromAuthorDisplayName,
fromAuthorAvatar)
as
select cuT.co_id as commentId,
cuT.co_page_path as pagePath,
cuT.co_content as content,
cuT.co_date as date,
cuT.co_status as status,
cuT.co_pid as pid,
cuT.co_to_author_id as toAuthorId,
cuT.toEmail as toAuthorEmail,
cuT.toDisplayName as toAuthorDisplayName,
cuT.toAvatar as toAuthorAvatar,
userFrom.u_id as fromAuthorId,
userFrom.u_email as fromAuthorEmail,
userFrom.u_display_name as fromAuthorDisplayName,
userFrom.u_avatar as fromAuthorAvatar
from (select comment.co_id,
comment.co_page_path,
comment.co_content,
comment.co_date,
comment.co_status,
comment.co_pid,
comment.co_from_author_id,
comment.co_to_author_id,
userTo.u_email as toEmail,
userTo.u_display_name as toDisplayName,
userTo.u_avatar as toAvatar
from comment
left join user userTo on (comment.co_to_author_id = userTo.u_id)
) as cuT,
user as userFrom
where cuT.co_from_author_id = userFrom.u_id;

View File

@@ -1,6 +1,15 @@
CREATE DATABASE if not exists `blog`; drop view if exists articleView;
drop view if exists commentView;
drop table if exists article_tag;
drop table if exists comment;
drop table if exists article;
drop table if exists user;
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;
USE blog;
CREATE TABLE `user` CREATE TABLE `user`
( (
@@ -66,7 +75,9 @@ CREATE TABLE `comment`
`co_status` tinyint not null default 0 comment '评论的状态', `co_status` tinyint not null default 0 comment '评论的状态',
`co_pid` bigint not null default -1 comment '评论/留言的父id', `co_pid` bigint not null default -1 comment '评论/留言的父id',
`co_from_author_id` int not null comment '留言者id', `co_from_author_id` int not null comment '留言者id',
`co_to_author_id` int default null comment '父评论的作者id' `co_to_author_id` int default null comment '父评论的作者id',
foreign key (co_from_author_id) references user (u_id),
foreign key (co_to_author_id) references user (u_id)
) DEFAULT CHARSET = utf8mb4 ) DEFAULT CHARSET = utf8mb4
COLLATE utf8mb4_general_ci,comment '评论/留言表'; COLLATE utf8mb4_general_ci,comment '评论/留言表';
@@ -100,6 +111,13 @@ CREATE TABLE `web_update`
`is_delete` boolean not null default false comment '该数据是否被删除' `is_delete` boolean not null default false comment '该数据是否被删除'
) 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 CREATE VIEW articleView
(articleId, title, summary, mdContent, url, isOriginal, readingCount, likeCount, dislikeCount, (articleId, title, summary, mdContent, url, isOriginal, readingCount, likeCount, dislikeCount,
publishDate, updateDate, isOpen, publishDate, updateDate, isOpen,

View File

@@ -1,319 +1,355 @@
package cn.celess.blog; package cn.celess.blog;
import cn.celess.blog.entity.Response; import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.model.UserModel; import cn.celess.blog.entity.model.FileInfo;
import cn.celess.blog.entity.request.LoginReq; import cn.celess.blog.entity.model.FileResponse;
import cn.celess.blog.service.MailService; import cn.celess.blog.entity.model.UserModel;
import com.fasterxml.jackson.core.JsonProcessingException; import cn.celess.blog.entity.request.LoginReq;
import com.fasterxml.jackson.core.type.TypeReference; import cn.celess.blog.service.MailService;
import com.fasterxml.jackson.databind.ObjectMapper; import cn.celess.blog.service.FileManager;
import lombok.extern.slf4j.Slf4j; import com.fasterxml.jackson.core.JsonProcessingException;
import org.junit.After; import com.fasterxml.jackson.core.type.TypeReference;
import org.junit.Before; import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test; import lombok.extern.slf4j.Slf4j;
import org.junit.runner.RunWith; import org.junit.After;
import org.slf4j.Logger; import org.junit.Before;
import org.slf4j.LoggerFactory; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest; import org.slf4j.Logger;
import org.springframework.http.MediaType; import org.slf4j.LoggerFactory;
import org.springframework.mail.SimpleMailMessage; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpSession; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles; import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.mail.SimpleMailMessage;
import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.test.web.servlet.MvcResult;
import org.springframework.web.context.WebApplicationContext; import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.io.IOException; import org.springframework.web.context.WebApplicationContext;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field; import java.io.IOException;
import java.util.Map; import java.io.InputStream;
import java.util.UUID; import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import static cn.celess.blog.enmu.ResponseEnum.SUCCESS; import java.util.ArrayList;
import static org.junit.Assert.*; import java.util.List;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import java.util.Map;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import java.util.UUID;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static cn.celess.blog.enmu.ResponseEnum.SUCCESS;
/** import static org.junit.Assert.*;
* @Author: 小海 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
* @Date: 2019/08/22 12:46 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
* @Description: 测试基类 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
*/
@SpringBootTest /**
@RunWith(SpringRunner.class) * @Author: 小海
@WebAppConfiguration * @Date: 2019/08/22 12:46
@ActiveProfiles("test") * @Description: 测试基类
public class BaseTest { */
@SpringBootTest
@RunWith(SpringRunner.class)
private final Logger logger = LoggerFactory.getLogger(this.getClass()); @WebAppConfiguration
@ActiveProfiles("test")
protected MockMvc mockMvc; public class BaseTest {
protected final static String Code = "code";
protected final static String Result = "result";
/** private final Logger logger = LoggerFactory.getLogger(this.getClass());
* jackson 序列化/反序列化Json
*/ protected MockMvc mockMvc;
protected final ObjectMapper mapper = new ObjectMapper(); protected final static String Code = "code";
protected static final TypeReference<?> BOOLEAN_TYPE = new TypeReference<Response<Boolean>>() { protected final static String Result = "result";
}; protected final static String USERE_MAIL = "zh56462271@qq.com";
protected static final TypeReference<?> STRING_TYPE = new TypeReference<Response<String>>() { protected final static String ADMIN_EMAIL = "a@celess.cn";
};
protected static final TypeReference<?> OBJECT_TYPE = new TypeReference<Response<Object>>() { /**
}; * jackson 序列化/反序列化Json
protected static final TypeReference<?> MAP_OBJECT_TYPE = new TypeReference<Response<Map<String, Object>>>() { */
}; protected final ObjectMapper mapper = new ObjectMapper();
@Autowired protected static final TypeReference<?> BOOLEAN_TYPE = new TypeReference<Response<Boolean>>() {
private WebApplicationContext wac; };
protected MockHttpSession session; protected static final TypeReference<?> STRING_TYPE = new TypeReference<Response<String>>() {
};
@Before protected static final TypeReference<?> OBJECT_TYPE = new TypeReference<Response<Object>>() {
public void before() { };
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); protected static final TypeReference<?> MAP_OBJECT_TYPE = new TypeReference<Response<Map<String, Object>>>() {
session = new MockHttpSession(); };
System.out.println("==========> 开始测试 <=========");
} @Autowired
private WebApplicationContext wac;
@After protected MockHttpSession session;
public void after() {
System.out.println("==========> 测试结束 <========="); @Before
} public void before() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
/** session = new MockHttpSession();
*  admin 权限用户登录 System.out.println("==========> 开始测试 <=========");
* }
* @return token
*/ @After
protected String adminLogin() { public void after() {
LoginReq req = new LoginReq(); System.out.println("==========> 测试结束 <=========");
req.setEmail("a@celess.cn"); }
req.setPassword("123456789");
req.setIsRememberMe(true); /**
String token = login(req); *  admin 权限用户登录
assertNotNull(token); *
return token; * @return token
} */
protected String adminLogin() {
/** LoginReq req = new LoginReq();
* user 权限用户登录 req.setEmail(ADMIN_EMAIL);
* req.setPassword("123456789");
* @return token req.setIsRememberMe(true);
*/ String token = login(req);
protected String userLogin() { assertNotNull(token);
LoginReq req = new LoginReq(); return token;
req.setEmail("zh56462271@qq.com"); }
req.setPassword("123456789");
req.setIsRememberMe(true); /**
String token = login(req); * user 权限用户登录
assertNotNull(token); *
return token; * @return token
} */
protected String userLogin() {
/** LoginReq req = new LoginReq();
* 登录逻辑 req.setEmail(USERE_MAIL);
* req.setPassword("123456789");
* @param req 用户信息 req.setIsRememberMe(true);
* @return token | null String token = login(req);
*/ assertNotNull(token);
private String login(LoginReq req) { return token;
String str = null; }
try {
str = getMockData(post("/login"), null, req) /**
.andReturn().getResponse().getContentAsString(); * 登录逻辑
Response<UserModel> response = mapper.readValue(str, new TypeReference<Response<UserModel>>() { *
}); * @param req 用户信息
assertEquals(SUCCESS.getCode(), response.getCode()); * @return token | null
String token = response.getResult().getToken(); */
assertNotNull(token); protected String login(LoginReq req) {
return token; String str = null;
} catch (Exception e) { try {
logger.error("测试登录错误"); str = getMockData(post("/login"), null, req)
e.printStackTrace(); .andReturn().getResponse().getContentAsString();
} Response<UserModel> response = mapper.readValue(str, new TypeReference<Response<UserModel>>() {
assertNotNull(str); });
return null; assertEquals(SUCCESS.getCode(), response.getCode());
} String token = response.getResult().getToken();
assertNotNull(token);
@Test return token;
public void test() { } catch (Exception e) {
// 测试登录 logger.error("测试登录错误");
assertNotNull(userLogin()); e.printStackTrace();
assertNotNull(adminLogin()); }
assertNotEquals(userLogin(), adminLogin()); assertNotNull(str);
try { return null;
// 测试getMockData方法 }
assertNotNull(getMockData(get("/headerInfo")));
getMockData((get("/headerInfo"))).andDo(result -> assertNotNull(getResponse(result, OBJECT_TYPE))); @Test
} catch (Exception e) { public void test() {
e.printStackTrace(); // 测试登录
} assertNotNull(userLogin());
} assertNotNull(adminLogin());
assertNotEquals(userLogin(), adminLogin());
/** try {
* 产生指定长度的随机字符 // 测试getMockData方法
* assertNotNull(getMockData(get("/headerInfo")));
* @param len len getMockData((get("/headerInfo"))).andDo(result -> assertNotNull(getResponse(result, OBJECT_TYPE)));
* @return str } catch (Exception e) {
*/ e.printStackTrace();
protected String randomStr(int len) { }
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, len); }
}
/**
/** * 产生指定长度的随机字符
* 产生指定长度的随机字符 *
* * @param len len
* @return str * @return str
*/ */
protected String randomStr() { protected String randomStr(int len) {
return UUID.randomUUID().toString(); return UUID.randomUUID().toString().replaceAll("-", "").substring(0, len);
} }
/** /**
* 抽离的mock请求方法 * 产生指定长度的随机字符
* *
* @param builder MockHttpServletRequestBuilder get(...) post(...) .... * @return str
* @return 返回 ResultActions */
* @throws Exception exc protected String randomStr() {
*/ return UUID.randomUUID().toString();
protected ResultActions getMockData(MockHttpServletRequestBuilder builder) throws Exception { }
return getMockData(builder, null, null);
} /**
* 抽离的mock请求方法
/** *
* 抽离的mock请求方法 重载 * @param builder MockHttpServletRequestBuilder get(...) post(...) ....
* * @return 返回 ResultActions
* @param builder .. * @throws Exception exc
* @param token 用户登录的token */
* @return .. protected ResultActions getMockData(MockHttpServletRequestBuilder builder) throws Exception {
* @throws Exception .. return getMockData(builder, null, null);
*/ }
protected ResultActions getMockData(MockHttpServletRequestBuilder builder, String token) throws Exception {
return getMockData(builder, token, null); /**
} * 抽离的mock请求方法 重载
*
/** * @param builder ..
* 抽离的mock请求方法 重载 * @param token 用户登录的token
* * @return ..
* @param builder .. * @throws Exception ..
* @param token .. */
* @param content http中发送的APPLICATION_JSON的json数据 protected ResultActions getMockData(MockHttpServletRequestBuilder builder, String token) throws Exception {
* @return .. return getMockData(builder, token, null);
* @throws Exception .. }
*/
protected ResultActions getMockData(MockHttpServletRequestBuilder builder, String token, Object content) throws Exception { /**
// MockHttpServletRequestBuilder mockHttpServletRequestBuilder = get(url); * 抽离的mock请求方法 重载
if (token != null) { *
builder.header("Authorization", token); * @param builder ..
} * @param token ..
if (content != null) { * @param content http中发送的APPLICATION_JSON的json数据
builder.content(mapper.writeValueAsString(content)).contentType(MediaType.APPLICATION_JSON); * @return ..
} * @throws Exception ..
return mockMvc.perform(builder).andExpect(status().isOk()); */
} protected ResultActions getMockData(MockHttpServletRequestBuilder builder, String token, Object content) throws Exception {
// MockHttpServletRequestBuilder mockHttpServletRequestBuilder = get(url);
if (token != null) {
protected <T> Response<T> getResponse(String json) { builder.header("Authorization", token);
return getResponse(json, OBJECT_TYPE); }
} if (content != null) {
builder.content(mapper.writeValueAsString(content)).contentType(MediaType.APPLICATION_JSON);
protected <T> Response<T> getResponse(MvcResult result) { logger.debug("param::json->{}", mapper.writeValueAsString(content));
return getResponse(result, OBJECT_TYPE); }
} return mockMvc.perform(builder).andExpect(status().isOk());
}
/**
* 根据json 信息反序列化成Response对象
* protected <T> Response<T> getResponse(String json) {
* @param json json return getResponse(json, OBJECT_TYPE);
* @param <T> 泛型 }
* @return Response对象
*/ protected <T> Response<T> getResponse(MvcResult result) {
protected <T> Response<T> getResponse(String json, TypeReference<?> responseType) { return getResponse(result, OBJECT_TYPE);
Response<T> response = null; }
System.out.println(responseType.getType());
try { /**
response = mapper.readValue(json, responseType); * 根据json 信息反序列化成Response对象
} catch (IOException e) { *
logger.error("解析json Response对象错误json:[{}]", json); * @param json json
e.printStackTrace(); * @param <T> 泛型
} * @return Response对象
assertNotNull(response); */
return response; protected <T> Response<T> getResponse(String json, TypeReference<?> responseType) {
} Response<T> response = null;
try {
/** response = mapper.readValue(json, responseType);
* 根据json 信息反序列化成Response对象 } catch (IOException e) {
* logger.error("解析json Response对象错误json:[{}]", json);
* @param result MvcResult e.printStackTrace();
* @param <T> 泛型 }
* @return Response对象 assertNotNull(response);
*/ return response;
protected <T> Response<T> getResponse(MvcResult result, TypeReference<?> responseType) { }
try {
return getResponse(result.getResponse().getContentAsString(), responseType); /**
} catch (UnsupportedEncodingException e) { * 根据json 信息反序列化成Response对象
logger.error("解析json Response对象错误result:[{}]", result); *
e.printStackTrace(); * @param result MvcResult
} * @param <T> 泛型
return null; * @return Response对象
} */
protected <T> Response<T> getResponse(MvcResult result, TypeReference<?> responseType) {
try {
/** return getResponse(result.getResponse().getContentAsString(), responseType);
* 修改 mailService 的实现类 } catch (UnsupportedEncodingException e) {
* logger.error("解析json Response对象错误result:[{}]", result);
* @param service service 类 e.printStackTrace();
* @param mailFiledName service 中自动注入的mailService字段名 }
*/ return null;
protected void mockEmailServiceInstance(Object service, String mailFiledName) { }
Field mailServiceField;
try {
mailServiceField = service.getClass().getDeclaredField(mailFiledName); /**
mailServiceField.setAccessible(true); * 修改 mailService 的实现类
mailServiceField.set(service, new TestMailServiceImpl()); *
} catch (NoSuchFieldException | IllegalAccessException e) { * @param service service 类
e.printStackTrace(); * @param mailFiledName service 中自动注入的mailService字段名
} */
} protected void mockInjectInstance(Object service, String mailFiledName, Object impl) {
Field field;
try {
@Slf4j assertNotNull(service);
protected static class TestMailServiceImpl implements MailService { field = service.getClass().getDeclaredField(mailFiledName);
field.setAccessible(true);
@Override field.set(service, impl);
public Boolean AsyncSend(SimpleMailMessage message) { } catch (NoSuchFieldException | IllegalAccessException e) {
log.debug("异步邮件请求,SimpleMailMessage:[{}]", getJson(message)); e.printStackTrace();
return true; }
} }
@Override
public Boolean send(SimpleMailMessage message) { @Slf4j
log.debug("邮件请求,SimpleMailMessage:[{}]", getJson(message)); public static class TestMailServiceImpl implements MailService {
return true;
} @Override
public Boolean AsyncSend(SimpleMailMessage message) {
/** log.debug("异步邮件请求,SimpleMailMessage:[{}]", getJson(message));
* 转json return true;
* }
* @param o
* @return @Override
*/ public Boolean send(SimpleMailMessage message) {
private String getJson(Object o) { log.debug("邮件请求,SimpleMailMessage:[{}]", getJson(message));
ObjectMapper mapper = new ObjectMapper(); return true;
try { }
return mapper.writeValueAsString(o);
} catch (JsonProcessingException e) { /**
return null; * 转json
} *
} * @param o
} * @return
*/
} private String getJson(Object o) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writeValueAsString(o);
} catch (JsonProcessingException e) {
return null;
}
}
}
@Slf4j
public static class TestFileManager implements FileManager {
@Override
public FileResponse uploadFile(InputStream is, String fileName) {
FileResponse response = new FileResponse();
log.debug("上传文件请求,[fileName:{}]", fileName);
response.key = "key";
response.type = "test";
response.hash = "hash";
response.size = 1;
return response;
}
@Override
public List<FileInfo> getFileList() {
log.debug("获取文件列表请求");
return new ArrayList<>();
}
@Override
public boolean deleteFile(String fileName) {
log.debug("删除[{}]成功", fileName);
return true;
}
}
}

View File

@@ -0,0 +1,37 @@
package cn.celess.blog;
import org.springframework.stereotype.Component;
import redis.embedded.RedisServer;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
/**
* @author : xiaohai
* @date : 2020/08/14 16:20
*/
@Component
public class RedisServerMock {
private RedisServer redisServer;
/**
* 构造方法之后执行.
*
* @throws IOException e
*/
@PostConstruct
public void startRedis() throws IOException {
redisServer = new RedisServer(6380);
redisServer.start();
}
/**
* 析构方法之后执行.
*/
@PreDestroy
public void stopRedis() {
redisServer.stop();
}
}

View File

@@ -0,0 +1,131 @@
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;
}
}
}

View File

@@ -9,29 +9,30 @@ import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.entity.request.ArticleReq; import cn.celess.blog.entity.request.ArticleReq;
import cn.celess.blog.mapper.ArticleMapper; import cn.celess.blog.mapper.ArticleMapper;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.sf.json.JSONObject;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.util.List;
import java.util.*; import static cn.celess.blog.enmu.ResponseEnum.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static cn.celess.blog.enmu.ResponseEnum.*;
public class ArticleControllerTest extends BaseTest { public class ArticleControllerTest extends BaseTest {
@Autowired @Autowired
ArticleMapper articleMapper; ArticleMapper articleMapper;
private static final TypeReference<?> ARTICLE_MODEL_TYPE = new TypeReference<Response<ArticleModel>>() {
};
private static final TypeReference<?> ARTICLE_MODEL_PAGE_TYPE = new TypeReference<Response<PageData<ArticleModel>>>() {
};
@Test @Test
public void create() { public void create() {
ArticleReq articleReq = new ArticleReq(); ArticleReq articleReq = new ArticleReq();
// 应该正常通过 // 应该正常通过
articleReq.setTitle("test-" + UUID.randomUUID().toString()); articleReq.setTitle("test-" + randomStr());
articleReq.setMdContent("# test title"); articleReq.setMdContent("# test title");
articleReq.setCategory("随笔"); articleReq.setCategory("随笔");
String[] tagList = {"tag", "category"}; String[] tagList = {"tag", "category"};
@@ -39,58 +40,29 @@ public class ArticleControllerTest extends BaseTest {
articleReq.setOpen(true); articleReq.setOpen(true);
articleReq.setType(true); articleReq.setType(true);
articleReq.setUrl("http://xxxx.com"); articleReq.setUrl("http://xxxx.com");
JSONObject jsonObject = JSONObject.fromObject(articleReq); MockHttpServletRequestBuilder post = post("/admin/article/create");
try { try {
// 未登录 getMockData(post, adminLogin(), articleReq).andDo(result -> {
mockMvc.perform(post("/admin/article/create") Response<ArticleModel> response = getResponse(result, ARTICLE_MODEL_TYPE);
.content(jsonObject.toString()) assertEquals(SUCCESS.getCode(), response.getCode());
.contentType("application/json")) assertNotNull(response.getResult());
.andExpect(status().isOk()) ArticleModel articleModel = response.getResult();
.andDo(result -> { assertNotNull(articleModel.getId());
assertEquals(HAVE_NOT_LOG_IN.getCode(), assertNotNull(articleModel.getTitle());
JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code) assertNotNull(articleModel.getSummary());
); assertNotNull(articleModel.getOriginal());
}); assertNotNull(articleModel.getTags());
// User权限 assertNotNull(articleModel.getCategory());
String token = userLogin(); assertNotNull(articleModel.getPublishDateFormat());
mockMvc.perform(post("/admin/article/create") assertNotNull(articleModel.getMdContent());
.content(jsonObject.toString()) assertNotNull(articleModel.getPreArticle());
.contentType("application/json") assertNull(articleModel.getNextArticle());
.header("Authorization", token)) assertNotNull(articleModel.getOpen());
.andExpect(status().isOk()) assertNotNull(articleModel.getReadingNumber());
.andDo(result -> { assertNotNull(articleModel.getAuthor());
assertEquals(PERMISSION_ERROR.getCode(), assertNotNull(articleModel.getUrl());
JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code) });
);
});
// Admin权限
token = adminLogin();
mockMvc.perform(post("/admin/article/create")
.content(jsonObject.toString())
.contentType("application/json")
.header("Authorization", token))
.andExpect(status().isOk())
.andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), object.getInt(Code));
ArticleModel articleModel = (ArticleModel) JSONObject.toBean(object.getJSONObject(Result), ArticleModel.class);
assertNotNull(articleModel.getId());
assertNotNull(articleModel.getTitle());
assertNotNull(articleModel.getSummary());
assertNotNull(articleModel.getOriginal());
assertNotNull(articleModel.getTags());
assertNotNull(articleModel.getCategory());
assertNotNull(articleModel.getPublishDateFormat());
assertNotNull(articleModel.getMdContent());
assertNotNull(articleModel.getPreArticle());
assertNull(articleModel.getNextArticle());
assertNotNull(articleModel.getOpen());
assertNotNull(articleModel.getReadingNumber());
assertNotNull(articleModel.getAuthor());
assertNotNull(articleModel.getUrl());
});
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -98,33 +70,22 @@ public class ArticleControllerTest extends BaseTest {
@Test @Test
public void delete() { public void delete() {
Article article = articleMapper.getLastestArticle(); Article article;
do {
article = articleMapper.getLastestArticle();
create();
} while (article.isDeleted());
assertFalse(article.isDeleted());
MockHttpServletRequestBuilder delete = MockMvcRequestBuilders.delete("/admin/article/del?articleID=" + article.getId());
try { try {
// 未登录删除文章 Article finalArticle = article;
mockMvc.perform(MockMvcRequestBuilders.delete("/admin/article/del?articleID=" + article.getId()) getMockData(delete, adminLogin()).andDo(result -> {
).andDo(result -> { Response<Boolean> response = getResponse(result, BOOLEAN_TYPE);
assertEquals(HAVE_NOT_LOG_IN.getCode(), assertEquals(SUCCESS.getCode(), response.getCode());
JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code) // 断言删除成功
); assertTrue(response.getResult());
assertTrue(articleMapper.isDeletedById(finalArticle.getId()));
}); });
// user 权限删除文章
String token = userLogin();
mockMvc.perform(MockMvcRequestBuilders.delete("/admin/article/del?articleID=" + article.getId())
.header("Authorization", token))
.andDo(result -> assertEquals(PERMISSION_ERROR.getCode(),
JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))
);
// admin 权限删除文章
token = adminLogin();
mockMvc.perform(MockMvcRequestBuilders.delete("/admin/article/del?articleID=" + article.getId())
.header("Authorization", token))
.andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), object.getInt(Code));
// 断言删除成功
assertTrue(object.getBoolean(Result));
});
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -146,27 +107,21 @@ public class ArticleControllerTest extends BaseTest {
articleReq.setTags(tagList); articleReq.setTags(tagList);
articleReq.setTitle("test-" + article.getTitle()); articleReq.setTitle("test-" + article.getTitle());
try { try {
// Admin 权限 getMockData(put("/admin/article/update"), adminLogin(), articleReq).andDo(result -> {
mockMvc.perform(put("/admin/article/update") Response<ArticleModel> response = getResponse(result, ARTICLE_MODEL_TYPE);
.content(JSONObject.fromObject(articleReq).toString()) assertEquals(SUCCESS.getCode(), response.getCode());
.contentType("application/json") ArticleModel a = response.getResult();
.header("Authorization", adminLogin())) assertEquals(articleReq.getCategory(), a.getCategory());
.andExpect(status().isOk()) assertEquals(articleReq.getUrl(), a.getUrl());
.andDo(result -> { assertEquals(articleReq.getMdContent(), a.getMdContent());
JSONObject jsonObject = JSONObject.fromObject(result.getResponse().getContentAsString()); assertEquals(articleReq.getTitle(), a.getTitle());
assertEquals(SUCCESS.getCode(), jsonObject.getInt(Code)); assertEquals(articleReq.getType(), a.getOriginal());
ArticleModel a = (ArticleModel) JSONObject.toBean(jsonObject.getJSONObject(Result), ArticleModel.class); // Tag
assertEquals(articleReq.getCategory(), a.getCategory()); List<Tag> asList = a.getTags();
assertEquals(articleReq.getUrl(), a.getUrl()); assertEquals(3, asList.size());
assertEquals(articleReq.getMdContent(), a.getMdContent()); assertEquals(articleReq.getOpen(), a.getOpen());
assertEquals(articleReq.getTitle(), a.getTitle()); assertEquals(articleReq.getId(), a.getId());
assertEquals(articleReq.getType(), a.getOriginal()); });
// Tag
List<Tag> asList = a.getTags();
assertEquals(3, asList.size());
assertEquals(articleReq.getOpen(), a.getOpen());
assertEquals(articleReq.getId(), a.getId());
});
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -176,43 +131,35 @@ public class ArticleControllerTest extends BaseTest {
public void retrieveOneById() { public void retrieveOneById() {
try { try {
long articleID = 3; long articleID = 3;
mockMvc.perform(MockMvcRequestBuilders.get("/article/articleID/" + articleID)) getMockData(MockMvcRequestBuilders.get("/article/articleID/" + articleID));
.andExpect(status().is(200)); getMockData(MockMvcRequestBuilders.get("/article/articleID/" + articleID + "?update=true"));
mockMvc.perform(MockMvcRequestBuilders.get("/article/articleID/" + articleID + "?update=true"))
.andExpect(status().is(200));
// 文章不存在 // 文章不存在
mockMvc.perform(MockMvcRequestBuilders.get("/article/articleID/-1")) getMockData(MockMvcRequestBuilders.get("/article/articleID/-1"))
.andExpect(status().is(200)) .andDo(result -> assertEquals(ARTICLE_NOT_EXIST.getCode(), getResponse(result, STRING_TYPE).getCode()));
.andDo(result -> {
JSONObject jsonObject = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(ARTICLE_NOT_EXIST.getCode(), jsonObject.getInt(Code));
});
// 正常情况 // 正常情况
mockMvc.perform(MockMvcRequestBuilders.get("/article/articleID/" + articleID + "?update=false")) getMockData(MockMvcRequestBuilders.get("/article/articleID/" + articleID + "?update=false")).andDo(result -> {
.andExpect(status().is(200)) Response<ArticleModel> response = getResponse(result, ARTICLE_MODEL_TYPE);
.andDo(result -> { // 断言获取数据成功
JSONObject articleJson = JSONObject.fromObject(result.getResponse().getContentAsString()); assertEquals(SUCCESS.getCode(), response.getCode());
// 断言获取数据成功 assertNotNull(response.getResult());
assertEquals(SUCCESS.getCode(), articleJson.getInt(Code));
assertNotNull(articleJson.getJSONObject(Result));
ArticleModel a = (ArticleModel) JSONObject.toBean(articleJson.getJSONObject(Result), ArticleModel.class); ArticleModel a = response.getResult();
assertNotNull(a.getTitle()); assertNotNull(a.getTitle());
assertNotNull(a.getId()); assertNotNull(a.getId());
assertNotNull(a.getSummary()); assertNotNull(a.getSummary());
assertNotNull(a.getMdContent()); assertNotNull(a.getMdContent());
assertNotNull(a.getUrl()); assertNotNull(a.getUrl());
assertNotNull(a.getUpdateDateFormat()); assertNotNull(a.getUpdateDateFormat());
assertTrue(a.getPreArticle() != null || a.getNextArticle() != null); assertTrue(a.getPreArticle() != null || a.getNextArticle() != null);
assertNotNull(a.getReadingNumber()); assertNotNull(a.getReadingNumber());
assertNotNull(a.getOriginal()); assertNotNull(a.getOriginal());
assertNotNull(a.getPublishDateFormat()); assertNotNull(a.getPublishDateFormat());
assertNotNull(a.getCategory()); assertNotNull(a.getCategory());
assertNotNull(a.getTags()); assertNotNull(a.getTags());
assertNotNull(a.getAuthor()); assertNotNull(a.getAuthor());
}); });
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -222,39 +169,32 @@ public class ArticleControllerTest extends BaseTest {
public void articles() { public void articles() {
try { try {
// 测试不带参数访问 // 测试不带参数访问
mockMvc.perform(MockMvcRequestBuilders.get("/articles")) getMockData(MockMvcRequestBuilders.get("/articles"));
.andExpect(status().is(200)); getMockData(MockMvcRequestBuilders.get("/articles?page=1&count=5")).andDo(result -> {
Response<PageData<ArticleModel>> response = getResponse(result, ARTICLE_MODEL_PAGE_TYPE);
mockMvc.perform(MockMvcRequestBuilders.get("/articles?page=1&count=5")) // 断言获取数据成功
.andExpect(status().is(200)) assertEquals(SUCCESS.getCode(), response.getCode());
.andDo(result -> { // 结果集非空
JSONObject articlesJSON = JSONObject.fromObject(result.getResponse().getContentAsString()); assertNotNull(response.getResult());
Response response = (Response) JSONObject.toBean(articlesJSON, Response.class); // 判断pageInfo是否包装完全
// 断言获取数据成功 PageData<ArticleModel> pageData = response.getResult();
assertEquals(SUCCESS.getCode(), response.getCode()); assertNotEquals(0, pageData.getTotal());
// 结果集非空 assertEquals(1, pageData.getPageNum());
assertNotNull(response.getResult()); assertEquals(5, pageData.getPageSize());
// 判断pageInfo是否包装完全 // 内容完整
JSONObject resultJson = JSONObject.fromObject(response.getResult()); for (ArticleModel a : pageData.getList()) {
PageData<ArticleModel> pageData = (PageData<ArticleModel>) JSONObject.toBean(resultJson, PageData.class); assertNotNull(a.getTitle());
assertNotEquals(0, pageData.getTotal()); assertNotNull(a.getId());
assertEquals(1, pageData.getPageNum()); assertNotNull(a.getSummary());
assertEquals(5, pageData.getPageSize()); assertNotNull(a.getOriginal());
// 内容完整 assertNotNull(a.getPublishDateFormat());
for (Object arc : pageData.getList()) { assertNotNull(a.getCategory());
ArticleModel a = (ArticleModel) JSONObject.toBean(JSONObject.fromObject(arc), ArticleModel.class); assertNotNull(a.getTags());
assertNotNull(a.getTitle()); assertNotNull(a.getAuthor());
assertNotNull(a.getId()); assertNull(a.getOpen());
assertNotNull(a.getSummary()); assertNull(a.getMdContent());
assertNotNull(a.getOriginal()); }
assertNotNull(a.getPublishDateFormat()); });
assertNotNull(a.getCategory());
assertNotNull(a.getTags());
assertNotNull(a.getAuthor());
assertNull(a.getOpen());
assertNull(a.getMdContent());
}
});
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -264,19 +204,18 @@ public class ArticleControllerTest extends BaseTest {
public void adminArticles() { public void adminArticles() {
try { try {
getMockData(get("/admin/articles?page=1&count=10")).andExpect(result -> getMockData(get("/admin/articles?page=1&count=10")).andExpect(result ->
assertEquals(HAVE_NOT_LOG_IN.getCode(), mapper.readValue(result.getResponse().getContentAsString(), Response.class).getCode()) assertEquals(HAVE_NOT_LOG_IN.getCode(), getResponse(result, STRING_TYPE).getCode())
); );
// User权限登陆 // User权限登陆
getMockData(get("/admin/articles?page=1&count=10"), userLogin()).andDo(result -> getMockData(get("/admin/articles?page=1&count=10"), userLogin()).andDo(result ->
assertEquals(PERMISSION_ERROR.getCode(), mapper.readValue(result.getResponse().getContentAsString(), Response.class).getCode()) assertEquals(PERMISSION_ERROR.getCode(), getResponse(result, STRING_TYPE).getCode())
); );
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
// admin权限登陆 // admin权限登陆
int finalI = i; int finalI = i;
getMockData(get("/admin/articles?page=1&count=10&deleted=" + (i == 1)), adminLogin()).andDo(result -> { getMockData(get("/admin/articles?page=1&count=10&deleted=" + (i == 1)), adminLogin()).andDo(result -> {
Response<PageData<ArticleModel>> response = mapper.readValue(result.getResponse().getContentAsString(), new TypeReference<Response<PageData<ArticleModel>>>() { Response<PageData<ArticleModel>> response = getResponse(result, ARTICLE_MODEL_PAGE_TYPE);
});
assertEquals(SUCCESS.getCode(), response.getCode()); assertEquals(SUCCESS.getCode(), response.getCode());
assertNotNull(response.getResult()); assertNotNull(response.getResult());
// 判断pageInfo是否包装完全 // 判断pageInfo是否包装完全
@@ -309,27 +248,22 @@ public class ArticleControllerTest extends BaseTest {
try { try {
// 分类不存在 // 分类不存在
String categoryName = "NoSuchCategory"; String categoryName = "NoSuchCategory";
mockMvc.perform(MockMvcRequestBuilders.get("/articles/category/" + categoryName + "?page=1&count=10")) getMockData(MockMvcRequestBuilders.get("/articles/category/" + categoryName + "?page=1&count=10"))
.andExpect(status().is(200)) .andDo(result -> assertEquals(CATEGORY_NOT_EXIST.getCode(), getResponse(result, STRING_TYPE).getCode()));
.andDo(result -> {
assertEquals(CATEGORY_NOT_EXIST.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code));
});
// 正常查询 // 正常查询
categoryName = "linux"; categoryName = "linux";
mockMvc.perform(MockMvcRequestBuilders.get("/articles/category/" + categoryName + "?page=1&count=10")) getMockData(MockMvcRequestBuilders.get("/articles/category/" + categoryName + "?page=1&count=10"))
.andExpect(status().is(200))
.andDo(result -> { .andDo(result -> {
JSONObject jsonObject = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<PageData<ArticleModel>> response = getResponse(result, ARTICLE_MODEL_PAGE_TYPE);
assertEquals(SUCCESS.getCode(), jsonObject.getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
PageData<ArticleModel> pageData = (PageData<ArticleModel>) JSONObject.toBean(jsonObject.getJSONObject(Result), PageData.class); PageData<ArticleModel> pageData = response.getResult();
assertNotEquals(0, pageData.getTotal()); assertNotEquals(0, pageData.getTotal());
assertEquals(1, pageData.getPageNum()); assertEquals(1, pageData.getPageNum());
assertEquals(10, pageData.getPageSize()); assertEquals(10, pageData.getPageSize());
for (Object arc : pageData.getList()) { for (ArticleModel arc : pageData.getList()) {
JSONObject jsonObject1 = JSONObject.fromObject(arc); assertNotEquals(0, arc.getId().longValue());
assertNotEquals(0, jsonObject1.getInt("id")); assertNotNull(arc.getTitle());
assertNotNull(jsonObject1.getString("title")); assertNotNull(arc.getSummary());
assertNotNull(jsonObject1.getString("summary"));
} }
}); });
} catch (Exception e) { } catch (Exception e) {
@@ -342,28 +276,23 @@ public class ArticleControllerTest extends BaseTest {
try { try {
// 分类不存在 // 分类不存在
String tagName = "NoSuchTag"; String tagName = "NoSuchTag";
mockMvc.perform(MockMvcRequestBuilders.get("/articles/tag/" + tagName + "?page=1&count=10")) getMockData(MockMvcRequestBuilders.get("/articles/tag/" + tagName + "?page=1&count=10"))
.andExpect(status().is(200)) .andDo(result -> assertEquals(TAG_NOT_EXIST.getCode(), getResponse(result, STRING_TYPE).getCode()));
.andDo(result -> {
assertEquals(TAG_NOT_EXIST.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code));
});
// 正常查询 // 正常查询
tagName = "linux"; tagName = "linux";
mockMvc.perform(MockMvcRequestBuilders.get("/articles/tag/" + tagName + "?page=1&count=10")) getMockData(MockMvcRequestBuilders.get("/articles/tag/" + tagName + "?page=1&count=10"))
.andExpect(status().is(200))
.andDo(result -> { .andDo(result -> {
JSONObject jsonObject = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<PageData<ArticleModel>> response = getResponse(result, ARTICLE_MODEL_PAGE_TYPE);
assertEquals(SUCCESS.getCode(), jsonObject.getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
PageData<ArticleModel> pageData = (PageData<ArticleModel>) JSONObject.toBean(jsonObject.getJSONObject(Result), PageData.class); PageData<ArticleModel> pageData = response.getResult();
assertNotEquals(0, pageData.getTotal()); assertNotEquals(0, pageData.getTotal());
assertEquals(1, pageData.getPageNum()); assertEquals(1, pageData.getPageNum());
assertEquals(10, pageData.getPageSize()); assertEquals(10, pageData.getPageSize());
for (Object arc : pageData.getList()) { for (ArticleModel arc : pageData.getList()) {
JSONObject jsonObject1 = JSONObject.fromObject(arc); assertNotEquals(0, arc.getId().longValue());
assertNotEquals(0, jsonObject1.getInt("id")); assertNotNull(arc.getTitle());
assertNotNull(jsonObject1.getString("title")); assertNotNull(arc.getSummary());
assertNotNull(jsonObject1.getString("summary"));
} }
}); });
} catch (Exception e) { } catch (Exception e) {

View File

@@ -2,132 +2,77 @@ package cn.celess.blog.controller;
import cn.celess.blog.BaseTest; import cn.celess.blog.BaseTest;
import cn.celess.blog.entity.Category; import cn.celess.blog.entity.Category;
import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.model.CategoryModel; import cn.celess.blog.entity.model.CategoryModel;
import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.mapper.CategoryMapper; import cn.celess.blog.mapper.CategoryMapper;
import net.sf.json.JSONArray; import com.fasterxml.jackson.core.type.TypeReference;
import net.sf.json.JSONObject;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.UUID; import static cn.celess.blog.enmu.ResponseEnum.SUCCESS;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static cn.celess.blog.enmu.ResponseEnum.*;
public class CategoryControllerTest extends BaseTest { public class CategoryControllerTest extends BaseTest {
@Autowired @Autowired
CategoryMapper categoryMapper; CategoryMapper categoryMapper;
private static final TypeReference<?> CATEGORY_MODEL_TYPE = new TypeReference<Response<CategoryModel>>() {
};
private static final TypeReference<?> CATEGORY_MODEL_PAGE_TYPE = new TypeReference<Response<PageData<CategoryModel>>>() {
};
@Test @Test
public void addOne() throws Exception { public void addOne() throws Exception {
String categoryName = randomStr(4); String categoryName = randomStr(4);
System.out.println("categoryName: ==> " + categoryName); getMockData(post("/admin/category/create?name=" + categoryName), adminLogin()).andDo(result -> {
// 未登录 Response<CategoryModel> response = getResponse(result, CATEGORY_MODEL_TYPE);
mockMvc.perform(post("/admin/category/create?name=" + categoryName)).andExpect(status().isOk()) assertEquals(SUCCESS.getCode(), response.getCode());
.andDo(result -> { CategoryModel category = response.getResult();
assertEquals(HAVE_NOT_LOG_IN.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code)); assertEquals(categoryName, category.getName());
}); assertNotNull(category.getId());
// User权限 assertNull(category.getArticles());
String token = userLogin(); });
mockMvc.perform(post("/admin/category/create?name=" + categoryName)
.header("Authorization", token))
.andExpect(status().isOk())
.andDo(result -> {
assertEquals(PERMISSION_ERROR.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code));
});
// Admin权限
token = adminLogin();
mockMvc.perform(post("/admin/category/create?name=" + categoryName)
.header("Authorization", token))
.andExpect(status().isOk())
.andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), object.getInt(Code));
CategoryModel category = (CategoryModel) JSONObject.toBean(object.getJSONObject(Result), CategoryModel.class);
assertEquals(categoryName, category.getName());
assertNotNull(category.getId());
assertNotEquals(0, category.getArticles());
});
} }
@Test @Test
public void deleteOne() throws Exception { public void deleteOne() throws Exception {
Category category = categoryMapper.getLastestCategory(); Category category = categoryMapper.getLastestCategory();
// 未登录 getMockData(delete("/admin/category/del?id=" + category.getId()), adminLogin()).andDo(result -> {
mockMvc.perform(delete("/admin/category/del?id=" + category.getId())).andExpect(status().isOk()) Response<Boolean> response = getResponse(result, BOOLEAN_TYPE);
.andDo(result -> { assertEquals(SUCCESS.getCode(), response.getCode());
assertEquals(HAVE_NOT_LOG_IN.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code)); assertTrue(response.getResult());
}); });
// User权限
String token = userLogin();
mockMvc.perform(delete("/admin/category/del?id=" + category.getId())
.header("Authorization", token))
.andExpect(status().isOk())
.andDo(result -> {
assertEquals(PERMISSION_ERROR.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code));
});
// Admin权限
token = adminLogin();
mockMvc.perform(delete("/admin/category/del?id=" + category.getId())
.header("Authorization", token))
.andExpect(status().isOk())
.andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), object.getInt(Code));
assertTrue(object.getBoolean(Result));
});
} }
@Test @Test
public void updateOne() throws Exception { public void updateOne() throws Exception {
Category category = categoryMapper.getLastestCategory(); Category category = categoryMapper.getLastestCategory();
String name = randomStr(4); String name = randomStr(4);
// 未登录 getMockData(put("/admin/category/update?id=" + category.getId() + "&name=" + name), adminLogin()).andDo(result -> {
mockMvc.perform(put("/admin/category/update?id=" + category.getId() + "&name=" + name)).andExpect(status().isOk()) // Response<CategoryModel> response = mapper.readValue(result.getResponse().getContentAsString(), new ResponseType<Response<CategoryModel>>());
.andDo(result -> { Response<CategoryModel> response = getResponse(result, CATEGORY_MODEL_TYPE);
assertEquals(HAVE_NOT_LOG_IN.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
}); CategoryModel c = response.getResult();
// User权限 assertEquals(name, c.getName());
String token = userLogin(); assertNull(c.getArticles());
mockMvc.perform(put("/admin/category/update?id=" + category.getId() + "&name=" + name) assertNotNull(c.getId());
.header("Authorization", token)) });
.andExpect(status().isOk())
.andDo(result -> {
assertEquals(PERMISSION_ERROR.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code));
});
// Admin权限
token = adminLogin();
mockMvc.perform(put("/admin/category/update?id=" + category.getId() + "&name=" + name)
.header("Authorization", token))
.andExpect(status().isOk())
.andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), object.getInt(Code));
CategoryModel c = (CategoryModel) JSONObject.toBean(object.getJSONObject(Result), CategoryModel.class);
assertEquals(name, c.getName());
assertNotEquals(0, c.getArticles());
assertNotNull(c.getId());
});
} }
@Test @Test
public void getPage() throws Exception { public void getPage() throws Exception {
mockMvc.perform(get("/categories")).andExpect(status().isOk()) getMockData(get("/categories")).andDo(result -> {
.andDo(result -> { Response<PageData<CategoryModel>> response = getResponse(result, CATEGORY_MODEL_PAGE_TYPE);
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); assertEquals(SUCCESS.getCode(), response.getCode());
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertNotNull(response.getResult());
JSONArray jsonArray = object.getJSONObject(Result).getJSONArray("list"); response.getResult().getList().forEach(c -> {
assertNotNull(jsonArray); assertNotNull(c.getName());
jsonArray.forEach(o -> { assertNotNull(c.getId());
CategoryModel c = (CategoryModel) JSONObject.toBean(JSONObject.fromObject(o), CategoryModel.class); assertNotNull(c.getArticles());
assertNotNull(c.getName()); });
assertNotNull(c.getId()); });
assertNotEquals(0, c.getArticles());
});
});
} }
} }

View File

@@ -3,21 +3,22 @@ package cn.celess.blog.controller;
import cn.celess.blog.BaseTest; import cn.celess.blog.BaseTest;
import cn.celess.blog.entity.Article; import cn.celess.blog.entity.Article;
import cn.celess.blog.entity.Comment; import cn.celess.blog.entity.Comment;
import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.User; import cn.celess.blog.entity.User;
import cn.celess.blog.entity.model.CommentModel; import cn.celess.blog.entity.model.CommentModel;
import cn.celess.blog.entity.request.CommentReq; import cn.celess.blog.entity.request.CommentReq;
import cn.celess.blog.mapper.ArticleMapper; import cn.celess.blog.mapper.ArticleMapper;
import cn.celess.blog.mapper.CommentMapper; import cn.celess.blog.mapper.CommentMapper;
import cn.celess.blog.mapper.UserMapper; import cn.celess.blog.mapper.UserMapper;
import net.sf.json.JSONObject; import com.fasterxml.jackson.core.type.TypeReference;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import java.util.UUID; import java.util.List;
import static cn.celess.blog.enmu.ResponseEnum.DATA_IS_DELETED;
import static cn.celess.blog.enmu.ResponseEnum.SUCCESS;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static cn.celess.blog.enmu.ResponseEnum.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
public class CommentControllerTest extends BaseTest { public class CommentControllerTest extends BaseTest {
@@ -27,46 +28,40 @@ public class CommentControllerTest extends BaseTest {
UserMapper userMapper; UserMapper userMapper;
@Autowired @Autowired
CommentMapper commentMapper; CommentMapper commentMapper;
private static final TypeReference<?> COMMENT_MODEL_TYPE = new TypeReference<Response<CommentModel>>() {
};
@Test @Test
public void addOne() throws Exception { public void addOne() throws Exception {
Article article = articleMapper.getLastestArticle(); Article article = articleMapper.getLastestArticle();
CommentReq commentReq = new CommentReq(); CommentReq commentReq = new CommentReq();
commentReq.setPagePath("/article/" + article.getId()); commentReq.setPagePath("/article/" + article.getId());
commentReq.setContent(UUID.randomUUID().toString()); commentReq.setContent(randomStr());
commentReq.setPid(-1L); List<User> all = userMapper.findAll();
commentReq.setToUserId(-1L); commentReq.setPid(1L);
String token = userLogin(); commentReq.setToUserId(2l);
mockMvc.perform(post("/user/comment/create") getMockData(post("/user/comment/create"), userLogin(), commentReq).andDo(result -> {
.contentType(MediaType.APPLICATION_JSON_UTF8) Response<CommentModel> response = getResponse(result, COMMENT_MODEL_TYPE);
.content(JSONObject.fromObject(commentReq).toString()) assertEquals(SUCCESS.getCode(), response.getCode());
.header("Authorization", token) CommentModel model = response.getResult();
).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), object.getInt(Code));
CommentModel model = (CommentModel) JSONObject.toBean(object.getJSONObject(Result), CommentModel.class);
assertNotEquals(0, model.getId()); assertNotEquals(0, model.getId());
assertEquals(commentReq.getPid(), model.getPid().longValue()); assertEquals(commentReq.getPid(), model.getPid().longValue());
assertEquals(-1, model.getPid().longValue()); assertEquals(1, model.getPid().longValue());
assertEquals(commentReq.getContent(), model.getContent()); assertEquals(commentReq.getContent(), model.getContent());
assertNotNull(model.getDate()); assertNotNull(model.getDate());
assertNotNull(model.getFromUser()); assertNotNull(model.getFromUser());
assertNull(model.getToUser()); assertNotNull(model.getToUser());
}); });
commentReq.setPagePath("/article/" + article.getId()); commentReq.setPagePath("/article/" + article.getId());
commentReq.setContent(UUID.randomUUID().toString()); commentReq.setContent(randomStr());
commentReq.setPid(-1L); commentReq.setPid(-1L);
commentReq.setToUserId(2); commentReq.setToUserId(2);
mockMvc.perform(post("/user/comment/create") getMockData(post("/user/comment/create"), userLogin(), commentReq).andDo(result -> {
.contentType(MediaType.APPLICATION_JSON_UTF8) Response<CommentModel> response = getResponse(result, COMMENT_MODEL_TYPE);
.content(JSONObject.fromObject(commentReq).toString()) assertEquals(SUCCESS.getCode(), response.getCode());
.header("Authorization", token) CommentModel model = response.getResult();
).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), object.getInt(Code));
CommentModel model = (CommentModel) JSONObject.toBean(object.getJSONObject(Result), CommentModel.class);
// 响应数据的完整性 // 响应数据的完整性
assertNotEquals(0, model.getId()); assertNotEquals(0, model.getId());
assertEquals(commentReq.getPid(), model.getPid().longValue()); assertEquals(commentReq.getPid(), model.getPid().longValue());
@@ -79,20 +74,16 @@ public class CommentControllerTest extends BaseTest {
}); });
// 测试二级回复 // 测试二级回复
Comment lastestComment = commentMapper.getLastestComment(); Comment latestComment = commentMapper.getLastestComment();
commentReq.setPagePath("/article/" + article.getId()); commentReq.setPagePath("/article/" + article.getId());
commentReq.setContent(UUID.randomUUID().toString()); commentReq.setContent(randomStr());
commentReq.setPid(lastestComment.getId()); commentReq.setPid(latestComment.getId());
mockMvc.perform(post("/user/comment/create") getMockData(post("/user/comment/create"), userLogin(), commentReq).andDo(result -> {
.contentType(MediaType.APPLICATION_JSON_UTF8) Response<CommentModel> response = getResponse(result, COMMENT_MODEL_TYPE);
.content(JSONObject.fromObject(commentReq).toString()) assertEquals(SUCCESS.getCode(), response.getCode());
.header("Authorization", token) CommentModel model = response.getResult();
).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), object.getInt(Code));
CommentModel model = (CommentModel) JSONObject.toBean(object.getJSONObject(Result), CommentModel.class);
// 重新获取父评论信息 // 重新获取父评论信息
Comment pCommon = commentMapper.findCommentById(lastestComment.getId()); Comment pCommon = commentMapper.findCommentById(latestComment.getId());
assertEquals(pCommon.getId(), model.getPid()); assertEquals(pCommon.getId(), model.getPid());
}); });
} }
@@ -116,16 +107,13 @@ public class CommentControllerTest extends BaseTest {
// 接口测试 // 接口测试
long id = comment.getId(); long id = comment.getId();
assertNotEquals(0, id); assertNotEquals(0, id);
String token = userLogin(); getMockData(delete("/user/comment/del?id=" + id), userLogin()).andDo(result -> {
mockMvc.perform(delete("/user/comment/del?id=" + id).header("Authorization", token)).andDo(result -> { Response<Boolean> response = getResponse(result, BOOLEAN_TYPE);
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); assertEquals(SUCCESS.getCode(), response.getCode());
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertTrue(response.getResult());
assertTrue(object.getBoolean(Result));
});
mockMvc.perform(delete("/user/comment/del?id=" + id).header("Authorization", token)).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(DATA_IS_DELETED.getCode(), object.getInt(Code));
}); });
getMockData(delete("/user/comment/del?id=" + id), userLogin())
.andDo(result -> assertEquals(DATA_IS_DELETED.getCode(), getResponse(result, COMMENT_MODEL_TYPE).getCode()));
} }
@Test @Test
@@ -133,16 +121,12 @@ public class CommentControllerTest extends BaseTest {
Comment comment = commentMapper.getLastestComment(); Comment comment = commentMapper.getLastestComment();
CommentReq commentReq = new CommentReq(); CommentReq commentReq = new CommentReq();
commentReq.setId(comment.getId()); commentReq.setId(comment.getId());
commentReq.setContent(UUID.randomUUID().toString()); commentReq.setContent(randomStr());
// 不合法数据 setResponseId // 不合法数据 setResponseId
mockMvc.perform(put("/user/comment/update") getMockData(put("/user/comment/update"), userLogin(), commentReq).andDo(result -> {
.content(JSONObject.fromObject(commentReq).toString()) Response<CommentModel> response = getResponse(result, COMMENT_MODEL_TYPE);
.contentType(MediaType.APPLICATION_JSON_UTF8) assertEquals(SUCCESS.getCode(), response.getCode());
.header("Authorization", userLogin()) CommentModel c = response.getResult();
).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), object.getInt(Code));
CommentModel c = (CommentModel) JSONObject.toBean(object.getJSONObject(Result), CommentModel.class);
assertEquals(commentReq.getContent(), c.getContent()); assertEquals(commentReq.getContent(), c.getContent());
}); });
} }

View File

@@ -1,261 +1,238 @@
package cn.celess.blog.controller; package cn.celess.blog.controller;
import cn.celess.blog.BaseTest; import cn.celess.blog.BaseTest;
import cn.celess.blog.entity.PartnerSite; import cn.celess.blog.entity.PartnerSite;
import cn.celess.blog.entity.model.PageData; import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.request.LinkApplyReq; import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.entity.request.LinkReq; import cn.celess.blog.entity.request.LinkApplyReq;
import cn.celess.blog.exception.MyException; import cn.celess.blog.entity.request.LinkReq;
import cn.celess.blog.mapper.PartnerMapper; import cn.celess.blog.exception.MyException;
import cn.celess.blog.service.MailService; import cn.celess.blog.mapper.PartnerMapper;
import cn.celess.blog.service.PartnerSiteService; import cn.celess.blog.service.PartnerSiteService;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j;
import lombok.extern.slf4j.Slf4j; import org.junit.Test;
import net.sf.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import java.util.List;
import org.springframework.http.MediaType;
import org.springframework.mail.SimpleMailMessage; import static cn.celess.blog.enmu.ResponseEnum.*;
import static org.junit.Assert.*;
import java.lang.reflect.Field; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import java.util.UUID;
@Slf4j
import static cn.celess.blog.enmu.ResponseEnum.*; public class LinksControllerTest extends BaseTest {
import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @Autowired
PartnerMapper mapper;
@Slf4j private static final TypeReference<?> LINK_MODEL_TYPE = new TypeReference<Response<PartnerSite>>() {
public class LinksControllerTest extends BaseTest { };
private static final TypeReference<?> LINK_MODEL_LIST_TYPE = new TypeReference<Response<List<PartnerSite>>>() {
@Autowired };
PartnerMapper mapper; private static final TypeReference<?> LINK_MODEL_PAGE_TYPE = new TypeReference<Response<PageData<PartnerSite>>>() {
@Autowired };
PartnerSiteService partnerSiteService; @Autowired
PartnerSiteService partnerSiteService;
@Test
public void create() throws Exception { @Test
LinkReq linkReq = new LinkReq(); public void create() throws Exception {
linkReq.setName(UUID.randomUUID().toString().substring(0, 4)); LinkReq linkReq = new LinkReq();
linkReq.setOpen(false); linkReq.setName(randomStr(4));
linkReq.setUrl("https://" + randomStr(4) + "celess.cn"); linkReq.setOpen(false);
String token = adminLogin(); linkReq.setUrl("https://" + randomStr(4) + "example.com");
mockMvc.perform( getMockData(post("/admin/links/create"), adminLogin(), linkReq).andDo(result -> {
post("/admin/links/create") Response<PartnerSite> response = getResponse(result, LINK_MODEL_TYPE);
.content(JSONObject.fromObject(linkReq).toString()) assertEquals(SUCCESS.getCode(), response.getCode());
.header("Authorization", token) PartnerSite site = response.getResult();
.contentType(MediaType.APPLICATION_JSON) assertNotNull(site.getId());
).andDo(result -> { assertEquals(linkReq.getName(), site.getName());
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); assertEquals(linkReq.getUrl(), site.getUrl());
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertEquals(linkReq.isOpen(), site.getOpen());
PartnerSite site = (PartnerSite) JSONObject.toBean(object.getJSONObject(Result), PartnerSite.class); });
assertNotNull(site.getId());
assertEquals(linkReq.getName(), site.getName()); // https/http
assertEquals(linkReq.getUrl(), site.getUrl()); linkReq.setName(randomStr(4));
assertEquals(linkReq.isOpen(), site.getOpen()); linkReq.setOpen(false);
}); linkReq.setUrl(randomStr(4) + ".example.com");
getMockData(post("/admin/links/create"), adminLogin(), linkReq).andDo(result -> {
// https/http Response<PartnerSite> response = getResponse(result, LINK_MODEL_TYPE);
linkReq.setName(UUID.randomUUID().toString().substring(0, 4)); assertEquals(SUCCESS.getCode(), response.getCode());
linkReq.setOpen(false); PartnerSite site = response.getResult();
String url = randomStr(4) + ".celess.cn"; assertEquals("http://" + linkReq.getUrl(), site.getUrl());
linkReq.setUrl(url); });
mockMvc.perform(
post("/admin/links/create") // 测试已存在的数据
.content(JSONObject.fromObject(linkReq).toString()) getMockData(post("/admin/links/create"), adminLogin(), linkReq).andDo(result ->
.header("Authorization", token) assertEquals(DATA_HAS_EXIST.getCode(), getResponse(result, STRING_TYPE).getCode())
.contentType("application/json") );
).andDo(result -> { }
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), object.getInt(Code)); @Test
PartnerSite site = (PartnerSite) JSONObject.toBean(object.getJSONObject(Result), PartnerSite.class); public void del() throws Exception {
assertEquals("http://" + url, site.getUrl()); PartnerSite partnerSite = new PartnerSite();
}); partnerSite.setName(randomStr(4));
partnerSite.setOpen(true);
// 测试已存在的数据 partnerSite.setDesc("");
mockMvc.perform( partnerSite.setIconPath("");
post("/admin/links/create") partnerSite.setUrl("https://" + randomStr(4) + ".celess.cn");
.content(JSONObject.fromObject(linkReq).toString()) mapper.insert(partnerSite);
.header("Authorization", token) PartnerSite latest = mapper.getLastest();
.contentType("application/json") assertNotNull(latest.getId());
).andDo(result -> assertEquals(DATA_HAS_EXIST.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))); getMockData(delete("/admin/links/del/" + latest.getId()), adminLogin()).andDo(result -> {
} Response<Boolean> response = getResponse(result, BOOLEAN_TYPE);
assertEquals(SUCCESS.getCode(), response.getCode());
@Test assertTrue(response.getResult());
public void del() throws Exception { });
PartnerSite partnerSite = new PartnerSite(); long id = latest.getId();
partnerSite.setName(UUID.randomUUID().toString().substring(0, 4)); do {
partnerSite.setOpen(true); id += 1;
partnerSite.setDesc(""); } while (mapper.existsById(id));
partnerSite.setIconPath(""); System.out.println("删除ID=" + id + "的数据");
partnerSite.setUrl("https://" + randomStr(4) + ".celess.cn"); getMockData(delete("/admin/links/del/" + id), adminLogin()).andDo(result ->
mapper.insert(partnerSite); assertEquals(DATA_NOT_EXIST.getCode(), getResponse(result, STRING_TYPE).getCode())
PartnerSite lastest = mapper.getLastest(); );
assertNotNull(lastest.getId()); }
String token = adminLogin();
mockMvc.perform(delete("/admin/links/del/" + lastest.getId()).header("Authorization", token)).andDo(result -> { @Test
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); public void update() throws Exception {
assertEquals(SUCCESS.getCode(), object.getInt(Code)); // 增数据
assertTrue(object.getBoolean(Result)); PartnerSite partnerSite = new PartnerSite();
}); partnerSite.setName(randomStr(4));
long id = lastest.getId(); partnerSite.setOpen(true);
do { partnerSite.setDesc("");
id += 1; partnerSite.setIconPath("");
} while (mapper.existsById(id)); partnerSite.setDelete(false);
System.out.println("删除ID=" + id + "的数据"); partnerSite.setUrl("https://" + randomStr(5) + ".celess.cn");
mockMvc.perform(delete("/admin/links/del/" + id).header("Authorization", token)).andDo(result -> mapper.insert(partnerSite);
assertEquals(DATA_NOT_EXIST.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code)) // 查数据
); PartnerSite latest = mapper.getLastest();
} assertNotNull(latest.getId());
// 构建请求
@Test LinkReq linkReq = new LinkReq();
public void update() throws Exception { linkReq.setUrl(latest.getUrl());
// 增数据 linkReq.setOpen(!latest.getOpen());
PartnerSite partnerSite = new PartnerSite(); linkReq.setName(randomStr(4));
partnerSite.setName(UUID.randomUUID().toString().substring(0, 4)); linkReq.setId(latest.getId());
partnerSite.setOpen(true);
partnerSite.setDesc(""); getMockData(put("/admin/links/update"), adminLogin(), linkReq).andDo(result -> {
partnerSite.setIconPath(""); Response<PartnerSite> response = getResponse(result, LINK_MODEL_TYPE);
partnerSite.setDelete(false); assertEquals(SUCCESS.getCode(), response.getCode());
partnerSite.setUrl("https://" + randomStr(4) + ".celess.cn"); PartnerSite site = response.getResult();
mapper.insert(partnerSite); assertNotNull(site.getId());
// 查数据 assertEquals(linkReq.getId(), site.getId().longValue());
PartnerSite lastest = mapper.getLastest(); assertEquals(linkReq.getUrl(), site.getUrl());
assertNotNull(lastest.getId()); assertEquals(linkReq.getName(), site.getName());
String token = adminLogin(); assertEquals(linkReq.isOpen(), site.getOpen());
// 构建请求 });
LinkReq linkReq = new LinkReq(); }
linkReq.setUrl(lastest.getUrl());
linkReq.setOpen(!lastest.getOpen()); @Test
linkReq.setName(UUID.randomUUID().toString().substring(0, 4)); public void allForOpen() throws Exception {
linkReq.setId(lastest.getId()); getMockData(get("/links")).andDo(result -> {
mockMvc.perform( Response<List<PartnerSite>> response = getResponse(result, LINK_MODEL_LIST_TYPE);
put("/admin/links/update") assertEquals(SUCCESS.getCode(), response.getCode());
.content(JSONObject.fromObject(linkReq).toString()) response.getResult().forEach(site -> {
.contentType(MediaType.APPLICATION_JSON) assertNotNull(site.getUrl());
.header("Authorization", token) assertNull(site.getOpen());
).andDo(result -> { assertNotNull(site.getName());
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); });
assertEquals(SUCCESS.getCode(), object.getInt(Code)); });
PartnerSite site = (PartnerSite) JSONObject.toBean(object.getJSONObject(Result), PartnerSite.class); }
assertNotNull(site.getId());
assertEquals(linkReq.getId(), site.getId().longValue()); @Test
assertEquals(linkReq.getUrl(), site.getUrl()); public void all() throws Exception {
assertEquals(linkReq.getName(), site.getName()); getMockData(get("/admin/links?page=1&count=10"), adminLogin()).andDo(result -> {
assertEquals(linkReq.isOpen(), site.getOpen()); Response<PageData<PartnerSite>> response = getResponse(result, LINK_MODEL_PAGE_TYPE);
}); assertEquals(SUCCESS.getCode(), response.getCode());
} PageData<PartnerSite> pageData = response.getResult();
assertEquals(1, pageData.getPageNum());
@Test assertEquals(10, pageData.getPageSize());
public void allForOpen() throws Exception { for (PartnerSite site : pageData.getList()) {
mockMvc.perform(get("/links")).andDo(result -> { assertNotNull(site.getUrl());
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); assertNotNull(site.getName());
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertNotNull(site.getOpen());
object.getJSONArray(Result).forEach(o -> { }
PartnerSite site = (PartnerSite) JSONObject.toBean(JSONObject.fromObject(o), PartnerSite.class); });
assertNotNull(site.getUrl()); }
assertNull(site.getOpen());
assertNotNull(site.getName()); @Test
}); public void apply() {
}); // 做service 层的测试
} // mockEmailServiceInstance(partnerSiteService, "mailService");
mockInjectInstance(partnerSiteService, "mailService", new TestMailServiceImpl());
@Test LinkApplyReq req = new LinkApplyReq();
public void all() throws Exception { req.setName(randomStr(4));
mockMvc.perform(get("/admin/links?page=1&count=10").header("Authorization", adminLogin())).andDo(result -> { req.setUrl("https://" + randomStr(4) + ".celess.cn");
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); req.setIconPath("https://www.celess.cn/example.png");
assertEquals(SUCCESS.getCode(), object.getInt(Code)); req.setDesc("desc :" + randomStr());
PageData<PartnerSite> pageData = (PageData<PartnerSite>) JSONObject.toBean(object.getJSONObject(Result), PageData.class); req.setEmail(randomStr(4) + "@celess.cn");
assertEquals(1, pageData.getPageNum()); req.setLinkUrl(req.getUrl() + "/links");
assertEquals(10, pageData.getPageSize()); try {
for (Object o : pageData.getList()) { // 抓取不到数据的链接
PartnerSite site = (PartnerSite) JSONObject.toBean(JSONObject.fromObject(o), PartnerSite.class); partnerSiteService.apply(req);
assertNotNull(site.getUrl()); } catch (MyException e) {
assertNotNull(site.getName()); log.debug("测试抓取不到数据");
assertNotNull(site.getOpen()); assertEquals(CANNOT_GET_DATA.getCode(), e.getCode());
} }
});
} req.setLinkUrl("https://bing.com");
req.setUrl(req.getLinkUrl());
// 手动测试 try {
@Test partnerSiteService.apply(req);
public void apply() { } catch (MyException e) {
// 做service 层的测试 log.debug("测试未添加本站链接的友链申请");
mockEmailServiceInstance(partnerSiteService, "mailService"); assertEquals(APPLY_LINK_NO_ADD_THIS_SITE.getCode(), e.getCode());
LinkApplyReq req = new LinkApplyReq(); assertNotNull(e.getResult());
req.setName(randomStr(4)); try {
req.setUrl("https://" + randomStr(4) + ".celess.cn"); // 测试uuid一致性
req.setIconPath("https://www.celess.cn/example.png"); log.debug("测试uuid一致性");
req.setDesc("desc :" + randomStr()); partnerSiteService.apply(req);
req.setEmail(randomStr(4) + "@celess.cn"); } catch (MyException e2) {
req.setLinkUrl(req.getUrl() + "/links"); assertEquals(e.getResult(), e2.getResult());
try { }
// 抓取不到数据的链接 }
partnerSiteService.apply(req); log.debug("测试正常申请");
} catch (MyException e) { req.setLinkUrl("https://www.celess.cn");
log.debug("测试抓取不到数据"); req.setUrl(req.getLinkUrl());
assertEquals(CANNOT_GET_DATA.getCode(), e.getCode()); PartnerSite apply = partnerSiteService.apply(req);
} assertNotNull(apply);
assertNotNull(apply.getId());
req.setLinkUrl("https://bing.com"); }
req.setUrl(req.getLinkUrl());
try { @Test
partnerSiteService.apply(req); public void reapply() {
} catch (MyException e) { //mockEmailServiceInstance(partnerSiteService, "mailService");
log.debug("测试未添加本站链接的友链申请"); try {
assertEquals(APPLY_LINK_NO_ADD_THIS_SITE.getCode(), e.getCode()); partnerSiteService.reapply(randomStr());
assertNotNull(e.getResult()); throw new AssertionError();
try { } catch (MyException e) {
// 测试uuid一致性 assertEquals(DATA_EXPIRED.getCode(), e.getCode());
log.debug("测试uuid一致性"); }
partnerSiteService.apply(req);
} catch (MyException e2) { LinkApplyReq req = new LinkApplyReq();
assertEquals(e.getResult(), e2.getResult()); req.setName(randomStr(4));
} req.setIconPath("https://www.celess.cn/example.png");
} req.setDesc("desc :" + randomStr());
log.debug("测试正常申请"); req.setEmail(randomStr(4) + "@celess.cn");
req.setLinkUrl("https://www.celess.cn"); req.setLinkUrl("https://bing.com");
req.setUrl(req.getLinkUrl()); req.setUrl(req.getLinkUrl());
PartnerSite apply = partnerSiteService.apply(req); String uuid;
assertNotNull(apply); try {
assertNotNull(apply.getId()); partnerSiteService.apply(req);
} // err here
throw new AssertionError();
@Test } catch (MyException e) {
public void reapply() { uuid = (String) e.getResult();
mockEmailServiceInstance(partnerSiteService, "mailService"); String reapply = partnerSiteService.reapply(uuid);
try { assertEquals(reapply, "success");
partnerSiteService.reapply(randomStr()); }
throw new AssertionError();
} catch (MyException e) { try {
assertEquals(DATA_EXPIRED.getCode(), e.getCode()); partnerSiteService.reapply(uuid);
} throw new AssertionError();
} catch (MyException e) {
LinkApplyReq req = new LinkApplyReq(); assertEquals(DATA_EXPIRED.getCode(), e.getCode());
req.setName(randomStr(4)); }
req.setIconPath("https://www.celess.cn/example.png"); }
req.setDesc("desc :" + randomStr());
req.setEmail(randomStr(4) + "@celess.cn");
req.setLinkUrl("https://bing.com");
req.setUrl(req.getLinkUrl());
String uuid = null;
try {
partnerSiteService.apply(req);
// err here
throw new AssertionError();
} catch (MyException e) {
uuid = (String) e.getResult();
String reapply = partnerSiteService.reapply(uuid);
assertEquals(reapply, "success");
}
try {
partnerSiteService.reapply(uuid);
throw new AssertionError();
} catch (MyException e) {
assertEquals(DATA_EXPIRED.getCode(), e.getCode());
}
}
} }

View File

@@ -1,36 +1,42 @@
package cn.celess.blog.controller; package cn.celess.blog.controller;
import cn.celess.blog.BaseTest; import cn.celess.blog.BaseTest;
import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.Tag; import cn.celess.blog.entity.Tag;
import cn.celess.blog.entity.model.PageData; import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.entity.model.TagModel; import cn.celess.blog.entity.model.TagModel;
import cn.celess.blog.mapper.TagMapper; import cn.celess.blog.mapper.TagMapper;
import net.sf.json.JSONArray; import com.fasterxml.jackson.core.type.TypeReference;
import net.sf.json.JSONObject;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.UUID; import java.util.List;
import java.util.Map;
import static cn.celess.blog.enmu.ResponseEnum.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static cn.celess.blog.enmu.ResponseEnum.*;
public class TagControllerTest extends BaseTest { public class TagControllerTest extends BaseTest {
@Autowired @Autowired
TagMapper tagMapper; TagMapper tagMapper;
private static final TypeReference<?> TAG_MODEL_TYPE = new TypeReference<Response<TagModel>>() {
};
private static final TypeReference<?> TAG_MODEL_PAGE_TYPE = new TypeReference<Response<PageData<TagModel>>>() {
};
private static final TypeReference<?> TAG_NAC_LIST_TYPE = new TypeReference<Response<List<Map<String, Object>>>>() {
};
@Test @Test
public void addOne() throws Exception { public void addOne() throws Exception {
String name = randomStr(4); String name = randomStr(4);
mockMvc.perform(post("/admin/tag/create?name=" + name)).andDo(result -> assertEquals(HAVE_NOT_LOG_IN.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))); getMockData(post("/admin/tag/create?name=" + name)).andDo(result -> assertEquals(HAVE_NOT_LOG_IN.getCode(), getResponse(result, STRING_TYPE).getCode()));
mockMvc.perform(post("/admin/tag/create?name=" + name).header("authorization", userLogin())).andDo(result -> assertEquals(PERMISSION_ERROR.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))); getMockData(post("/admin/tag/create?name=" + name), userLogin()).andDo(result -> assertEquals(PERMISSION_ERROR.getCode(), getResponse(result, STRING_TYPE).getCode()));
mockMvc.perform(post("/admin/tag/create?name=" + name).header("authorization", adminLogin())).andDo(result -> { getMockData(post("/admin/tag/create?name=" + name), adminLogin()).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<TagModel> response = getResponse(result, TAG_MODEL_TYPE);
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
JSONObject resJson = object.getJSONObject(Result); TagModel tag = response.getResult();
TagModel tag = (TagModel) JSONObject.toBean(resJson, TagModel.class);
assertNotNull(tag.getId()); assertNotNull(tag.getId());
assertEquals(name, tag.getName()); assertEquals(name, tag.getName());
}); });
@@ -42,16 +48,14 @@ public class TagControllerTest extends BaseTest {
public void delOne() throws Exception { public void delOne() throws Exception {
Tag lastestTag = tagMapper.getLastestTag(); Tag lastestTag = tagMapper.getLastestTag();
assertNotNull(lastestTag.getId()); assertNotNull(lastestTag.getId());
String token = adminLogin(); getMockData(delete("/admin/tag/del?id=" + lastestTag.getId()), adminLogin()).andDo(result -> {
mockMvc.perform(delete("/admin/tag/del?id=" + lastestTag.getId()).header("Authorization", token)).andDo(result -> { Response<Boolean> response = getResponse(result, BOOLEAN_TYPE);
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); assertEquals(SUCCESS.getCode(), response.getCode());
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertTrue(response.getResult());
assertTrue(object.getBoolean(Result));
}); });
long id = lastestTag.getId() * 2; long id = lastestTag.getId() * 2;
mockMvc.perform(delete("/admin/tag/del?id=" + id).header("Authorization", token)).andDo(result -> getMockData(delete("/admin/tag/del?id=" + id), adminLogin())
assertEquals(TAG_NOT_EXIST.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code)) .andDo(result -> assertEquals(TAG_NOT_EXIST.getCode(), getResponse(result, STRING_TYPE).getCode()));
);
} }
@@ -59,12 +63,12 @@ public class TagControllerTest extends BaseTest {
public void updateOne() throws Exception { public void updateOne() throws Exception {
Tag tag = tagMapper.getLastestTag(); Tag tag = tagMapper.getLastestTag();
assertNotNull(tag.getId()); assertNotNull(tag.getId());
String name = UUID.randomUUID().toString().substring(0, 4); String name = randomStr(4);
mockMvc.perform(put("/admin/tag/update?id=" + tag.getId() + "&name=" + name).header("Authorization", adminLogin())).andDo(result -> { getMockData(put("/admin/tag/update?id=" + tag.getId() + "&name=" + name), adminLogin()).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<TagModel> response = getResponse(result, TAG_MODEL_TYPE);
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
assertNotNull(object.getJSONObject(Result)); assertNotNull(response.getResult());
TagModel t = (TagModel) JSONObject.toBean(object.getJSONObject(Result), TagModel.class); TagModel t = response.getResult();
assertEquals(name, t.getName()); assertEquals(name, t.getName());
assertEquals(tag.getId(), t.getId()); assertEquals(tag.getId(), t.getId());
}); });
@@ -73,40 +77,33 @@ public class TagControllerTest extends BaseTest {
@Test @Test
public void getPage() throws Exception { public void getPage() throws Exception {
mockMvc.perform(get("/tags?page=1&count=5")) getMockData(get("/tags?page=1&count=5")).andDo(result -> {
.andExpect(status().is(200)) Response<PageData<TagModel>> response = getResponse(result, TAG_MODEL_PAGE_TYPE);
.andDo(result -> { assertEquals(SUCCESS.getCode(), response.getCode());
JSONObject articlesJSON = JSONObject.fromObject(result.getResponse().getContentAsString()); // 结果集非空
// 断言获取数据成功 assertNotNull(response.getResult());
assertEquals(SUCCESS.getCode(), articlesJSON.getInt(Code)); // 判断pageInfo是否包装完全
// 结果集非空 PageData<TagModel> pageData = response.getResult();
assertNotNull(articlesJSON.getJSONObject(Result)); assertNotEquals(0, pageData.getTotal());
// 判断pageInfo是否包装完全 assertEquals(1, pageData.getPageNum());
JSONObject resultJson = JSONObject.fromObject(articlesJSON.getJSONObject(Result)); assertEquals(5, pageData.getPageSize());
PageData<TagModel> pageData = (PageData<TagModel>) JSONObject.toBean(resultJson, PageData.class); // 内容完整
assertNotEquals(0, pageData.getTotal()); for (TagModel t : pageData.getList()) {
assertEquals(1, pageData.getPageNum()); assertNotNull(t.getId());
assertEquals(5, pageData.getPageSize()); assertNotNull(t.getName());
// 内容完整 }
for (Object tag : pageData.getList()) { });
TagModel t = (TagModel) JSONObject.toBean(JSONObject.fromObject(tag), TagModel.class);
assertNotNull(t.getId());
assertNotNull(t.getName());
}
});
} }
@Test @Test
public void getTagNameAndCount() throws Exception { public void getTagNameAndCount() throws Exception {
mockMvc.perform(get("/tags/nac")).andDo(result -> { getMockData(get("/tags/nac")).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<List<Map<String, Object>>> response = getResponse(result, TAG_NAC_LIST_TYPE);
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
JSONArray jsonArray = object.getJSONArray(Result); assertNotNull(response.getResult());
assertNotNull(jsonArray); response.getResult().forEach(o -> {
jsonArray.forEach(o -> { assertNotNull(o.get("name"));
JSONObject json = JSONObject.fromObject(o); assertNotNull(o.get("size"));
assertTrue(json.containsKey("size"));
assertTrue(json.containsKey("name"));
}); });
}); });
} }

View File

@@ -1,276 +1,278 @@
package cn.celess.blog.controller; package cn.celess.blog.controller;
import cn.celess.blog.BaseTest; import cn.celess.blog.BaseTest;
import cn.celess.blog.entity.User; import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.model.PageData; import cn.celess.blog.entity.User;
import cn.celess.blog.entity.model.UserModel; import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.entity.request.LoginReq; import cn.celess.blog.entity.model.UserModel;
import cn.celess.blog.entity.request.UserReq; import cn.celess.blog.entity.request.LoginReq;
import cn.celess.blog.mapper.UserMapper; import cn.celess.blog.entity.request.UserReq;
import cn.celess.blog.util.MD5Util; import cn.celess.blog.mapper.UserMapper;
import net.sf.json.JSONArray; import cn.celess.blog.service.UserService;
import net.sf.json.JSONObject; import cn.celess.blog.service.FileService;
import org.junit.Test; import cn.celess.blog.util.MD5Util;
import org.springframework.beans.factory.annotation.Autowired; import cn.celess.blog.util.RedisUtil;
import org.springframework.http.MediaType; import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.mock.web.MockMultipartFile; import org.junit.Test;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MultiValueMap; import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import java.io.InputStream; import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import java.net.HttpURLConnection; import org.springframework.util.LinkedMultiValueMap;
import java.net.URL; import org.springframework.util.MultiValueMap;
import java.util.*;
import java.io.InputStream;
import static org.junit.Assert.*; import java.net.HttpURLConnection;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import java.net.URL;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import java.util.ArrayList;
import static cn.celess.blog.enmu.ResponseEnum.*; import java.util.List;
import java.util.Map;
public class UserControllerTest extends BaseTest { import java.util.Random;
import java.util.concurrent.TimeUnit;
@Autowired import java.util.stream.Collectors;
UserMapper userMapper;
import static cn.celess.blog.enmu.ResponseEnum.*;
@Test import static org.junit.Assert.*;
public void login() throws Exception { import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
assertNotNull(userLogin());
assertNotNull(adminLogin());
// 用户不存在 public class UserControllerTest extends BaseTest {
LoginReq req = new LoginReq();
req.setEmail("zh@celess.cn"); @Autowired
req.setPassword("123456789"); UserMapper userMapper;
req.setIsRememberMe(false); @Autowired
JSONObject loginReq = JSONObject.fromObject(req);
mockMvc.perform(post("/login").content(loginReq.toString()).contentType("application/json")) RedisUtil redisUtil;
.andDo(result -> private static final TypeReference<?> USER_MODEL_TYPE = new TypeReference<Response<UserModel>>() {
assertEquals(USER_NOT_EXIST.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code)) };
); private static final TypeReference<?> USER_MODEL_PAGE_TYPE = new TypeReference<Response<PageData<UserModel>>>() {
} };
private static final TypeReference<?> USER_MODEL_LIST_TYPE = new TypeReference<Response<List<Map<String, Object>>>>() {
@Test };
public void registration() { @Autowired
// ignore UserService userService;
}
@Test @Test
public void logout() throws Exception { public void login() throws Exception {
mockMvc.perform(get("/logout")).andDo(result -> assertEquals(SUCCESS.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))); assertNotNull(userLogin());
mockMvc.perform(get("/logout").header("Authorization", userLogin())).andDo(result -> assertEquals(SUCCESS.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))); assertNotNull(adminLogin());
} // 用户不存在
LoginReq req = new LoginReq();
@Test req.setEmail("zh@celess.cn");
public void updateInfo() throws Exception { req.setPassword("123456789");
String desc = UUID.randomUUID().toString().substring(0, 4); req.setIsRememberMe(false);
String disPlayName = UUID.randomUUID().toString().substring(0, 4); getMockData(post("/login"), null, req).andDo(result -> assertEquals(USER_NOT_EXIST.getCode(), getResponse(result, STRING_TYPE).getCode()));
mockMvc.perform(put("/user/userInfo/update?desc=" + desc + "&displayName=" + disPlayName).header("Authorization", userLogin())) }
.andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); @Test
assertEquals(SUCCESS.getCode(), object.getInt(Code)); public void registration() {
UserModel u = (UserModel) JSONObject.toBean(object.getJSONObject(Result), UserModel.class); // ignore
assertEquals(desc, u.getDesc()); }
assertEquals(disPlayName, u.getDisplayName());
assertNotNull(u.getId()); @Test
}); public void logout() throws Exception {
} getMockData(get("/logout")).andDo(result -> assertEquals(SUCCESS.getCode(), getResponse(result, STRING_TYPE).getCode()));
getMockData(get("/logout"), adminLogin()).andDo(result -> assertEquals(SUCCESS.getCode(), getResponse(result).getCode()));
@Test }
public void getUserInfo() throws Exception {
mockMvc.perform(get("/user/userInfo").header("Authorization", userLogin())) @Test
.andDo(result -> { public void updateInfo() throws Exception {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); String desc = randomStr(4);
assertEquals(SUCCESS.getCode(), object.getInt(Code)); String disPlayName = randomStr(4);
UserModel u = (UserModel) JSONObject.toBean(object.getJSONObject(Result), UserModel.class); getMockData(put("/user/userInfo/update?desc=" + desc + "&displayName=" + disPlayName), userLogin()).andDo(result -> {
assertNotNull(u.getId()); Response<UserModel> response = getResponse(result, USER_MODEL_TYPE);
assertNotNull(u.getEmail()); assertEquals(SUCCESS.getCode(), response.getCode());
assertNotNull(u.getDisplayName()); UserModel u = response.getResult();
assertNotNull(u.getEmailStatus()); assertEquals(desc, u.getDesc());
assertNotNull(u.getAvatarImgUrl()); assertEquals(disPlayName, u.getDisplayName());
assertNotNull(u.getDesc()); assertNotNull(u.getId());
assertNotNull(u.getRecentlyLandedDate()); });
assertNotNull(u.getRole()); }
});
} @Test
public void getUserInfo() throws Exception {
@Test getMockData(get("/user/userInfo"), adminLogin()).andDo(result -> {
public void upload() throws Exception { Response<UserModel> response = getResponse(result, USER_MODEL_TYPE);
URL url = new URL("https://56462271.oss-cn-beijing.aliyuncs.com/web/logo.png"); assertEquals(SUCCESS.getCode(), response.getCode());
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); UserModel u = response.getResult();
connection.setRequestMethod("GET"); assertNotNull(u.getId());
InputStream inputStream = connection.getInputStream(); assertNotNull(u.getEmail());
assertNotNull(inputStream); assertNotNull(u.getDisplayName());
MockMultipartFile file = new MockMultipartFile("file", "logo.png", MediaType.IMAGE_PNG_VALUE, inputStream); assertNotNull(u.getEmailStatus());
mockMvc.perform(multipart("/user/imgUpload").file(file)).andDo(result -> assertEquals(HAVE_NOT_LOG_IN.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))); assertNotNull(u.getAvatarImgUrl());
mockMvc.perform(multipart("/user/imgUpload").file(file).header("Authorization", userLogin())).andDo(result -> { assertNotNull(u.getDesc());
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); assertNotNull(u.getRecentlyLandedDate());
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertNotNull(u.getRole());
assertNotNull(object.getString(Result)); });
}); }
}
@Test
@Test public void upload() throws Exception {
public void sendResetPwdEmail() { URL url = new URL("https://56462271.oss-cn-beijing.aliyuncs.com/web/logo.png");
// ignore HttpURLConnection connection = (HttpURLConnection) url.openConnection();
} connection.setRequestMethod("GET");
InputStream inputStream = connection.getInputStream();
@Test assertNotNull(inputStream);
public void sendVerifyEmail() {
// ignore // mock 实现类
} mockInjectInstance(userService, "fileService", (FileService) TestFileManager::new);
@Test MockMultipartFile file = new MockMultipartFile("file", "logo.png", MediaType.IMAGE_PNG_VALUE, inputStream);
public void emailVerify() { getMockData(multipart("/user/imgUpload").file(file), userLogin()).andDo(result -> {
// ignore Response<Object> response = getResponse(result, OBJECT_TYPE);
} assertEquals(SUCCESS.getCode(), response.getCode());
assertNotNull(response.getResult());
@Test });
public void resetPwd() { }
// ignore
} @Test
public void sendResetPwdEmail() {
@Test // ignore
public void multipleDelete() throws Exception { }
List<User> userList = new ArrayList<>();
for (int i = 0; i < 10; i++) { @Test
String s = UUID.randomUUID().toString(); public void sendVerifyEmail() {
String email = s.substring(s.length() - 4) + "@celess.cn"; // ignore
String pwd = MD5Util.getMD5("123456789"); }
User user = new User(email, pwd);
int i1 = userMapper.addUser(user); @Test
if (i1 == 0) { public void emailVerify() throws Exception {
continue; String email = randomStr(4) + "@celess.cn";
} String pwd = MD5Util.getMD5("123456789");
userList.add(userMapper.findByEmail(email)); userMapper.addUser(new User(email, pwd));
if (i == 9) { String verifyId = randomStr();
//设置一个管理员 LoginReq req = new LoginReq(email, "123456789", true);
userMapper.setUserRole(userMapper.findByEmail(email).getId(), "admin"); redisUtil.setEx(email + "-verify", verifyId, 2, TimeUnit.DAYS);
} getMockData(post("/emailVerify").param("verifyId", verifyId).param("email", email), login(req)).andDo(result ->
} assertEquals(SUCCESS.getCode(), getResponse(result, OBJECT_TYPE).getCode())
List<Long> idList = new ArrayList<>(); );
userList.forEach(user -> idList.add(user.getId())); }
System.out.println("id :: == > " + idList.toString());
mockMvc.perform(delete("/admin/user/delete").content(idList.toString()).contentType("application/json")) @Test
.andDo(result -> assertEquals(HAVE_NOT_LOG_IN.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))); public void resetPwd() throws Exception {
mockMvc.perform(delete("/admin/user/delete").content(idList.toString()).contentType("application/json").header("Authorization", userLogin())) String email = randomStr(4) + "@celess.cn";
.andDo(result -> assertEquals(PERMISSION_ERROR.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))); String pwd = MD5Util.getMD5("1234567890");
mockMvc.perform(delete("/admin/user/delete").content(idList.toString()).contentType("application/json").header("Authorization", adminLogin())) userMapper.addUser(new User(email, pwd));
.andDo(result -> { LoginReq req = new LoginReq(email, "1234567890", true);
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); String verifyId = randomStr();
assertEquals(SUCCESS.getCode(), object.getInt(Code)); // 设置验证id
JSONArray jsonArray = object.getJSONArray(Result); redisUtil.setEx(email + "-resetPwd", verifyId, 2, TimeUnit.DAYS);
jsonArray.forEach(o -> { MockHttpServletRequestBuilder resetPwd = post("/resetPwd").param("verifyId", verifyId).param("email", email).param("pwd", "123456789");
JSONObject json = JSONObject.fromObject(o); // 未验证
// 判断响应数据中是否包含输入的id getMockData(resetPwd, login(req)).andDo(result -> assertEquals(USEREMAIL_NOT_VERIFY.getCode(), getResponse(result, OBJECT_TYPE).getCode()));
assertTrue(idList.contains((long) json.getInt("id"))); // 设置未验证
// 判断处理状态 userMapper.updateEmailStatus(email, true);
boolean status = json.getBoolean("status"); // 正常
if (json.containsKey("msg")) getMockData(resetPwd, login(req)).andDo(result -> assertEquals(SUCCESS.getCode(), getResponse(result, OBJECT_TYPE).getCode()));
assertFalse(status); }
else
assertTrue(status); @Test
}); public void multipleDelete() throws Exception {
}); List<User> userList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
} String s = randomStr();
String email = s.substring(s.length() - 4) + "@celess.cn";
@Test String pwd = MD5Util.getMD5("123456789");
public void updateInfoByAdmin() throws Exception { User user = new User(email, pwd);
UserReq userReq = new UserReq(); int i1 = userMapper.addUser(user);
String email = UUID.randomUUID().toString().substring(0, 4) + "@celess.cn"; if (i1 == 0) {
User user = new User(email, MD5Util.getMD5("123456789")); continue;
userMapper.addUser(user); }
User userByDb = userMapper.findByEmail(email); userList.add(userMapper.findByEmail(email));
userReq.setId(userByDb.getId()); if (i == 9) {
userReq.setPwd(UUID.randomUUID().toString().replaceAll("-", "").substring(0, 10)); //设置一个管理员
userReq.setDesc(UUID.randomUUID().toString()); userMapper.setUserRole(userMapper.findByEmail(email).getId(), "admin");
userReq.setEmailStatus(new Random().nextBoolean()); }
userReq.setRole("admin"); }
userReq.setDisplayName(UUID.randomUUID().toString().substring(0, 4)); List<Integer> idList = userList.stream().map(user -> user.getId().intValue()).collect(Collectors.toList());
userReq.setEmail(UUID.randomUUID().toString().substring(0, 5) + "@celess.cn"); getMockData(delete("/admin/user/delete"), adminLogin(), idList).andDo(result -> {
mockMvc.perform(put("/admin/user").contentType("application/json").content(JSONObject.fromObject(userReq).toString())) Response<List<Map<String, Object>>> response = getResponse(result, USER_MODEL_LIST_TYPE);
.andDo(result -> assertEquals(HAVE_NOT_LOG_IN.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))); assertEquals(SUCCESS.getCode(), response.getCode());
mockMvc.perform(put("/admin/user").contentType("application/json").header("Authorization", userLogin()).content(JSONObject.fromObject(userReq).toString())) response.getResult().forEach(o -> {
.andDo(result -> assertEquals(PERMISSION_ERROR.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))); // 判断响应数据中是否包含输入的id
mockMvc.perform(put("/admin/user").contentType("application/json").header("Authorization", adminLogin()).content(JSONObject.fromObject(userReq).toString())) assertTrue(idList.contains((int) o.get("id")));
.andDo(result -> { // 判断处理状态
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); boolean status = (boolean) o.get("status");
assertEquals(SUCCESS.getCode(), object.getInt(Code)); if (o.containsKey("msg"))
UserModel userModel = (UserModel) JSONObject.toBean(object.getJSONObject(Result), UserModel.class); assertFalse(status);
assertEquals(userReq.getId(), userModel.getId()); else
assertEquals(userReq.getRole(), userModel.getRole()); assertTrue(status);
assertEquals(userReq.getEmail(), userModel.getEmail()); });
assertEquals(userReq.getDesc(), userModel.getDesc()); });
assertEquals(userReq.getDisplayName(), userModel.getDisplayName());
}); }
}
@Test
@Test public void updateInfoByAdmin() throws Exception {
public void getAllUser() throws Exception { UserReq userReq = new UserReq();
mockMvc.perform(get("/admin/users?page=1&count=10")) String email = randomStr(4) + "@celess.cn";
.andDo(result -> assertEquals(HAVE_NOT_LOG_IN.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))); User user = new User(email, MD5Util.getMD5("123456789"));
mockMvc.perform(get("/admin/users?page=1&count=10").header("authorization", userLogin())) userMapper.addUser(user);
.andDo(result -> assertEquals(PERMISSION_ERROR.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))); User userByDb = userMapper.findByEmail(email);
mockMvc.perform(get("/admin/users?page=1&count=10").header("Authorization", adminLogin())) userReq.setId(userByDb.getId());
.andDo(result -> { userReq.setPwd(randomStr().substring(0, 10));
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); userReq.setDesc(randomStr());
assertEquals(SUCCESS.getCode(), object.getInt(Code)); userReq.setEmailStatus(new Random().nextBoolean());
// 结果集非空 userReq.setRole("admin");
assertNotNull(object.getJSONObject(Result)); userReq.setDisplayName(randomStr(4));
// 判断pageInfo是否包装完全 userReq.setEmail(randomStr(5) + "@celess.cn");
JSONObject resultJson = JSONObject.fromObject(object.getJSONObject(Result)); getMockData(put("/admin/user"), adminLogin(), userReq).andDo(result -> {
PageData<UserModel> pageData = (PageData<UserModel>) JSONObject.toBean(resultJson, PageData.class); Response<UserModel> response = getResponse(result, USER_MODEL_TYPE);
assertNotEquals(0, pageData.getTotal()); assertEquals(SUCCESS.getCode(), response.getCode());
assertEquals(1, pageData.getPageNum()); UserModel userModel = response.getResult();
assertEquals(10, pageData.getPageSize()); assertEquals(userReq.getId(), userModel.getId());
// 内容完整 assertEquals(userReq.getRole(), userModel.getRole());
for (Object user : pageData.getList()) { assertEquals(userReq.getEmail(), userModel.getEmail());
UserModel u = (UserModel) JSONObject.toBean(JSONObject.fromObject(user), UserModel.class); assertEquals(userReq.getDesc(), userModel.getDesc());
assertNotNull(u.getId()); assertEquals(userReq.getDisplayName(), userModel.getDisplayName());
assertNotNull(u.getEmail()); });
assertNotNull(u.getRole()); }
assertNotNull(u.getEmailStatus());
assertNotNull(u.getDisplayName()); @Test
} public void getAllUser() throws Exception {
}); getMockData(get("/admin/users?page=1&count=10"), adminLogin()).andDo(result -> {
} Response<PageData<UserModel>> response = getResponse(result, USER_MODEL_PAGE_TYPE);
assertEquals(SUCCESS.getCode(), response.getCode());
@Test // 结果集非空
public void getEmailStatus() throws Exception { assertNotNull(response.getResult());
String email = UUID.randomUUID().toString().substring(0, 4) + "@celess.cn"; // 判断pageInfo是否包装完全
mockMvc.perform(get("/emailStatus/" + email)).andDo(result -> { PageData<UserModel> pageData = response.getResult();
String content = result.getResponse().getContentAsString(); assertNotEquals(0, pageData.getTotal());
assertEquals(SUCCESS.getCode(), JSONObject.fromObject(content).getInt(Code)); assertEquals(1, pageData.getPageNum());
assertFalse(JSONObject.fromObject(content).getBoolean(Result)); assertEquals(10, pageData.getPageSize());
}); // 内容完整
email = "a@celess.cn"; for (UserModel u : pageData.getList()) {
mockMvc.perform(get("/emailStatus/" + email)).andDo(result -> { assertNotNull(u.getId());
String content = result.getResponse().getContentAsString(); assertNotNull(u.getEmail());
assertEquals(SUCCESS.getCode(), JSONObject.fromObject(content).getInt(Code)); assertNotNull(u.getRole());
assertTrue(JSONObject.fromObject(content).getBoolean(Result)); assertNotNull(u.getEmailStatus());
}); assertNotNull(u.getDisplayName());
} }
});
@Test }
public void setPwd() throws Exception {
String email = UUID.randomUUID().toString().substring(0, 4) + "@celess.cn"; @Test
assertEquals(1, userMapper.addUser(new User(email, MD5Util.getMD5("1234567890")))); public void getEmailStatus() throws Exception {
LoginReq req = new LoginReq(); String email = randomStr(4) + "@celess.cn";
req.setEmail(email); getMockData(get("/emailStatus/" + email)).andDo(result -> assertFalse((Boolean) getResponse(result, BOOLEAN_TYPE).getResult()));
req.setPassword("1234567890"); getMockData(get("/emailStatus/" + ADMIN_EMAIL)).andDo(result -> assertTrue((Boolean) getResponse(result, BOOLEAN_TYPE).getResult()));
req.setIsRememberMe(false); }
JSONObject loginReq = JSONObject.fromObject(req);
String contentAsString = mockMvc.perform(post("/login").content(loginReq.toString()).contentType("application/json")).andReturn().getResponse().getContentAsString(); @Test
assertNotNull(contentAsString); public void setPwd() throws Exception {
String token = JSONObject.fromObject(contentAsString).getJSONObject(Result).getString("token"); String email = randomStr(4) + "@celess.cn";
assertNotNull(token); assertEquals(1, userMapper.addUser(new User(email, MD5Util.getMD5("1234567890"))));
MultiValueMap<String, String> param = new LinkedMultiValueMap<String, String>(); LoginReq req = new LoginReq(email, "1234567890", false);
param.add("pwd", "1234567890"); String token = login(req);
param.add("newPwd", "aaabbbccc"); assertNotNull(token);
param.add("confirmPwd", "aaabbbccc"); MultiValueMap<String, String> param = new LinkedMultiValueMap<String, String>();
mockMvc.perform(post("/user/setPwd").header("Authorization", token).params(param)).andDo(result -> { param.add("pwd", "1234567890");
String content = result.getResponse().getContentAsString(); param.add("newPwd", "aaabbbccc");
assertEquals(SUCCESS.getCode(), JSONObject.fromObject(content).getInt(Code)); param.add("confirmPwd", "aaabbbccc");
assertEquals(MD5Util.getMD5("aaabbbccc"), userMapper.getPwd(email)); getMockData(post("/user/setPwd").params(param), token).andDo(result -> {
}); assertEquals(SUCCESS.getCode(), getResponse(result).getCode());
} assertEquals(MD5Util.getMD5("aaabbbccc"), userMapper.getPwd(email));
});
}
} }

View File

@@ -1,25 +1,29 @@
package cn.celess.blog.controller; package cn.celess.blog.controller;
import cn.celess.blog.BaseTest; import cn.celess.blog.BaseTest;
import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.model.PageData; import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.entity.model.VisitorModel; import cn.celess.blog.entity.model.VisitorModel;
import com.github.pagehelper.PageInfo; import com.fasterxml.jackson.core.type.TypeReference;
import net.sf.json.JSONObject;
import org.junit.Test; import org.junit.Test;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import static cn.celess.blog.enmu.ResponseEnum.SUCCESS;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static cn.celess.blog.enmu.ResponseEnum.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
public class VisitorControllerTest extends BaseTest { public class VisitorControllerTest extends BaseTest {
private final TypeReference<?> VISITOR_PAGE_TYPE = new TypeReference<Response<PageData<VisitorModel>>>() {
};
private final TypeReference<?> VISITOR_TYPE = new TypeReference<Response<VisitorModel>>() {
};
@Test @Test
public void getVisitorCount() throws Exception { public void getVisitorCount() throws Exception {
mockMvc.perform(get("/visitor/count")).andDo(result -> { getMockData(get("/visitor/count")).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<Object> response = getResponse(result);
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
assertTrue(object.containsKey(Result)); assertNotNull(response.getResult());
}); });
} }
@@ -27,29 +31,28 @@ public class VisitorControllerTest extends BaseTest {
public void page() throws Exception { public void page() throws Exception {
int count = 10; int count = 10;
int page = 1; int page = 1;
mockMvc.perform(get("/admin/visitor/page?count=" + count + "&page=" + page).header("Authorization", adminLogin())) // 默认显示location
.andDo(result -> { getMockData(get("/admin/visitor/page?count=" + count + "&page=" + page), adminLogin()).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<PageData<VisitorModel>> response = getResponse(result, VISITOR_PAGE_TYPE);
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
JSONObject resultJson = JSONObject.fromObject(object.getJSONObject(Result)); PageData<VisitorModel> pageData = response.getResult();
PageData<VisitorModel> pageData = (PageData<VisitorModel>) JSONObject.toBean(resultJson, PageData.class); assertNotEquals(0, pageData.getTotal());
assertNotEquals(0, pageData.getTotal()); assertEquals(1, pageData.getPageNum());
assertEquals(1, pageData.getPageNum()); assertEquals(10, pageData.getPageSize());
assertEquals(10, pageData.getPageSize()); for (VisitorModel v : pageData.getList()) {
for (Object ver : pageData.getList()) { assertNotEquals(0, v.getId());
VisitorModel v = (VisitorModel) JSONObject.toBean(JSONObject.fromObject(ver), VisitorModel.class); assertNotNull(v.getDate());
assertNotEquals(0, v.getId()); assertNotNull(v.getLocation());
assertNotNull(v.getDate()); }
} });
});
} }
@Test @Test
public void add() throws Exception { public void add() throws Exception {
mockMvc.perform(post("/visit")).andDo(MockMvcResultHandlers.print()).andDo(result -> { getMockData(post("/visit")).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<VisitorModel> response = getResponse(result, VISITOR_TYPE);
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
VisitorModel visitorModel = (VisitorModel) JSONObject.toBean(object.getJSONObject(Result), VisitorModel.class); VisitorModel visitorModel = response.getResult();
assertNotEquals(0, visitorModel.getId()); assertNotEquals(0, visitorModel.getId());
assertNotNull(visitorModel.getIp()); assertNotNull(visitorModel.getIp());
}); });
@@ -57,26 +60,26 @@ public class VisitorControllerTest extends BaseTest {
@Test @Test
public void dayVisitCount() throws Exception { public void dayVisitCount() throws Exception {
mockMvc.perform(get("/dayVisitCount")).andDo(MockMvcResultHandlers.print()).andDo(result -> getMockData(get("/dayVisitCount")).andDo(result -> assertEquals(SUCCESS.getCode(), getResponse(result).getCode()));
assertEquals(SUCCESS.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))
);
} }
// 手动测试 // 手动测试
// @Test // @Test
public void ipLocation() throws Exception { public void ipLocation() throws Exception {
String ip = "127.0.0.1"; String ip = "127.0.0.1";
mockMvc.perform(get("/ip/" + ip)).andDo(MockMvcResultHandlers.print()).andDo(result -> { getMockData(get("/ip/" + ip)).andDo(result -> {
assertEquals(SUCCESS.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code)); Response<Object> response = getResponse(result);
assertTrue(JSONObject.fromObject(result.getResponse().getContentAsString()).containsKey(Result)); assertEquals(SUCCESS.getCode(), response.getCode());
assertNotNull(response.getResult());
}); });
} }
@Test @Test
public void getIp() throws Exception { public void getIp() throws Exception {
mockMvc.perform(get("/ip")).andDo(MockMvcResultHandlers.print()).andDo(result -> { getMockData(get("/ip")).andDo(result -> {
assertEquals(SUCCESS.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code)); Response<String> response = getResponse(result, STRING_TYPE);
assertEquals("127.0.0.1", JSONObject.fromObject(result.getResponse().getContentAsString()).getString(Result)); assertEquals(SUCCESS.getCode(), response.getCode());
assertEquals("127.0.0.1", response.getResult());
}); });
} }
} }

View File

@@ -1,35 +1,46 @@
package cn.celess.blog.controller; package cn.celess.blog.controller;
import cn.celess.blog.BaseTest; import cn.celess.blog.BaseTest;
import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.WebUpdate; import cn.celess.blog.entity.WebUpdate;
import cn.celess.blog.entity.model.PageData; import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.entity.model.WebUpdateModel; import cn.celess.blog.entity.model.WebUpdateModel;
import cn.celess.blog.mapper.WebUpdateInfoMapper; import cn.celess.blog.mapper.WebUpdateInfoMapper;
import net.sf.json.JSONArray; import com.fasterxml.jackson.core.type.TypeReference;
import net.sf.json.JSONObject; import lombok.extern.slf4j.Slf4j;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.UUID;
import static cn.celess.blog.enmu.ResponseEnum.*; import static cn.celess.blog.enmu.ResponseEnum.DATA_NOT_EXIST;
import static cn.celess.blog.enmu.ResponseEnum.SUCCESS;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
@Slf4j
public class WebUpdateInfoControllerTest extends BaseTest { public class WebUpdateInfoControllerTest extends BaseTest {
private final TypeReference<?> MODAL_TYPE = new TypeReference<Response<WebUpdateModel>>() {
};
private final TypeReference<?> MODAL_LIST_TYPE = new TypeReference<Response<List<WebUpdateModel>>>() {
};
private final TypeReference<?> MODAL_PAGE_TYPE = new TypeReference<Response<PageData<WebUpdateModel>>>() {
};
@Autowired @Autowired
WebUpdateInfoMapper mapper; WebUpdateInfoMapper mapper;
@Test @Test
public void create() throws Exception { public void create() throws Exception {
String info = UUID.randomUUID().toString(); String info = randomStr();
mockMvc.perform(post("/admin/webUpdate/create?info=" + info).header("Authorization", adminLogin())).andDo(result -> { getMockData(post("/admin/webUpdate/create?info=" + info), adminLogin()).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<WebUpdateModel> response = getResponse(result, MODAL_TYPE);
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
assertTrue(object.containsKey(Result)); assertNotNull(response.getResult());
WebUpdateModel webUpdateModel = (WebUpdateModel) JSONObject.toBean(object.getJSONObject(Result), WebUpdateModel.class); WebUpdateModel webUpdateModel = response.getResult();
assertEquals(info, webUpdateModel.getInfo()); assertEquals(info, webUpdateModel.getInfo());
assertNotNull(webUpdateModel.getTime()); assertNotNull(webUpdateModel.getTime());
assertNotEquals(0, webUpdateModel.getId()); assertNotEquals(0, webUpdateModel.getId());
@@ -40,7 +51,7 @@ public class WebUpdateInfoControllerTest extends BaseTest {
public void del() throws Exception { public void del() throws Exception {
// 新增数据 // 新增数据
WebUpdate webUpdate = new WebUpdate(); WebUpdate webUpdate = new WebUpdate();
webUpdate.setUpdateInfo(UUID.randomUUID().toString()); webUpdate.setUpdateInfo(randomStr());
webUpdate.setUpdateTime(new Date()); webUpdate.setUpdateTime(new Date());
mapper.insert(webUpdate); mapper.insert(webUpdate);
// 接口测试 // 接口测试
@@ -49,32 +60,31 @@ public class WebUpdateInfoControllerTest extends BaseTest {
assertNotEquals(0, update.getId()); assertNotEquals(0, update.getId());
long id = update.getId(); long id = update.getId();
mockMvc.perform(delete("/admin/webUpdate/del/" + id).header("Authorization", adminLogin())).andDo(result -> { getMockData(delete("/admin/webUpdate/del/" + id), adminLogin()).andDo(result -> {
assertEquals(SUCCESS.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code)); Response<Object> response = getResponse(result);
assertTrue(JSONObject.fromObject(result.getResponse().getContentAsString()).getBoolean(Result)); assertEquals(SUCCESS.getCode(), response.getCode());
assertNotNull(response.getResult());
}); });
do { do {
id += 2; id += 2;
} while (mapper.existsById(id)); } while (mapper.existsById(id));
System.out.println("准备删除ID=" + id + "的不存在记录"); log.debug("准备删除ID={}的不存在记录", id);
mockMvc.perform(delete("/admin/webUpdate/del/" + id).header("Authorization", adminLogin())).andDo(result -> getMockData(delete("/admin/webUpdate/del/" + id), adminLogin()).andDo(result -> assertEquals(DATA_NOT_EXIST.getCode(), getResponse(result).getCode()));
assertEquals(DATA_NOT_EXIST.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code))
);
} }
@Test @Test
public void update() throws Exception { public void update() throws Exception {
// 新增数据 // 新增数据
WebUpdate webUpdate = new WebUpdate(); WebUpdate webUpdate = new WebUpdate();
webUpdate.setUpdateInfo(UUID.randomUUID().toString()); webUpdate.setUpdateInfo(randomStr());
webUpdate.setUpdateTime(new Date()); webUpdate.setUpdateTime(new Date());
mapper.insert(webUpdate); mapper.insert(webUpdate);
List<WebUpdate> all = mapper.findAll(); List<WebUpdate> all = mapper.findAll();
WebUpdate update = all.get(all.size() - 1); WebUpdate update = all.get(all.size() - 1);
assertNotEquals(0, update.getId()); assertNotEquals(0, update.getId());
assertNotNull(update.getUpdateInfo()); assertNotNull(update.getUpdateInfo());
String info = UUID.randomUUID().toString(); String info = randomStr();
mockMvc.perform(put("/admin/webUpdate/update?id=" + update.getId() + "&info=" + info).header("Authorization", adminLogin())).andDo(result -> { getMockData(put("/admin/webUpdate/update?id=" + update.getId() + "&info=" + info), adminLogin()).andDo(result -> {
List<WebUpdate> list = mapper.findAll(); List<WebUpdate> list = mapper.findAll();
WebUpdate up = list.get(list.size() - 1); WebUpdate up = list.get(list.size() - 1);
assertEquals(update.getId(), up.getId()); assertEquals(update.getId(), up.getId());
@@ -85,12 +95,12 @@ public class WebUpdateInfoControllerTest extends BaseTest {
@Test @Test
public void findAll() throws Exception { public void findAll() throws Exception {
mockMvc.perform(get("/webUpdate")).andDo(result -> { getMockData(get("/webUpdate")).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<List<WebUpdateModel>> response = getResponse(result, MODAL_LIST_TYPE);
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
JSONArray jsonArray = object.getJSONArray(Result); assertNotNull(response.getResult());
jsonArray.forEach(o -> { assertNotEquals(0, response.getResult());
WebUpdateModel webUpdate = (WebUpdateModel) JSONObject.toBean(JSONObject.fromObject(o), WebUpdateModel.class); response.getResult().forEach(webUpdate -> {
assertNotEquals(0, webUpdate.getId()); assertNotEquals(0, webUpdate.getId());
assertNotNull(webUpdate.getTime()); assertNotNull(webUpdate.getTime());
assertNotNull(webUpdate.getInfo()); assertNotNull(webUpdate.getInfo());
@@ -100,15 +110,14 @@ public class WebUpdateInfoControllerTest extends BaseTest {
@Test @Test
public void page() throws Exception { public void page() throws Exception {
mockMvc.perform(get("/webUpdate/pages?page=1&count=10")).andDo(result -> { getMockData(get("/webUpdate/pages?page=1&count=10")).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<PageData<WebUpdateModel>> response = getResponse(result, MODAL_PAGE_TYPE);
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
assertNotNull(object.getJSONObject(Result)); assertNotNull(response.getResult());
PageData<WebUpdateModel> pageData = (PageData<WebUpdateModel>) JSONObject.toBean(object.getJSONObject(Result), PageData.class); PageData<WebUpdateModel> pageData = response.getResult();
assertEquals(1, pageData.getPageNum()); assertEquals(1, pageData.getPageNum());
assertEquals(10, pageData.getPageSize()); assertEquals(10, pageData.getPageSize());
for (Object o : pageData.getList()) { for (WebUpdateModel model : pageData.getList()) {
WebUpdateModel model = (WebUpdateModel) JSONObject.toBean(JSONObject.fromObject(o), WebUpdateModel.class);
assertNotEquals(0, model.getId()); assertNotEquals(0, model.getId());
assertNotNull(model.getTime()); assertNotNull(model.getTime());
assertNotNull(model.getInfo()); assertNotNull(model.getInfo());
@@ -118,7 +127,6 @@ public class WebUpdateInfoControllerTest extends BaseTest {
@Test @Test
public void lastestUpdateTime() throws Exception { public void lastestUpdateTime() throws Exception {
mockMvc.perform(get("/lastestUpdate")).andDo(result -> getMockData(get("/lastestUpdate")).andDo(result -> assertEquals(SUCCESS.getCode(), getResponse(result).getCode()));
assertEquals(SUCCESS.getCode(), JSONObject.fromObject(result.getResponse().getContentAsString()).getInt(Code)));
} }
} }

View File

@@ -0,0 +1,36 @@
package cn.celess.blog.enmu;
import cn.celess.blog.BaseTest;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import java.io.IOException;
import static org.junit.Assert.*;
public class UserAccountStatusEnumTest extends BaseTest {
@Test
public void get() {
assertEquals(UserAccountStatusEnum.NORMAL, UserAccountStatusEnum.get(0));
assertEquals(UserAccountStatusEnum.LOCKED, UserAccountStatusEnum.get(1));
assertEquals(UserAccountStatusEnum.DELETED, UserAccountStatusEnum.get(2));
}
@Test
public void toJson() throws JsonProcessingException {
// 序列化
ObjectMapper objectMapper = new ObjectMapper();
assertEquals("{\"code\":0,\"desc\":\"正常\"}", objectMapper.writeValueAsString(UserAccountStatusEnum.NORMAL));
}
@Test
public void testGet() throws IOException {
// 反序列化
ObjectMapper mapper = new ObjectMapper();
UserAccountStatusEnum userAccountStatusEnum = mapper.readValue(mapper.writeValueAsString(UserAccountStatusEnum.NORMAL), UserAccountStatusEnum.class);
assertEquals(UserAccountStatusEnum.NORMAL.getCode(), userAccountStatusEnum.getCode());
assertEquals(UserAccountStatusEnum.NORMAL.getDesc(), userAccountStatusEnum.getDesc());
}
}

View File

@@ -1,12 +1,12 @@
package cn.celess.blog.filter; package cn.celess.blog.filter;
import cn.celess.blog.BaseTest; import cn.celess.blog.BaseTest;
import net.sf.json.JSONObject; import cn.celess.blog.entity.Response;
import org.junit.Test; import org.junit.Test;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.junit.Assert.*;
import static cn.celess.blog.enmu.ResponseEnum.*; import static cn.celess.blog.enmu.ResponseEnum.*;
import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
/** /**
* @Author: 小海 * @Author: 小海
@@ -17,60 +17,37 @@ public class AuthorizationFilter extends BaseTest {
@Test @Test
public void UserAccess() throws Exception { public void UserAccess() throws Exception {
String token = "";
// 未登录 // 未登录
mockMvc.perform(get("/user/userInfo").header("Authorization", token)).andDo(result -> { getMockData(get("/user/userInfo")).andDo(result -> assertEquals(HAVE_NOT_LOG_IN.getCode(), getResponse(result).getCode()));
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); // user权限登录
assertEquals(HAVE_NOT_LOG_IN.getCode(), object.getInt(Code)); getMockData(get("/user/userInfo"), userLogin()).andDo(result -> assertEquals(SUCCESS.getCode(), getResponse(result).getCode()));
});
token = userLogin();
mockMvc.perform(get("/user/userInfo").header("Authorization", token)).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), object.getInt(Code));
});
} }
@Test @Test
public void AdminAccess() throws Exception { public void AdminAccess() throws Exception {
String token = "";
// 未登录 // 未登录
mockMvc.perform(get("/admin/articles?page=1&count=1").header("Authorization", token)).andDo(result -> { getMockData(get("/admin/articles?page=1&count=1")).andDo(result -> assertEquals(HAVE_NOT_LOG_IN.getCode(), getResponse(result).getCode()));
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); // user权限
assertEquals(HAVE_NOT_LOG_IN.getCode(), object.getInt(Code)); getMockData(get("/admin/articles?page=1&count=1"), userLogin()).andDo(result -> assertEquals(PERMISSION_ERROR.getCode(), getResponse(result).getCode()));
}); // admin 权限
token = userLogin(); getMockData(get("/admin/articles?page=1&count=1"), adminLogin()).andDo(result -> assertEquals(SUCCESS.getCode(), getResponse(result).getCode()));
mockMvc.perform(get("/admin/articles?page=1&count=1").header("Authorization", token)).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(PERMISSION_ERROR.getCode(), object.getInt(Code));
});
token = adminLogin();
mockMvc.perform(get("/admin/articles?page=1&count=1").header("Authorization", token)).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(SUCCESS.getCode(), object.getInt(Code));
});
} }
@Test @Test
public void VisitorAccess() throws Exception { public void VisitorAccess() throws Exception {
mockMvc.perform(get("/user/userInfo")).andDo(result -> { getMockData(get("/user/userInfo")).andDo(result -> assertEquals(HAVE_NOT_LOG_IN.getCode(), getResponse(result).getCode()));
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); getMockData(get("/admin/articles?page=1&count=1")).andDo(result -> assertEquals(HAVE_NOT_LOG_IN.getCode(), getResponse(result).getCode()));
assertEquals(HAVE_NOT_LOG_IN.getCode(), object.getInt(Code));
});
mockMvc.perform(get("/admin/articles?page=1&count=1")).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString());
assertEquals(HAVE_NOT_LOG_IN.getCode(), object.getInt(Code));
});
} }
@Test @Test
public void authorizationTest() throws Exception { public void authorizationTest() throws Exception {
// 测试response中有无Authorization字段 // 测试response中有无Authorization字段
String s = userLogin(); String token = userLogin();
mockMvc.perform(get("/user/userInfo").header("Authorization", s)).andDo(result -> { getMockData(get("/user/userInfo"), token).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<Object> response = getResponse(result);
assertEquals(SUCCESS.getCode(), object.getInt(Code)); assertEquals(SUCCESS.getCode(), response.getCode());
assertNotNull(result.getResponse().getHeader("Authorization")); assertNotNull(result.getResponse().getHeader("Authorization"));
assertNotEquals(s, result.getResponse().getHeader("Authorization")); assertNotEquals(token, result.getResponse().getHeader("Authorization"));
}); });
} }
} }

View File

@@ -2,16 +2,11 @@ package cn.celess.blog.filter;
import cn.celess.blog.BaseTest; import cn.celess.blog.BaseTest;
import cn.celess.blog.enmu.ResponseEnum; import cn.celess.blog.enmu.ResponseEnum;
import net.sf.json.JSONObject; import cn.celess.blog.entity.Response;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession; import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import javax.servlet.http.Cookie;
/** /**
* @Author: 小海 * @Author: 小海
@@ -31,11 +26,11 @@ public class MultipleSubmitFilter extends BaseTest {
private void sendRequest(ResponseEnum expectResponse, String... msg) throws Exception { private void sendRequest(ResponseEnum expectResponse, String... msg) throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/counts").session(session)).andDo(result -> { getMockData(MockMvcRequestBuilders.get("/counts").session(session)).andDo(result -> {
JSONObject object = JSONObject.fromObject(result.getResponse().getContentAsString()); Response<Object> response = getResponse(result);
Assert.assertEquals(expectResponse.getCode(), object.getInt(Code)); Assert.assertEquals(expectResponse.getCode(), response.getCode());
if (msg.length != 0) { if (msg.length != 0) {
Assert.assertEquals(msg[0], object.getString("msg")); Assert.assertEquals(msg[0], response.getMsg());
} }
}); });
} }

View File

@@ -6,7 +6,6 @@ import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.List; import java.util.List;
import java.util.UUID;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@@ -37,7 +36,7 @@ public class ArticleMapperTest extends BaseTest {
@Test @Test
public void update() { public void update() {
Article article = generateArticle().getArticle(); Article article = generateArticle().getArticle();
String randomText = UUID.randomUUID().toString(); String randomText = randomStr();
// 此字段不会通过insert被写入数据库而是使用插入数据的默认值 数据库中该字段默认为true // 此字段不会通过insert被写入数据库而是使用插入数据的默认值 数据库中该字段默认为true
article.setOpen(true); article.setOpen(true);
@@ -117,7 +116,7 @@ public class ArticleMapperTest extends BaseTest {
public void existsByTitle() { public void existsByTitle() {
Article article = generateArticle().getArticle(); Article article = generateArticle().getArticle();
assertTrue(articleMapper.existsByTitle(article.getTitle())); assertTrue(articleMapper.existsByTitle(article.getTitle()));
assertFalse(articleMapper.existsByTitle(UUID.randomUUID().toString())); assertFalse(articleMapper.existsByTitle(randomStr()));
} }
@Test @Test
@@ -196,7 +195,7 @@ public class ArticleMapperTest extends BaseTest {
} }
private ArticleTag generateArticle() { private ArticleTag generateArticle() {
String randomText = UUID.randomUUID().toString(); String randomText = randomStr();
Article article = new Article(); Article article = new Article();
Category category = new Category(); Category category = new Category();

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