Compare commits

..

75 Commits

Author SHA1 Message Date
dependabot[bot]
db8d648f54 build(deps): bump pagehelper-spring-boot-starter from 1.4.1 to 1.4.6
Bumps [pagehelper-spring-boot-starter](https://github.com/pagehelper/pagehelper-spring-boot) from 1.4.1 to 1.4.6.
- [Release notes](https://github.com/pagehelper/pagehelper-spring-boot/releases)
- [Commits](https://github.com/pagehelper/pagehelper-spring-boot/compare/1.4.1...1.4.6)

---
updated-dependencies:
- dependency-name: com.github.pagehelper:pagehelper-spring-boot-starter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-02 12:43:54 +00: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
52 changed files with 583 additions and 2392 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:
build:
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '.md')" # 如果 commit 信息包含以下关键字则跳过该任务
runs-on: ubuntu-latest
env:
KEY: ${{ secrets.WEB_HOOK_ACCESS_KEY }}
QINIU_ACCESSKEY: ${{ secrets.QINIU_ACCESSKEY }}
QINIU_SECRETKEY: ${{ secrets.QINIU_SECRETKEY }}
steps:
- uses: actions/checkout@v2
@@ -24,5 +22,16 @@ jobs:
with:
java-version: 1.8
- name: Sync repository
uses: x-dr/sync-repo-to-gitee@v1.0
env:
# 在 Settings->Secrets 配置 GITEE_KEY
SSH_KEY: ${{ secrets.GITEE_KEY }}
with:
# GitHub存储库的SSH URL.
github-repo: git@github.com:xiaohai2271/blog-backEnd.git
# Gitee存储库的SSH URL.
gitee-repo: git@gitee.com:xiaohai2271/blog-backEnd.git
- name: Deploy
run: mvn -B test --file pom.xml && curl http://bt.celess.cn:2271/hook?access_key=$KEY

View File

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

View File

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

34
pom.xml
View File

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

View File

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

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

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

View File

@@ -2,10 +2,10 @@ package cn.celess.blog.controller;
import cn.celess.blog.enmu.ResponseEnum;
import cn.celess.blog.entity.Response;
import cn.celess.blog.entity.model.FileResponse;
import cn.celess.blog.entity.model.QiniuResponse;
import cn.celess.blog.exception.MyException;
import cn.celess.blog.service.CountService;
import cn.celess.blog.service.FileService;
import cn.celess.blog.service.QiniuService;
import cn.celess.blog.util.HttpUtil;
import cn.celess.blog.util.RedisUserUtil;
import cn.celess.blog.util.RedisUtil;
@@ -42,7 +42,7 @@ public class CommonController {
@Autowired
CountService countService;
@Autowired
FileService fileService;
QiniuService qiniuService;
@Autowired
RedisUtil redisUtil;
@Autowired
@@ -161,10 +161,10 @@ public class CommonController {
String mime = fileName.substring(fileName.lastIndexOf("."));
if (".png".equals(mime.toLowerCase()) || ".jpg".equals(mime.toLowerCase()) ||
".jpeg".equals(mime.toLowerCase()) || ".bmp".equals(mime.toLowerCase())) {
FileResponse fileResponse = fileService.getFileManager().uploadFile(file.getInputStream(), "img_" + System.currentTimeMillis() + mime);
QiniuResponse qiniuResponse = qiniuService.uploadFile(file.getInputStream(), "img_" + System.currentTimeMillis() + mime);
map.put("success", 1);
map.put("message", "上传成功");
map.put("url", "http://cdn.celess.cn/" + fileResponse.key);
map.put("url", "http://cdn.celess.cn/" + qiniuResponse.key);
response.getWriter().println(mapper.writeValueAsString(map));
redisUtil.setEx(request.getRemoteAddr() + "-ImgUploadTimes", uploadTimes + 1 + "", 2, TimeUnit.HOURS);
return;
@@ -208,12 +208,12 @@ public class CommonController {
assert fileName != null;
String mime = fileName.substring(fileName.lastIndexOf("."));
String name = fileName.replace(mime, "").replaceAll(" ", "");
FileResponse fileResponse = fileService.getFileManager().uploadFile(file.getInputStream(), "file_" + name + '_' + System.currentTimeMillis() + mime);
QiniuResponse qiniuResponse = qiniuService.uploadFile(file.getInputStream(), "file_" + name + '_' + System.currentTimeMillis() + mime);
resp.put("originalFilename", fileName);
resp.put("success", fileResponse != null);
if (fileResponse != null) {
resp.put("success", qiniuResponse != null);
if (qiniuResponse != null) {
resp.put("host", "http://cdn.celess.cn/");
resp.put("path", fileResponse.key);
resp.put("path", qiniuResponse.key);
}
result.add(resp);
}

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
* @date : 2019/04/21 22:43
*/
public class FileResponse {
public class QiniuResponse {
public String key;
public String hash;
public String type;
public long size;
public String bucket;
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.mail.SimpleMailMessage;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@@ -20,10 +18,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.Set;
/**
* @author : xiaohai
@@ -47,32 +41,27 @@ public class ExceptionHandle {
if (e instanceof MyException) {
MyException exception = (MyException) e;
logger.debug("返回了自定义的exception,[code={},msg={},result={}]", exception.getCode(), e.getMessage(), exception.getResult());
return new Response<>(exception.getCode(), e.getMessage(), exception.getResult());
return new Response(exception.getCode(), e.getMessage(), exception.getResult());
}
//请求路径不支持该方法
if (e instanceof HttpRequestMethodNotSupportedException) {
logger.debug("遇到请求路径与请求方法不匹配的请求,[msg={}path:{},method:{}]", e.getMessage(), request.getRequestURL(), request.getMethod());
return new Response<>(ResponseEnum.ERROR.getCode(), e.getMessage(), null);
return new Response(ResponseEnum.ERROR.getCode(), e.getMessage(), null);
}
//数据输入类型不匹配
if (e instanceof MethodArgumentTypeMismatchException) {
logger.debug("输入类型不匹配,[msg={}]", e.getMessage());
return new Response<>(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入有问题,请修改后再访问", null);
return new Response(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入有问题,请修改后再访问", null);
}
//数据验证失败
if (e instanceof BindException) {
logger.debug("数据验证失败,[msg={}]", e.getMessage());
return new Response<>(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入有问题,请修改", null);
return new Response(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入有问题,请修改", null);
}
//数据输入不完整
if (e instanceof MissingServletRequestParameterException) {
logger.debug("数据输入不完整,[msg={}]", e.getMessage());
return new Response<>(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入不完整,请检查", null);
}
if (e instanceof MethodArgumentNotValidException) {
logger.debug("数据验证失败,[msg: {}]", e.getMessage());
BindingResult violations = ((MethodArgumentNotValidException) e).getBindingResult();
return new Response<>(ResponseEnum.PARAMETERS_ERROR.getCode(), violations.getAllErrors().get(0).getDefaultMessage(), null);
return new Response(ResponseEnum.PARAMETERS_ERROR.getCode(), "数据输入不完整,请检查", null);
}
// 发送错误信息到邮箱
@@ -81,7 +70,7 @@ public class ExceptionHandle {
sendMessage(e);
}
e.printStackTrace();
return new Response<>(ResponseEnum.ERROR.getCode(), "服务器出现错误,已记录", null);
return new Response(ResponseEnum.ERROR.getCode(), "服务器出现错误,已记录", null);
}
/**

View File

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

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

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.entity.Response;
import cn.celess.blog.entity.User;
import cn.celess.blog.entity.model.FileResponse;
import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.entity.model.QiniuResponse;
import cn.celess.blog.entity.model.UserModel;
import cn.celess.blog.entity.request.LoginReq;
import cn.celess.blog.entity.request.UserReq;
import cn.celess.blog.exception.MyException;
import cn.celess.blog.mapper.UserMapper;
import cn.celess.blog.service.FileService;
import cn.celess.blog.service.MailService;
import cn.celess.blog.service.QiniuService;
import cn.celess.blog.service.UserService;
import cn.celess.blog.util.*;
import com.github.pagehelper.PageHelper;
@@ -24,7 +24,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.beans.Transient;
import java.io.InputStream;
@@ -46,8 +45,8 @@ public class UserServiceImpl implements UserService {
HttpServletRequest request;
@Autowired
MailService mailService;
@Resource(name = "fileServiceImpl")
FileService fileService;
@Autowired
QiniuService qiniuService;
@Autowired
RedisUtil redisUtil;
@Autowired
@@ -186,7 +185,7 @@ public class UserServiceImpl implements UserService {
@Override
public Object updateUserAavatarImg(InputStream is, String mime) {
User user = redisUserUtil.get();
FileResponse upload = fileService.getFileManager().uploadFile(is, user.getEmail() + "_" + user.getId() + mime.toLowerCase());
QiniuResponse upload = qiniuService.uploadFile(is, user.getEmail() + "_" + user.getId() + mime.toLowerCase());
user.setAvatarImgUrl(upload.key);
userMapper.updateAvatarImgUrl(upload.key, user.getId());
redisUserUtil.set(user);

View File

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

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,9 +1,9 @@
server.port=8081
# 七牛的密钥配置
file.qiniu.accessKey=
file.qiniu.secretKey=
file.qiniu.bucket=
qiniu.accessKey=
qiniu.secretKey=
qiniu.bucket=
# sitemap 存放地址
sitemap.path=
# 生成JWT时候的密钥
@@ -62,6 +62,12 @@ spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFact
spring.mail.properties.mail.smtp.socketFactory.fallback=false
#### 用于nginx的代理 获取真实ip
server.use-forward-headers = true
server.tomcat.remote-ip-header = X-Real-IP
server.tomcat.protocol-header = X-Forwarded-Proto
############### redis ##############
# REDIS (RedisProperties)
# Redis数据库索引默认为0

View File

@@ -1,9 +1,9 @@
server.port=8081
# 七牛的密钥配置
file.qiniu.accessKey=${QINIU_ACCESSKEY:null}
file.qiniu.secretKey=${QINIU_SECRETKEY:null}
file.qiniu.bucket=xiaohai
qiniu.accessKey=
qiniu.secretKey=
qiniu.bucket=
# sitemap 存放地址
sitemap.path=
# 生成JWT时候的密钥
@@ -32,9 +32,10 @@ spring.datasource.username=sa
spring.datasource.password=
spring.datasource.platform=h2
spring.datasource.sql-script-encoding=utf-8
spring.datasource.initialization-mode=ALWAYS
spring.datasource.schema=classpath:sql/schema-h2.sql
spring.datasource.schema=classpath:sql/schema_h2.sql
spring.datasource.data=classpath:sql/data.sql
@@ -49,6 +50,13 @@ pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql
#### 用于nginx的代理 获取真实ip
server.use-forward-headers = true
server.tomcat.remote-ip-header = X-Real-IP
server.tomcat.protocol-header = X-Forwarded-Proto
############### email ##############
spring.mail.host=smtp.163.com
spring.mail.username=

View File

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

View File

@@ -64,6 +64,14 @@
and article_tag.t_id = tag_category.t_id
</select>
<select id="findTagByArticleId" resultMap="cn.celess.blog.mapper.TagMapper.tagResultMap">
select tag_category.*
from article_tag,
tag_category
where a_id = #{articleId}
and article_tag.t_id = tag_category.t_id
</select>
<select id="findOneById" resultMap="articleTagResultMap">
select *
from article_tag,

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"
resultMap="cn.celess.blog.mapper.CategoryMapper.categoryResultMap">
</association>
<collection property="tags" ofType="cn.celess.blog.entity.TagCategory"
resultMap="cn.celess.blog.mapper.CategoryMapper.categoryResultMap">
<collection property="tags" ofType="cn.celess.blog.entity.Tag"
select="cn.celess.blog.mapper.ArticleTagMapper.findTagByArticleId" column="a_id">
<id column="tagId" property="id"/>
<result column="tagName" property="name"/>
</collection>
</resultMap>
@@ -49,7 +51,8 @@
<result column="userAvatar" property="avatarImgUrl"/>
<result column="userDisplayName" property="displayName"/>
</association>
<collection property="tags" ofType="cn.celess.blog.entity.Tag">
<collection property="tags" ofType="cn.celess.blog.entity.Tag"
select="cn.celess.blog.mapper.ArticleTagMapper.findTagByArticleId" column="{articleId=articleId}">
<id column="tagId" property="id"/>
<result column="tagName" property="name"/>
</collection>
@@ -119,11 +122,37 @@
</select>
<select id="findAllByOpen" resultMap="articleViewResultMap">
select *
from articleView
where isOpen = #{isOpen}
and isDelete = false
order by articleId desc
select article.a_id as articleId,
article.a_title as title,
article.a_summary as summary,
article.a_md_content as mdContent,
article.a_url as url,
article.a_is_original as isOriginal,
article.a_reading_number as readingCount,
article.a_like as likeCount,
article.a_dislike as dislikeCount,
article.a_publish_date as publishDate,
article.a_update_date as updateDate,
article.a_is_open as isOpen,
category.t_id as categoryId,
category.t_name as categoryName,
user.u_id as authorId,
user.u_email as userEmail,
user.u_avatar as userAvatar,
user.u_display_name as userDisplayName,
article.is_delete as isDelete
from article,
tag_category as category,
article_tag,
user
where article.a_is_open = #{isOpen}
and article.is_delete = false
and article.a_id = article_tag.a_id
and article.a_category_id = category.t_id
and category.is_category = true
and article.a_author_id = user.u_id
group by article.a_id
order by article.a_id desc
</select>
@@ -152,9 +181,35 @@
<select id="findAll" resultMap="articleViewResultMap">
select *
from articleView
order by articleId desc
select article.a_id as articleId,
article.a_title as title,
article.a_summary as summary,
article.a_md_content as mdContent,
article.a_url as url,
article.a_is_original as isOriginal,
article.a_reading_number as readingCount,
article.a_like as likeCount,
article.a_dislike as dislikeCount,
article.a_publish_date as publishDate,
article.a_update_date as updateDate,
article.a_is_open as isOpen,
category.t_id as categoryId,
category.t_name as categoryName,
user.u_id as authorId,
user.u_email as userEmail,
user.u_avatar as userAvatar,
user.u_display_name as userDisplayName,
article.is_delete as isDelete
from article,
tag_category as category,
article_tag,
user
where article.a_id = article_tag.a_id
and article.a_category_id = category.t_id
and category.is_category = true
and article.a_author_id = user.u_id
group by article.a_id
order by article.a_id desc
</select>
@@ -169,7 +224,8 @@
from articleView
where articleId = (select max(articleId)
from articleView
where articleId &lt; #{id}
where isOpen = true
and articleId &lt; #{id}
)
</select>
<select id="getNextArticle" resultMap="articleViewResultMap">
@@ -177,7 +233,8 @@
from articleView
where articleId = (select min(articleId)
from articleView
where articleId &gt; #{id}
where isOpen = true
and articleId &gt; #{id}
)
</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),
(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 visitor;
drop table if exists web_update;
drop table if exists config;
CREATE TABLE `user`
@@ -111,13 +110,6 @@ CREATE TABLE `web_update`
`is_delete` boolean not null default false comment '该数据是否被删除'
) comment '更新内容表';
CREATE TABLE `config`
(
`conf_id` int primary key auto_increment,
`conf_name` varchar(255) unique not null comment '配置名',
`conf_value` varchar(255) default null comment '配置值'
);
CREATE VIEW articleView
(articleId, title, summary, mdContent, url, isOriginal, readingCount, likeCount, dislikeCount,
publishDate, updateDate, isOpen,

View File

@@ -8,7 +8,6 @@ drop table if exists tag_category;
drop table if exists links;
drop table if exists visitor;
drop table if exists web_update;
drop table if exists config;
-- 用户表
CREATE TABLE `user`
@@ -116,13 +115,6 @@ CREATE TABLE `web_update`
`is_delete` boolean not null default false comment '该数据是否被删除'
);
CREATE TABLE `config`
(
`conf_id` int primary key auto_increment,
`conf_name` varchar(255) unique not null comment '配置名',
`conf_value` varchar(255) default null comment '配置值'
);
CREATE VIEW articleView
(articleId, title, summary, mdContent, url, isOriginal, readingCount, likeCount, dislikeCount,
publishDate, updateDate, isOpen,

View File

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

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

View File

@@ -134,4 +134,13 @@ public class ArticleTagMapperTest extends BaseTest {
return articleTag;
}
@Test
public void findTagByArticleId() {
Article article = articleMapper.findAll().get(0);
assertNotNull(article);
List<Tag> tagByArticleId = articleTagMapper.findTagByArticleId(article.getId());
assertNotEquals(0, tagByArticleId.size());
}
}

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.entity.model.ArticleModel;
import cn.celess.blog.entity.model.PageData;
import cn.celess.blog.mapper.ArticleMapper;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -12,6 +14,8 @@ public class ArticleServiceTest extends BaseTest {
@Autowired
ArticleService articleService;
@Autowired
ArticleMapper articleMapper;
@Test
public void adminArticles() {
@@ -24,4 +28,25 @@ public class ArticleServiceTest extends BaseTest {
assertTrue(pageData.getList().stream().anyMatch(ArticleModel::isDeleted));
assertTrue(pageData.getList().stream().anyMatch(articleModel -> !articleModel.isDeleted()));
}
@Test
public void retrievePageForOpen() {
PageData<ArticleModel> articleModelPageData = articleService.retrievePageForOpen(10, 1);
assertEquals(10, articleModelPageData.getPageSize());
assertEquals(1, articleModelPageData.getPageNum());
assertEquals(10, articleModelPageData.getList().size());
articleModelPageData.getList().forEach(Assert::assertNotNull);
// 测试open字段
articleModelPageData.getList().forEach(articleModel -> {
// 当前文章
assertTrue(articleMapper.findArticleById(articleModel.getId()).getOpen());
if (articleModel.getPreArticle() != null) {
assertTrue(articleMapper.findArticleById(articleModel.getPreArticle().getId()).getOpen());
}
if (articleModel.getNextArticle() != null) {
assertTrue(articleMapper.findArticleById(articleModel.getNextArticle().getId()).getOpen());
}
});
}
}

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