Ver código fonte

fix: SpringBoot3 + mybatis-flex + Spring-security

liaoyitao 2 meses atrás
pai
commit
3e3a605f91
46 arquivos alterados com 2962 adições e 0 exclusões
  1. 5 0
      .gitignore
  2. 259 0
      mvnw
  3. 149 0
      mvnw.cmd
  4. 147 0
      pom.xml
  5. 23 0
      src/main/java/com/lqkj/cmlcp/CmlcpServerApplication.java
  6. 136 0
      src/main/java/com/lqkj/cmlcp/config/PropertyDeploy.java
  7. 26 0
      src/main/java/com/lqkj/cmlcp/config/RedisConfig.java
  8. 35 0
      src/main/java/com/lqkj/cmlcp/config/SpringDocConfig.java
  9. 19 0
      src/main/java/com/lqkj/cmlcp/config/WebConfig.java
  10. 76 0
      src/main/java/com/lqkj/cmlcp/config/WebSecurityConfig.java
  11. 44 0
      src/main/java/com/lqkj/cmlcp/config/auth/LoginAuthenticationProvider.java
  12. 130 0
      src/main/java/com/lqkj/cmlcp/config/auth/OauthAuthorizationConfig.java
  13. 24 0
      src/main/java/com/lqkj/cmlcp/config/auth/OauthResourceConfig.java
  14. 28 0
      src/main/java/com/lqkj/cmlcp/exception/GlobalAsyncExceptionHandler.java
  15. 25 0
      src/main/java/com/lqkj/cmlcp/exception/GlobalExceptionHandler.java
  16. 54 0
      src/main/java/com/lqkj/cmlcp/filter/JwtAuthFilter.java
  17. 17 0
      src/main/java/com/lqkj/cmlcp/filter/RequestUrlLoggingFilter.java
  18. 112 0
      src/main/java/com/lqkj/cmlcp/message/MessageBaseBean.java
  19. 59 0
      src/main/java/com/lqkj/cmlcp/message/MessageBean.java
  20. 68 0
      src/main/java/com/lqkj/cmlcp/message/MessageListBean.java
  21. 110 0
      src/main/java/com/lqkj/cmlcp/message/Result.java
  22. 59 0
      src/main/java/com/lqkj/cmlcp/message/ResultCodeEnum.java
  23. 39 0
      src/main/java/com/lqkj/cmlcp/module/authority/domain/RoleInfo.java
  24. 112 0
      src/main/java/com/lqkj/cmlcp/module/authority/domain/UserInfo.java
  25. 13 0
      src/main/java/com/lqkj/cmlcp/module/authority/mapper/UserInfoMapper.java
  26. 16 0
      src/main/java/com/lqkj/cmlcp/module/authority/service/UserInfoService.java
  27. 35 0
      src/main/java/com/lqkj/cmlcp/module/authority/service/impl/DatabaseUserDetailService.java
  28. 149 0
      src/main/java/com/lqkj/cmlcp/module/authority/service/impl/UserInfoServiceImpl.java
  29. 32 0
      src/main/java/com/lqkj/cmlcp/module/base/controller/BaseController.java
  30. 9 0
      src/main/java/com/lqkj/cmlcp/module/base/service/BaseService.java
  31. 23 0
      src/main/java/com/lqkj/cmlcp/module/base/service/impl/BaseServiceImpl.java
  32. 97 0
      src/main/java/com/lqkj/cmlcp/module/jwt/controller/JwtController.java
  33. 80 0
      src/main/java/com/lqkj/cmlcp/module/jwt/service/JwtService.java
  34. 29 0
      src/main/java/com/lqkj/cmlcp/module/test/controller/TestController.java
  35. 33 0
      src/main/java/com/lqkj/cmlcp/module/test/domain/Captcha.java
  36. 9 0
      src/main/java/com/lqkj/cmlcp/module/test/mapper/CaptchaMapper.java
  37. 12 0
      src/main/java/com/lqkj/cmlcp/module/test/service/CaptchaService.java
  38. 44 0
      src/main/java/com/lqkj/cmlcp/module/test/service/impl/CaptchaServiceImpl.java
  39. 182 0
      src/main/java/com/lqkj/cmlcp/utils/FileUtils.java
  40. 124 0
      src/main/java/com/lqkj/cmlcp/utils/RSAUtils.java
  41. 78 0
      src/main/resources/application-install.yml
  42. 13 0
      src/main/resources/com/lqkj/cmlcp/module/authority/mapper/UserInfoMapper.xml
  43. 4 0
      src/main/resources/com/lqkj/cmlcp/module/test/mapper/CaptchaMapper.xml
  44. 164 0
      src/main/resources/db/migration/V1__INIT.sql
  45. 47 0
      src/main/resources/log4j2.xml
  46. 13 0
      src/test/java/com/lqkj/cmlcp/CmlcpServerApplicationTests.java

+ 5 - 0
.gitignore

@@ -31,3 +31,8 @@ build/
31 31
 
32 32
 ### VS Code ###
33 33
 .vscode/
34
+
35
+/log
36
+/logs
37
+/config
38
+/.mvn

+ 259 - 0
mvnw

@@ -0,0 +1,259 @@
1
+#!/bin/sh
2
+# ----------------------------------------------------------------------------
3
+# Licensed to the Apache Software Foundation (ASF) under one
4
+# or more contributor license agreements.  See the NOTICE file
5
+# distributed with this work for additional information
6
+# regarding copyright ownership.  The ASF licenses this file
7
+# to you under the Apache License, Version 2.0 (the
8
+# "License"); you may not use this file except in compliance
9
+# with the License.  You may obtain a copy of the License at
10
+#
11
+#    https://www.apache.org/licenses/LICENSE-2.0
12
+#
13
+# Unless required by applicable law or agreed to in writing,
14
+# software distributed under the License is distributed on an
15
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+# KIND, either express or implied.  See the License for the
17
+# specific language governing permissions and limitations
18
+# under the License.
19
+# ----------------------------------------------------------------------------
20
+
21
+# ----------------------------------------------------------------------------
22
+# Apache Maven Wrapper startup batch script, version 3.3.2
23
+#
24
+# Optional ENV vars
25
+# -----------------
26
+#   JAVA_HOME - location of a JDK home dir, required when download maven via java source
27
+#   MVNW_REPOURL - repo url base for downloading maven distribution
28
+#   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
29
+#   MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
30
+# ----------------------------------------------------------------------------
31
+
32
+set -euf
33
+[ "${MVNW_VERBOSE-}" != debug ] || set -x
34
+
35
+# OS specific support.
36
+native_path() { printf %s\\n "$1"; }
37
+case "$(uname)" in
38
+CYGWIN* | MINGW*)
39
+  [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
40
+  native_path() { cygpath --path --windows "$1"; }
41
+  ;;
42
+esac
43
+
44
+# set JAVACMD and JAVACCMD
45
+set_java_home() {
46
+  # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
47
+  if [ -n "${JAVA_HOME-}" ]; then
48
+    if [ -x "$JAVA_HOME/jre/sh/java" ]; then
49
+      # IBM's JDK on AIX uses strange locations for the executables
50
+      JAVACMD="$JAVA_HOME/jre/sh/java"
51
+      JAVACCMD="$JAVA_HOME/jre/sh/javac"
52
+    else
53
+      JAVACMD="$JAVA_HOME/bin/java"
54
+      JAVACCMD="$JAVA_HOME/bin/javac"
55
+
56
+      if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
57
+        echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
58
+        echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
59
+        return 1
60
+      fi
61
+    fi
62
+  else
63
+    JAVACMD="$(
64
+      'set' +e
65
+      'unset' -f command 2>/dev/null
66
+      'command' -v java
67
+    )" || :
68
+    JAVACCMD="$(
69
+      'set' +e
70
+      'unset' -f command 2>/dev/null
71
+      'command' -v javac
72
+    )" || :
73
+
74
+    if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
75
+      echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
76
+      return 1
77
+    fi
78
+  fi
79
+}
80
+
81
+# hash string like Java String::hashCode
82
+hash_string() {
83
+  str="${1:-}" h=0
84
+  while [ -n "$str" ]; do
85
+    char="${str%"${str#?}"}"
86
+    h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
87
+    str="${str#?}"
88
+  done
89
+  printf %x\\n $h
90
+}
91
+
92
+verbose() { :; }
93
+[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
94
+
95
+die() {
96
+  printf %s\\n "$1" >&2
97
+  exit 1
98
+}
99
+
100
+trim() {
101
+  # MWRAPPER-139:
102
+  #   Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
103
+  #   Needed for removing poorly interpreted newline sequences when running in more
104
+  #   exotic environments such as mingw bash on Windows.
105
+  printf "%s" "${1}" | tr -d '[:space:]'
106
+}
107
+
108
+# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
109
+while IFS="=" read -r key value; do
110
+  case "${key-}" in
111
+  distributionUrl) distributionUrl=$(trim "${value-}") ;;
112
+  distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
113
+  esac
114
+done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
115
+[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
116
+
117
+case "${distributionUrl##*/}" in
118
+maven-mvnd-*bin.*)
119
+  MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
120
+  case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
121
+  *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
122
+  :Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
123
+  :Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
124
+  :Linux*x86_64*) distributionPlatform=linux-amd64 ;;
125
+  *)
126
+    echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
127
+    distributionPlatform=linux-amd64
128
+    ;;
129
+  esac
130
+  distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
131
+  ;;
132
+maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
133
+*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
134
+esac
135
+
136
+# apply MVNW_REPOURL and calculate MAVEN_HOME
137
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
138
+[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
139
+distributionUrlName="${distributionUrl##*/}"
140
+distributionUrlNameMain="${distributionUrlName%.*}"
141
+distributionUrlNameMain="${distributionUrlNameMain%-bin}"
142
+MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
143
+MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
144
+
145
+exec_maven() {
146
+  unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
147
+  exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
148
+}
149
+
150
+if [ -d "$MAVEN_HOME" ]; then
151
+  verbose "found existing MAVEN_HOME at $MAVEN_HOME"
152
+  exec_maven "$@"
153
+fi
154
+
155
+case "${distributionUrl-}" in
156
+*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
157
+*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
158
+esac
159
+
160
+# prepare tmp dir
161
+if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
162
+  clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
163
+  trap clean HUP INT TERM EXIT
164
+else
165
+  die "cannot create temp dir"
166
+fi
167
+
168
+mkdir -p -- "${MAVEN_HOME%/*}"
169
+
170
+# Download and Install Apache Maven
171
+verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
172
+verbose "Downloading from: $distributionUrl"
173
+verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
174
+
175
+# select .zip or .tar.gz
176
+if ! command -v unzip >/dev/null; then
177
+  distributionUrl="${distributionUrl%.zip}.tar.gz"
178
+  distributionUrlName="${distributionUrl##*/}"
179
+fi
180
+
181
+# verbose opt
182
+__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
183
+[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
184
+
185
+# normalize http auth
186
+case "${MVNW_PASSWORD:+has-password}" in
187
+'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
188
+has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
189
+esac
190
+
191
+if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
192
+  verbose "Found wget ... using wget"
193
+  wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
194
+elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
195
+  verbose "Found curl ... using curl"
196
+  curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
197
+elif set_java_home; then
198
+  verbose "Falling back to use Java to download"
199
+  javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
200
+  targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
201
+  cat >"$javaSource" <<-END
202
+	public class Downloader extends java.net.Authenticator
203
+	{
204
+	  protected java.net.PasswordAuthentication getPasswordAuthentication()
205
+	  {
206
+	    return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
207
+	  }
208
+	  public static void main( String[] args ) throws Exception
209
+	  {
210
+	    setDefault( new Downloader() );
211
+	    java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
212
+	  }
213
+	}
214
+	END
215
+  # For Cygwin/MinGW, switch paths to Windows format before running javac and java
216
+  verbose " - Compiling Downloader.java ..."
217
+  "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
218
+  verbose " - Running Downloader.java ..."
219
+  "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
220
+fi
221
+
222
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
223
+if [ -n "${distributionSha256Sum-}" ]; then
224
+  distributionSha256Result=false
225
+  if [ "$MVN_CMD" = mvnd.sh ]; then
226
+    echo "Checksum validation is not supported for maven-mvnd." >&2
227
+    echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
228
+    exit 1
229
+  elif command -v sha256sum >/dev/null; then
230
+    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
231
+      distributionSha256Result=true
232
+    fi
233
+  elif command -v shasum >/dev/null; then
234
+    if echo "$distributionSha256Sum  $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
235
+      distributionSha256Result=true
236
+    fi
237
+  else
238
+    echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
239
+    echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
240
+    exit 1
241
+  fi
242
+  if [ $distributionSha256Result = false ]; then
243
+    echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
244
+    echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
245
+    exit 1
246
+  fi
247
+fi
248
+
249
+# unzip and move
250
+if command -v unzip >/dev/null; then
251
+  unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
252
+else
253
+  tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
254
+fi
255
+printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
256
+mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
257
+
258
+clean || :
259
+exec_maven "$@"

+ 149 - 0
mvnw.cmd

@@ -0,0 +1,149 @@
1
+<# : batch portion
2
+@REM ----------------------------------------------------------------------------
3
+@REM Licensed to the Apache Software Foundation (ASF) under one
4
+@REM or more contributor license agreements.  See the NOTICE file
5
+@REM distributed with this work for additional information
6
+@REM regarding copyright ownership.  The ASF licenses this file
7
+@REM to you under the Apache License, Version 2.0 (the
8
+@REM "License"); you may not use this file except in compliance
9
+@REM with the License.  You may obtain a copy of the License at
10
+@REM
11
+@REM    https://www.apache.org/licenses/LICENSE-2.0
12
+@REM
13
+@REM Unless required by applicable law or agreed to in writing,
14
+@REM software distributed under the License is distributed on an
15
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+@REM KIND, either express or implied.  See the License for the
17
+@REM specific language governing permissions and limitations
18
+@REM under the License.
19
+@REM ----------------------------------------------------------------------------
20
+
21
+@REM ----------------------------------------------------------------------------
22
+@REM Apache Maven Wrapper startup batch script, version 3.3.2
23
+@REM
24
+@REM Optional ENV vars
25
+@REM   MVNW_REPOURL - repo url base for downloading maven distribution
26
+@REM   MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
27
+@REM   MVNW_VERBOSE - true: enable verbose log; others: silence the output
28
+@REM ----------------------------------------------------------------------------
29
+
30
+@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
31
+@SET __MVNW_CMD__=
32
+@SET __MVNW_ERROR__=
33
+@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
34
+@SET PSModulePath=
35
+@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
36
+  IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
37
+)
38
+@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
39
+@SET __MVNW_PSMODULEP_SAVE=
40
+@SET __MVNW_ARG0_NAME__=
41
+@SET MVNW_USERNAME=
42
+@SET MVNW_PASSWORD=
43
+@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
44
+@echo Cannot start maven from wrapper >&2 && exit /b 1
45
+@GOTO :EOF
46
+: end batch / begin powershell #>
47
+
48
+$ErrorActionPreference = "Stop"
49
+if ($env:MVNW_VERBOSE -eq "true") {
50
+  $VerbosePreference = "Continue"
51
+}
52
+
53
+# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
54
+$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
55
+if (!$distributionUrl) {
56
+  Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
57
+}
58
+
59
+switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
60
+  "maven-mvnd-*" {
61
+    $USE_MVND = $true
62
+    $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
63
+    $MVN_CMD = "mvnd.cmd"
64
+    break
65
+  }
66
+  default {
67
+    $USE_MVND = $false
68
+    $MVN_CMD = $script -replace '^mvnw','mvn'
69
+    break
70
+  }
71
+}
72
+
73
+# apply MVNW_REPOURL and calculate MAVEN_HOME
74
+# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
75
+if ($env:MVNW_REPOURL) {
76
+  $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
77
+  $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
78
+}
79
+$distributionUrlName = $distributionUrl -replace '^.*/',''
80
+$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
81
+$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
82
+if ($env:MAVEN_USER_HOME) {
83
+  $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
84
+}
85
+$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
86
+$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
87
+
88
+if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
89
+  Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
90
+  Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
91
+  exit $?
92
+}
93
+
94
+if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
95
+  Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
96
+}
97
+
98
+# prepare tmp dir
99
+$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
100
+$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
101
+$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
102
+trap {
103
+  if ($TMP_DOWNLOAD_DIR.Exists) {
104
+    try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
105
+    catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
106
+  }
107
+}
108
+
109
+New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
110
+
111
+# Download and Install Apache Maven
112
+Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
113
+Write-Verbose "Downloading from: $distributionUrl"
114
+Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
115
+
116
+$webclient = New-Object System.Net.WebClient
117
+if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
118
+  $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
119
+}
120
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
121
+$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
122
+
123
+# If specified, validate the SHA-256 sum of the Maven distribution zip file
124
+$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
125
+if ($distributionSha256Sum) {
126
+  if ($USE_MVND) {
127
+    Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
128
+  }
129
+  Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
130
+  if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
131
+    Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
132
+  }
133
+}
134
+
135
+# unzip and move
136
+Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
137
+Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
138
+try {
139
+  Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
140
+} catch {
141
+  if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
142
+    Write-Error "fail to move MAVEN_HOME"
143
+  }
144
+} finally {
145
+  try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
146
+  catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
147
+}
148
+
149
+Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"

