Compare commits
93 Commits
v2.3.0
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49a1a53ecb | ||
| 2a3ae4a376 | |||
| 92e818e370 | |||
|
|
c8e93c45c7 | ||
|
|
32de31a21e | ||
|
|
cc20df91e6 | ||
|
|
71d79ed008 | ||
|
|
f7ff494ea4 | ||
|
|
971f48c5f9 | ||
|
|
e1522a8cc1 | ||
|
|
3cc4989960 | ||
|
|
8c751e6e76 | ||
|
|
af47631126 | ||
|
|
2107a1c100 | ||
|
|
2eac16dbe4 | ||
|
|
d248e15cea | ||
|
|
91a818d293 | ||
|
|
65c31e96b4 | ||
|
|
81b4851e42 | ||
|
|
9c580cf6d9 | ||
|
|
9eea5b3db9 | ||
|
|
eacb2e29f3 | ||
|
|
fafee4f918 | ||
|
|
30a4c11366 | ||
|
|
5632d47674 | ||
|
|
15b5d89554 | ||
|
|
79426dbe24 | ||
|
|
b3b19dbc45 | ||
|
|
87ec6d24ca | ||
|
|
0148c5e3f5 | ||
|
|
7cff3b9c08 | ||
|
|
a354f48edf | ||
|
|
2cd2dc93d7 | ||
|
|
d5fbc0fbf1 | ||
|
|
b29362eb8c | ||
|
|
d7c6cca683 | ||
|
|
8020eaeff3 | ||
|
|
aedcaf207b | ||
|
|
af9bf9ef46 | ||
|
|
b38ce4c8ce | ||
|
|
3d3548b984 | ||
|
|
4be9eda566 | ||
|
|
e5711746fb | ||
|
|
cc9cf8b1e8 | ||
|
|
ff076f8366 | ||
|
|
dd9ae0b3f9 | ||
|
|
0e7d5f2d23 | ||
|
|
1de1af2a54 | ||
|
|
857a3d9473 | ||
|
|
78efa62476 | ||
|
|
674812c5c6 | ||
|
|
14ce46c312 | ||
|
|
5f5fbadfd8 | ||
|
|
c153d9a0e3 | ||
|
|
18d35809f5 | ||
|
|
75e2424f75 | ||
|
|
b6c4251198 | ||
|
|
fc1bfa0e4f | ||
|
|
e37de0e177 | ||
|
|
082662af66 | ||
|
|
0c0e2404d0 | ||
|
|
71f82bfe32 | ||
|
|
61ce2fddad | ||
|
|
a245f259f7 | ||
|
|
aa22369b13 | ||
|
|
8c3866afe6 | ||
|
|
2c85c3eaac | ||
|
|
2559937e02 | ||
|
|
8de4be602e | ||
|
|
1f88995884 | ||
|
|
c879fbff5f | ||
|
|
f6020bf8d0 | ||
|
|
418b1d78e5 | ||
|
|
98ed489bb1 | ||
|
|
cfdd818829 | ||
|
|
3afbef009f | ||
|
|
8f4d1cd6c8 | ||
|
|
0ba7e06695 | ||
|
|
512d04f3e9 | ||
|
|
ada8f67171 | ||
|
|
6e12331e61 | ||
|
|
81ee71adf1 | ||
|
|
7e7332694e | ||
|
|
8db690a55f | ||
|
|
0b40522e93 | ||
|
|
9026ba0732 | ||
|
|
f5f2437fa4 | ||
|
|
0bcca091e1 | ||
|
|
3c69baa4ad | ||
|
|
baf5b1bbb7 | ||
|
|
38621bcfa4 | ||
|
|
cf435a588f | ||
|
|
feab26f4f7 |
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal 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.
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
12
.github/dependabot.yml
vendored
Normal file
12
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "maven" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
open-pull-requests-limit: 10
|
||||
13
.github/workflows/build.yml
vendored
13
.github/workflows/build.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '.md')" # 如果 commit 信息包含以下关键字则跳过该任务
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
KEY: ${{ secrets.WEB_HOOK_ACCESS_KEY }}
|
||||
@@ -22,5 +22,16 @@ jobs:
|
||||
with:
|
||||
java-version: 1.8
|
||||
|
||||
- name: Sync repository
|
||||
uses: x-dr/sync-repo-to-gitee@v1.0
|
||||
env:
|
||||
# 在 Settings->Secrets 配置 GITEE_KEY
|
||||
SSH_KEY: ${{ secrets.GITEE_KEY }}
|
||||
with:
|
||||
# GitHub存储库的SSH URL.
|
||||
github-repo: git@github.com:xiaohai2271/blog-backEnd.git
|
||||
# Gitee存储库的SSH URL.
|
||||
gitee-repo: git@gitee.com:xiaohai2271/blog-backEnd.git
|
||||
|
||||
- name: Deploy
|
||||
run: mvn -B test --file pom.xml && curl http://bt.celess.cn:2271/hook?access_key=$KEY
|
||||
|
||||
71
.github/workflows/codeql-analysis.yml
vendored
Normal file
71
.github/workflows/codeql-analysis.yml
vendored
Normal 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
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '.md')" # 如果 commit 信息包含以下关键字则跳过该任务
|
||||
runs-on: ubuntu-latest
|
||||
# env:
|
||||
# APPLICATION_PROPERTIES_TEST: ${{ secrets.APPLICATION_PROPERTIES_TEST }}
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
|
||||
[](https://github.com/xiaohai2271/blog-backEnd)
|
||||
[](https://github.com/xiaohai2271/blog-backEnd)
|
||||
[](https://github.com/xiaohai2271/blog-backEnd)
|
||||
[](https://github.com/xiaohai2271/blog-backEnd)
|
||||
[](https://github.com/xiaohai2271/blog-backEnd)
|
||||
[](https://github.com/xiaohai2271/blog-backEnd)
|
||||
[](https://github.com/xiaohai2271/blog-backEnd)
|
||||
[](https://www.celess.cn)
|
||||
</div>
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
### 2. 拉取项目到本地
|
||||
``` shell script
|
||||
git clone https://github.com/xiaohai2271/blog-backEnd.git
|
||||
或 git clone git@github.com:xiaohai2271/blog-backEnd.git
|
||||
# 或
|
||||
git clone git@github.com:xiaohai2271/blog-backEnd.git
|
||||
```
|
||||
|
||||
### 3. maven构建
|
||||
@@ -26,7 +27,7 @@ java -jar target/blog-0.0.1-SNAPSHOT.jar
|
||||
```shell script
|
||||
mvn clean # 清理项目资源
|
||||
mvn clean package # 清理项目资源并重新打包
|
||||
mvn clean package -DskipTest # 清理项目资源,重新打包并跳过测试
|
||||
mvn clean package -DskipTests # 清理项目资源,重新打包并跳过测试
|
||||
mvn test # 运行测试
|
||||
..... #待添加
|
||||
```
|
||||
60
pom.xml
60
pom.xml
@@ -5,8 +5,8 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.3.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
<version>3.0.3</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<groupId>cn.celess</groupId>
|
||||
<artifactId>blog</artifactId>
|
||||
@@ -40,14 +40,14 @@
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.14</version>
|
||||
<version>1.2.6</version>
|
||||
</dependency>
|
||||
|
||||
<!-- lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.6</version>
|
||||
<version>1.18.20</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -67,12 +67,12 @@
|
||||
<dependency>
|
||||
<groupId>com.youbenzi</groupId>
|
||||
<artifactId>MDTool</artifactId>
|
||||
<version>1.2.3</version>
|
||||
<version>1.2.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.minidev</groupId>
|
||||
<artifactId>json-smart</artifactId>
|
||||
<version>2.3</version>
|
||||
<version>2.4.7</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -99,39 +99,39 @@
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<version>2.2.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- pageHelper -->
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
<version>1.2.12</version>
|
||||
<version>1.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- protostuff序列化依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.dyuproject.protostuff</groupId>
|
||||
<artifactId>protostuff-core</artifactId>
|
||||
<version>1.0.8</version>
|
||||
<version>1.1.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dyuproject.protostuff</groupId>
|
||||
<artifactId>protostuff-runtime</artifactId>
|
||||
<version>1.0.8</version>
|
||||
<version>1.1.6</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Ua解析-->
|
||||
<dependency>
|
||||
<groupId>eu.bitwalker</groupId>
|
||||
<artifactId>UserAgentUtils</artifactId>
|
||||
<version>1.20</version>
|
||||
<version>1.21</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<version>4.13.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JJwt -->
|
||||
@@ -145,12 +145,12 @@
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>4.8.0</version>
|
||||
<version>4.9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
<version>1.3.72</version>
|
||||
<version>1.4.20</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<version>2.42.0</version>
|
||||
<version>2.45.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -175,6 +175,34 @@
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-core</artifactId>
|
||||
<version>2.3.0.1</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>
|
||||
|
||||
<build>
|
||||
@@ -186,7 +214,7 @@
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>1.3.72</version>
|
||||
<version>1.5.10</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package cn.celess.blog.configuration;
|
||||
|
||||
import cn.celess.blog.util.EnvironmentUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.env.EnvironmentPostProcessor;
|
||||
import org.springframework.boot.logging.DeferredLog;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* <p>date: 2022/12/02</P>
|
||||
* <p>desc: </p>
|
||||
* <p>mail: a@celess.cn</p>
|
||||
*
|
||||
* @author 禾几海
|
||||
*/
|
||||
|
||||
@Component
|
||||
public class CommonEnvPostProcessor implements EnvironmentPostProcessor, ApplicationListener<ApplicationEvent>, Ordered {
|
||||
public static final DeferredLog log = new DeferredLog();
|
||||
|
||||
private static final String CONFIG_PATH = "/HBlog/config/blog.properties";
|
||||
private static final String SOURCE_NAME = "localize";
|
||||
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment configurableEnvironment, SpringApplication springApplication) {
|
||||
|
||||
EnvironmentUtil.setEnvironment(configurableEnvironment);
|
||||
|
||||
log.info("加载本地配置文件--");
|
||||
//获取环境变量
|
||||
String homeEnv = EnvironmentUtil.getEnv("BLOG_HOME", EnvironmentUtil.getEnv("USERPROFILE"));
|
||||
String configPath = (homeEnv + CONFIG_PATH).replaceAll("[\\|/]+", Matcher.quoteReplacement(File.separator));
|
||||
try (InputStream input = Files.newInputStream(Paths.get(configPath))) {
|
||||
Properties properties = new Properties();
|
||||
properties.load(input);
|
||||
PropertiesPropertySource propertySource = new PropertiesPropertySource(SOURCE_NAME, properties);
|
||||
configurableEnvironment.getPropertySources().addLast(propertySource);
|
||||
log.info("成功加载本地配置文件:)");
|
||||
} catch (Exception e) {
|
||||
log.info("加载本地[" + configPath + "]的配置文件失败:(");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(@NotNull ApplicationEvent event) {
|
||||
log.replayTo(CommonEnvPostProcessor.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import cn.celess.blog.exception.MyException;
|
||||
import cn.celess.blog.service.CountService;
|
||||
import cn.celess.blog.service.QiniuService;
|
||||
import cn.celess.blog.util.HttpUtil;
|
||||
import cn.celess.blog.util.RedisUserUtil;
|
||||
import cn.celess.blog.util.RedisUtil;
|
||||
import cn.celess.blog.util.VeriCodeUtil;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
@@ -27,9 +28,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -47,7 +46,7 @@ public class CommonController {
|
||||
@Autowired
|
||||
RedisUtil redisUtil;
|
||||
@Autowired
|
||||
HttpServletRequest request;
|
||||
RedisUserUtil redisUserUtil;
|
||||
|
||||
|
||||
@GetMapping("/counts")
|
||||
@@ -89,7 +88,7 @@ public class CommonController {
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
@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();
|
||||
request.getSession().setAttribute("code", obj[0]);
|
||||
//将图片输出给浏览器
|
||||
@@ -133,9 +132,10 @@ public class CommonController {
|
||||
* FIXME :: 单张图片多次上传的问题
|
||||
* editor.md图片上传的接口
|
||||
* FUCK !!!
|
||||
*
|
||||
* !! 推荐使用 fileUpload(/fileUpload) 接口
|
||||
* @param file 文件
|
||||
*/
|
||||
@Deprecated
|
||||
@PostMapping("/imgUpload")
|
||||
public void upload(HttpServletRequest request, HttpServletResponse response, @RequestParam("editormd-image-file") MultipartFile file) throws IOException {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
@@ -186,4 +186,37 @@ public class CommonController {
|
||||
JsonNode images = root.get("images").elements().next();
|
||||
return Response.success("https://cn.bing.com" + images.get("url").asText());
|
||||
}
|
||||
|
||||
@PostMapping("/fileUpload")
|
||||
public Response<List<Map<String, Object>>> fileUpload(@RequestParam("file[]") MultipartFile[] files) throws IOException {
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
String uploadTimesStr = redisUtil.get(redisUserUtil.get().getEmail() + "-fileUploadTimes");
|
||||
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(" ", "");
|
||||
QiniuResponse qiniuResponse = qiniuService.uploadFile(file.getInputStream(), "file_" + name + '_' + System.currentTimeMillis() + mime);
|
||||
resp.put("originalFilename", fileName);
|
||||
resp.put("success", qiniuResponse != null);
|
||||
if (qiniuResponse != null) {
|
||||
resp.put("host", "http://cdn.celess.cn/");
|
||||
resp.put("path", qiniuResponse.key);
|
||||
}
|
||||
result.add(resp);
|
||||
}
|
||||
return Response.success(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public class VisitorController {
|
||||
@GetMapping("/admin/visitor/page")
|
||||
public Response page(@RequestParam(value = "count", required = false, defaultValue = "10") int count,
|
||||
@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));
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,8 @@ public enum ResponseEnum {
|
||||
APPLY_LINK_NO_ADD_THIS_SITE(7200, "暂未在您的网站中抓取到本站链接"),
|
||||
DATA_EXPIRED(7300, "数据过期"),
|
||||
CANNOT_GET_DATA(7400, "暂无法获取到数据"),
|
||||
NO_FILE(7500, "未选择文件,请重新选择"),
|
||||
|
||||
|
||||
//提交更新之前,没有获取数据/,
|
||||
DID_NOT_GET_THE_DATA(8020, "非法访问"),
|
||||
|
||||
@@ -32,8 +32,8 @@ public class Response<T> implements Serializable {
|
||||
* @param result 结果
|
||||
* @return Response
|
||||
*/
|
||||
public static Response success(Object result) {
|
||||
return new Response(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMsg(), result);
|
||||
public static <T> Response<T> success(T result) {
|
||||
return new Response<T>(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMsg(), result);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,8 +42,8 @@ public class Response<T> implements Serializable {
|
||||
* @param result 结果
|
||||
* @return Response
|
||||
*/
|
||||
public static Response failure(String result) {
|
||||
return new Response(ResponseEnum.FAILURE.getCode(), ResponseEnum.FAILURE.getMsg(), result);
|
||||
public static Response<String> failure(String result) {
|
||||
return new Response<String>(ResponseEnum.FAILURE.getCode(), ResponseEnum.FAILURE.getMsg(), result);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,8 +53,8 @@ public class Response<T> implements Serializable {
|
||||
* @param result 结果
|
||||
* @return Response
|
||||
*/
|
||||
public static Response response(ResponseEnum r, String result) {
|
||||
return new Response(r.getCode(), r.getMsg(), result);
|
||||
public static <T> Response<T> response(ResponseEnum r, T result) {
|
||||
return new Response<T>(r.getCode(), r.getMsg(), result);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cn.celess.blog.mapper;
|
||||
|
||||
import cn.celess.blog.entity.ArticleTag;
|
||||
import cn.celess.blog.entity.Tag;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -27,6 +28,8 @@ public interface ArticleTagMapper {
|
||||
|
||||
List<ArticleTag> findAllByArticleId(Long articleId);
|
||||
|
||||
List<Tag> findTagByArticleId(Long articleId);
|
||||
|
||||
int deleteMultiById(List<ArticleTag> articleTags);
|
||||
|
||||
List<ArticleTag> findArticleByTag(Long tagId);
|
||||
|
||||
@@ -279,21 +279,20 @@ public class ArticleServiceImpl implements ArticleService {
|
||||
*/
|
||||
@Override
|
||||
public PageData<ArticleModel> adminArticles(int count, int page, Boolean deleted) {
|
||||
PageHelper.startPage(page, count);
|
||||
List<Article> articleList = articleMapper.findAll();
|
||||
|
||||
PageData<ArticleModel> pageData = new PageData<>(null, 0, count, page);
|
||||
PageData<ArticleModel> pageData = new PageData<>(new PageInfo<>(articleList));
|
||||
|
||||
List<Article> collect;
|
||||
if (deleted != null) {
|
||||
collect = articleList.stream().filter(article -> article.isDeleted() == deleted).collect(Collectors.toList());
|
||||
} else {
|
||||
collect = articleList;
|
||||
}
|
||||
pageData.setTotal(collect.size());
|
||||
List<ArticleModel> articleModels = collect.stream()
|
||||
.peek(article -> article.setMdContent(null))
|
||||
.map(ModalTrans::article)
|
||||
.skip((page - 1) * count)
|
||||
.limit(count)
|
||||
.collect(Collectors.toList());
|
||||
pageData.setList(articleModels);
|
||||
|
||||
@@ -304,16 +303,12 @@ public class ArticleServiceImpl implements ArticleService {
|
||||
public PageData<ArticleModel> retrievePageForOpen(int count, int page) {
|
||||
PageHelper.startPage(page, count);
|
||||
List<Article> articleList = articleMapper.findAllByOpen(true);
|
||||
PageData<ArticleModel> pageData = new PageData<>(new PageInfo<Article>(articleList));
|
||||
|
||||
List<ArticleModel> articleModelList = new ArrayList<>();
|
||||
|
||||
articleList.forEach(article -> {
|
||||
ArticleModel model = ModalTrans.article(article, true);
|
||||
setPreAndNextArticle(model);
|
||||
articleModelList.add(model);
|
||||
});
|
||||
PageData<ArticleModel> pageData = new PageData<>(new PageInfo<>(articleList));
|
||||
|
||||
List<ArticleModel> articleModelList = articleList
|
||||
.stream()
|
||||
.map(article -> setPreAndNextArticle(ModalTrans.article(article, true)))
|
||||
.collect(Collectors.toList());
|
||||
pageData.setList(articleModelList);
|
||||
return pageData;
|
||||
}
|
||||
@@ -327,17 +322,14 @@ public class ArticleServiceImpl implements ArticleService {
|
||||
PageHelper.startPage(page, count);
|
||||
List<Article> open = articleMapper.findAllByCategoryIdAndOpen(category.getId());
|
||||
|
||||
List<ArticleModel> modelList = new ArrayList<>();
|
||||
|
||||
open.forEach(article -> {
|
||||
ArticleModel model = ModalTrans.article(article, true);
|
||||
model.setTags(null);
|
||||
// setPreAndNextArticle(model);
|
||||
model.setNextArticle(null);
|
||||
model.setPreArticle(null);
|
||||
modelList.add(model);
|
||||
});
|
||||
return new PageData<ArticleModel>(new PageInfo<Article>(open), modelList);
|
||||
List<ArticleModel> modelList = open.stream()
|
||||
.map(article -> ModalTrans.article(article, true))
|
||||
.peek(articleModel -> {
|
||||
articleModel.setNextArticle(null);
|
||||
articleModel.setPreArticle(null);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
return new PageData<>(new PageInfo<>(open), modelList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -348,21 +340,22 @@ public class ArticleServiceImpl implements ArticleService {
|
||||
}
|
||||
PageHelper.startPage(page, count);
|
||||
List<ArticleTag> articleByTag = articleTagMapper.findArticleByTagAndOpen(tag.getId());
|
||||
List<ArticleModel> modelList = new ArrayList<>();
|
||||
articleByTag.forEach(articleTag -> {
|
||||
ArticleModel model = ModalTrans.article(articleTag.getArticle(), true);
|
||||
model.setNextArticle(null);
|
||||
model.setPreArticle(null);
|
||||
modelList.add(model);
|
||||
});
|
||||
return new PageData<ArticleModel>(new PageInfo<ArticleTag>(articleByTag), modelList);
|
||||
List<ArticleModel> modelList = articleByTag
|
||||
.stream()
|
||||
.map(articleTag -> ModalTrans.article(articleTag.getArticle(), true))
|
||||
.peek(articleModel -> {
|
||||
articleModel.setNextArticle(null);
|
||||
articleModel.setPreArticle(null);
|
||||
}).collect(Collectors.toList());
|
||||
return new PageData<>(new PageInfo<>(articleByTag), modelList);
|
||||
}
|
||||
|
||||
private void setPreAndNextArticle(ArticleModel articleModel) {
|
||||
private ArticleModel setPreAndNextArticle(ArticleModel articleModel) {
|
||||
if (articleModel == null) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
articleModel.setPreArticle(ModalTrans.article(articleMapper.getPreArticle(articleModel.getId()), true));
|
||||
articleModel.setNextArticle(ModalTrans.article(articleMapper.getNextArticle(articleModel.getId()), true));
|
||||
return articleModel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
@@ -68,22 +68,25 @@ public class CategoryServiceImpl implements CategoryService {
|
||||
public PageData<CategoryModel> retrievePage(int page, int count) {
|
||||
PageHelper.startPage(page, count);
|
||||
List<Category> all = categoryMapper.findAll();
|
||||
List<CategoryModel> modelList = new ArrayList<>();
|
||||
all.forEach(e -> {
|
||||
CategoryModel model = ModalTrans.category(e);
|
||||
List<Article> allByCategoryId = articleMapper.findAllByCategoryId(e.getId());
|
||||
List<ArticleModel> articleModelList = new ArrayList<>();
|
||||
allByCategoryId.forEach(article -> {
|
||||
ArticleModel articleModel = ModalTrans.article(article, true);
|
||||
// 遍历没一个category
|
||||
List<CategoryModel> modelList = all
|
||||
.stream()
|
||||
.map(ModalTrans::category)
|
||||
.peek(categoryModel -> {
|
||||
// 根据category去查article,并赋值给categoryModel
|
||||
List<Article> allByCategoryId = articleMapper.findAllByCategoryId(categoryModel.getId());
|
||||
List<ArticleModel> articleModelList = allByCategoryId
|
||||
.stream()
|
||||
.map(article -> ModalTrans.article(article, true))
|
||||
.peek(articleModel -> {
|
||||
// 去除不必要的字段
|
||||
articleModel.setPreArticle(null);
|
||||
articleModel.setNextArticle(null);
|
||||
articleModel.setTags(null);
|
||||
articleModelList.add(articleModel);
|
||||
});
|
||||
model.setArticles(articleModelList);
|
||||
modelList.add(model);
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.stereotype.Service;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
@@ -107,14 +108,11 @@ public class CommentServiceImpl implements CommentService {
|
||||
@Override
|
||||
public List<CommentModel> retrievePageByPid(long pid) {
|
||||
List<Comment> allByPagePath = commentMapper.findAllByPid(pid);
|
||||
List<CommentModel> commentModels = new ArrayList<>();
|
||||
allByPagePath.forEach(comment -> {
|
||||
if (comment.getStatus() != CommentStatusEnum.DELETED.getCode()) {
|
||||
commentModels.add(ModalTrans.comment(comment));
|
||||
}
|
||||
});
|
||||
|
||||
return commentModels;
|
||||
return allByPagePath
|
||||
.stream()
|
||||
.filter(comment -> comment.getStatus() != CommentStatusEnum.DELETED.getCode())
|
||||
.map(ModalTrans::comment)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,14 +143,11 @@ public class CommentServiceImpl implements CommentService {
|
||||
|
||||
private PageData<CommentModel> pageTrans(List<Comment> commentList, boolean noResponseList) {
|
||||
PageInfo<Comment> p = PageInfo.of(commentList);
|
||||
List<CommentModel> modelList = new ArrayList<>();
|
||||
commentList.forEach(l -> {
|
||||
CommentModel model = ModalTrans.comment(l);
|
||||
if (!noResponseList) {
|
||||
model.setRespComment(this.retrievePageByPid(model.getId()));
|
||||
}
|
||||
modelList.add(model);
|
||||
});
|
||||
return new PageData<CommentModel>(p, modelList);
|
||||
List<CommentModel> modelList = commentList
|
||||
.stream()
|
||||
.map(ModalTrans::comment)
|
||||
.peek(commentModel -> commentModel.setRespComment(this.retrievePageByPid(commentModel.getId())))
|
||||
.collect(Collectors.toList());
|
||||
return new PageData<>(p, modelList);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
@@ -81,20 +82,22 @@ public class TagServiceImpl implements TagService {
|
||||
List<Tag> tagList = tagMapper.findAll();
|
||||
List<TagModel> modelList = new ArrayList<>();
|
||||
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
|
||||
public List<TagModel> findAll() {
|
||||
List<TagModel> list = new ArrayList<>();
|
||||
tagMapper.findAll().forEach(e -> {
|
||||
TagModel model = ModalTrans.tag(e);
|
||||
List<ArticleTag> articleByTagAndOpen = articleTagMapper.findArticleByTagAndOpen(e.getId());
|
||||
List<ArticleModel> articleModelList = new ArrayList<>();
|
||||
articleByTagAndOpen.forEach(articleTag -> articleModelList.add(ModalTrans.article(articleTag.getArticle(), true)));
|
||||
model.setArticles(articleModelList);
|
||||
list.add(model);
|
||||
});
|
||||
return list;
|
||||
return tagMapper.findAll().stream()
|
||||
.map(ModalTrans::tag)
|
||||
.peek(tagModel -> {
|
||||
List<ArticleTag> articleByTagAndOpen = articleTagMapper.findArticleByTagAndOpen(tagModel.getId());
|
||||
tagModel.setArticles(
|
||||
articleByTagAndOpen
|
||||
.stream()
|
||||
.map(articleTag -> ModalTrans.article(articleTag.getArticle(), true))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import cn.celess.blog.entity.model.VisitorModel;
|
||||
import cn.celess.blog.exception.MyException;
|
||||
import cn.celess.blog.mapper.VisitorMapper;
|
||||
import cn.celess.blog.service.VisitorService;
|
||||
import cn.celess.blog.util.AddressUtil;
|
||||
import cn.celess.blog.util.DateFormatUtil;
|
||||
import cn.celess.blog.util.RedisUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
@@ -50,7 +51,7 @@ public class VisitorServiceImpl implements VisitorService {
|
||||
public PageData<VisitorModel> visitorPage(int page, int count, boolean showLocation) {
|
||||
PageHelper.startPage(page, count);
|
||||
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
|
||||
@@ -151,60 +152,7 @@ public class VisitorServiceImpl implements VisitorService {
|
||||
* @return
|
||||
*/
|
||||
private String getLocation(String ip) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
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();
|
||||
|
||||
return AddressUtil.getCityInfo(ip);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.springframework.stereotype.Service;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author : xiaohai
|
||||
@@ -72,7 +73,7 @@ public class WebUpdateInfoServiceImpl implements WebUpdateInfoService {
|
||||
public PageData<WebUpdateModel> pages(int count, int page) {
|
||||
PageHelper.startPage(page, count);
|
||||
List<WebUpdate> updateList = webUpdateInfoMapper.findAll();
|
||||
return new PageData<WebUpdateModel>(new PageInfo<WebUpdate>(updateList), list2List(updateList));
|
||||
return new PageData<>(new PageInfo<>(updateList), list2List(updateList));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,8 +109,6 @@ public class WebUpdateInfoServiceImpl implements WebUpdateInfoService {
|
||||
}
|
||||
|
||||
private List<WebUpdateModel> list2List(List<WebUpdate> webUpdates) {
|
||||
List<WebUpdateModel> webUpdateModels = new ArrayList<>();
|
||||
webUpdates.forEach(update -> webUpdateModels.add(ModalTrans.webUpdate(update)));
|
||||
return webUpdateModels;
|
||||
return webUpdates.stream().map(ModalTrans::webUpdate).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
71
src/main/java/cn/celess/blog/util/AddressUtil.java
Normal file
71
src/main/java/cn/celess/blog/util/AddressUtil.java
Normal 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;
|
||||
}
|
||||
}
|
||||
51
src/main/java/cn/celess/blog/util/EnvironmentUtil.java
Normal file
51
src/main/java/cn/celess/blog/util/EnvironmentUtil.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package cn.celess.blog.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* <p>date: 2022/12/02</P>
|
||||
* <p>desc: </p>
|
||||
* <p>mail: a@celess.cn</p>
|
||||
*
|
||||
* @author 禾几海
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class EnvironmentUtil {
|
||||
|
||||
private static Environment environment;
|
||||
|
||||
public static String getEnv(String name) {
|
||||
String value = System.getenv(name);
|
||||
if (StringUtils.isBlank(value)) {
|
||||
log.error("没有找到环境变量:" + name);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static String getEnv(String name, String defaultValue) {
|
||||
String env = getEnv(name);
|
||||
if (env == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
public static String getProperties(String key) {
|
||||
String value = environment.getProperty(key);
|
||||
if (StringUtils.isBlank(value)) {
|
||||
log.error("没有找到配置项: {}", key);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static String getProperties(String key, String defaultValue) {
|
||||
return environment.getProperty(key, defaultValue);
|
||||
}
|
||||
|
||||
public static void setEnvironment(Environment environment) {
|
||||
EnvironmentUtil.environment = environment;
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,8 @@ public class JwtUtil {
|
||||
*/
|
||||
public static final long EXPIRATION_SHORT_TIME = 7200000;
|
||||
private static final String CLAIM_KEY_USERNAME = "sub";
|
||||
private static final String BEARER_PREFIX_UPPER = "Bearer";
|
||||
private static final String BEARER_PREFIX_LOWER = "bearer";
|
||||
/**
|
||||
* JWT 秘钥需自行设置不可泄露
|
||||
*/
|
||||
@@ -48,7 +50,7 @@ public class JwtUtil {
|
||||
}
|
||||
|
||||
public String updateTokenDate(String token) {
|
||||
Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
|
||||
Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(getJwtString(token)).getBody();
|
||||
return Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.setExpiration(new Date(claims.getExpiration().getTime() + EXPIRATION_SHORT_TIME))
|
||||
@@ -60,7 +62,7 @@ public class JwtUtil {
|
||||
* 获取token是否过期
|
||||
*/
|
||||
public Boolean isTokenExpired(String token) {
|
||||
Date expiration = getExpirationDateFromToken(token);
|
||||
Date expiration = getExpirationDateFromToken(getJwtString(token));
|
||||
return expiration == null || expiration.before(new Date());
|
||||
}
|
||||
|
||||
@@ -68,7 +70,7 @@ public class JwtUtil {
|
||||
* 根据token获取username
|
||||
*/
|
||||
public String getUsernameFromToken(String token) {
|
||||
Claims claims = getClaimsFromToken(token);
|
||||
Claims claims = getClaimsFromToken(getJwtString(token));
|
||||
return claims == null ? null : claims.getSubject();
|
||||
}
|
||||
|
||||
@@ -76,7 +78,7 @@ public class JwtUtil {
|
||||
* 获取token的过期时间
|
||||
*/
|
||||
public Date getExpirationDateFromToken(String token) {
|
||||
Claims claims = getClaimsFromToken(token);
|
||||
Claims claims = getClaimsFromToken(getJwtString(token));
|
||||
return claims == null ? null : claims.getExpiration();
|
||||
}
|
||||
|
||||
@@ -88,7 +90,7 @@ public class JwtUtil {
|
||||
try {
|
||||
claims = Jwts.parser()
|
||||
.setSigningKey(SECRET)
|
||||
.parseClaimsJws(token)
|
||||
.parseClaimsJws(getJwtString(token))
|
||||
.getBody();
|
||||
} catch (ExpiredJwtException e) {
|
||||
log.info("JWT令牌过期");
|
||||
@@ -107,4 +109,9 @@ public class JwtUtil {
|
||||
return claims;
|
||||
}
|
||||
|
||||
private String getJwtString(String token) {
|
||||
if (token == null) return token;
|
||||
return token.replaceFirst(BEARER_PREFIX_UPPER, "").replace(BEARER_PREFIX_LOWER, "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
2
src/main/resources/META-INF/spring.factories
Normal file
2
src/main/resources/META-INF/spring.factories
Normal file
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.env.EnvironmentPostProcessor=cn.celess.blog.configuration.CommonEnvPostProcessor
|
||||
org.springframework.context.ApplicationListener=cn.celess.blog.configuration.CommonEnvPostProcessor
|
||||
@@ -1,26 +1,26 @@
|
||||
server.port=8081
|
||||
|
||||
# 七牛的密钥配置
|
||||
# ???????
|
||||
qiniu.accessKey=
|
||||
qiniu.secretKey=
|
||||
qiniu.bucket=
|
||||
# sitemap 存放地址
|
||||
# sitemap ????
|
||||
sitemap.path=
|
||||
# 生成JWT时候的密钥
|
||||
# ??JWT?????
|
||||
jwt.secret=
|
||||
|
||||
spring.jpa.show-sql=false
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
# 上传单个文件的大小
|
||||
# ?????????
|
||||
spring.servlet.multipart.max-file-size=10MB
|
||||
# 上传文件的总大小
|
||||
# ????????
|
||||
spring.servlet.multipart.max-request-size=10MB
|
||||
##null字段不显示
|
||||
##null?????
|
||||
spring.jackson.default-property-inclusion=non_null
|
||||
|
||||
|
||||
################# 数据库 ##################
|
||||
#请先填写下面的配置
|
||||
################# ??? ##################
|
||||
#?????????
|
||||
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
|
||||
spring.datasource.url=
|
||||
spring.datasource.username=
|
||||
@@ -48,7 +48,7 @@ pagehelper.params=count=countSql
|
||||
|
||||
|
||||
################ email ##############
|
||||
#请先填写下面的配置,不然可能运行不起来
|
||||
#???????????????????
|
||||
spring.mail.host=
|
||||
spring.mail.username=
|
||||
spring.mail.password=
|
||||
@@ -62,7 +62,7 @@ spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFact
|
||||
spring.mail.properties.mail.smtp.socketFactory.fallback=false
|
||||
|
||||
|
||||
#### 用于nginx的代理 获取真实ip
|
||||
#### ??nginx??? ????ip
|
||||
server.use-forward-headers = true
|
||||
server.tomcat.remote-ip-header = X-Real-IP
|
||||
server.tomcat.protocol-header = X-Forwarded-Proto
|
||||
@@ -70,21 +70,21 @@ server.tomcat.protocol-header = X-Forwarded-Proto
|
||||
|
||||
############### redis ##############
|
||||
# REDIS (RedisProperties)
|
||||
# Redis数据库索引(默认为0)
|
||||
# Redis?????????0?
|
||||
spring.redis.database=0
|
||||
# Redis服务器地址
|
||||
# Redis?????
|
||||
spring.redis.host=
|
||||
# Redis服务器连接端口
|
||||
# Redis???????
|
||||
spring.redis.port=6379
|
||||
# Redis服务器连接密码(默认为空)
|
||||
# Redis?????????????
|
||||
spring.redis.password=
|
||||
# 连接池最大连接数(使用负值表示没有限制)
|
||||
# ????????????????????
|
||||
spring.redis.jedis.pool.max-active=-1
|
||||
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
# ???????????????????????
|
||||
spring.redis.jedis.pool.max-wait=-1
|
||||
# 连接池中的最大空闲连接
|
||||
# ???????????
|
||||
spring.redis.jedis.pool.max-idle=8
|
||||
# 连接池中的最小空闲连接
|
||||
# ???????????
|
||||
spring.redis.jedis.pool.min-idle=0
|
||||
# 连接超时时间(毫秒)
|
||||
# ??????????
|
||||
spring.redis.timeout=5000
|
||||
@@ -1,12 +1,12 @@
|
||||
server.port=8081
|
||||
|
||||
# 七牛的密钥配置
|
||||
# ???????
|
||||
qiniu.accessKey=
|
||||
qiniu.secretKey=
|
||||
qiniu.bucket=
|
||||
# sitemap 存放地址
|
||||
# sitemap ????
|
||||
sitemap.path=
|
||||
# 生成JWT时候的密钥
|
||||
# ??JWT?????
|
||||
jwt.secret=sdaniod213k123123ipoeqowekqwe
|
||||
|
||||
##spring.jpa.show-sql=false
|
||||
@@ -14,15 +14,15 @@ jwt.secret=sdaniod213k123123ipoeqowekqwe
|
||||
|
||||
mybatis.type-handlers-package=cn.celess.blog.mapper.typehandler
|
||||
logging.level.cn.celess.blog.mapper=debug
|
||||
# 上传单个文件的大小
|
||||
# ?????????
|
||||
spring.servlet.multipart.max-file-size=10MB
|
||||
# 上传文件的总大小
|
||||
# ????????
|
||||
spring.servlet.multipart.max-request-size=10MB
|
||||
|
||||
spring.jackson.default-property-inclusion=non_null
|
||||
|
||||
|
||||
################# 数据库 ##################
|
||||
################# ??? ##################
|
||||
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
|
||||
|
||||
#h2
|
||||
@@ -51,7 +51,7 @@ pagehelper.params=count=countSql
|
||||
|
||||
|
||||
|
||||
#### 用于nginx的代理 获取真实ip
|
||||
#### ??nginx??? ????ip
|
||||
server.use-forward-headers = true
|
||||
server.tomcat.remote-ip-header = X-Real-IP
|
||||
server.tomcat.protocol-header = X-Forwarded-Proto
|
||||
@@ -75,22 +75,21 @@ spring.mail.properties.mail.smtp.socketFactory.fallback=false
|
||||
############### redis ##############
|
||||
|
||||
# REDIS (RedisProperties)
|
||||
# Redis数据库索引(默认为0)
|
||||
# Redis?????????0?
|
||||
spring.redis.database=1
|
||||
# Redis服务器地址
|
||||
# Redis?????
|
||||
spring.redis.host=127.0.0.1
|
||||
# Redis服务器连接端口 解决端口冲突 防止使用本地的redis
|
||||
# Redis??????? ?????? ???????redis
|
||||
spring.redis.port=6380
|
||||
# Redis服务器连接密码(默认为空)
|
||||
# Redis?????????????
|
||||
spring.redis.password=
|
||||
# 连接池最大连接数(使用负值表示没有限制)
|
||||
# ????????????????????
|
||||
spring.redis.jedis.pool.max-active=-1
|
||||
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
# ???????????????????????
|
||||
spring.redis.jedis.pool.max-wait=-1
|
||||
# 连接池中的最大空闲连接
|
||||
# ???????????
|
||||
spring.redis.jedis.pool.max-idle=8
|
||||
# 连接池中的最小空闲连接
|
||||
# ???????????
|
||||
spring.redis.jedis.pool.min-idle=0
|
||||
# 连接超时时间(毫秒)
|
||||
# ??????????
|
||||
spring.redis.timeout=5000
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
spring.profiles.active=prod
|
||||
####七牛的配置
|
||||
spring.profiles.active=dev
|
||||
#### ?????
|
||||
####cn.celess.blog.service.serviceimpl.QiniuServiceImpl
|
||||
logging.level.cn.celess.blog=debug
|
||||
logging.level.cn.celess.blog.mapper=info
|
||||
|
||||
## 修改openSource 添加-test 文件用于测试 -prod文件用于线上发布
|
||||
## ??openSource ??-test ?????? -prod????????
|
||||
BIN
src/main/resources/ip2region/ip2region.db
Normal file
BIN
src/main/resources/ip2region/ip2region.db
Normal file
Binary file not shown.
@@ -64,6 +64,14 @@
|
||||
and article_tag.t_id = tag_category.t_id
|
||||
</select>
|
||||
|
||||
<select id="findTagByArticleId" resultMap="cn.celess.blog.mapper.TagMapper.tagResultMap">
|
||||
select tag_category.*
|
||||
from article_tag,
|
||||
tag_category
|
||||
where a_id = #{articleId}
|
||||
and article_tag.t_id = tag_category.t_id
|
||||
</select>
|
||||
|
||||
<select id="findOneById" resultMap="articleTagResultMap">
|
||||
select *
|
||||
from article_tag,
|
||||
|
||||
@@ -19,8 +19,10 @@
|
||||
<association property="category" column="a_category_id" javaType="cn.celess.blog.entity.TagCategory"
|
||||
resultMap="cn.celess.blog.mapper.CategoryMapper.categoryResultMap">
|
||||
</association>
|
||||
<collection property="tags" ofType="cn.celess.blog.entity.TagCategory"
|
||||
resultMap="cn.celess.blog.mapper.CategoryMapper.categoryResultMap">
|
||||
<collection property="tags" ofType="cn.celess.blog.entity.Tag"
|
||||
select="cn.celess.blog.mapper.ArticleTagMapper.findTagByArticleId" column="a_id">
|
||||
<id column="tagId" property="id"/>
|
||||
<result column="tagName" property="name"/>
|
||||
</collection>
|
||||
</resultMap>
|
||||
|
||||
@@ -49,7 +51,8 @@
|
||||
<result column="userAvatar" property="avatarImgUrl"/>
|
||||
<result column="userDisplayName" property="displayName"/>
|
||||
</association>
|
||||
<collection property="tags" ofType="cn.celess.blog.entity.Tag">
|
||||
<collection property="tags" ofType="cn.celess.blog.entity.Tag"
|
||||
select="cn.celess.blog.mapper.ArticleTagMapper.findTagByArticleId" column="{articleId=articleId}">
|
||||
<id column="tagId" property="id"/>
|
||||
<result column="tagName" property="name"/>
|
||||
</collection>
|
||||
@@ -119,11 +122,37 @@
|
||||
</select>
|
||||
|
||||
<select id="findAllByOpen" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
where isOpen = #{isOpen}
|
||||
and isDelete = false
|
||||
order by articleId desc
|
||||
select article.a_id as articleId,
|
||||
article.a_title as title,
|
||||
article.a_summary as summary,
|
||||
article.a_md_content as mdContent,
|
||||
article.a_url as url,
|
||||
article.a_is_original as isOriginal,
|
||||
article.a_reading_number as readingCount,
|
||||
article.a_like as likeCount,
|
||||
article.a_dislike as dislikeCount,
|
||||
article.a_publish_date as publishDate,
|
||||
article.a_update_date as updateDate,
|
||||
article.a_is_open as isOpen,
|
||||
category.t_id as categoryId,
|
||||
category.t_name as categoryName,
|
||||
user.u_id as authorId,
|
||||
user.u_email as userEmail,
|
||||
user.u_avatar as userAvatar,
|
||||
user.u_display_name as userDisplayName,
|
||||
article.is_delete as isDelete
|
||||
from article,
|
||||
tag_category as category,
|
||||
article_tag,
|
||||
user
|
||||
where article.a_is_open = #{isOpen}
|
||||
and article.is_delete = false
|
||||
and article.a_id = article_tag.a_id
|
||||
and article.a_category_id = category.t_id
|
||||
and category.is_category = true
|
||||
and article.a_author_id = user.u_id
|
||||
group by article.a_id
|
||||
order by article.a_id desc
|
||||
</select>
|
||||
|
||||
|
||||
@@ -152,9 +181,35 @@
|
||||
|
||||
|
||||
<select id="findAll" resultMap="articleViewResultMap">
|
||||
select *
|
||||
from articleView
|
||||
order by articleId desc
|
||||
select article.a_id as articleId,
|
||||
article.a_title as title,
|
||||
article.a_summary as summary,
|
||||
article.a_md_content as mdContent,
|
||||
article.a_url as url,
|
||||
article.a_is_original as isOriginal,
|
||||
article.a_reading_number as readingCount,
|
||||
article.a_like as likeCount,
|
||||
article.a_dislike as dislikeCount,
|
||||
article.a_publish_date as publishDate,
|
||||
article.a_update_date as updateDate,
|
||||
article.a_is_open as isOpen,
|
||||
category.t_id as categoryId,
|
||||
category.t_name as categoryName,
|
||||
user.u_id as authorId,
|
||||
user.u_email as userEmail,
|
||||
user.u_avatar as userAvatar,
|
||||
user.u_display_name as userDisplayName,
|
||||
article.is_delete as isDelete
|
||||
from article,
|
||||
tag_category as category,
|
||||
article_tag,
|
||||
user
|
||||
where article.a_id = article_tag.a_id
|
||||
and article.a_category_id = category.t_id
|
||||
and category.is_category = true
|
||||
and article.a_author_id = user.u_id
|
||||
group by article.a_id
|
||||
order by article.a_id desc
|
||||
</select>
|
||||
|
||||
|
||||
@@ -169,7 +224,8 @@
|
||||
from articleView
|
||||
where articleId = (select max(articleId)
|
||||
from articleView
|
||||
where articleId < #{id}
|
||||
where isOpen = true
|
||||
and articleId < #{id}
|
||||
)
|
||||
</select>
|
||||
<select id="getNextArticle" resultMap="articleViewResultMap">
|
||||
@@ -177,7 +233,8 @@
|
||||
from articleView
|
||||
where articleId = (select min(articleId)
|
||||
from articleView
|
||||
where articleId > #{id}
|
||||
where isOpen = true
|
||||
and articleId > #{id}
|
||||
)
|
||||
</select>
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ public class BaseTest {
|
||||
protected ResultActions getMockData(MockHttpServletRequestBuilder builder, String token, Object content) throws Exception {
|
||||
// MockHttpServletRequestBuilder mockHttpServletRequestBuilder = get(url);
|
||||
if (token != null) {
|
||||
builder.header("Authorization", token);
|
||||
builder.header("Authorization", "Bearer "+token);
|
||||
}
|
||||
if (content != null) {
|
||||
builder.content(mapper.writeValueAsString(content)).contentType(MediaType.APPLICATION_JSON);
|
||||
|
||||
@@ -31,6 +31,7 @@ public class VisitorControllerTest extends BaseTest {
|
||||
public void page() throws Exception {
|
||||
int count = 10;
|
||||
int page = 1;
|
||||
// 默认显示location
|
||||
getMockData(get("/admin/visitor/page?count=" + count + "&page=" + page), adminLogin()).andDo(result -> {
|
||||
Response<PageData<VisitorModel>> response = getResponse(result, VISITOR_PAGE_TYPE);
|
||||
assertEquals(SUCCESS.getCode(), response.getCode());
|
||||
@@ -41,6 +42,7 @@ public class VisitorControllerTest extends BaseTest {
|
||||
for (VisitorModel v : pageData.getList()) {
|
||||
assertNotEquals(0, v.getId());
|
||||
assertNotNull(v.getDate());
|
||||
assertNotNull(v.getLocation());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -134,4 +134,13 @@ public class ArticleTagMapperTest extends BaseTest {
|
||||
|
||||
return articleTag;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findTagByArticleId() {
|
||||
Article article = articleMapper.findAll().get(0);
|
||||
assertNotNull(article);
|
||||
|
||||
List<Tag> tagByArticleId = articleTagMapper.findTagByArticleId(article.getId());
|
||||
assertNotEquals(0, tagByArticleId.size());
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package cn.celess.blog.service;
|
||||
import cn.celess.blog.BaseTest;
|
||||
import cn.celess.blog.entity.model.ArticleModel;
|
||||
import cn.celess.blog.entity.model.PageData;
|
||||
import cn.celess.blog.mapper.ArticleMapper;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@@ -12,6 +14,8 @@ public class ArticleServiceTest extends BaseTest {
|
||||
|
||||
@Autowired
|
||||
ArticleService articleService;
|
||||
@Autowired
|
||||
ArticleMapper articleMapper;
|
||||
|
||||
@Test
|
||||
public void adminArticles() {
|
||||
@@ -24,4 +28,25 @@ public class ArticleServiceTest extends BaseTest {
|
||||
assertTrue(pageData.getList().stream().anyMatch(ArticleModel::isDeleted));
|
||||
assertTrue(pageData.getList().stream().anyMatch(articleModel -> !articleModel.isDeleted()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrievePageForOpen() {
|
||||
PageData<ArticleModel> articleModelPageData = articleService.retrievePageForOpen(10, 1);
|
||||
assertEquals(10, articleModelPageData.getPageSize());
|
||||
assertEquals(1, articleModelPageData.getPageNum());
|
||||
assertEquals(10, articleModelPageData.getList().size());
|
||||
articleModelPageData.getList().forEach(Assert::assertNotNull);
|
||||
|
||||
// 测试open字段
|
||||
articleModelPageData.getList().forEach(articleModel -> {
|
||||
// 当前文章
|
||||
assertTrue(articleMapper.findArticleById(articleModel.getId()).getOpen());
|
||||
if (articleModel.getPreArticle() != null) {
|
||||
assertTrue(articleMapper.findArticleById(articleModel.getPreArticle().getId()).getOpen());
|
||||
}
|
||||
if (articleModel.getNextArticle() != null) {
|
||||
assertTrue(articleMapper.findArticleById(articleModel.getNextArticle().getId()).getOpen());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
29
src/test/java/cn/celess/blog/service/VisitorServiceTest.java
Normal file
29
src/test/java/cn/celess/blog/service/VisitorServiceTest.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package cn.celess.blog.service;
|
||||
|
||||
import cn.celess.blog.BaseTest;
|
||||
import cn.celess.blog.entity.model.PageData;
|
||||
import cn.celess.blog.entity.model.VisitorModel;
|
||||
import com.alibaba.druid.util.StringUtils;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class VisitorServiceTest extends BaseTest {
|
||||
|
||||
@Autowired
|
||||
VisitorService visitorService;
|
||||
|
||||
@Test
|
||||
public void location() {
|
||||
assertEquals("0|0|0|内网IP|内网IP", visitorService.location("127.0.0.1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void visitorPage() {
|
||||
long start = System.currentTimeMillis();
|
||||
PageData<VisitorModel> visitorModelPageData = visitorService.visitorPage(1, 10, true);
|
||||
assertTrue(System.currentTimeMillis() - start <= 1500);
|
||||
assertTrue(visitorModelPageData.getList().stream().noneMatch(visitor -> StringUtils.isEmpty(visitor.getLocation())));
|
||||
}
|
||||
}
|
||||
15
src/test/java/cn/celess/blog/util/AddressUtilTest.java
Normal file
15
src/test/java/cn/celess/blog/util/AddressUtilTest.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package cn.celess.blog.util;
|
||||
|
||||
import cn.celess.blog.BaseTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class AddressUtilTest extends BaseTest {
|
||||
|
||||
@Test
|
||||
public void getCityInfo() {
|
||||
assertEquals("0|0|0|内网IP|内网IP", AddressUtil.getCityInfo("127.0.0.1"));
|
||||
assertEquals("中国|0|上海|上海市|阿里云", AddressUtil.getCityInfo("106.15.205.190"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user