Compare commits

..

77 Commits

Author SHA1 Message Date
dependabot[bot]
1d6950fb11 build(deps): bump jaxb-impl from 3.0.0 to 4.0.2
Bumps jaxb-impl from 3.0.0 to 4.0.2.

---
updated-dependencies:
- dependency-name: com.sun.xml.bind:jaxb-impl
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-01 09:58:19 +00:00
2a3ae4a376 调整 2022-12-02 21:49:31 +08:00
92e818e370 调整 2022-12-02 21:27:47 +08:00
禾几海
c8e93c45c7 Merge pull request #74 from xiaohai2271/dependabot/maven/com.alibaba-druid-1.2.6
build(deps): bump druid from 1.2.5 to 1.2.6
2021-06-02 10:57:25 +08:00
禾几海
32de31a21e Merge pull request #75 from xiaohai2271/dependabot/maven/org.mybatis.spring.boot-mybatis-spring-boot-starter-2.2.0
build(deps): bump mybatis-spring-boot-starter from 2.1.4 to 2.2.0
2021-06-02 10:57:04 +08:00
禾几海
cc20df91e6 Merge pull request #63 from xiaohai2271/dependabot/maven/org.projectlombok-lombok-1.18.20
build(deps): bump lombok from 1.18.18 to 1.18.20
2021-06-01 23:30:23 +08:00
dependabot[bot]
71d79ed008 build(deps): bump mybatis-spring-boot-starter from 2.1.4 to 2.2.0
Bumps [mybatis-spring-boot-starter](https://github.com/mybatis/spring-boot-starter) from 2.1.4 to 2.2.0.
- [Release notes](https://github.com/mybatis/spring-boot-starter/releases)
- [Commits](https://github.com/mybatis/spring-boot-starter/compare/mybatis-spring-boot-2.1.4...mybatis-spring-boot-2.2.0)

---
updated-dependencies:
- dependency-name: org.mybatis.spring.boot:mybatis-spring-boot-starter
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-01 15:30:00 +00:00
dependabot[bot]
f7ff494ea4 build(deps): bump druid from 1.2.5 to 1.2.6
Bumps [druid](https://github.com/alibaba/druid) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/alibaba/druid/releases)
- [Commits](https://github.com/alibaba/druid/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: com.alibaba:druid
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-01 15:29:55 +00:00
禾几海
971f48c5f9 Merge pull request #72 from xiaohai2271/dependabot/maven/org.jetbrains.kotlin-kotlin-maven-plugin-1.5.10
build(deps): bump kotlin-maven-plugin from 1.4.10 to 1.5.10
2021-06-01 23:29:54 +08:00
禾几海
e1522a8cc1 Merge pull request #73 from xiaohai2271/dependabot/maven/net.minidev-json-smart-2.4.7
build(deps): bump json-smart from 2.3 to 2.4.7
2021-06-01 23:29:32 +08:00
dependabot[bot]
3cc4989960 build(deps): bump json-smart from 2.3 to 2.4.7
Bumps [json-smart](https://github.com/netplex/json-smart-v2) from 2.3 to 2.4.7.
- [Release notes](https://github.com/netplex/json-smart-v2/releases)
- [Commits](https://github.com/netplex/json-smart-v2/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-01 05:22:45 +00:00
dependabot[bot]
8c751e6e76 build(deps): bump kotlin-maven-plugin from 1.4.10 to 1.5.10
Bumps kotlin-maven-plugin from 1.4.10 to 1.5.10.

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-01 05:22:39 +00:00
dependabot[bot]
af47631126 build(deps): bump lombok from 1.18.18 to 1.18.20
Bumps [lombok](https://github.com/rzwitserloot/lombok) from 1.18.18 to 1.18.20.
- [Release notes](https://github.com/rzwitserloot/lombok/releases)
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/rzwitserloot/lombok/compare/v1.18.18...v1.18.20)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-01 05:24:17 +00:00
禾几海
2107a1c100 Merge pull request #49 from xiaohai2271/dependabot/maven/com.squareup.okhttp3-okhttp-4.9.1
build(deps): bump okhttp from 4.9.0 to 4.9.1
2021-04-01 14:14:35 +08:00
禾几海
2eac16dbe4 Merge pull request #52 from xiaohai2271/dependabot/maven/com.alibaba-druid-1.2.5
build(deps): bump druid from 1.2.3 to 1.2.5
2021-04-01 14:12:39 +08:00
禾几海
d248e15cea fix: 规范请求头的token
规范为` Authorization: Bearer $token`
2021-03-16 20:09:06 +08:00
禾几海
91a818d293 fix: sql条件错误 2021-03-16 15:54:26 +08:00
禾几海
65c31e96b4 test: 补增单元测试 2021-03-16 15:45:49 +08:00
禾几海
81b4851e42 refactor: 分页查询
通过数据库进行分页查询而非查询全部然后分页
2021-03-16 15:38:49 +08:00
禾几海
9c580cf6d9 fix: 文章不可见
当open字段为false时文章应当不被感知
而之前的版本并没有做强制要求
2021-03-16 15:30:05 +08:00
禾几海
9eea5b3db9 ci: Sync repository to gitee 2021-03-15 22:12:49 +08:00
禾几海
eacb2e29f3 fix: 修复数据异常 2021-03-15 18:51:53 +08:00
禾几海
fafee4f918 fix: 分页数据异常 2021-03-15 17:31:37 +08:00
dependabot[bot]
30a4c11366 build(deps): bump druid from 1.2.3 to 1.2.5
Bumps [druid](https://github.com/alibaba/druid) from 1.2.3 to 1.2.5.
- [Release notes](https://github.com/alibaba/druid/releases)
- [Commits](https://github.com/alibaba/druid/compare/1.2.3...1.2.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-01 05:31:55 +00:00
禾几海
5632d47674 Merge pull request #48 from xiaohai2271/dependabot/maven/org.projectlombok-lombok-1.18.18
build(deps): bump lombok from 1.18.16 to 1.18.18
2021-02-28 22:24:55 +08:00
dependabot[bot]
15b5d89554 build(deps): bump okhttp from 4.9.0 to 4.9.1
Bumps [okhttp](https://github.com/square/okhttp) from 4.9.0 to 4.9.1.
- [Release notes](https://github.com/square/okhttp/releases)
- [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/okhttp/compare/parent-4.9.0...parent-4.9.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-01 05:28:43 +00:00
dependabot[bot]
79426dbe24 build(deps): bump lombok from 1.18.16 to 1.18.18
Bumps [lombok](https://github.com/rzwitserloot/lombok) from 1.18.16 to 1.18.18.
- [Release notes](https://github.com/rzwitserloot/lombok/releases)
- [Changelog](https://github.com/rzwitserloot/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/rzwitserloot/lombok/compare/v1.18.16...v1.18.18)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-01 05:28:40 +00:00
禾几海
b3b19dbc45 Merge pull request #38 from xiaohai2271/dependabot/maven/net.sourceforge.htmlunit-htmlunit-2.45.0
build(deps): bump htmlunit from 2.44.0 to 2.45.0
2020-12-02 11:00:34 +08:00
禾几海
87ec6d24ca Merge pull request #37 from xiaohai2271/dependabot/maven/org.mybatis.spring.boot-mybatis-spring-boot-starter-2.1.4
build(deps): bump mybatis-spring-boot-starter from 2.1.3 to 2.1.4
2020-12-01 14:08:15 +08:00
禾几海
0148c5e3f5 Merge pull request #39 from xiaohai2271/dependabot/maven/com.alibaba-druid-1.2.3
build(deps): bump druid from 1.2.1 to 1.2.3
2020-12-01 14:04:58 +08:00
禾几海
7cff3b9c08 Merge pull request #40 from xiaohai2271/dependabot/maven/com.sun.xml.bind-jaxb-impl-3.0.0
build(deps): bump jaxb-impl from 2.3.3 to 3.0.0
2020-12-01 14:02:35 +08:00
禾几海
a354f48edf Merge pull request #41 from xiaohai2271/dependabot/maven/org.jetbrains.kotlin-kotlin-stdlib-1.4.20
build(deps): bump kotlin-stdlib from 1.4.10 to 1.4.20
2020-12-01 14:02:02 +08:00
dependabot[bot]
2cd2dc93d7 build(deps): bump kotlin-stdlib from 1.4.10 to 1.4.20
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.4.10 to 1.4.20.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.4.10...v1.4.20)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-01 05:39:35 +00:00
dependabot[bot]
d5fbc0fbf1 build(deps): bump jaxb-impl from 2.3.3 to 3.0.0
Bumps jaxb-impl from 2.3.3 to 3.0.0.

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-01 05:39:09 +00:00
dependabot[bot]
b29362eb8c build(deps): bump druid from 1.2.1 to 1.2.3
Bumps [druid](https://github.com/alibaba/druid) from 1.2.1 to 1.2.3.
- [Release notes](https://github.com/alibaba/druid/releases)
- [Commits](https://github.com/alibaba/druid/compare/1.2.1...1.2.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-01 05:39:07 +00:00
dependabot[bot]
d7c6cca683 build(deps): bump htmlunit from 2.44.0 to 2.45.0
Bumps [htmlunit](https://github.com/HtmlUnit/htmlunit) from 2.44.0 to 2.45.0.
- [Release notes](https://github.com/HtmlUnit/htmlunit/releases)
- [Commits](https://github.com/HtmlUnit/htmlunit/compare/2.44.0...2.45.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-01 05:39:03 +00:00
dependabot[bot]
8020eaeff3 build(deps): bump mybatis-spring-boot-starter from 2.1.3 to 2.1.4
Bumps [mybatis-spring-boot-starter](https://github.com/mybatis/spring-boot-starter) from 2.1.3 to 2.1.4.
- [Release notes](https://github.com/mybatis/spring-boot-starter/releases)
- [Commits](https://github.com/mybatis/spring-boot-starter/compare/mybatis-spring-boot-2.1.3...mybatis-spring-boot-2.1.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-01 05:39:02 +00:00
禾几海
aedcaf207b ci: skip ci action situation
[skip ci]
2020-11-14 21:38:58 +08:00
禾几海
af9bf9ef46 ci: skip ci action situation 2020-11-14 21:27:44 +08:00
禾几海
b38ce4c8ce Update dependabot.yml 2020-11-02 15:04:20 +08:00
禾几海
3d3548b984 Merge pull request #27 from xiaohai2271/dependabot/maven/com.youbenzi-MDTool-1.2.4
build(deps): bump MDTool from 1.2.3 to 1.2.4
2020-11-01 19:12:55 +08:00
禾几海
4be9eda566 Merge pull request #28 from xiaohai2271/dependabot/maven/com.dyuproject.protostuff-protostuff-runtime-1.1.6
build(deps): bump protostuff-runtime from 1.0.8 to 1.1.6
2020-11-01 19:12:14 +08:00
禾几海
e5711746fb Merge pull request #29 from xiaohai2271/dependabot/maven/org.mybatis.spring.boot-mybatis-spring-boot-starter-2.1.3
build(deps): bump mybatis-spring-boot-starter from 2.0.1 to 2.1.3
2020-11-01 19:11:36 +08:00
禾几海
cc9cf8b1e8 Merge pull request #31 from xiaohai2271/dependabot/maven/com.alibaba-druid-1.2.1
build(deps): bump druid from 1.1.14 to 1.2.1
2020-10-27 13:22:10 +08:00
禾几海
ff076f8366 Merge pull request #32 from xiaohai2271/dependabot/maven/com.squareup.okhttp3-okhttp-4.9.0
build(deps): bump okhttp from 4.8.0 to 4.9.0
2020-10-27 13:17:27 +08:00
禾几海
dd9ae0b3f9 Merge pull request #30 from xiaohai2271/dependabot/maven/eu.bitwalker-UserAgentUtils-1.21
build(deps): bump UserAgentUtils from 1.20 to 1.21
2020-10-22 22:37:46 +08:00
dependabot[bot]
0e7d5f2d23 build(deps): bump okhttp from 4.8.0 to 4.9.0
Bumps [okhttp](https://github.com/square/okhttp) from 4.8.0 to 4.9.0.
- [Release notes](https://github.com/square/okhttp/releases)
- [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/okhttp/compare/parent-4.8.0...parent-4.9.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-20 16:17:29 +00:00
dependabot[bot]
1de1af2a54 build(deps): bump druid from 1.1.14 to 1.2.1
Bumps [druid](https://github.com/alibaba/druid) from 1.1.14 to 1.2.1.
- [Release notes](https://github.com/alibaba/druid/releases)
- [Commits](https://github.com/alibaba/druid/compare/1.1.14...1.2.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-20 16:17:25 +00:00
dependabot[bot]
857a3d9473 build(deps): bump UserAgentUtils from 1.20 to 1.21
Bumps [UserAgentUtils](https://github.com/HaraldWalker/user-agent-utils) from 1.20 to 1.21.
- [Release notes](https://github.com/HaraldWalker/user-agent-utils/releases)
- [Commits](https://github.com/HaraldWalker/user-agent-utils/compare/1.20...1.21)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-20 16:17:24 +00:00
dependabot[bot]
78efa62476 build(deps): bump protostuff-runtime from 1.0.8 to 1.1.6
Bumps protostuff-runtime from 1.0.8 to 1.1.6.

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-20 16:17:22 +00:00
dependabot[bot]
674812c5c6 build(deps): bump mybatis-spring-boot-starter from 2.0.1 to 2.1.3
Bumps [mybatis-spring-boot-starter](https://github.com/mybatis/spring-boot-starter) from 2.0.1 to 2.1.3.
- [Release notes](https://github.com/mybatis/spring-boot-starter/releases)
- [Commits](https://github.com/mybatis/spring-boot-starter/compare/mybatis-spring-boot-2.0.1...mybatis-spring-boot-2.1.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-20 16:17:22 +00:00
dependabot[bot]
14ce46c312 build(deps): bump MDTool from 1.2.3 to 1.2.4
Bumps [MDTool](https://github.com/cevin15/MDTool) from 1.2.3 to 1.2.4.
- [Release notes](https://github.com/cevin15/MDTool/releases)
- [Commits](https://github.com/cevin15/MDTool/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-20 16:17:21 +00:00
禾几海
5f5fbadfd8 Merge pull request #15 from xiaohai2271/dependabot/maven/com.sun.xml.bind-jaxb-core-2.3.0.1
build(deps): bump jaxb-core from 2.3.0 to 2.3.0.1
2020-10-21 00:11:48 +08:00
禾几海
c153d9a0e3 Merge pull request #16 from xiaohai2271/dependabot/maven/org.jetbrains.kotlin-kotlin-maven-plugin-1.4.10
build(deps): bump kotlin-maven-plugin from 1.3.72 to 1.4.10
2020-10-21 00:11:25 +08:00
禾几海
18d35809f5 Merge pull request #17 from xiaohai2271/dependabot/maven/com.sun.xml.bind-jaxb-impl-2.3.3
build(deps): bump jaxb-impl from 2.3.0 to 2.3.3
2020-10-21 00:11:00 +08:00
禾几海
75e2424f75 Merge pull request #22 from xiaohai2271/dependabot/maven/javax.xml.bind-jaxb-api-2.3.1
build(deps): bump jaxb-api from 2.3.0 to 2.3.1
2020-10-21 00:10:24 +08:00
禾几海
b6c4251198 Merge pull request #21 from xiaohai2271/dependabot/maven/com.github.pagehelper-pagehelper-spring-boot-starter-1.3.0
build(deps): bump pagehelper-spring-boot-starter from 1.2.12 to 1.3.0
2020-10-21 00:08:04 +08:00
禾几海
fc1bfa0e4f Merge pull request #19 from xiaohai2271/dependabot/maven/org.jetbrains.kotlin-kotlin-stdlib-1.4.10
build(deps): bump kotlin-stdlib from 1.3.72 to 1.4.10
2020-10-21 00:07:25 +08:00
禾几海
e37de0e177 Merge pull request #20 from xiaohai2271/dependabot/maven/com.dyuproject.protostuff-protostuff-core-1.1.6
build(deps): bump protostuff-core from 1.0.8 to 1.1.6
2020-10-21 00:06:58 +08:00
dependabot[bot]
082662af66 build(deps): bump protostuff-core from 1.0.8 to 1.1.6
Bumps protostuff-core from 1.0.8 to 1.1.6.

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-20 15:11:14 +00:00
dependabot[bot]
0c0e2404d0 Merge pull request #26 from xiaohai2271/dependabot/maven/org.projectlombok-lombok-1.18.16 2020-10-20 14:59:05 +00:00
dependabot[bot]
71f82bfe32 build(deps): bump lombok from 1.18.6 to 1.18.16
Bumps [lombok](https://github.com/rzwitserloot/lombok) from 1.18.6 to 1.18.16.
- [Release notes](https://github.com/rzwitserloot/lombok/releases)
- [Changelog](https://github.com/rzwitserloot/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/rzwitserloot/lombok/compare/v1.18.6...v1.18.16)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-20 07:06:17 +00:00
禾几海
61ce2fddad Merge pull request #24 from xiaohai2271/dependabot/maven/net.sourceforge.htmlunit-htmlunit-2.44.0
build(deps): bump htmlunit from 2.42.0 to 2.44.0
2020-10-20 13:03:25 +08:00
禾几海
a245f259f7 revert: "Update test.yml"
This reverts commit 2c85c3ea
2020-10-17 23:28:58 +08:00
禾几海
aa22369b13 Merge pull request #25 from kingzhongking/master
style(pom):  delete some comment
2020-10-17 22:51:00 +08:00
kingzhongking
8c3866afe6 style(pom): delete some comment 2020-10-17 14:44:29 +00:00
禾几海
2c85c3eaac Update test.yml 2020-10-16 19:32:36 +08:00
dependabot[bot]
2559937e02 build(deps): bump htmlunit from 2.42.0 to 2.44.0
Bumps [htmlunit](https://github.com/HtmlUnit/htmlunit) from 2.42.0 to 2.44.0.
- [Release notes](https://github.com/HtmlUnit/htmlunit/releases)
- [Commits](https://github.com/HtmlUnit/htmlunit/compare/2.42.0...2.44.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:21:27 +00:00
dependabot[bot]
8de4be602e build(deps): bump jaxb-api from 2.3.0 to 2.3.1
Bumps [jaxb-api](https://github.com/javaee/jaxb-spec) from 2.3.0 to 2.3.1.
- [Release notes](https://github.com/javaee/jaxb-spec/releases)
- [Commits](https://github.com/javaee/jaxb-spec/compare/2.3.0...2.3.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:21:23 +00:00
dependabot[bot]
1f88995884 build(deps): bump pagehelper-spring-boot-starter from 1.2.12 to 1.3.0
Bumps pagehelper-spring-boot-starter from 1.2.12 to 1.3.0.

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:21:23 +00:00
禾几海
c879fbff5f Update dependabot.yml 2020-10-16 19:21:00 +08:00
dependabot[bot]
f6020bf8d0 build(deps): bump kotlin-stdlib from 1.3.72 to 1.4.10
Bumps [kotlin-stdlib](https://github.com/JetBrains/kotlin) from 1.3.72 to 1.4.10.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.4.10/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.3.72...v1.4.10)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:09:51 +00:00
dependabot[bot]
418b1d78e5 build(deps): bump jaxb-impl from 2.3.0 to 2.3.3
Bumps jaxb-impl from 2.3.0 to 2.3.3.

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:09:20 +00:00
dependabot[bot]
98ed489bb1 build(deps): bump kotlin-maven-plugin from 1.3.72 to 1.4.10
Bumps kotlin-maven-plugin from 1.3.72 to 1.4.10.

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:09:19 +00:00
dependabot[bot]
cfdd818829 build(deps): bump jaxb-core from 2.3.0 to 2.3.0.1
Bumps jaxb-core from 2.3.0 to 2.3.0.1.

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:09:18 +00:00
禾几海
3afbef009f Create dependabot.yml 2020-10-16 19:08:56 +08:00
禾几海
8f4d1cd6c8 Update issue templates 2020-10-15 16:46:31 +08:00
55 changed files with 737 additions and 2428 deletions

View 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
View 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

View File

@@ -10,12 +10,10 @@ on:
jobs: jobs:
build: build:
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '.md')" # 如果 commit 信息包含以下关键字则跳过该任务
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
KEY: ${{ secrets.WEB_HOOK_ACCESS_KEY }} KEY: ${{ secrets.WEB_HOOK_ACCESS_KEY }}
QINIU_ACCESSKEY: ${{ secrets.QINIU_ACCESSKEY }}
QINIU_SECRETKEY: ${{ secrets.QINIU_SECRETKEY }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@@ -24,5 +22,16 @@ jobs:
with: with:
java-version: 1.8 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 - name: Deploy
run: mvn -B test --file pom.xml && curl http://bt.celess.cn:2271/hook?access_key=$KEY run: mvn -B test --file pom.xml && curl http://bt.celess.cn:2271/hook?access_key=$KEY

View File

@@ -10,11 +10,11 @@ on:
jobs: jobs:
build: build:
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '.md')" # 如果 commit 信息包含以下关键字则跳过该任务
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: # env:
QINIU_ACCESSKEY: ${{ secrets.QINIU_ACCESSKEY }} # APPLICATION_PROPERTIES_TEST: ${{ secrets.APPLICATION_PROPERTIES_TEST }}
QINIU_SECRETKEY: ${{ secrets.QINIU_SECRETKEY }} # APPLICATION_PROPERTIES_PROD: ${{ secrets.APPLICATION_PROPERTIES_PROD }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View File

@@ -1411,78 +1411,6 @@
| 401 | Unauthorized || | 401 | Unauthorized ||
| 403 | Forbidden || | 403 | Forbidden ||
| 404 | Not Found || | 404 | Not Found ||
## fileUpload
**接口描述**:
**接口地址**:`/fileUpload`
**请求方式**`POST`
**consumes**:`["application/json"]`
**produces**:`["*/*"]`
**请求参数**
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| ------------ | -------------------------------- |-----------|--------|----|--- |
|file[]| file[] | formData | true |array | file |
**响应示例**:
```json
{
"code": 0,
"msg": "",
"result": [
{}
]
}
```
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| ------------ | -------------------|-------|----------- |
|code| |integer(int32) | integer(int32) |
|msg| |string | |
|result| |array | Map«string,object» |
**schema属性说明**
**Map«string,object»**
| 参数名称 | 参数说明 | 类型 | schema |
| ------------ | ------------------|--------|----------- |
**响应状态**:
| 状态码 | 说明 | schema |
| ------------ | -------------------------------- |---------------------- |
| 200 | OK |Response«List«Map«string,object»»»|
| 201 | Created ||
| 401 | Unauthorized ||
| 403 | Forbidden ||
| 404 | Not Found ||
## headerInfo ## headerInfo
@@ -1695,231 +1623,6 @@
| 401 | Unauthorized || | 401 | Unauthorized ||
| 403 | Forbidden || | 403 | Forbidden ||
| 404 | Not Found || | 404 | Not Found ||
# config-controller
## getConfiguration
**接口描述**:
**接口地址**:`/admin/config`
**请求方式**`GET`
**consumes**:``
**produces**:`["*/*"]`
**请求参数**
暂无
**响应示例**:
```json
{
"code": 0,
"msg": "",
"result": [
{
"id": 0,
"name": "",
"value": ""
}
]
}
```
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| ------------ | -------------------|-------|----------- |
|code| |integer(int32) | integer(int32) |
|msg| |string | |
|result| |array | Config |
**schema属性说明**
**Config**
| 参数名称 | 参数说明 | 类型 | schema |
| ------------ | ------------------|--------|----------- |
|id | |integer(int32) | |
|name | |string | |
|value | |string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------------ | -------------------------------- |---------------------- |
| 200 | OK |Response«List«Config»»|
| 401 | Unauthorized ||
| 403 | Forbidden ||
| 404 | Not Found ||
## addConfiguration
**接口描述**:
**接口地址**:`/admin/config`
**请求方式**`POST`
**consumes**:`["application/json"]`
**produces**:`["*/*"]`
**请求参数**
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| ------------ | -------------------------------- |-----------|--------|----|--- |
|configs| configs | query | false |array | Config |
**响应示例**:
```json
{
"code": 0,
"msg": "",
"result": [
{
"id": 0,
"name": "",
"value": ""
}
]
}
```
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| ------------ | -------------------|-------|----------- |
|code| |integer(int32) | integer(int32) |
|msg| |string | |
|result| |array | Config |
**schema属性说明**
**Config**
| 参数名称 | 参数说明 | 类型 | schema |
| ------------ | ------------------|--------|----------- |
|id | |integer(int32) | |
|name | |string | |
|value | |string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------------ | -------------------------------- |---------------------- |
| 200 | OK |Response«List«Config»»|
| 201 | Created ||
| 401 | Unauthorized ||
| 403 | Forbidden ||
| 404 | Not Found ||
## updateConfiguration
**接口描述**:
**接口地址**:`/admin/config`
**请求方式**`PUT`
**consumes**:`["application/json"]`
**produces**:`["*/*"]`
**请求参数**
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| ------------ | -------------------------------- |-----------|--------|----|--- |
|configs| configs | query | false |array | Config |
**响应示例**:
```json
{
"code": 0,
"msg": "",
"result": [
{
"id": 0,
"name": "",
"value": ""
}
]
}
```
**响应参数**:
| 参数名称 | 参数说明 | 类型 | schema |
| ------------ | -------------------|-------|----------- |
|code| |integer(int32) | integer(int32) |
|msg| |string | |
|result| |array | Config |
**schema属性说明**
**Config**
| 参数名称 | 参数说明 | 类型 | schema |
| ------------ | ------------------|--------|----------- |
|id | |integer(int32) | |
|name | |string | |
|value | |string | |
**响应状态**:
| 状态码 | 说明 | schema |
| ------------ | -------------------------------- |---------------------- |
| 200 | OK |Response«List«Config»»|
| 201 | Created ||
| 401 | Unauthorized ||
| 403 | Forbidden ||
| 404 | Not Found ||
# links-controller # links-controller
## all ## all
@@ -1946,8 +1649,8 @@
| 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema | | 参数名称 | 参数说明 | in | 是否必须 | 数据类型 | schema |
| ------------ | -------------------------------- |-----------|--------|----|--- | | ------------ | -------------------------------- |-----------|--------|----|--- |
|count| count | query | true |integer | | |count| count | query | true |integer | |
|deleted| deleted | query | false |boolean | |
|page| page | query | true |integer | | |page| page | query | true |integer | |
|deleted| deleted | query | false |boolean | |
**响应示例**: **响应示例**:

34
pom.xml
View File

@@ -6,7 +6,7 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version> <version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/>
</parent> </parent>
<groupId>cn.celess</groupId> <groupId>cn.celess</groupId>
<artifactId>blog</artifactId> <artifactId>blog</artifactId>
@@ -40,14 +40,14 @@
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>druid</artifactId> <artifactId>druid</artifactId>
<version>1.1.14</version> <version>1.2.6</version>
</dependency> </dependency>
<!-- lombok --> <!-- lombok -->
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>1.18.6</version> <version>1.18.20</version>
</dependency> </dependency>
@@ -67,12 +67,12 @@
<dependency> <dependency>
<groupId>com.youbenzi</groupId> <groupId>com.youbenzi</groupId>
<artifactId>MDTool</artifactId> <artifactId>MDTool</artifactId>
<version>1.2.3</version> <version>1.2.4</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.minidev</groupId> <groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId> <artifactId>json-smart</artifactId>
<version>2.3</version> <version>2.4.7</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
@@ -99,33 +99,33 @@
<dependency> <dependency>
<groupId>org.mybatis.spring.boot</groupId> <groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId> <artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version> <version>2.2.0</version>
</dependency> </dependency>
<!-- pageHelper --> <!-- pageHelper -->
<dependency> <dependency>
<groupId>com.github.pagehelper</groupId> <groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId> <artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.12</version> <version>1.3.0</version>
</dependency> </dependency>
<!-- protostuff序列化依赖 --> <!-- protostuff序列化依赖 -->
<dependency> <dependency>
<groupId>com.dyuproject.protostuff</groupId> <groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-core</artifactId> <artifactId>protostuff-core</artifactId>
<version>1.0.8</version> <version>1.1.6</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.dyuproject.protostuff</groupId> <groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId> <artifactId>protostuff-runtime</artifactId>
<version>1.0.8</version> <version>1.1.6</version>
</dependency> </dependency>
<!-- Ua解析--> <!-- Ua解析-->
<dependency> <dependency>
<groupId>eu.bitwalker</groupId> <groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId> <artifactId>UserAgentUtils</artifactId>
<version>1.20</version> <version>1.21</version>
</dependency> </dependency>
<dependency> <dependency>
@@ -145,12 +145,12 @@
<dependency> <dependency>
<groupId>com.squareup.okhttp3</groupId> <groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId> <artifactId>okhttp</artifactId>
<version>4.8.0</version> <version>4.9.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId> <artifactId>kotlin-stdlib</artifactId>
<version>1.3.72</version> <version>1.4.20</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
@@ -158,7 +158,7 @@
<dependency> <dependency>
<groupId>net.sourceforge.htmlunit</groupId> <groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId> <artifactId>htmlunit</artifactId>
<version>2.42.0</version> <version>2.45.0</version>
</dependency> </dependency>
@@ -178,17 +178,17 @@
<dependency> <dependency>
<groupId>javax.xml.bind</groupId> <groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId> <artifactId>jaxb-api</artifactId>
<version>2.3.0</version> <version>2.3.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.sun.xml.bind</groupId> <groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId> <artifactId>jaxb-impl</artifactId>
<version>2.3.0</version> <version>4.0.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.sun.xml.bind</groupId> <groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId> <artifactId>jaxb-core</artifactId>
<version>2.3.0</version> <version>2.3.0.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.activation</groupId> <groupId>javax.activation</groupId>
@@ -214,7 +214,7 @@
<plugin> <plugin>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId> <artifactId>kotlin-maven-plugin</artifactId>
<version>1.3.72</version> <version>1.5.10</version>
<executions> <executions>
<execution> <execution>
<id>compile</id> <id>compile</id>

View File

@@ -1,34 +1,20 @@
package cn.celess.blog; package cn.celess.blog;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.ApplicationArguments; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication; import org.springframework.boot.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 ConfigurableApplicationContext context; public static final Logger logger = LoggerFactory.getLogger(BlogApplication.class);
public static void main(String[] args) { public static void main(String[] args) {
context = SpringApplication.run(BlogApplication.class, args); 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

@@ -1,59 +0,0 @@
package cn.celess.blog.configuration;
import cn.celess.blog.enmu.ConfigKeyEnum;
import cn.celess.blog.entity.Config;
import cn.celess.blog.mapper.ConfigMapper;
import cn.celess.blog.service.fileserviceimpl.LocalFileServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author : xiaohai
* @date : 2020/10/16 16:00
* @desc :
*/
@Component
@Slf4j
public class ApplicationListener implements ApplicationRunner {
@Autowired
ConfigMapper configMapper;
@Autowired
Environment env;
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("博客启动!");
// 设置初始值
setProperty(ConfigKeyEnum.FILE_QINIU_SECRET_KEY);
setProperty(ConfigKeyEnum.FILE_QINIU_ACCESS_KEY);
setProperty(ConfigKeyEnum.FILE_QINIU_BUCKET);
setProperty(ConfigKeyEnum.BLOG_FILE_PATH);
List<Config> configurations = configMapper.getConfigurations()
.stream()
.filter(config -> config.getValue() != null && !"".equals(config.getValue()))
.collect(Collectors.toList());
configurations.forEach(config -> System.setProperty(config.getName(), config.getValue()));
log.debug("注入配置成功 {}", configurations.stream().map(Config::getName).collect(Collectors.toList()));
File path = new File(LocalFileServiceImpl.getPath(System.getProperty(ConfigKeyEnum.BLOG_FILE_PATH.getKey())));
if (!path.exists() && !path.mkdirs()) {
throw new IllegalAccessException("创建数据目录失败==>" + path.getAbsolutePath());
}
}
private void setProperty(ConfigKeyEnum e) {
String property = env.getProperty(e.getKey());
if (property != null) {
System.setProperty(e.getKey(), property);
}
}
}

View File

@@ -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;
}
}

View File

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

@@ -2,10 +2,10 @@ 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.FileResponse; import cn.celess.blog.entity.model.QiniuResponse;
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.FileService; import cn.celess.blog.service.QiniuService;
import cn.celess.blog.util.HttpUtil; import cn.celess.blog.util.HttpUtil;
import cn.celess.blog.util.RedisUserUtil; import cn.celess.blog.util.RedisUserUtil;
import cn.celess.blog.util.RedisUtil; import cn.celess.blog.util.RedisUtil;
@@ -42,7 +42,7 @@ public class CommonController {
@Autowired @Autowired
CountService countService; CountService countService;
@Autowired @Autowired
FileService fileService; QiniuService qiniuService;
@Autowired @Autowired
RedisUtil redisUtil; RedisUtil redisUtil;
@Autowired @Autowired
@@ -161,10 +161,10 @@ 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())) {
FileResponse fileResponse = fileService.getFileManager().uploadFile(file.getInputStream(), "img_" + System.currentTimeMillis() + mime); QiniuResponse qiniuResponse = qiniuService.uploadFile(file.getInputStream(), "img_" + System.currentTimeMillis() + mime);
map.put("success", 1); map.put("success", 1);
map.put("message", "上传成功"); map.put("message", "上传成功");
map.put("url", "http://cdn.celess.cn/" + fileResponse.key); map.put("url", "http://cdn.celess.cn/" + qiniuResponse.key);
response.getWriter().println(mapper.writeValueAsString(map)); 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;
@@ -208,12 +208,12 @@ public class CommonController {
assert fileName != null; assert fileName != null;
String mime = fileName.substring(fileName.lastIndexOf(".")); String mime = fileName.substring(fileName.lastIndexOf("."));
String name = fileName.replace(mime, "").replaceAll(" ", ""); String name = fileName.replace(mime, "").replaceAll(" ", "");
FileResponse fileResponse = fileService.getFileManager().uploadFile(file.getInputStream(), "file_" + name + '_' + System.currentTimeMillis() + mime); QiniuResponse qiniuResponse = qiniuService.uploadFile(file.getInputStream(), "file_" + name + '_' + System.currentTimeMillis() + mime);
resp.put("originalFilename", fileName); resp.put("originalFilename", fileName);
resp.put("success", fileResponse != null); resp.put("success", qiniuResponse != null);
if (fileResponse != null) { if (qiniuResponse != null) {
resp.put("host", "http://cdn.celess.cn/"); resp.put("host", "http://cdn.celess.cn/");
resp.put("path", fileResponse.key); resp.put("path", qiniuResponse.key);
} }
result.add(resp); result.add(resp);
} }

View File

@@ -1,39 +0,0 @@
package cn.celess.blog.controller;
import cn.celess.blog.entity.Config;
import cn.celess.blog.entity.Response;
import cn.celess.blog.mapper.ConfigMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author : xiaohai
* @date : 2020/10/16 20:56
* @desc : 配置管理接口
*/
@RestController
public class ConfigController {
@Autowired
ConfigMapper configMapper;
@GetMapping("/admin/config")
public Response<List<Config>> getConfiguration() {
return Response.success(configMapper.getConfigurations());
}
@PutMapping("/admin/config")
public Response<List<Config>> updateConfiguration(@RequestBody List<Config> configs) {
configs.forEach(config -> configMapper.updateConfiguration(config));
configs.forEach(config -> System.setProperty(config.getName(), config.getValue()));
return Response.success(configMapper.getConfigurations());
}
@PostMapping("/admin/config")
public Response<List<Config>> addConfiguration(@RequestBody List<Config> configs) {
configs.forEach(config -> configMapper.addConfiguration(config));
configs.forEach(config -> System.setProperty(config.getName(), config.getValue()));
return Response.success(configMapper.getConfigurations());
}
}

View File

@@ -1,78 +0,0 @@
package cn.celess.blog.controller;
import cn.celess.blog.BlogApplication;
import cn.celess.blog.enmu.ConfigKeyEnum;
import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.entity.Config;
import cn.celess.blog.entity.InstallParam;
import cn.celess.blog.entity.Response;
import cn.celess.blog.exception.MyException;
import cn.celess.blog.mapper.ConfigMapper;
import cn.celess.blog.service.InstallService;
import cn.celess.blog.util.RegexUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.validation.Valid;
import java.util.Map;
/**
* @author : xiaohai
* @date : 2020/10/18 15:36
* @desc :
*/
@Slf4j
@Controller
@Validated
public class InstallController {
@Autowired
InstallService installService;
@Autowired
ConfigMapper configMapper;
@GetMapping("/is_install")
@ResponseBody
public Response<Map<String, Object>> isInstall() {
Map<String, Object> install = installService.isInstall();
return Response.success(install);
}
@PostMapping("/install")
@ResponseBody
public Response<Object> install(@Valid @RequestBody InstallParam installParam) {
if (!RegexUtil.emailMatch(installParam.getEmail())) {
throw new MyException(ResponseEnum.PARAMETERS_EMAIL_ERROR);
}
if (!RegexUtil.pwdMatch(installParam.getPassword())) {
throw new MyException(ResponseEnum.PARAMETERS_PWD_ERROR);
}
return Response.success(installService.install(installParam));
}
@GetMapping("/default_config")
@ResponseBody
public Response<String> defaultConfig() {
return null;
}
@GetMapping("/install")
public String install() {
Config configuration = configMapper.getConfiguration(ConfigKeyEnum.BLOG_INSTALLED.getKey());
if (Boolean.parseBoolean(configuration.getValue())) {
return "index.html";
}
log.info("博客第一次运行,还未安装");
return "install.html";
}
}

View File

@@ -1,37 +0,0 @@
package cn.celess.blog.enmu;
/**
* @author : xiaohai
* @date : 2020/10/16 16:41
* @desc :
*/
public enum ConfigKeyEnum {
/**
* 枚举
*/
FILE_TYPE("file.type"),
FILE_QINIU_ACCESS_KEY("file.qiniu.accessKey"),
FILE_QINIU_SECRET_KEY("file.qiniu.secretKey"),
FILE_QINIU_BUCKET("file.qiniu.bucket"),
FILE_LOCAL_DIRECTORY_PATH("file.local.directoryPath"),
BLOG_FILE_PATH("blog.file.path"),
BLOG_INSTALLED("blog.installed"),
DB_TYPE("db.type"),
DB_URL("spring.datasource.url"),
DB_USERNAME("spring.datasource.username"),
DB_PASSWORD("spring.datasource.password"),
DB_DRIVER_CLASS_NAME("spring.datasource.driver-class-name"),
BLOG_DB_PATH("blog.db.path");
private final String key;
ConfigKeyEnum(String key) {
this.key = key;
}
public String getKey() {
return key;
}
}

View File

@@ -1,26 +0,0 @@
package cn.celess.blog.entity;
import cn.celess.blog.enmu.ConfigKeyEnum;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author : xiaohai
* @date : 2020/10/16 15:24
* @desc :
*/
@Data
@NoArgsConstructor
public class Config {
private Integer id;
private String name;
private String value;
public Config(String name) {
this.name = name;
}
public Config(ConfigKeyEnum e) {
this.name = e.getKey();
}
}

View File

@@ -1,38 +0,0 @@
package cn.celess.blog.entity;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @author : xiaohai
* @date : 2020/10/18 14:52
* @desc :
*/
@Data
public class InstallParam {
@NotBlank(message = "数据库类型不可为空")
private String dbType;
@NotBlank(message = "数据库主机不可为空")
private String dbHost;
@NotBlank(message = "数据库名称不可为空")
private String dbName;
@NotBlank(message = "数据库用户名不可为空")
private String dbUsername;
@NotBlank(message = "数据库密码不可为空")
private String dbPassword;
/**
* user 相关
*/
@NotBlank(message = "用户邮箱地址不可为空")
private String email;
@NotBlank(message = "用户密码不可为空")
private String password;
}

View File

@@ -1,25 +0,0 @@
package cn.celess.blog.entity.model;
/**
* @author : xiaohai
* @date : 2020/10/15 22:16
* @desc :
*/
public class FileInfo {
/**
* 文件名
*/
public String key;
/**
* 文件hash值
*/
public String hash;
/**
* 文件大小,单位:字节
*/
public long size;
/**
* 文件上传时间单位为100纳秒
*/
public long uploadTime;
}

View File

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

View File

@@ -10,9 +10,7 @@ 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;
@@ -20,10 +18,6 @@ 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
@@ -47,32 +41,27 @@ 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);
} }
// 发送错误信息到邮箱 // 发送错误信息到邮箱
@@ -81,7 +70,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);
} }
/** /**

View File

@@ -1,6 +1,7 @@
package cn.celess.blog.mapper; package cn.celess.blog.mapper;
import cn.celess.blog.entity.ArticleTag; import cn.celess.blog.entity.ArticleTag;
import cn.celess.blog.entity.Tag;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@@ -27,6 +28,8 @@ public interface ArticleTagMapper {
List<ArticleTag> findAllByArticleId(Long articleId); List<ArticleTag> findAllByArticleId(Long articleId);
List<Tag> findTagByArticleId(Long articleId);
int deleteMultiById(List<ArticleTag> articleTags); int deleteMultiById(List<ArticleTag> articleTags);
List<ArticleTag> findArticleByTag(Long tagId); List<ArticleTag> findArticleByTag(Long tagId);

View File

@@ -1,55 +0,0 @@
package cn.celess.blog.mapper;
import cn.celess.blog.entity.Config;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author : xiaohai
* @date : 2020/10/16 15:24
* @desc :
*/
@Mapper
@Repository
public interface ConfigMapper {
/**
* 获取单个配置
*
* @param key 配置名
* @return 配置
*/
Config getConfiguration(String key);
/**
* 更新配置
*
* @param c 配置
* @return 改变数据行数
*/
int updateConfiguration(Config c);
/**
* 获取所有配置
*
* @return 所有配置
*/
List<Config> getConfigurations();
/**
* 新增配置
*
* @param c 配置
* @return 改变行数
*/
int addConfiguration(Config c);
/**
* 删除配置
*
* @param id 主键id
* @return 改变行数
*/
int deleteConfiguration(int id);
}

View File

@@ -1,40 +0,0 @@
package cn.celess.blog.service;
import cn.celess.blog.entity.model.FileInfo;
import cn.celess.blog.entity.model.FileResponse;
import org.springframework.stereotype.Service;
import java.io.InputStream;
import java.util.List;
/**
* @author : xiaohai
* @date : 2020/10/15 18:19
* @desc : 文件管理器 定义操作文件的方法
*/
@Service
public interface FileManager {
/**
* 上传文件到文件存储容器中
*
* @param is 文件流
* @param fileName 文件名
* @return FileResponse
*/
FileResponse uploadFile(InputStream is, String fileName);
/**
* 获取文件列表
*
* @return 文件信息
*/
List<FileInfo> getFileList();
/**
* 删除文件
*
* @param fileName 文件名
* @return 是否删除成功
*/
boolean deleteFile(String fileName);
}

View File

@@ -1,18 +0,0 @@
package cn.celess.blog.service;
import org.springframework.stereotype.Service;
/**
* @author : xiaohai
* @date : 2019/04/25 18:15
*/
@Service("fileService")
@FunctionalInterface
public interface FileService {
/**
* 获取文件管理器
*
* @return 文件管理器 可以操作文件
*/
FileManager getFileManager();
}

View File

@@ -1,20 +0,0 @@
package cn.celess.blog.service;
import cn.celess.blog.entity.InstallParam;
import org.springframework.stereotype.Service;
import javax.validation.constraints.NotNull;
import java.util.Map;
/**
* @author : xiaohai
* @date : 2020/10/23 16:22
* @desc :
*/
@Service
public interface InstallService {
Map<String, Object> isInstall();
Map<String, Object> install(@NotNull InstallParam installParam);
}

View File

@@ -0,0 +1,31 @@
package cn.celess.blog.service;
import cn.celess.blog.entity.model.QiniuResponse;
import com.qiniu.storage.model.FileInfo;
import org.springframework.stereotype.Service;
import java.io.InputStream;
/**
* @author : xiaohai
* @date : 2019/04/25 18:15
*/
@Service
public interface QiniuService {
/**
* 上传文件
*
* @param is InputStream流
* @param fileName 文件名
* @return 响应数据
*/
QiniuResponse uploadFile(InputStream is, String fileName);
/**
* 获取文件列表
*
* @return 文件列表
*/
FileInfo[] getFileList();
}

View File

@@ -1,36 +0,0 @@
package cn.celess.blog.service.fileserviceimpl;
import cn.celess.blog.enmu.ConfigKeyEnum;
import cn.celess.blog.service.FileManager;
import cn.celess.blog.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @author : xiaohai
* @date : 2020/10/15 18:52
* @desc : 提供文件管理器的服务
*/
@Slf4j
@Service("fileServiceImpl")
public class FileServiceImpl implements FileService {
@Resource(name = "qiniuFileServiceImpl")
FileManager qiniuFileManager;
@Resource(name = "localFileServiceImpl")
FileManager localFileServiceImpl;
@Override
public FileManager getFileManager() {
String property = System.getProperty(ConfigKeyEnum.FILE_TYPE.getKey());
log.info("获取到{}:{}", ConfigKeyEnum.FILE_TYPE.getKey(), property);
if ("qiniu".equals(property)){
return qiniuFileManager;
}else if ("local".equals(property)){
return localFileServiceImpl;
}
return localFileServiceImpl;
}
}

View File

@@ -1,104 +0,0 @@
package cn.celess.blog.service.fileserviceimpl;
import cn.celess.blog.enmu.ConfigKeyEnum;
import cn.celess.blog.entity.model.FileInfo;
import cn.celess.blog.entity.model.FileResponse;
import cn.celess.blog.service.FileManager;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
/**
* @author : xiaohai
* @date : 2020/10/16 14:39
* @desc :
*/
@Slf4j
@Service("localFileServiceImpl")
public class LocalFileServiceImpl implements FileManager {
private static String path = null;
@SneakyThrows
@Override
public FileResponse uploadFile(InputStream is, String fileName) {
if (path == null) {
path = System.getProperty(ConfigKeyEnum.FILE_LOCAL_DIRECTORY_PATH.getKey());
}
// 判断文件夹是否存在
File directory = new File(getPath(path));
if (!directory.exists() && directory.mkdirs()) {
log.info("不存在文件夹,创建文件夹=>{}", directory.getAbsolutePath());
}
log.info("上传文件 {}", fileName);
// 存储文件
File file1 = new File(getPath(path) + File.separator + fileName);
FileOutputStream fos = new FileOutputStream(file1);
byte[] cache = new byte[1024 * 100];
int len = 0;
FileResponse fileResponse = new FileResponse();
while ((len = is.read(cache)) != -1) {
fileResponse.size += len;
fos.write(cache, 0, len);
}
fos.flush();
fos.close();
is.close();
fileResponse.key = URLEncoder.encode(fileName, "UTF-8");
fileResponse.type = "local";
return fileResponse;
}
@SneakyThrows
@Override
public List<FileInfo> getFileList() {
if (path == null) {
path = System.getProperty(ConfigKeyEnum.FILE_LOCAL_DIRECTORY_PATH.getKey());
}
File file = new File(getPath(path));
File[] files = file.listFiles();
List<FileInfo> fileInfoList = new ArrayList<>();
if (files == null) {
return null;
}
for (File file1 : files) {
FileInfo fileInfo = new FileInfo();
fileInfo.key = URLEncoder.encode(file1.getName(), "UTF-8");
fileInfo.size = file1.length();
BasicFileAttributes basicFileAttributes = Files.readAttributes(file1.toPath(), BasicFileAttributes.class);
fileInfo.uploadTime = basicFileAttributes.creationTime().toMillis();
fileInfoList.add(fileInfo);
}
return fileInfoList;
}
@Override
public boolean deleteFile(String fileName) {
if (path == null) {
path = System.getProperty(ConfigKeyEnum.FILE_LOCAL_DIRECTORY_PATH.getKey());
}
File file = new File(getPath(path) + File.separator + fileName);
return file.delete();
}
public static String getPath(String path) {
if (path == null) {
return "";
}
String pathCop = path.replaceAll("//", File.separator);
if (path.startsWith("~")) {
// 家目录
pathCop = path.replaceFirst("~", "");
pathCop = System.getProperty("user.home") + pathCop;
}
return pathCop;
}
}

View File

@@ -1,120 +0,0 @@
package cn.celess.blog.service.fileserviceimpl;
import cn.celess.blog.enmu.ConfigKeyEnum;
import cn.celess.blog.entity.model.FileInfo;
import cn.celess.blog.entity.model.FileResponse;
import cn.celess.blog.service.FileManager;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author : xiaohai
* @date : 2019/04/25 18:15
*/
@Service("qiniuFileServiceImpl")
public class QiniuFileServiceImpl implements FileManager {
private static final Configuration cfg = new Configuration(Zone.zone2());
private static UploadManager uploadManager;
private static BucketManager bucketManager;
private static Auth auth;
private String bucket;
/**
* todo :: 添加reload 方法 配置修改重新创建对象
*/
private void init() {
String accessKey = System.getProperty(ConfigKeyEnum.FILE_QINIU_ACCESS_KEY.getKey());
String secretKey = System.getProperty(ConfigKeyEnum.FILE_QINIU_SECRET_KEY.getKey());
this.bucket = System.getProperty(ConfigKeyEnum.FILE_QINIU_BUCKET.getKey());
if (auth == null || uploadManager == null || bucketManager == null) {
auth = Auth.create(accessKey, secretKey);
uploadManager = new UploadManager(cfg);
bucketManager = new BucketManager(auth, cfg);
}
}
@Override
public FileResponse uploadFile(InputStream is, String fileName) {
init();
//文件存在则删除文件
if (continueFile(fileName)) {
try {
System.out.println(bucketManager.delete(bucket, fileName).toString());
} catch (QiniuException e) {
e.printStackTrace();
}
}
//上传
try {
Response response = uploadManager.put(is, fileName, auth.uploadToken(bucket), null, null);
FileResponse fileResponse = new FileResponse();
StringMap stringMap = response.jsonToMap();
fileResponse.key = (String) stringMap.get("key");
fileResponse.type = "qiniu";
fileResponse.size = 0;
fileResponse.hash = (String) stringMap.get("hash");
return fileResponse;
} catch (QiniuException e) {
Response r = e.response;
System.err.println(r.toString());
return null;
}
}
@Override
public List<FileInfo> getFileList() {
init();
List<FileInfo> infoList = null;
BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(bucket, "", 1000, "");
while (fileListIterator.hasNext()) {
//处理获取的file list结果
infoList = new ArrayList<com.qiniu.storage.model.FileInfo>(Arrays.asList(fileListIterator.next()))
.stream()
.map(item -> {
FileInfo fileInfo = new FileInfo();
fileInfo.key = item.key;
fileInfo.hash = item.hash;
fileInfo.size = item.fsize;
fileInfo.uploadTime = item.putTime;
return fileInfo;
})
.collect(Collectors.toList());
}
return infoList;
}
@SneakyThrows
@Override
public boolean deleteFile(String fileName) {
init();
Response response = bucketManager.delete(bucket, fileName);
return "".equals(response.bodyString());
}
private boolean continueFile(String key) {
List<FileInfo> fileList = getFileList();
for (FileInfo fileInfo : fileList) {
if (key.equals(fileInfo.key)) {
return true;
}
}
return false;
}
}

View File

@@ -279,21 +279,20 @@ public class ArticleServiceImpl implements ArticleService {
*/ */
@Override @Override
public PageData<ArticleModel> adminArticles(int count, int page, Boolean deleted) { public PageData<ArticleModel> adminArticles(int count, int page, Boolean deleted) {
PageHelper.startPage(page, count);
List<Article> articleList = articleMapper.findAll(); 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; List<Article> collect;
if (deleted != null) { if (deleted != null) {
collect = articleList.stream().filter(article -> article.isDeleted() == deleted).collect(Collectors.toList()); collect = articleList.stream().filter(article -> article.isDeleted() == deleted).collect(Collectors.toList());
} else { } else {
collect = articleList; collect = articleList;
} }
pageData.setTotal(collect.size());
List<ArticleModel> articleModels = collect.stream() List<ArticleModel> articleModels = collect.stream()
.peek(article -> article.setMdContent(null)) .peek(article -> article.setMdContent(null))
.map(ModalTrans::article) .map(ModalTrans::article)
.skip((page - 1) * count)
.limit(count)
.collect(Collectors.toList()); .collect(Collectors.toList());
pageData.setList(articleModels); pageData.setList(articleModels);

View File

@@ -1,118 +0,0 @@
package cn.celess.blog.service.serviceimpl;
import cn.celess.blog.BlogApplication;
import cn.celess.blog.enmu.ConfigKeyEnum;
import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.entity.Config;
import cn.celess.blog.entity.InstallParam;
import cn.celess.blog.entity.User;
import cn.celess.blog.exception.MyException;
import cn.celess.blog.mapper.ConfigMapper;
import cn.celess.blog.mapper.UserMapper;
import cn.celess.blog.service.InstallService;
import cn.celess.blog.service.fileserviceimpl.LocalFileServiceImpl;
import cn.celess.blog.util.MD5Util;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
/**
* @author : xiaohai
* @date : 2020/10/23 16:23
* @desc :
*/
@Slf4j
@Service
public class InstallServiceImpl implements InstallService {
public static final String MYSQL_DRIVER_CLASS_NAME = "com.mysql.cj.jdbc.Driver";
public static final String H2_DRIVER_CLASS_NAME = "org.h2.Driver";
@Autowired
ConfigMapper configMapper;
@Autowired
UserMapper userMapper;
@Override
public Map<String, Object> isInstall() {
Config installed = configMapper.getConfiguration(ConfigKeyEnum.BLOG_INSTALLED.getKey());
Boolean isInstall = Boolean.valueOf(installed.getValue());
Map<String, Object> result = new HashMap<>(3);
result.put("is_install", isInstall);
if (isInstall) {
Map<String, String> configMap = configMapper.getConfigurations()
.stream()
.filter(config -> config.getValue() != null)
.collect(Collectors.toMap(Config::getName, Config::getValue));
result.put(ConfigKeyEnum.FILE_TYPE.getKey(), configMap.get(ConfigKeyEnum.FILE_TYPE.getKey()));
result.put(ConfigKeyEnum.DB_TYPE.getKey(), configMap.get(ConfigKeyEnum.DB_TYPE.getKey()));
}
return result;
}
@SneakyThrows
@Override
@Transactional(rollbackFor = Exception.class)
public Map<String, Object> install(@NotNull InstallParam installParam) {
User user = new User(installParam.getEmail(), MD5Util.getMD5(installParam.getPassword()));
userMapper.addUser(user);
userMapper.setUserRole(user.getId(), "admin");
Config install = configMapper.getConfiguration(ConfigKeyEnum.BLOG_INSTALLED.getKey());
boolean isInstall = Boolean.parseBoolean(install.getValue());
if (isInstall) {
throw new MyException(ResponseEnum.FAILURE, "已经安装过了");
}
Config config = new Config(ConfigKeyEnum.DB_TYPE);
config.setValue(installParam.getDbType());
Properties properties = new Properties();
StringBuilder urlSb = new StringBuilder();
if ("h2".equals(installParam.getDbType())) {
properties.setProperty(ConfigKeyEnum.DB_DRIVER_CLASS_NAME.getKey(), H2_DRIVER_CLASS_NAME);
urlSb.append("jdbc:h2:");
} else {
properties.setProperty(ConfigKeyEnum.DB_DRIVER_CLASS_NAME.getKey(), MYSQL_DRIVER_CLASS_NAME);
urlSb.append("jdbc:mysql:");
}
// TODO ::
urlSb.append(installParam.getDbHost()).append('/').append(installParam.getDbName());
properties.setProperty(ConfigKeyEnum.DB_URL.getKey(), urlSb.toString());
properties.setProperty(ConfigKeyEnum.DB_USERNAME.getKey(), installParam.getDbUsername());
properties.setProperty(ConfigKeyEnum.DB_PASSWORD.getKey(), installParam.getDbPassword());
Config configuration = configMapper.getConfiguration(ConfigKeyEnum.BLOG_DB_PATH.getKey());
File file = new File(LocalFileServiceImpl.getPath(configuration.getValue()));
if (!file.exists() && file.createNewFile()) {
log.info("创建数据库配置文件: {}", file.getAbsolutePath());
}
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file);
properties.load(fis);
configMapper.addConfiguration(config);
properties.store(fos, "DB CONFIG");
install.setValue(Boolean.valueOf(true).toString());
configMapper.updateConfiguration(install);
log.info("重启...");
// 重启
BlogApplication.restart();
return null;
}
}

View File

@@ -0,0 +1,87 @@
package cn.celess.blog.service.serviceimpl;
import cn.celess.blog.entity.model.QiniuResponse;
import cn.celess.blog.service.QiniuService;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.InputStream;
/**
* @author : xiaohai
* @date : 2019/04/25 18:15
*/
@Service
public class QiniuServiceImpl implements QiniuService {
private static final Configuration cfg = new Configuration(Zone.zone2());
private static UploadManager uploadManager;
private static BucketManager bucketManager;
private static Auth auth;
@Value("${qiniu.accessKey}")
private String accessKey;
@Value("${qiniu.secretKey}")
private String secretKey;
@Value("${qiniu.bucket}")
private String bucket;
private void init() {
if (auth == null || uploadManager == null || bucketManager == null) {
auth = Auth.create(accessKey, secretKey);
uploadManager = new UploadManager(cfg);
bucketManager = new BucketManager(auth, cfg);
}
}
@Override
public QiniuResponse uploadFile(InputStream is, String fileName) {
init();
//文件存在则删除文件
if (continueFile(fileName)) {
try {
System.out.println(bucketManager.delete(bucket, fileName).toString());
} catch (QiniuException e) {
e.printStackTrace();
}
}
//上传
try {
Response response = uploadManager.put(is, fileName, auth.uploadToken(bucket), null, null);
return response.jsonToObject(QiniuResponse.class);
} catch (QiniuException e) {
Response r = e.response;
System.err.println(r.toString());
return null;
}
}
@Override
public FileInfo[] getFileList() {
init();
BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(bucket, "", 1000, "");
FileInfo[] items = null;
while (fileListIterator.hasNext()) {
//处理获取的file list结果
items = fileListIterator.next();
}
return items;
}
private boolean continueFile(String key) {
FileInfo[] allFile = getFileList();
for (FileInfo fileInfo : allFile) {
if (key.equals(fileInfo.key)) {
return true;
}
}
return false;
}
}

View File

@@ -5,15 +5,15 @@ import cn.celess.blog.enmu.RoleEnum;
import cn.celess.blog.enmu.UserAccountStatusEnum; 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;
@@ -24,7 +24,6 @@ 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;
@@ -46,8 +45,8 @@ public class UserServiceImpl implements UserService {
HttpServletRequest request; HttpServletRequest request;
@Autowired @Autowired
MailService mailService; MailService mailService;
@Resource(name = "fileServiceImpl") @Autowired
FileService fileService; QiniuService qiniuService;
@Autowired @Autowired
RedisUtil redisUtil; RedisUtil redisUtil;
@Autowired @Autowired
@@ -186,7 +185,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();
FileResponse upload = fileService.getFileManager().uploadFile(is, user.getEmail() + "_" + user.getId() + mime.toLowerCase()); QiniuResponse upload = qiniuService.uploadFile(is, user.getEmail() + "_" + user.getId() + mime.toLowerCase());
user.setAvatarImgUrl(upload.key); user.setAvatarImgUrl(upload.key);
userMapper.updateAvatarImgUrl(upload.key, user.getId()); userMapper.updateAvatarImgUrl(upload.key, user.getId());
redisUserUtil.set(user); redisUserUtil.set(user);

View 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;
}
}

View File

@@ -30,6 +30,8 @@ public class JwtUtil {
*/ */
public static final long EXPIRATION_SHORT_TIME = 7200000; public static final long EXPIRATION_SHORT_TIME = 7200000;
private static final String CLAIM_KEY_USERNAME = "sub"; 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 秘钥需自行设置不可泄露 * JWT 秘钥需自行设置不可泄露
*/ */
@@ -48,7 +50,7 @@ public class JwtUtil {
} }
public String updateTokenDate(String token) { 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() return Jwts.builder()
.setClaims(claims) .setClaims(claims)
.setExpiration(new Date(claims.getExpiration().getTime() + EXPIRATION_SHORT_TIME)) .setExpiration(new Date(claims.getExpiration().getTime() + EXPIRATION_SHORT_TIME))
@@ -60,7 +62,7 @@ public class JwtUtil {
* 获取token是否过期 * 获取token是否过期
*/ */
public Boolean isTokenExpired(String token) { public Boolean isTokenExpired(String token) {
Date expiration = getExpirationDateFromToken(token); Date expiration = getExpirationDateFromToken(getJwtString(token));
return expiration == null || expiration.before(new Date()); return expiration == null || expiration.before(new Date());
} }
@@ -68,7 +70,7 @@ public class JwtUtil {
* 根据token获取username * 根据token获取username
*/ */
public String getUsernameFromToken(String token) { public String getUsernameFromToken(String token) {
Claims claims = getClaimsFromToken(token); Claims claims = getClaimsFromToken(getJwtString(token));
return claims == null ? null : claims.getSubject(); return claims == null ? null : claims.getSubject();
} }
@@ -76,7 +78,7 @@ public class JwtUtil {
* 获取token的过期时间 * 获取token的过期时间
*/ */
public Date getExpirationDateFromToken(String token) { public Date getExpirationDateFromToken(String token) {
Claims claims = getClaimsFromToken(token); Claims claims = getClaimsFromToken(getJwtString(token));
return claims == null ? null : claims.getExpiration(); return claims == null ? null : claims.getExpiration();
} }
@@ -88,7 +90,7 @@ public class JwtUtil {
try { try {
claims = Jwts.parser() claims = Jwts.parser()
.setSigningKey(SECRET) .setSigningKey(SECRET)
.parseClaimsJws(token) .parseClaimsJws(getJwtString(token))
.getBody(); .getBody();
} catch (ExpiredJwtException e) { } catch (ExpiredJwtException e) {
log.info("JWT令牌过期"); log.info("JWT令牌过期");
@@ -107,4 +109,9 @@ public class JwtUtil {
return claims; return claims;
} }
private String getJwtString(String token) {
if (token == null) return token;
return token.replaceFirst(BEARER_PREFIX_UPPER, "").replace(BEARER_PREFIX_LOWER, "");
}
} }

View File

@@ -0,0 +1,2 @@
org.springframework.boot.env.EnvironmentPostProcessor=cn.celess.blog.configuration.CommonEnvPostProcessor
org.springframework.context.ApplicationListener=cn.celess.blog.configuration.CommonEnvPostProcessor

View File

@@ -1,65 +0,0 @@
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:h2:~/blog/db
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.platform=h2
spring.datasource.sql-script-encoding=utf-8
spring.datasource.initialization-mode=never
spring.datasource.schema=classpath:sql/schema-h2.sql
spring.datasource.data=classpath:sql/data.sql
spring.h2.console.path=/h2-console
spring.h2.console.enabled=true
# 生成JWT时候的密钥
jwt.secret=11111222223333444455556667778888
# sitemap 存放地址
sitemap.path=/www/wwwroot/celess.cn/sitemap.xml
############### email ##############
spring.mail.host=smtp.163.com
spring.mail.username=
spring.mail.password=
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.default-encoding=UTF-8
spring.mail.port=465
spring.mail.properties.mail.smtp.socketFactory.port=465
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.smtp.socketFactory.fallback=false
################## mybatis ##################
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=cn.celess.blog.entity
pagehelper.helper-dialect=mysql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql
############### redis ##############
# REDIS (RedisProperties)
# Redis数据库索引默认为0
spring.redis.database=1
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口 解决端口冲突 防止使用本地的redis
spring.redis.port=6379
# Redis服务器连接密码默认为空
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=-1
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=5000

View File

@@ -1,26 +1,26 @@
server.port=8081 server.port=8081
# 七牛的密钥配置 # ???????
file.qiniu.accessKey= qiniu.accessKey=
file.qiniu.secretKey= qiniu.secretKey=
file.qiniu.bucket= qiniu.bucket=
# sitemap 存放地址 # sitemap ????
sitemap.path= sitemap.path=
# 生成JWT时候的密钥 # ??JWT?????
jwt.secret= jwt.secret=
spring.jpa.show-sql=false spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=update spring.jpa.hibernate.ddl-auto=update
# 上传单个文件的大小 # ?????????
spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-file-size=10MB
# 上传文件的总大小 # ????????
spring.servlet.multipart.max-request-size=10MB spring.servlet.multipart.max-request-size=10MB
##null字段不显示 ##null?????
spring.jackson.default-property-inclusion=non_null spring.jackson.default-property-inclusion=non_null
################# 数据库 ################## ################# ??? ##################
#请先填写下面的配置 #?????????
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url= spring.datasource.url=
spring.datasource.username= spring.datasource.username=
@@ -48,7 +48,7 @@ pagehelper.params=count=countSql
################ email ############## ################ email ##############
#请先填写下面的配置,不然可能运行不起来 #???????????????????
spring.mail.host= spring.mail.host=
spring.mail.username= spring.mail.username=
spring.mail.password= spring.mail.password=
@@ -62,23 +62,29 @@ spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFact
spring.mail.properties.mail.smtp.socketFactory.fallback=false 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?
spring.redis.database=0 spring.redis.database=0
# Redis服务器地址 # Redis?????
spring.redis.host= spring.redis.host=
# Redis服务器连接端口 # Redis???????
spring.redis.port=6379 spring.redis.port=6379
# Redis服务器连接密码(默认为空) # Redis?????????????
spring.redis.password= spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制) # ????????????????????
spring.redis.jedis.pool.max-active=-1 spring.redis.jedis.pool.max-active=-1
# 连接池最大阻塞等待时间(使用负值表示没有限制) # ???????????????????????
spring.redis.jedis.pool.max-wait=-1 spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接 # ???????????
spring.redis.jedis.pool.max-idle=8 spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接 # ???????????
spring.redis.jedis.pool.min-idle=0 spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒) # ??????????
spring.redis.timeout=5000 spring.redis.timeout=5000

View File

@@ -1,12 +1,12 @@
server.port=8081 server.port=8081
# 七牛的密钥配置 # ???????
file.qiniu.accessKey=${QINIU_ACCESSKEY:null} qiniu.accessKey=
file.qiniu.secretKey=${QINIU_SECRETKEY:null} qiniu.secretKey=
file.qiniu.bucket=xiaohai qiniu.bucket=
# sitemap 存放地址 # sitemap ????
sitemap.path= sitemap.path=
# 生成JWT时候的密钥 # ??JWT?????
jwt.secret=sdaniod213k123123ipoeqowekqwe jwt.secret=sdaniod213k123123ipoeqowekqwe
##spring.jpa.show-sql=false ##spring.jpa.show-sql=false
@@ -14,15 +14,15 @@ jwt.secret=sdaniod213k123123ipoeqowekqwe
mybatis.type-handlers-package=cn.celess.blog.mapper.typehandler mybatis.type-handlers-package=cn.celess.blog.mapper.typehandler
logging.level.cn.celess.blog.mapper=debug logging.level.cn.celess.blog.mapper=debug
# 上传单个文件的大小 # ?????????
spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-file-size=10MB
# 上传文件的总大小 # ????????
spring.servlet.multipart.max-request-size=10MB spring.servlet.multipart.max-request-size=10MB
spring.jackson.default-property-inclusion=non_null spring.jackson.default-property-inclusion=non_null
################# 数据库 ################## ################# ??? ##################
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#h2 #h2
@@ -32,9 +32,10 @@ spring.datasource.username=sa
spring.datasource.password= spring.datasource.password=
spring.datasource.platform=h2
spring.datasource.sql-script-encoding=utf-8 spring.datasource.sql-script-encoding=utf-8
spring.datasource.initialization-mode=ALWAYS spring.datasource.initialization-mode=ALWAYS
spring.datasource.schema=classpath:sql/schema-h2.sql spring.datasource.schema=classpath:sql/schema_h2.sql
spring.datasource.data=classpath:sql/data.sql spring.datasource.data=classpath:sql/data.sql
@@ -49,6 +50,13 @@ pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql pagehelper.params=count=countSql
#### ??nginx??? ????ip
server.use-forward-headers = true
server.tomcat.remote-ip-header = X-Real-IP
server.tomcat.protocol-header = X-Forwarded-Proto
############### email ############## ############### email ##############
spring.mail.host=smtp.163.com spring.mail.host=smtp.163.com
spring.mail.username= spring.mail.username=
@@ -67,22 +75,21 @@ spring.mail.properties.mail.smtp.socketFactory.fallback=false
############### redis ############## ############### redis ##############
# REDIS (RedisProperties) # REDIS (RedisProperties)
# Redis数据库索引默认为0 # Redis?????????0?
spring.redis.database=1 spring.redis.database=1
# Redis服务器地址 # Redis?????
spring.redis.host=127.0.0.1 spring.redis.host=127.0.0.1
# Redis服务器连接端口 解决端口冲突 防止使用本地的redis # Redis??????? ?????? ???????redis
spring.redis.port=6380 spring.redis.port=6380
# Redis服务器连接密码(默认为空) # Redis?????????????
spring.redis.password= spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制) # ????????????????????
spring.redis.jedis.pool.max-active=-1 spring.redis.jedis.pool.max-active=-1
# 连接池最大阻塞等待时间(使用负值表示没有限制) # ???????????????????????
spring.redis.jedis.pool.max-wait=-1 spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接 # ???????????
spring.redis.jedis.pool.max-idle=8 spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接 # ???????????
spring.redis.jedis.pool.min-idle=0 spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒) # ??????????
spring.redis.timeout=5000 spring.redis.timeout=5000

View File

@@ -1,10 +1,7 @@
spring.profiles.active=easyDeploy spring.profiles.active=dev
#### ?????
####cn.celess.blog.service.serviceimpl.QiniuServiceImpl
logging.level.cn.celess.blog=debug logging.level.cn.celess.blog=debug
logging.level.cn.celess.blog.mapper=info logging.level.cn.celess.blog.mapper=info
#### 用于nginx的代理 获取真实ip ## ??openSource ??-test ?????? -prod????????
server.use-forward-headers = true
server.tomcat.remote-ip-header = X-Real-IP
server.tomcat.protocol-header = X-Forwarded-Proto
## 修改openSource 添加-test 文件用于测试 -prod文件用于线上发布

View File

@@ -64,6 +64,14 @@
and article_tag.t_id = tag_category.t_id and article_tag.t_id = tag_category.t_id
</select> </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 id="findOneById" resultMap="articleTagResultMap">
select * select *
from article_tag, from article_tag,

View File

@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.celess.blog.mapper.ConfigMapper">
<resultMap type="cn.celess.blog.entity.Config" id="ConfigMap">
<result property="id" column="conf_id" jdbcType="INTEGER"/>
<result property="name" column="conf_name" jdbcType="VARCHAR"/>
<result property="value" column="conf_value" jdbcType="VARCHAR"/>
</resultMap>
<!--查询单个-->
<select id="getConfiguration" resultMap="ConfigMap">
select conf_id,
conf_name,
conf_value
from config
where conf_name = #{key}
</select>
<!--查询指定行数据-->
<select id="getConfigurations" resultMap="ConfigMap">
select conf_id,
conf_name,
conf_value
from config
</select>
<!--新增所有列-->
<insert id="addConfiguration" keyProperty="id" useGeneratedKeys="true">
insert into config(conf_name, conf_value)
values (#{name}, #{value})
</insert>
<!--通过主键修改数据-->
<update id="updateConfiguration">
update config
set conf_value = #{value}
where conf_id = #{id}
</update>
<!--通过主键删除-->
<delete id="deleteConfiguration">
delete
from config
where conf_id = #{id}
</delete>
</mapper>

View File

@@ -19,8 +19,10 @@
<association property="category" column="a_category_id" javaType="cn.celess.blog.entity.TagCategory" <association property="category" column="a_category_id" javaType="cn.celess.blog.entity.TagCategory"
resultMap="cn.celess.blog.mapper.CategoryMapper.categoryResultMap"> resultMap="cn.celess.blog.mapper.CategoryMapper.categoryResultMap">
</association> </association>
<collection property="tags" ofType="cn.celess.blog.entity.TagCategory" <collection property="tags" ofType="cn.celess.blog.entity.Tag"
resultMap="cn.celess.blog.mapper.CategoryMapper.categoryResultMap"> select="cn.celess.blog.mapper.ArticleTagMapper.findTagByArticleId" column="a_id">
<id column="tagId" property="id"/>
<result column="tagName" property="name"/>
</collection> </collection>
</resultMap> </resultMap>
@@ -49,7 +51,8 @@
<result column="userAvatar" property="avatarImgUrl"/> <result column="userAvatar" property="avatarImgUrl"/>
<result column="userDisplayName" property="displayName"/> <result column="userDisplayName" property="displayName"/>
</association> </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"/> <id column="tagId" property="id"/>
<result column="tagName" property="name"/> <result column="tagName" property="name"/>
</collection> </collection>
@@ -119,11 +122,37 @@
</select> </select>
<select id="findAllByOpen" resultMap="articleViewResultMap"> <select id="findAllByOpen" resultMap="articleViewResultMap">
select * select article.a_id as articleId,
from articleView article.a_title as title,
where isOpen = #{isOpen} article.a_summary as summary,
and isDelete = false article.a_md_content as mdContent,
order by articleId desc article.a_url as url,
article.a_is_original as isOriginal,
article.a_reading_number as readingCount,
article.a_like as likeCount,
article.a_dislike as dislikeCount,
article.a_publish_date as publishDate,
article.a_update_date as updateDate,
article.a_is_open as isOpen,
category.t_id as categoryId,
category.t_name as categoryName,
user.u_id as authorId,
user.u_email as userEmail,
user.u_avatar as userAvatar,
user.u_display_name as userDisplayName,
article.is_delete as isDelete
from article,
tag_category as category,
article_tag,
user
where article.a_is_open = #{isOpen}
and article.is_delete = false
and article.a_id = article_tag.a_id
and article.a_category_id = category.t_id
and category.is_category = true
and article.a_author_id = user.u_id
group by article.a_id
order by article.a_id desc
</select> </select>
@@ -152,9 +181,35 @@
<select id="findAll" resultMap="articleViewResultMap"> <select id="findAll" resultMap="articleViewResultMap">
select * select article.a_id as articleId,
from articleView article.a_title as title,
order by articleId desc article.a_summary as summary,
article.a_md_content as mdContent,
article.a_url as url,
article.a_is_original as isOriginal,
article.a_reading_number as readingCount,
article.a_like as likeCount,
article.a_dislike as dislikeCount,
article.a_publish_date as publishDate,
article.a_update_date as updateDate,
article.a_is_open as isOpen,
category.t_id as categoryId,
category.t_name as categoryName,
user.u_id as authorId,
user.u_email as userEmail,
user.u_avatar as userAvatar,
user.u_display_name as userDisplayName,
article.is_delete as isDelete
from article,
tag_category as category,
article_tag,
user
where article.a_id = article_tag.a_id
and article.a_category_id = category.t_id
and category.is_category = true
and article.a_author_id = user.u_id
group by article.a_id
order by article.a_id desc
</select> </select>
@@ -169,7 +224,8 @@
from articleView from articleView
where articleId = (select max(articleId) where articleId = (select max(articleId)
from articleView from articleView
where articleId &lt; #{id} where isOpen = true
and articleId &lt; #{id}
) )
</select> </select>
<select id="getNextArticle" resultMap="articleViewResultMap"> <select id="getNextArticle" resultMap="articleViewResultMap">
@@ -177,7 +233,8 @@
from articleView from articleView
where articleId = (select min(articleId) where articleId = (select min(articleId)
from articleView from articleView
where articleId &gt; #{id} where isOpen = true
and articleId &gt; #{id}
) )
</select> </select>

View File

@@ -1,110 +0,0 @@
* {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
.box {
width: 600px;
height: 45vh;
padding: 8px 10px;
border: 1px solid rgba(50, 50, 50, .1);
border-radius: 3px;
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.box-inner {
height: 100%;
width: 100%;
overflow: hidden;
}
.box-inner select, input, button {
width: 90%;
margin: 12px 5%;
height: 40px;
padding: 5px 10px;
border-radius: 3px;
border: 1px solid rgba(50, 50, 50, .1);
box-sizing: border-box;
}
input:focus {
border: 1px solid rgba(0, 50, 50, .6);
outline: none;
}
.box-inner h3 {
text-align: center;
margin-bottom: 20px;
}
.err-msg {
display: none;
color: red;
width: 100%;
padding-left: 30px;
font-size: small;
font-weight: lighter;
}
.show-err-tip {
display: block;
}
#first-page, #second-page {
height: 100%;
margin: 10px 0;
}
.hidden {
height: 0 !important;
visibility: hidden;
position: absolute;
}
.show {
width: 100%;
position: relative;
height: 100%;
visibility: visible;
}
#next-step, .button-group {
position: absolute;
left: 0;
right: 0;
bottom: 10px;
}
.button-group button {
width: 80px;
}
.button-group #install {
position: absolute;
bottom: 0;
right: 20px;
background: #1890ff;
color: white;
}
.loading-show {
z-index: 10000;
display: flex !important;
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
}

View File

@@ -1,171 +0,0 @@
.pacman {
position: relative;
}
.loading {
box-sizing: border-box;
flex: 0 1 auto;
display: none;
flex-direction: column;
flex-grow: 1;
flex-shrink: 0;
flex-basis: 100%;
max-width: 100%;
/*height: 200px;*/
align-items: center;
justify-content: center;
background: #ececec;
}
.pacman > div:nth-child(2) {
-webkit-animation: pacman-balls 1s 0s infinite linear;
animation: pacman-balls 1s 0s infinite linear;
}
.pacman > div:nth-child(3) {
-webkit-animation: pacman-balls 1s 0.33s infinite linear;
animation: pacman-balls 1s 0.33s infinite linear;
}
.pacman > div:nth-child(4) {
-webkit-animation: pacman-balls 1s 0.66s infinite linear;
animation: pacman-balls 1s 0.66s infinite linear;
}
.pacman > div:nth-child(5) {
-webkit-animation: pacman-balls 1s 0.99s infinite linear;
animation: pacman-balls 1s 0.99s infinite linear;
}
.pacman > div:first-of-type {
width: 0px;
height: 0px;
border-right: 25px solid transparent;
border-top: 25px solid #ed5565;
border-left: 25px solid #ed5565;
border-bottom: 25px solid #ed5565;
border-radius: 25px;
-webkit-animation: rotate_pacman_half_up 0.5s 0s infinite;
animation: rotate_pacman_half_up 0.5s 0s infinite;
}
.pacman > div:nth-child(2) {
width: 0px;
height: 0px;
border-right: 25px solid transparent;
border-top: 25px solid #ed5565;
border-left: 25px solid #ed5565;
border-bottom: 25px solid #ed5565;
border-radius: 25px;
-webkit-animation: rotate_pacman_half_down 0.5s 0s infinite;
animation: rotate_pacman_half_down 0.5s 0s infinite;
margin-top: -50px;
}
.pacman > div:nth-child(3), .pacman > div:nth-child(4), .pacman > div:nth-child(5), .pacman > div:nth-child(6) {
background-color: #ed5565;
width: 15px;
height: 15px;
border-radius: 100%;
margin: 2px;
width: 10px;
height: 10px;
position: absolute;
-webkit-transform: translate(0, -6.25px);
-ms-transform: translate(0, -6.25px);
transform: translate(0, -6.25px);
top: 25px;
left: 100px;
}
@-webkit-keyframes rotate_pacman_half_up {
0% {
-webkit-transform: rotate(270deg);
transform: rotate(270deg);
}
50% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
100% {
-webkit-transform: rotate(270deg);
transform: rotate(270deg);
}
}
@keyframes rotate_pacman_half_up {
0% {
-webkit-transform: rotate(270deg);
transform: rotate(270deg);
}
50% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
100% {
-webkit-transform: rotate(270deg);
transform: rotate(270deg);
}
}
@-webkit-keyframes rotate_pacman_half_down {
0% {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
50% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
}
@keyframes rotate_pacman_half_down {
0% {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
50% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
}
@-webkit-keyframes pacman-balls {
75% {
opacity: 0.7;
}
100% {
-webkit-transform: translate(-100px, -6.25px);
transform: translate(-100px, -6.25px);
}
}
@keyframes pacman-balls {
75% {
opacity: 0.7;
}
100% {
-webkit-transform: translate(-100px, -6.25px);
transform: translate(-100px, -6.25px);
}
}

View File

@@ -1,164 +0,0 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>博客安装页面</title>
<link rel="stylesheet" href="css/install.css">
<link rel="stylesheet" href="css/loading.css">
<script src="//cdn.bootcdn.net/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
</head>
<body>
<div class="loading">
<div class="loader-inner pacman">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<p style="margin-top: 20px;margin-left: 10px;">
加载中....
</p>
</div>
<div class="box">
<div class="box-inner">
<div id="first-page" class="show">
<h3>数据库配置</h3>
<!-- 数据库-->
<select id="db-type">
<option value="h2">H2数据库</option>
<option value="mysql">Mysql数据库</option>
</select>
<input id="db-host" type="text" placeholder="请输入数据库的主机地址">
<span class="err-msg" id="err-tip-db-host">数据库的主机地址不可为空</span>
<input id="db-name" type="text" placeholder="请输入数据库的名称">
<span class="err-msg" id="err-tip-db-name">数据库的地址名称不可为空</span>
<input id="db-username" type="text" placeholder="请输入数据库用户名">
<span class="err-msg" id="err-tip-db-username">数据库用户名不可为空</span>
<input id="db-password" type="password" placeholder="请输入数据库密码">
<span class="err-msg" id="err-tip-db-password">数据库密码不可为空</span>
<button onclick="nextPage()" id="next-step">下一步</button>
</div>
<div id="second-page" class="hidden">
<h3>新建管理员用户</h3>
<input id="email" type="email" placeholder="请输入用户名">
<span class="err-msg" id="err-tip-email">用户名不可为空</span>
<input id="password" type="password" placeholder="请输入密码">
<span class="err-msg" id="err-tip-password">密码不可为空</span>
<div class="button-group">
<button onclick="preStep()" id="pre-step">上一步</button>
<button onclick="postInstallEvent()" id="install"> 安装</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
let requestData;
let interValId;
function postInstallEvent() {
requestData.email = $('#email').val()
requestData.password = $('#password').val()
$('#err-tip-email').removeClass("show-err-tip");
$('#err-tip-password').removeClass("show-err-tip");
!requestData.password && checkInput($('#password'), $('#err-tip-password'))
!requestData.email && checkInput($('#email'), $('#err-tip-email'))
if (!requestData.email || !requestData.password) return;
$('.loading').addClass('loading-show');
$.ajax('/install', {
method: "POST",
contentType: 'application/json',
data: JSON.stringify(requestData),
withCredentials: true,
dataType: 'json',
success: function (data) {
console.log("data", data);
console.log("requestData", requestData);
interValId = setInterval(checkConnection, 500)
checkConnection();
}
})
}
function checkConnection() {
$.ajax('/is_install', {
method: "GET",
dataType: 'json',
success: function (data) {
if (data.result.is_install) {
console.log("安装成功");
window.location.href = '/';
} else {
console.log("安装失败");
}
$('.loading').removeClass('loading-show');
clearInterval(interValId);
},
error: function (err) {
console.log(err);
}
})
}
/**
* 切换下一页
*/
function nextPage() {
requestData = {
dbPassword: $('#db-password').val(),
dbType: $('#db-type').val(),
dbHost: $('#db-host').val(),
dbName: $('#db-name').val(),
dbUsername: $('#db-username').val(),
email: '',
password: '',
}
$('#err-tip-db-type').removeClass("show-err-tip");
$('#err-tip-db-host').removeClass("show-err-tip");
$('#err-tip-db-name').removeClass("show-err-tip");
$('#err-tip-db-username').removeClass("show-err-tip");
$('#err-tip-db-password').removeClass("show-err-tip");
!requestData.dbType && checkInput($('#db-type'), $('#err-tip-db-type'))
!requestData.dbHost && checkInput($('#db-host'), $('#err-tip-db-host'))
!requestData.dbName && checkInput($('#db-name'), $('#err-tip-db-name'))
!requestData.dbUsername && checkInput($('#db-username'), $('#err-tip-db-username'))
!requestData.dbPassword && checkInput($('#db-password'), $('#err-tip-db-password'))
if (!requestData.dbType || !requestData.dbUrl || !requestData.dbUsername || !requestData.dbPassword) return
$('#first-page').addClass('hidden');
$('#first-page').removeClass('show');
$('#second-page').addClass('show');
$('#second-page').removeClass('hidden');
}
function preStep() {
$('#second-page').addClass('hidden');
$('#second-page').removeClass('show');
$('#first-page').addClass('show');
$('#first-page').removeClass('hidden');
$('#err-tip-email').removeClass("show-err-tip");
$('#err-tip-password').removeClass("show-err-tip");
}
/**
* 检查组件的状态
* @param component 输入框
* @param errTipComponent 错误信息提示框
* @returns {boolean} 是否有错误
*/
function checkInput(component, errTipComponent) {
if (!component.val()) {
errTipComponent.addClass("show-err-tip");
component.focus();
return true;
}
return false;
}
</script>
</body>
</html>

View File

@@ -214,12 +214,3 @@ VALUES (1, '1.新增网站更新接口api \n2.新增友链api \n3.优化了文
(16, '登陆处理过程变更登陆时长修改至5天', '2019-11-22 11:39:03', 0), (16, '登陆处理过程变更登陆时长修改至5天', '2019-11-22 11:39:03', 0),
(17, '界面改版v2.0', '2020-04-06 11:00:53', 0); (17, '界面改版v2.0', '2020-04-06 11:00:53', 0);
INSERT INTO config (conf_id, conf_name, conf_value)
VALUES (1, 'file.type', 'local'),
(2, 'file.qiniu.accessKey', null),
(3, 'file.qiniu.secretKey', null),
(4, 'file.qiniu.bucket', null),
(5, 'blog.file.path', '~/blog/'),
(6, 'file.local.directoryPath', '~/blog/files/'),
(8, 'blog.installed', 'false'),
(9, 'blog.db.path', '~/blog/db.properties')

View File

@@ -8,7 +8,6 @@ drop table if exists tag_category;
drop table if exists links; drop table if exists links;
drop table if exists visitor; drop table if exists visitor;
drop table if exists web_update; drop table if exists web_update;
drop table if exists config;
CREATE TABLE `user` CREATE TABLE `user`
@@ -89,7 +88,7 @@ CREATE TABLE `links`
`l_url` varchar(255) unique not null comment '首页地址', `l_url` varchar(255) unique not null comment '首页地址',
`l_icon_path` varchar(255) not null comment '友链的icon地址', `l_icon_path` varchar(255) not null comment '友链的icon地址',
`l_desc` varchar(255) COLLATE utf8mb4_unicode_ci not null comment '友链的说明描述', `l_desc` varchar(255) COLLATE utf8mb4_unicode_ci not null comment '友链的说明描述',
`is_delete` boolean not null default false comment '该数据是否被删除', `is_delete` boolean not null default false comment '该数据是否被删除',
`l_email` varchar(255) comment '网站管理员的邮箱', `l_email` varchar(255) comment '网站管理员的邮箱',
`l_notification` boolean default false comment '是否通知了' `l_notification` boolean default false comment '是否通知了'
) comment '友站表'; ) comment '友站表';
@@ -111,13 +110,6 @@ 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

@@ -8,7 +8,6 @@ drop table if exists tag_category;
drop table if exists links; drop table if exists links;
drop table if exists visitor; drop table if exists visitor;
drop table if exists web_update; drop table if exists web_update;
drop table if exists config;
-- 用户表 -- 用户表
CREATE TABLE `user` CREATE TABLE `user`
@@ -116,13 +115,6 @@ CREATE TABLE `web_update`
`is_delete` boolean not null default false 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 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

@@ -2,15 +2,15 @@ package cn.celess.blog;
import cn.celess.blog.entity.Response; import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.model.FileInfo; import cn.celess.blog.entity.model.QiniuResponse;
import cn.celess.blog.entity.model.FileResponse;
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.service.MailService; import cn.celess.blog.service.MailService;
import cn.celess.blog.service.FileManager; import cn.celess.blog.service.QiniuService;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.qiniu.storage.model.FileInfo;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@@ -37,8 +37,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@@ -221,7 +219,7 @@ public class BaseTest {
protected ResultActions getMockData(MockHttpServletRequestBuilder builder, String token, Object content) throws Exception { protected ResultActions getMockData(MockHttpServletRequestBuilder builder, String token, Object content) throws Exception {
// MockHttpServletRequestBuilder mockHttpServletRequestBuilder = get(url); // MockHttpServletRequestBuilder mockHttpServletRequestBuilder = get(url);
if (token != null) { if (token != null) {
builder.header("Authorization", token); builder.header("Authorization", "Bearer "+token);
} }
if (content != null) { if (content != null) {
builder.content(mapper.writeValueAsString(content)).contentType(MediaType.APPLICATION_JSON); builder.content(mapper.writeValueAsString(content)).contentType(MediaType.APPLICATION_JSON);
@@ -327,29 +325,23 @@ public class BaseTest {
} }
@Slf4j @Slf4j
public static class TestFileManager implements FileManager { public static class TestQiNiuServiceImpl implements QiniuService {
@Override @Override
public FileResponse uploadFile(InputStream is, String fileName) { public QiniuResponse uploadFile(InputStream is, String fileName) {
FileResponse response = new FileResponse(); QiniuResponse response = new QiniuResponse();
log.debug("上传文件请求,[fileName:{}]", fileName); log.debug("上传文件请求,[fileName:{}]", fileName);
response.key = "key"; response.key = "key";
response.type = "test"; response.bucket = "bucket";
response.hash = "hash"; response.hash = "hash";
response.size = 1; response.fsize = 1;
return response; return response;
} }
@Override @Override
public List<FileInfo> getFileList() { public FileInfo[] getFileList() {
log.debug("获取文件列表请求"); log.debug("获取文件列表请求");
return new ArrayList<>(); return new FileInfo[0];
}
@Override
public boolean deleteFile(String fileName) {
log.debug("删除[{}]成功", fileName);
return true;
} }
} }
} }

View File

@@ -1,131 +0,0 @@
package cn.celess.blog.configuration;
import cn.celess.blog.BaseTest;
import cn.celess.blog.enmu.ConfigKeyEnum;
import cn.celess.blog.service.fileserviceimpl.LocalFileServiceImpl;
import com.alibaba.druid.pool.DruidDataSource;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Properties;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class DruidConfigTest extends BaseTest {
@Mock
Environment env;
@Autowired
Environment globalEnvironment;
private File configFile;
private File bakConfigFile;
@Test
public void initDataSource() throws IOException {
DruidConfig druidConfig = new DruidConfig();
druidConfig.env = env;
System.out.println(Arrays.toString(env.getActiveProfiles()));
// 无配置文件
assertTrue(!configFile.exists() || configFile.delete());
DruidDataSource druidDataSource = druidConfig.initDataSource();
// 加载初始化时候配置文件的数据库连接
assertEquals(env.getProperty(DruidConfig.DB_CONFIG_URL_PREFIX), druidDataSource.getUrl());
assertEquals(env.getProperty(DruidConfig.DB_CONFIG_DRIVER_CLASS_NAME_PREFIX), druidDataSource.getDriverClassName());
assertEquals(env.getProperty(DruidConfig.DB_CONFIG_USERNAME_PREFIX), druidDataSource.getUsername());
assertEquals(env.getProperty(DruidConfig.DB_CONFIG_PASSWORD_PREFIX), druidDataSource.getPassword());
assertTrue(configFile.createNewFile());
// 有配置文件的测试
Properties properties = new Properties();
FileInputStream fileInputStream = new FileInputStream(configFile);
properties.load(fileInputStream);
fileInputStream.close();
properties.setProperty(DruidConfig.DB_CONFIG_URL_PREFIX, "jdbc:mysql://localhost:3306/blog");
properties.setProperty(DruidConfig.DB_CONFIG_DRIVER_CLASS_NAME_PREFIX, "com.mysql.cj.jdbc.Driver");
properties.setProperty(DruidConfig.DB_CONFIG_USERNAME_PREFIX, "username");
properties.setProperty(DruidConfig.DB_CONFIG_PASSWORD_PREFIX, "password");
// 保存到文件
FileOutputStream fileOutputStream = new FileOutputStream(configFile);
properties.store(fileOutputStream, "数据库配置");
fileOutputStream.close();
druidDataSource = druidConfig.initDataSource();
assertEquals(properties.getProperty(DruidConfig.DB_CONFIG_URL_PREFIX), druidDataSource.getUrl());
assertEquals(properties.getProperty(DruidConfig.DB_CONFIG_DRIVER_CLASS_NAME_PREFIX), druidDataSource.getDriverClassName());
assertEquals(properties.getProperty(DruidConfig.DB_CONFIG_USERNAME_PREFIX), druidDataSource.getUsername());
assertEquals(properties.getProperty(DruidConfig.DB_CONFIG_PASSWORD_PREFIX), druidDataSource.getPassword());
}
@After
public void setConfigBack() {
if (bakConfigFile.exists()) {
System.out.println("恢复配置文件成功");
copyFile(bakConfigFile, configFile);
assertTrue(bakConfigFile.delete());
} else {
configFile.deleteOnExit();
}
}
@Before
public void recordConfig() {
File path = new File(LocalFileServiceImpl.getPath(System.getProperty(ConfigKeyEnum.BLOG_FILE_PATH.getKey())));
if (!path.exists() && !path.mkdirs()) {
fail("创建失败");
}
this.bakConfigFile = new File(DruidConfig.DB_CONFIG_PATH + ".bak");
this.configFile = new File(DruidConfig.DB_CONFIG_PATH);
if (configFile.exists()) {
System.out.println("备份文件成功");
copyFile(configFile, bakConfigFile);
}
when(this.env.getActiveProfiles()).thenReturn(new String[]{"dev"});
when(this.env.getProperty(DruidConfig.DB_CONFIG_PASSWORD_PREFIX)).thenReturn(globalEnvironment.getProperty(DruidConfig.DB_CONFIG_PASSWORD_PREFIX));
when(this.env.getProperty(DruidConfig.DB_CONFIG_URL_PREFIX)).thenReturn(globalEnvironment.getProperty(DruidConfig.DB_CONFIG_URL_PREFIX));
when(this.env.getProperty(DruidConfig.DB_CONFIG_USERNAME_PREFIX)).thenReturn(globalEnvironment.getProperty(DruidConfig.DB_CONFIG_USERNAME_PREFIX));
when(this.env.getProperty(DruidConfig.DB_CONFIG_DRIVER_CLASS_NAME_PREFIX)).thenReturn(globalEnvironment.getProperty(DruidConfig.DB_CONFIG_DRIVER_CLASS_NAME_PREFIX));
}
/**
* 复制文件
*
* @param src
* @param dist
* @return
*/
private boolean copyFile(File src, File dist) {
try {
// 复制备份文件
FileOutputStream fos = new FileOutputStream(dist);
FileInputStream fis = new FileInputStream(src);
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
fos.close();
fis.close();
return true;
} catch (IOException e) {
return false;
}
}
}

View File

@@ -9,7 +9,6 @@ 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.mapper.UserMapper; import cn.celess.blog.mapper.UserMapper;
import cn.celess.blog.service.UserService; import cn.celess.blog.service.UserService;
import cn.celess.blog.service.FileService;
import cn.celess.blog.util.MD5Util; import cn.celess.blog.util.MD5Util;
import cn.celess.blog.util.RedisUtil; import cn.celess.blog.util.RedisUtil;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
@@ -116,7 +115,7 @@ public class UserControllerTest extends BaseTest {
assertNotNull(inputStream); assertNotNull(inputStream);
// mock 实现类 // mock 实现类
mockInjectInstance(userService, "fileService", (FileService) TestFileManager::new); mockInjectInstance(userService, "qiniuService", new TestQiNiuServiceImpl());
MockMultipartFile file = new MockMultipartFile("file", "logo.png", MediaType.IMAGE_PNG_VALUE, inputStream); MockMultipartFile file = new MockMultipartFile("file", "logo.png", MediaType.IMAGE_PNG_VALUE, inputStream);
getMockData(multipart("/user/imgUpload").file(file), userLogin()).andDo(result -> { getMockData(multipart("/user/imgUpload").file(file), userLogin()).andDo(result -> {

View File

@@ -134,4 +134,13 @@ public class ArticleTagMapperTest extends BaseTest {
return articleTag; 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());
}
} }

View File

@@ -1,63 +0,0 @@
package cn.celess.blog.mapper;
import cn.celess.blog.BaseTest;
import cn.celess.blog.entity.Config;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import static org.junit.Assert.*;
public class ConfigMapperTest extends BaseTest {
@Autowired
ConfigMapper configMapper;
@Test
public void getConfiguration() {
Config file = configMapper.getConfiguration("file.type");
assertNotNull(file);
assertNotNull(file.getId());
assertEquals("file.type", file.getName());
assertEquals("local", file.getValue());
}
@Test
public void updateConfiguration() {
Config config = generateConfig();
configMapper.addConfiguration(config);
assertNotNull(config.getId());
String s = randomStr();
config.setValue(s);
configMapper.updateConfiguration(config);
assertEquals(s, configMapper.getConfiguration(config.getName()).getValue());
}
@Test
public void getConfigurations() {
assertTrue(configMapper.getConfigurations().size() > 0);
}
@Test
public void addConfiguration() {
Config config = generateConfig();
configMapper.addConfiguration(config);
assertNotNull(config.getId());
}
@Test
public void deleteConfiguration() {
Config config = generateConfig();
configMapper.addConfiguration(config);
assertNotNull(config.getId());
assertNotEquals(0, configMapper.deleteConfiguration(config.getId()));
assertNull(configMapper.getConfiguration(config.getName()));
}
private Config generateConfig() {
Config config = new Config();
config.setName("test" + randomStr(4));
config.setValue(randomStr(4));
return config;
}
}

View File

@@ -3,6 +3,8 @@ package cn.celess.blog.service;
import cn.celess.blog.BaseTest; import cn.celess.blog.BaseTest;
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.model.PageData;
import cn.celess.blog.mapper.ArticleMapper;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -12,6 +14,8 @@ public class ArticleServiceTest extends BaseTest {
@Autowired @Autowired
ArticleService articleService; ArticleService articleService;
@Autowired
ArticleMapper articleMapper;
@Test @Test
public void adminArticles() { 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::isDeleted));
assertTrue(pageData.getList().stream().anyMatch(articleModel -> !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());
}
});
}
} }

View File

@@ -1,123 +0,0 @@
package cn.celess.blog.service.fileserviceimpl;
import cn.celess.blog.BaseTest;
import cn.celess.blog.enmu.ConfigKeyEnum;
import cn.celess.blog.entity.model.FileInfo;
import cn.celess.blog.entity.model.FileResponse;
import cn.celess.blog.service.FileManager;
import cn.celess.blog.service.FileService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
import static org.junit.Assert.*;
@Slf4j
public class FileManagerTest extends BaseTest {
@Autowired
FileService fileService;
FileManager fileManager;
@Test
public void testUploadFile() {
// 测试本地的文件上传
fileManager = null;
System.setProperty(ConfigKeyEnum.FILE_TYPE.getKey(), "local");
fileManager = fileService.getFileManager();
assertTrue(fileManager instanceof LocalFileServiceImpl);
uploadFile();
// 测试七牛云的文件上传
fileManager = null;
System.setProperty(ConfigKeyEnum.FILE_TYPE.getKey(), "qiniu");
fileManager = fileService.getFileManager();
assertTrue(fileManager instanceof QiniuFileServiceImpl);
uploadFile();
}
@Test
public void testGetFileList() {
// 测试获取本地的文件列表
fileManager = null;
System.setProperty(ConfigKeyEnum.FILE_TYPE.getKey(), "local");
fileManager = fileService.getFileManager();
assertTrue(fileManager instanceof LocalFileServiceImpl);
getFileList();
// 测试获取七牛云的文件列表
fileManager = null;
System.setProperty(ConfigKeyEnum.FILE_TYPE.getKey(), "qiniu");
fileManager = fileService.getFileManager();
assertTrue(fileManager instanceof QiniuFileServiceImpl);
getFileList();
}
@Test
public void testDeleteFile() {
// 测试删除本地文件
fileManager = null;
System.setProperty(ConfigKeyEnum.FILE_TYPE.getKey(), "local");
fileManager = fileService.getFileManager();
assertTrue(fileManager instanceof LocalFileServiceImpl);
deleteFile();
// 测试删除七牛云文件
fileManager = null;
System.setProperty(ConfigKeyEnum.FILE_TYPE.getKey(), "qiniu");
fileManager = fileService.getFileManager();
assertTrue(fileManager instanceof QiniuFileServiceImpl);
deleteFile();
}
@SneakyThrows
public void uploadFile() {
String fileName = null;
File file = createFile();
FileResponse fileResponse = fileManager.uploadFile(new FileInputStream(file), file.getName());
assertEquals(file.getName(), fileResponse.key);
assertEquals(System.getProperty(ConfigKeyEnum.FILE_TYPE.getKey()), fileResponse.type);
// assertNotNull(fileResponse.hash);
fileName = fileResponse.key;
fileManager.deleteFile(fileName);
file.deleteOnExit();
}
public void getFileList() {
List<FileInfo> fileList = fileManager.getFileList();
fileList.forEach(fileInfo -> {
assertNotNull(fileInfo.key);
// assertNotNull(fileInfo.hash);
});
}
public void deleteFile() {
uploadFile();
}
@SneakyThrows
private File createFile() {
String fileName = "test." + randomStr(3);
File file = new File(fileName);
if (!file.exists() && file.createNewFile()) {
// 创建文件
log.debug("创建文件[{}]", fileName);
FileOutputStream outputStream = new FileOutputStream(file);
for (int i = 0; i < 100; i++) {
outputStream.write(new byte[1024]);
}
outputStream.flush();
outputStream.close();
}
return file;
}
}