+ 147 - 0
pom.xml

@@ -0,0 +1,147 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4
+    <modelVersion>4.0.0</modelVersion>
5
+    <parent>
6
+        <groupId>org.springframework.boot</groupId>
7
+        <artifactId>spring-boot-starter-parent</artifactId>
8
+        <version>3.2.8</version>
9
+        <relativePath/> <!-- lookup parent from repository -->
10
+    </parent>
11
+    <groupId>com.lqkj</groupId>
12
+    <artifactId>CMLCP-SERVER</artifactId>
13
+    <version>0.0.1-SNAPSHOT</version>
14
+    <name>CMLCP-SERVER</name>
15
+    <description>CMLCP-SERVER</description>
16
+    <url/>
17
+    <licenses>
18
+        <license/>
19
+    </licenses>
20
+    <developers>
21
+        <developer/>
22
+    </developers>
23
+    <scm>
24
+        <connection/>
25
+        <developerConnection/>
26
+        <tag/>
27
+        <url/>
28
+    </scm>
29
+    <properties>
30
+        <java.version>17</java.version>
31
+    </properties>
32
+    <dependencies>
33
+        <dependency>
34
+            <groupId>org.springframework.boot</groupId>
35
+            <artifactId>spring-boot-starter-web</artifactId>
36
+        </dependency>
37
+        <dependency>
38
+            <groupId>org.springframework.boot</groupId>
39
+            <artifactId>spring-boot-starter-jdbc</artifactId>
40
+        </dependency>
41
+        <dependency>
42
+            <groupId>org.postgresql</groupId>
43
+            <artifactId>postgresql</artifactId>
44
+            <scope>runtime</scope>
45
+        </dependency>
46
+        <dependency>
47
+            <groupId>org.projectlombok</groupId>
48
+            <artifactId>lombok</artifactId>
49
+            <optional>true</optional>
50
+        </dependency>
51
+        <dependency>
52
+            <groupId>org.springframework.boot</groupId>
53
+            <artifactId>spring-boot-starter-test</artifactId>
54
+            <scope>test</scope>
55
+        </dependency>
56
+        <dependency>
57
+            <groupId>org.apache.commons</groupId>
58
+            <artifactId>commons-lang3</artifactId>
59
+            <version>3.14.0</version>
60
+        </dependency>
61
+        <dependency>
62
+            <groupId>org.flywaydb</groupId>
63
+            <artifactId>flyway-core</artifactId>
64
+        </dependency>
65
+
66
+        <dependency>
67
+            <groupId>org.springdoc</groupId>
68
+            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
69
+            <version>2.1.0</version>
70
+        </dependency>
71
+        <dependency>
72
+            <groupId>org.springdoc</groupId>
73
+            <artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
74
+            <version>2.1.0</version>
75
+        </dependency>
76
+        <dependency>
77
+            <groupId>jakarta.servlet</groupId>
78
+            <artifactId>jakarta.servlet-api</artifactId>
79
+            <scope>provided</scope>
80
+        </dependency>
81
+        <dependency>
82
+            <groupId>com.squareup.okio</groupId>
83
+            <artifactId>okio</artifactId>
84
+            <version>3.6.0</version>
85
+        </dependency>
86
+        <!-- mybatis-flex -->
87
+        <dependency>
88
+            <groupId>com.mybatis-flex</groupId>
89
+            <artifactId>mybatis-flex-spring-boot3-starter</artifactId>
90
+            <version>1.9.5</version>
91
+        </dependency>
92
+        <dependency>
93
+            <groupId>com.zaxxer</groupId>
94
+            <artifactId>HikariCP</artifactId>
95
+        </dependency>
96
+<!--        redis-->
97
+        <dependency>
98
+            <groupId>org.springframework.boot</groupId>
99
+            <artifactId>spring-boot-starter-data-redis</artifactId>
100
+        </dependency>
101
+        <dependency>
102
+            <groupId>commons-io</groupId>
103
+            <artifactId>commons-io</artifactId>
104
+            <version>2.15.1</version>
105
+        </dependency>
106
+        <dependency>
107
+            <groupId>org.springframework.boot</groupId>
108
+            <artifactId>spring-boot-starter-security</artifactId>
109
+        </dependency>
110
+        <!-- JWT 相关 -->
111
+        <dependency>
112
+            <groupId>io.jsonwebtoken</groupId>
113
+            <artifactId>jjwt-api</artifactId>
114
+            <version>0.11.5</version>
115
+        </dependency>
116
+        <dependency>
117
+            <groupId>io.jsonwebtoken</groupId>
118
+            <artifactId>jjwt-impl</artifactId>
119
+            <version>0.11.5</version>
120
+            <scope>runtime</scope>
121
+        </dependency>
122
+        <dependency>
123
+            <groupId>io.jsonwebtoken</groupId>
124
+            <artifactId>jjwt-jackson</artifactId>
125
+            <version>0.11.5</version>
126
+            <scope>runtime</scope>
127
+        </dependency>
128
+    </dependencies>
129
+
130
+    <build>
131
+        <plugins>
132
+            <plugin>
133
+                <groupId>org.springframework.boot</groupId>
134
+                <artifactId>spring-boot-maven-plugin</artifactId>
135
+                <configuration>
136
+                    <excludes>
137
+                        <exclude>
138
+                            <groupId>org.projectlombok</groupId>
139
+                            <artifactId>lombok</artifactId>
140
+                        </exclude>
141
+                    </excludes>
142
+                </configuration>
143
+            </plugin>
144
+        </plugins>
145
+    </build>
146
+
147
+</project>

+ 23 - 0
src/main/java/com/lqkj/cmlcp/CmlcpServerApplication.java

@@ -0,0 +1,23 @@
1
+package com.lqkj.cmlcp;
2
+
3
+import com.lqkj.cmlcp.config.PropertyDeploy;
4
+import org.springframework.boot.Banner;
5
+import org.springframework.boot.SpringApplication;
6
+import org.springframework.boot.autoconfigure.SpringBootApplication;
7
+
8
+@SpringBootApplication
9
+public class CmlcpServerApplication {
10
+
11
+    public static void main(String[] args) {
12
+        // 生成配置文件
13
+        PropertyDeploy deploy=new PropertyDeploy();
14
+        deploy.deploy();
15
+
16
+        // 禁止actuator端点
17
+        SpringApplication app = new SpringApplication(CmlcpServerApplication.class);
18
+        app.setBannerMode(Banner.Mode.OFF);
19
+        app.setAddCommandLineProperties(false);
20
+        app.run(args);
21
+    }
22
+
23
+}

+ 136 - 0
src/main/java/com/lqkj/cmlcp/config/PropertyDeploy.java

@@ -0,0 +1,136 @@
1
+package com.lqkj.cmlcp.config;
2
+
3
+import okio.BufferedSink;
4
+import okio.Okio;
5
+import org.apache.commons.lang3.StringUtils;
6
+import org.slf4j.Logger;
7
+import org.slf4j.LoggerFactory;
8
+import org.springframework.core.io.ClassPathResource;
9
+import org.yaml.snakeyaml.Yaml;
10
+
11
+import java.io.File;
12
+import java.io.IOException;
13
+import java.io.InputStream;
14
+import java.nio.file.Files;
15
+import java.nio.file.Paths;
16
+import java.util.LinkedHashMap;
17
+import java.util.Scanner;
18
+
19
+/**
20
+ * 环境文件部署
21
+ */
22
+public class PropertyDeploy {
23
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
24
+    public static final String PropertyDirPath = "./config";
25
+    public static final String PropertyFilePath = PropertyDirPath + "/application.yml";
26
+
27
+    /**
28
+     * 查询文件是否存在
29
+     *
30
+     * @return
31
+     */
32
+    private boolean isPropertyFileExist() {
33
+        return Files.exists(Paths.get(PropertyFilePath));
34
+    }
35
+
36
+    /**
37
+     * 数据库链接询问
38
+     */
39
+    private void inputDataBaseConfig() {
40
+        Scanner scanner = new Scanner(System.in);
41
+
42
+        System.out.println("请输入数据库IP:");
43
+        String ip = scanner.nextLine();
44
+
45
+        System.out.println("请输入数据库端口:");
46
+        String port = scanner.nextLine();
47
+
48
+        System.out.println("请输入数据库名称");
49
+        String dbName = scanner.nextLine();
50
+
51
+        System.out.println("请输入数据库用户名:");
52
+        String userName = scanner.nextLine();
53
+
54
+        System.out.println("请输入数据库密码");
55
+        String passWord = scanner.nextLine();
56
+
57
+        System.out.println("指定server绑定的地址");
58
+        String address = scanner.nextLine();
59
+
60
+        createConfigureFile(ip, port, dbName, userName, passWord, address);
61
+    }
62
+
63
+    /**
64
+     * 创建配置文件
65
+     */
66
+    public void createConfigureFile(String ip, String port, String dbName, String userName, String passWord, String address) {
67
+        if (StringUtils.isEmpty(ip)) {
68
+            ip = "127.0.0.1";
69
+        }
70
+        if (StringUtils.isEmpty(port)) {
71
+            port = "5432";
72
+        }
73
+        File applicationFile = new File(PropertyFilePath);
74
+
75
+        ClassPathResource resource = new ClassPathResource("application-install.yml");
76
+
77
+        Yaml yaml = new Yaml();
78
+
79
+        BufferedSink sink = null;
80
+
81
+        InputStream inputStream = null;
82
+
83
+        try {
84
+            Files.createDirectories(Paths.get(PropertyDirPath));
85
+
86
+            Files.createFile(Paths.get(PropertyFilePath));
87
+
88
+            inputStream = resource.getInputStream();
89
+
90
+            LinkedHashMap<String, LinkedHashMap> application = yaml.load(inputStream);
91
+
92
+            LinkedHashMap<String, Object> dateSource = (LinkedHashMap<String, Object>) application.get("spring").get("datasource");
93
+            LinkedHashMap<String, Object> hikari = (LinkedHashMap<String, Object>) dateSource.get("hikari");
94
+            dateSource.put("url", "jdbc:postgresql://" + ip + ":" + port + "/" + dbName);
95
+            hikari.put("username", userName);
96
+            hikari.put("password", passWord);
97
+
98
+            LinkedHashMap<String, Object> serverAddress = (LinkedHashMap<String, Object>) application.get("server");
99
+            serverAddress.put("address", address);
100
+
101
+            sink = Okio.buffer(Okio.sink(applicationFile));
102
+
103
+            sink.write(yaml.dump(application).getBytes());
104
+
105
+            sink.flush();
106
+        } catch (IOException e) {
107
+            e.printStackTrace();
108
+        } finally {
109
+            try {
110
+                if (sink != null) {
111
+                    sink.close();
112
+                }
113
+                if (inputStream != null) {
114
+                    inputStream.close();
115
+                }
116
+            } catch (Exception e) {
117
+                e.printStackTrace();
118
+            }
119
+        }
120
+    }
121
+
122
+
123
+    /**
124
+     * 部署文件
125
+     */
126
+    public void deploy() {
127
+        try {
128
+            if (!isPropertyFileExist()) {
129
+                inputDataBaseConfig();
130
+            }
131
+        } catch (Exception e) {
132
+            logger.error(e.getMessage(), e);
133
+        }
134
+
135
+    }
136
+}

+ 26 - 0
src/main/java/com/lqkj/cmlcp/config/RedisConfig.java

