From 2b028c8d81b7bd5833b678cca5a0db2bf2d4c4d0 Mon Sep 17 00:00:00 2001 From: Miles <1010933988@qq.com> Date: Tue, 23 Apr 2019 20:40:13 +0800 Subject: [PATCH 01/52] =?UTF-8?q?=E6=B7=BB=E5=8A=A0vue=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fstackforum-vue/.babelrc | 12 ++ fstackforum-vue/.editorconfig | 9 ++ fstackforum-vue/.gitignore | 14 +++ fstackforum-vue/.postcssrc.js | 10 ++ fstackforum-vue/README.md | 21 ++++ fstackforum-vue/config/dev.env.js | 7 ++ fstackforum-vue/config/index.js | 69 +++++++++++ fstackforum-vue/config/prod.env.js | 4 + fstackforum-vue/index.html | 12 ++ fstackforum-vue/package.json | 62 ++++++++++ fstackforum-vue/src/App.vue | 23 ++++ fstackforum-vue/src/assets/logo.png | Bin 0 -> 6849 bytes fstackforum-vue/src/components/HelloWorld.vue | 113 ++++++++++++++++++ fstackforum-vue/src/main.js | 15 +++ fstackforum-vue/src/router/index.js | 15 +++ 15 files changed, 386 insertions(+) create mode 100644 fstackforum-vue/.babelrc create mode 100644 fstackforum-vue/.editorconfig create mode 100644 fstackforum-vue/.gitignore create mode 100644 fstackforum-vue/.postcssrc.js create mode 100644 fstackforum-vue/README.md create mode 100644 fstackforum-vue/config/dev.env.js create mode 100644 fstackforum-vue/config/index.js create mode 100644 fstackforum-vue/config/prod.env.js create mode 100644 fstackforum-vue/index.html create mode 100644 fstackforum-vue/package.json create mode 100644 fstackforum-vue/src/App.vue create mode 100644 fstackforum-vue/src/assets/logo.png create mode 100644 fstackforum-vue/src/components/HelloWorld.vue create mode 100644 fstackforum-vue/src/main.js create mode 100644 fstackforum-vue/src/router/index.js diff --git a/fstackforum-vue/.babelrc b/fstackforum-vue/.babelrc new file mode 100644 index 0000000..3a280ba --- /dev/null +++ b/fstackforum-vue/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] + } + }], + "stage-2" + ], + "plugins": ["transform-vue-jsx", "transform-runtime"] +} diff --git a/fstackforum-vue/.editorconfig b/fstackforum-vue/.editorconfig new file mode 100644 index 0000000..9d08a1a --- /dev/null +++ b/fstackforum-vue/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/fstackforum-vue/.gitignore b/fstackforum-vue/.gitignore new file mode 100644 index 0000000..541a820 --- /dev/null +++ b/fstackforum-vue/.gitignore @@ -0,0 +1,14 @@ +.DS_Store +node_modules/ +/dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln diff --git a/fstackforum-vue/.postcssrc.js b/fstackforum-vue/.postcssrc.js new file mode 100644 index 0000000..eee3e92 --- /dev/null +++ b/fstackforum-vue/.postcssrc.js @@ -0,0 +1,10 @@ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + "postcss-import": {}, + "postcss-url": {}, + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {} + } +} diff --git a/fstackforum-vue/README.md b/fstackforum-vue/README.md new file mode 100644 index 0000000..1d7ea7d --- /dev/null +++ b/fstackforum-vue/README.md @@ -0,0 +1,21 @@ +# fstackforum-vue + +> A Vue.js project + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build + +# build for production and view the bundle analyzer report +npm run build --report +``` + +For a detailed explanation on how things work, check out the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). diff --git a/fstackforum-vue/config/dev.env.js b/fstackforum-vue/config/dev.env.js new file mode 100644 index 0000000..1e22973 --- /dev/null +++ b/fstackforum-vue/config/dev.env.js @@ -0,0 +1,7 @@ +'use strict' +const merge = require('webpack-merge') +const prodEnv = require('./prod.env') + +module.exports = merge(prodEnv, { + NODE_ENV: '"development"' +}) diff --git a/fstackforum-vue/config/index.js b/fstackforum-vue/config/index.js new file mode 100644 index 0000000..c5eded7 --- /dev/null +++ b/fstackforum-vue/config/index.js @@ -0,0 +1,69 @@ +'use strict' +// Template version: 1.3.1 +// see http://vuejs-templates.github.io/webpack for documentation. + +const path = require('path') + +module.exports = { + dev: { + + // Paths + assetsSubDirectory: 'static', + assetsPublicPath: '/', + proxyTable: {}, + + // Various Dev Server settings + host: 'localhost', // can be overwritten by process.env.HOST + port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined + autoOpenBrowser: false, + errorOverlay: true, + notifyOnErrors: true, + poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- + + + /** + * Source Maps + */ + + // https://webpack.js.org/configuration/devtool/#development + devtool: 'cheap-module-eval-source-map', + + // If you have problems debugging vue-files in devtools, + // set this to false - it *may* help + // https://vue-loader.vuejs.org/en/options.html#cachebusting + cacheBusting: true, + + cssSourceMap: true + }, + + build: { + // Template for index.html + index: path.resolve(__dirname, '../dist/index.html'), + + // Paths + assetsRoot: path.resolve(__dirname, '../dist'), + assetsSubDirectory: 'static', + assetsPublicPath: '/', + + /** + * Source Maps + */ + + productionSourceMap: true, + // https://webpack.js.org/configuration/devtool/#production + devtool: '#source-map', + + // Gzip off by default as many popular static hosts such as + // Surge or Netlify already gzip all static assets for you. + // Before setting to `true`, make sure to: + // npm install --save-dev compression-webpack-plugin + productionGzip: false, + productionGzipExtensions: ['js', 'css'], + + // Run the build command with an extra argument to + // View the bundle analyzer report after build finishes: + // `npm run build --report` + // Set to `true` or `false` to always turn it on or off + bundleAnalyzerReport: process.env.npm_config_report + } +} diff --git a/fstackforum-vue/config/prod.env.js b/fstackforum-vue/config/prod.env.js new file mode 100644 index 0000000..a6f9976 --- /dev/null +++ b/fstackforum-vue/config/prod.env.js @@ -0,0 +1,4 @@ +'use strict' +module.exports = { + NODE_ENV: '"production"' +} diff --git a/fstackforum-vue/index.html b/fstackforum-vue/index.html new file mode 100644 index 0000000..13d368e --- /dev/null +++ b/fstackforum-vue/index.html @@ -0,0 +1,12 @@ + + + + + + fstackforum-vue + + +
+ + + diff --git a/fstackforum-vue/package.json b/fstackforum-vue/package.json new file mode 100644 index 0000000..a68435f --- /dev/null +++ b/fstackforum-vue/package.json @@ -0,0 +1,62 @@ +{ + "name": "fstackforum-vue", + "version": "1.0.0", + "description": "A Vue.js project", + "author": "Miles <1010933988@qq.com>", + "private": true, + "scripts": { + "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", + "start": "npm run dev", + "build": "node build/build.js" + }, + "dependencies": { + "vue": "^2.5.2", + "vue-router": "^3.0.1" + }, + "devDependencies": { + "autoprefixer": "^7.1.2", + "babel-core": "^6.22.1", + "babel-helper-vue-jsx-merge-props": "^2.0.3", + "babel-loader": "^7.1.1", + "babel-plugin-syntax-jsx": "^6.18.0", + "babel-plugin-transform-runtime": "^6.22.0", + "babel-plugin-transform-vue-jsx": "^3.5.0", + "babel-preset-env": "^1.3.2", + "babel-preset-stage-2": "^6.22.0", + "chalk": "^2.0.1", + "copy-webpack-plugin": "^4.0.1", + "css-loader": "^0.28.0", + "extract-text-webpack-plugin": "^3.0.0", + "file-loader": "^1.1.4", + "friendly-errors-webpack-plugin": "^1.6.1", + "html-webpack-plugin": "^2.30.1", + "node-notifier": "^5.1.2", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "ora": "^1.2.0", + "portfinder": "^1.0.13", + "postcss-import": "^11.0.0", + "postcss-loader": "^2.0.8", + "postcss-url": "^7.2.1", + "rimraf": "^2.6.0", + "semver": "^5.3.0", + "shelljs": "^0.7.6", + "uglifyjs-webpack-plugin": "^1.1.1", + "url-loader": "^0.5.8", + "vue-loader": "^13.3.0", + "vue-style-loader": "^3.0.1", + "vue-template-compiler": "^2.5.2", + "webpack": "^3.6.0", + "webpack-bundle-analyzer": "^2.9.0", + "webpack-dev-server": "^2.9.1", + "webpack-merge": "^4.1.0" + }, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not ie <= 8" + ] +} diff --git a/fstackforum-vue/src/App.vue b/fstackforum-vue/src/App.vue new file mode 100644 index 0000000..d74c648 --- /dev/null +++ b/fstackforum-vue/src/App.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/fstackforum-vue/src/assets/logo.png b/fstackforum-vue/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +
+

{{ msg }}

+

Essential Links

+ +

Ecosystem

+ +
+ + + + + + diff --git a/fstackforum-vue/src/main.js b/fstackforum-vue/src/main.js new file mode 100644 index 0000000..417390e --- /dev/null +++ b/fstackforum-vue/src/main.js @@ -0,0 +1,15 @@ +// The Vue build version to load with the `import` command +// (runtime-only or standalone) has been set in webpack.base.conf with an alias. +import Vue from 'vue' +import App from './App' +import router from './router' + +Vue.config.productionTip = false + +/* eslint-disable no-new */ +new Vue({ + el: '#app', + router, + components: { App }, + template: '' +}) diff --git a/fstackforum-vue/src/router/index.js b/fstackforum-vue/src/router/index.js new file mode 100644 index 0000000..5fa7f9d --- /dev/null +++ b/fstackforum-vue/src/router/index.js @@ -0,0 +1,15 @@ +import Vue from 'vue' +import Router from 'vue-router' +import HelloWorld from '@/components/HelloWorld' + +Vue.use(Router) + +export default new Router({ + routes: [ + { + path: '/', + name: 'HelloWorld', + component: HelloWorld + } + ] +}) -- Gitee From 3d18f9ee5877169156152058858b45e3441d666a Mon Sep 17 00:00:00 2001 From: Miles <1010933988@qq.com> Date: Tue, 23 Apr 2019 20:42:21 +0800 Subject: [PATCH 02/52] =?UTF-8?q?=E5=B0=81=E8=A3=85=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fstack/common/CommonConstant.java | 7 +++ src/main/java/com/fstack/common/Result.java | 44 +++++++++++++++++++ .../java/com/fstack/common/ResultCode.java | 22 ++++++++++ .../com/fstack/common/ResultGenerator.java | 24 ++++++++++ 4 files changed, 97 insertions(+) create mode 100644 src/main/java/com/fstack/common/CommonConstant.java create mode 100644 src/main/java/com/fstack/common/Result.java create mode 100644 src/main/java/com/fstack/common/ResultCode.java create mode 100644 src/main/java/com/fstack/common/ResultGenerator.java diff --git a/src/main/java/com/fstack/common/CommonConstant.java b/src/main/java/com/fstack/common/CommonConstant.java new file mode 100644 index 0000000..b63c9ce --- /dev/null +++ b/src/main/java/com/fstack/common/CommonConstant.java @@ -0,0 +1,7 @@ +package com.fstack.common; + +/** + * 项目中使用的常量 + */ +public class CommonConstant { +} diff --git a/src/main/java/com/fstack/common/Result.java b/src/main/java/com/fstack/common/Result.java new file mode 100644 index 0000000..da3984d --- /dev/null +++ b/src/main/java/com/fstack/common/Result.java @@ -0,0 +1,44 @@ +package com.fstack.common; + +import com.alibaba.fastjson.JSON; + +/** + * 统一API响应结果封装 + */ +public class Result { + private int code; + private String message; + private T data; + + public Result setCode(ResultCode resultCode) { + this.code = resultCode.code(); + return this; + } + + public int getCode() { + return code; + } + + public String getMessage() { + return message; + } + + public Result setMessage(String message) { + this.message = message; + return this; + } + + public T getData() { + return data; + } + + public Result setData(T data) { + this.data = data; + return this; + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/src/main/java/com/fstack/common/ResultCode.java b/src/main/java/com/fstack/common/ResultCode.java new file mode 100644 index 0000000..ac3f4c5 --- /dev/null +++ b/src/main/java/com/fstack/common/ResultCode.java @@ -0,0 +1,22 @@ +package com.fstack.common; + +/** + * 响应码枚举,参考HTTP状态码的语义 + */ +public enum ResultCode { + SUCCESS(200),//成功 + FAIL(400),//失败 + UNAUTHORIZED(401),//未认证(签名错误) + NOT_FOUND(404),//接口不存在 + INTERNAL_SERVER_ERROR(500);//服务器内部错误 + + private final int code; + + ResultCode(int code) { + this.code = code; + } + + public int code() { + return code; + } +} diff --git a/src/main/java/com/fstack/common/ResultGenerator.java b/src/main/java/com/fstack/common/ResultGenerator.java new file mode 100644 index 0000000..07405a4 --- /dev/null +++ b/src/main/java/com/fstack/common/ResultGenerator.java @@ -0,0 +1,24 @@ +package com.fstack.common; + +public class ResultGenerator { + private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS"; + + public static Result genSuccessResult() { + return new Result() + .setCode(ResultCode.SUCCESS) + .setMessage(DEFAULT_SUCCESS_MESSAGE); + } + + public static Result genSuccessResult(T data) { + return new Result() + .setCode(ResultCode.SUCCESS) + .setMessage(DEFAULT_SUCCESS_MESSAGE) + .setData(data); + } + + public static Result genFailResult(String message) { + return new Result() + .setCode(ResultCode.FAIL) + .setMessage(message); + } +} -- Gitee From d70b8e1358389c7a6c6270c2ac67f164a67d2198 Mon Sep 17 00:00:00 2001 From: Miles <1010933988@qq.com> Date: Tue, 23 Apr 2019 21:36:55 +0800 Subject: [PATCH 03/52] =?UTF-8?q?=E4=BD=BF=E7=94=A8vue=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E7=BD=91=E7=BB=9C=E8=AF=B7=E6=B1=82=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fstackforum-vue/package.json | 1 + fstackforum-vue/src/axios.js | 8 ++ fstackforum-vue/src/components/HelloWorld.vue | 106 ++---------------- fstackforum-vue/src/main.js | 4 +- fstackforum-vue/static/.gitkeep | 0 .../fstack/web/controller/TestController.java | 16 +++ 6 files changed, 38 insertions(+), 97 deletions(-) create mode 100644 fstackforum-vue/src/axios.js create mode 100644 fstackforum-vue/static/.gitkeep create mode 100644 src/main/java/com/fstack/web/controller/TestController.java diff --git a/fstackforum-vue/package.json b/fstackforum-vue/package.json index a68435f..d8c1ae9 100644 --- a/fstackforum-vue/package.json +++ b/fstackforum-vue/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "vue": "^2.5.2", + "vue-axios": "^2.1.4", "vue-router": "^3.0.1" }, "devDependencies": { diff --git a/fstackforum-vue/src/axios.js b/fstackforum-vue/src/axios.js new file mode 100644 index 0000000..70eb8e2 --- /dev/null +++ b/fstackforum-vue/src/axios.js @@ -0,0 +1,8 @@ +import axios from "axios"; + + +axios.defaults.timeout=60000; +axios.defaults.headers.post["Content-type"]="application/json"; + + +export default axios \ No newline at end of file diff --git a/fstackforum-vue/src/components/HelloWorld.vue b/fstackforum-vue/src/components/HelloWorld.vue index 1c19f2a..374ab88 100644 --- a/fstackforum-vue/src/components/HelloWorld.vue +++ b/fstackforum-vue/src/components/HelloWorld.vue @@ -1,85 +1,6 @@ @@ -88,26 +9,19 @@ export default { name: 'HelloWorld', data () { return { - msg: 'Welcome to Your Vue.js App' + info: null } + }, + mounted(){ + this.axios({ + method:"get", + url:"https://api.coindesk.com/v1/bpi/currentprice.json" + }).then(reponse=>this.info=reponse); } } diff --git a/fstackforum-vue/src/main.js b/fstackforum-vue/src/main.js index 417390e..41360a6 100644 --- a/fstackforum-vue/src/main.js +++ b/fstackforum-vue/src/main.js @@ -3,9 +3,11 @@ import Vue from 'vue' import App from './App' import router from './router' +import axios from './axios' +import VueAxios from "vue-axios"; Vue.config.productionTip = false - +Vue.use(VueAxios ,axios); /* eslint-disable no-new */ new Vue({ el: '#app', diff --git a/fstackforum-vue/static/.gitkeep b/fstackforum-vue/static/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/com/fstack/web/controller/TestController.java b/src/main/java/com/fstack/web/controller/TestController.java new file mode 100644 index 0000000..7a4301d --- /dev/null +++ b/src/main/java/com/fstack/web/controller/TestController.java @@ -0,0 +1,16 @@ +package com.fstack.web.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/test") +public class TestController { + + + + + + +} -- Gitee From e63cf4916f5599003bb37eae82cea89ee31e9c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 24 Apr 2019 10:05:46 +0800 Subject: [PATCH 04/52] "" --- .../com/fstack/common/CommonConstant.java | 7 --- src/main/java/com/fstack/common/Result.java | 44 ------------------- .../com/fstack/common/ResultGenerator.java | 24 ---------- 3 files changed, 75 deletions(-) delete mode 100644 src/main/java/com/fstack/common/CommonConstant.java delete mode 100644 src/main/java/com/fstack/common/Result.java delete mode 100644 src/main/java/com/fstack/common/ResultGenerator.java diff --git a/src/main/java/com/fstack/common/CommonConstant.java b/src/main/java/com/fstack/common/CommonConstant.java deleted file mode 100644 index b63c9ce..0000000 --- a/src/main/java/com/fstack/common/CommonConstant.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.fstack.common; - -/** - * 项目中使用的常量 - */ -public class CommonConstant { -} diff --git a/src/main/java/com/fstack/common/Result.java b/src/main/java/com/fstack/common/Result.java deleted file mode 100644 index da3984d..0000000 --- a/src/main/java/com/fstack/common/Result.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.fstack.common; - -import com.alibaba.fastjson.JSON; - -/** - * 统一API响应结果封装 - */ -public class Result { - private int code; - private String message; - private T data; - - public Result setCode(ResultCode resultCode) { - this.code = resultCode.code(); - return this; - } - - public int getCode() { - return code; - } - - public String getMessage() { - return message; - } - - public Result setMessage(String message) { - this.message = message; - return this; - } - - public T getData() { - return data; - } - - public Result setData(T data) { - this.data = data; - return this; - } - - @Override - public String toString() { - return JSON.toJSONString(this); - } -} diff --git a/src/main/java/com/fstack/common/ResultGenerator.java b/src/main/java/com/fstack/common/ResultGenerator.java deleted file mode 100644 index 07405a4..0000000 --- a/src/main/java/com/fstack/common/ResultGenerator.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.fstack.common; - -public class ResultGenerator { - private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS"; - - public static Result genSuccessResult() { - return new Result() - .setCode(ResultCode.SUCCESS) - .setMessage(DEFAULT_SUCCESS_MESSAGE); - } - - public static Result genSuccessResult(T data) { - return new Result() - .setCode(ResultCode.SUCCESS) - .setMessage(DEFAULT_SUCCESS_MESSAGE) - .setData(data); - } - - public static Result genFailResult(String message) { - return new Result() - .setCode(ResultCode.FAIL) - .setMessage(message); - } -} -- Gitee From d506e4b2ca9e8595c2a5d65c6341f98c606c0265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 24 Apr 2019 10:11:37 +0800 Subject: [PATCH 05/52] "" --- src/main/java/com/fstack/common/ApiResponse.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/fstack/common/ApiResponse.java b/src/main/java/com/fstack/common/ApiResponse.java index 59fe568..e132521 100644 --- a/src/main/java/com/fstack/common/ApiResponse.java +++ b/src/main/java/com/fstack/common/ApiResponse.java @@ -27,7 +27,7 @@ public class ApiResponse { public ApiResponse() { this.setSuccess(true); - this.setCode(200); + this.setCode(ResultCode.SUCCESS.code()); this.setMsg("成功!"); } @@ -46,18 +46,14 @@ public class ApiResponse { public static ApiResponse toSuccess(Object data) { - return new ApiResponse(true, 200, "success", data); + return new ApiResponse(true, ResultCode.SUCCESS.code(), "success", data); } public static ApiResponse toNotFound() { - return new ApiResponse(false, 404, "NotFound"); - } - - public static ApiResponse toPermissions(){ - return new ApiResponse(false, 6,"对不起,您没有没有权限"); + return new ApiResponse(false, ResultCode.NOT_FOUND.code(), "NotFound"); } public static ApiResponse toException(String msg) { - return new ApiResponse(false, 404, msg); + return new ApiResponse(false, ResultCode.FAIL.code(), msg); } } -- Gitee From be1d3a17ead9c03c739e2ad097cb7629f5cc58e4 Mon Sep 17 00:00:00 2001 From: Keven Date: Wed, 24 Apr 2019 12:58:25 +0800 Subject: [PATCH 06/52] =?UTF-8?q?=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=8F=8A=E5=9B=BD=E9=99=85=E5=8C=96=E9=85=8D=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E6=9D=83=E9=99=90=E9=85=8D=E7=BD=AE=E4=BF=AE=E6=AD=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fstack/common/ApiResponse.java | 3 +- src/main/java/com/fstack/common/Page.java | 26 +- .../java/com/fstack/common/ResultCode.java | 25 +- .../CustomAuthenticationFailureHandler.java | 2 +- .../security/MyUserDetailsService.java | 2 +- .../security/WebSecurityConfig.java | 4 +- .../com/fstack/constant/ExceptionMessage.java | 8 - .../java/com/fstack/constant/PageMessage.java | 19 - .../com/fstack/constant/PostConstant.java | 17 + .../java/com/fstack/constant/RoleMessage.java | 9 - .../com/fstack/constant/UserConstant.java | 15 + .../fstack/event/RegistrationListener.java | 91 ++--- .../{util => service}/EmailService.java | 2 +- .../service/impl/CategoryServiceImpl.java | 89 ++-- .../fstack/service/impl/PostServiceImpl.java | 383 +++++++++--------- src/main/java/com/fstack/util/I18nUtil.java | 68 ++++ .../com/fstack/util/NewPostFormValidator.java | 40 -- .../com/fstack/util/NewUserFormValidator.java | 76 ---- .../NewCommentFormValidator.java | 2 +- .../validator/NewPostFormValidator.java | 40 ++ .../validator/NewUserFormValidator.java | 76 ++++ .../fstack/web/controller/PostController.java | 2 +- .../fstack/web/controller/UserController.java | 2 +- src/main/resources/logback.xml | 4 +- src/main/resources/messages.properties | 18 +- src/main/resources/messages_en.properties | 13 + src/main/resources/messages_zh_CN.properties | 2 + 27 files changed, 571 insertions(+), 467 deletions(-) rename src/main/java/com/fstack/{ => config}/security/CustomAuthenticationFailureHandler.java (97%) rename src/main/java/com/fstack/{ => config}/security/MyUserDetailsService.java (97%) rename src/main/java/com/fstack/{ => config}/security/WebSecurityConfig.java (98%) delete mode 100644 src/main/java/com/fstack/constant/ExceptionMessage.java delete mode 100644 src/main/java/com/fstack/constant/PageMessage.java create mode 100644 src/main/java/com/fstack/constant/PostConstant.java delete mode 100644 src/main/java/com/fstack/constant/RoleMessage.java create mode 100644 src/main/java/com/fstack/constant/UserConstant.java rename src/main/java/com/fstack/{util => service}/EmailService.java (95%) create mode 100644 src/main/java/com/fstack/util/I18nUtil.java delete mode 100644 src/main/java/com/fstack/util/NewPostFormValidator.java delete mode 100644 src/main/java/com/fstack/util/NewUserFormValidator.java rename src/main/java/com/fstack/{util => validator}/NewCommentFormValidator.java (58%) create mode 100644 src/main/java/com/fstack/validator/NewPostFormValidator.java create mode 100644 src/main/java/com/fstack/validator/NewUserFormValidator.java create mode 100644 src/main/resources/messages_en.properties create mode 100644 src/main/resources/messages_zh_CN.properties diff --git a/src/main/java/com/fstack/common/ApiResponse.java b/src/main/java/com/fstack/common/ApiResponse.java index e132521..1e33b3d 100644 --- a/src/main/java/com/fstack/common/ApiResponse.java +++ b/src/main/java/com/fstack/common/ApiResponse.java @@ -54,6 +54,7 @@ public class ApiResponse { } public static ApiResponse toException(String msg) { - return new ApiResponse(false, ResultCode.FAIL.code(), msg); + return new ApiResponse(false, ResultCode.INTERNAL_SERVER_ERROR.code(), msg); } + } diff --git a/src/main/java/com/fstack/common/Page.java b/src/main/java/com/fstack/common/Page.java index caaee41..7eca211 100644 --- a/src/main/java/com/fstack/common/Page.java +++ b/src/main/java/com/fstack/common/Page.java @@ -3,9 +3,13 @@ package com.fstack.common; import com.google.common.collect.Lists; import lombok.Data; -import java.util.ArrayList; import java.util.List; +/** + * 数据分页 + * + * @param + */ @Data public class Page { @@ -44,13 +48,6 @@ public class Page { */ private Boolean hasCount; - /***************************************************单独的一个类对象转为分页数据 调用这个****************************************/ - public static Page singleObjectToPage(Object object) { - List list = Lists.newArrayList(); - list.add(object); - return new Page(list); - } - /***************************************************非分页list数据 调用这个****************************************/ public Page(List result) { this.setResult(result); @@ -66,7 +63,16 @@ public class Page { this.init(); } - //初始化计算分页 + /***************************************************单独的一个类对象转为分页数据 调用这个****************************************/ + public static Page singleObjectToPage(T object) { + List list = Lists.newArrayList(); + list.add(object); + return new Page<>(list); + } + + /** + * 初始化计算分页 + */ private void init() { this.setTotalPages(); } @@ -77,7 +83,7 @@ public class Page { this.totalCount = result.size(); } - public void setTotalPages() { + private void setTotalPages() { this.totalPages = (int) ((this.totalRecords % this.limit > 0) ? (this.totalRecords / this.limit + 1) : this.totalRecords / this.limit); } diff --git a/src/main/java/com/fstack/common/ResultCode.java b/src/main/java/com/fstack/common/ResultCode.java index ac3f4c5..c155bd8 100644 --- a/src/main/java/com/fstack/common/ResultCode.java +++ b/src/main/java/com/fstack/common/ResultCode.java @@ -4,11 +4,26 @@ package com.fstack.common; * 响应码枚举,参考HTTP状态码的语义 */ public enum ResultCode { - SUCCESS(200),//成功 - FAIL(400),//失败 - UNAUTHORIZED(401),//未认证(签名错误) - NOT_FOUND(404),//接口不存在 - INTERNAL_SERVER_ERROR(500);//服务器内部错误 + /** + * success + */ + SUCCESS(200), + /** + * Bad Request + */ + FAIL(400), + /** + * unauthorized request + */ + UNAUTHORIZED(401), + /** + * not found + */ + NOT_FOUND(404), + /** + * server internal error + */ + INTERNAL_SERVER_ERROR(500); private final int code; diff --git a/src/main/java/com/fstack/security/CustomAuthenticationFailureHandler.java b/src/main/java/com/fstack/config/security/CustomAuthenticationFailureHandler.java similarity index 97% rename from src/main/java/com/fstack/security/CustomAuthenticationFailureHandler.java rename to src/main/java/com/fstack/config/security/CustomAuthenticationFailureHandler.java index 517aa13..f122fcc 100644 --- a/src/main/java/com/fstack/security/CustomAuthenticationFailureHandler.java +++ b/src/main/java/com/fstack/config/security/CustomAuthenticationFailureHandler.java @@ -1,4 +1,4 @@ -package com.fstack.security; +package com.fstack.config.security; import java.io.IOException; import java.util.Locale; diff --git a/src/main/java/com/fstack/security/MyUserDetailsService.java b/src/main/java/com/fstack/config/security/MyUserDetailsService.java similarity index 97% rename from src/main/java/com/fstack/security/MyUserDetailsService.java rename to src/main/java/com/fstack/config/security/MyUserDetailsService.java index 4cfcd4e..878d8d0 100644 --- a/src/main/java/com/fstack/security/MyUserDetailsService.java +++ b/src/main/java/com/fstack/config/security/MyUserDetailsService.java @@ -1,4 +1,4 @@ -package com.fstack.security; +package com.fstack.config.security; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/fstack/security/WebSecurityConfig.java b/src/main/java/com/fstack/config/security/WebSecurityConfig.java similarity index 98% rename from src/main/java/com/fstack/security/WebSecurityConfig.java rename to src/main/java/com/fstack/config/security/WebSecurityConfig.java index 2c39344..65950a8 100644 --- a/src/main/java/com/fstack/security/WebSecurityConfig.java +++ b/src/main/java/com/fstack/config/security/WebSecurityConfig.java @@ -1,4 +1,4 @@ -package com.fstack.security; +package com.fstack.config.security; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -48,7 +48,6 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable().authorizeRequests() - .anyRequest().authenticated() // all static resource and home page .antMatchers("/", "/avatar/**", "/", "/js/**", "/css/**", "/images/**", "/fonts/**", "/bootstrap-select/**", "/bootstrap-datetimepicker/**", "/custom/**", "/daterangepicker/**", "/chartjs/**").permitAll() @@ -60,6 +59,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/user/**").permitAll() // all categories are allowed to be viewed without authentication .antMatchers("/category/**").permitAll() + .anyRequest().authenticated() // login URL can be accessed by anyone .and() .formLogin().loginPage("/user/login").permitAll() diff --git a/src/main/java/com/fstack/constant/ExceptionMessage.java b/src/main/java/com/fstack/constant/ExceptionMessage.java deleted file mode 100644 index f383bcf..0000000 --- a/src/main/java/com/fstack/constant/ExceptionMessage.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.fstack.constant; - -/** - * @author ab - */ -public class ExceptionMessage { - -} diff --git a/src/main/java/com/fstack/constant/PageMessage.java b/src/main/java/com/fstack/constant/PageMessage.java deleted file mode 100644 index 59ab45a..0000000 --- a/src/main/java/com/fstack/constant/PageMessage.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.fstack.constant; - -/** - * @author ab - */ -public class PageMessage { - public static String MESSAGE_NEW_POST_CN = "新帖子"; - public static String MESSAGE_NEW_POST_EN = "New Post"; - - public static String MESSAGE_HOMEPAGE_TITLE_CN = "首页"; - public static String MESSAGE_HOMEPAGE_TITLE_EN = "Home Page"; - - public static String MESSAGE_NEW_POST_TITLE_CN = "发表新帖"; - public static String MESSAGE_NEW_POST_TITLE_EN = "New Post"; - - public static String MESSAGE_POST_BY_CATEGORY_TITLE_CN = "根据节点"; - public static String MESSAGE_POST_BY_CATEGORY_TITLE_EN = "By category"; - -} diff --git a/src/main/java/com/fstack/constant/PostConstant.java b/src/main/java/com/fstack/constant/PostConstant.java new file mode 100644 index 0000000..7e9e324 --- /dev/null +++ b/src/main/java/com/fstack/constant/PostConstant.java @@ -0,0 +1,17 @@ +package com.fstack.constant; + +/** + * @author Hu Jie + * @date 2019/04/24 11:10 AM + */ +public class PostConstant { + + public static final int TITLE_LENGTH_MAX = 30; + public static final int TITLE_LENGTH_MIN = 3; + + public static final int BODY_LENGTH_MAX = 100; + public static final int BODY_LENGTH_MIN = 3; + + private PostConstant() { + } +} diff --git a/src/main/java/com/fstack/constant/RoleMessage.java b/src/main/java/com/fstack/constant/RoleMessage.java deleted file mode 100644 index 5e1e703..0000000 --- a/src/main/java/com/fstack/constant/RoleMessage.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.fstack.constant; - -/** - * @author ab - */ -public class RoleMessage { - public static String USER = "USER"; - public static String ADMIN = "ADMIN"; -} diff --git a/src/main/java/com/fstack/constant/UserConstant.java b/src/main/java/com/fstack/constant/UserConstant.java new file mode 100644 index 0000000..07a02b0 --- /dev/null +++ b/src/main/java/com/fstack/constant/UserConstant.java @@ -0,0 +1,15 @@ +package com.fstack.constant; + +/** + * @author Hu Jie + * @date 2019/04/24 11:16 AM + */ +public class UserConstant { + public static final int USERNAME_LENGTH_MAX = 10; + public static final int USERNAME_LENGTH_MIN = 3; + public static final int PASSOWRD_LENGTH_MAX = 32; + public static final int PASSOWRD_LENGTH_MIN = 6; + + private UserConstant() { + } +} diff --git a/src/main/java/com/fstack/event/RegistrationListener.java b/src/main/java/com/fstack/event/RegistrationListener.java index ce102ef..b5e3918 100644 --- a/src/main/java/com/fstack/event/RegistrationListener.java +++ b/src/main/java/com/fstack/event/RegistrationListener.java @@ -1,7 +1,10 @@ package com.fstack.event; -import java.util.UUID; - +import com.fstack.persistence.dao.UserMapper; +import com.fstack.persistence.dao.VerificationTokenMapper; +import com.fstack.persistence.model.User; +import com.fstack.persistence.model.VerificationToken; +import com.fstack.service.EmailService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -10,11 +13,7 @@ import org.springframework.context.ApplicationListener; import org.springframework.mail.SimpleMailMessage; import org.springframework.stereotype.Component; -import com.fstack.persistence.dao.UserMapper; -import com.fstack.persistence.dao.VerificationTokenMapper; -import com.fstack.persistence.model.User; -import com.fstack.persistence.model.VerificationToken; -import com.fstack.util.EmailService; +import java.util.UUID; /** * @author ab @@ -22,55 +21,55 @@ import com.fstack.util.EmailService; @Component public class RegistrationListener implements ApplicationListener { - private static final String VERIFICATION_EMAIL_FROM_ADDR = "672943942@qq.com"; + private static final String VERIFICATION_EMAIL_FROM_ADDR = "672943942@qq.com"; - private static final String VERIFICATION_EMAIL_SUBJECT = "用户注册确认"; + private static final String VERIFICATION_EMAIL_SUBJECT = "用户注册确认"; - private static final String CONFIRM_ENDPOINT = "registration-confirm"; + private static final String CONFIRM_ENDPOINT = "registration-confirm"; - private static final Logger logger = LoggerFactory.getLogger(RegistrationListener.class); + private static final Logger logger = LoggerFactory.getLogger(RegistrationListener.class); - @Autowired - private VerificationTokenMapper verificationTokenMapper; + @Autowired + private VerificationTokenMapper verificationTokenMapper; - @Autowired - private EmailService emailService; + @Autowired + private EmailService emailService; - @Autowired - private UserMapper userMapper; + @Autowired + private UserMapper userMapper; - @Value("${service.url}") - private String serviceUrl; + @Value("${service.url}") + private String serviceUrl; - @Override - public void onApplicationEvent(final OnRegistrationCompleteEvent event) { - this.confirmRegistration(event); - } + @Override + public void onApplicationEvent(final OnRegistrationCompleteEvent event) { + this.confirmRegistration(event); + } - private void confirmRegistration(final OnRegistrationCompleteEvent event) { - logger.info("confirmRegistration() >> " + event); - String username = event.getUsername(); - this.createUserVerificationToken(username); - } + private void confirmRegistration(final OnRegistrationCompleteEvent event) { + logger.info("confirmRegistration() >> " + event); + String username = event.getUsername(); + this.createUserVerificationToken(username); + } - private void createUserVerificationToken(String username) { - String token = UUID.randomUUID().toString(); // token string - User user = this.userMapper.findByUsername(username); - VerificationToken verificationToken = new VerificationToken(user, token); - this.verificationTokenMapper.save(verificationToken); + private void createUserVerificationToken(String username) { + String token = UUID.randomUUID().toString(); + User user = this.userMapper.findByUsername(username); + VerificationToken verificationToken = new VerificationToken(user, token); + this.verificationTokenMapper.save(verificationToken); - // construct verification email - SimpleMailMessage email = new SimpleMailMessage(); + // construct verification email + SimpleMailMessage email = new SimpleMailMessage(); - // confirmation link in email - String confirmationLink = serviceUrl + "/user/" + CONFIRM_ENDPOINT + "?token=" + token; - System.out.println("confirmation link >> " + confirmationLink); - email.setFrom(VERIFICATION_EMAIL_FROM_ADDR); - email.setSubject(VERIFICATION_EMAIL_SUBJECT); - email.setText(confirmationLink); - email.setTo(user.getEmail()); -// TODO: 2019/4/18 - // send email asynchronously - this.emailService.sendEmail(email); - } + // confirmation link in email + String confirmationLink = serviceUrl + "/user/" + CONFIRM_ENDPOINT + "?token=" + token; + System.out.println("confirmation link >> " + confirmationLink); + email.setFrom(VERIFICATION_EMAIL_FROM_ADDR); + email.setSubject(VERIFICATION_EMAIL_SUBJECT); + email.setText(confirmationLink); + email.setTo(user.getEmail()); + // TODO: 2019/4/18 + // send email asynchronously + this.emailService.sendEmail(email); + } } diff --git a/src/main/java/com/fstack/util/EmailService.java b/src/main/java/com/fstack/service/EmailService.java similarity index 95% rename from src/main/java/com/fstack/util/EmailService.java rename to src/main/java/com/fstack/service/EmailService.java index f8cea1b..cf72d79 100644 --- a/src/main/java/com/fstack/util/EmailService.java +++ b/src/main/java/com/fstack/service/EmailService.java @@ -1,4 +1,4 @@ -package com.fstack.util; +package com.fstack.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.SimpleMailMessage; diff --git a/src/main/java/com/fstack/service/impl/CategoryServiceImpl.java b/src/main/java/com/fstack/service/impl/CategoryServiceImpl.java index 9f0e1c1..679cd71 100644 --- a/src/main/java/com/fstack/service/impl/CategoryServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/CategoryServiceImpl.java @@ -1,55 +1,58 @@ package com.fstack.service.impl; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.fstack.constant.PageMessage; import com.fstack.persistence.dao.CategoryMapper; import com.fstack.persistence.model.Category; import com.fstack.service.CategoryService; +import com.fstack.util.I18nUtil; import com.fstack.web.dto.PostDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @Service("categoryService") public class CategoryServiceImpl implements CategoryService { - @Autowired - private CategoryMapper categoryMapper; - - @Override - public int save(Category category) { - return this.categoryMapper.save(category); - } - - @Override - public Map getNewPostPageWithCategoryName(String categoryName) { - Map attributes = new HashMap<>(); - Category category = this.categoryMapper.findByName(categoryName); - attributes.put("title", PageMessage.MESSAGE_NEW_POST_CN); - PostDto newPostForm = new PostDto(); - newPostForm.setCategory(category.getName()); - attributes.put("postDto", newPostForm); - attributes.put("isQuickNewPost", false); - return attributes; - } - - @Override - public Map getNewPostPageWithCategorySelect() { - List categories = this.categoryMapper.findAll(); - Map attributes = new HashMap<>(); - attributes.put("title", PageMessage.MESSAGE_NEW_POST_CN); - attributes.put("categories", categories); - attributes.put("postDto", new PostDto()); - attributes.put("isQuickNewPost", true); - return attributes; - } - - @Override - public List findAll() { - return this.categoryMapper.findAll(); - } + @Autowired + private CategoryMapper categoryMapper; + + @Resource + private I18nUtil i18nUtil; + + @Override + public Map getNewPostPageWithCategoryName(String categoryName) { + Map attributes = new HashMap<>(); + Category category = this.categoryMapper.findByName(categoryName); + attributes.put("title", i18nUtil.getMessage("")); + PostDto newPostForm = new PostDto(); + newPostForm.setCategory(category.getName()); + attributes.put("postDto", newPostForm); + attributes.put("isQuickNewPost", false); + return attributes; + } + + @Override + public Map getNewPostPageWithCategorySelect() { + List categories = this.categoryMapper.findAll(); + Map attributes = new HashMap<>(); + attributes.put("title", i18nUtil.getMessage("post.new")); + attributes.put("categories", categories); + attributes.put("postDto", new PostDto()); + attributes.put("isQuickNewPost", true); + return attributes; + } + + @Override + public int save(Category category) { + return this.categoryMapper.save(category); + } + + @Override + public List findAll() { + return this.categoryMapper.findAll(); + } } diff --git a/src/main/java/com/fstack/service/impl/PostServiceImpl.java b/src/main/java/com/fstack/service/impl/PostServiceImpl.java index 549c8f5..d9f260d 100644 --- a/src/main/java/com/fstack/service/impl/PostServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/PostServiceImpl.java @@ -1,21 +1,5 @@ package com.fstack.service.impl; -import java.sql.Timestamp; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import com.github.pagehelper.PageHelper; -import com.github.pagehelper.PageInfo; -import com.fstack.constant.PageMessage; import com.fstack.persistence.dao.CategoryMapper; import com.fstack.persistence.dao.CommentMapper; import com.fstack.persistence.dao.PostMapper; @@ -25,187 +9,204 @@ import com.fstack.persistence.model.Comment; import com.fstack.persistence.model.Post; import com.fstack.persistence.model.User; import com.fstack.service.PostService; +import com.fstack.util.I18nUtil; import com.fstack.web.dto.CommentDto; import com.fstack.web.dto.PostDto; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.sql.Timestamp; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @Service("postService") @Transactional public class PostServiceImpl implements PostService { - private static final Logger logger = LoggerFactory.getLogger(PostServiceImpl.class); - - // private static String CACHE_ID_PREFIX = "POST_"; - - // private static int EXPIRATION_TIME_IN_MINUTES = 15; - - // @Autowired - // private RedisTemplate redisTemplate; - - @Autowired - private PostMapper postMapper; - - @Autowired - private UserMapper userMapper; - - @Autowired - private CategoryMapper categoryMapper; - - @Autowired - private CommentMapper commentMapper; - - @Override - public void save(Post post) { - this.postMapper.save(post); - } - - @Override - public void delete(Long postId) { - this.postMapper.delete(postId); - } - - @Override - public void update(Post post) { - this.postMapper.update(post); - } - - @Override - public Post findById(Long id) { - // left for future implementation - // - // ValueOperations operations = redisTemplate.opsForValue(); - // String key = CACHE_ID_PREFIX + id; - // - // // retrieve from cache if exists in cache - // boolean hasKey = redisTemplate.hasKey(key); - // if (hasKey) { - // Post post = (Post) operations.get(key); - // logger.info("PostServiceImpl.findById() : retrieve from cache >> id: " + - // post.getId()); - // return post; - // } - // - // // retrieve from database if not exists in cache - // Post post = this.postMapper.findById(id); - // operations.set(key, post, EXPIRATION_TIME_IN_MINUTES, TimeUnit.MINUTES); - // logger.info("PostServiceImpl.findById() : retrieve from database >> id: " + - // post.getId()); - - Post post = this.postMapper.findById(id); - return post; - } - - @Override - public Map findPosts() { - List posts = this.postMapper.findAll(); - Map attributes = new HashMap<>(); - attributes.put("posts", posts); - return attributes; - } - - @Override - public Map findPostDetailsAndCommentsByPostId(Long postId) { - Post post = this.postMapper.findById(postId); - if (null == post) { - return null; - } - List comments = this.commentMapper.findCommentsByPostId(postId); - // increase hit count by one - post.setHitCount(post.getHitCount() == null ? 1 : post.getHitCount() + 1); - this.postMapper.update(post); - // load attributes map - Map attributes = new HashMap<>(); - attributes.put("post", post); - attributes.put("title", post.getTitle()); - attributes.put("comments", comments); - attributes.put("commentDto", new CommentDto()); - return attributes; - } - - @Override - public Post createNewPost(PostDto newPostForm) { - // find authenticated user - Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - String username = auth.getName(); - User user = this.userMapper.findByUsername(username); - // find category - String categoryName = newPostForm.getCategory().replace(",", ""); - Category category = this.categoryMapper.findByName(categoryName); - // construct new post - Post post = new Post(); - post.setTitle(newPostForm.getTitle()); - post.setBody(newPostForm.getBody()); - post.setCategory(category); - post.setDateCreated(new Timestamp(System.currentTimeMillis())); - post.setUser(user); - return post; - } - - @Override - public Map findPostsByPage(int currPage, int pageSize) { - // find posts by page - PageHelper.startPage(currPage, pageSize); - List posts = this.postMapper.findAll(); - PageInfo postsPageInfo = new PageInfo<>(posts); - // find categories - List categories = this.categoryMapper.findAll(); - // construct attributes map - Map attributes = new HashMap<>(); - attributes.put("title", PageMessage.MESSAGE_HOMEPAGE_TITLE_CN); - attributes.put("categories", categories); - attributes.put("posts", postsPageInfo.getList()); - attributes.put("pageNum", postsPageInfo.getPageNum()); - attributes.put("isFirstPage", postsPageInfo.isIsFirstPage()); - attributes.put("isLastPage", postsPageInfo.isIsLastPage()); - attributes.put("totalPages", postsPageInfo.getPages()); - attributes.put("pageType", "homePage"); - return attributes; - } - - @Override - public Map findPostsListByCategoryByPage(String categoryName, int currPage, int pageSize) { - // find posts by page - PageHelper.startPage(currPage, pageSize); - List posts = this.postMapper.findPostsByCategory(categoryName); - PageInfo postsPageInfo = new PageInfo<>(posts); - // find categories - List categories = this.categoryMapper.findAll(); - // find category details - Category category = this.categoryMapper.findByName(categoryName); - // construct attributes map - Map attributes = new HashMap<>(); - attributes.put("title", PageMessage.MESSAGE_HOMEPAGE_TITLE_CN); - attributes.put("category", category); - attributes.put("categories", categories); - attributes.put("posts", postsPageInfo.getList()); - attributes.put("pageNum", postsPageInfo.getPageNum()); - attributes.put("isFirstPage", postsPageInfo.isIsFirstPage()); - attributes.put("isLastPage", postsPageInfo.isIsLastPage()); - attributes.put("totalPages", postsPageInfo.getPages()); - attributes.put("pageType", "categoryPage"); - return attributes; - } - - @Override - public int deletePostAndComments(Long postId) { - if (null == postId) { - return 0; - } - // delete comment related to post - int commentDeletedRows = this.commentMapper.deleteCommentsByPostId(postId); - // delete post by id - int postDeletedRows = this.postMapper.delete(postId); - return postDeletedRows + commentDeletedRows; - } - - @Override - public Map findPostsBetweenDateRange(String start, String end) { - if (null == start && null == end) { - return null; - } - List posts = this.postMapper.findPostsBetweenRange(start + " 00:00:00", end + " 23:59:59"); - Map attributes = new HashMap<>(); - attributes.put("posts", posts); - return attributes; - } + private static final Logger logger = LoggerFactory.getLogger(PostServiceImpl.class); + + // private static String CACHE_ID_PREFIX = "POST_"; + + // private static int EXPIRATION_TIME_IN_MINUTES = 15; + + // @Autowired + // private RedisTemplate redisTemplate; + + @Autowired + private PostMapper postMapper; + + @Autowired + private UserMapper userMapper; + + @Autowired + private CategoryMapper categoryMapper; + + @Autowired + private CommentMapper commentMapper; + @Autowired + private I18nUtil i18nUtil; + + @Override + public void save(Post post) { + this.postMapper.save(post); + } + + @Override + public void delete(Long postId) { + this.postMapper.delete(postId); + } + + @Override + public void update(Post post) { + this.postMapper.update(post); + } + + @Override + public Post findById(Long id) { + // left for future implementation + // + // ValueOperations operations = redisTemplate.opsForValue(); + // String key = CACHE_ID_PREFIX + id; + // + // // retrieve from cache if exists in cache + // boolean hasKey = redisTemplate.hasKey(key); + // if (hasKey) { + // Post post = (Post) operations.get(key); + // logger.info("PostServiceImpl.findById() : retrieve from cache >> id: " + + // post.getId()); + // return post; + // } + // + // // retrieve from database if not exists in cache + // Post post = this.postMapper.findById(id); + // operations.set(key, post, EXPIRATION_TIME_IN_MINUTES, TimeUnit.MINUTES); + // logger.info("PostServiceImpl.findById() : retrieve from database >> id: " + + // post.getId()); + + Post post = this.postMapper.findById(id); + return post; + } + + @Override + public Post createNewPost(PostDto newPostForm) { + // find authenticated user + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + String username = auth.getName(); + User user = this.userMapper.findByUsername(username); + // find category + String categoryName = newPostForm.getCategory().replace(",", ""); + Category category = this.categoryMapper.findByName(categoryName); + // construct new post + Post post = new Post(); + post.setTitle(newPostForm.getTitle()); + post.setBody(newPostForm.getBody()); + post.setCategory(category); + post.setDateCreated(new Timestamp(System.currentTimeMillis())); + post.setUser(user); + return post; + } + + @Override + public int deletePostAndComments(Long postId) { + if (null == postId) { + return 0; + } + // delete comment related to post + int commentDeletedRows = this.commentMapper.deleteCommentsByPostId(postId); + // delete post by id + int postDeletedRows = this.postMapper.delete(postId); + return postDeletedRows + commentDeletedRows; + } + + @Override + public Map findPosts() { + List posts = this.postMapper.findAll(); + Map attributes = new HashMap<>(); + attributes.put("posts", posts); + return attributes; + } + + @Override + public Map findPostsByPage(int currPage, int pageSize) { + // find posts by page + PageHelper.startPage(currPage, pageSize); + List posts = this.postMapper.findAll(); + PageInfo postsPageInfo = new PageInfo<>(posts); + // find categories + List categories = this.categoryMapper.findAll(); + // construct attributes map + Map attributes = new HashMap<>(); + attributes.put("title", i18nUtil.getMessage("homepage.title")); + attributes.put("categories", categories); + attributes.put("posts", postsPageInfo.getList()); + attributes.put("pageNum", postsPageInfo.getPageNum()); + attributes.put("isFirstPage", postsPageInfo.isIsFirstPage()); + attributes.put("isLastPage", postsPageInfo.isIsLastPage()); + attributes.put("totalPages", postsPageInfo.getPages()); + attributes.put("pageType", "homePage"); + return attributes; + } + + @Override + public Map findPostsListByCategoryByPage(String categoryName, int currPage, int pageSize) { + // find posts by page + PageHelper.startPage(currPage, pageSize); + List posts = this.postMapper.findPostsByCategory(categoryName); + PageInfo postsPageInfo = new PageInfo<>(posts); + // find categories + List categories = this.categoryMapper.findAll(); + // find category details + Category category = this.categoryMapper.findByName(categoryName); + // construct attributes map + Map attributes = new HashMap<>(); + attributes.put("title", i18nUtil.getMessage("homepage.title")); + attributes.put("category", category); + attributes.put("categories", categories); + attributes.put("posts", postsPageInfo.getList()); + attributes.put("pageNum", postsPageInfo.getPageNum()); + attributes.put("isFirstPage", postsPageInfo.isIsFirstPage()); + attributes.put("isLastPage", postsPageInfo.isIsLastPage()); + attributes.put("totalPages", postsPageInfo.getPages()); + attributes.put("pageType", "categoryPage"); + return attributes; + } + + @Override + public Map findPostDetailsAndCommentsByPostId(Long postId) { + Post post = this.postMapper.findById(postId); + if (null == post) { + return null; + } + List comments = this.commentMapper.findCommentsByPostId(postId); + // increase hit count by one + post.setHitCount(post.getHitCount() == null ? 1 : post.getHitCount() + 1); + this.postMapper.update(post); + // load attributes map + Map attributes = new HashMap<>(); + attributes.put("post", post); + attributes.put("title", post.getTitle()); + attributes.put("comments", comments); + attributes.put("commentDto", new CommentDto()); + return attributes; + } + + @Override + public Map findPostsBetweenDateRange(String start, String end) { + if (null == start && null == end) { + return null; + } + List posts = this.postMapper.findPostsBetweenRange(start + " 00:00:00", end + " 23:59:59"); + Map attributes = new HashMap<>(); + attributes.put("posts", posts); + return attributes; + } } diff --git a/src/main/java/com/fstack/util/I18nUtil.java b/src/main/java/com/fstack/util/I18nUtil.java new file mode 100644 index 0000000..a4af2cf --- /dev/null +++ b/src/main/java/com/fstack/util/I18nUtil.java @@ -0,0 +1,68 @@ +package com.fstack.util; + +import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; +import org.springframework.web.servlet.support.RequestContextUtils; + +import javax.annotation.Resource; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.util.Locale; + +/** + * @author fantome + * @date 9/4/17 + */ +@Component +public class I18nUtil { + + @Resource + private HttpServletRequest request; + + @Resource + private HttpSession session; + + public String getMessage(String code) { + if (code == null) { + return null; + } else { + ServletContext servletContext = this.request.getServletContext(); + WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext); + Locale locale = RequestContextUtils.getLocale(this.request); + return applicationContext.getMessage(code, null, locale); + } + } + + public String getMessage(String code, Object[] args) { + if (code == null) { + return null; + } else { + ServletContext servletContext = this.request.getServletContext(); + WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext); + Locale locale = RequestContextUtils.getLocale(this.request); + return applicationContext.getMessage(code, args, locale); + } + } + + public String getMessage(String code, Object[] args, String defaultMessage) { + if (code == null) { + return null; + } else { + ServletContext servletContext = this.request.getServletContext(); + WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext); + Locale locale = RequestContextUtils.getLocale(this.request); + return applicationContext.getMessage(code, args, defaultMessage, locale); + } + } + + + public HttpServletRequest getRequest() { + return request; + } + + public HttpSession getSession() { + return session; + } +} diff --git a/src/main/java/com/fstack/util/NewPostFormValidator.java b/src/main/java/com/fstack/util/NewPostFormValidator.java deleted file mode 100644 index 74db8bf..0000000 --- a/src/main/java/com/fstack/util/NewPostFormValidator.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.fstack.util; - -import org.springframework.stereotype.Component; -import org.springframework.validation.Errors; -import org.springframework.validation.ValidationUtils; -import org.springframework.validation.Validator; - -import com.fstack.persistence.model.Post; - -@Component -public class NewPostFormValidator implements Validator { - - @Override - public boolean supports(Class clazz) { - return Post.class.equals(clazz); - } - - @Override - public void validate(Object object, Errors errors) { - Post newPost = (Post) object; - - // new post title validation - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "title", "NotEmpty"); - if (newPost.getTitle() != null && !newPost.getTitle().isEmpty()) { - if (newPost.getTitle().length() < 3 || newPost.getTitle().length() > 30) { - errors.rejectValue("title", "Size.post.title"); - } - } - - // new post body validation - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "body", "NotEmpty"); - if (newPost.getBody() != null && !newPost.getBody().isEmpty()) { - if (newPost.getBody().length() < 3 || newPost.getBody().length() > 100) { - errors.rejectValue("body", "Size.post.body"); - } - } - - } - -} \ No newline at end of file diff --git a/src/main/java/com/fstack/util/NewUserFormValidator.java b/src/main/java/com/fstack/util/NewUserFormValidator.java deleted file mode 100644 index 909be6e..0000000 --- a/src/main/java/com/fstack/util/NewUserFormValidator.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.fstack.util; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.validation.Errors; -import org.springframework.validation.ValidationUtils; -import org.springframework.validation.Validator; - -import com.fstack.persistence.model.User; -import com.fstack.service.UserService; -import com.fstack.web.dto.UserRegistrationDto; - -@Component -public class NewUserFormValidator implements Validator { - - private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; - - @Autowired - private UserService userService; - - @Override - public boolean supports(Class aClass) { - return User.class.equals(aClass); - } - - @Override - public void validate(Object object, Errors errors) { - UserRegistrationDto userForm = (UserRegistrationDto) object; - - // username validation - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "username", "NotEmpty"); - if (userForm.getUsername() != null && !userForm.getUsername().isEmpty()) { - if (userForm.getUsername().length() < 3 || userForm.getUsername().length() > 10) { - errors.rejectValue("username", "Size.userForm.username"); - } - if (null != userService.findByUsername(userForm.getUsername())) { - errors.rejectValue("username", "Duplicate.userForm.username"); - } - } - - // email validation - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "email", "NotEmpty"); - if (userForm.getEmail() != null && !userForm.getEmail().isEmpty()) { - Pattern pattern = Pattern.compile(EMAIL_PATTERN); - Matcher matcher = pattern.matcher(userForm.getEmail()); - if (!matcher.matches()) { - errors.rejectValue("email", "Invalid.userForm.email"); - } - if (null != userService.findByEmail(userForm.getEmail())) { - errors.rejectValue("email", "Duplicate.userForm.email"); - } - } - - // password validation - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "NotEmpty"); - if (userForm.getPassword() != null && !userForm.getPassword().isEmpty()) { - if (userForm.getPassword().length() < 3 || userForm.getPassword().length() > 32) { - errors.rejectValue("password", "Size.userForm.password"); - } - } - - // password confirmation validation - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "matchingPassword", "NotEmpty"); - if (userForm.getMatchingPassword() != null && !userForm.getMatchingPassword().isEmpty()) { - if (userForm.getMatchingPassword().length() < 3 || userForm.getMatchingPassword().length() > 32) { - errors.rejectValue("matchingPassword", "Size.userForm.password"); - } - if (!userForm.getMatchingPassword().equals(userForm.getPassword())) { - errors.rejectValue("matchingPassword", "Diff.userForm.matchingPassword"); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/fstack/util/NewCommentFormValidator.java b/src/main/java/com/fstack/validator/NewCommentFormValidator.java similarity index 58% rename from src/main/java/com/fstack/util/NewCommentFormValidator.java rename to src/main/java/com/fstack/validator/NewCommentFormValidator.java index 9a2af36..d1f79b2 100644 --- a/src/main/java/com/fstack/util/NewCommentFormValidator.java +++ b/src/main/java/com/fstack/validator/NewCommentFormValidator.java @@ -1,4 +1,4 @@ -package com.fstack.util; +package com.fstack.validator; public class NewCommentFormValidator { diff --git a/src/main/java/com/fstack/validator/NewPostFormValidator.java b/src/main/java/com/fstack/validator/NewPostFormValidator.java new file mode 100644 index 0000000..8ca0804 --- /dev/null +++ b/src/main/java/com/fstack/validator/NewPostFormValidator.java @@ -0,0 +1,40 @@ +package com.fstack.validator; + +import com.fstack.constant.PostConstant; +import com.fstack.persistence.model.Post; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.ValidationUtils; +import org.springframework.validation.Validator; + +@Component +public class NewPostFormValidator implements Validator { + + @Override + public boolean supports(Class clazz) { + return Post.class.equals(clazz); + } + + @Override + public void validate(Object object, Errors errors) { + Post newPost = (Post) object; + + // new post title validation + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "title", "NotEmpty"); + if (newPost.getTitle() != null && !newPost.getTitle().isEmpty()) { + if (newPost.getTitle().length() < PostConstant.TITLE_LENGTH_MIN || newPost.getTitle().length() > PostConstant.TITLE_LENGTH_MAX) { + errors.rejectValue("title", "post.title.length"); + } + } + + // new post body validation + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "body", "NotEmpty"); + if (newPost.getBody() != null && !newPost.getBody().isEmpty()) { + if (newPost.getBody().length() < PostConstant.BODY_LENGTH_MIN || newPost.getBody().length() > PostConstant.BODY_LENGTH_MAX) { + errors.rejectValue("body", "post.body.length"); + } + } + + } + +} \ No newline at end of file diff --git a/src/main/java/com/fstack/validator/NewUserFormValidator.java b/src/main/java/com/fstack/validator/NewUserFormValidator.java new file mode 100644 index 0000000..fb63ea6 --- /dev/null +++ b/src/main/java/com/fstack/validator/NewUserFormValidator.java @@ -0,0 +1,76 @@ +package com.fstack.validator; + +import com.fstack.constant.UserConstant; +import com.fstack.persistence.model.User; +import com.fstack.service.UserService; +import com.fstack.web.dto.UserRegistrationDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.ValidationUtils; +import org.springframework.validation.Validator; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Component +public class NewUserFormValidator implements Validator { + + private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; + + @Autowired + private UserService userService; + + @Override + public boolean supports(Class aClass) { + return User.class.equals(aClass); + } + + @Override + public void validate(Object object, Errors errors) { + UserRegistrationDto userForm = (UserRegistrationDto) object; + + // username validation + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "username", "NotEmpty"); + if (userForm.getUsername() != null && !userForm.getUsername().isEmpty()) { + if (userForm.getUsername().length() < UserConstant.USERNAME_LENGTH_MIN || userForm.getUsername().length() > UserConstant.USERNAME_LENGTH_MAX) { + errors.rejectValue("username", "userForm.username.length"); + } + if (null != userService.findByUsername(userForm.getUsername())) { + errors.rejectValue("username", "userForm.username.duplicate"); + } + } + + // email validation + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "email", "NotEmpty"); + if (userForm.getEmail() != null && !userForm.getEmail().isEmpty()) { + Pattern pattern = Pattern.compile(EMAIL_PATTERN); + Matcher matcher = pattern.matcher(userForm.getEmail()); + if (!matcher.matches()) { + errors.rejectValue("email", "userForm.email.invalid"); + } + if (null != userService.findByEmail(userForm.getEmail())) { + errors.rejectValue("email", "userForm.email.duplicate"); + } + } + + // password validation + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "NotEmpty"); + if (userForm.getPassword() != null && !userForm.getPassword().isEmpty()) { + if (userForm.getPassword().length() < UserConstant.PASSOWRD_LENGTH_MIN || userForm.getPassword().length() > UserConstant.PASSOWRD_LENGTH_MAX) { + errors.rejectValue("password", "userForm.password.length"); + } + } + + // password confirmation validation + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "matchingPassword", "NotEmpty"); + if (userForm.getMatchingPassword() != null && !userForm.getMatchingPassword().isEmpty()) { + if (userForm.getMatchingPassword().length() < UserConstant.PASSOWRD_LENGTH_MIN || userForm.getMatchingPassword().length() > UserConstant.PASSOWRD_LENGTH_MAX) { + errors.rejectValue("matchingPassword", "userForm.password.length"); + } + if (!userForm.getMatchingPassword().equals(userForm.getPassword())) { + errors.rejectValue("matchingPassword", "userForm.password.diff"); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/fstack/web/controller/PostController.java b/src/main/java/com/fstack/web/controller/PostController.java index f63556e..63d71e5 100644 --- a/src/main/java/com/fstack/web/controller/PostController.java +++ b/src/main/java/com/fstack/web/controller/PostController.java @@ -23,7 +23,7 @@ import com.fstack.persistence.model.Post; import com.fstack.service.CategoryService; import com.fstack.service.CommentService; import com.fstack.service.PostService; -import com.fstack.util.NewPostFormValidator; +import com.fstack.validator.NewPostFormValidator; import com.fstack.web.dto.CommentDto; import com.fstack.web.dto.PostDto; diff --git a/src/main/java/com/fstack/web/controller/UserController.java b/src/main/java/com/fstack/web/controller/UserController.java index e5bd08a..21f08a7 100644 --- a/src/main/java/com/fstack/web/controller/UserController.java +++ b/src/main/java/com/fstack/web/controller/UserController.java @@ -20,7 +20,7 @@ import org.springframework.web.bind.annotation.RequestParam; import com.fstack.exception.BadRequestException; import com.fstack.exception.ResourceNotFoundException; import com.fstack.service.UserService; -import com.fstack.util.NewUserFormValidator; +import com.fstack.validator.NewUserFormValidator; import com.fstack.web.dto.UserRegistrationDto; import com.fstack.web.dto.UserSettingsDto; diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 8769bfb..c8a8b65 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -10,7 +10,7 @@ - + @@ -18,7 +18,7 @@ - ${LOG_HOME}/eva-ops_%d{yyyy-MM-dd}.log + ${LOG_HOME}/${APP_NAME}_%d{yyyy-MM-dd}.log 30 diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index a461a9f..f56f6c8 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -1,11 +1,11 @@ NotEmpty=This field can't be empty. -Size.userForm.username=Please use between 3 and 10 characters. -Duplicate.userForm.username=Someone already has that username. -Invalid.userForm.email=This is an invalid Email. -Duplicate.userForm.email=This Email already exists. -Size.userForm.password=Try one with at least 5 characters. -Diff.userForm.matchingPassword=These passwords don't match. - +# user +userForm.username.duplicate=Someone already has that username. +userForm.username.length=Please use between 3 and 10 characters. +userForm.email.invalid=This is an invalid Email. +userForm.email.duplicate=This Email already exists. +userForm.password.length=Try one with at least 5 characters. +userForm.password.diff=These passwords don't match. # new post messages -Size.post.title=Title of new post must use 3 and 30 characters. -Size.post.body=Title of new post must use 3 and 30 characters. \ No newline at end of file +post.title.length=Title of new post must use 3 and 30 characters. +post.body.length=Title of new post must use 3 and 30 characters. diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties new file mode 100644 index 0000000..9c29943 --- /dev/null +++ b/src/main/resources/messages_en.properties @@ -0,0 +1,13 @@ +NotEmpty=This field can't be empty. +# user +userForm.username.duplicate=Someone already has that username. +userForm.username.length=Please use between 3 and 10 characters. +userForm.email.invalid=This is an invalid Email. +userForm.email.duplicate=This Email already exists. +userForm.password.length=Try one with at least 5 characters. +userForm.password.diff=These passwords don't match. +# new post messages +psot.new=New Post +post.title.length=Title of new post must use 3 and 30 characters. +post.body.length=Title of new post must use 3 and 30 characters. +homepage.title=Home Page \ No newline at end of file diff --git a/src/main/resources/messages_zh_CN.properties b/src/main/resources/messages_zh_CN.properties new file mode 100644 index 0000000..15db952 --- /dev/null +++ b/src/main/resources/messages_zh_CN.properties @@ -0,0 +1,2 @@ +post.new=新帖子 +homepage.title=首页 \ No newline at end of file -- Gitee From 548c78a3197c64d6e99153949e047d48c0404420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 24 Apr 2019 13:29:17 +0800 Subject: [PATCH 07/52] "" --- src/main/java/com/fstack/config/RedisTemplateConfig.java | 2 +- src/main/resources/logback.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/fstack/config/RedisTemplateConfig.java b/src/main/java/com/fstack/config/RedisTemplateConfig.java index 38ef8b2..c530c40 100644 --- a/src/main/java/com/fstack/config/RedisTemplateConfig.java +++ b/src/main/java/com/fstack/config/RedisTemplateConfig.java @@ -35,7 +35,7 @@ public class RedisTemplateConfig { //key序列化 redisTemplate.setKeySerializer(stringSerializer); //value序列化 - redisTemplate.setValueSerializer(stringSerializer); + redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); //Hash key序列化 redisTemplate.setHashKeySerializer(stringSerializer); //Hash value序列化 diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index c8a8b65..7ba1505 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -18,7 +18,7 @@ - ${LOG_HOME}/${APP_NAME}_%d{yyyy-MM-dd}.log + ${LOG_HOME}/logback_%d{yyyy-MM-dd}.log 30 -- Gitee From 0448ab6d514a772d799e67360d932a801a3555b2 Mon Sep 17 00:00:00 2001 From: Keven Date: Wed, 24 Apr 2019 15:31:25 +0800 Subject: [PATCH 08/52] =?UTF-8?q?=E5=AD=98=E5=82=A8=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 12 ++- .../config/FsForumConfigProperties.java | 40 ++++++++++ .../fstack/config/StaticResourceConfig.java | 14 ++-- .../config/security/WebSecurityConfig.java | 4 - .../com/fstack/constant/StorageConstant.java | 22 ++++++ .../com/fstack/service/StorageService.java | 13 +++- .../service/impl/StorageServiceImpl.java | 70 ++++++++++++------ .../fstack/service/impl/UserServiceImpl.java | 9 ++- src/main/resources/application.properties | 13 +--- src/main/resources/messages_en.properties | 2 +- src/main/resources/static/default.jpg | Bin 0 -> 16223 bytes src/main/resources/templates/forum/post.html | 7 +- .../templates/forum/user-profile.html | 4 +- .../templates/forum/user-settings.html | 16 +++- .../templates/fragments/comments.html | 7 +- .../resources/templates/fragments/head.html | 16 ++-- .../templates/fragments/posts-list.html | 4 +- 17 files changed, 180 insertions(+), 73 deletions(-) create mode 100644 src/main/java/com/fstack/config/FsForumConfigProperties.java create mode 100644 src/main/java/com/fstack/constant/StorageConstant.java create mode 100644 src/main/resources/static/default.jpg diff --git a/pom.xml b/pom.xml index ce399ff..88ef2a7 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,6 @@ - + 4.0.0 com.fstack @@ -49,7 +49,13 @@ spring-boot-starter-mail - + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot spring-boot-starter-thymeleaf diff --git a/src/main/java/com/fstack/config/FsForumConfigProperties.java b/src/main/java/com/fstack/config/FsForumConfigProperties.java new file mode 100644 index 0000000..97f67b9 --- /dev/null +++ b/src/main/java/com/fstack/config/FsForumConfigProperties.java @@ -0,0 +1,40 @@ +package com.fstack.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.thymeleaf.util.StringUtils; + + +/** + * @author Hu Jie + * @date 2019/04/24 2:02 PM + */ +@ConfigurationProperties(prefix = "fs.forum") +@Configuration +public class FsForumConfigProperties { + + private static final String DEFAULT_DATA_DIRECTORY = System.getProperty("user.home"); + + private String dataDirectory = DEFAULT_DATA_DIRECTORY; + + public String getDataDirectory() { + return dataDirectory; + } + + public void setDataDirectory(String dataDirectory) { + this.dataDirectory = clean(dataDirectory); + } + + private String clean(String path) { + if (StringUtils.isEmpty(path)) { + return DEFAULT_DATA_DIRECTORY; + } + if (path.endsWith("/") || path.endsWith("\\")) { + path = path.substring(0, path.length() - 1); + if (StringUtils.isEmpty(path)) { + return DEFAULT_DATA_DIRECTORY; + } + } + return path; + } +} diff --git a/src/main/java/com/fstack/config/StaticResourceConfig.java b/src/main/java/com/fstack/config/StaticResourceConfig.java index 48f5366..5996059 100644 --- a/src/main/java/com/fstack/config/StaticResourceConfig.java +++ b/src/main/java/com/fstack/config/StaticResourceConfig.java @@ -1,25 +1,29 @@ package com.fstack.config; -import com.fstack.util.CommonUtil; -import org.springframework.beans.factory.annotation.Value; +import com.fstack.constant.StorageConstant; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import java.io.File; + /** * @author ab */ @Configuration public class StaticResourceConfig implements WebMvcConfigurer { - @Value("${resource.staticResourceLocation}") - private String staticResourceLocation; + @Autowired + private FsForumConfigProperties forumConfigProperties; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { + String avatarLocation = forumConfigProperties.getDataDirectory() + File.separator; + avatarLocation += (StorageConstant.AVATAR_DIRECTORY_NAME + File.separator); registry.addResourceHandler("/avatar/**") - .addResourceLocations("file:" + CommonUtil.getRootPath() + staticResourceLocation); + .addResourceLocations("file:" + avatarLocation); } @Override diff --git a/src/main/java/com/fstack/config/security/WebSecurityConfig.java b/src/main/java/com/fstack/config/security/WebSecurityConfig.java index 65950a8..740afad 100644 --- a/src/main/java/com/fstack/config/security/WebSecurityConfig.java +++ b/src/main/java/com/fstack/config/security/WebSecurityConfig.java @@ -51,12 +51,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { // all static resource and home page .antMatchers("/", "/avatar/**", "/", "/js/**", "/css/**", "/images/**", "/fonts/**", "/bootstrap-select/**", "/bootstrap-datetimepicker/**", "/custom/**", "/daterangepicker/**", "/chartjs/**").permitAll() - .antMatchers("/user/**").permitAll() - .antMatchers("/user/settings").authenticated() // all posts are allowed to be viewed without authentication .antMatchers("/post/**").permitAll() - // all user profiles are allowed to be viewed without authentication - .antMatchers("/user/**").permitAll() // all categories are allowed to be viewed without authentication .antMatchers("/category/**").permitAll() .anyRequest().authenticated() diff --git a/src/main/java/com/fstack/constant/StorageConstant.java b/src/main/java/com/fstack/constant/StorageConstant.java new file mode 100644 index 0000000..fbfad57 --- /dev/null +++ b/src/main/java/com/fstack/constant/StorageConstant.java @@ -0,0 +1,22 @@ +package com.fstack.constant; + +import java.io.File; + +/** + * @author Hu Jie + * @date 2019/04/24 1:52 PM + */ +public class StorageConstant { + + public static final String STORAGE_BASE_DIRECTORY_NAME = "FsForumData"; + + public static final String IAMGE_DIRECTORY_NAME = STORAGE_BASE_DIRECTORY_NAME + File.separator + "images"; + public static final String AVATAR_DIRECTORY_NAME = STORAGE_BASE_DIRECTORY_NAME + File.separator + "avatar"; + + + public static final String DEFAULT_AVATAR_FILENAME = "default.jpg"; + + private StorageConstant() { + } +} + diff --git a/src/main/java/com/fstack/service/StorageService.java b/src/main/java/com/fstack/service/StorageService.java index 781090f..8230cc3 100644 --- a/src/main/java/com/fstack/service/StorageService.java +++ b/src/main/java/com/fstack/service/StorageService.java @@ -1,13 +1,20 @@ package com.fstack.service; -import com.fstack.persistence.model.User; import org.springframework.web.multipart.MultipartFile; public interface StorageService { - void init(); - User store(MultipartFile file, String path); + String store(MultipartFile file, String path); + + /** + * 根据用户名存储头像,返回头像的路径 + * + * @param file + * @param username + * @return + */ + String storeAvatar(MultipartFile file, String username); void deleteAll(); diff --git a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java index cf4f439..55d4192 100644 --- a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java @@ -1,64 +1,86 @@ package com.fstack.service.impl; +import com.fstack.config.FsForumConfigProperties; +import com.fstack.constant.StorageConstant; import com.fstack.exception.StorageException; -import com.fstack.persistence.dao.UserMapper; -import com.fstack.persistence.model.User; import com.fstack.service.StorageService; -import com.fstack.util.CommonUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.util.ResourceUtils; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.util.Objects; @Service("storageService") public class StorageServiceImpl implements StorageService { private static final Logger logger = LoggerFactory.getLogger(StorageServiceImpl.class); - @Value("${resource.staticResourceLocation}") - private String staticResourceLocation; + private final FsForumConfigProperties forumConfigProperties; @Autowired - private UserMapper userMapper; + public StorageServiceImpl(FsForumConfigProperties forumConfigProperties) { + this.forumConfigProperties = forumConfigProperties; + init(); + } - @Override - public void init() { + /** + * 初始化创建数据目录,配置默认头像 + */ + private void init() { + String avatarDir = forumConfigProperties.getDataDirectory() + File.separator + StorageConstant.AVATAR_DIRECTORY_NAME + File.separator; + Path avatarDirectoryLocation = Paths.get(avatarDir); try { - Files.createDirectories(Paths.get(this.staticResourceLocation)); - } catch (Exception e) { - throw new StorageException("Could not initialize storage", e); + if (!Files.exists(avatarDirectoryLocation)) { + Files.createDirectories(avatarDirectoryLocation); + } + Path resolve = avatarDirectoryLocation.resolve(StorageConstant.DEFAULT_AVATAR_FILENAME); + URL defaultAvatarUrl = ResourceUtils.getURL("classpath:static/" + StorageConstant.DEFAULT_AVATAR_FILENAME); + Files.copy(Paths.get(defaultAvatarUrl.toURI()), resolve, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException | URISyntaxException e) { + e.printStackTrace(); } + } @Override - public User store(MultipartFile file, String username) { // re-factor needed - if (null == file || file.isEmpty() || null == username || username.isEmpty() || username.equalsIgnoreCase("")) { + public String store(MultipartFile file, String username) { // re-factor needed + throw new UnsupportedOperationException(); + } + + @Override + public String storeAvatar(MultipartFile file, String username) { + if (Objects.isNull(file) || file.isEmpty() || StringUtils.isEmpty(username)) { return null; } - String filename = StringUtils.cleanPath(file.getOriginalFilename()); + + String filename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename())); + String basePath = forumConfigProperties.getDataDirectory(); + basePath += File.separator + StorageConstant.AVATAR_DIRECTORY_NAME; + Path avatarLocation = Paths.get(basePath + File.separator + username); + try { - String path = this.staticResourceLocation + username; - Path avatarLocation = Paths.get(CommonUtil.getRootPath() + path); - if (!Files.exists(avatarLocation)){ + if (!Files.exists(avatarLocation)) { Files.createDirectories(avatarLocation); } + Path resolve = avatarLocation.resolve(filename); Files.copy(file.getInputStream(), resolve, StandardCopyOption.REPLACE_EXISTING); logger.info("Saved file to >> " + resolve); - // update user avatar location - User user = this.userMapper.findByUsername(username); - String avatar = path + "/" + filename; - user.setAvatarLocation(avatar); - return user; - } catch (Exception e) { + + return username + "/" + filename; + } catch (IOException e) { throw new StorageException("Failed to store file " + filename, e); } } diff --git a/src/main/java/com/fstack/service/impl/UserServiceImpl.java b/src/main/java/com/fstack/service/impl/UserServiceImpl.java index 5ec7957..42ca29e 100644 --- a/src/main/java/com/fstack/service/impl/UserServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/UserServiceImpl.java @@ -1,5 +1,6 @@ package com.fstack.service.impl; +import com.fstack.constant.StorageConstant; import com.fstack.event.OnRegistrationCompleteEvent; import com.fstack.persistence.dao.CommentMapper; import com.fstack.persistence.dao.PostMapper; @@ -58,6 +59,7 @@ public class UserServiceImpl implements UserService { @Override public int save(User user) { user.setPassword(passwordEncoder.encode(user.getPassword())); + user.setAvatarLocation(StorageConstant.DEFAULT_AVATAR_FILENAME); return userMapper.save(user); } @@ -116,14 +118,17 @@ public class UserServiceImpl implements UserService { return attributes; } + User user = userMapper.findByUsername(authenticatedUsername); // update user profile - User user = this.storageService.store(userSettingsDto.getAvatar(), authenticatedUsername); + String avatarLocation = this.storageService.storeAvatar(userSettingsDto.getAvatar(), authenticatedUsername); if (null == user) { attributes.put("uploadResultMessage", "uploadFailure"); - user = this.findAuthenticatedUser(); // find authenticated user if no user found + // find authenticated user if no user found + user = this.findAuthenticatedUser(); } user.setEmail(userSettingsDto.getEmail()); user.setBio(userSettingsDto.getBio()); + user.setAvatarLocation(avatarLocation); this.userMapper.update(user); // return attributes diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3cc53ef..3d78eed 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -2,14 +2,12 @@ server.port=8080 spring.profiles.active=pro server.servlet.context-path= / spring.aop.proxy-target-class=true - # ============================== # MyBatis configuration # ============================== mybatis.type-aliases-package=com.fstack.persistence.model mybatis.config-location=classpath:mybatis/mybatis-config.xml mybatis.mapper-locations=classpath:mybatis/mapper/*.xml - # ============================== # Thymeleaf configurations # ============================== @@ -18,14 +16,13 @@ spring.thymeleaf.servlet.content-type=text/html spring.thymeleaf.enabled=true spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.mode=HTML -spring.thymeleaf.prefix = classpath:/templates/ -spring.thymeleaf.suffix = .html +spring.thymeleaf.prefix=classpath:/templates/ +spring.thymeleaf.suffix=.html # ============================== # Message # ============================== spring.messages.basename=messages spring.messages.encoding=UTF-8 - # ============================== # PageHelper configuration # ============================== @@ -33,11 +30,9 @@ pagehelper.helperDialect=mysql pagehelper.reasonable=true pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql - # ============================== -# avatar location, must end with / +# fsforum data directory # ============================== -resource.staticResourceLocation=avatar/ - +#fs.forum.data-directory=D: spring.output.ansi.enabled=always logging.config=classpath:logback.xml \ No newline at end of file diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 9c29943..435bac9 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -7,7 +7,7 @@ userForm.email.duplicate=This Email already exists. userForm.password.length=Try one with at least 5 characters. userForm.password.diff=These passwords don't match. # new post messages -psot.new=New Post +post.new=New Post post.title.length=Title of new post must use 3 and 30 characters. post.body.length=Title of new post must use 3 and 30 characters. homepage.title=Home Page \ No newline at end of file diff --git a/src/main/resources/static/default.jpg b/src/main/resources/static/default.jpg new file mode 100644 index 0000000000000000000000000000000000000000..620bbfd7e5912609e81558b13ea255c00c0a5b98 GIT binary patch literal 16223 zcmb7qWl&sS@a4c@!9BRUCCK0|gF6iF?hNi4Bm@SBFhPU6y95dT!(D@Ga3?@E|J~ZE z{kr`=_N#MW-COV6)2I9I^4~20t`b-g3_w6Y1Tg-40Dsp2G5{1LWE5m16cl6>R8$l+ zbX;`wckj>%v2ieQ-xHFMyeA|kCZlAeCL^b(ASR~aprL1CW@Td~rRMy|$?}nrg_Y%h zKoC$-QPI)R3DD6ASjdRUSpL7`Z!Z834Z#$F4TwMoK*U1;;vxL~37`Z35Rei61>pY% z5P*RA?|V_v-u+8U;sOv6fIvi~{~ahmgnvmO00|EnpO#w+g+S8+m5v8WC>@?muT{{8 zMpQq;t8KZ>z$fF8a!D+E75NW=6afJIf8qZv^A7?E`Cp0-@87bB|L_q1;r^dMK*Xcv z2I5Q6X%g^QNdH|0VE#)X;sNmh5`cTwJ8~(1VgFeMoIB)`;R`+I+M2}~`nXv|4fm+F zC&%un>MG~xP3j$Q+7L^e_A{eVH}~mte+VrsjwjU9$nd<~DjvbD_>*e}H{LLio{+X| zQ%OCU2Vu^!z>zcKE0f0rjit~isl;NF<=kHY_Tl)~3^Bsn@^+^Es5p)BO5AsQe*tH} zSNmhnGK9>}3b!K@Mkzu%<}IE}z&{HZPo|Sh9#Zrrs^n`z0tRGvFD0NGI*l@4To3tE zgVAb5Oe!zS>7mGUJ(|}_MK03q6h%@*f)s^O@r6l8L#ItS&>BrNXx|EW`T#Ooa)Az6 zZq9@Of-10JlTtL18?J0w3wnAc4)*UGx2WXP0^Xq-$z$FfT@T>k3hVH2^) zQI8Nn@lc@u#^iTxOf9Vk1QEFLWn!A7k5RQ9h0MD$?R#{!Hzf^wiwq4CGowy#UBQnz z&gm6=M-X$rjoZ;LfySIJRk5}?20vw|2$t42cJzGKwSI?~o1+S{lb~$j0*SS%eCc+{ zKKCay5A&=1-C{|-y(8+CEadj1+hU^7q>@E3J{H`sF3C1)uZl$dSXmxaOsxcc*1G?N z*~+X8fv?By2q}&5Muo)O5fwj%V}cbAu;?kmxgj&EKsO=2VinuT z_aB517QjYgCqH&Xj|r@;xwgXq!|MxQ$~CvV6Y5iwf>pKSzmB9cp!#Cs$RsLNEG;E8 zx$NK@dy-`%zLPkW>ukY9k8JK8OV(;iYT`N#+e`fmaCB<&$K)wpAU$lQJocD$JLSAD zLJ>;(NJ>Gmki)E|>?eaO&???W^!~|JOApn-d26>=->I30vi3TETzhfK*U*?waPAd4 z=&{-`2=y{TE)*qz6Fw~IExBNIW~f}sQ$UJ*P&UV%BSQk=vBi}1-R63hGXVGY#h#cbh(u7n05 zLRi{!REmloTinKFTUC}omfC*c%KN?2%l4zt&#>L(c4lF7h=>XY?185dk?sO)tqFs<~f~<;$}8X&)rHGMRzY&D>o*Sl(DLB&E-X$$5OA~zUPj6 z4r-rNRi+KrCR^kXnK;X?{>G8-w=8kD9&lKgXvC+RjK;q}<`|-B;Fn13ulhh$Y zlLqMq)NYsW+KHK#REJ{f&Hg{Bh%R@GrR$FMo@>gzX#<_SeO9txwIn19g*FUxKU`LI zc)2?WYmwAmFl^X=J|NlxZ13%P@Sp^mFQ}0P>~`x_9>4L=aGA0@85B8~2yi%Ha05#P zsoL`gcR%2)ZH!xR-Y~9~CokIPiURzF=u7-2{Hgx}68vI%Gx403mM%Azt2pM?R;}AZ zIz2p=g-&vYU7H6^LqKi>ehDa*4({9T8TZ#o$>1(r(6*EoBL3;&Qqa@acgzVQNk;7IZGRi%TlNpW)#jtc>A zjL@8|O0zAM3>`OU>`!C9)`b@ziv-*8`MoLb`iF!|f!+J$$~y z-etG1A!_RsZLClYtWk>HXqtbKN1pN}} z2@Ocs`TjTyT*+(TDCq$R$3qs>6@Prus&DQJJ0MLG&a-6GtD53~mT$q$w3*pFt32Ox zpu7)PjN=*osc^>q5ybZEr-cpXeOH=2-` zf?xAlX^buntE!z)aBsu$#Kg*dP!S~fYa#)lg1?S0!HG7`xl!Ounhgztm*e6PRbbm6q% z32#PtYRyJ?TM$-f3s@LmW=^C2k3(F0L(a-x(%3lDk{_m@YAo?ZoM9O1b$OKZt-W0@ zC@3yet$FA)K>o{JC%4doOLes}pD+5&6FUaB&u+pY#cq2=O7qaU6Uj4B^C~8WV}H%N z-0-P)*IM60tS#TnucLqSoLv!lussWdAqA`;iZ4iXQ<7z|{rPuQ(;q+A8c}uL4{vG^ zIE~cF)RSkg)syFDH#6kXGn7xW;xRYyTNbXf0UbwK(RD#%B+OmCnA54@Zp=qCge_6A zYoR3P`~zdyL0})6HPS0fX&ETE%c$D;7$RWknvpW<-ubdpj85chj!CtrXH?;*HoK;f z=1}?QRNo?>%d)VSR?EPXOOkhC{3C8oY1X_w(WEDW$zC>TC>|mk5}v~SD;v6*ZOR`6 zeb^Kx77$Kqhi!u}f(Qen$(4!w%YbE5)%L&qHdTEd{p2Cj=bRTdYxG5~1@3^L3)A*t zsXt4wU&EzGc&28*#u!r|*IXPnT#dLMJ}vUl$lT_FE%jJ_-&P|~7G3>3{-S>VJd@A$ zbm(!-Otw|~IpCqf!MnY+!B75YN6`Bjrb5btWCu*Cg51}xx-FR2N58e?)6~A|KnW^) zc*&`KjpdIv|10E0` zQC?GjJ>0}@zzy9|ocl^vSS{5Px#_=XaEe{84icgyMg3tE1-xAIthDEa{P90$&h6Re z1$_N-^c1=%Kh!pAjSDlGfwI0pLOq{`q8Y&r@`ACtyNMuRrT)bBgq!vpm#gLbXYYaj z1KxDY>iEbD)4@x-9g_NvxN)ttmh7|71fsNW7OEj40^=w8K()cXei+8xYq@D3{u;i! z5w%{mG<)nOva$!0{HjJ_P_epNFq_E|5-#M2(CJLjkZW|aP`4({^*Jx>6eJMWT$&9)N`%Yi4A*MzH4 z4W%R_TX9%>7xnagoXI!Hr8xs^xoW6PIh>vyghB7qae3%5Z&HF!UT%h)_wjN04{2^+ z*#$?E|AYR>?efa+iV#ccaDy=5i$u=Fg`)4?K0K@$vgkh0n^TFvr(2u;0tU*Gt!(r- zdTRy6{Hq>0zAMsWZ`zX6_AJ!RiZZFjHLzoDWo!0e7L9=4X?__T9PHdcqwu?*0w2x7>5t5sf(3aL7z->whXrF zXJ@wK*MF_o!xXk%YB59qQ#^*XSBeYIf!v5X$UjTGD=ls(PX77kxiKby%%OKIrZ^>a zVd^ZZ%z;1XAABIz_hi$ovsy{D&f+TkahNDK7qnQ#l%emM))W<@NJv>xN-O!BcT(h` z(*ub=3NVO~c zde%eu13hXk3L4FQZAKUSPH5k$9u@aIXHnaH;a6@a{}kGYC{xuUo6n5?lsCp5kKeQj z#se8&mv$LE3}utbC%JP4kCUJ0QcSfy;lZTPD``cGc`uRJBLA)dJE9{qhTir*OjKxO zJVmy~-GuP$ZD=O2M1B#FyYCL!!S4y&A#gu8a_7YC|m>m_v@3Mk;bn9 zOhv)t)ZD`w5e@5Rc4z9G&2%l97qRYB(KdD$1emIekwb=-pY5)uiy_(_QoFvk8q1q? za{6czKmQg5rkz-DV;nY1y^!|xU6sKk#In`LRet=4ZD<$qOn&-u@cd0Wb= z-$85oZU#SgA~}(@#Rv^7Mr_dDk=Sn(Q@j@jH#e`gI7s_4^k-teU&-t~X;+LptZ0jes=c=LcUOD0MV3CFYj`H*M+c|i)?p#; z*>+9}o{=n$o@S{Us=!E66?Q8ppb7Ro5MZ|$NdY~~3G=B~kFXP||K^SfEw@O)en*56 ziIb)w=nWJ!Gn{T)T@N!tB>{a2r7QDWA|Dy;-T54x{+d?f+WM0S;4VZPb6bsrBhA?I zqS7^{AExjud0XRRoxTrA@H>&LiN5N5V|?BVc6S6~j>@iv6G=HMdaIyPAJvpVmQud;eQKUlY&OvxhY@=YJ}BJlxj9 zn&(c+s!7HxoqTzGpQ8JY&x~L9K4TWAK=5%Y=_Q)=l5+iujx1Lc0XZ}(%XB1R6>doaeeVXH*LXSWydiS6R-lxozQ17YXu=f8mF zpu*az26@)LGx(&*?3Bb@ffR2~W!Qd%0@_PNJg-Nbf-4UyC)zyP z1u{HT#c}YYnd?RBMF;%8s&;CRkZLU$v>Nd|)w9mLLOQ3e*2?l}VVNr4_rui03lsed zP>LcJREgX-S1-09ov0dcuW+Z=5Ys=X84ln<;7+WoT4>D9C6KU^HDZtI-0 z+MtV`1l(2fZ-^ zPxkgBw9@ROfWREzwYfRsuprey>9K(+>E>DhIdU%Dr!X}z`*~>8!<^|Oy-JGt;3o_J zb5t2Kj39}oRK3M2ujOmgz)uO#bN{!j+UZx~A#!rQrf?$5a0m!k0w~Zrx#l{w2zxhW zp_yz*5+7d_MM+R?h7Q<*%FrN8d@#6uZJk3h6&t8csfrVFAn~etJexR9erU}g`AssU zUhU;ee6`Mm*pTST_PxI)<2PRKXPwB?jwX0EIFxII&FMCUs zauf2W^4kfNot#jv8q2gNoI_*k~XG^ynK5g*}+Mp$W0XS`D>OP{2Id z#m`JmwsgF*cvdmN+8j`fT^DQi4g9_~K}*z>ZNbtiTQP68i|zQ^74q`SVQn*5%q20^ zXp0fzkGPd;!jxmz0vg|aOFwZ!p9o9B4>{;iCJoWG7Nm(F@n+Cf(4X)K25(gF*%!B@ zkm>}Dvk_V3`lG@}+N1c-B_3*0P3O7p$VJ9w!vF11SRlXf~whsO)j5c zw}#{lHGbW{ij36b_^#(xR!)iaUZZ(Ugm6#WaPS5*1*g7{^n0pqXUSR{4W@Xo@Zt+U zD-C%j*4%~8ElDdb8qSgDNX_inxEE={r^pTgl&aI@j_IF)@Q*yf?7WwHs_cvns_fr0 z==iuKDb-Nj0#5FfYZ>EGvqQA|h@z-!eM=|!oy1oq2O492!jY%3B? z;!QG$N>nYxRry#Y{AQp>efoB%q%dE?W_(CjKcthV3r?@7O z7T)(d5!`1fUh-yT#`+f!sVW4kuRTEq)3@lS{rMk1`ni9`J*&6?^1i%GfyYyuFj3u6 zFnoW4rD`{7s zMOprvin;-e#&5Yhd*6ye^XUjq}SWgQ1obKlW&)7#6HwPq0PK2Gs!?AAcaDeYG{PQk} zYNsjRZB8~-0X6HtfQWUspzJo4q_BuW`{Trbo6|24tZaN$pJ(qc#&j7M)4E1yyn$O3 z%m)_B=#6th?9>w)GCpS5TvEWXng>pmDGf;8U!$Gcm*l9Wvgs zx~s|5UOI1f!?y2WUs)b>DSqlPzLIG%@XgNSZoIK-1rkLck+{TLyf42iyHhWdcT6ZB zy#rMiHv(|FHKI56_P7WkJ$dgac#?Qw_Qy~w&E@Iy-VKAr3esouC1uJ8Nb{jf|&cA>UTxi49y01|ictOROM+{~f?(%0Q9%iechVmeuc#AfR z=cSw#(W;`J#CSjX=XF<4;>8B=)I@GG}V30WmyBsnJh%(ZxmVJf99ZZCp4#n|gP z5?fZNxwmhH%nPMq6|12g4Ybx*K-=T@{i)JjC={uzo?|rOIWK~Kc0jhVBC3i2vTFCZ zDk|QuQ?+i6TENbNo!TS4M2kv;%_69h%c0^YPp&=7Dl|-yc$j>#=H7Gd3ypz)2=3yA zAf3~vc&nAr3o~iMSCpSZ{qL>;9&NG!* zd0Wx8V9e6_etLElP*(M=)3P*szSK}MY+Y-W%^Iqae?Mtsm-NKja1}iqV1H(?ORGo| zRO(Aw(lm6q&R-ie55H##k3(jhqA|~PXiB-b^8fG{K4UfCMR@Zwf7E$MQsIyiD=07& z*Fc!ce=xZ73Id7g&s1g6i0|ajeG*+7B0H(r!0l<@$za@HZ&>7WKj)aZtz{OQaB$F! z$)*};*8KWAN>iT8(*(&-?mpGcimT88)L|yw%HJUPWE-1Tu3mcgI;bsRR)X7d+~&f; zJ#4W)le=Qq4@<|Rv&=+>a=n)BFJRvsnIN$Y_9MjMX#JC6 zK$VR9Kp>fw9a+f(xfKQU*D_?c%5}x6g>ceu5X=Wj#{f_K4^^V@w!Rg<%{y5rjrIB` z75(bR7u3L^)kzYdwpi>Q9u7t2OF&g`YM%ueeaTu$S0Nx2nZHZ+*#%gY;LHo%?TT{e z+wL>vs1B}wMbD8G&wJhJ9`4U2__z||ZJhU*c=}r`^*z+J-PsiHp@ zIxKaxR6CU(*MSDl#$*2(_nB7Hm{+PEDXYecZoUKqPy)gf0b~Ob3S6lpslpe|N?~VL zb*k^*kSI^*b&5FNqb6%glt&prueHv^Q(Z-xJ@0e&%1f#w@3T<# z#+Dt$5*_jNS>m3HN2gM*Z(CSoE0W|cX?g9W6V4+_1H(63;gHGx%>{|u-FJU5wUTT! z0uPFFOq*OTBf*r8&2`sjQ-<8`XsELhD%06pb4^FW*$_x|#oBTkevbfVoZqDG7g+_~ z35D$#qW?a8cEQ+E$g9+S^gb2!WDC8nY&-U)^qS7#xZRrW>hkb>o@Q8dj_OLy8crn^ z9ioVuQhC;sC<~IA=ESS_V6>R#6iWVcyiltNryV7kWFJ3xgxdwT@OSx4K{d=sPL|}^ zK7Gh1DP6u#KS9{=ct=7cAr`FnP%GBhxllXBNmp(9f>QVwz;Cvhk?JuxUGy`h&G=d1 zp{!woc7tiq*vdNS1|oq}vtm2${YRI*_UGV-4C~d}UUy+Frw`l*zsQ*|wqw2&Rz}9( zksJ2N%KRUNK5U{1YGHKR8f8-{FUBdXsPb0tnp#4VM7M!mkR z85j%^U+mH?J?4iORXzp_BSrI>!nTNbT0*&vfv}ILL?fmO2I;&LYDf;I4C?>+Bre5y z!_Ni}=BWi{`4c@2g+%9+ zJYY)K?rUc2>}uL^^$hE#Sg}IL*Y;%2{ico$1Da=z)&^{FtbwI8z6`IYNi)_gCx_RV zZ_TYXn3a_=Oq726OXt(l<>knA`~Fql zsfqf)uNZZ|Bx94|*l(y%5(n|kg!Nf=^%oQM9SiRgK_j=7%jez(Dao zrlq`TW$+y?31;uQmeeSVt3Uw&0lKmC2(#HWP9iR1WuvY&=yh9*T$M!wz8Las07-iH z6Q`2338|fR9KdX*eCyQa$4fgN@bNWuLA@#W4i2`m3vao4PU!LJg_)h>vwkiU$ph8G zp*ZbjcTavbRxh{O59P$S8^bBO=HE}A1H#4ss6$lKuErrY0aQuQpk6#5QI!C5m!jFJ z6IHA-J6)ZaEUi>~c>jRaVPIB?3!tt8gruK_uw8yyY#b%%Czcw~J=$Fe4qa^95a}b! zi>mf6))F25)+vg7!vsxaZ~@PzK^e_m9NTfWb@4*AvcKQ2^k7(FtH8BX((8%U3aKaod-2HbX=P6ej0 z1NCQU7lK$T9a_=IgsRugVW`GrtA@ag!=~3{#y&*)MLrA2hh(EYJ4Pcl%ZTB zmQQ*#*#QKm;agMDHzpIL?OKG_0OR^5SU0Q=+?i4lqqYK&o$-A#v9ao5(C9>br(Q-!( z$na%1woTZ2jqS0=lkfWrDF3mnXJ++XiUb4G0@Wh`z8r^4(P}8TWv+{>u_BL%n-A5# zRwefdbu@mClggr8AxIh-?2a+)I8Vgm>Iz)ssKRTNRgmhlTDmO+jbzLh8Hm6Zf_9lo zI&TKFp@)9~_`Myou5qPfrLKVA;Prn+=i|86r@jz*hMIl)b=#iXE2a$O$`TI)18 z7$SDHnN$$(B_eaCZ`t61NRm&$?)N|F;$ODi&`u1a(?3M+{8%GY;hLCX{BpQI>9=tg zEWyS73v~7@{xw6RB1~X6_4rIPSJgdFd-gYS1NOI(VIYEhK2b%U!frK~Z`icSoI7rk zZ4M@^#gxwGz`c_ls^t8v{bv@fBSNSu*ho=1YCYeL63h8qdtF^5c_Px;?i<8UJ zzQ$^^^af#&{FN_jd~Mf(&wej&v^x=JI*A+J^aG>j!`WW|L1D*+{8QRTeCBn%&d1vA zqa?n1Sw;;W(vadR9Mm7#ZP(ztwG z3d+pr-j$iXA1~Mp$B$iZX7?}Pu6p-#&*S0q68+`#4rQR}JYyWeqadTWvO=eRjo(PE z=IT4t8n&yAv&`Jx_LHg*V`?c`cT5KOr{z7{udSD;Wgr#A)UXPiZdHo&VaM2~b=%lj zpf;m{oms4jI=6*^$j2$mz4g=af*# zDRH70H@8QJ?eu9;31>zX6X7RV@VkRfYYpy61wsb;2>GDoQwWz$LLIJEyw{+`n)2Wb z$|32Xa;O+PwNCd7A5HDzIyx*pl<~j#6ee_-x?{Vb*_93S-VK;Mfi15iJvmk(oZ`-+ zrC9H2+|zCmT-BO-*rY-A5u1%mlYp2yUYzatS>;#cY<|kyV@`plUxgvKa<>-OP%u-y zWiI^yhjO5Ovp#(6_fg2xh0(KHOcM@9ZMM~yNs27%y}V|f`4F~8D^*6Dt^_c5AL3{E z%Hml*A==M|=g&J1(9ua`mm)+^f4jt=%1OG%*6pWHZj|#j6xQKv8C1)6HI33&py*2c z=B{=I>w*(h=ed=Dv+1ZOsh#h7Vu7=YK$wJ5o)X?P6C=&lgw-h-az+8(jfKf@Ik4KT zVyBeQ=qte--`?`W-G1t}1kUOae+n8dN_uO3b(ZxqOdUb~?t2OXg|3Ut*M8Wiy~Vj` z{`23sKMR_y?Y=Mb{^0E4(>Sugz&9ca3t$*g)pz?+48WHVmxH2#4K4dGy@hQT5DN~Mhf9O#-;9X1{q1ucdu1CDv99=HXBytC1 zBIfJtSLWMde}c?Z`{dZFB40ssu!Od0<>k8HxcZEiI<`Z>?Dm(guhg4e{q|TnMIr8M z2T#?oVN}HK!@gg*oP0P)tMo`W5Zc~eRG1Sr)0xAk{n=x^AGp`Zd;Avij0Rw*Y5o)9 zQD?4P)?8WSdrTLx-oxYzGl^e8zLv~w%@KA@@liMYQIf+g>e^?rmxqtBEp46p&Flu2 zDlVAdt5;#2|6FpoRzA2DFh#l2EDxkU?_}ha4m%HKLapXg7aRFpJf;lhw&(d)bho`x zBa@AiR2bFMZnQfWoIH9uGQ;B#g({ZR_ho;2Q!MP8vb@)D13wT6+kF_GpaQw!``rv< z0kDJ)B<$H=}lBrY?Yn}VPDRDtgas?6|&jCvPpk2 z`}nA?JQrkg#l$YgtC*)SSJcY5WuP*F!RE1*>uyA$H*1E~LuGQL?-|Tde|Vf^o_cB` zAJId3)I$naf4$^Gsx=GY;(PlWu9sob=M3+3O?6m}$HLo;}=pXHoa7B%4pvyGHb z*=tvDC&m(++*g_#QfTtMtlWyJ1eI@NP$B?Pllp6%V8zVGO~+n7bopZKG|yqBHpi~< zRuT%bst=3-kU?=aBgK+F%1V<`8(7+HhgY!_(|Z;p!9f|{y5cFT#e&o$R;;pBWyXoA zRKA!Xc~7FPK!j7nH;c7vte+Hk28b)pZf8G3^Jr4%I-r4_W02TVVk5z@=Q#? z>C!RqwqQdt^P?hRAKwFW^hapyT1ae$dB{+=us7p69sL8IFrh$-o{q?1frW|DiI zUrOq)$AuDt0$MZPvbLPW0=F^Y$lVPIrnARf86VdSw`iZzxQ`4J4;Q-z`rjy)yv*>M zAEJq6d#J3Htr%O5arwc+*!-`jr!$3;wFeyL6h6B|K4bkD&B(5&QTpc)DquPFMSYf*^Vnr%e@sl5~VErXesRc2A=ez!4q#i^3 zxz8;;tTG(NO8iie{X7c<8G%z#L9`bdy@=mx37v0c55u*9K*BV0s2VGtfST~4_iu|5 zuvjKhvBATCqBFS*?u26QA`9WY6^r?u#HJB2@@6tRF^9fGx@h%DHmBP>C4ffusGjyQ zwc}(M9`mUo>usEuY=Yd9$4;?Q(rg{FpXjVP_iEg3K|za-U9;(Z4rvdZNJxlp!NY-3 zwZ6h@tqfQPF?WAQ`R+_HQ3-$S-Eka^tDNO(q|fyh+A=GBIcY&((hs5at%RSN)>s^I z1<|}Wfq&2$aM3aym75N~CSgtBf%${{^s~lVCZ_taA*PP5ZhX*9wKP-ZK?|3{J%9`es>rYfE`psc zLq-~75v~s@dF;o+1px?0EV&XZzXXoh{kodT+a1N^=}R1l@2Z6@CYTQLq0h6ngwX-v z(goq9r&`RSKn)>L%cA#`_DBd47urLpgg*~Ul?msR$AL68~#v3f!<%hla{&9pE*?0r#8NcOok@N!`)qbGF`o|7+mQ19-% zZg-VVG%15+w(hai!Szh`bpQgSilPOlMOCXKDpw~V0K2)^#)(GdOpJTN2z08p7k?$| zL3+(9MIcX%&EqI7?mxte@IJrX@++oJIq`pB*7D;7-e_hx*76fDz`Jmsx9=Q>P>rR6 zCW3WXEkK7cDtR;!Y9_UsUo{XBlW6$s6Vqt6WkLHZvWjr{5_JG|cHRxLSc>N;o;Ol7 z%~fu?1IiYf(1hpAsxjlJEd*5Tk)-wnx+%v0*< zMkb1`I%Cr**NG&El%e6tJ&0Y0vB>NTy|Sh-)66MmPz1|7&rdOn9pn9(Uu#w@CdJIL z>a}=vgeqB+&|?b6&+Kb}!D54Y$pRi-c++v|eF}v9IrM^-Y)z?xPh2SLmn2>w%_==; z@P6Y3Tosyf{{wVgI_r5~hVd=NEZOInV~ z3V@O|4S>RCFsS2c;}gQhaEq8Vb)m%Pya&fmLb@xrOc&!>sn_t+g(-X|bDqZ4p9x?= zDPh&hCt?fG0b1tqt(1t_lhLavl<}Sk4k9(4KWQu|1Y=IXsV)_Ne|fd%ViI$&d?@Id zjuYVb)Ga!5n=*zq;I9k(5Uh-hJO3bg;09F%=t>A8EcXOGmm^6-Z;js4A)* zlfyJ(ue}Ph(roZeml332UdZwo=?mETzQNy_DK&uU)DJ^d5*Mr*N8m9|OXC+lXu6qX zDIfFD8Olwk(M2)7J<~3h1VnVfp(8u-V0pgx(%AA!a@{0lVsf&>;e8~xAdoY*s<^y4 zn;u(dK1~F|lwk?yUigE|4OpEeFt}3N^?be`GrQ3?fqezCUU(hjE75F{z`X?b+m@Xi z#K>*?jvip=u`0OB_b1rl*cPrrh#sVEn+-=~%77}RgNPlxONeNDi}WIQGX8B?TsoT$ zB8VW)r>su!E+3VlAW+x9^=mE)OT&=j?tR4&{rxMuBCX*Ug^BsO52Ds{Pj*YsTGt6C zvs$aDj^2qt`iG*P7r3bN*e8Ug)%;tkerP0|YwlPZNNN8qrkGuo1m-6uN1X3oD&D0N z)6LcZgj>FIb4+KGEY~WQWYeivk3*SIN@oMOkcc4*Gi`RW^W_GA~tjXL0+#ZM=UlS?&v=4xy=%mcL3Jo@SQxq6fivZ>of*mqpDKY(QN`+J0&WS zq4IZBDLg4rMWdX+7G0<;OUJk3M!7RA)UcGJzF$DWGdE5+RpoZpKV65LJ~dos z-5MYB63co;QMA>KaS_S?r_;;#=Crf;Bp&@sF^5VmG(t?at5YyAjzT#M!~45!3hQxs zt9EW09zJjUynyEjh^{A%Cn52GDvd%xQ2a-;xYRBY@{_z4PC-fXPxB118>tx4Z+<8h zqzHn7#Ug{et_Bf#U_!=EUpF#jeN4wUYlwzEf1-PETv`kf{6mk&BP$0$0BKW4MYs{W77C-#fI0%8O_$=vZ z@f6{y8xYU6T$B^yj5QZxp3_aArH1?`7>ztk?dr6YJGM-;NkLmLQKWm zIGZgue#%JhuRyaA8675lsENPPNMTH}nE&`tv1YLUsHr)Kp1>5*pvqG6_))ywn3@6bcOnTJgd^5c7HI_0e|>T`o-rP3hwW z4EU(Var}Uc9gr@2in`{p4s-XAPYbr=!UB9GuRnF%b!ATvR4wmooj@;bA`e!RDs5>S zZK+N>g_aGz6Jkygi}E@``6wKqm-WbXm-ka)cGs$q>EgCl*|=2mc{=ZdC4zdKg}T-# znLH({Ho^^=qr9sKoUqI%l|)ZG-u|#yPWq5N4#(LkIwy9Wlt7Rcl_~6GD}E?0vOGh@ zwzWhZgdPC~^N2u@o~z zDxMh-C<@DtShh>{p6eks3N&JKONNaDsDgUb z>3~6pIN>_XjOr+0(^n_5Zjp zR?|Ut4x|iIs0`@#G|c2{QRVn*`;^MNOjUyY=Dy#x5tg8g9aN~R@f8)QfaF(Je_z2otvwlIF3fUln1nwTuwMzdBta zelT|OvNs}l&>O5`C^kB&sccTwJXzAx7{SG96+G;AY-pA7CK42)Yy&^Kua{#Zf*_C| z0B?ZDaZ3#n(H0%5J>ebj{*;F?lEwt{_`BZmkUI#c)V2OOgEzyq!%EB2KxQiCW^P!D zD?-}*%IDiEO8m2uM67IYGshJONB*LZ=oHg?jDnfQaP53dYwz!e_M>m<#JmdHb3g^S a - + @@ -18,8 +18,9 @@
-- Gitee From f6fd7f78f0b2bc9736105e1a4fb26c7f517ac920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 24 Apr 2019 15:56:49 +0800 Subject: [PATCH 09/52] file normal --- .../com/fstack/constant/StorageConstant.java | 2 +- .../service/impl/StorageServiceImpl.java | 21 +++++++++++++++++-- .../fstack/web/controller/TestController.java | 16 -------------- 3 files changed, 20 insertions(+), 19 deletions(-) delete mode 100644 src/main/java/com/fstack/web/controller/TestController.java diff --git a/src/main/java/com/fstack/constant/StorageConstant.java b/src/main/java/com/fstack/constant/StorageConstant.java index fbfad57..126a186 100644 --- a/src/main/java/com/fstack/constant/StorageConstant.java +++ b/src/main/java/com/fstack/constant/StorageConstant.java @@ -8,7 +8,7 @@ import java.io.File; */ public class StorageConstant { - public static final String STORAGE_BASE_DIRECTORY_NAME = "FsForumData"; + static final String STORAGE_BASE_DIRECTORY_NAME = "FsForumData"; public static final String IAMGE_DIRECTORY_NAME = STORAGE_BASE_DIRECTORY_NAME + File.separator + "images"; public static final String AVATAR_DIRECTORY_NAME = STORAGE_BASE_DIRECTORY_NAME + File.separator + "avatar"; diff --git a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java index 55d4192..5425097 100644 --- a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java @@ -55,8 +55,25 @@ public class StorageServiceImpl implements StorageService { } @Override - public String store(MultipartFile file, String username) { // re-factor needed - throw new UnsupportedOperationException(); + public String store(MultipartFile file, String dirname) { // save file to ${dirname} Directory + if (Objects.isNull(file) || file.isEmpty() || StringUtils.isEmpty(dirname)) { + return null; + } + String filename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename())); + String basePath = forumConfigProperties.getDataDirectory(); + basePath += File.separator + dirname; + Path avatarLocation = Paths.get(basePath); + try { + if (!Files.exists(avatarLocation)) { + Files.createDirectories(avatarLocation); + } + Path resolve = avatarLocation.resolve(filename); + Files.copy(file.getInputStream(), resolve, StandardCopyOption.REPLACE_EXISTING); + logger.info("Saved file to >> " + resolve); + return filename; + } catch (IOException e) { + throw new StorageException("Failed to store file " + filename, e); + } } @Override diff --git a/src/main/java/com/fstack/web/controller/TestController.java b/src/main/java/com/fstack/web/controller/TestController.java deleted file mode 100644 index 7a4301d..0000000 --- a/src/main/java/com/fstack/web/controller/TestController.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.fstack.web.controller; - - -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/test") -public class TestController { - - - - - - -} -- Gitee From a79d31c5306dc4efa06a57741218d7df28ea7f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 24 Apr 2019 16:00:58 +0800 Subject: [PATCH 10/52] file normal --- src/main/java/com/fstack/constant/StorageConstant.java | 2 +- src/main/java/com/fstack/service/impl/StorageServiceImpl.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/fstack/constant/StorageConstant.java b/src/main/java/com/fstack/constant/StorageConstant.java index 126a186..fbfad57 100644 --- a/src/main/java/com/fstack/constant/StorageConstant.java +++ b/src/main/java/com/fstack/constant/StorageConstant.java @@ -8,7 +8,7 @@ import java.io.File; */ public class StorageConstant { - static final String STORAGE_BASE_DIRECTORY_NAME = "FsForumData"; + public static final String STORAGE_BASE_DIRECTORY_NAME = "FsForumData"; public static final String IAMGE_DIRECTORY_NAME = STORAGE_BASE_DIRECTORY_NAME + File.separator + "images"; public static final String AVATAR_DIRECTORY_NAME = STORAGE_BASE_DIRECTORY_NAME + File.separator + "avatar"; diff --git a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java index 5425097..c5c66e4 100644 --- a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java @@ -22,6 +22,8 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Objects; +import static com.fstack.constant.StorageConstant.STORAGE_BASE_DIRECTORY_NAME; + @Service("storageService") public class StorageServiceImpl implements StorageService { @@ -61,7 +63,7 @@ public class StorageServiceImpl implements StorageService { } String filename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename())); String basePath = forumConfigProperties.getDataDirectory(); - basePath += File.separator + dirname; + basePath += File.separator + STORAGE_BASE_DIRECTORY_NAME + File.separator + dirname; Path avatarLocation = Paths.get(basePath); try { if (!Files.exists(avatarLocation)) { -- Gitee From 6eb8dd68dfc74fb3b3e0a8c6dc6c185d49904805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 24 Apr 2019 16:42:29 +0800 Subject: [PATCH 11/52] file normal --- src/main/java/com/fstack/service/impl/StorageServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java index c5c66e4..2b7de52 100644 --- a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java @@ -72,7 +72,7 @@ public class StorageServiceImpl implements StorageService { Path resolve = avatarLocation.resolve(filename); Files.copy(file.getInputStream(), resolve, StandardCopyOption.REPLACE_EXISTING); logger.info("Saved file to >> " + resolve); - return filename; + return dirname + File.separator + filename; } catch (IOException e) { throw new StorageException("Failed to store file " + filename, e); } -- Gitee From 7870c3a505a646e0b65eda3d800dc67dd48c7fdc Mon Sep 17 00:00:00 2001 From: Keven Date: Wed, 24 Apr 2019 18:15:07 +0800 Subject: [PATCH 12/52] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A4=B4=E5=83=8F?= =?UTF-8?q?=E5=9C=B0=E5=9D=80=E5=89=8D=E7=BC=80=E3=80=81Redis=E7=AB=AF?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/StorageServiceImpl.java | 10 +- src/main/resources/application-pro.properties | 2 +- src/main/resources/templates/forum/post.html | 4 +- .../templates/forum/user-profile.html | 2 +- .../templates/forum/user-settings.html | 197 +++++++++--------- .../templates/fragments/comments.html | 4 +- .../templates/fragments/posts-list.html | 2 +- 7 files changed, 113 insertions(+), 108 deletions(-) diff --git a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java index 2b7de52..8abded0 100644 --- a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java @@ -64,12 +64,12 @@ public class StorageServiceImpl implements StorageService { String filename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename())); String basePath = forumConfigProperties.getDataDirectory(); basePath += File.separator + STORAGE_BASE_DIRECTORY_NAME + File.separator + dirname; - Path avatarLocation = Paths.get(basePath); + Path path = Paths.get(basePath); try { - if (!Files.exists(avatarLocation)) { - Files.createDirectories(avatarLocation); + if (!Files.exists(path)) { + Files.createDirectories(path); } - Path resolve = avatarLocation.resolve(filename); + Path resolve = path.resolve(filename); Files.copy(file.getInputStream(), resolve, StandardCopyOption.REPLACE_EXISTING); logger.info("Saved file to >> " + resolve); return dirname + File.separator + filename; @@ -98,7 +98,7 @@ public class StorageServiceImpl implements StorageService { Files.copy(file.getInputStream(), resolve, StandardCopyOption.REPLACE_EXISTING); logger.info("Saved file to >> " + resolve); - return username + "/" + filename; + return "/avatar/" + username + "/" + filename; } catch (IOException e) { throw new StorageException("Failed to store file " + filename, e); } diff --git a/src/main/resources/application-pro.properties b/src/main/resources/application-pro.properties index 4e83710..032f544 100644 --- a/src/main/resources/application-pro.properties +++ b/src/main/resources/application-pro.properties @@ -20,7 +20,7 @@ spring.datasource.hikari.connection-test-query=SELECT 1 # ============================== spring.redis.database=0 spring.redis.host=www.polysys.cn -spring.redis.port=6379 +spring.redis.port=16161 spring.redis.password=fstack spring.redis.timeout=5000ms spring.redis.lettuce.pool.max-idle=10 diff --git a/src/main/resources/templates/forum/post.html b/src/main/resources/templates/forum/post.html index db9cd85..c61c1d1 100644 --- a/src/main/resources/templates/forum/post.html +++ b/src/main/resources/templates/forum/post.html @@ -19,8 +19,8 @@
diff --git a/src/main/resources/templates/fragments/posts-list.html b/src/main/resources/templates/fragments/posts-list.html index c25fc66..81d8102 100644 --- a/src/main/resources/templates/fragments/posts-list.html +++ b/src/main/resources/templates/fragments/posts-list.html @@ -23,7 +23,7 @@
-- Gitee From 92aad17c2acf7e7db040ca15d78e5097ca518d18 Mon Sep 17 00:00:00 2001 From: ab <672943942@qq.com> Date: Wed, 24 Apr 2019 18:22:13 +0800 Subject: [PATCH 13/52] =?UTF-8?q?=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/fstack/service/impl/StorageServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java index 8abded0..8a11e87 100644 --- a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java @@ -72,7 +72,7 @@ public class StorageServiceImpl implements StorageService { Path resolve = path.resolve(filename); Files.copy(file.getInputStream(), resolve, StandardCopyOption.REPLACE_EXISTING); logger.info("Saved file to >> " + resolve); - return dirname + File.separator + filename; + return File.separator + dirname + File.separator + filename; } catch (IOException e) { throw new StorageException("Failed to store file " + filename, e); } -- Gitee From 748fc3f8bdddb2ef1003a4111518a0e7eadcbeb0 Mon Sep 17 00:00:00 2001 From: ab <672943942@qq.com> Date: Wed, 24 Apr 2019 18:49:24 +0800 Subject: [PATCH 14/52] =?UTF-8?q?=E9=9B=86=E6=88=90swagger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 11 +++++ .../java/com/fstack/config/SwaggerConfig.java | 43 +++++++++++++++++++ src/main/resources/application-dev.properties | 4 +- src/main/resources/application-pro.properties | 4 +- 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/fstack/config/SwaggerConfig.java diff --git a/pom.xml b/pom.xml index 88ef2a7..f028a9d 100644 --- a/pom.xml +++ b/pom.xml @@ -31,6 +31,7 @@ 4.5.8 1.2.57 27.1-jre + 2.9.2 @@ -126,6 +127,16 @@ guava ${guava.version} + + io.springfox + springfox-swagger2 + ${swagger.version} + + + io.springfox + springfox-swagger-ui + ${swagger.version} + diff --git a/src/main/java/com/fstack/config/SwaggerConfig.java b/src/main/java/com/fstack/config/SwaggerConfig.java new file mode 100644 index 0000000..bf23ac5 --- /dev/null +++ b/src/main/java/com/fstack/config/SwaggerConfig.java @@ -0,0 +1,43 @@ +package com.fstack.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + + +@Configuration +@EnableSwagger2 +public class SwaggerConfig { + + @Value("${enable.swagger}") + private Boolean enable; + + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + .enable(enable) + .apiInfo(apiInfo()) + .select() + .apis(RequestHandlerSelectors.basePackage("com.fstack")) + .paths(PathSelectors.any()) + .build(); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("Spring Boot中使用Swagger2构建RESTful API") + .description("rest api 文档") + .termsOfServiceUrl("https://gitee.com/abj01") + .contact(new Contact("ab", "https://gitee.com/abj01", "672943942@qq.com")) + .version("1.0.0") + .build(); + } +} diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 5c51037..cf23669 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -49,4 +49,6 @@ service.url=http://localhost:8080 # File upload configuration # ============================== spring.servlet.multipart.max-file-size=500KB -spring.servlet.multipart.max-request-size =500KB \ No newline at end of file +spring.servlet.multipart.max-request-size =500KB + +enable.swagger=true \ No newline at end of file diff --git a/src/main/resources/application-pro.properties b/src/main/resources/application-pro.properties index 032f544..2450a74 100644 --- a/src/main/resources/application-pro.properties +++ b/src/main/resources/application-pro.properties @@ -49,4 +49,6 @@ service.url=http://localhost:8080 # File upload configuration # ============================== spring.servlet.multipart.max-file-size=500KB -spring.servlet.multipart.max-request-size =500KB \ No newline at end of file +spring.servlet.multipart.max-request-size =500KB + +enable.swagger=false \ No newline at end of file -- Gitee From 2ede950db79e7196dbcfdba1fa3dd98637891707 Mon Sep 17 00:00:00 2001 From: ab <672943942@qq.com> Date: Wed, 24 Apr 2019 18:54:06 +0800 Subject: [PATCH 15/52] =?UTF-8?q?=E9=9B=86=E6=88=90swagger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/fstack/config/StaticResourceConfig.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/fstack/config/StaticResourceConfig.java b/src/main/java/com/fstack/config/StaticResourceConfig.java index 5996059..ed1f62e 100644 --- a/src/main/java/com/fstack/config/StaticResourceConfig.java +++ b/src/main/java/com/fstack/config/StaticResourceConfig.java @@ -20,6 +20,11 @@ public class StaticResourceConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("swagger-ui.html") + .addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/"); + String avatarLocation = forumConfigProperties.getDataDirectory() + File.separator; avatarLocation += (StorageConstant.AVATAR_DIRECTORY_NAME + File.separator); registry.addResourceHandler("/avatar/**") -- Gitee From 0a6dc0ff5d43c60da4b0cc48878e2ee300105144 Mon Sep 17 00:00:00 2001 From: ab <672943942@qq.com> Date: Wed, 24 Apr 2019 19:50:15 +0800 Subject: [PATCH 16/52] =?UTF-8?q?=E9=9B=86=E6=88=90swagger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fstack/config/StaticResourceConfig.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/fstack/config/StaticResourceConfig.java b/src/main/java/com/fstack/config/StaticResourceConfig.java index ed1f62e..ad77987 100644 --- a/src/main/java/com/fstack/config/StaticResourceConfig.java +++ b/src/main/java/com/fstack/config/StaticResourceConfig.java @@ -2,6 +2,7 @@ package com.fstack.config; import com.fstack.constant.StorageConstant; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; @@ -18,12 +19,17 @@ public class StaticResourceConfig implements WebMvcConfigurer { @Autowired private FsForumConfigProperties forumConfigProperties; + @Value("${enable.swagger}") + private Boolean enable; + @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { - registry.addResourceHandler("swagger-ui.html") - .addResourceLocations("classpath:/META-INF/resources/"); - registry.addResourceHandler("/webjars/**") - .addResourceLocations("classpath:/META-INF/resources/webjars/"); + if (enable) { + registry.addResourceHandler("swagger-ui.html") + .addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/"); + } String avatarLocation = forumConfigProperties.getDataDirectory() + File.separator; avatarLocation += (StorageConstant.AVATAR_DIRECTORY_NAME + File.separator); -- Gitee From 7e75f034079d0678fcfe314767d6b00e1c9ce5cb Mon Sep 17 00:00:00 2001 From: ab <672943942@qq.com> Date: Wed, 24 Apr 2019 20:20:19 +0800 Subject: [PATCH 17/52] =?UTF-8?q?=E9=9B=86=E6=88=90swagger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fstack/config/StaticResourceConfig.java | 13 ++++++++----- .../com/fstack/constant/StorageConstant.java | 16 ++++++++-------- .../fstack/service/impl/StorageServiceImpl.java | 10 +++++----- src/main/resources/application.properties | 2 +- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/fstack/config/StaticResourceConfig.java b/src/main/java/com/fstack/config/StaticResourceConfig.java index ad77987..022c3a7 100644 --- a/src/main/java/com/fstack/config/StaticResourceConfig.java +++ b/src/main/java/com/fstack/config/StaticResourceConfig.java @@ -1,6 +1,5 @@ package com.fstack.config; -import com.fstack.constant.StorageConstant; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @@ -10,6 +9,8 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.io.File; +import static com.fstack.constant.StorageConstant.*; + /** * @author ab */ @@ -31,10 +32,12 @@ public class StaticResourceConfig implements WebMvcConfigurer { .addResourceLocations("classpath:/META-INF/resources/webjars/"); } - String avatarLocation = forumConfigProperties.getDataDirectory() + File.separator; - avatarLocation += (StorageConstant.AVATAR_DIRECTORY_NAME + File.separator); - registry.addResourceHandler("/avatar/**") - .addResourceLocations("file:" + avatarLocation); + registry.addResourceHandler(AVATAR_DIRECTORY_NAME + "/**") + .addResourceLocations("file:" + + forumConfigProperties.getDataDirectory() + File.separator + + BASE_DIRECTORY_NAME + + AVATAR_DIRECTORY_NAME + File.separator + ); } @Override diff --git a/src/main/java/com/fstack/constant/StorageConstant.java b/src/main/java/com/fstack/constant/StorageConstant.java index fbfad57..95762f6 100644 --- a/src/main/java/com/fstack/constant/StorageConstant.java +++ b/src/main/java/com/fstack/constant/StorageConstant.java @@ -1,22 +1,22 @@ package com.fstack.constant; -import java.io.File; /** * @author Hu Jie * @date 2019/04/24 1:52 PM */ public class StorageConstant { + private StorageConstant() {} + //default avatar + public static final String DEFAULT_AVATAR_FILENAME = "default.jpg"; + //base path define + public static final String BASE_DIRECTORY_NAME = "FsForumData"; - public static final String STORAGE_BASE_DIRECTORY_NAME = "FsForumData"; - - public static final String IAMGE_DIRECTORY_NAME = STORAGE_BASE_DIRECTORY_NAME + File.separator + "images"; - public static final String AVATAR_DIRECTORY_NAME = STORAGE_BASE_DIRECTORY_NAME + File.separator + "avatar"; + // some directory define + public static final String IAMGE_DIRECTORY_NAME = "/images"; + public static final String AVATAR_DIRECTORY_NAME = "/avatar"; - public static final String DEFAULT_AVATAR_FILENAME = "default.jpg"; - private StorageConstant() { - } } diff --git a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java index 8a11e87..17ec046 100644 --- a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java @@ -22,7 +22,7 @@ import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Objects; -import static com.fstack.constant.StorageConstant.STORAGE_BASE_DIRECTORY_NAME; +import static com.fstack.constant.StorageConstant.*; @Service("storageService") public class StorageServiceImpl implements StorageService { @@ -41,7 +41,7 @@ public class StorageServiceImpl implements StorageService { * 初始化创建数据目录,配置默认头像 */ private void init() { - String avatarDir = forumConfigProperties.getDataDirectory() + File.separator + StorageConstant.AVATAR_DIRECTORY_NAME + File.separator; + String avatarDir = forumConfigProperties.getDataDirectory() + File.separator + BASE_DIRECTORY_NAME + AVATAR_DIRECTORY_NAME + File.separator; Path avatarDirectoryLocation = Paths.get(avatarDir); try { if (!Files.exists(avatarDirectoryLocation)) { @@ -63,7 +63,7 @@ public class StorageServiceImpl implements StorageService { } String filename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename())); String basePath = forumConfigProperties.getDataDirectory(); - basePath += File.separator + STORAGE_BASE_DIRECTORY_NAME + File.separator + dirname; + basePath += File.separator + BASE_DIRECTORY_NAME + File.separator + dirname; Path path = Paths.get(basePath); try { if (!Files.exists(path)) { @@ -86,7 +86,7 @@ public class StorageServiceImpl implements StorageService { String filename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename())); String basePath = forumConfigProperties.getDataDirectory(); - basePath += File.separator + StorageConstant.AVATAR_DIRECTORY_NAME; + basePath += File.separator + BASE_DIRECTORY_NAME + AVATAR_DIRECTORY_NAME; Path avatarLocation = Paths.get(basePath + File.separator + username); try { @@ -98,7 +98,7 @@ public class StorageServiceImpl implements StorageService { Files.copy(file.getInputStream(), resolve, StandardCopyOption.REPLACE_EXISTING); logger.info("Saved file to >> " + resolve); - return "/avatar/" + username + "/" + filename; + return AVATAR_DIRECTORY_NAME + "/" + username + "/" + filename; } catch (IOException e) { throw new StorageException("Failed to store file " + filename, e); } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3d78eed..829c07b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,4 @@ -server.port=8080 +server.port=8081 spring.profiles.active=pro server.servlet.context-path= / spring.aop.proxy-target-class=true -- Gitee From 2324bce7d0683da4bf3fd3c5f45ad1158fbee499 Mon Sep 17 00:00:00 2001 From: ab <672943942@qq.com> Date: Wed, 24 Apr 2019 20:26:03 +0800 Subject: [PATCH 18/52] =?UTF-8?q?=E9=9B=86=E6=88=90swagger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fstack/service/impl/StorageServiceImpl.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java index 17ec046..b0b22be 100644 --- a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java @@ -62,8 +62,7 @@ public class StorageServiceImpl implements StorageService { return null; } String filename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename())); - String basePath = forumConfigProperties.getDataDirectory(); - basePath += File.separator + BASE_DIRECTORY_NAME + File.separator + dirname; + String basePath = forumConfigProperties.getDataDirectory() + File.separator + BASE_DIRECTORY_NAME + File.separator + dirname; Path path = Paths.get(basePath); try { if (!Files.exists(path)) { @@ -83,21 +82,16 @@ public class StorageServiceImpl implements StorageService { if (Objects.isNull(file) || file.isEmpty() || StringUtils.isEmpty(username)) { return null; } - String filename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename())); - String basePath = forumConfigProperties.getDataDirectory(); - basePath += File.separator + BASE_DIRECTORY_NAME + AVATAR_DIRECTORY_NAME; + String basePath = forumConfigProperties.getDataDirectory() + File.separator + BASE_DIRECTORY_NAME + AVATAR_DIRECTORY_NAME; Path avatarLocation = Paths.get(basePath + File.separator + username); - try { if (!Files.exists(avatarLocation)) { Files.createDirectories(avatarLocation); } - Path resolve = avatarLocation.resolve(filename); Files.copy(file.getInputStream(), resolve, StandardCopyOption.REPLACE_EXISTING); logger.info("Saved file to >> " + resolve); - return AVATAR_DIRECTORY_NAME + "/" + username + "/" + filename; } catch (IOException e) { throw new StorageException("Failed to store file " + filename, e); -- Gitee From f6aeaae795e47d2970baab12dab188f6892edc98 Mon Sep 17 00:00:00 2001 From: ab <672943942@qq.com> Date: Wed, 24 Apr 2019 20:28:24 +0800 Subject: [PATCH 19/52] =?UTF-8?q?=E8=B7=AF=E5=BE=84=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 829c07b..3d78eed 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,4 @@ -server.port=8081 +server.port=8080 spring.profiles.active=pro server.servlet.context-path= / spring.aop.proxy-target-class=true -- Gitee From 2624c1fab038f396be5b5f131bf33c4cf3f378f4 Mon Sep 17 00:00:00 2001 From: Miles <1010933988@qq.com> Date: Wed, 24 Apr 2019 21:04:24 +0800 Subject: [PATCH 20/52] =?UTF-8?q?=E6=B7=BB=E5=8A=A0vue=E7=9A=84build?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 - fstackforum-vue/build/build.js | 41 ++++++ fstackforum-vue/build/check-versions.js | 54 ++++++++ fstackforum-vue/build/logo.png | Bin 0 -> 6849 bytes fstackforum-vue/build/utils.js | 101 ++++++++++++++ fstackforum-vue/build/vue-loader.conf.js | 22 ++++ fstackforum-vue/build/webpack.base.conf.js | 82 ++++++++++++ fstackforum-vue/build/webpack.dev.conf.js | 95 ++++++++++++++ fstackforum-vue/build/webpack.prod.conf.js | 145 +++++++++++++++++++++ 9 files changed, 540 insertions(+), 1 deletion(-) create mode 100644 fstackforum-vue/build/build.js create mode 100644 fstackforum-vue/build/check-versions.js create mode 100644 fstackforum-vue/build/logo.png create mode 100644 fstackforum-vue/build/utils.js create mode 100644 fstackforum-vue/build/vue-loader.conf.js create mode 100644 fstackforum-vue/build/webpack.base.conf.js create mode 100755 fstackforum-vue/build/webpack.dev.conf.js create mode 100644 fstackforum-vue/build/webpack.prod.conf.js diff --git a/.gitignore b/.gitignore index 73d39e4..4e6fd26 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,6 @@ target/ ### NetBeans ### nbproject/private/ -build/ nbbuild/ dist/ nbdist/ diff --git a/fstackforum-vue/build/build.js b/fstackforum-vue/build/build.js new file mode 100644 index 0000000..8f2ad8a --- /dev/null +++ b/fstackforum-vue/build/build.js @@ -0,0 +1,41 @@ +'use strict' +require('./check-versions')() + +process.env.NODE_ENV = 'production' + +const ora = require('ora') +const rm = require('rimraf') +const path = require('path') +const chalk = require('chalk') +const webpack = require('webpack') +const config = require('../config') +const webpackConfig = require('./webpack.prod.conf') + +const spinner = ora('building for production...') +spinner.start() + +rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { + if (err) throw err + webpack(webpackConfig, (err, stats) => { + spinner.stop() + if (err) throw err + process.stdout.write(stats.toString({ + colors: true, + modules: false, + children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. + chunks: false, + chunkModules: false + }) + '\n\n') + + if (stats.hasErrors()) { + console.log(chalk.red(' Build failed with errors.\n')) + process.exit(1) + } + + console.log(chalk.cyan(' Build complete.\n')) + console.log(chalk.yellow( + ' Tip: built files are meant to be served over an HTTP server.\n' + + ' Opening index.html over file:// won\'t work.\n' + )) + }) +}) diff --git a/fstackforum-vue/build/check-versions.js b/fstackforum-vue/build/check-versions.js new file mode 100644 index 0000000..3ef972a --- /dev/null +++ b/fstackforum-vue/build/check-versions.js @@ -0,0 +1,54 @@ +'use strict' +const chalk = require('chalk') +const semver = require('semver') +const packageConfig = require('../package.json') +const shell = require('shelljs') + +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + currentVersion: semver.clean(process.version), + versionRequirement: packageConfig.engines.node + } +] + +if (shell.which('npm')) { + versionRequirements.push({ + name: 'npm', + currentVersion: exec('npm --version'), + versionRequirement: packageConfig.engines.npm + }) +} + +module.exports = function () { + const warnings = [] + + for (let i = 0; i < versionRequirements.length; i++) { + const mod = versionRequirements[i] + + if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { + warnings.push(mod.name + ': ' + + chalk.red(mod.currentVersion) + ' should be ' + + chalk.green(mod.versionRequirement) + ) + } + } + + if (warnings.length) { + console.log('') + console.log(chalk.yellow('To use this template, you must update following to modules:')) + console.log() + + for (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + + console.log() + process.exit(1) + } +} diff --git a/fstackforum-vue/build/logo.png b/fstackforum-vue/build/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 zcmaKRcUV(fvo}bjDT-7nLI_nlK}sT_69H+`qzVWDA|yaU?}j417wLi^B1KB1SLsC& zL0ag7$U(XW5YR7p&Ux?sP$d4lvMt8C^+TcQu4F zQqv!UF!I+kw)c0jhd6+g6oCr9P?7)?!qX1ui*iL{p}sKCAGuJ{{W)0z1pLF|=>h}& zt(2Lr0Z`2ig8<5i%Zk}cO5Fm=LByqGWaS`oqChZdEFmc`0hSb#gg|Aap^{+WKOYcj zHjINK)KDG%&s?Mt4CL(T=?;~U@bU2x_mLKN!#GJuK_CzbNw5SMEJorG!}_5;?R>@1 zSl)jns3WlU7^J%=(hUtfmuUCU&C3%8B5C^f5>W2Cy8jW3#{Od{lF1}|?c61##3dzA zsPlFG;l_FzBK}8>|H_Ru_H#!_7$UH4UKo3lKOA}g1(R&|e@}GINYVzX?q=_WLZCgh z)L|eJMce`D0EIwgRaNETDsr+?vQknSGAi=7H00r`QnI%oQnFxm`G2umXso9l+8*&Q z7WqF|$p49js$mdzo^BXpH#gURy=UO;=IMrYc5?@+sR4y_?d*~0^YP7d+y0{}0)zBM zIKVM(DBvICK#~7N0a+PY6)7;u=dutmNqK3AlsrUU9U`d;msiucB_|8|2kY=(7XA;G zwDA8AR)VCA#JOkxm#6oHNS^YVuOU;8p$N)2{`;oF|rQ?B~K$%rHDxXs+_G zF5|-uqHZvSzq}L;5Kcy_P+x0${33}Ofb6+TX&=y;;PkEOpz%+_bCw_{<&~ zeLV|!bP%l1qxywfVr9Z9JI+++EO^x>ZuCK);=$VIG1`kxK8F2M8AdC$iOe3cj1fo(ce4l-9 z7*zKy3={MixvUk=enQE;ED~7tv%qh&3lR<0m??@w{ILF|e#QOyPkFYK!&Up7xWNtL zOW%1QMC<3o;G9_S1;NkPB6bqbCOjeztEc6TsBM<(q9((JKiH{01+Ud=uw9B@{;(JJ z-DxI2*{pMq`q1RQc;V8@gYAY44Z!%#W~M9pRxI(R?SJ7sy7em=Z5DbuDlr@*q|25V)($-f}9c#?D%dU^RS<(wz?{P zFFHtCab*!rl(~j@0(Nadvwg8q|4!}L^>d?0al6}Rrv9$0M#^&@zjbfJy_n!%mVHK4 z6pLRIQ^Uq~dnyy$`ay51Us6WaP%&O;@49m&{G3z7xV3dLtt1VTOMYl3UW~Rm{Eq4m zF?Zl_v;?7EFx1_+#WFUXxcK78IV)FO>42@cm@}2I%pVbZqQ}3;p;sDIm&knay03a^ zn$5}Q$G!@fTwD$e(x-~aWP0h+4NRz$KlnO_H2c< z(XX#lPuW_%H#Q+c&(nRyX1-IadKR-%$4FYC0fsCmL9ky3 zKpxyjd^JFR+vg2!=HWf}2Z?@Td`0EG`kU?{8zKrvtsm)|7>pPk9nu@2^z96aU2<#` z2QhvH5w&V;wER?mopu+nqu*n8p~(%QkwSs&*0eJwa zMXR05`OSFpfyRb!Y_+H@O%Y z0=K^y6B8Gcbl?SA)qMP3Z+=C(?8zL@=74R=EVnE?vY!1BQy2@q*RUgRx4yJ$k}MnL zs!?74QciNb-LcG*&o<9=DSL>1n}ZNd)w1z3-0Pd^4ED1{qd=9|!!N?xnXjM!EuylY z5=!H>&hSofh8V?Jofyd!h`xDI1fYAuV(sZwwN~{$a}MX^=+0TH*SFp$vyxmUv7C*W zv^3Gl0+eTFgBi3FVD;$nhcp)ka*4gSskYIqQ&+M}xP9yLAkWzBI^I%zR^l1e?bW_6 zIn{mo{dD=)9@V?s^fa55jh78rP*Ze<3`tRCN4*mpO$@7a^*2B*7N_|A(Ve2VB|)_o z$=#_=aBkhe(ifX}MLT()@5?OV+~7cXC3r!%{QJxriXo9I%*3q4KT4Xxzyd{ z9;_%=W%q!Vw$Z7F3lUnY+1HZ*lO;4;VR2+i4+D(m#01OYq|L_fbnT;KN<^dkkCwtd zF7n+O7KvAw8c`JUh6LmeIrk4`F3o|AagKSMK3))_5Cv~y2Bb2!Ibg9BO7Vkz?pAYX zoI=B}+$R22&IL`NCYUYjrdhwjnMx_v=-Qcx-jmtN>!Zqf|n1^SWrHy zK|MwJ?Z#^>)rfT5YSY{qjZ&`Fjd;^vv&gF-Yj6$9-Dy$<6zeP4s+78gS2|t%Z309b z0^fp~ue_}i`U9j!<|qF92_3oB09NqgAoehQ`)<)dSfKoJl_A6Ec#*Mx9Cpd-p#$Ez z={AM*r-bQs6*z$!*VA4|QE7bf@-4vb?Q+pPKLkY2{yKsw{&udv_2v8{Dbd zm~8VAv!G~s)`O3|Q6vFUV%8%+?ZSVUa(;fhPNg#vab@J*9XE4#D%)$UU-T5`fwjz! z6&gA^`OGu6aUk{l*h9eB?opVdrHK>Q@U>&JQ_2pR%}TyOXGq_6s56_`U(WoOaAb+K zXQr#6H}>a-GYs9^bGP2Y&hSP5gEtW+GVC4=wy0wQk=~%CSXj=GH6q z-T#s!BV`xZVxm{~jr_ezYRpqqIcXC=Oq`b{lu`Rt(IYr4B91hhVC?yg{ol4WUr3v9 zOAk2LG>CIECZ-WIs0$N}F#eoIUEtZudc7DPYIjzGqDLWk_A4#(LgacooD z2K4IWs@N`Bddm-{%oy}!k0^i6Yh)uJ1S*90>|bm3TOZxcV|ywHUb(+CeX-o1|LTZM zwU>dY3R&U)T(}5#Neh?-CWT~@{6Ke@sI)uSuzoah8COy)w)B)aslJmp`WUcjdia-0 zl2Y}&L~XfA`uYQboAJ1;J{XLhYjH){cObH3FDva+^8ioOQy%Z=xyjGLmWMrzfFoH; zEi3AG`_v+%)&lDJE;iJWJDI@-X9K5O)LD~j*PBe(wu+|%ar~C+LK1+-+lK=t# z+Xc+J7qp~5q=B~rD!x78)?1+KUIbYr^5rcl&tB-cTtj+e%{gpZZ4G~6r15+d|J(ky zjg@@UzMW0k9@S#W(1H{u;Nq(7llJbq;;4t$awM;l&(2s+$l!Ay9^Ge|34CVhr7|BG z?dAR83smef^frq9V(OH+a+ki#q&-7TkWfFM=5bsGbU(8mC;>QTCWL5ydz9s6k@?+V zcjiH`VI=59P-(-DWXZ~5DH>B^_H~;4$)KUhnmGo*G!Tq8^LjfUDO)lASN*=#AY_yS zqW9UX(VOCO&p@kHdUUgsBO0KhXxn1sprK5h8}+>IhX(nSXZKwlNsjk^M|RAaqmCZB zHBolOHYBas@&{PT=R+?d8pZu zUHfyucQ`(umXSW7o?HQ3H21M`ZJal+%*)SH1B1j6rxTlG3hx1IGJN^M7{$j(9V;MZ zRKybgVuxKo#XVM+?*yTy{W+XHaU5Jbt-UG33x{u(N-2wmw;zzPH&4DE103HV@ER86 z|FZEmQb|&1s5#`$4!Cm}&`^{(4V}OP$bk`}v6q6rm;P!H)W|2i^e{7lTk2W@jo_9q z*aw|U7#+g59Fv(5qI`#O-qPj#@_P>PC#I(GSp3DLv7x-dmYK=C7lPF8a)bxb=@)B1 zUZ`EqpXV2dR}B&r`uM}N(TS99ZT0UB%IN|0H%DcVO#T%L_chrgn#m6%x4KE*IMfjX zJ%4veCEqbXZ`H`F_+fELMC@wuy_ch%t*+Z+1I}wN#C+dRrf2X{1C8=yZ_%Pt6wL_~ zZ2NN-hXOT4P4n$QFO7yYHS-4wF1Xfr-meG9Pn;uK51?hfel`d38k{W)F*|gJLT2#T z<~>spMu4(mul-8Q3*pf=N4DcI)zzjqAgbE2eOT7~&f1W3VsdD44Ffe;3mJp-V@8UC z)|qnPc12o~$X-+U@L_lWqv-RtvB~%hLF($%Ew5w>^NR82qC_0FB z)=hP1-OEx?lLi#jnLzH}a;Nvr@JDO-zQWd}#k^an$Kwml;MrD&)sC5b`s0ZkVyPkb zt}-jOq^%_9>YZe7Y}PhW{a)c39G`kg(P4@kxjcYfgB4XOOcmezdUI7j-!gs7oAo2o zx(Ph{G+YZ`a%~kzK!HTAA5NXE-7vOFRr5oqY$rH>WI6SFvWmahFav!CfRMM3%8J&c z*p+%|-fNS_@QrFr(at!JY9jCg9F-%5{nb5Bo~z@Y9m&SHYV`49GAJjA5h~h4(G!Se zZmK{Bo7ivCfvl}@A-ptkFGcWXAzj3xfl{evi-OG(TaCn1FAHxRc{}B|x+Ua1D=I6M z!C^ZIvK6aS_c&(=OQDZfm>O`Nxsw{ta&yiYPA~@e#c%N>>#rq)k6Aru-qD4(D^v)y z*>Rs;YUbD1S8^D(ps6Jbj0K3wJw>L4m)0e(6Pee3Y?gy9i0^bZO?$*sv+xKV?WBlh zAp*;v6w!a8;A7sLB*g-^<$Z4L7|5jXxxP1}hQZ<55f9<^KJ>^mKlWSGaLcO0=$jem zWyZkRwe~u{{tU63DlCaS9$Y4CP4f?+wwa(&1ou)b>72ydrFvm`Rj-0`kBJgK@nd(*Eh!(NC{F-@=FnF&Y!q`7){YsLLHf0_B6aHc# z>WIuHTyJwIH{BJ4)2RtEauC7Yq7Cytc|S)4^*t8Va3HR zg=~sN^tp9re@w=GTx$;zOWMjcg-7X3Wk^N$n;&Kf1RgVG2}2L-(0o)54C509C&77i zrjSi{X*WV=%C17((N^6R4Ya*4#6s_L99RtQ>m(%#nQ#wrRC8Y%yxkH;d!MdY+Tw@r zjpSnK`;C-U{ATcgaxoEpP0Gf+tx);buOMlK=01D|J+ROu37qc*rD(w`#O=3*O*w9?biwNoq3WN1`&Wp8TvKj3C z3HR9ssH7a&Vr<6waJrU zdLg!ieYz%U^bmpn%;(V%%ugMk92&?_XX1K@mwnVSE6!&%P%Wdi7_h`CpScvspMx?N zQUR>oadnG17#hNc$pkTp+9lW+MBKHRZ~74XWUryd)4yd zj98$%XmIL4(9OnoeO5Fnyn&fpQ9b0h4e6EHHw*l68j;>(ya`g^S&y2{O8U>1*>4zR zq*WSI_2o$CHQ?x0!wl9bpx|Cm2+kFMR)oMud1%n2=qn5nE&t@Fgr#=Zv2?}wtEz^T z9rrj=?IH*qI5{G@Rn&}^Z{+TW}mQeb9=8b<_a`&Cm#n%n~ zU47MvCBsdXFB1+adOO)03+nczfWa#vwk#r{o{dF)QWya9v2nv43Zp3%Ps}($lA02*_g25t;|T{A5snSY?3A zrRQ~(Ygh_ebltHo1VCbJb*eOAr;4cnlXLvI>*$-#AVsGg6B1r7@;g^L zFlJ_th0vxO7;-opU@WAFe;<}?!2q?RBrFK5U{*ai@NLKZ^};Ul}beukveh?TQn;$%9=R+DX07m82gP$=}Uo_%&ngV`}Hyv8g{u z3SWzTGV|cwQuFIs7ZDOqO_fGf8Q`8MwL}eUp>q?4eqCmOTcwQuXtQckPy|4F1on8l zP*h>d+cH#XQf|+6c|S{7SF(Lg>bR~l(0uY?O{OEVlaxa5@e%T&xju=o1`=OD#qc16 zSvyH*my(dcp6~VqR;o(#@m44Lug@~_qw+HA=mS#Z^4reBy8iV?H~I;{LQWk3aKK8$bLRyt$g?- { + const notifier = require('node-notifier') + + return (severity, errors) => { + if (severity !== 'error') return + + const error = errors[0] + const filename = error.file && error.file.split('!').pop() + + notifier.notify({ + title: packageConfig.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +} diff --git a/fstackforum-vue/build/vue-loader.conf.js b/fstackforum-vue/build/vue-loader.conf.js new file mode 100644 index 0000000..33ed58b --- /dev/null +++ b/fstackforum-vue/build/vue-loader.conf.js @@ -0,0 +1,22 @@ +'use strict' +const utils = require('./utils') +const config = require('../config') +const isProduction = process.env.NODE_ENV === 'production' +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: ['src', 'poster'], + source: 'src', + img: 'src', + image: 'xlink:href' + } +} diff --git a/fstackforum-vue/build/webpack.base.conf.js b/fstackforum-vue/build/webpack.base.conf.js new file mode 100644 index 0000000..a07e683 --- /dev/null +++ b/fstackforum-vue/build/webpack.base.conf.js @@ -0,0 +1,82 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const vueLoaderConfig = require('./vue-loader.conf') + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + + + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + }, + node: { + // prevent webpack from injecting useless setImmediate polyfill because Vue + // source contains it (although only uses it if it's native). + setImmediate: false, + // prevent webpack from injecting mocks to Node native modules + // that does not make sense for the client + dgram: 'empty', + fs: 'empty', + net: 'empty', + tls: 'empty', + child_process: 'empty' + } +} diff --git a/fstackforum-vue/build/webpack.dev.conf.js b/fstackforum-vue/build/webpack.dev.conf.js new file mode 100755 index 0000000..070ae22 --- /dev/null +++ b/fstackforum-vue/build/webpack.dev.conf.js @@ -0,0 +1,95 @@ +'use strict' +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const path = require('path') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') +const portfinder = require('portfinder') + +const HOST = process.env.HOST +const PORT = process.env.PORT && Number(process.env.PORT) + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + clientLogLevel: 'warning', + historyApiFallback: { + rewrites: [ + { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, + ], + }, + hot: true, + contentBase: false, // since we use CopyWebpackPlugin. + compress: true, + host: HOST || config.dev.host, + port: PORT || config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay + ? { warnings: false, errors: true } + : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.dev.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port + portfinder.getPort((err, port) => { + if (err) { + reject(err) + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port + // add port to devServer config + devWebpackConfig.devServer.port = port + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })) + + resolve(devWebpackConfig) + } + }) +}) diff --git a/fstackforum-vue/build/webpack.prod.conf.js b/fstackforum-vue/build/webpack.prod.conf.js new file mode 100644 index 0000000..d9f99f6 --- /dev/null +++ b/fstackforum-vue/build/webpack.prod.conf.js @@ -0,0 +1,145 @@ +'use strict' +const path = require('path') +const utils = require('./utils') +const webpack = require('webpack') +const config = require('../config') +const merge = require('webpack-merge') +const baseWebpackConfig = require('./webpack.base.conf') +const CopyWebpackPlugin = require('copy-webpack-plugin') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') + +const env = require('../config/prod.env') + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + new UglifyJsPlugin({ + uglifyOptions: { + compress: { + warnings: false + } + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // Setting the following option to `false` will not extract CSS from codesplit chunks. + // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. + // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, + // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 + allChunks: true, + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSPlugin({ + cssProcessorOptions: config.build.productionSourceMap + ? { safe: true, map: { inline: false } } + : { safe: true } + }), + // generate dist index.html with correct asset hash for caching. + // you can customize output by editing /index.html + // see https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: config.build.index, + template: 'index.html', + inject: true, + minify: { + removeComments: true, + collapseWhitespace: true, + removeAttributeQuotes: true + // more options: + // https://github.com/kangax/html-minifier#options-quick-reference + }, + // necessary to consistently work with multiple chunks via CommonsChunkPlugin + chunksSortMode: 'dependency' + }), + // keep module.id stable when vendor modules does not change + new webpack.HashedModuleIdsPlugin(), + // enable scope hoisting + new webpack.optimize.ModuleConcatenationPlugin(), + // split vendor js into its own file + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks (module) { + // any required modules inside node_modules are extracted to vendor + return ( + module.resource && + /\.js$/.test(module.resource) && + module.resource.indexOf( + path.join(__dirname, '../node_modules') + ) === 0 + ) + } + }), + // extract webpack runtime and module manifest to its own file in order to + // prevent vendor hash from being updated whenever app bundle is updated + new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + minChunks: Infinity + }), + // This instance extracts shared chunks from code splitted chunks and bundles them + // in a separate chunk, similar to the vendor chunk + // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk + new webpack.optimize.CommonsChunkPlugin({ + name: 'app', + async: 'vendor-async', + children: true, + minChunks: 3 + }), + + // copy custom static assets + new CopyWebpackPlugin([ + { + from: path.resolve(__dirname, '../static'), + to: config.build.assetsSubDirectory, + ignore: ['.*'] + } + ]) + ] +}) + +if (config.build.productionGzip) { + const CompressionWebpackPlugin = require('compression-webpack-plugin') + + webpackConfig.plugins.push( + new CompressionWebpackPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp( + '\\.(' + + config.build.productionGzipExtensions.join('|') + + ')$' + ), + threshold: 10240, + minRatio: 0.8 + }) + ) +} + +if (config.build.bundleAnalyzerReport) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin + webpackConfig.plugins.push(new BundleAnalyzerPlugin()) +} + +module.exports = webpackConfig -- Gitee From 53242bf88a8f77726d3a6881e73a739378e3f52f Mon Sep 17 00:00:00 2001 From: Miles <1010933988@qq.com> Date: Wed, 24 Apr 2019 21:55:29 +0800 Subject: [PATCH 21/52] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E7=AB=AF=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-dev.properties | 2 +- src/main/resources/application.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index cf23669..dab59dd 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -43,7 +43,7 @@ spring.mail.properties.mail.smtp.starttls.required=true # ============================== # service base URL for confirmation link # ============================== -service.url=http://localhost:8080 +service.url=http://localhost:8090 # ============================== # File upload configuration diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3d78eed..3304f4a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,4 @@ -server.port=8080 +server.port=8090 spring.profiles.active=pro server.servlet.context-path= / spring.aop.proxy-target-class=true -- Gitee From c59fc5603a4206bd0d9790025bcae6b5618df0a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Thu, 25 Apr 2019 08:34:29 +0800 Subject: [PATCH 22/52] file normal --- src/main/java/com/fstack/service/impl/StorageServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java index b0b22be..0505102 100644 --- a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java @@ -71,7 +71,7 @@ public class StorageServiceImpl implements StorageService { Path resolve = path.resolve(filename); Files.copy(file.getInputStream(), resolve, StandardCopyOption.REPLACE_EXISTING); logger.info("Saved file to >> " + resolve); - return File.separator + dirname + File.separator + filename; + return "/" + dirname + "/" + filename; } catch (IOException e) { throw new StorageException("Failed to store file " + filename, e); } @@ -91,7 +91,7 @@ public class StorageServiceImpl implements StorageService { } Path resolve = avatarLocation.resolve(filename); Files.copy(file.getInputStream(), resolve, StandardCopyOption.REPLACE_EXISTING); - logger.info("Saved file to >> " + resolve); + logger.info("Saved avatar to >> " + resolve); return AVATAR_DIRECTORY_NAME + "/" + username + "/" + filename; } catch (IOException e) { throw new StorageException("Failed to store file " + filename, e); -- Gitee From de86942dffece0f7e642d769a3c6b9660a3bed0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Thu, 25 Apr 2019 08:57:20 +0800 Subject: [PATCH 23/52] hikari cp --- src/main/resources/application-pro.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-pro.properties b/src/main/resources/application-pro.properties index 2450a74..69dbc5c 100644 --- a/src/main/resources/application-pro.properties +++ b/src/main/resources/application-pro.properties @@ -9,7 +9,7 @@ spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.maximum-pool-size=15 spring.datasource.hikari.auto-commit=true -spring.datasource.hikari.idle-timeout=60000 +spring.datasource.hikari.idle-timeout=600000 spring.datasource.hikari.pool-name=fang spring.datasource.hikari.max-lifetime=1800000 spring.datasource.hikari.connection-timeout=30000 -- Gitee From 3a903748eb56a7fad406ad0e55fc9ba3bbb40239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Thu, 25 Apr 2019 09:09:23 +0800 Subject: [PATCH 24/52] hikari cp bug fixed --- src/main/resources/application-pro.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application-pro.properties b/src/main/resources/application-pro.properties index 69dbc5c..45e7c05 100644 --- a/src/main/resources/application-pro.properties +++ b/src/main/resources/application-pro.properties @@ -10,8 +10,8 @@ spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.maximum-pool-size=15 spring.datasource.hikari.auto-commit=true spring.datasource.hikari.idle-timeout=600000 -spring.datasource.hikari.pool-name=fang -spring.datasource.hikari.max-lifetime=1800000 +spring.datasource.hikari.pool-name=ab01 +spring.datasource.hikari.max-lifetime=700000 spring.datasource.hikari.connection-timeout=30000 spring.datasource.hikari.connection-test-query=SELECT 1 -- Gitee From 8a72571156ebe93df121a01acdd1bae955f61b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Fri, 26 Apr 2019 08:45:56 +0800 Subject: [PATCH 25/52] swagger permit --- .../java/com/fstack/config/security/WebSecurityConfig.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/fstack/config/security/WebSecurityConfig.java b/src/main/java/com/fstack/config/security/WebSecurityConfig.java index 740afad..b3ede4b 100644 --- a/src/main/java/com/fstack/config/security/WebSecurityConfig.java +++ b/src/main/java/com/fstack/config/security/WebSecurityConfig.java @@ -48,6 +48,9 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable().authorizeRequests() + // swagger be allowed to be viewed without authentication + .antMatchers("/swagger-ui.html", "/swagger-resources/**", + "/v2/api-docs", "/webjars/**" ).permitAll() // all static resource and home page .antMatchers("/", "/avatar/**", "/", "/js/**", "/css/**", "/images/**", "/fonts/**", "/bootstrap-select/**", "/bootstrap-datetimepicker/**", "/custom/**", "/daterangepicker/**", "/chartjs/**").permitAll() -- Gitee From 7c7fe7d4167b1cf20351b5a21fa02ca32350c71d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Fri, 26 Apr 2019 08:50:19 +0800 Subject: [PATCH 26/52] registration permit --- .../config/security/WebSecurityConfig.java | 2 ++ .../fstack/web/controller/UserController.java | 17 +++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/fstack/config/security/WebSecurityConfig.java b/src/main/java/com/fstack/config/security/WebSecurityConfig.java index b3ede4b..3eda8e2 100644 --- a/src/main/java/com/fstack/config/security/WebSecurityConfig.java +++ b/src/main/java/com/fstack/config/security/WebSecurityConfig.java @@ -58,6 +58,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/post/**").permitAll() // all categories are allowed to be viewed without authentication .antMatchers("/category/**").permitAll() + // user registration be allowed to be viewed without authentication + .antMatchers("/user/registration").permitAll() .anyRequest().authenticated() // login URL can be accessed by anyone .and() diff --git a/src/main/java/com/fstack/web/controller/UserController.java b/src/main/java/com/fstack/web/controller/UserController.java index 21f08a7..362c9d5 100644 --- a/src/main/java/com/fstack/web/controller/UserController.java +++ b/src/main/java/com/fstack/web/controller/UserController.java @@ -25,6 +25,7 @@ import com.fstack.web.dto.UserRegistrationDto; import com.fstack.web.dto.UserSettingsDto; @Controller +@RequestMapping("/user") public class UserController { private static final Logger logger = LoggerFactory.getLogger(UserController.class); @@ -35,7 +36,7 @@ public class UserController { @Autowired private NewUserFormValidator userValidator; - @RequestMapping(value = "/user/{userId}", method = RequestMethod.GET) + @RequestMapping(value = "/{userId}", method = RequestMethod.GET) public String showUserProfilePage(@RequestParam(value = "tab", required = false) String tabType, @PathVariable Long userId, Model model) { if (null == userId) { @@ -49,13 +50,13 @@ public class UserController { return "forum/user-profile"; } - @RequestMapping(value = "/user/registration", method = RequestMethod.GET) + @RequestMapping(value = "/registration", method = RequestMethod.GET) public String showRegistrationPage(Model model) { model.addAttribute("userDto", new UserRegistrationDto()); return "forum/user-registration"; } - @RequestMapping(value = "/user/registration", method = RequestMethod.POST) + @RequestMapping(value = "/registration", method = RequestMethod.POST) public String registerNewUser(@Valid @ModelAttribute("userDto") UserRegistrationDto userDto, BindingResult bindingResult, Model model, HttpServletRequest request) { /* @@ -74,18 +75,18 @@ public class UserController { return "forum/user-registration-result"; } - @RequestMapping(value = "/user/login", method = RequestMethod.GET) + @RequestMapping(value = "/login", method = RequestMethod.GET) public String displayLoginPage(Model model) { model.addAttribute("title", "用户登录"); return "forum/user-login"; } - @RequestMapping(value = "/user/login-success", method = RequestMethod.GET) + @RequestMapping(value = "/login-success", method = RequestMethod.GET) public String showAdminPage() { return "forum/user-login"; } - @RequestMapping(value = "/user/registration-confirm", method = RequestMethod.GET) + @RequestMapping(value = "/registration-confirm", method = RequestMethod.GET) public String confirmRegistration(@RequestParam("token") String token, Model model) { if (null == token || token.equals("")) { throw new BadRequestException("Invalid user registration confirmation token."); @@ -98,7 +99,7 @@ public class UserController { return "forum/user-registration-confirm"; } - @RequestMapping(value = "/user/settings", method = RequestMethod.GET) + @RequestMapping(value = "/settings", method = RequestMethod.GET) public String showUserSettingsPage(Model model) { Map attributes = this.userService.getUserSettingPage(); if (null == attributes) { @@ -108,7 +109,7 @@ public class UserController { return "forum/user-settings"; } - @RequestMapping(value = "/user/settings", method = RequestMethod.POST) + @RequestMapping(value = "/settings", method = RequestMethod.POST) public String handleFileUpload(@ModelAttribute("userSettingsDto") UserSettingsDto userSettingsDto, Model model) { if (null == userSettingsDto) { throw new BadRequestException("UserSettingsDto cound not be null."); -- Gitee From 8a7bb7d58ab67910492cbd7b9be411cd2a97c79c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Fri, 26 Apr 2019 09:01:01 +0800 Subject: [PATCH 27/52] pro swagger enabled true --- .../fstack/web/controller/UserController.java | 188 +++++++++--------- src/main/resources/application-pro.properties | 2 +- 2 files changed, 96 insertions(+), 94 deletions(-) diff --git a/src/main/java/com/fstack/web/controller/UserController.java b/src/main/java/com/fstack/web/controller/UserController.java index 362c9d5..ab3af45 100644 --- a/src/main/java/com/fstack/web/controller/UserController.java +++ b/src/main/java/com/fstack/web/controller/UserController.java @@ -5,6 +5,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; +import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -28,98 +29,99 @@ import com.fstack.web.dto.UserSettingsDto; @RequestMapping("/user") public class UserController { - private static final Logger logger = LoggerFactory.getLogger(UserController.class); - - @Autowired - private UserService userService; - - @Autowired - private NewUserFormValidator userValidator; - - @RequestMapping(value = "/{userId}", method = RequestMethod.GET) - public String showUserProfilePage(@RequestParam(value = "tab", required = false) String tabType, - @PathVariable Long userId, Model model) { - if (null == userId) { - throw new BadRequestException("Path variable userId cound not be null."); - } - Map attributes = this.userService.getUserProfileAndPostsByUserIdByTabType(userId, tabType); - if (null == attributes) { - throw new ResourceNotFoundException("attributes not found."); - } - model.addAllAttributes(attributes); - return "forum/user-profile"; - } - - @RequestMapping(value = "/registration", method = RequestMethod.GET) - public String showRegistrationPage(Model model) { - model.addAttribute("userDto", new UserRegistrationDto()); - return "forum/user-registration"; - } - - @RequestMapping(value = "/registration", method = RequestMethod.POST) - public String registerNewUser(@Valid @ModelAttribute("userDto") UserRegistrationDto userDto, - BindingResult bindingResult, Model model, HttpServletRequest request) { - /* - * form validation, check username and email uniqueness - */ - this.userValidator.validate(userDto, bindingResult); - if (bindingResult.hasErrors()) { - logger.info("BindingResult has errors >> " + bindingResult.getFieldError()); - return "forum/user-registration"; - } - Map attributes = this.userService.registerUserAccount(userDto, request); - if (null == attributes) { - throw new ResourceNotFoundException("attributes not found."); - } - model.addAllAttributes(attributes); - return "forum/user-registration-result"; - } - - @RequestMapping(value = "/login", method = RequestMethod.GET) - public String displayLoginPage(Model model) { - model.addAttribute("title", "用户登录"); - return "forum/user-login"; - } - - @RequestMapping(value = "/login-success", method = RequestMethod.GET) - public String showAdminPage() { - return "forum/user-login"; - } - - @RequestMapping(value = "/registration-confirm", method = RequestMethod.GET) - public String confirmRegistration(@RequestParam("token") String token, Model model) { - if (null == token || token.equals("")) { - throw new BadRequestException("Invalid user registration confirmation token."); - } - Map attributes = this.userService.confirmUserRegistrationWithToken(token); - if (null == attributes) { - throw new ResourceNotFoundException("attributes not found."); - } - model.addAllAttributes(attributes); - return "forum/user-registration-confirm"; - } - - @RequestMapping(value = "/settings", method = RequestMethod.GET) - public String showUserSettingsPage(Model model) { - Map attributes = this.userService.getUserSettingPage(); - if (null == attributes) { - throw new ResourceNotFoundException("attributes not found."); - } - model.addAllAttributes(attributes); - return "forum/user-settings"; - } - - @RequestMapping(value = "/settings", method = RequestMethod.POST) - public String handleFileUpload(@ModelAttribute("userSettingsDto") UserSettingsDto userSettingsDto, Model model) { - if (null == userSettingsDto) { - throw new BadRequestException("UserSettingsDto cound not be null."); - } - Map attributes = this.userService.updateUserProfile(userSettingsDto); - if (null == attributes) { - throw new ResourceNotFoundException("attributes not found."); - } - model.addAllAttributes(attributes); - return "forum/user-settings"; - } + private static final Logger logger = LoggerFactory.getLogger(UserController.class); + + @Autowired + private UserService userService; + + @Autowired + private NewUserFormValidator userValidator; + + @ApiOperation("获取用户信息") + @RequestMapping(value = "/{userId}", method = RequestMethod.GET) + public String showUserProfilePage(@RequestParam(value = "tab", required = false) String tabType, + @PathVariable Long userId, Model model) { + if (null == userId) { + throw new BadRequestException("Path variable userId cound not be null."); + } + Map attributes = this.userService.getUserProfileAndPostsByUserIdByTabType(userId, tabType); + if (null == attributes) { + throw new ResourceNotFoundException("attributes not found."); + } + model.addAllAttributes(attributes); + return "forum/user-profile"; + } + + @RequestMapping(value = "/registration", method = RequestMethod.GET) + public String showRegistrationPage(Model model) { + model.addAttribute("userDto", new UserRegistrationDto()); + return "forum/user-registration"; + } + + @RequestMapping(value = "/registration", method = RequestMethod.POST) + public String registerNewUser(@Valid @ModelAttribute("userDto") UserRegistrationDto userDto, + BindingResult bindingResult, Model model, HttpServletRequest request) { + /* + * form validation, check username and email uniqueness + */ + this.userValidator.validate(userDto, bindingResult); + if (bindingResult.hasErrors()) { + logger.info("BindingResult has errors >> " + bindingResult.getFieldError()); + return "forum/user-registration"; + } + Map attributes = this.userService.registerUserAccount(userDto, request); + if (null == attributes) { + throw new ResourceNotFoundException("attributes not found."); + } + model.addAllAttributes(attributes); + return "forum/user-registration-result"; + } + + @RequestMapping(value = "/login", method = RequestMethod.GET) + public String displayLoginPage(Model model) { + model.addAttribute("title", "用户登录"); + return "forum/user-login"; + } + + @RequestMapping(value = "/login-success", method = RequestMethod.GET) + public String showAdminPage() { + return "forum/user-login"; + } + + @RequestMapping(value = "/registration-confirm", method = RequestMethod.GET) + public String confirmRegistration(@RequestParam("token") String token, Model model) { + if (null == token || token.equals("")) { + throw new BadRequestException("Invalid user registration confirmation token."); + } + Map attributes = this.userService.confirmUserRegistrationWithToken(token); + if (null == attributes) { + throw new ResourceNotFoundException("attributes not found."); + } + model.addAllAttributes(attributes); + return "forum/user-registration-confirm"; + } + + @RequestMapping(value = "/settings", method = RequestMethod.GET) + public String showUserSettingsPage(Model model) { + Map attributes = this.userService.getUserSettingPage(); + if (null == attributes) { + throw new ResourceNotFoundException("attributes not found."); + } + model.addAllAttributes(attributes); + return "forum/user-settings"; + } + + @RequestMapping(value = "/settings", method = RequestMethod.POST) + public String handleFileUpload(@ModelAttribute("userSettingsDto") UserSettingsDto userSettingsDto, Model model) { + if (null == userSettingsDto) { + throw new BadRequestException("UserSettingsDto cound not be null."); + } + Map attributes = this.userService.updateUserProfile(userSettingsDto); + if (null == attributes) { + throw new ResourceNotFoundException("attributes not found."); + } + model.addAllAttributes(attributes); + return "forum/user-settings"; + } } diff --git a/src/main/resources/application-pro.properties b/src/main/resources/application-pro.properties index 45e7c05..39077dd 100644 --- a/src/main/resources/application-pro.properties +++ b/src/main/resources/application-pro.properties @@ -51,4 +51,4 @@ service.url=http://localhost:8080 spring.servlet.multipart.max-file-size=500KB spring.servlet.multipart.max-request-size =500KB -enable.swagger=false \ No newline at end of file +enable.swagger=true \ No newline at end of file -- Gitee From 4fa5460e7b3005a2987564c291e2b71fd1c644da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Fri, 26 Apr 2019 09:02:58 +0800 Subject: [PATCH 28/52] description --- src/main/java/com/fstack/config/SwaggerConfig.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/fstack/config/SwaggerConfig.java b/src/main/java/com/fstack/config/SwaggerConfig.java index bf23ac5..031ad8a 100644 --- a/src/main/java/com/fstack/config/SwaggerConfig.java +++ b/src/main/java/com/fstack/config/SwaggerConfig.java @@ -33,8 +33,8 @@ public class SwaggerConfig { private ApiInfo apiInfo() { return new ApiInfoBuilder() - .title("Spring Boot中使用Swagger2构建RESTful API") - .description("rest api 文档") + .title("给菜鸡看的文档") + .description("金太阳幼儿园三班专属") .termsOfServiceUrl("https://gitee.com/abj01") .contact(new Contact("ab", "https://gitee.com/abj01", "672943942@qq.com")) .version("1.0.0") -- Gitee From b4025f15c1e6846711dfb41ca045633f780d1d6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Fri, 26 Apr 2019 09:04:07 +0800 Subject: [PATCH 29/52] swagger description --- src/main/java/com/fstack/config/SwaggerConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/fstack/config/SwaggerConfig.java b/src/main/java/com/fstack/config/SwaggerConfig.java index 031ad8a..c2a46f2 100644 --- a/src/main/java/com/fstack/config/SwaggerConfig.java +++ b/src/main/java/com/fstack/config/SwaggerConfig.java @@ -37,7 +37,7 @@ public class SwaggerConfig { .description("金太阳幼儿园三班专属") .termsOfServiceUrl("https://gitee.com/abj01") .contact(new Contact("ab", "https://gitee.com/abj01", "672943942@qq.com")) - .version("1.0.0") + .version("6.6.6") .build(); } } -- Gitee From fae3cba49caa870ee300f8908a4bdf641faf1e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Fri, 26 Apr 2019 09:06:03 +0800 Subject: [PATCH 30/52] swagger description --- src/main/java/com/fstack/web/controller/UserController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/fstack/web/controller/UserController.java b/src/main/java/com/fstack/web/controller/UserController.java index ab3af45..fafd63d 100644 --- a/src/main/java/com/fstack/web/controller/UserController.java +++ b/src/main/java/com/fstack/web/controller/UserController.java @@ -5,6 +5,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; +import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,6 +26,7 @@ import com.fstack.validator.NewUserFormValidator; import com.fstack.web.dto.UserRegistrationDto; import com.fstack.web.dto.UserSettingsDto; +@Api(value = "UserController", description = "用户管理") @Controller @RequestMapping("/user") public class UserController { -- Gitee From 0853ab9f9e5068344b47e732ee72288b3f1530ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Mon, 1 Jul 2019 15:44:49 +0800 Subject: [PATCH 31/52] swagger description --- src/main/resources/application-dev.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index dab59dd..f595da9 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -2,9 +2,9 @@ # MySQL connection config # ============================== spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver -spring.datasource.url = jdbc:mysql://localhost:3306/forum?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 +spring.datasource.url = jdbc:mysql://192.168.1.130:3306/forum?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 spring.datasource.username = root -spring.datasource.password = root +spring.datasource.password = 902db98ee7f45aae spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.maximum-pool-size=15 @@ -19,7 +19,7 @@ spring.datasource.hikari.connection-test-query=SELECT 1 # Redis configuration # ============================== spring.redis.database=0 -spring.redis.host=192.168.1.129 +spring.redis.host=192.168.1.130 spring.redis.port=6379 spring.redis.password=kaixin spring.redis.timeout=5000ms -- Gitee From 4f1da2f01e5721812c1e8178cd33aeca3249e6db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Mon, 1 Jul 2019 15:48:58 +0800 Subject: [PATCH 32/52] swagger description --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f819a0f..cccc480 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 菜鸡论坛 +# 私人论坛 ### Backend 后端 - Spring Boot 2.1.4 -- Gitee From 57d1d38798bd54331e96af527f6b9d9cb2498b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Mon, 1 Jul 2019 15:50:29 +0800 Subject: [PATCH 33/52] =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-pro.properties | 54 ------------------- 1 file changed, 54 deletions(-) diff --git a/src/main/resources/application-pro.properties b/src/main/resources/application-pro.properties index 39077dd..e69de29 100644 --- a/src/main/resources/application-pro.properties +++ b/src/main/resources/application-pro.properties @@ -1,54 +0,0 @@ -# ============================== -# MySQL connection config -# ============================== -spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver -spring.datasource.url = jdbc:mysql://www.polysys.cn:13306/fs_forum?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 -spring.datasource.username = fstack -spring.datasource.password = fstack -spring.datasource.type=com.zaxxer.hikari.HikariDataSource -spring.datasource.hikari.minimum-idle=5 -spring.datasource.hikari.maximum-pool-size=15 -spring.datasource.hikari.auto-commit=true -spring.datasource.hikari.idle-timeout=600000 -spring.datasource.hikari.pool-name=ab01 -spring.datasource.hikari.max-lifetime=700000 -spring.datasource.hikari.connection-timeout=30000 -spring.datasource.hikari.connection-test-query=SELECT 1 - -# ============================== -# Redis configuration -# ============================== -spring.redis.database=0 -spring.redis.host=www.polysys.cn -spring.redis.port=16161 -spring.redis.password=fstack -spring.redis.timeout=5000ms -spring.redis.lettuce.pool.max-idle=10 -spring.redis.lettuce.pool.min-idle=5 -spring.redis.lettuce.pool.max-active=20 -spring.redis.lettuce.pool.max-wait=-1ms - -# ============================== -# SMTP Email -# ============================== -spring.mail.default-encoding=UTF-8 -spring.mail.host = smtp.qq.com -spring.mail.username = 672943942@qq.com -# \u6388\u6743\u7801\u4E0D\u662F\u771F\u5B9E\u5BC6\u7801 -spring.mail.password = 123456 -spring.mail.properties.mail.smtp.auth=true -spring.mail.properties.mail.smtp.starttls.enable=true -spring.mail.properties.mail.smtp.starttls.required=true - -# ============================== -# service base URL for confirmation link -# ============================== -service.url=http://localhost:8080 - -# ============================== -# File upload configuration -# ============================== -spring.servlet.multipart.max-file-size=500KB -spring.servlet.multipart.max-request-size =500KB - -enable.swagger=true \ No newline at end of file -- Gitee From 503f4e08bf3eed0bc8d66ae0ac2e194b8a181ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Mon, 1 Jul 2019 15:51:40 +0800 Subject: [PATCH 34/52] =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/fstack/service/impl/PostServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/fstack/service/impl/PostServiceImpl.java b/src/main/java/com/fstack/service/impl/PostServiceImpl.java index d9f260d..582ae7f 100644 --- a/src/main/java/com/fstack/service/impl/PostServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/PostServiceImpl.java @@ -27,7 +27,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -@Service("postService") +@Service @Transactional public class PostServiceImpl implements PostService { -- Gitee From 9635dce2e9689770551555ccb1e5663f505f4e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Mon, 1 Jul 2019 15:58:35 +0800 Subject: [PATCH 35/52] =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-dev.properties | 6 +++--- src/main/resources/application.properties | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index f595da9..62b872d 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -2,9 +2,9 @@ # MySQL connection config # ============================== spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver -spring.datasource.url = jdbc:mysql://192.168.1.130:3306/forum?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 -spring.datasource.username = root -spring.datasource.password = 902db98ee7f45aae +spring.datasource.url = jdbc:mysql://192.168.1.130:3306/fangrong?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 +spring.datasource.username = fangrong +spring.datasource.password = GsWJAHJtNc2R85xx spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.maximum-pool-size=15 diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3304f4a..6562132 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,5 @@ -server.port=8090 -spring.profiles.active=pro +server.port=9999 +spring.profiles.active=dev server.servlet.context-path= / spring.aop.proxy-target-class=true # ============================== -- Gitee From 4fedcb8728a499f200d2a85250b9b9db71dca6d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Mon, 1 Jul 2019 16:21:51 +0800 Subject: [PATCH 36/52] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=90=8D=E4=BB=A5IT?= =?UTF-8?q?=E5=BC=80=E5=A4=B4=E7=9A=84=E8=87=AA=E5=8A=A8=E6=BF=80=E6=B4=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/fstack/service/impl/UserServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/fstack/service/impl/UserServiceImpl.java b/src/main/java/com/fstack/service/impl/UserServiceImpl.java index 42ca29e..7587345 100644 --- a/src/main/java/com/fstack/service/impl/UserServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/UserServiceImpl.java @@ -161,7 +161,7 @@ public class UserServiceImpl implements UserService { user.setDateCreated(new Timestamp(System.currentTimeMillis())); user.activated(false); user.setRoles(User.USER); - + if (userDto.getUsername().startsWith("IT")) user.setActivated(1L); // save new user and get number of affected row int affectedRow = userMapper.save(user); -- Gitee From c8768696e081ccd518f0118aa1129c2b49fc24c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Mon, 1 Jul 2019 16:23:19 +0800 Subject: [PATCH 37/52] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=90=8D=E4=BB=A5IT?= =?UTF-8?q?=E5=BC=80=E5=A4=B4=E7=9A=84=E8=87=AA=E5=8A=A8=E6=BF=80=E6=B4=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/fstack/service/impl/UserServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/fstack/service/impl/UserServiceImpl.java b/src/main/java/com/fstack/service/impl/UserServiceImpl.java index 7587345..0d9a84f 100644 --- a/src/main/java/com/fstack/service/impl/UserServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/UserServiceImpl.java @@ -159,9 +159,9 @@ public class UserServiceImpl implements UserService { user.setUsername(userDto.getUsername()); user.setEmail(userDto.getEmail()); user.setDateCreated(new Timestamp(System.currentTimeMillis())); - user.activated(false); user.setRoles(User.USER); - if (userDto.getUsername().startsWith("IT")) user.setActivated(1L); + if (userDto.getUsername().startsWith("IT")) user.activated(true); + else user.activated(false); // save new user and get number of affected row int affectedRow = userMapper.save(user); -- Gitee From 893316350bef2cea06d811ddc8e33ee223f41054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Mon, 1 Jul 2019 17:28:26 +0800 Subject: [PATCH 38/52] =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/fstack/service/impl/PostServiceImpl.java | 2 +- .../java/com/fstack/service/impl/StorageServiceImpl.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/fstack/service/impl/PostServiceImpl.java b/src/main/java/com/fstack/service/impl/PostServiceImpl.java index 582ae7f..d9f260d 100644 --- a/src/main/java/com/fstack/service/impl/PostServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/PostServiceImpl.java @@ -27,7 +27,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -@Service +@Service("postService") @Transactional public class PostServiceImpl implements PostService { diff --git a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java index 0505102..d2499ef 100644 --- a/src/main/java/com/fstack/service/impl/StorageServiceImpl.java +++ b/src/main/java/com/fstack/service/impl/StorageServiceImpl.java @@ -47,10 +47,10 @@ public class StorageServiceImpl implements StorageService { if (!Files.exists(avatarDirectoryLocation)) { Files.createDirectories(avatarDirectoryLocation); } - Path resolve = avatarDirectoryLocation.resolve(StorageConstant.DEFAULT_AVATAR_FILENAME); + /*Path resolve = avatarDirectoryLocation.resolve(StorageConstant.DEFAULT_AVATAR_FILENAME); URL defaultAvatarUrl = ResourceUtils.getURL("classpath:static/" + StorageConstant.DEFAULT_AVATAR_FILENAME); - Files.copy(Paths.get(defaultAvatarUrl.toURI()), resolve, StandardCopyOption.REPLACE_EXISTING); - } catch (IOException | URISyntaxException e) { + Files.copy(Paths.get(defaultAvatarUrl.toURI()), resolve, StandardCopyOption.REPLACE_EXISTING);*/ + } catch (IOException e) { e.printStackTrace(); } -- Gitee From af005563137a13b075bafec068c53ae7e5cb446e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Mon, 1 Jul 2019 17:32:36 +0800 Subject: [PATCH 39/52] =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-dev.properties | 2 +- src/main/resources/application.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 62b872d..ab138b4 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -2,7 +2,7 @@ # MySQL connection config # ============================== spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver -spring.datasource.url = jdbc:mysql://192.168.1.130:3306/fangrong?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 +spring.datasource.url = jdbc:mysql://127.0.0.1:3306/fangrong?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 spring.datasource.username = fangrong spring.datasource.password = GsWJAHJtNc2R85xx spring.datasource.type=com.zaxxer.hikari.HikariDataSource diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6562132..3673d60 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,6 +1,6 @@ server.port=9999 spring.profiles.active=dev -server.servlet.context-path= / +server.servlet.context-path= /forum spring.aop.proxy-target-class=true # ============================== # MyBatis configuration -- Gitee From 6583d5cdacc683c35a9ad55f624d00c601b11498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Mon, 1 Jul 2019 17:37:35 +0800 Subject: [PATCH 40/52] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E6=A0=B9=E8=B7=AF?= =?UTF-8?q?=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3673d60..6562132 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,6 +1,6 @@ server.port=9999 spring.profiles.active=dev -server.servlet.context-path= /forum +server.servlet.context-path= / spring.aop.proxy-target-class=true # ============================== # MyBatis configuration -- Gitee From ca3ec506c50f7c5e3e71b18c63959f659ea16db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Mon, 1 Jul 2019 17:47:25 +0800 Subject: [PATCH 41/52] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-dev.properties | 2 +- .../resources/application-local.properties | 54 +++++++++++++++++++ src/main/resources/application-pro.properties | 0 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/application-local.properties delete mode 100644 src/main/resources/application-pro.properties diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index ab138b4..62b872d 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -2,7 +2,7 @@ # MySQL connection config # ============================== spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver -spring.datasource.url = jdbc:mysql://127.0.0.1:3306/fangrong?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 +spring.datasource.url = jdbc:mysql://192.168.1.130:3306/fangrong?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 spring.datasource.username = fangrong spring.datasource.password = GsWJAHJtNc2R85xx spring.datasource.type=com.zaxxer.hikari.HikariDataSource diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties new file mode 100644 index 0000000..ab138b4 --- /dev/null +++ b/src/main/resources/application-local.properties @@ -0,0 +1,54 @@ +# ============================== +# MySQL connection config +# ============================== +spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver +spring.datasource.url = jdbc:mysql://127.0.0.1:3306/fangrong?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 +spring.datasource.username = fangrong +spring.datasource.password = GsWJAHJtNc2R85xx +spring.datasource.type=com.zaxxer.hikari.HikariDataSource +spring.datasource.hikari.minimum-idle=5 +spring.datasource.hikari.maximum-pool-size=15 +spring.datasource.hikari.auto-commit=true +spring.datasource.hikari.idle-timeout=60000 +spring.datasource.hikari.pool-name=fang +spring.datasource.hikari.max-lifetime=1800000 +spring.datasource.hikari.connection-timeout=30000 +spring.datasource.hikari.connection-test-query=SELECT 1 + +# ============================== +# Redis configuration +# ============================== +spring.redis.database=0 +spring.redis.host=192.168.1.130 +spring.redis.port=6379 +spring.redis.password=kaixin +spring.redis.timeout=5000ms +spring.redis.lettuce.pool.max-idle=10 +spring.redis.lettuce.pool.min-idle=5 +spring.redis.lettuce.pool.max-active=20 +spring.redis.lettuce.pool.max-wait=-1ms + +# ============================== +# SMTP Email +# ============================== +spring.mail.default-encoding=UTF-8 +spring.mail.host = smtp.qq.com +spring.mail.username = 672943942@qq.com +# \u6388\u6743\u7801\u4E0D\u662F\u771F\u5B9E\u5BC6\u7801 +spring.mail.password = 123456 +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true +spring.mail.properties.mail.smtp.starttls.required=true + +# ============================== +# service base URL for confirmation link +# ============================== +service.url=http://localhost:8090 + +# ============================== +# File upload configuration +# ============================== +spring.servlet.multipart.max-file-size=500KB +spring.servlet.multipart.max-request-size =500KB + +enable.swagger=true \ No newline at end of file diff --git a/src/main/resources/application-pro.properties b/src/main/resources/application-pro.properties deleted file mode 100644 index e69de29..0000000 -- Gitee From 9ffd8dd8a7320273a8cea365245472dfed1ab30c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 3 Jul 2019 08:02:48 +0800 Subject: [PATCH 42/52] =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-dev.properties | 2 +- src/main/resources/application-local.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 62b872d..ab138b4 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -2,7 +2,7 @@ # MySQL connection config # ============================== spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver -spring.datasource.url = jdbc:mysql://192.168.1.130:3306/fangrong?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 +spring.datasource.url = jdbc:mysql://127.0.0.1:3306/fangrong?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 spring.datasource.username = fangrong spring.datasource.password = GsWJAHJtNc2R85xx spring.datasource.type=com.zaxxer.hikari.HikariDataSource diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index ab138b4..24af4b5 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -3,8 +3,8 @@ # ============================== spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver spring.datasource.url = jdbc:mysql://127.0.0.1:3306/fangrong?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 -spring.datasource.username = fangrong -spring.datasource.password = GsWJAHJtNc2R85xx +spring.datasource.username = root +spring.datasource.password = root spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.maximum-pool-size=15 -- Gitee From 2179eb310d1a4bb52268013aab560005b7b09d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 3 Jul 2019 08:04:53 +0800 Subject: [PATCH 43/52] =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f028a9d..6f5bf70 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.fstack FStackForum - 0.0.1-SNAPSHOT + 1.0.0 jar FStackForum -- Gitee From 00fdeca2e09cf8772738cd00a43b58f829740ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 3 Jul 2019 08:39:01 +0800 Subject: [PATCH 44/52] =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-local.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 24af4b5..a35c7d6 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -2,7 +2,7 @@ # MySQL connection config # ============================== spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver -spring.datasource.url = jdbc:mysql://127.0.0.1:3306/fangrong?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 +spring.datasource.url = jdbc:mysql://192.168.1.204:3306/forum?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=UTF-8 spring.datasource.username = root spring.datasource.password = root spring.datasource.type=com.zaxxer.hikari.HikariDataSource -- Gitee From bbe896f0ee9cb1cbdb843c13ca4cacac75da3979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 3 Jul 2019 08:40:14 +0800 Subject: [PATCH 45/52] =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6562132..3c1d377 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,5 @@ server.port=9999 -spring.profiles.active=dev +spring.profiles.active=local server.servlet.context-path= / spring.aop.proxy-target-class=true # ============================== -- Gitee From 068058c2750a4613cd46a190d0aa9070e32f7496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 3 Jul 2019 09:18:58 +0800 Subject: [PATCH 46/52] =?UTF-8?q?=E9=82=AE=E7=AE=B1=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/fstack/event/RegistrationListener.java | 4 ++-- src/main/resources/application-dev.properties | 9 ++++----- src/main/resources/application-local.properties | 9 ++++----- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/fstack/event/RegistrationListener.java b/src/main/java/com/fstack/event/RegistrationListener.java index b5e3918..9c61c67 100644 --- a/src/main/java/com/fstack/event/RegistrationListener.java +++ b/src/main/java/com/fstack/event/RegistrationListener.java @@ -21,9 +21,9 @@ import java.util.UUID; @Component public class RegistrationListener implements ApplicationListener { - private static final String VERIFICATION_EMAIL_FROM_ADDR = "672943942@qq.com"; + private static final String VERIFICATION_EMAIL_FROM_ADDR = "look7788ab@163.com"; - private static final String VERIFICATION_EMAIL_SUBJECT = "用户注册确认"; + private static final String VERIFICATION_EMAIL_SUBJECT = "私人论坛用户注册确认"; private static final String CONFIRM_ENDPOINT = "registration-confirm"; diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index ab138b4..3035dff 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -32,10 +32,9 @@ spring.redis.lettuce.pool.max-wait=-1ms # SMTP Email # ============================== spring.mail.default-encoding=UTF-8 -spring.mail.host = smtp.qq.com -spring.mail.username = 672943942@qq.com -# \u6388\u6743\u7801\u4E0D\u662F\u771F\u5B9E\u5BC6\u7801 -spring.mail.password = 123456 +spring.mail.host = smtp.163.com +spring.mail.username = look7788ab@163.com +spring.mail.password = ab7788look spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true @@ -43,7 +42,7 @@ spring.mail.properties.mail.smtp.starttls.required=true # ============================== # service base URL for confirmation link # ============================== -service.url=http://localhost:8090 +service.url=http://192.168.1.130:9999 # ============================== # File upload configuration diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index a35c7d6..99bca4e 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -32,10 +32,9 @@ spring.redis.lettuce.pool.max-wait=-1ms # SMTP Email # ============================== spring.mail.default-encoding=UTF-8 -spring.mail.host = smtp.qq.com -spring.mail.username = 672943942@qq.com -# \u6388\u6743\u7801\u4E0D\u662F\u771F\u5B9E\u5BC6\u7801 -spring.mail.password = 123456 +spring.mail.host = smtp.163.com +spring.mail.username = look7788ab@163.com +spring.mail.password = ab7788look spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true @@ -43,7 +42,7 @@ spring.mail.properties.mail.smtp.starttls.required=true # ============================== # service base URL for confirmation link # ============================== -service.url=http://localhost:8090 +service.url=http://192.168.1.204:9999 # ============================== # File upload configuration -- Gitee From 793cf011b061e3fa1a9b31c551598dab082c6d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 3 Jul 2019 09:33:08 +0800 Subject: [PATCH 47/52] =?UTF-8?q?=E9=82=AE=E7=AE=B1=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E6=BF=80=E6=B4=BB=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/fstack/config/security/WebSecurityConfig.java | 1 + src/main/resources/application-dev.properties | 2 +- src/main/resources/application-local.properties | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/fstack/config/security/WebSecurityConfig.java b/src/main/java/com/fstack/config/security/WebSecurityConfig.java index 3eda8e2..723c955 100644 --- a/src/main/java/com/fstack/config/security/WebSecurityConfig.java +++ b/src/main/java/com/fstack/config/security/WebSecurityConfig.java @@ -60,6 +60,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/category/**").permitAll() // user registration be allowed to be viewed without authentication .antMatchers("/user/registration").permitAll() + .antMatchers("/user/registration-confirm").permitAll() .anyRequest().authenticated() // login URL can be accessed by anyone .and() diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 3035dff..cf0bb0b 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -34,7 +34,7 @@ spring.redis.lettuce.pool.max-wait=-1ms spring.mail.default-encoding=UTF-8 spring.mail.host = smtp.163.com spring.mail.username = look7788ab@163.com -spring.mail.password = ab7788look +spring.mail.password = look7788ab spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 99bca4e..7c9960f 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -34,7 +34,7 @@ spring.redis.lettuce.pool.max-wait=-1ms spring.mail.default-encoding=UTF-8 spring.mail.host = smtp.163.com spring.mail.username = look7788ab@163.com -spring.mail.password = ab7788look +spring.mail.password = look7788ab spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true -- Gitee From 0eb931b5b604ceca0e29f0a380591959c222a9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 3 Jul 2019 09:50:53 +0800 Subject: [PATCH 48/52] =?UTF-8?q?=E9=82=AE=E7=AE=B1=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E6=BF=80=E6=B4=BB=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/templates/forum/user-registration-result.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/forum/user-registration-result.html b/src/main/resources/templates/forum/user-registration-result.html index e103e96..9dd9712 100644 --- a/src/main/resources/templates/forum/user-registration-result.html +++ b/src/main/resources/templates/forum/user-registration-result.html @@ -15,7 +15,7 @@
- 注册成功。 + 注册成功,请及时去邮箱激活您的账号。
-- Gitee From ab58b8b5785ff2c6baf4590ace43bd63508eabe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 3 Jul 2019 09:54:06 +0800 Subject: [PATCH 49/52] =?UTF-8?q?=E9=82=AE=E7=AE=B1=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E6=BF=80=E6=B4=BB=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/fstack/event/RegistrationListener.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/fstack/event/RegistrationListener.java b/src/main/java/com/fstack/event/RegistrationListener.java index 9c61c67..b21b80f 100644 --- a/src/main/java/com/fstack/event/RegistrationListener.java +++ b/src/main/java/com/fstack/event/RegistrationListener.java @@ -66,10 +66,8 @@ public class RegistrationListener implements ApplicationListener> " + confirmationLink); email.setFrom(VERIFICATION_EMAIL_FROM_ADDR); email.setSubject(VERIFICATION_EMAIL_SUBJECT); - email.setText(confirmationLink); + email.setText("请及时激活您的账号,该链接24小时内有效===> " + confirmationLink); email.setTo(user.getEmail()); - // TODO: 2019/4/18 - // send email asynchronously this.emailService.sendEmail(email); } } -- Gitee From cfde694aa1f938401c854d8125fe08defb839653 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 3 Jul 2019 10:20:48 +0800 Subject: [PATCH 50/52] =?UTF-8?q?=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/forum/home.html | 8 ++++---- src/main/resources/templates/forum/new-post.html | 4 ++-- src/main/resources/templates/forum/post.html | 8 ++++---- src/main/resources/templates/forum/user-login.html | 8 ++++---- src/main/resources/templates/forum/user-profile.html | 4 ++-- .../templates/forum/user-registration-confirm.html | 8 ++++---- .../templates/forum/user-registration-result.html | 8 ++++---- src/main/resources/templates/forum/user-registration.html | 8 ++++---- src/main/resources/templates/forum/user-settings.html | 4 ++-- src/main/resources/templates/fragments/footer.html | 2 +- 10 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/main/resources/templates/forum/home.html b/src/main/resources/templates/forum/home.html index e0b9333..033c0c6 100644 --- a/src/main/resources/templates/forum/home.html +++ b/src/main/resources/templates/forum/home.html @@ -22,12 +22,12 @@ 快速发帖
-
消息1
-
消息内容1
+
广告位1
+
详情请联系管理员:)
-
消息2
-
消息内容2
+
广告位2
+
672943942@qq.com
diff --git a/src/main/resources/templates/forum/new-post.html b/src/main/resources/templates/forum/new-post.html index 9d2465f..76fa8fd 100644 --- a/src/main/resources/templates/forum/new-post.html +++ b/src/main/resources/templates/forum/new-post.html @@ -45,8 +45,8 @@
-
消息1
-
消息内容1
+
广告位1
+
详情请联系管理员:)
diff --git a/src/main/resources/templates/forum/post.html b/src/main/resources/templates/forum/post.html index c61c1d1..aff3ac4 100644 --- a/src/main/resources/templates/forum/post.html +++ b/src/main/resources/templates/forum/post.html @@ -43,12 +43,12 @@
-
消息
-
消息内容
+
广告位1
+
详情请联系管理员:)
-
消息
-
消息内容
+
广告位2
+
详情请联系管理员:)
diff --git a/src/main/resources/templates/forum/user-login.html b/src/main/resources/templates/forum/user-login.html index 3b623e0..44af823 100644 --- a/src/main/resources/templates/forum/user-login.html +++ b/src/main/resources/templates/forum/user-login.html @@ -39,13 +39,13 @@
-
消息
-
消息内容
+
广告位1
+
详情请联系管理员:)
-
消息
-
消息内容
+
广告位2
+
详情请联系管理员:)
diff --git a/src/main/resources/templates/forum/user-profile.html b/src/main/resources/templates/forum/user-profile.html index 5fdd5f2..afb2254 100644 --- a/src/main/resources/templates/forum/user-profile.html +++ b/src/main/resources/templates/forum/user-profile.html @@ -67,8 +67,8 @@
-
公告
-
公告内容
+
广告位
+
详情请联系管理员:)
diff --git a/src/main/resources/templates/forum/user-registration-confirm.html b/src/main/resources/templates/forum/user-registration-confirm.html index 2f350a6..ff4ca17 100644 --- a/src/main/resources/templates/forum/user-registration-confirm.html +++ b/src/main/resources/templates/forum/user-registration-confirm.html @@ -31,12 +31,12 @@
-
消息
-
消息内容
+
广告位1
+
详情请联系管理员:)
-
消息
-
消息内容
+
广告位2
+
详情请联系管理员:)
diff --git a/src/main/resources/templates/forum/user-registration-result.html b/src/main/resources/templates/forum/user-registration-result.html index 9dd9712..21bac21 100644 --- a/src/main/resources/templates/forum/user-registration-result.html +++ b/src/main/resources/templates/forum/user-registration-result.html @@ -31,13 +31,13 @@
-
消息
-
消息内容
+
广告位1
+
详情请联系管理员:)
-
消息
-
消息内容
+
广告位2
+
详情请联系管理员:)
diff --git a/src/main/resources/templates/forum/user-registration.html b/src/main/resources/templates/forum/user-registration.html index c45ca1a..714e5a4 100644 --- a/src/main/resources/templates/forum/user-registration.html +++ b/src/main/resources/templates/forum/user-registration.html @@ -61,13 +61,13 @@
-
消息
-
消息内容
+
广告位1
+
详情请联系管理员:)
-
消息
-
消息内容
+
广告位2
+
详情请联系管理员:)
diff --git a/src/main/resources/templates/forum/user-settings.html b/src/main/resources/templates/forum/user-settings.html index 2602305..8f60de0 100644 --- a/src/main/resources/templates/forum/user-settings.html +++ b/src/main/resources/templates/forum/user-settings.html @@ -109,8 +109,8 @@
-
消息1
-
消息内容1
+
广告位
+
详情请联系管理员:)
diff --git a/src/main/resources/templates/fragments/footer.html b/src/main/resources/templates/fragments/footer.html index 7a5692c..d0a7371 100644 --- a/src/main/resources/templates/fragments/footer.html +++ b/src/main/resources/templates/fragments/footer.html @@ -4,7 +4,7 @@