@@ -0,0 +1,26 @@
1
+package com.lqkj.cmlcp.config;
2
+
3
+import org.springframework.context.annotation.Bean;
4
+   import org.springframework.context.annotation.Configuration;
5
+   import org.springframework.data.redis.connection.RedisConnectionFactory;
6
+   import org.springframework.data.redis.core.RedisTemplate;
7
+   import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
8
+   import org.springframework.data.redis.serializer.StringRedisSerializer;
9
+
10
+   @Configuration
11
+   public class RedisConfig {
12
+
13
+       @Bean
14
+       public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
15
+           RedisTemplate<String, Object> template = new RedisTemplate<>();
16
+           template.setConnectionFactory(factory);
17
+
18
+           Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
19
+           // 使用Jackson2JsonRedisSerializer 替换默认的 JdkSerializationRedisSerializer
20
+           template.setValueSerializer(serializer);
21
+           template.setKeySerializer(new StringRedisSerializer());
22
+           template.afterPropertiesSet();
23
+
24
+           return template;
25
+       }
26
+   }

+ 35 - 0
src/main/java/com/lqkj/cmlcp/config/SpringDocConfig.java

@@ -0,0 +1,35 @@
1
+package com.lqkj.cmlcp.config;
2
+
3
+import io.swagger.v3.oas.models.OpenAPI;
4
+import io.swagger.v3.oas.models.info.Contact;
5
+import io.swagger.v3.oas.models.info.Info;
6
+import io.swagger.v3.oas.models.info.License;
7
+import org.springframework.context.annotation.Bean;
8
+import org.springframework.context.annotation.Configuration;
9
+
10
+@Configuration
11
+public class SpringDocConfig {
12
+    @Bean
13
+    public OpenAPI openAPI() {
14
+        return new OpenAPI()
15
+                // 配置接口文档基本信息
16
+                .info(this.getApiInfo())
17
+                ;
18
+    }
19
+    private Info getApiInfo() {
20
+        return new Info()
21
+                 // 配置文档标题
22
+                .title("SpringBoot3集成Swagger3")
23
+                // 配置文档描述
24
+                .description("SpringBoot3集成Swagger3示例文档")
25
+                // 配置作者信息
26
+                .contact(new Contact().name("lqkj").url("").email(""))
27
+                // 配置License许可证信息
28
+                .license(new License().name("Apache 2.0").url("https://www.xiezhrspace.cn"))
29
+                // 概述信息
30
+                .summary("SpringBoot3集成Swagger3示例文档aaa")
31
+                .termsOfService("")
32
+                // 配置版本号
33
+                .version("2.0");
34
+    }
35
+}

+ 19 - 0
src/main/java/com/lqkj/cmlcp/config/WebConfig.java

@@ -0,0 +1,19 @@
1
+package com.lqkj.cmlcp.config;
2
+
3
+import com.lqkj.cmlcp.filter.RequestUrlLoggingFilter;
4
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
5
+import org.springframework.context.annotation.Bean;
6
+import org.springframework.context.annotation.Configuration;
7
+ 
8
+@Configuration
9
+public class WebConfig {
10
+ 
11
+    @Bean
12
+    public FilterRegistrationBean<RequestUrlLoggingFilter> loggingFilter() {
13
+        FilterRegistrationBean<RequestUrlLoggingFilter> registrationBean = new FilterRegistrationBean<>();
14
+        registrationBean.setFilter(new RequestUrlLoggingFilter());
15
+        registrationBean.addUrlPatterns("/*");
16
+        registrationBean.setOrder(1);
17
+        return registrationBean;
18
+    }
19
+}

+ 76 - 0
src/main/java/com/lqkj/cmlcp/config/WebSecurityConfig.java

@@ -0,0 +1,76 @@
1
+package com.lqkj.cmlcp.config;
2
+
3
+
4
+import com.lqkj.cmlcp.config.auth.LoginAuthenticationProvider;
5
+import com.lqkj.cmlcp.filter.JwtAuthFilter;
6
+import com.lqkj.cmlcp.module.authority.service.impl.DatabaseUserDetailService;
7
+import org.springframework.context.annotation.Bean;
8
+import org.springframework.context.annotation.Configuration;
9
+import org.springframework.security.authentication.AuthenticationManager;
10
+import org.springframework.security.authentication.AuthenticationProvider;
11
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
12
+import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
13
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
14
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
15
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
16
+import org.springframework.security.config.http.SessionCreationPolicy;
17
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
18
+import org.springframework.security.crypto.password.PasswordEncoder;
19
+import org.springframework.security.web.SecurityFilterChain;
20
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
21
+
22
+
23
+@Configuration
24
+@EnableWebSecurity
25
+public class WebSecurityConfig {
26
+    private final JwtAuthFilter authFilter;
27
+    private final DatabaseUserDetailService userDetailService;
28
+
29
+    public WebSecurityConfig(JwtAuthFilter authFilter, DatabaseUserDetailService userDetailService) {
30
+        this.authFilter = authFilter;
31
+        this.userDetailService = userDetailService;
32
+    }
33
+
34
+    @Bean
35
+    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
36
+        return http
37
+                .csrf(AbstractHttpConfigurer::disable)
38
+                .authorizeHttpRequests((requests) -> requests
39
+                        .requestMatchers(
40
+                                "/jwt/token",
41
+                                "/jwt/getAdminToken",
42
+                                "/encrypt/**",
43
+                                "/swagger-ui.html",
44
+                                "/swagger-ui/**",
45
+                                "/v3/api-docs/**",
46
+                                "/geom/all",
47
+                                "/test/**",
48
+                                "/upload/**")
49
+                        .permitAll()
50
+                        .requestMatchers("/**")
51
+                        .authenticated())
52
+                .sessionManagement((session) -> session
53
+                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
54
+                .authenticationProvider(authenticationProvider())
55
+                .addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
56
+                .build();
57
+    }
58
+
59
+
60
+    @Bean
61
+    public PasswordEncoder passwordEncoder() {
62
+        return new BCryptPasswordEncoder();
63
+    }
64
+    @Bean
65
+    public AuthenticationProvider authenticationProvider(){
66
+        DaoAuthenticationProvider authenticationProvider=new LoginAuthenticationProvider(userDetailService, passwordEncoder());
67
+        authenticationProvider.setUserDetailsService(userDetailService);
68
+        authenticationProvider.setPasswordEncoder(passwordEncoder());
69
+        return authenticationProvider;
70
+    }
71
+    @Bean
72
+    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
73
+        return config.getAuthenticationManager();
74
+    }
75
+
76
+}

+ 44 - 0
src/main/java/com/lqkj/cmlcp/config/auth/LoginAuthenticationProvider.java

@@ -0,0 +1,44 @@
1
+package com.lqkj.cmlcp.config.auth;
2
+
3
+import com.lqkj.cmlcp.module.authority.service.impl.DatabaseUserDetailService;
4
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
5
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
6
+import org.springframework.security.core.AuthenticationException;
7
+import org.springframework.security.core.userdetails.UserDetails;
8
+import org.springframework.security.crypto.password.PasswordEncoder;
9
+
10
+/**
11
+ * oauth2验证
12
+ */
13
+public class LoginAuthenticationProvider extends DaoAuthenticationProvider {
14
+    private final PasswordEncoder passwordEncoder;
15
+    public LoginAuthenticationProvider(DatabaseUserDetailService userDetailsService, PasswordEncoder passwordEncoder) {
16
+        setUserDetailsService(userDetailsService);
17
+        this.passwordEncoder = passwordEncoder;
18
+    }
19
+
20
+    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
21
+//        //在接收到符合权限的帐号密码后进行再处理
22
+//        if (authentication.getCredentials() == null) {
23
+//            this.logger.debug("Authentication failed: no credentials provided");
24
+//            throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
25
+//        } else {
26
+//            String pw;
27
+//            //如果位数为172则先解密
28
+//            if (authentication.getCredentials().toString().length() != 172) {
29
+//                this.logger.debug("Authentication failed: password length error");
30
+//                throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
31
+//            }
32
+//            pw = RSAUtils.decryptBase64(authentication.getCredentials().toString());
33
+//            DatabaseUserDetailService userDetailsService = (DatabaseUserDetailService) getUserDetailsService();
34
+//            if (userDetailsService.isLocked(userDetails.getUsername())) {//账号是否被冻结
35
+//                throw new LockedException("账号已被冻结,请稍后重试");
36
+//            }
37
+//            if (!passwordEncoder.matches(pw, userDetails.getPassword())) {
38
+//                throw new LockedException(userDetailsService.lockedUser(userDetails.getUsername()));
39
+//            }else {
40
+//                userDetailsService.unlockedUser(userDetails.getUsername());
41
+//            }
42
+//        }
43
+    }
44
+}

+ 130 - 0
src/main/java/com/lqkj/cmlcp/config/auth/OauthAuthorizationConfig.java

@@ -0,0 +1,130 @@
1
+package com.lqkj.cmlcp.config.auth;//package com.lqkj.link.config.auth;
2
+//
3
+//
4
+//import com.nimbusds.jose.jwk.JWKSet;
5
+//import com.nimbusds.jose.jwk.RSAKey;
6
+//import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
7
+//import com.nimbusds.jose.jwk.source.JWKSource;
8
+//import org.springframework.context.annotation.Bean;
9
+//import org.springframework.context.annotation.Configuration;
10
+//import org.springframework.core.annotation.Order;
11
+//import org.springframework.security.config.Customizer;
12
+//import org.springframework.security.config.annotation.web.builders.HttpSecurity;
13
+//import org.springframework.security.core.userdetails.User;
14
+//import org.springframework.security.core.userdetails.UserDetails;
15
+//import org.springframework.security.core.userdetails.UserDetailsService;
16
+//import org.springframework.security.oauth2.core.AuthorizationGrantType;
17
+//import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
18
+//import org.springframework.security.oauth2.core.oidc.OidcScopes;
19
+//import org.springframework.security.oauth2.jwt.JwtDecoder;
20
+//import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
21
+//import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
22
+//import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
23
+//import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
24
+//import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
25
+//import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
26
+//import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
27
+//import org.springframework.security.provisioning.InMemoryUserDetailsManager;
28
+//import org.springframework.security.web.SecurityFilterChain;
29
+//import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
30
+//
31
+//import java.security.KeyPair;
32
+//import java.security.KeyPairGenerator;
33
+//import java.security.interfaces.RSAPrivateKey;
34
+//import java.security.interfaces.RSAPublicKey;
35
+//import java.util.UUID;
36
+//
37
+//@Configuration
38
+//public class OauthAuthorizationConfig {
39
+//    @Bean
40
+//    @Order(1)
41
+//    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
42
+//        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
43
+//        http
44
+//                .getConfigurer(OAuth2AuthorizationServerConfigurer.class)
45
+//                .oidc(Customizer.withDefaults());
46
+//
47
+//        http
48
+//                .oauth2ResourceServer(Customizer.withDefaults());
49
+//        return http.build();
50
+//    }
51
+//
52
+//    @Bean
53
+//    @Order(2)
54
+//    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
55
+//        http
56
+//                .authorizeHttpRequests((authorize) ->
57
+//                        authorize
58
+//                                .requestMatchers(
59
+//                                    new AntPathRequestMatcher("/oauth2/**"),
60
+//                                    new AntPathRequestMatcher("/**/*.html"))
61
+//                                .permitAll()
62
+//                                .anyRequest()
63
+//                                .authenticated());
64
+//
65
+//        return http.build();
66
+//    }
67
+//
68
+//    @Bean
69
+//    public UserDetailsService userDetailsService() {
70
+//        UserDetails userDetails = User.withDefaultPasswordEncoder()
71
+//                .username("test")
72
+//                .password("test")
73
+//                .roles("USER")
74
+//                .build();
75
+//
76
+//        return new InMemoryUserDetailsManager(userDetails);
77
+//    }
78
+//
79
+//    @Bean
80
+//    public RegisteredClientRepository registeredClientRepository() {
81
+//        RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
82
+//                .clientId("link_server")
83
+//                .clientSecret("{noop}demo-client-secret")
84
+//                .authorizationGrantType(AuthorizationGrantType.PASSWORD)
85
+//                .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
86
+//                .scope("all")
87
+//                // 登录成功后对scope进行确认授权
88
+//                .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
89
+//                .build();
90
+//
91
+//        return new InMemoryRegisteredClientRepository(registeredClient);
92
+//    }
93
+//
94
+//    @Bean
95
+//    public JWKSource jwkSource() {
96
+//        KeyPair keyPair = generateRsaKey();
97
+//        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
98
+//        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
99
+//        RSAKey rsaKey = new RSAKey
100
+//                .Builder(publicKey)
101
+//                .privateKey(privateKey)
102
+//                .keyID(UUID.randomUUID().toString())
103
+//                .build();
104
+//        JWKSet jwkSet = new JWKSet(rsaKey);
105
+//        return new ImmutableJWKSet<>(jwkSet);
106
+//    }
107
+//
108
+//    private static KeyPair generateRsaKey() {
109
+//        KeyPair keyPair;
110
+//        try {
111
+//            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
112
+//            keyPairGenerator.initialize(2048);
113
+//            keyPair = keyPairGenerator.generateKeyPair();
114
+//        }
115
+//        catch (Exception ex) {
116
+//            throw new IllegalStateException(ex);
117
+//        }
118
+//        return keyPair;
119
+//    }
120
+//
121
+//    @Bean
122
+//    public JwtDecoder jwtDecoder(JWKSource jwkSource) {
123
+//        return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
124
+//    }
125
+//
126
+//    @Bean
127
+//    public AuthorizationServerSettings authorizationServerSettings() {
128
+//        return AuthorizationServerSettings.builder().build();
129
+//    }
130
+//}

+ 24 - 0
src/main/java/com/lqkj/cmlcp/config/auth/OauthResourceConfig.java

@@ -0,0 +1,24 @@
1
+package com.lqkj.cmlcp.config.auth;//package com.lqkj.link.config.auth;
2
+//
3
+//import org.springframework.context.annotation.Bean;
4
+//import org.springframework.context.annotation.Configuration;
5
+//import org.springframework.security.config.annotation.web.builders.HttpSecurity;
6
+//import org.springframework.security.oauth2.jwt.JwtDecoders;
7
+//import org.springframework.security.web.SecurityFilterChain;
8
+//
9
+//@Configuration
10
+//public class OauthResourceConfig {
11
+//
12
+//    @Bean
13
+//    public SecurityFilterChain resourceServerSecurityFilterChain(HttpSecurity http) throws Exception {
14
+//        return http
15
+//                .authorizeHttpRequests((authorize) -> authorize
16
+//                            .anyRequest()
17
+//                            .authenticated()
18
+//                )
19
+//                .oauth2ResourceServer(oauth2 -> oauth2
20
+//                        .jwt(jwt -> jwt.decoder(JwtDecoders.fromIssuerLocation())))
21
+//                .jwt();
22
+//
23
+//    }
24
+//}

+ 28 - 0
src/main/java/com/lqkj/cmlcp/exception/GlobalAsyncExceptionHandler.java

@@ -0,0 +1,28 @@
1
+package com.lqkj.cmlcp.exception;
2
+
3
+import com.lqkj.cmlcp.message.Result;
4
+import org.slf4j.Logger;
5
+import org.slf4j.LoggerFactory;
6
+import org.springframework.web.context.request.NativeWebRequest;
7
+import org.springframework.web.context.request.async.CallableProcessingInterceptor;
8
+
9
+import java.util.concurrent.Callable;
10
+
11
+/**
12
+ * 异步全局异常处理
13
+ */
14
+public class GlobalAsyncExceptionHandler implements CallableProcessingInterceptor {
15
+
16
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
17
+
18
+    @Override
19
+    public <T> Object handleTimeout(NativeWebRequest request, Callable<T> task) throws Exception {
20
+        return Result.fail("请求超时");
21
+    }
22
+
23
+    @Override
24
+    public <T> Object handleError(NativeWebRequest request, Callable<T> task, Throwable t) throws Exception {
25
+        logger.error("收到异常", t);
26
+        return Result.fail(t.toString());
27
+    }
28
+}

+ 25 - 0
src/main/java/com/lqkj/cmlcp/exception/GlobalExceptionHandler.java

@@ -0,0 +1,25 @@
1
+package com.lqkj.cmlcp.exception;
2
+
3
+import com.lqkj.cmlcp.message.Result;
4
+import org.slf4j.Logger;
5
+import org.slf4j.LoggerFactory;
6
+import org.springframework.web.bind.annotation.ControllerAdvice;
7
+import org.springframework.web.bind.annotation.ExceptionHandler;
8
+import org.springframework.web.bind.annotation.ResponseBody;
9
+
10
+/**
11
+ * 全局异常处理
12
+ */
13
+@ControllerAdvice
14
+public class GlobalExceptionHandler {
15
+
16
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
17
+
18
+    @ExceptionHandler(Exception.class)
19
+    @ResponseBody
20
+    public Result<String> resolveException(Exception e) {
21
+        logger.error("收到异常", e);
22
+
23
+        return Result.fail(e.toString());
24
+    }
25
+}

+ 54 - 0
src/main/java/com/lqkj/cmlcp/filter/JwtAuthFilter.java

@@ -0,0 +1,54 @@
1
+package com.lqkj.cmlcp.filter;
2
+
3
+
4
+import com.lqkj.cmlcp.module.authority.service.impl.DatabaseUserDetailService;
5
+import com.lqkj.cmlcp.module.jwt.service.JwtService;
6
+import jakarta.servlet.FilterChain;
7
+import jakarta.servlet.ServletException;
8
+import jakarta.servlet.http.HttpServletRequest;
9
+import jakarta.servlet.http.HttpServletResponse;
10
+import org.jetbrains.annotations.NotNull;
11
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
12
+import org.springframework.security.core.context.SecurityContextHolder;
13
+import org.springframework.security.core.userdetails.UserDetails;
14
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
15
+import org.springframework.stereotype.Component;
16
+import org.springframework.web.filter.OncePerRequestFilter;
17
+
18
+import java.io.IOException;
19
+
20
+@Component
21
+public class JwtAuthFilter extends OncePerRequestFilter {
22
+
23
+    private final JwtService jwtService;
24
+    private final DatabaseUserDetailService userDetailService;
25
+
26
+    public JwtAuthFilter(JwtService jwtService, DatabaseUserDetailService userDetailService) {
27
+        this.jwtService = jwtService;
28
+        this.userDetailService = userDetailService;
29
+    }
30
+
31
+    @Override
32
+    protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException {
33
+        String url = request.getRequestURI();
34
+        logger.info(url);
35
+
36
+        String authHeader = request.getHeader("Authorization");
37
+        String token = null;
38
+        String username = null;
39
+        if (authHeader != null && authHeader.startsWith("Bearer ")) {
40
+            token = authHeader.substring(7);
41
+            username = jwtService.extractUsername(token);
42
+        }
43
+
44
+        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
45
+            UserDetails userDetails = userDetailService.loadUserByUsername(username);
46
+            if (jwtService.validateToken(token, userDetails)) {
47
+                UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
48
+                authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
49
+                SecurityContextHolder.getContext().setAuthentication(authToken);
50
+            }
51
+        }
52
+        filterChain.doFilter(request, response);
53
+    }
54
+}

+ 17 - 0
src/main/java/com/lqkj/cmlcp/filter/RequestUrlLoggingFilter.java

@@ -0,0 +1,17 @@
1
+package com.lqkj.cmlcp.filter;
2
+
3
+
4
+import jakarta.servlet.*;
5
+import jakarta.servlet.http.HttpServletRequest;
6
+
7
+import java.io.IOException;
8
+ 
9
+public class RequestUrlLoggingFilter implements Filter {
10
+
11
+    @Override
12
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
13
+        HttpServletRequest request = (HttpServletRequest) servletRequest;
14
+        System.out.println("Request URL: " + request.getRequestURL());
15
+        filterChain.doFilter(servletRequest, servletResponse);
16
+    }
17
+}

+ 112 - 0
src/main/java/com/lqkj/cmlcp/message/MessageBaseBean.java

@@ -0,0 +1,112 @@
1
+package com.lqkj.cmlcp.message;
2
+
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
5
+import java.io.Serializable;
6
+import java.util.HashMap;
7
+import java.util.Map;
8
+
9
+/**
10
+ * 基础消息bean
11
+ * Created by free on 2017/7/27 0027.
12
+ */
13
+@Schema(description = "基础返回对象")
14
+public class MessageBaseBean implements Serializable {
15
+
16
+    public static final String NEXT_PAGE="nextPage";
17
+    /**
18
+     * 总页数
19
+     */
20
+    public static final String ALL_PAGE="allPage";
21
+    /**
22
+     * 当前页数
23
+     */
24
+    public static final String TOTAL_PAGE="totalPage";
25
+
26
+    /**
27
+     * 消息状态
28
+     */
29
+    @Schema(description = "消息状态")
30
+    private boolean status;
31
+
32
+    /**
33
+     * 消息时间戳
34
+     */
35
+    @Schema(description = "消息时间戳")
36
+    private long time;
37
+
38
+    /**
39
+     * 消息状态码
40
+     */
41
+    @Schema(description = "消息状态码")
42
+    private int code;
43
+
44
+    /**
45
+     * 提示信息
46
+     */
47
+    @Schema(description = "提示信息")
48
+    private String message;
49
+
50
+    /**
51
+     * 附加消息
52
+     */
53
+    @Schema(description = "附加消息")
54
+    private Map<String,Object> properties=new HashMap<String, Object>();
55
+
56
+    public boolean isStatus() {
57
+        return status;
58
+    }
59
+
60
+    public long getTime() {
61
+        return time;
62
+    }
63
+
64
+    public int getCode() {
65
+        return code;
66
+    }
67
+
68
+    public String getMessage() {
69
+        return message;
70
+    }
71
+
72
+    public Map<String, Object> getProperties() {
73
+        return properties;
74
+    }
75
+
76
+    public void setStatus(boolean status) {
77
+        this.status = status;
78
+    }
79
+
80
+    public void setTime(long time) {
81
+        this.time = time;
82
+    }
83
+
84
+    public void setCode(int code) {
85
+        this.code = code;
86
+    }
87
+
88
+    public void setMessage(String message) {
89
+        this.message = message;
90
+    }
91
+
92
+    public void setProperties(Map<String, Object> properties) {
93
+        this.properties = properties;
94
+    }
95
+
96
+    /**
97
+     * 增加一个附属信息
98
+     * @param key 附属信息的名称
99
+     * @param value 附属信息
100
+     */
101
+    public void addPropertie(String key,Object value){
102
+        this.properties.put(key,value);
103
+    }
104
+
105
+    /**
106
+     * 移除一个附属信息
107
+     * @param key 附属信息的名称
108
+     */
109
+    public void removePropertie(String key){
110
+        this.properties.remove(key);
111
+    }
112
+}

+ 59 - 0
src/main/java/com/lqkj/cmlcp/message/MessageBean.java

@@ -0,0 +1,59 @@
1
+package com.lqkj.cmlcp.message;
2
+
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
5
+import java.io.Serializable;
6
+
7
+/**
8
+ * 服务器单个信息bean
9
+ * Created by free on 2017/7/27 0027.
10
+ */
11
+@Schema(description = "单个实体返回对象")
12
+public class MessageBean<T> extends MessageBaseBean implements Serializable {
13
+
14
+    public MessageBean() {
15
+        this.setTime(System.currentTimeMillis());
16
+    }
17
+
18
+    public MessageBean(T data) {
19
+        this.data = data;
20
+        this.setTime(System.currentTimeMillis());
21
+    }
22
+
23
+    /**
24
+     * 被包含的消息实体
25
+     */
26
+    @Schema(description = "包含的数据")
27
+    private T data;
28
+
29
+    public T getData() {
30
+        return data;
31
+    }
32
+
33
+    public void setData(T data) {
34
+        this.data = data;
35
+    }
36
+
37
+    public static <T> MessageBean<T> ok() {
38
+        MessageBean<T> messageBean = new MessageBean<>();
39
+        messageBean.setStatus(true);
40
+        return messageBean;
41
+    }
42
+
43
+    public static <T> MessageBean<T> ok(T data, String message) {
44
+        MessageBean<T> messageBean = new MessageBean<>();
45
+        messageBean.setStatus(true);
46
+        messageBean.setData(data);
47
+        messageBean.setCode(200);
48
+        messageBean.setMessage(message);
49
+        return messageBean;
50
+    }
51
+
52
+    public static <T> MessageBean<T> error(String message) {
53
+        MessageBean<T> messageBean = new MessageBean<>();
54
+        messageBean.setStatus(false);
55
+        messageBean.setCode(-1);
56
+        messageBean.setMessage(message);
57
+        return messageBean;
58
+    }
59
+}

+ 68 - 0
src/main/java/com/lqkj/cmlcp/message/MessageListBean.java

@@ -0,0 +1,68 @@
1
+package com.lqkj.cmlcp.message;
2
+
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
5
+import java.io.Serializable;
6
+import java.util.ArrayList;
7
+import java.util.List;
8
+
9
+/**
10
+ * 服务器多个信息bean
11
+ * Created by free on 2017/7/27 0027.
12
+ */
13
+@Schema(description = "多个实体返回对象")
14
+public class MessageListBean<T> extends MessageBaseBean implements Serializable {
15
+
16
+    public MessageListBean() {
17
+        this.setTime(System.currentTimeMillis());
18
+    }
19
+
20
+    public MessageListBean(List<T> data) {
21
+        this.data = data;
22
+
23
+        this.setTime(System.currentTimeMillis());
24
+    }
25
+
26
+    /**
27
+     * 被包含的多个消息实体
28
+     */
29
+    @Schema(description = "包含的对象")
30
+    private List<T> data;
31
+
32
+    public List<T> getData() {
33
+        return data;
34
+    }
35
+
36
+    public void setData(List<T> data) {
37
+        this.data = data;
38
+    }
39
+
40
+    /**
41
+     * 增加一个数据
42
+     *
43
+     * @param data 数据
44
+     */
45
+    public void addData(T data) {
46
+        if (this.data == null) {
47
+            this.data = new ArrayList<T>(5);
48
+        }
49
+        this.data.add(data);
50
+    }
51
+
52
+    public static <T> MessageListBean<T> ok(List<T> data, String message) {
53
+        MessageListBean<T> messageListBean = new MessageListBean<>();
54
+        messageListBean.setStatus(true);
55
+        messageListBean.setData(data);
56
+        messageListBean.setCode(200);
57
+        messageListBean.setMessage(message);
58
+        return messageListBean;
59
+    }
60
+
61
+    public static <T> MessageListBean<T> error(String message) {
62
+        MessageListBean<T> messageListBean = new MessageListBean<>();
63
+        messageListBean.setStatus(false);
64
+        messageListBean.setCode(-1);
65
+        messageListBean.setMessage(message);
66
+        return messageListBean;
67
+    }
68
+}

+ 110 - 0
src/main/java/com/lqkj/cmlcp/message/Result.java

@@ -0,0 +1,110 @@
1
+package com.lqkj.cmlcp.message;
2
+import lombok.Data;
3
+
4
+/**
5
+ * 全局统一返回结果类
6
+ */
7
+@Data
8
+//@ApiModel(value = "全局统一返回结果")
9
+public class Result<T> {
10
+
11
+    //@ApiModelProperty(value = "返回码")
12
+    private Integer code;
13
+
14
+    //@ApiModelProperty(value = "返回消息")
15
+    private String message;
16
+
17
+    //@ApiModelProperty(value = "返回数据")
18
+    private T data;
19
+
20
+    private Boolean success = true;    // 表示当前操作是成功还是失败 true:成功 false:失败
21
+
22
+    public Result(){}
23
+
24
+    protected static <T> Result<T> build(T data) {
25
+            Result<T> result = new Result<T>();
26
+            if (data != null)
27
+            result.setData(data);
28
+        return result;
29
+    }
30
+
31
+    public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum, Boolean isSuccess) {
32
+        Result<T> result = build(body);
33
+        result.setCode(resultCodeEnum.getCode());
34
+        result.setMessage(resultCodeEnum.getMessage());
35
+        result.setSuccess(isSuccess);
36
+        return result;
37
+    }
38
+
39
+    public static <T> Result<T> build(Integer code, String message, Boolean isSuccess) {
40
+        Result<T> result = build(null);
41
+        result.setCode(code);
42
+        result.setMessage(message);
43
+        result.setSuccess(isSuccess);
44
+        return result;
45
+    }
46
+
47
+    private static <T> Result<T> build(T data, String msg, boolean isSuccess) {
48
+        Result<T> result = build(data);
49
+        result.setCode(200);
50
+        result.setMessage(msg);
51
+        result.setSuccess(isSuccess);
52
+        return result;
53
+    }
54
+
55
+    public static<T> Result<T> ok(){
56
+        return Result.ok(null);
57
+    }
58
+
59
+    public static <T> Result<T> me(Integer code, String message, Boolean isSuccess){
60
+        return build(code, message, isSuccess);
61
+    }
62
+
63
+    /**
64
+     * 操作成功
65
+     * @param data
66
+     * @param <T>
67
+     * @return
68
+     */
69
+    public static<T> Result<T> ok(T data){
70
+        return build(data, ResultCodeEnum.SUCCESS, true);
71
+    }
72
+
73
+    public static<T> Result<T> ok(T data, String msg){
74
+        return build(data, msg, true);
75
+    }
76
+
77
+
78
+
79
+    public static<T> Result<T> fail(){
80
+        return Result.fail(null);
81
+    }
82
+
83
+    /**
84
+     * 操作失败
85
+     * @param data
86
+     * @param <T>
87
+     * @return
88
+     */
89
+    public static<T> Result<T> fail(T data){
90
+        Result<T> result = build(data);
91
+        return build(data, ResultCodeEnum.FAIL, false);
92
+    }
93
+
94
+    public Result<T> message(String msg){
95
+        this.setMessage(msg);
96
+        return this;
97
+    }
98
+
99
+    public Result<T> code(Integer code){
100
+        this.setCode(code);
101
+        return this;
102
+    }
103
+
104
+    public boolean isOk() {
105
+        if(this.getCode().intValue() == ResultCodeEnum.SUCCESS.getCode().intValue()) {
106
+            return true;
107
+        }
108
+        return false;
109
+    }
110
+}