- wh© 2019 bbc.caiJi.com + wh© 2019 bbc.wong.com

-- Gitee From cf0ce8b2ea56c5b3325e3dcb0db19192dc89c1cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 3 Jul 2019 11:02:58 +0800 Subject: [PATCH 51/52] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=9D=83=E9=99=90?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 6f5bf70..c8cfd58 100644 --- a/pom.xml +++ b/pom.xml @@ -19,11 +19,14 @@ + + UTF-8 UTF-8 1.8 1.16.14 - 3.0.4.RELEASE + 3.0.4.RELEASE 8.0.15 1.3.2 1.2.3 @@ -74,8 +77,8 @@ org.thymeleaf.extras - thymeleaf-extras-springsecurity4 - ${springsecurity4.version} + thymeleaf-extras-springsecurity5 + ${springsecurity5.version} -- Gitee From 05574a7ab67ace05965a52694f24aec5141328de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8D=8E?= <672943942@qq.com> Date: Wed, 3 Jul 2019 11:03:20 +0800 Subject: [PATCH 52/52] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=9D=83=E9=99=90?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pom.xml b/pom.xml index c8cfd58..5b29ebf 100644 --- a/pom.xml +++ b/pom.xml @@ -19,9 +19,6 @@ - - UTF-8 UTF-8 1.8 -- Gitee