+ 59 - 0
src/main/java/com/lqkj/cmlcp/message/ResultCodeEnum.java

@@ -0,0 +1,59 @@
1
+package com.lqkj.cmlcp.message;
2
+
3
+import lombok.Getter;
4
+
5
+/**
6
+ * 统一返回结果状态信息类
7
+ */
8
+@Getter
9
+public enum ResultCodeEnum {
10
+
11
+    SUCCESS(200,"成功"),
12
+    FAIL(201, "网络异常!请联系管理员!"),
13
+    PARAM_ERROR( 202, "参数不正确"),
14
+    SERVICE_ERROR(203, "服务异常"),
15
+    DATA_ERROR(204, "数据异常"),
16
+    DATA_UPDATE_ERROR(205, "数据版本异常"),
17
+
18
+    LOGIN_AUTH(208, "未登陆"),
19
+    PERMISSION(209, "没有权限"),
20
+
21
+    CODE_ERROR(210, "验证码错误"),
22
+//    LOGIN_MOBLE_ERROR(211, "账号不正确"),
23
+    LOGIN_DISABLED_ERROR(212, "改用户已被禁用"),
24
+    REGISTER_MOBLE_ERROR(213, "手机号已被使用"),
25
+    LOGIN_AURH(214, "需要登录"),
26
+    LOGIN_ACL(215, "没有权限"),
27
+
28
+    URL_ENCODE_ERROR( 216, "URL编码失败"),
29
+    ILLEGAL_CALLBACK_REQUEST_ERROR( 217, "非法回调请求"),
30
+    FETCH_ACCESSTOKEN_FAILD( 218, "获取accessToken失败"),
31
+    FETCH_USERINFO_ERROR( 219, "获取用户信息失败"),
32
+    //LOGIN_ERROR( 23005, "登录失败"),
33
+
34
+    PAY_RUN(220, "支付中"),
35
+    CANCEL_ORDER_FAIL(225, "取消订单失败"),
36
+    CANCEL_ORDER_NO(225, "不能取消预约"),
37
+
38
+    HOSCODE_EXIST(230, "医院编号已经存在"),
39
+    NUMBER_NO(240, "可预约号不足"),
40
+    TIME_NO(250, "当前时间不可以预约"),
41
+
42
+    SIGN_ERROR(300, "签名错误"),
43
+    HOSPITAL_OPEN(310, "医院未开通,暂时不能访问"),
44
+    HOSPITAL_LOCK(320, "医院被锁定,暂时不能访问"),
45
+
46
+    RESPONSE_CODE_400(400,"参数错误!"),
47
+    RESPONSE_CODE_400001(400001,"两次密码不一致,请检查后重新提交!"),
48
+    RESPONSE_CODE_400002(400002,"店铺已存在,请检查后重新提交!"),
49
+    RESPONSE_CODE_500(500,"网络异常!请稍后重试!");
50
+    ;
51
+
52
+    private Integer code;
53
+    private String message;
54
+
55
+    private ResultCodeEnum(Integer code, String message) {
56
+        this.code = code;
57
+        this.message = message;
58
+    }
59
+}

+ 39 - 0
src/main/java/com/lqkj/cmlcp/module/authority/domain/RoleInfo.java

@@ -0,0 +1,39 @@
1
+package com.lqkj.cmlcp.module.authority.domain;
2
+
3
+import com.fasterxml.jackson.annotation.JsonFormat;
4
+import com.mybatisflex.annotation.Column;
5
+import com.mybatisflex.annotation.Id;
6
+import com.mybatisflex.annotation.KeyType;
7
+import io.swagger.v3.oas.annotations.media.Schema;
8
+import lombok.*;
9
+import lombok.experimental.Accessors;
10
+
11
+import java.util.Date;
12
+import java.util.List;
13
+
14
+
15
+@Accessors(chain = true)
16
+@Data(staticConstructor = "create")
17
+@NoArgsConstructor
18
+@AllArgsConstructor
19
+public class RoleInfo {
20
+
21
+    @Id(keyType = KeyType.Auto)
22
+    @Schema(description = "角色ID")
23
+    private Integer roleId;
24
+
25
+    @Schema(description = "角色名称")
26
+    private String roleName;
27
+
28
+    @Schema(description = "")
29
+    private String enName;
30
+
31
+    @JsonFormat(pattern = "YYYY-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
32
+    private Date updateTime;
33
+
34
+    @Column(ignore = true)
35
+    private List<Integer> authorityList;
36
+
37
+    @Column(ignore = true)
38
+    private String auths;
39
+}

+ 112 - 0
src/main/java/com/lqkj/cmlcp/module/authority/domain/UserInfo.java

@@ -0,0 +1,112 @@
1
+package com.lqkj.cmlcp.module.authority.domain;
2
+
3
+import com.fasterxml.jackson.annotation.JsonFormat;
4
+import com.fasterxml.jackson.annotation.JsonProperty;
5
+import com.mybatisflex.annotation.Column;
6
+import com.mybatisflex.annotation.Id;
7
+import com.mybatisflex.annotation.KeyType;
8
+import com.mybatisflex.core.activerecord.Model;
9
+import io.swagger.v3.oas.annotations.media.Schema;
10
+import lombok.AllArgsConstructor;
11
+import lombok.Data;
12
+import lombok.NoArgsConstructor;
13
+import lombok.experimental.Accessors;
14
+import org.springframework.security.core.GrantedAuthority;
15
+import org.springframework.security.core.userdetails.UserDetails;
16
+
17
+import java.util.Collection;
18
+import java.util.Date;
19
+import java.util.List;
20
+
21
+@Accessors(chain = true)
22
+@Data(staticConstructor = "create")
23
+@NoArgsConstructor
24
+@AllArgsConstructor
25
+public class UserInfo extends Model<UserInfo> implements UserDetails {
26
+
27
+	@Id(keyType = KeyType.Auto)
28
+	@Schema(description = "用户ID")
29
+	private Integer Id;
30
+
31
+	@Schema(description = "登录账号")
32
+	private String userCode;
33
+
34
+	@Schema(description = "显示名称")
35
+	private String displayName;
36
+
37
+	@Schema(description = "密码")
38
+	@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
39
+	private String password;
40
+
41
+	@Schema(description = "授权码")
42
+	private String authorizationCode;
43
+
44
+	@Schema(description = "头像图片地址")
45
+	private String headImg;
46
+
47
+	@Schema(description = "文件存储路径")
48
+	private String fileSavePath;
49
+
50
+	@Schema(description = "是否有审核权限")
51
+	private Boolean hasAuth;
52
+
53
+	@Schema(description = "是否锁定")
54
+	private Boolean locking;
55
+
56
+	@Schema(description = "登录错误次数")
57
+	private Integer loginErrorCount;
58
+
59
+	@Schema(description = "锁定时间")
60
+	@JsonFormat(pattern = "YYYY-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
61
+	private Date lockTime;
62
+
63
+	@JsonFormat(pattern = "YYYY-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
64
+	@Schema(description = "更新时间")
65
+	private Date updateTime;
66
+
67
+	@Schema(description = "是否能进入后台")
68
+	private Boolean hasManage;
69
+
70
+	@Schema(description = "角色列表")
71
+	private List<RoleInfo> roleInfoList;
72
+
73
+	@Schema(description = "角色ID数组")
74
+	private List<Integer> roleIds;
75
+
76
+	@Column(ignore = true)
77
+	private String roleNames;
78
+
79
+
80
+	/**
81
+	 * @Description 得到用户的角色列表
82
+	 */
83
+	@Column(ignore = true)
84
+    private Collection<? extends GrantedAuthority> authorities;
85
+	/**
86
+	 * 判断用户是否为过期
87
+	 */
88
+	@Column(ignore = true)
89
+    private boolean accountNonExpired = true;
90
+	/**
91
+	 * 判断用户是否为锁定
92
+	 */
93
+	@Column(ignore = true)
94
+    private boolean accountNonLocked = true;
95
+	/**
96
+	 * 判断密码是否未过期
97
+	 */
98
+	@Column(ignore = true)
99
+    private boolean credentialsNonExpired = true;
100
+	/**
101
+	 * 判断账户是否激活
102
+	 */
103
+	@Column(ignore = true)
104
+    private boolean enabled = true;
105
+
106
+
107
+	@Override
108
+	public String getUsername() {
109
+		return this.userCode;
110
+	}
111
+
112
+}

+ 13 - 0
src/main/java/com/lqkj/cmlcp/module/authority/mapper/UserInfoMapper.java

@@ -0,0 +1,13 @@
1
+package com.lqkj.cmlcp.module.authority.mapper;
2
+
3
+import com.lqkj.cmlcp.module.authority.domain.UserInfo;
4
+import com.mybatisflex.core.BaseMapper;
5
+import org.apache.ibatis.annotations.Mapper;
6
+
7
+@Mapper
8
+public interface UserInfoMapper extends BaseMapper<UserInfo> {
9
+    void initUserIdSeq();
10
+
11
+    void initSuperAdminRole();
12
+
13
+}

+ 16 - 0
src/main/java/com/lqkj/cmlcp/module/authority/service/UserInfoService.java

@@ -0,0 +1,16 @@
1
+package com.lqkj.cmlcp.module.authority.service;
2
+
3
+import com.lqkj.cmlcp.module.authority.domain.UserInfo;
4
+import com.mybatisflex.core.service.IService;
5
+
6
+public interface UserInfoService extends IService<UserInfo> {
7
+    UserInfo findByUserCode(String userCode);
8
+
9
+    boolean isLocked(String userCode);
10
+
11
+    String lockedUser(String userCode);
12
+
13
+    void unlockedUser(String userCode);
14
+
15
+    UserInfo selectByUserName(String username);
16
+}

+ 35 - 0
src/main/java/com/lqkj/cmlcp/module/authority/service/impl/DatabaseUserDetailService.java

@@ -0,0 +1,35 @@
1
+package com.lqkj.cmlcp.module.authority.service.impl;
2
+
3
+import com.lqkj.cmlcp.module.authority.domain.UserInfo;
4
+import com.lqkj.cmlcp.module.authority.service.UserInfoService;
5
+import org.springframework.beans.factory.annotation.Autowired;
6
+import org.springframework.security.core.userdetails.UserDetails;
7
+import org.springframework.security.core.userdetails.UserDetailsService;
8
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
9
+import org.springframework.stereotype.Service;
10
+
11
+@Service
12
+public class DatabaseUserDetailService implements UserDetailsService {
13
+
14
+    @Autowired
15
+    private UserInfoService userInfoService;
16
+
17
+
18
+    @Override
19
+    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
20
+//        if (username.length() != 172) throw new UsernameNotFoundException("用户名错误!");
21
+//        try {
22
+//            username = RSAUtils.decryptBase64(username);
23
+//        } catch (Exception e) {
24
+//            throw new UsernameNotFoundException("用户名错误!");
25
+//        }
26
+        UserInfo userInfo = userInfoService.selectByUserName(username);
27
+        if (userInfo == null) {
28
+            throw new UsernameNotFoundException("用户名不存在!");
29
+        }
30
+        return userInfo;
31
+    }
32
+
33
+
34
+
35
+}

+ 149 - 0
src/main/java/com/lqkj/cmlcp/module/authority/service/impl/UserInfoServiceImpl.java

@@ -0,0 +1,149 @@
1
+package com.lqkj.cmlcp.module.authority.service.impl;
2
+
3
+import com.lqkj.cmlcp.module.authority.domain.UserInfo;
4
+import com.lqkj.cmlcp.module.authority.mapper.UserInfoMapper;
5
+import com.lqkj.cmlcp.module.authority.service.UserInfoService;
6
+import com.mybatisflex.core.query.QueryWrapper;
7
+import com.mybatisflex.core.update.UpdateChain;
8
+import com.mybatisflex.spring.service.impl.ServiceImpl;
9
+import jakarta.annotation.PostConstruct;
10
+import org.springframework.beans.factory.annotation.Autowired;
11
+import org.springframework.stereotype.Component;
12
+import org.springframework.transaction.annotation.Transactional;
13
+
14
+import java.util.Date;
15
+import java.util.Objects;
16
+
17
+@Component
18
+public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService{
19
+
20
+    @Autowired
21
+    private UserInfoMapper userInfoMapper;
22
+
23
+
24
+    @Override
25
+    public UserInfo findByUserCode(String userCode) {
26
+        return userInfoMapper.selectOneByQuery(new QueryWrapper().eq("user_code",userCode));
27
+    }
28
+
29
+        /**
30
+     * 账号是否锁定
31
+     * @param userCode
32
+     * @return
33
+     */
34
+    @Transactional
35
+    public boolean isLocked(String userCode) {
36
+        UserInfo userInfo = findByUserCode(userCode);
37
+        if (userInfo == null){
38
+            return false;
39
+        }else {
40
+            if (userInfo.getLocking()) {
41
+                if (new Date().getTime() - userInfo.getLockTime().getTime() > 1000 * 60 * 60){
42
+                    UpdateChain.of(UserInfo.class)
43
+                            .set(UserInfo::getLocking, false)
44
+                            .set(UserInfo::getLockTime, null)
45
+                            .set(UserInfo::getLoginErrorCount, 0)
46
+                            .where(UserInfo::getId).eq(userInfo.getId())
47
+                            .update();
48
+                    return false;
49
+                }else{
50
+                    return true;
51
+                }
52
+            }else{
53
+                return false;
54
+            }
55
+        }
56
+    }
57
+
58
+    /**
59
+     * 更新登录错误次数
60
+     * @param userCode
61
+     * @return
62
+     */
63
+    @Transactional
64
+    public String lockedUser(String userCode){
65
+        UserInfo userInfo = findByUserCode(userCode);
66
+        if (userInfo == null){
67
+            return "用户名或密码错误";
68
+        }else{
69
+            int loginErrorCount = userInfo.getLoginErrorCount() == null ? 0 : userInfo.getLoginErrorCount();
70
+            loginErrorCount += 1;
71
+            userInfo.setLoginErrorCount(loginErrorCount);
72
+            if (loginErrorCount == 4){
73
+                userInfo.setLocking(true);
74
+                userInfo.setLockTime(new Date());
75
+                userInfoMapper.update(userInfo);
76
+                return "账号已被冻结,请稍后重试";
77
+            }
78
+            userInfoMapper.update(userInfo);
79
+            return "账号、密码或授权码输入错误," + (4 - loginErrorCount) +"次错误后,账号将会冻结1小时";
80
+        }
81
+    }
82
+
83
+    /**
84
+     * 解锁用户
85
+     * @param userCode
86
+     */
87
+    @Transactional
88
+    public void unlockedUser(String userCode){
89
+        UserInfo userInfo = findByUserCode(userCode);
90
+        UpdateChain.of(UserInfo.class)
91
+                .set(UserInfo::getLocking, false)
92
+                .set(UserInfo::getLockTime, null)
93
+                .set(UserInfo::getLoginErrorCount, 0)
94
+                .where(UserInfo::getId).eq(userInfo.getId())
95
+                .update();
96
+    }
97
+
98
+    @Override
99
+    public UserInfo selectByUserName(String username) {
100
+        return userInfoMapper.selectOneByQuery(new QueryWrapper().eq("user_name",username));
101
+    }
102
+
103
+
104
+    @PostConstruct
105
+    @Transactional
106
+    public void initSuperUser() {
107
+        if (Objects.isNull(userInfoMapper.selectOneById(1))){
108
+            initSuperAdmin();
109
+            initUserIdSeq();
110
+            initSuperAdminRole();
111
+        }
112
+    }
113
+
114
+    private void initSuperAdmin() {
115
+        UserInfo userInfo = new UserInfo()
116
+                .setId(1)
117
+                .setUserCode("admin")
118
+                .setDisplayName("超级管理员")
119
+                .setPassword("$2a$10$OIBK8kKBDY07OS4CcVdx9e2GdxKH4T2lqWfDXgubjwZbxbis5.vSu")
120
+                .setAuthorizationCode("87449007")
121
+                .setHeadImg("")
122
+                .setFileSavePath("")
123
+                .setHasManage(true)
124
+                .setHasAuth(true)
125
+                .setLocking(false)
126
+                .setLockTime(null)
127
+                .setLoginErrorCount(0)
128
+                .setUpdateTime(new Date())
129
+                .setEnabled(true);
130
+        userInfoMapper.insert(userInfo);
131
+
132
+    }
133
+
134
+    private void initUserIdSeq() {
135
+        userInfoMapper.initUserIdSeq();
136
+    }
137
+
138
+    private void initSuperAdminRole() {
139
+
140
+        userInfoMapper.initSuperAdminRole();
141
+    }
142
+
143
+    private void test(){
144
+
145
+
146
+
147
+    }
148
+
149
+}

+ 32 - 0
src/main/java/com/lqkj/cmlcp/module/base/controller/BaseController.java

@@ -0,0 +1,32 @@
1
+package com.lqkj.cmlcp.module.base.controller;
2
+
3
+
4
+import com.lqkj.cmlcp.message.Result;
5
+import com.lqkj.cmlcp.module.base.service.BaseService;
6
+import io.swagger.v3.oas.annotations.Operation;
7
+import io.swagger.v3.oas.annotations.Parameter;
8
+import org.springframework.beans.factory.annotation.Autowired;
9
+import org.springframework.web.bind.annotation.PostMapping;
10
+import org.springframework.web.bind.annotation.RequestMapping;
11
+import org.springframework.web.bind.annotation.RestController;
12
+import org.springframework.web.multipart.MultipartFile;
13
+
14
+@RestController
15
+@RequestMapping("/base")
16
+public class BaseController {
17
+
18
+    @Autowired
19
+    private BaseService baseService;
20
+
21
+    @Operation(
22
+            summary = "5.1.3.33 空间信息json文件上传接口",
23
+            description = "5.1.3.33 空间信息json文件上传接口",
24
+            parameters = {
25
+                    @Parameter(name = "file", description = "空间信息json文件上传接口", required = true)
26
+            }
27
+    )
28
+    @PostMapping({"/addJsonFile"})
29
+    public Result<String> addJsonFile(MultipartFile file) {
30
+        return Result.ok(baseService.uploadJsonFile(file, "base/json/"));
31
+    }
32
+}

+ 9 - 0
src/main/java/com/lqkj/cmlcp/module/base/service/BaseService.java

@@ -0,0 +1,9 @@
1
+package com.lqkj.cmlcp.module.base.service;
2
+
3
+import org.springframework.web.multipart.MultipartFile;
4
+
5
+public interface BaseService {
6
+
7
+
8
+    String uploadJsonFile(MultipartFile file, String s);
9
+}

+ 23 - 0
src/main/java/com/lqkj/cmlcp/module/base/service/impl/BaseServiceImpl.java

@@ -0,0 +1,23 @@
1
+package com.lqkj.cmlcp.module.base.service.impl;
2
+
3
+import com.lqkj.cmlcp.message.Result;
4
+import com.lqkj.cmlcp.module.base.service.BaseService;
5
+import com.lqkj.cmlcp.utils.FileUtils;
6
+import org.springframework.stereotype.Service;
7
+import org.springframework.web.multipart.MultipartFile;
8
+
9
+import java.util.UUID;
10
+
11
+@Service
12
+public class BaseServiceImpl implements BaseService {
13
+    @Override
14
+    public String uploadJsonFile(MultipartFile file, String path) {
15
+        String fileName = file.getOriginalFilename();
16
+        String suffix = fileName == null ? "" : fileName.substring(fileName.lastIndexOf(".") + 1);
17
+        if (!suffix.equals("json")) throw new RuntimeException("上传文件类型必须是json格式的json文件");
18
+        String newFileName = UUID.randomUUID() + "." + suffix;
19
+        String filePath = "./upload/" + path;
20
+        FileUtils.saveFile(file, filePath, newFileName);
21
+        return filePath.substring(1) + newFileName;
22
+    }
23
+}

+ 97 - 0
src/main/java/com/lqkj/cmlcp/module/jwt/controller/JwtController.java

@@ -0,0 +1,97 @@
1
+package com.lqkj.cmlcp.module.jwt.controller;
2
+
3
+import com.lqkj.cmlcp.message.MessageBean;
4
+import com.lqkj.cmlcp.message.Result;
5
+import com.lqkj.cmlcp.module.authority.domain.LoginBody;
6
+import com.lqkj.cmlcp.module.authority.domain.UserInfo;
7
+import com.lqkj.cmlcp.module.authority.service.UserInfoService;
8
+import com.lqkj.cmlcp.module.jwt.service.JwtService;
9
+import io.swagger.v3.oas.annotations.Operation;
10
+import io.swagger.v3.oas.annotations.media.Content;
11
+import io.swagger.v3.oas.annotations.media.Schema;
12
+import io.swagger.v3.oas.annotations.tags.Tag;
13
+import jakarta.servlet.http.HttpServletRequest;
14
+import org.springframework.beans.factory.annotation.Autowired;
15
+import org.springframework.security.crypto.password.PasswordEncoder;
16
+import org.springframework.web.bind.annotation.PostMapping;
17
+import org.springframework.web.bind.annotation.RequestBody;
18
+import org.springframework.web.bind.annotation.RequestMapping;
19
+import org.springframework.web.bind.annotation.RestController;
20
+
21
+@RestController
22
+@RequestMapping("/jwt")
23
+@Tag(name = "授权服务", description = "授权服务")
24
+public class JwtController {
25
+
26
+    @Autowired
27
+    private  UserInfoService userInfoService;
28
+    private final JwtService jwtService;
29
+    private final PasswordEncoder passwordEncoder;
30
+
31
+    public JwtController(JwtService jwtService, PasswordEncoder passwordEncoder) {
32
+        this.jwtService = jwtService;
33
+        this.passwordEncoder = passwordEncoder;
34
+    }
35
+
36
+    @Operation(
37
+            summary = "5.1.1.2 登录接口",
38
+            description = "5.1.1.2 登录接口",
39
+            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
40
+                    description = "登录信息对象",
41
+                    required = true,
42
+                    content = @Content(
43
+                            mediaType = "application/json",
44
+                            schema = @Schema(implementation = LoginBody.class)
45
+                    )
46
+            ))
47
+    @PostMapping("/token")
48
+    public Result<String> getToken(@RequestBody LoginBody loginBody){
49
+        String userCode = loginBody.getUsername();
50
+        String password = loginBody.getPassword();
51
+        String authCode = loginBody.getAuthCode();
52
+//        if (userCode.length() != 172 || password.length() != 172 || authCode.length() != 172) {
53
+//            return Result.fail("用户名或密码或授权码错误!");
54
+//        }
55
+//        userCode = RSAUtils.decryptBase64(userCode);
56
+//        password = RSAUtils.decryptBase64(password);
57
+//        authCode = RSAUtils.decryptBase64(authCode);
58
+
59
+        UserInfo userInfo = userInfoService.findByUserCode(userCode);
60
+        if (userInfo == null) {
61
+            return Result.fail("账号不存在!");
62
+        }
63
+        if (userInfoService.isLocked(userInfo.getUserCode())) {//账号是否被冻结
64
+            return Result.fail("账号已被冻结,请稍后重试!");
65
+        }
66
+        if (!passwordEncoder.matches(password, userInfo.getPassword())) {
67
+            return Result.fail(userInfoService.lockedUser(userInfo.getUserCode()));
68
+        }
69
+        if (!authCode.equals(userInfo.getAuthorizationCode())) {
70
+            return Result.fail("授权码错误!");
71
+        }
72
+        userInfoService.unlockedUser(userInfo.getUserCode());
73
+
74
+        return Result.ok(jwtService.generateToken(userCode));
75
+    }
76
+
77
+    @Operation(
78
+            summary = "5.1.1.4 刷新token接口",
79
+            description = "5.1.1.4 刷新token接口"
80
+    )
81
+    @PostMapping("/refreshToken")
82
+    public MessageBean<String> refreshToken(HttpServletRequest request) {
83
+        String authHeader = request.getHeader("Authorization");
84
+        String username = jwtService.decryptUsernameWithHeader(authHeader);
85
+        return MessageBean.ok(jwtService.generateToken(username), "刷新token");
86
+
87
+    }
88
+
89
+    @Operation(
90
+            summary = "直接获取ADMIN-TOKEN",
91
+            description = "直接获取ADMIN-TOKEN"
92
+    )
93
+    @PostMapping("/getAdminToken")
94
+    public Result<String> getAdminToken() {
95
+        return Result.ok(jwtService.generateToken("meta-link"), "获取ADMIN-TOKEN");
96
+    }
97
+}

+ 80 - 0
src/main/java/com/lqkj/cmlcp/module/jwt/service/JwtService.java

@@ -0,0 +1,80 @@
1
+package com.lqkj.cmlcp.module.jwt.service;
2
+
3
+import com.lqkj.cmlcp.utils.RSAUtils;
4
+import io.jsonwebtoken.Claims;
5
+import io.jsonwebtoken.Jwts;
6
+import io.jsonwebtoken.SignatureAlgorithm;
7
+import io.jsonwebtoken.io.Decoders;
8
+import io.jsonwebtoken.security.Keys;
9
+import org.springframework.security.core.userdetails.UserDetails;
10
+import org.springframework.stereotype.Component;
11
+
12
+import java.security.Key;
13
+import java.util.Date;
14
+import java.util.HashMap;
15
+import java.util.Map;
16
+import java.util.function.Function;
17
+
18
+@Component
19
+public class JwtService {
20
+
21
+
22
+    public static final String SECRET = "zdvilXBILaMtQVtcJQ19ovIAo6GE1fEreTVYFXU1TZXg42Cc6AacW9fC1LV0u5Pc";
23
+
24
+
25
+    public String extractUsername(String token) {
26
+        return extractClaim(token, Claims::getSubject);
27
+    }
28
+
29
+    public String decryptUsernameWithHeader(String header) {
30
+        String token = header.substring(7);
31
+        return RSAUtils.decryptBase64(extractUsername(token));
32
+    }
33
+
34
+    public Date extractExpiration(String token) {
35
+        return extractClaim(token, Claims::getExpiration);
36
+    }
37
+
38
+    public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
39
+        final Claims claims = extractAllClaims(token);
40
+        return claimsResolver.apply(claims);
41
+    }
42
+
43
+    private Claims extractAllClaims(String token) {
44
+        return Jwts
45
+                .parserBuilder()
46
+                .setSigningKey(getSignKey())
47
+                .build()
48
+                .parseClaimsJws(token)
49
+                .getBody();
50
+    }
51
+
52
+    private Boolean isTokenExpired(String token) {
53
+        return extractExpiration(token).before(new Date());
54
+    }
55
+
56
+    public Boolean validateToken(String token, UserDetails userDetails) {
57
+        final String username = extractUsername(token);
58
+        return (RSAUtils.decryptBase64(username).equals(userDetails.getUsername()) && !isTokenExpired(token));
59
+    }
60
+
61
+
62
+    public String generateToken(String userName){
63
+        Map<String,Object> claims=new HashMap<>();
64
+        return createToken(claims,userName);
65
+    }
66
+
67
+    private String createToken(Map<String, Object> claims, String userName) {
68
+        return Jwts.builder()
69
+                .setClaims(claims)
70
+                .setSubject(RSAUtils.encryptBase64(userName))
71
+                .setIssuedAt(new Date(System.currentTimeMillis()))
72
+                .setExpiration(new Date(System.currentTimeMillis()+1000*60*30))
73
+                .signWith(getSignKey(), SignatureAlgorithm.HS256).compact();
74
+    }
75
+
76
+    private Key getSignKey() {
77
+        byte[] keyBytes= Decoders.BASE64.decode(SECRET);
78
+        return Keys.hmacShaKeyFor(keyBytes);
79
+    }
80
+}

+ 29 - 0
src/main/java/com/lqkj/cmlcp/module/test/controller/TestController.java

@@ -0,0 +1,29 @@
1
+package com.lqkj.cmlcp.module.test.controller;
2
+
3
+import com.lqkj.cmlcp.message.Result;
4
+import com.lqkj.cmlcp.module.test.service.CaptchaService;
5
+import org.springframework.beans.factory.annotation.Autowired;
6
+import org.springframework.web.bind.annotation.GetMapping;
7
+import org.springframework.web.bind.annotation.PostMapping;
8
+import org.springframework.web.bind.annotation.RequestMapping;
9
+import org.springframework.web.bind.annotation.RestController;
10
+
11
+@RestController
12
+@RequestMapping("/test")
13
+public class TestController {
14
+
15
+    @Autowired
16
+    private CaptchaService captchaService;
17
+
18
+    @GetMapping("/test1")
19
+    public Result test1() {
20
+        var captcha = captchaService.findAll();
21
+        return Result.ok(captcha);
22
+    }
23
+
24
+    @PostMapping("/test2")
25
+    public Result test2() {
26
+        var captcha = captchaService.findById();
27
+        return Result.ok(captcha);
28
+    }
29
+}

+ 33 - 0
src/main/java/com/lqkj/cmlcp/module/test/domain/Captcha.java

@@ -0,0 +1,33 @@
1
+package com.lqkj.cmlcp.module.test.domain;
2
+
3
+import com.fasterxml.jackson.annotation.JsonFormat;
4
+import io.swagger.v3.oas.annotations.media.Schema;
5
+import lombok.AllArgsConstructor;
6
+import lombok.Data;
7
+import lombok.NoArgsConstructor;
8
+import lombok.experimental.Accessors;
9
+
10
+import java.util.Date;
11
+
12
+
13
+@Accessors(chain = true)
14
+@Data(staticConstructor = "create")
15
+@NoArgsConstructor
16
+@AllArgsConstructor
17
+public class Captcha {
18
+
19
+    private static final long serialVersionUID = 1L;
20
+
21
+    @Schema(description = "验证码id")
22
+    private Long id;
23
+
24
+    @Schema(description = "验证码")
25
+    private String code;
26
+
27
+    @Schema(description = "手机号")
28
+    private String phoneNumber;
29
+
30
+    @JsonFormat(pattern = "YYYY-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
31
+    private Date createTime;
32
+
33
+}

+ 9 - 0
src/main/java/com/lqkj/cmlcp/module/test/mapper/CaptchaMapper.java

@@ -0,0 +1,9 @@
1
+package com.lqkj.cmlcp.module.test.mapper;
2
+
3
+import com.lqkj.cmlcp.module.test.domain.Captcha;
4
+import com.mybatisflex.core.BaseMapper;
5
+import org.apache.ibatis.annotations.Mapper;
6
+
7
+@Mapper
8
+public interface CaptchaMapper extends BaseMapper<Captcha> {
9
+}

+ 12 - 0
src/main/java/com/lqkj/cmlcp/module/test/service/CaptchaService.java

@@ -0,0 +1,12 @@
1
+package com.lqkj.cmlcp.module.test.service;
2
+
3
+import com.lqkj.cmlcp.module.test.domain.Captcha;
4
+import com.mybatisflex.core.service.IService;
5
+
6
+import java.util.List;
7
+
8
+public interface CaptchaService extends IService<Captcha> {
9
+    List<Captcha> findAll();
10
+
11
+    Captcha findById();
12
+}

+ 44 - 0
src/main/java/com/lqkj/cmlcp/module/test/service/impl/CaptchaServiceImpl.java

@@ -0,0 +1,44 @@
1
+package com.lqkj.cmlcp.module.test.service.impl;
2
+
3
+import com.lqkj.cmlcp.module.test.domain.Captcha;
4
+import com.lqkj.cmlcp.module.test.mapper.CaptchaMapper;
5
+import com.lqkj.cmlcp.module.test.service.CaptchaService;
6
+import com.mybatisflex.spring.service.impl.ServiceImpl;
7
+import jakarta.annotation.Resource;
8
+import org.springframework.beans.factory.annotation.Autowired;
9
+import org.springframework.data.redis.core.RedisTemplate;
10
+import org.springframework.stereotype.Service;
11
+import org.springframework.transaction.annotation.Propagation;
12
+import org.springframework.transaction.annotation.Transactional;
13
+
14
+import java.util.List;
15
+import java.util.Objects;
16
+
17
+
18
+@Service
19
+@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
20
+public class CaptchaServiceImpl extends ServiceImpl<CaptchaMapper, Captcha> implements CaptchaService {
21
+    @Autowired
22
+    private CaptchaMapper captchaMapper;
23
+
24
+    @Resource
25
+    private RedisTemplate<String, List<Captcha>> redisTemplate;
26
+
27
+
28
+    @Override
29
+    public List<Captcha> findAll() {
30
+        var test = redisTemplate.opsForValue().get("test");
31
+        if (Objects.nonNull(test)){
32
+            return test;
33
+        }
34
+        var list = super.list();
35
+        redisTemplate.opsForValue().set("test",list);
36
+        return super.list();
37
+
38
+    }
39
+
40
+    @Override
41
+    public Captcha findById() {
42
+        return captchaMapper.selectOneById(1);
43
+    }
44
+}

+ 182 - 0
src/main/java/com/lqkj/cmlcp/utils/FileUtils.java

@@ -0,0 +1,182 @@
1
+package com.lqkj.cmlcp.utils;
2
+
3
+import org.springframework.web.multipart.MultipartFile;
4
+
5
+import java.io.*;
6
+import java.net.URL;
7
+import java.net.URLConnection;
8
+import java.util.ArrayList;
9
+import java.util.Base64;
10
+import java.util.List;
11
+
12
+/**
13
+ * @ClassName FileUtils
14
+ * @Description: TODO
15
+ * @Author wells
16
+ * @Date 2019/11/29 9:22
17
+ * @Version V1.0
18
+ **/
19
+public class FileUtils {
20
+
21
+    public static void dirCopy(File src, String destPath) throws Exception {
22
+        if (!new File(destPath).exists()) {
23
+            new File(destPath).mkdirs();
24
+        }
25
+        for (File s : src.listFiles()) {
26
+            if (s.isFile()) {
27
+                fileCopy(s.getPath(), destPath + File.separator + s.getName());
28
+            } else {
29
+                dirCopy(s, destPath + File.separator + s.getName());
30
+            }
31
+        }
32
+    }
33
+
34
+    public static void fileCopy(String srcPath, String destPath) throws IOException {
35
+        File src = new File(srcPath);
36
+        File dest = new File(destPath);
37
+        try (InputStream is = new BufferedInputStream(new FileInputStream(src));
38
+             OutputStream out = new BufferedOutputStream(new FileOutputStream(dest))) {
39
+            byte[] flush = new byte[1024];
40
+            int len = -1;
41
+            while ((len = is.read(flush)) != -1) {
42
+                out.write(flush, 0, len);
43
+            }
44
+            out.flush();
45
+        } catch (FileNotFoundException e) {
46
+            e.printStackTrace();
47
+        } catch (IOException e) {
48
+            e.printStackTrace();
49
+        }
50
+    }
51
+
52
+    public static void fileCopyIn(InputStream srcIn, String destPath, String fileName) {
53
+        if (!new File(destPath).exists()) {
54
+            new File(destPath).mkdirs();
55
+        }
56
+        File dest = new File(destPath + fileName);
57
+        try (
58
+                OutputStream out = new BufferedOutputStream(new FileOutputStream(dest))) {
59
+            byte[] flush = new byte[1024];
60
+            int len = -1;
61
+            while ((len = srcIn.read(flush)) != -1) {
62
+                out.write(flush, 0, len);
63
+            }
64
+            out.flush();
65
+        } catch (FileNotFoundException e) {
66
+            e.printStackTrace();
67
+        } catch (IOException e) {
68
+            e.printStackTrace();
69
+        }
70
+    }
71
+
72
+    /**
73
+     * 将base64字符解码保存文件
74
+     *
75
+     * @param base64Code
76
+     * @param targetPath
77
+     * @throws Exception
78
+     */
79
+
80
+    public static void decoderBase64File(String base64Code, String targetPath)
81
+            throws Exception {
82
+        File file = new File(targetPath.substring(0, targetPath.lastIndexOf("/")));
83
+        if (!file.exists()) {
84
+            file.mkdirs();
85
+        }
86
+        byte[] buffer = Base64.getDecoder().decode(base64Code);
87
+        FileOutputStream out = new FileOutputStream(targetPath);
88
+        out.write(buffer);
89
+        out.close();
90
+    }
91
+
92
+    /**
93
+     * 判断是否为图片格式
94
+     *
95
+     * @param fileExtension
96
+     * @return
97
+     */
98
+    public static Boolean isImgFile(String fileExtension) {
99
+        if (fileExtension.toLowerCase().contains("jpg") || fileExtension.toLowerCase().contains("jpeg") || fileExtension.toLowerCase().contains("png")
100
+                || fileExtension.contains("gif")) {
101
+            return true;
102
+        }
103
+        return false;
104
+    }
105
+
106
+    public static void downloadFile(String url, String targetPath) throws Exception {
107
+        File file = new File(targetPath.substring(0, targetPath.lastIndexOf("/")));
108
+        if (!file.exists()) {
109
+            file.mkdirs();
110
+        }
111
+
112
+        URL downloadUrl = new URL(url);
113
+        // 下载网络文件
114
+        int bytesum = 0;
115
+        int byteread = 0;
116
+        try {
117
+            URLConnection conn = downloadUrl.openConnection();
118
+            InputStream inStream = conn.getInputStream();
119
+            FileOutputStream fs = new FileOutputStream(targetPath);
120
+
121
+            byte[] buffer = new byte[1024];
122
+            while ((byteread = inStream.read(buffer)) != -1) {
123
+                bytesum += byteread;
124
+                System.out.println(bytesum);
125
+                fs.write(buffer, 0, byteread);
126
+            }
127
+        } catch (FileNotFoundException e) {
128
+            e.printStackTrace();
129
+        } catch (IOException e) {
130
+            e.printStackTrace();
131
+        }
132
+    }
133
+
134
+    /**
135
+     * 保存上传的文件到本地
136
+     *
137
+     * @param file 被删除文件的文件名
138
+     * @param path 保存路径
139
+     * @return 保存后的文件
140
+     */
141
+    public static File saveFile(MultipartFile file, String path, String name) {
142
+        try (InputStream inputStream = file.getInputStream()) {
143
+            File writeFile = new File(path + name);
144
+            org.apache.commons.io.FileUtils.copyInputStreamToFile(inputStream, writeFile);
145
+            return writeFile;
146
+        } catch (Exception e) {
147
+            return null;
148
+        }
149
+    }
150
+
151
+    public static List<File> searchFiles(File folder, final String keyword) {
152
+        List<File> result = new ArrayList<File>();
153
+        if (folder.isFile())
154
+            result.add(folder);
155
+
156
+        File[] subFolders = folder.listFiles(new FileFilter() {
157
+            @Override
158
+            public boolean accept(File file) {
159
+                if (file.isDirectory()) {
160
+                    return true;
161
+                }
162
+                if (file.getName().toLowerCase().contains(keyword)) {
163
+                    return true;
164
+                }
165
+                return false;
166
+            }
167
+        });
168
+
169
+        if (subFolders != null) {
170
+            for (File file : subFolders) {
171
+                if (file.isFile()) {
172
+                    // 如果是文件则将文件添加到结果列表中
173
+                    result.add(file);
174
+                } else {
175
+                    // 如果是文件夹,则递归调用本方法,然后把所有的文件加到结果列表中
176
+                    result.addAll(searchFiles(file, keyword));
177
+                }
178
+            }
179
+        }
180
+        return result;
181
+    }
182
+}

+ 124 - 0
src/main/java/com/lqkj/cmlcp/utils/RSAUtils.java

@@ -0,0 +1,124 @@
1
+package com.lqkj.cmlcp.utils;
2
+
3
+import javax.crypto.Cipher;
4
+import java.nio.charset.StandardCharsets;
5
+import java.security.*;
6
+import java.security.spec.InvalidKeySpecException;
7
+import java.security.spec.X509EncodedKeySpec;
8
+import java.util.Base64;
9
+
10
+/**
11
+ * @ClassName RSAUtils
12
+ * @Description TODO
13
+ * @Author wells
14
+ * @Date 2021/3/2 11:37 上午
15
+ * @Version 1.0
16
+ **/
17
+public class RSAUtils {
18
+    //KeyPair is a simple holder for a key pair.
19
+    private static final KeyPair keyPair = initKey();
20
+
21
+
22
+
23
+    /**
24
+     * 初始化方法,产生key pair,提供provider和random
25
+     *
26
+     * @return KeyPair instance
27
+     */
28
+    private static KeyPair initKey() {
29
+        try {
30
+            //添加provider
31
+            //产生用于安全加密的随机数
32
+            SecureRandom random = new SecureRandom();
33
+            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
34
+            generator.initialize(1024, random);
35
+            return generator.generateKeyPair();
36
+        } catch (Exception e) {
37
+            throw new RuntimeException(e);
38
+        }
39
+    }
40
+
41
+    /**
42
+     * 产生public key
43
+     *
44
+     * @return public key字符串
45
+     */
46
+    public static String generateBase64PublicKey() {
47
+        PublicKey publicKey = keyPair.getPublic();
48
+        //encodeBase64(): Encodes binary data using the base64
49
+        //algorithm but does not chunk the output.
50
+        //getEncoded():返回key的原始编码形式
51
+        return Base64.getEncoder().encodeToString(publicKey.getEncoded());
52
+    }
53
+
54
+    /**
55
+     * 解密数据
56
+     *
57
+     * @param string 需要解密的字符串
58
+     * @return 破解之后的字符串
59
+     */
60
+    public static String decryptBase64(String string) {
61
+        //decodeBase64():将Base64数据解码为"八位字节”数据
62
+        return new String(decrypt(Base64.getDecoder().decode(string.getBytes())));
63
+    }
64
+    public static String encryptBase64(String str) {
65
+        return Base64.getEncoder().encodeToString(encrypt(str.getBytes(StandardCharsets.UTF_8)));
66
+    }
67
+
68
+    public static String encryptBase64(String str, String publicKey) {
69
+        return Base64.getEncoder().encodeToString(encrypt(str.getBytes(StandardCharsets.UTF_8), publicKey));
70
+    }
71
+
72
+    private static byte[] encrypt(byte[] byteArray){
73
+        try {
74
+
75
+            Cipher cipher = Cipher.getInstance("RSA");
76
+            PublicKey publicKey = keyPair.getPublic();
77
+            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
78
+            return cipher.doFinal(byteArray);
79
+        } catch (Exception e) {
80
+            throw new RuntimeException(e);
81
+        }
82
+    }
83
+
84
+    private static byte[] decrypt(byte[] byteArray) {
85
+        try {
86
+
87
+            //Cipher: 提供加密和解密功能的实例
88
+            //transformation: "algorithm/mode/padding"
89
+            Cipher cipher = Cipher.getInstance("RSA");
90
+            PrivateKey privateKey = keyPair.getPrivate();
91
+            //初始化
92
+            cipher.init(Cipher.DECRYPT_MODE, privateKey);
93
+            //doFinal(): 加密或者解密数据
94
+            return cipher.doFinal(byteArray);
95
+        } catch (Exception e) {
96
+            throw new RuntimeException(e);
97
+        }
98
+    }
99
+
100
+    private static byte[] encrypt(byte[] byteArray, String publicKey){
101
+        try {
102
+
103
+            Cipher cipher = Cipher.getInstance("RSA");
104
+            cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKey));
105
+            return cipher.doFinal(byteArray);
106
+        } catch (Exception e) {
107
+            throw new RuntimeException(e);
108
+        }
109
+    }
110
+
111
+    private static PublicKey getPublicKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
112
+        byte[] keyBytes = Base64.getDecoder().decode(key);
113
+        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
114
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
115
+        return keyFactory.generatePublic(keySpec);
116
+    }
117
+
118
+    public static void main(String[] args) {
119
+        String s = RSAUtils.encryptBase64("9wytyRIgskPdprmHvb13kJJpUv78=");
120
+        System.out.println(s);
121
+        String a = RSAUtils.decryptBase64(s);
122
+        System.out.println(a);
123
+    }
124
+}

+ 78 - 0
src/main/resources/application-install.yml

@@ -0,0 +1,78 @@
1
+server:
2
+  address: 192.168.4.219
3
+  servlet:
4
+    context-path: /cmlcp-server
5
+  port: 9999
6
+  error:
7
+    include-exception: true
8
+  compression:
9
+    enabled: false
10
+  tomcat:
11
+    max-connections: 1000
12
+    max-swallow-size: 1000MB
13
+    max-http-form-post-size: 1000MB
14
+spring:
15
+  data:
16
+    redis:
17
+      host: 127.0.0.1
18
+      database: 0
19
+      port: 6379
20
+      connect-timeout: 10s
21
+      lettuce:
22
+        pool:
23
+          # 连接池最大连接数
24
+          max-active: 200
25
+          # 连接池最大阻塞等待时间(使用负值表示没有限制)
26
+          max-wait: -1ms
27
+          # 连接池中的最大空闲连接
28
+          max-idle: 10
29
+          # 连接池中的最小空闲连接
30
+          min-idle: 0
31
+  application:
32
+    name: CMLCP-SERVER
33
+  servlet:
34
+    multipart:
35
+      max-file-size: 1000MB
36
+      max-request-size: 1000MB
37
+      file-size-threshold: 10MB
38
+  jdbc:
39
+    template:
40
+      query-timeout: 20s
41
+  datasource:
42
+    hikari:
43
+      driver-class-name: org.postgresql.Driver
44
+      username: postgres
45
+      password: lqkj!@#456
46
+      auto-commit: true
47
+      pool-name: link
48
+      minimum-idle: 4
49
+      maximum-pool-size: 200
50
+      idle-timeout: 60000
51
+      max-lifetime: 1800000
52
+      connection-timeout: 30000
53
+      read-only: false
54
+    url: jdbc:postgresql://192.168.4.241:5432/dev_cmlcp
55
+  flyway:
56
+    baseline-on-migrate: true
57
+    enabled: true
58
+    validate-on-migrate: false
59
+  web:
60
+    resources:
61
+      cache:
62
+        cachecontrol:
63
+          cache-public: true
64
+          max-age: 0s
65
+      chain:
66
+        cache: true
67
+        enabled: true
68
+logging:
69
+  register-shutdown-hook: true
70
+  level:
71
+    org.springframework.boot: info
72
+    org.ehcache.impl.internal.store.heap.OnHeapStore: error
73
+    org.apache.coyote.http11.Http11InputBuffer: debug
74
+    org.hibernate.SQL: debug
75
+    io.swagger.models.parameters.AbstractSerializableParameter: error
76
+  file:
77
+    name: ./log/link.log
78
+    path: classpath:log4j2.xml

+ 13 - 0
src/main/resources/com/lqkj/cmlcp/module/authority/mapper/UserInfoMapper.xml

@@ -0,0 +1,13 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
3
+<mapper namespace="com.lqkj.cmlcp.module.authority.mapper.UserInfoMapper">
4
+
5
+    <insert id="initSuperAdminRole">
6
+        insert into user_role values (1, 1)
7
+    </insert>
8
+
9
+    <select id="initUserIdSeq">
10
+        ALTER SEQUENCE user_info_id_seq RESTART WITH 3
11
+    </select>
12
+
13
+</mapper>

+ 4 - 0
src/main/resources/com/lqkj/cmlcp/module/test/mapper/CaptchaMapper.xml

@@ -0,0 +1,4 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
3
+<mapper namespace="com.lqkj.cmlcp.module.test.mapper.CaptchaMapper">
4
+</mapper>

+ 164 - 0
src/main/resources/db/migration/V1__INIT.sql

@@ -0,0 +1,164 @@
1
+create table authority_info (
2
+                                authority_id         INT4                 not null,
3
+                                parent_id            INT4                 null,
4
+                                authority_name       VARCHAR(255)         null,
5
+                                en_name              VARCHAR(255)         null,
6
+                                route                VARCHAR(255)         null,
7
+                                component            VARCHAR(255)         null,
8
+                                redirect             VARCHAR(255)         null,
9
+                                icon                 VARCHAR(255)         null,
10
+                                order_id             INT4                 null,
11
+                                constraint PK_AUTHORITY_INFO primary key (authority_id)
12
+);
13
+
14
+comment on table authority_info is
15
+'权限信息:authority_info';
16
+
17
+comment on column authority_info.authority_id is
18
+'权限ID:authority_id';
19
+
20
+comment on column authority_info.parent_id is
21
+'父权限ID:parent_id';
22
+
23
+comment on column authority_info.authority_name is
24
+'权限名称:authority_name';
25
+
26
+comment on column authority_info.en_name is
27
+'英文名:en_name';
28
+
29
+comment on column authority_info.route is
30
+'路由地址:route';
31
+
32
+comment on column authority_info.component is
33
+'组件:component';
34
+
35
+comment on column authority_info.redirect is
36
+'重定向地址:redirect';
37
+
38
+comment on column authority_info.icon is
39
+'图标:icon';
40
+
41
+comment on column authority_info.order_id is
42
+'排序:order_id';
43
+
44
+create table role_authority (
45
+                                role_id              INT4                 not null,
46
+                                authority_id         INT4                 not null,
47
+                                constraint PK_ROLE_AUTHORITY primary key (role_id, authority_id)
48
+);
49
+comment on table role_authority is
50
+'角色权限信息:role_authority';
51
+
52
+comment on column role_authority.role_id is
53
+'角色ID:role_id';
54
+
55
+comment on column role_authority.authority_id is
56
+'权限ID:authority_id';
57
+insert into role_authority select 1,  generate_series (1, 11);
58
+
59
+create table role_info (
60
+                           role_id              SERIAL               not null,
61
+                           role_name            VARCHAR(255)         null,
62
+                           en_name              VARCHAR(255)         null,
63
+                           update_time          TIMESTAMP            null,
64
+                           constraint PK_ROLE_INFO primary key (role_id)
65
+);
66
+comment on table role_info is
67
+'角色信息:role_info';
68
+
69
+comment on column role_info.role_id is
70
+'角色ID:role_id';
71
+
72
+comment on column role_info.role_name is
73
+'角色名称:role_name';
74
+
75
+comment on column role_info.en_name is
76
+'英文名称:en_name';
77
+
78
+comment on column role_info.update_time is
79
+'更新时间:update_time';
80
+
81
+insert into role_info values
82
+    (1, '超级管理员', 'superAdmin', now());
83
+
84
+select nextval('role_info_role_id_seq');
85
+
86
+/*==============================================================*/
87
+/* Table: user_info                                             */
88
+/*==============================================================*/
89
+create table user_info (
90
+   id              SERIAL               not null,
91
+   user_code            VARCHAR(255)         null,
92
+   display_name         VARCHAR(255)         null,
93
+   password             VARCHAR(255)         null,
94
+   authorization_code   VARCHAR(64)          null,
95
+   head_img             VARCHAR(1024)        null,
96
+   file_save_path       VARCHAR(1024)        null,
97
+   has_auth             BOOL                 null,
98
+   login_error_count    INT4                 null,
99
+   locking              BOOL                 null,
100
+   lock_time            TIMESTAMP            null,
101
+   update_time          TIMESTAMP            null,
102
+   has_manage           BOOLEAN              null,
103
+   constraint PK_USER_INFO primary key (id)
104
+);
105
+comment on table user_info is
106
+'用户信息:user_info';
107
+
108
+comment on column user_info.id is
109
+'用户ID:user_id';
110
+
111
+comment on column user_info.user_code is
112
+'登录账号:user_code';
113
+
114
+comment on column user_info.display_name is
115
+'显示名称:display_name';
116
+
117
+comment on column user_info.password is
118
+'登录密码:password';
119
+
120
+comment on column user_info.authorization_code is
121
+'授权码:authorization_code';
122
+
123
+comment on column user_info.head_img is
124
+'头像:head_img';
125
+
126
+comment on column user_info.file_save_path is
127
+'文件保存路径:file_save_path';
128
+
129
+comment on column user_info.has_auth is
130
+'是否有审核权限:has_auth';
131
+
132
+comment on column user_info.login_error_count is
133
+'登录错误次数:login_error_count';
134
+
135
+comment on column user_info.locking is
136
+'是否锁定:locking';
137
+
138
+comment on column user_info.lock_time is
139
+'锁定时间:lock_time';
140
+
141
+comment on column user_info.update_time is
142
+'更新时间:update_time';
143
+
144
+comment on column user_info.has_manage is
145
+'能否进入管理后台:has_manage';
146
+
147
+
148
+/*==============================================================*/
149
+/* Table: user_role                                             */
150
+/*==============================================================*/
151
+create table user_role (
152
+                           role_id              INT4                 not null,
153
+                           user_id              INT4                 not null,
154
+                           constraint PK_USER_ROLE primary key (role_id, user_id)
155
+);
156
+
157
+comment on table user_role is
158
+'用户角色:user_role';
159
+
160
+comment on column user_role.role_id is
161
+'角色ID:role_id';
162
+
163
+comment on column user_role.user_id is
164
+'用户ID:user_id';

+ 47 - 0
src/main/resources/log4j2.xml

@@ -0,0 +1,47 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!-- 设置log4j2的自身log级别为warn -->
3
+<!-- OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
4
+<Configuration status="OFF">
5
+    <Properties>
6
+        <Property name="LOG_PATH">./log</Property>
7
+        <Property name="LOG_FILE">./log/cmccr2.log</Property>
8
+        <Property name="PID">????</Property>
9
+        <Property name="LOG_EXCEPTION_CONVERSION_WORD">%xwEx</Property>
10
+        <Property name="LOG_LEVEL_PATTERN">%5p</Property>
11
+        <Property name="LOG_DATEFORMAT_PATTERN">yyyy-MM-dd HH:mm:ss.SSS</Property>
12
+        <Property name="CONSOLE_LOG_PATTERN">%clr{%d{${LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD}</Property>
13
+        <Property name="FILE_LOG_PATTERN">%d{${LOG_DATEFORMAT_PATTERN}} ${LOG_LEVEL_PATTERN} ${sys:PID} --- [%t] %-40.40c{1.} : %m%n${LOG_EXCEPTION_CONVERSION_WORD}</Property>
14
+    </Properties>
15
+    <Appenders>
16
+        <Console name="Console" target="SYSTEM_OUT" follow="true" immediateFlush="false">
17
+            <PatternLayout pattern="${CONSOLE_LOG_PATTERN}" />
18
+        </Console>
19
+        <RollingFile name="File" fileName="${LOG_FILE}" filePattern="${LOG_PATH}/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz" immediateFlush="false">
20
+            <PatternLayout>
21
+                <Pattern>${FILE_LOG_PATTERN}</Pattern>
22
+            </PatternLayout>
23
+            <Policies>
24
+                <SizeBasedTriggeringPolicy size="10 MB" />
25
+            </Policies>
26
+        </RollingFile>
27
+    </Appenders>
28
+
29
+    <Loggers>
30
+        <Logger name="org.apache.catalina.startup.DigesterFactory" level="info" />
31
+        <Logger name="org.apache.catalina.util.LifecycleBase" level="info" />
32
+        <Logger name="org.apache.coyote.http11.Http11NioProtocol" level="info" />
33
+        <logger name="org.apache.sshd.common.util.SecurityUtils" level="info"/>
34
+        <Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="info" />
35
+        <Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="info" />
36
+        <Logger name="org.hibernate.validator.internal.util.Version" level="info" />
37
+        <logger name="org.springframework.boot.actuate.endpoint.jmx" level="info"/>
38
+        <logger name="com.apache.ibatis" level="info"/>
39
+        <logger name="java.sql.Connection" level="info"/>
40
+        <logger name="java.sql.Statement" level="info"/>
41
+        <logger name="java.sql.PreparedStatement" level="info"/>
42
+        <AsyncRoot level="info" additivity="false">
43
+            <AppenderRef ref="Console"/>
44
+            <AppenderRef ref="File"/>
45
+        </AsyncRoot>
46
+    </Loggers>
47
+</Configuration>

+ 13 - 0
src/test/java/com/lqkj/cmlcp/CmlcpServerApplicationTests.java

@@ -0,0 +1,13 @@
1
+package com.lqkj.cmlcp;
2
+
3
+import org.junit.jupiter.api.Test;
4
+import org.springframework.boot.test.context.SpringBootTest;
5
+
6
+@SpringBootTest
7
+class CmlcpServerApplicationTests {
8
+
9
+    @Test
10
+    void contextLoads() {
11
+    }
12
+
13
+}