├── .gitignore
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── oym
│ │ └── cms
│ │ ├── CmsApplication.java
│ │ ├── client
│ │ ├── ContractClient.java
│ │ └── FastDFSClient.java
│ │ ├── config
│ │ ├── fisco
│ │ │ └── FiscoBcos.java
│ │ ├── mapper
│ │ │ ├── DataSourceConfiguration.java
│ │ │ └── SessionFactoryConfiguration.java
│ │ ├── redis
│ │ │ ├── JedisPoolFactory.java
│ │ │ ├── JedisUtil.java
│ │ │ └── RedisConfiguration.java
│ │ ├── service
│ │ │ └── TransactionManagementConfiguration.java
│ │ ├── shiro
│ │ │ ├── MySessionManager.java
│ │ │ ├── MyShiroRealm.java
│ │ │ └── ShiroConfig.java
│ │ └── web
│ │ │ └── MvcConfiguration.java
│ │ ├── contract
│ │ └── CertificateIQ.java
│ │ ├── controller
│ │ ├── CertificateController.java
│ │ └── UserController.java
│ │ ├── dto
│ │ ├── CertificateDTO.java
│ │ ├── ImageHolder.java
│ │ └── UserDTO.java
│ │ ├── entity
│ │ ├── Certificate.java
│ │ └── User.java
│ │ ├── enums
│ │ ├── CertificateTypeEnum.java
│ │ ├── DTOMsgEnum.java
│ │ ├── UserIdStatusEnum.java
│ │ └── UserPositionEnum.java
│ │ ├── exceptions
│ │ ├── CertificateException.java
│ │ └── UserException.java
│ │ ├── mapper
│ │ ├── JurisdictionMapper.java
│ │ └── UserMapper.java
│ │ ├── service
│ │ ├── CacheService.java
│ │ ├── CertificateService.java
│ │ ├── UserService.java
│ │ └── impl
│ │ │ ├── CacheServiceImpl.java
│ │ │ ├── CertificateServiceImpl.java
│ │ │ └── UserServiceImpl.java
│ │ └── util
│ │ ├── CertificateIdBuildUtil.java
│ │ ├── DESUtil.java
│ │ ├── EncryptionUtil.java
│ │ ├── HttpServletRequestUtil.java
│ │ ├── ImageUtil.java
│ │ ├── PageCalculator.java
│ │ └── PasswordHelper.java
└── resources
│ ├── FastDFSConfig.properties
│ ├── application.yml
│ ├── conf
│ ├── ca.crt
│ ├── sdk.crt
│ ├── sdk.key
│ └── sdk.publickey
│ ├── contract
│ ├── CertificateIQ.sol
│ └── Table.sol
│ ├── mapper
│ ├── JurisdicitonMapper.xml
│ └── UserMapper.xml
│ ├── mybatis-config.xml
│ └── slf4j.xml
└── test
└── java
└── com
└── oym
└── cms
├── CmsApplicationTests.java
├── contract
└── ContractTest.java
├── mapper
├── JurisdictionMapperTest.java
└── UserMapperTest.java
└── service
├── CertificateServiceImpl.java
└── UserServiceTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dylan666666/Certificate-Management-System/a633b8fc9e5ea006b7a086d4bca96be87abbc14d/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
3 |
--------------------------------------------------------------------------------
/mvnw:
--------------------------------------------------------------------------------
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 | # Maven Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /usr/local/etc/mavenrc ] ; then
40 | . /usr/local/etc/mavenrc
41 | fi
42 |
43 | if [ -f /etc/mavenrc ] ; then
44 | . /etc/mavenrc
45 | fi
46 |
47 | if [ -f "$HOME/.mavenrc" ] ; then
48 | . "$HOME/.mavenrc"
49 | fi
50 |
51 | fi
52 |
53 | # OS specific support. $var _must_ be set to either true or false.
54 | cygwin=false;
55 | darwin=false;
56 | mingw=false
57 | case "`uname`" in
58 | CYGWIN*) cygwin=true ;;
59 | MINGW*) mingw=true;;
60 | Darwin*) darwin=true
61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
63 | if [ -z "$JAVA_HOME" ]; then
64 | if [ -x "/usr/libexec/java_home" ]; then
65 | export JAVA_HOME="`/usr/libexec/java_home`"
66 | else
67 | export JAVA_HOME="/Library/Java/Home"
68 | fi
69 | fi
70 | ;;
71 | esac
72 |
73 | if [ -z "$JAVA_HOME" ] ; then
74 | if [ -r /etc/gentoo-release ] ; then
75 | JAVA_HOME=`java-config --jre-home`
76 | fi
77 | fi
78 |
79 | if [ -z "$M2_HOME" ] ; then
80 | ## resolve links - $0 may be a link to maven's home
81 | PRG="$0"
82 |
83 | # need this for relative symlinks
84 | while [ -h "$PRG" ] ; do
85 | ls=`ls -ld "$PRG"`
86 | link=`expr "$ls" : '.*-> \(.*\)$'`
87 | if expr "$link" : '/.*' > /dev/null; then
88 | PRG="$link"
89 | else
90 | PRG="`dirname "$PRG"`/$link"
91 | fi
92 | done
93 |
94 | saveddir=`pwd`
95 |
96 | M2_HOME=`dirname "$PRG"`/..
97 |
98 | # make it fully qualified
99 | M2_HOME=`cd "$M2_HOME" && pwd`
100 |
101 | cd "$saveddir"
102 | # echo Using m2 at $M2_HOME
103 | fi
104 |
105 | # For Cygwin, ensure paths are in UNIX format before anything is touched
106 | if $cygwin ; then
107 | [ -n "$M2_HOME" ] &&
108 | M2_HOME=`cygpath --unix "$M2_HOME"`
109 | [ -n "$JAVA_HOME" ] &&
110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
111 | [ -n "$CLASSPATH" ] &&
112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
113 | fi
114 |
115 | # For Mingw, ensure paths are in UNIX format before anything is touched
116 | if $mingw ; then
117 | [ -n "$M2_HOME" ] &&
118 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
119 | [ -n "$JAVA_HOME" ] &&
120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
121 | fi
122 |
123 | if [ -z "$JAVA_HOME" ]; then
124 | javaExecutable="`which javac`"
125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
126 | # readlink(1) is not available as standard on Solaris 10.
127 | readLink=`which readlink`
128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
129 | if $darwin ; then
130 | javaHome="`dirname \"$javaExecutable\"`"
131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
132 | else
133 | javaExecutable="`readlink -f \"$javaExecutable\"`"
134 | fi
135 | javaHome="`dirname \"$javaExecutable\"`"
136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
137 | JAVA_HOME="$javaHome"
138 | export JAVA_HOME
139 | fi
140 | fi
141 | fi
142 |
143 | if [ -z "$JAVACMD" ] ; then
144 | if [ -n "$JAVA_HOME" ] ; then
145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
146 | # IBM's JDK on AIX uses strange locations for the executables
147 | JAVACMD="$JAVA_HOME/jre/sh/java"
148 | else
149 | JAVACMD="$JAVA_HOME/bin/java"
150 | fi
151 | else
152 | JAVACMD="`\\unset -f command; \\command -v java`"
153 | fi
154 | fi
155 |
156 | if [ ! -x "$JAVACMD" ] ; then
157 | echo "Error: JAVA_HOME is not defined correctly." >&2
158 | echo " We cannot execute $JAVACMD" >&2
159 | exit 1
160 | fi
161 |
162 | if [ -z "$JAVA_HOME" ] ; then
163 | echo "Warning: JAVA_HOME environment variable is not set."
164 | fi
165 |
166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
167 |
168 | # traverses directory structure from process work directory to filesystem root
169 | # first directory with .mvn subdirectory is considered project base directory
170 | find_maven_basedir() {
171 |
172 | if [ -z "$1" ]
173 | then
174 | echo "Path not specified to find_maven_basedir"
175 | return 1
176 | fi
177 |
178 | basedir="$1"
179 | wdir="$1"
180 | while [ "$wdir" != '/' ] ; do
181 | if [ -d "$wdir"/.mvn ] ; then
182 | basedir=$wdir
183 | break
184 | fi
185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
186 | if [ -d "${wdir}" ]; then
187 | wdir=`cd "$wdir/.."; pwd`
188 | fi
189 | # end of workaround
190 | done
191 | echo "${basedir}"
192 | }
193 |
194 | # concatenates all lines of a file
195 | concat_lines() {
196 | if [ -f "$1" ]; then
197 | echo "$(tr -s '\n' ' ' < "$1")"
198 | fi
199 | }
200 |
201 | BASE_DIR=`find_maven_basedir "$(pwd)"`
202 | if [ -z "$BASE_DIR" ]; then
203 | exit 1;
204 | fi
205 |
206 | ##########################################################################################
207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
208 | # This allows using the maven wrapper in projects that prohibit checking in binary data.
209 | ##########################################################################################
210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
211 | if [ "$MVNW_VERBOSE" = true ]; then
212 | echo "Found .mvn/wrapper/maven-wrapper.jar"
213 | fi
214 | else
215 | if [ "$MVNW_VERBOSE" = true ]; then
216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
217 | fi
218 | if [ -n "$MVNW_REPOURL" ]; then
219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
220 | else
221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
222 | fi
223 | while IFS="=" read key value; do
224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
225 | esac
226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
227 | if [ "$MVNW_VERBOSE" = true ]; then
228 | echo "Downloading from: $jarUrl"
229 | fi
230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
231 | if $cygwin; then
232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
233 | fi
234 |
235 | if command -v wget > /dev/null; then
236 | if [ "$MVNW_VERBOSE" = true ]; then
237 | echo "Found wget ... using wget"
238 | fi
239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
241 | else
242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
243 | fi
244 | elif command -v curl > /dev/null; then
245 | if [ "$MVNW_VERBOSE" = true ]; then
246 | echo "Found curl ... using curl"
247 | fi
248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
249 | curl -o "$wrapperJarPath" "$jarUrl" -f
250 | else
251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
252 | fi
253 |
254 | else
255 | if [ "$MVNW_VERBOSE" = true ]; then
256 | echo "Falling back to using Java to download"
257 | fi
258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
259 | # For Cygwin, switch paths to Windows format before running javac
260 | if $cygwin; then
261 | javaClass=`cygpath --path --windows "$javaClass"`
262 | fi
263 | if [ -e "$javaClass" ]; then
264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
265 | if [ "$MVNW_VERBOSE" = true ]; then
266 | echo " - Compiling MavenWrapperDownloader.java ..."
267 | fi
268 | # Compiling the Java class
269 | ("$JAVA_HOME/bin/javac" "$javaClass")
270 | fi
271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
272 | # Running the downloader
273 | if [ "$MVNW_VERBOSE" = true ]; then
274 | echo " - Running MavenWrapperDownloader.java ..."
275 | fi
276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
277 | fi
278 | fi
279 | fi
280 | fi
281 | ##########################################################################################
282 | # End of extension
283 | ##########################################################################################
284 |
285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
286 | if [ "$MVNW_VERBOSE" = true ]; then
287 | echo $MAVEN_PROJECTBASEDIR
288 | fi
289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
290 |
291 | # For Cygwin, switch paths to Windows format before running java
292 | if $cygwin; then
293 | [ -n "$M2_HOME" ] &&
294 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
295 | [ -n "$JAVA_HOME" ] &&
296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
297 | [ -n "$CLASSPATH" ] &&
298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
299 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
301 | fi
302 |
303 | # Provide a "standardized" way to retrieve the CLI args that will
304 | # work with both Windows and non-Windows executions.
305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
306 | export MAVEN_CMD_LINE_ARGS
307 |
308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
309 |
310 | exec "$JAVACMD" \
311 | $MAVEN_OPTS \
312 | $MAVEN_DEBUG_OPTS \
313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
314 | "-Dmaven.home=${M2_HOME}" \
315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
317 |
--------------------------------------------------------------------------------
/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM https://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM set title of command window
39 | title %0
40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
42 |
43 | @REM set %HOME% to equivalent of $HOME
44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
45 |
46 | @REM Execute a user defined script before this one
47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
51 | :skipRcPre
52 |
53 | @setlocal
54 |
55 | set ERROR_CODE=0
56 |
57 | @REM To isolate internal variables from possible post scripts, we use another setlocal
58 | @setlocal
59 |
60 | @REM ==== START VALIDATION ====
61 | if not "%JAVA_HOME%" == "" goto OkJHome
62 |
63 | echo.
64 | echo Error: JAVA_HOME not found in your environment. >&2
65 | echo Please set the JAVA_HOME variable in your environment to match the >&2
66 | echo location of your Java installation. >&2
67 | echo.
68 | goto error
69 |
70 | :OkJHome
71 | if exist "%JAVA_HOME%\bin\java.exe" goto init
72 |
73 | echo.
74 | echo Error: JAVA_HOME is set to an invalid directory. >&2
75 | echo JAVA_HOME = "%JAVA_HOME%" >&2
76 | echo Please set the JAVA_HOME variable in your environment to match the >&2
77 | echo location of your Java installation. >&2
78 | echo.
79 | goto error
80 |
81 | @REM ==== END VALIDATION ====
82 |
83 | :init
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
122 |
123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
124 |
125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
127 | )
128 |
129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data.
131 | if exist %WRAPPER_JAR% (
132 | if "%MVNW_VERBOSE%" == "true" (
133 | echo Found %WRAPPER_JAR%
134 | )
135 | ) else (
136 | if not "%MVNW_REPOURL%" == "" (
137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
138 | )
139 | if "%MVNW_VERBOSE%" == "true" (
140 | echo Couldn't find %WRAPPER_JAR%, downloading it ...
141 | echo Downloading from: %DOWNLOAD_URL%
142 | )
143 |
144 | powershell -Command "&{"^
145 | "$webclient = new-object System.Net.WebClient;"^
146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
148 | "}"^
149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
150 | "}"
151 | if "%MVNW_VERBOSE%" == "true" (
152 | echo Finished downloading %WRAPPER_JAR%
153 | )
154 | )
155 | @REM End of extension
156 |
157 | @REM Provide a "standardized" way to retrieve the CLI args that will
158 | @REM work with both Windows and non-Windows executions.
159 | set MAVEN_CMD_LINE_ARGS=%*
160 |
161 | %MAVEN_JAVA_EXE% ^
162 | %JVM_CONFIG_MAVEN_PROPS% ^
163 | %MAVEN_OPTS% ^
164 | %MAVEN_DEBUG_OPTS% ^
165 | -classpath %WRAPPER_JAR% ^
166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
168 | if ERRORLEVEL 1 goto error
169 | goto end
170 |
171 | :error
172 | set ERROR_CODE=1
173 |
174 | :end
175 | @endlocal & set ERROR_CODE=%ERROR_CODE%
176 |
177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
181 | :skipRcPost
182 |
183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause
185 |
186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
187 |
188 | cmd /C exit /B %ERROR_CODE%
189 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.3.1.RELEASE
9 |
10 |
11 | com.oym
12 | cms
13 | 0.0.1-SNAPSHOT
14 | cms
15 | jar
16 |
17 |
18 | 11
19 | 4.1
20 | 1.8.0
21 | 3.3.1
22 |
23 |
24 |
25 |
26 | org.springframework.boot
27 | spring-boot-starter-jdbc
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-web
32 |
33 |
34 | org.mybatis.spring.boot
35 | mybatis-spring-boot-starter
36 | 2.1.3
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-configuration-processor
41 | true
42 |
43 |
44 |
45 | mysql
46 | mysql-connector-java
47 | runtime
48 |
49 |
50 |
51 | org.springframework.boot
52 | spring-boot-starter-test
53 | test
54 |
55 |
56 | org.junit.vintage
57 | junit-vintage-engine
58 |
59 |
60 |
61 |
62 |
63 |
64 | org.fisco-bcos.java-sdk
65 | fisco-bcos-java-sdk
66 | 2.8.0
67 |
68 |
69 | org.springframework
70 | spring
71 |
72 |
73 | org.slf4j
74 | slf4j-log4j12
75 |
76 |
77 |
78 |
79 |
80 |
81 | org.projectlombok
82 | lombok
83 | true
84 |
85 |
86 |
87 |
88 | javax.servlet
89 | javax.servlet-api
90 | 4.0.1
91 |
92 |
93 |
94 |
95 | com.fasterxml.jackson.core
96 | jackson-databind
97 | 2.11.0
98 |
99 |
100 | com.alibaba
101 | fastjson
102 | 1.2.70
103 |
104 |
105 |
106 |
107 | mysql
108 | mysql-connector-java
109 | 8.0.19
110 |
111 |
112 | com.mchange
113 | c3p0
114 | 0.9.5.2
115 |
116 |
117 |
118 |
119 | redis.clients
120 | jedis
121 | 2.9.0
122 |
123 |
124 |
125 |
126 | junit
127 | junit
128 | test
129 |
130 |
131 |
132 |
133 | commons-fileupload
134 | commons-fileupload
135 | 1.4
136 |
137 |
138 | org.apache.directory.studio
139 | org.apache.commons.codec
140 | 1.8
141 |
142 |
143 |
144 |
145 | net.coobird
146 | thumbnailator
147 | 0.4.10
148 |
149 |
150 |
151 |
152 | commons-collections
153 | commons-collections
154 | 3.2.2
155 |
156 |
157 |
158 |
159 | org.apache.commons
160 | commons-lang3
161 | 3.4
162 |
163 |
164 |
165 |
166 | org.apache.commons
167 | commons-collections4
168 | ${commons-collections4.version}
169 |
170 |
171 |
172 |
173 | org.apache.shiro
174 | shiro-spring
175 | ${shiro-spring.version}
176 |
177 |
178 | org.crazycake
179 | shiro-redis
180 | ${shiro-redis.version}
181 |
182 |
183 |
184 |
185 | javax.validation
186 | validation-api
187 | 2.0.1.Final
188 |
189 |
190 |
191 |
192 | com.google.guava
193 | guava
194 | 31.0.1-jre
195 |
196 |
197 |
198 |
199 | cn.bestwu
200 | fastdfs-client-java
201 | 1.27
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 | org.springframework.boot
210 | spring-boot-maven-plugin
211 |
212 |
213 |
214 |
215 |
216 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/CmsApplication.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | /**
7 | * @Author: Mr_OO
8 | * @Date: 2022/2/23 16:17
9 | */
10 | @SpringBootApplication
11 | public class CmsApplication {
12 |
13 | public static void main(String[] args) {
14 | SpringApplication.run(CmsApplication.class, args);
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/client/ContractClient.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.client;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.oym.cms.config.fisco.FiscoBcos;
5 | import com.oym.cms.contract.CertificateIQ;
6 | import com.oym.cms.entity.Certificate;
7 | import com.oym.cms.enums.DTOMsgEnum;
8 | import lombok.RequiredArgsConstructor;
9 | import lombok.extern.slf4j.Slf4j;
10 | import lombok.val;
11 | import org.fisco.bcos.sdk.BcosSDK;
12 | import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple1;
13 | import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple6;
14 | import org.fisco.bcos.sdk.model.TransactionReceipt;
15 | import org.fisco.bcos.sdk.transaction.model.exception.ContractException;
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 | import org.springframework.stereotype.Service;
19 |
20 | import javax.annotation.PostConstruct;
21 | import javax.annotation.Resource;
22 | import java.math.BigInteger;
23 | import java.util.ArrayList;
24 | import java.util.Date;
25 | import java.util.List;
26 | import java.util.Objects;
27 |
28 | /**
29 | * 合约接口调用类
30 | * @Author: Mr_OO
31 | * @Date: 2022/4/6 12:03
32 | */
33 | @Service
34 | @RequiredArgsConstructor
35 | @Slf4j
36 | public class ContractClient {
37 |
38 | private CertificateIQ certificateIQ;
39 |
40 | @Resource
41 | private FiscoBcos fiscoBcos;
42 |
43 | private static final Logger LOGGER = LoggerFactory.getLogger(ContractClient.class);
44 |
45 | private final static BigInteger SUCCESS_RET = new BigInteger("0");
46 |
47 | @PostConstruct
48 | public void initClient() {
49 | fiscoBcos.init();
50 | BcosSDK bcosSDK = fiscoBcos.getBcosSDK();
51 | val cryptoSuite = bcosSDK.getClient(1).getCryptoSuite();
52 | val cryptoKeyPair = cryptoSuite.getCryptoKeyPair();
53 | try {
54 | certificateIQ = CertificateIQ.deploy(bcosSDK.getClient(1), cryptoKeyPair);
55 | certificateIQ.create();
56 | } catch (ContractException e) {
57 | LOGGER.error("ContractClient deploy fail");
58 | e.printStackTrace();
59 | }
60 | }
61 |
62 | /**
63 | * 证书注册到区块链上
64 | * @param schoolFlag
65 | * @param stuNumber
66 | * @param userName
67 | * @param cmsName
68 | * @param cmsType
69 | * @param cmsWinTime
70 | * @param cmsDesc
71 | * @param cmsUrl
72 | * @return
73 | */
74 | public int registerCertificate(String schoolFlag, String stuNumber, String userName, String cmsName,
75 | String cmsType, String cmsWinTime, String cmsDesc, String cmsUrl) {
76 | try {
77 | TransactionReceipt receipt = certificateIQ.register(schoolFlag, stuNumber, userName, cmsName, cmsType,
78 | cmsWinTime, cmsDesc, cmsUrl);
79 | Tuple1 registerOutput = certificateIQ.getRegisterOutput(receipt);
80 | if (registerOutput != null && Objects.equals(registerOutput.getValue1(), SUCCESS_RET)) {
81 | LOGGER.info("ContractClient registerCertificate success cmsUrl:{}", cmsUrl);
82 | return DTOMsgEnum.OK.getStatus();
83 | }
84 | } catch (Exception e) {
85 | LOGGER.info("ContractClient registerCertificate exception cmsUrl:{}, e:{}", cmsUrl, JSON.toJSONString(e));
86 | }
87 | return DTOMsgEnum.ERROR_EXCEPTION.getStatus();
88 | }
89 |
90 | /**
91 | * 通过学号查询证书集合
92 | * @param userId
93 | * @return
94 | */
95 | public List queryCertificateList(String userId) {
96 | try {
97 | Tuple6, List, List, List, List> result = certificateIQ.select(userId);
98 | //判断是否集合为空
99 | if (!Objects.equals(result.getValue1(), SUCCESS_RET)) {
100 | //开始封装
101 | List list1 = result.getValue2();
102 | List list2 = result.getValue3();
103 | List list3 = result.getValue4();
104 | List list4 = result.getValue5();
105 | List list5 = result.getValue6();
106 | List certificateList = new ArrayList<>(list1.size());
107 | for (int i = 0; i < list1.size(); i++) {
108 | Certificate certificate = new Certificate();
109 | certificate.setUserId(userId);
110 | certificate.setCertificateName(list1.get(i));
111 | certificate.setCertificateType(Integer.valueOf(list2.get(i)));
112 | certificate.setCertificateWinTime(new Date(Long.parseLong(list3.get(i))));
113 | certificate.setCertificateDescription(list4.get(i));
114 | certificate.setCertificateUrl(list5.get(i));
115 | certificateList.add(certificate);
116 | }
117 | LOGGER.info("ContractClient registerCertificate success userId:{}", userId);
118 | return certificateList;
119 | }
120 | } catch (Exception e) {
121 | LOGGER.info("ContractClient queryCertificateList exception userId:{}", userId);
122 | }
123 | return new ArrayList<>();
124 | }
125 |
126 | }
127 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/client/FastDFSClient.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.client;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.csource.common.NameValuePair;
5 | import org.csource.fastdfs.*;
6 | import java.io.*;
7 |
8 | /**
9 | * 分布式证书存储客户端类
10 | * @Author: Mr_OO
11 | * @Date: 2022/4/2 15:04
12 | */
13 | public class FastDFSClient {
14 |
15 | private static StorageClient storageClient = null;
16 |
17 | /**
18 | * 只加载一次.
19 | */
20 | static {
21 | try {
22 | ClientGlobal.init("FastDFSConfig.properties");
23 | TrackerClient trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);
24 | TrackerServer trackerServer = trackerClient.getConnection();
25 | StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
26 | storageClient = new StorageClient(trackerServer, storageServer);
27 | } catch (Exception e) {
28 | e.printStackTrace();
29 | }
30 | }
31 |
32 | /**
33 | * @param inputStream
34 | * 上传的文件输入流
35 | * @param fileName
36 | * 上传的文件原始名
37 | * @return
38 | */
39 | public static String[] uploadFile(InputStream inputStream, String fileName) {
40 | try {
41 | // 文件的元数据
42 | NameValuePair[] meta_list = new NameValuePair[2];
43 | // 第一组元数据,文件的原始名称
44 | meta_list[0] = new NameValuePair("file name", fileName);
45 | // 第二组元数据
46 | meta_list[1] = new NameValuePair("file length", inputStream.available()+"");
47 | // 准备字节数组
48 | byte[] file_buff = null;
49 | if (inputStream != null) {
50 | // 查看文件的长度
51 | int len = inputStream.available();
52 | // 创建对应长度的字节数组
53 | file_buff = new byte[len];
54 | // 将输入流中的字节内容,读到字节数组中。
55 | inputStream.read(file_buff);
56 | }
57 | // 上传文件。参数含义:要上传的文件的内容(使用字节数组传递),上传的文件的类型(扩展名),元数据
58 | String[] fileids = storageClient.upload_file(file_buff, getFileExt(fileName), meta_list);
59 | return fileids;
60 | } catch (Exception ex) {
61 | ex.printStackTrace();
62 | }
63 | return null;
64 | }
65 |
66 | /**
67 | * @param file
68 | * 文件
69 | * @param fileName
70 | * 文件名
71 | * @return 返回Null则为失败
72 | */
73 | public static String[] uploadFile(File file, String fileName) {
74 | FileInputStream fis = null;
75 | try {
76 | NameValuePair[] metaList = null;
77 | fis = new FileInputStream(file);
78 | byte[] fileBuff = null;
79 | if (fis != null) {
80 | int len = fis.available();
81 | fileBuff = new byte[len];
82 | fis.read(fileBuff);
83 | }
84 | String[] fileids = storageClient.upload_file(fileBuff, getFileExt(fileName), metaList);
85 | return fileids;
86 | } catch (Exception ex) {
87 | return null;
88 | } finally {
89 | if (fis != null) {
90 | try {
91 | fis.close();
92 | } catch (IOException e) {
93 | e.printStackTrace();
94 | }
95 | }
96 | }
97 | }
98 |
99 | /**
100 | * 根据组名和远程文件名来删除一个文件
101 | *
102 | * @param groupName
103 | * 例如 "group1" 如果不指定该值,默认为group1
104 | * @param remoteFileName
105 | * 例如"M00/00/00/wKgxgk5HbLvfP86RAAAAChd9X1Y736.jpg"
106 | * @return 0为成功,非0为失败,具体为错误代码
107 | */
108 | private static int deleteFile(String groupName, String remoteFileName) {
109 | try {
110 | int result = storageClient.delete_file(groupName == null ? "group1" : groupName, remoteFileName);
111 | return result;
112 | } catch (Exception ex) {
113 | return 0;
114 | }
115 | }
116 |
117 | /**
118 | * 修改一个已经存在的文件
119 | *
120 | * @param oldGroupName
121 | * 旧的组名
122 | * @param oldFileName
123 | * 旧的文件名
124 | * @param file
125 | * 新文件
126 | * @param fileName
127 | * 新文件名
128 | * @return 返回空则为失败
129 | */
130 | private static String[] modifyFile(String oldGroupName, String oldFileName, File file, String fileName) {
131 | String[] fileids = null;
132 | try {
133 | // 先上传
134 | fileids = uploadFile(file, fileName);
135 | if (fileids == null) {
136 | return null;
137 | }
138 | // 再删除
139 | int delResult = deleteFile(oldGroupName, oldFileName);
140 | if (delResult != 0) {
141 | return null;
142 | }
143 | } catch (Exception ex) {
144 | return null;
145 | }
146 | return fileids;
147 | }
148 |
149 | /**
150 | * 文件下载
151 | *
152 | * @param groupName 卷名
153 | * @param remoteFileName 文件名
154 | * @return 返回一个流
155 | */
156 | public static InputStream downloadFile(String groupName, String remoteFileName) {
157 | try {
158 | byte[] bytes = storageClient.download_file(groupName, remoteFileName);
159 | InputStream inputStream = new ByteArrayInputStream(bytes);
160 | return inputStream;
161 | } catch (Exception ex) {
162 | return null;
163 | }
164 | }
165 |
166 | public static NameValuePair[] getMetaDate(String groupName, String remoteFileName){
167 | try {
168 | NameValuePair[] nvp = storageClient.get_metadata(groupName, remoteFileName);
169 | return nvp;
170 | } catch (Exception ex) {
171 | ex.printStackTrace();
172 | return null;
173 | }
174 | }
175 |
176 | /**
177 | * 获取文件后缀名(不带点).
178 | *
179 | * @return 如:"jpg" or "png".
180 | */
181 | private static String getFileExt(String fileName) {
182 | if (StringUtils.isBlank(fileName) || !fileName.contains(".")) {
183 | return "";
184 | } else {
185 | return fileName.substring(fileName.lastIndexOf(".") + 1);
186 | }
187 | }
188 |
189 | public static void main(String[] args) {
190 | try {
191 | // File file = new File("C:/Users/14396/Desktop/my/图片/绿叶.png");
192 | // InputStream inputStream = new FileInputStream(file);
193 | // String fileName = "110429" + ImageUtil.getRandomFileName() + ".png"
194 | // String[] result = FastDFSClient.uploadFile(inputStream, fileName);
195 | // //[group1, M00/00/00/CgAYCGJFpQKACftIAAAbnjkyo8A652.png]
196 | // System.out.println(ImageUtil.IMAGE_URL_PRE + ImageUtil.getImageUrl(result));
197 | // //http://101.43.139.237:8081/group1/M00/00/00/CgAYCGJFsVmAWtitAAAbnjkyo8A098.png
198 | } catch (Exception e) {
199 | e.printStackTrace();
200 | }
201 | }
202 |
203 | }
204 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/config/fisco/FiscoBcos.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.config.fisco;
2 |
3 | import lombok.Data;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.fisco.bcos.sdk.BcosSDK;
6 | import org.fisco.bcos.sdk.config.ConfigOption;
7 | import org.fisco.bcos.sdk.config.exceptions.ConfigException;
8 | import org.fisco.bcos.sdk.config.model.ConfigProperty;
9 | import org.springframework.stereotype.Component;
10 | import org.yaml.snakeyaml.Yaml;
11 | import org.yaml.snakeyaml.representer.Representer;
12 |
13 | import java.io.InputStream;
14 |
15 | /**
16 | * @author 14396
17 | */
18 | @Data
19 | @Component
20 | @Slf4j
21 | public class FiscoBcos {
22 |
23 | BcosSDK bcosSDK;
24 |
25 | public void init() {
26 | ConfigProperty configProperty = loadProperty();
27 | ConfigOption configOption ;
28 | try {
29 | configOption = new ConfigOption(configProperty);
30 | } catch (ConfigException e) {
31 | log.error("init error:" + e.toString());
32 | return ;
33 | }
34 | bcosSDK = new BcosSDK(configOption);
35 | }
36 |
37 | public ConfigProperty loadProperty() {
38 | Representer representer = new Representer();
39 | representer.getPropertyUtils().setSkipMissingProperties(true);
40 | Yaml yaml = new Yaml(representer);
41 | String configFile = "/application.yml";
42 | try (InputStream inputStream = this.getClass().getResourceAsStream(configFile)) {
43 | return yaml.loadAs(inputStream, ConfigProperty.class);
44 | } catch (Exception e) {
45 | log.error("load property: ", e);
46 | }
47 | return null;
48 | }
49 | }
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/config/mapper/DataSourceConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.config.mapper;
2 |
3 | import com.mchange.v2.c3p0.ComboPooledDataSource;
4 | import com.oym.cms.util.DESUtil;
5 | import org.mybatis.spring.annotation.MapperScan;
6 | import org.springframework.beans.factory.annotation.Value;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 |
10 | import java.beans.PropertyVetoException;
11 |
12 | /**
13 | * @Author: Mr_OO
14 | * @Date: 2022/3/1 13:25
15 | */
16 | @Configuration
17 | @MapperScan("com.oym.cms.mapper")
18 | public class DataSourceConfiguration {
19 | @Value("${jdbc.driver}")
20 | private String jdbcDriver;
21 | @Value("${jdbc.url}")
22 | private String jdbcUrl;
23 | @Value("${jdbc.username}")
24 | private String jdbcUsername;
25 | @Value("${jdbc.password}")
26 | private String jdbcPassword;
27 |
28 | /**
29 | * 生成与spring-dao.xml对应的bean dataSource
30 | * @return
31 | * @throws PropertyVetoException
32 | */
33 | @Bean(name = "dataSource")
34 | public ComboPooledDataSource createDataSource() throws PropertyVetoException {
35 | // 生成datasource实例
36 | ComboPooledDataSource dataSource = new ComboPooledDataSource();
37 | // 跟配置文件一样设置以下信息
38 | // 驱动
39 | dataSource.setDriverClass(jdbcDriver);
40 | // 数据库连接URL
41 | dataSource.setJdbcUrl(jdbcUrl);
42 | // 设置用户名
43 | dataSource.setUser(DESUtil.getDecryptString(jdbcUsername));
44 | // 设置用户密码
45 | dataSource.setPassword(DESUtil.getDecryptString(jdbcPassword));
46 | // 配置c3p0连接池的私有属性
47 | // 连接池最大线程数
48 | dataSource.setMaxPoolSize(30);
49 | // 连接池最小线程数
50 | dataSource.setMinPoolSize(10);
51 | dataSource.setInitialPoolSize(10);
52 | // 关闭连接后不自动commit
53 | dataSource.setAutoCommitOnClose(false);
54 | // 连接超时时间
55 | dataSource.setCheckoutTimeout(10000);
56 | // 连接失败重试次数
57 | dataSource.setAcquireRetryAttempts(2);
58 | return dataSource;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/config/mapper/SessionFactoryConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.config.mapper;
2 |
3 | import org.mybatis.spring.SqlSessionFactoryBean;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.core.io.ClassPathResource;
8 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
9 | import org.springframework.core.io.support.ResourcePatternResolver;
10 |
11 | import javax.annotation.Resource;
12 | import javax.sql.DataSource;
13 | import java.io.IOException;
14 |
15 | /**
16 | * @Author: Mr_OO
17 | * @Date: 2022/3/1 13:34
18 | */
19 | @Configuration
20 | public class SessionFactoryConfiguration {
21 |
22 | /**
23 | * mybatis-config.xml配置文件的路径
24 | */
25 | private static String mybatisConfigFile;
26 |
27 | @Value("${mybatis_config_file}")
28 | public void setMybatisConfigFile(String mybatisConfigFile) {
29 | SessionFactoryConfiguration.mybatisConfigFile = mybatisConfigFile;
30 | }
31 |
32 | /**
33 | * mybatis mapper文件所在路径
34 | */
35 | private static String mapperPath;
36 |
37 | @Value("${mybatis.mapper-locations}")
38 | public void setMapperPath(String mapperPath) {
39 | SessionFactoryConfiguration.mapperPath = mapperPath;
40 | }
41 |
42 |
43 | /**
44 | * 实体类所在的package
45 | */
46 | @Value("${type_alias_package}")
47 | private String typeAliasPackage;
48 |
49 | @Resource
50 | private DataSource dataSource;
51 |
52 | /**
53 | * 创建sqlSessionFactoryBean实例,并且设置configuration,设置mapper映射路径,设置datasource数据源
54 | * @return
55 | * @throws IOException
56 | */
57 | @Bean(name = "sqlSessionFactory")
58 | public SqlSessionFactoryBean createSqlSessionFactoryBean() throws IOException {
59 | SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
60 | // 设置mybatis configuration 扫描路径
61 | sqlSessionFactoryBean.setConfigLocation(new ClassPathResource(mybatisConfigFile));
62 | // 添加mapper 扫描路径
63 | PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
64 | String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + mapperPath;
65 | sqlSessionFactoryBean.setMapperLocations(pathMatchingResourcePatternResolver.getResources(packageSearchPath));
66 | // 设置dataSource
67 | sqlSessionFactoryBean.setDataSource(dataSource);
68 | // 设置typeAlias 包扫描路径
69 | sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasPackage);
70 | return sqlSessionFactoryBean;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/config/redis/JedisPoolFactory.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.config.redis;
2 |
3 | import redis.clients.jedis.JedisPool;
4 | import redis.clients.jedis.JedisPoolConfig;
5 |
6 | /**
7 | * 生产jedis连接池
8 | * @Author: Mr_OO
9 | * @Date: 2022/3/3 14:17
10 | */
11 | public class JedisPoolFactory {
12 | /** Redis连接池对象 */
13 | private JedisPool jedisPool;
14 |
15 | public JedisPoolFactory(final JedisPoolConfig poolConfig, final String host, final int port) {
16 | try {
17 | jedisPool = new JedisPool(poolConfig, host, port);
18 | } catch (Exception e) {
19 | e.printStackTrace();
20 | }
21 | }
22 |
23 | /**
24 | * 获取Redis连接池对象
25 | * @return
26 | */
27 | public JedisPool getJedisPool() {
28 | return jedisPool;
29 | }
30 |
31 | /**
32 | * 注入Redis连接池对象
33 | * @param jedisPool
34 | */
35 | public void setJedisPool(JedisPool jedisPool) {
36 | this.jedisPool = jedisPool;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/config/redis/JedisUtil.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.config.redis;
2 |
3 | import redis.clients.jedis.BinaryClient;
4 | import redis.clients.jedis.Jedis;
5 | import redis.clients.jedis.JedisPool;
6 | import redis.clients.jedis.SortingParams;
7 | import redis.clients.util.SafeEncoder;
8 |
9 | import java.util.List;
10 | import java.util.Map;
11 | import java.util.Set;
12 |
13 | /**
14 | * Jedis工具类
15 | * @Author: Mr_OO
16 | * @Date: 2022/3/3 14:17
17 | */
18 | public class JedisUtil {
19 | /**
20 | * 缓存生存时间
21 | */
22 | private final int expire = 60000;
23 | /** 操作Key的方法 */
24 | public Keys KEYS;
25 | /** 对存储结构为String类型的操作 */
26 | public Strings STRINGS;
27 | /** 对存储结构为List类型的操作 */
28 | public Lists LISTS;
29 | /** 对存储结构为Set类型的操作 */
30 | public Sets SETS;
31 | /** 对存储结构为HashMap类型的操作 */
32 | public Hash HASH;
33 |
34 | /** Redis连接池对象 */
35 | private JedisPool jedisPool;
36 |
37 | /**
38 | * 获取redis连接池
39 | *
40 | * @return
41 | */
42 | public JedisPool getJedisPool() {
43 | return jedisPool;
44 | }
45 |
46 | /**
47 | * 设置redis连接池
48 | *
49 | * @return
50 | */
51 | public void setJedisPool(JedisPoolFactory jedisPoolFactory) {
52 | this.jedisPool = jedisPoolFactory.getJedisPool();
53 | }
54 |
55 | /**
56 | * 从jedis连接池中获取获取jedis对象
57 | *
58 | * @return
59 | */
60 | public Jedis getJedis() {
61 | return jedisPool.getResource();
62 | }
63 |
64 | /**
65 | * 设置过期时间
66 | * @param key
67 | * @param seconds
68 | */
69 | public void expire(String key, int seconds) {
70 | if (seconds <= 0) {
71 | return;
72 | }
73 | Jedis jedis = getJedis();
74 | jedis.expire(key, seconds);
75 | jedis.close();
76 | }
77 |
78 | /**
79 | * 设置默认过期时间
80 | * @param key
81 | */
82 | public void expire(String key) {
83 | expire(key, expire);
84 | }
85 |
86 | // *******************************************Keys*******************************************//
87 | public class Keys {
88 |
89 | public Keys(JedisUtil jedisUtil) {
90 | }
91 |
92 | public Keys() {}
93 |
94 | /**
95 | * 清空所有key
96 | */
97 | public String flushAll() {
98 | Jedis jedis = getJedis();
99 | String state = jedis.flushAll();
100 | jedis.close();
101 | return state;
102 | }
103 |
104 | /**
105 | * 更改key
106 | * @param oldKey
107 | * @param newKey
108 | * @return 状态码
109 | */
110 | public String rename(String oldKey, String newKey) {
111 | return rename(SafeEncoder.encode(oldKey), SafeEncoder.encode(newKey));
112 | }
113 |
114 | /**
115 | * 更改key,仅当新key不存在时才执行
116 | * @param oldKey
117 | * @param newKey
118 | * @return 状态码
119 | */
120 | public long renamenx(String oldKey, String newKey) {
121 | Jedis jedis = getJedis();
122 | long status = jedis.renamenx(oldKey, newKey);
123 | jedis.close();
124 | return status;
125 | }
126 |
127 | /**
128 | * 更改key
129 | * @param oldkey
130 | * @param newkey
131 | * @return 状态码
132 | */
133 | public String rename(byte[] oldkey, byte[] newkey) {
134 | Jedis jedis = getJedis();
135 | String status = jedis.rename(oldkey, newkey);
136 | jedis.close();
137 | return status;
138 | }
139 |
140 | /**
141 | * 设置key的过期时间,以秒为单位
142 | * @param key
143 | * @param seconds
144 | * 时间 ,已秒为单位
145 | * @return 影响的记录数
146 | */
147 | public long expired(String key, int seconds) {
148 | Jedis jedis = getJedis();
149 | long count = jedis.expire(key, seconds);
150 | jedis.close();
151 | return count;
152 | }
153 |
154 | /**
155 | * 设置key的过期时间,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00,格里高利历)的偏移量。
156 | * @param key
157 | *
158 | * @param timestamp
159 | * 时间 ,已秒为单位
160 | * @return 影响的记录数
161 | */
162 | public long expireAt(String key, long timestamp) {
163 | Jedis jedis = getJedis();
164 | long count = jedis.expireAt(key, timestamp);
165 | jedis.close();
166 | return count;
167 | }
168 |
169 | /**
170 | * 查询key的过期时间
171 | *
172 | * @param key
173 | * @return 以秒为单位的时间表示
174 | */
175 | public long ttl(String key) {
176 | // ShardedJedis sjedis = getShardedJedis();
177 | Jedis sjedis = getJedis();
178 | long len = sjedis.ttl(key);
179 | sjedis.close();
180 | return len;
181 | }
182 |
183 | /**
184 | * 取消对key过期时间的设置
185 | *
186 | * @param key
187 | * @return 影响的记录数
188 | */
189 | public long persist(String key) {
190 | Jedis jedis = getJedis();
191 | long count = jedis.persist(key);
192 | jedis.close();
193 | return count;
194 | }
195 |
196 | /**
197 | * 删除keys对应的记录,可以是多个key
198 | * @param keys
199 | * @return 删除的记录数
200 | */
201 | public long del(String... keys) {
202 | Jedis jedis = getJedis();
203 | long count = jedis.del(keys);
204 | jedis.close();
205 | return count;
206 | }
207 |
208 | /**
209 | * 删除keys对应的记录,可以是多个key
210 | * @param keys
211 | * @return 删除的记录数
212 | */
213 | public long del(byte[]... keys) {
214 | Jedis jedis = getJedis();
215 | long count = jedis.del(keys);
216 | jedis.close();
217 | return count;
218 | }
219 |
220 | /**
221 | * 判断key是否存在
222 | *
223 | * @param key
224 | * @return boolean
225 | */
226 | public boolean exists(String key) {
227 | // ShardedJedis sjedis = getShardedJedis();
228 | Jedis sjedis = getJedis();
229 | boolean exis = sjedis.exists(key);
230 | sjedis.close();
231 | return exis;
232 | }
233 |
234 | /**
235 | * 对List,Set,SortSet进行排序,如果集合数据较大应避免使用这个方法
236 | * @param key
237 | * @return List 集合的全部记录
238 | **/
239 | public List sort(String key) {
240 | // ShardedJedis sjedis = getShardedJedis();
241 | Jedis sjedis = getJedis();
242 | List list = sjedis.sort(key);
243 | sjedis.close();
244 | return list;
245 | }
246 |
247 | /**
248 | * 对List,Set,SortSet进行排序或limit
249 | * @param key
250 | * @param parame
251 | * 定义排序类型或limit的起止位置.
252 | * @return List 全部或部分记录
253 | **/
254 | public List sort(String key, SortingParams parame) {
255 | // ShardedJedis sjedis = getShardedJedis();
256 | Jedis sjedis = getJedis();
257 | List list = sjedis.sort(key, parame);
258 | sjedis.close();
259 | return list;
260 | }
261 |
262 | /**
263 | * 返回指定key存储的类型
264 | * @param key
265 | * @return String string|list|set|zset|hash
266 | **/
267 | public String type(String key) {
268 | // ShardedJedis sjedis = getShardedJedis();
269 | Jedis sjedis = getJedis();
270 | String type = sjedis.type(key);
271 | sjedis.close();
272 | return type;
273 | }
274 |
275 | /**
276 | * 查找所有匹配给定的模式的键
277 | * @param pattern
278 | * key的表达式,*表示多个,?表示一个
279 | */
280 | public Set keys(String pattern) {
281 | Jedis jedis = getJedis();
282 | Set set = jedis.keys(pattern);
283 | jedis.close();
284 | return set;
285 | }
286 | }
287 |
288 | // *******************************************Strings*******************************************//
289 | public class Strings {
290 | public Strings(JedisUtil jedisUtil) {}
291 |
292 | public Strings() {}
293 |
294 | /**
295 | * 根据key获取记录
296 | * @param key
297 | * @return
298 | */
299 | public String get(String key) {
300 | // ShardedJedis sjedis = getShardedJedis();
301 | Jedis sjedis = getJedis();
302 | String value = sjedis.get(key);
303 | sjedis.close();
304 | return value;
305 | }
306 |
307 | /**
308 | * 根据key获取记录
309 | * @param key
310 | * @return
311 | */
312 | public byte[] get(byte[] key) {
313 | // ShardedJedis sjedis = getShardedJedis();
314 | Jedis sjedis = getJedis();
315 | byte[] value = sjedis.get(key);
316 | sjedis.close();
317 | return value;
318 | }
319 |
320 | /**
321 | * 添加记录,如果记录已存在将覆盖原有的value
322 | * @param key
323 | * @param value
324 | * @return 状态码
325 | */
326 | public String set(String key, String value) {
327 | return set(SafeEncoder.encode(key), SafeEncoder.encode(value));
328 | }
329 |
330 | /**
331 | * 添加记录,如果记录已存在将覆盖原有的value
332 | *
333 | * @param key
334 | * @param value
335 | * @return 状态码
336 | */
337 | public String set(String key, byte[] value) {
338 | return set(SafeEncoder.encode(key), value);
339 | }
340 |
341 | /**
342 | * 添加记录,如果记录已存在将覆盖原有的value
343 | *
344 | * @param key
345 | * @param value
346 | * @return 状态码
347 | */
348 | public String set(byte[] key, byte[] value) {
349 | Jedis jedis = getJedis();
350 | String status = jedis.set(key, value);
351 | jedis.close();
352 | return status;
353 | }
354 |
355 | /**
356 | * 添加有过期时间的记录
357 | * @param key
358 | * @param seconds 过期时间,以秒为单位
359 | * @param value
360 | * @return String 操作状态
361 | */
362 | public String setEx(String key, int seconds, String value) {
363 | Jedis jedis = getJedis();
364 | String str = jedis.setex(key, seconds, value);
365 | jedis.close();
366 | return str;
367 | }
368 |
369 | /**
370 | * 添加有过期时间的记录
371 | *
372 | * @param key
373 | * @param seconds 过期时间,以秒为单位
374 | * @param value
375 | * @return String 操作状态
376 | */
377 | public String setEx(byte[] key, int seconds, byte[] value) {
378 | Jedis jedis = getJedis();
379 | String str = jedis.setex(key, seconds, value);
380 | jedis.close();
381 | return str;
382 | }
383 |
384 | /**
385 | * 添加一条记录,仅当给定的key不存在时才插入
386 | * @param key
387 | * @param value
388 | * @return long 状态码,1插入成功且key不存在,0未插入,key存在
389 | */
390 | public long setnx(String key, String value) {
391 | Jedis jedis = getJedis();
392 | long str = jedis.setnx(key, value);
393 | jedis.close();
394 | return str;
395 | }
396 |
397 | /**
398 | * 从指定位置开始插入数据,插入的数据会覆盖指定位置以后的数据
399 | * 例:String str1="123456789";
400 | * 对str1操作后setRange(key,4,0000),str1="123400009";
401 | *
402 | * @param key
403 | * @param offset
404 | * @param value
405 | * @return long value的长度
406 | */
407 | public long setRange(String key, long offset, String value) {
408 | Jedis jedis = getJedis();
409 | long len = jedis.setrange(key, offset, value);
410 | jedis.close();
411 | return len;
412 | }
413 |
414 | /**
415 | * 在指定的key中追加value
416 | *
417 | * @param key
418 | * @param value
419 | * @return long 追加后value的长度
420 | **/
421 | public long append(String key, String value) {
422 | Jedis jedis = getJedis();
423 | long len = jedis.append(key, value);
424 | jedis.close();
425 | return len;
426 | }
427 |
428 | /**
429 | * 将key对应的value减去指定的值,只有value可以转为数字时该方法才可用
430 | *
431 | * @param key
432 | * @param number 要减去的值
433 | * @return long 减指定值后的值
434 | */
435 | public long decrBy(String key, long number) {
436 | Jedis jedis = getJedis();
437 | long len = jedis.decrBy(key, number);
438 | jedis.close();
439 | return len;
440 | }
441 |
442 | /**
443 | * 可以作为获取唯一id的方法
444 | * 将key对应的value加上指定的值,只有value可以转为数字时该方法才可用
445 | * @param key
446 | * @param number 要减去的值
447 | * @return long 相加后的值
448 | */
449 | public long incrBy(String key, long number) {
450 | Jedis jedis = getJedis();
451 | long len = jedis.incrBy(key, number);
452 | jedis.close();
453 | return len;
454 | }
455 |
456 | /**
457 | * 对指定key对应的value进行截取
458 | *
459 | * @param key
460 | * @param startOffset 开始位置(包含)
461 | * @param endOffset 结束位置(包含)
462 | * @return String 截取的值
463 | */
464 | public String getrange(String key, long startOffset, long endOffset) {
465 | // ShardedJedis sjedis = getShardedJedis();
466 | Jedis sjedis = getJedis();
467 | String value = sjedis.getrange(key, startOffset, endOffset);
468 | sjedis.close();
469 | return value;
470 | }
471 |
472 | /**
473 | * 获取并设置指定key对应的value
474 | * 如果key存在返回之前的value,否则返回null
475 | *
476 | * @param key
477 | * @param value
478 | * @return String 原始value或null
479 | */
480 | public String getSet(String key, String value) {
481 | Jedis jedis = getJedis();
482 | String str = jedis.getSet(key, value);
483 | jedis.close();
484 | return str;
485 | }
486 |
487 | /**
488 | * 批量获取记录,如果指定的key不存在返回List的对应位置将是null
489 | * @param keys
490 | * @return List 值得集合
491 | */
492 | public List mget(String... keys) {
493 | Jedis jedis = getJedis();
494 | List str = jedis.mget(keys);
495 | jedis.close();
496 | return str;
497 | }
498 |
499 | /**
500 | * 批量存储记录
501 | *
502 | * @param keysvalues 例:keysvalues="key1","value1","key2","value2";
503 | * @return String 状态码
504 | */
505 | public String mset(String... keysvalues) {
506 | Jedis jedis = getJedis();
507 | String str = jedis.mset(keysvalues);
508 | jedis.close();
509 | return str;
510 | }
511 |
512 | /**
513 | * 获取key对应的值的长度
514 | *
515 | * @param key
516 | * @return value值得长度
517 | */
518 | public long strlen(String key) {
519 | Jedis jedis = getJedis();
520 | long len = jedis.strlen(key);
521 | jedis.close();
522 | return len;
523 | }
524 | }
525 |
526 | // *******************************************Sets*******************************************//
527 | public class Sets {
528 |
529 | /**
530 | * 向Set添加一条记录,如果member已存在返回0,否则返回1
531 | *
532 | * @param key
533 | * @param member
534 | * @return 操作码,0或1
535 | */
536 | public long sadd(String key, String member) {
537 | Jedis jedis = getJedis();
538 | long s = jedis.sadd(key, member);
539 | jedis.close();
540 | return s;
541 | }
542 |
543 | public long sadd(byte[] key, byte[] member) {
544 | Jedis jedis = getJedis();
545 | long s = jedis.sadd(key, member);
546 | jedis.close();
547 | return s;
548 | }
549 |
550 | /**
551 | * 获取给定key中元素个数
552 | * @param key
553 | * @return 元素个数
554 | */
555 | public long scard(String key) {
556 | // ShardedJedis sjedis = getShardedJedis();
557 | Jedis sjedis = getJedis();
558 | long len = sjedis.scard(key);
559 | sjedis.close();
560 | return len;
561 | }
562 |
563 | /**
564 | * 返回从第一组和所有的给定集合之间的差异的成员
565 | *
566 | * @param keys
567 | * @return 差异的成员集合
568 | */
569 | public Set sdiff(String... keys) {
570 | Jedis jedis = getJedis();
571 | Set set = jedis.sdiff(keys);
572 | jedis.close();
573 | return set;
574 | }
575 |
576 | /**
577 | * 这个命令等于sdiff,但返回的不是结果集,而是将结果集存储在新的集合中,如果目标已存在,则覆盖。
578 | *
579 | * @param newkey 新结果集的key
580 | * @param keys 比较的集合
581 | * @return 新集合中的记录数
582 | **/
583 | public long sdiffstore(String newkey, String... keys) {
584 | Jedis jedis = getJedis();
585 | long s = jedis.sdiffstore(newkey, keys);
586 | jedis.close();
587 | return s;
588 | }
589 |
590 | /**
591 | * 返回给定集合交集的成员,如果其中一个集合为不存在或为空,则返回空Set
592 | *
593 | * @param keys
594 | * @return 交集成员的集合
595 | **/
596 | public Set sinter(String... keys) {
597 | Jedis jedis = getJedis();
598 | Set set = jedis.sinter(keys);
599 | jedis.close();
600 | return set;
601 | }
602 |
603 | /**
604 | * 这个命令等于sinter,但返回的不是结果集,而是将结果集存储在新的集合中,如果目标已存在,则覆盖。
605 | *
606 | * @param newkey 新结果集的key
607 | * @param keys 比较的集合
608 | * @return 新集合中的记录数
609 | **/
610 | public long sinterstore(String newkey, String... keys) {
611 | Jedis jedis = getJedis();
612 | long s = jedis.sinterstore(newkey, keys);
613 | jedis.close();
614 | return s;
615 | }
616 |
617 | /**
618 | * 确定一个给定的值是否存在
619 | *
620 | * @param key
621 | * @param member 要判断的值
622 | * @return 存在返回1,不存在返回0
623 | **/
624 | public boolean sismember(String key, String member) {
625 | // ShardedJedis sjedis = getShardedJedis();
626 | Jedis sjedis = getJedis();
627 | boolean s = sjedis.sismember(key, member);
628 | sjedis.close();
629 | return s;
630 | }
631 |
632 | /**
633 | * 返回集合中的所有成员
634 | * @param key
635 | * @return 成员集合
636 | */
637 | public Set smembers(String key) {
638 | // ShardedJedis sjedis = getShardedJedis();
639 | Jedis sjedis = getJedis();
640 | Set set = sjedis.smembers(key);
641 | sjedis.close();
642 | return set;
643 | }
644 |
645 | public Set smembers(byte[] key) {
646 | // ShardedJedis sjedis = getShardedJedis();
647 | Jedis sjedis = getJedis();
648 | Set set = sjedis.smembers(key);
649 | sjedis.close();
650 | return set;
651 | }
652 |
653 | /**
654 | * 将成员从源集合移出放入目标集合
655 | * 如果源集合不存在或不包哈指定成员,不进行任何操作,返回0
656 | * 否则该成员从源集合上删除,并添加到目标集合,如果目标集合中成员已存在,则只在源集合进行删除
657 | *
658 | * @param srckey 源集合
659 | * @param dstkey 目标集合
660 | * @param member 源集合中的成员
661 | * @return 状态码,1成功,0失败
662 | */
663 | public long smove(String srckey, String dstkey, String member) {
664 | Jedis jedis = getJedis();
665 | long s = jedis.smove(srckey, dstkey, member);
666 | jedis.close();
667 | return s;
668 | }
669 |
670 | /**
671 | * 从集合中删除成员
672 | *
673 | * @param key
674 | * @return 被删除的成员
675 | */
676 | public String spop(String key) {
677 | Jedis jedis = getJedis();
678 | String s = jedis.spop(key);
679 | jedis.close();
680 | return s;
681 | }
682 |
683 | /**
684 | * 从集合中删除指定成员
685 | *
686 | * @param key
687 | * @param member 要删除的成员
688 | * @return 状态码,成功返回1,成员不存在返回0
689 | */
690 | public long srem(String key, String member) {
691 | Jedis jedis = getJedis();
692 | long s = jedis.srem(key, member);
693 | jedis.close();
694 | return s;
695 | }
696 |
697 | /**
698 | * 合并多个集合并返回合并后的结果,合并后的结果集合并不保存
699 | *
700 | * @param keys
701 | * @return 合并后的结果集合
702 | */
703 | public Set sunion(String... keys) {
704 | Jedis jedis = getJedis();
705 | Set set = jedis.sunion(keys);
706 | jedis.close();
707 | return set;
708 | }
709 |
710 | /**
711 | * 合并多个集合并将合并后的结果集保存在指定的新集合中,如果新集合已经存在则覆盖
712 | *
713 | * @param newkey 新集合的key
714 | * @param keys 要合并的集合
715 | **/
716 | public long sunionstore(String newkey, String... keys) {
717 | Jedis jedis = getJedis();
718 | long s = jedis.sunionstore(newkey, keys);
719 | jedis.close();
720 | return s;
721 | }
722 | }
723 |
724 | // *******************************************Hash*******************************************//
725 | public class Hash {
726 |
727 | /**
728 | * 从hash中删除指定的存储
729 | *
730 | * @param key
731 | * @param fieid 存储的名字
732 | * @return 状态码,1成功,0失败
733 | */
734 | public long hdel(String key, String fieid) {
735 | Jedis jedis = getJedis();
736 | long s = jedis.hdel(key, fieid);
737 | jedis.close();
738 | return s;
739 | }
740 |
741 | public long hdel(String key) {
742 | Jedis jedis = getJedis();
743 | long s = jedis.del(key);
744 | jedis.close();
745 | return s;
746 | }
747 |
748 | /**
749 | * 测试hash中指定的存储是否存在
750 | *
751 | * @param key
752 | * @param fieid 存储的名字
753 | * @return 1存在,0不存在
754 | */
755 | public boolean hexists(String key, String fieid) {
756 | // ShardedJedis sjedis = getShardedJedis();
757 | Jedis sjedis = getJedis();
758 | boolean s = sjedis.hexists(key, fieid);
759 | sjedis.close();
760 | return s;
761 | }
762 |
763 | /**
764 | * 返回hash中指定存储位置的值
765 | *
766 | * @param key
767 | * @param fieid 存储的名字
768 | * @return 存储对应的值
769 | */
770 | public String hget(String key, String fieid) {
771 | // ShardedJedis sjedis = getShardedJedis();
772 | Jedis sjedis = getJedis();
773 | String s = sjedis.hget(key, fieid);
774 | sjedis.close();
775 | return s;
776 | }
777 |
778 | public byte[] hget(byte[] key, byte[] fieid) {
779 | // ShardedJedis sjedis = getShardedJedis();
780 | Jedis sjedis = getJedis();
781 | byte[] s = sjedis.hget(key, fieid);
782 | sjedis.close();
783 | return s;
784 | }
785 |
786 | /**
787 | * 以Map的形式返回hash中的存储和值
788 | *
789 | * @param key
790 | * @return Map
791 | */
792 | public Map hgetAll(String key) {
793 | // ShardedJedis sjedis = getShardedJedis();
794 | Jedis sjedis = getJedis();
795 | Map map = sjedis.hgetAll(key);
796 | sjedis.close();
797 | return map;
798 | }
799 |
800 | /**
801 | * 添加一个对应关系
802 | * @param key
803 | * @param fieid
804 | * @param value
805 | * @return 状态码 1成功,0失败,fieid已存在将更新,也返回0
806 | **/
807 | public long hset(String key, String fieid, String value) {
808 | Jedis jedis = getJedis();
809 | long s = jedis.hset(key, fieid, value);
810 | jedis.close();
811 | return s;
812 | }
813 |
814 | public long hset(String key, String fieid, byte[] value) {
815 | Jedis jedis = getJedis();
816 | long s = jedis.hset(key.getBytes(), fieid.getBytes(), value);
817 | jedis.close();
818 | return s;
819 | }
820 |
821 | /**
822 | * 添加对应关系,只有在fieid不存在时才执行
823 | *
824 | * @param key
825 | * @param fieid
826 | * @param value
827 | * @return 状态码 1成功,0失败fieid已存
828 | **/
829 | public long hsetnx(String key, String fieid, String value) {
830 | Jedis jedis = getJedis();
831 | long s = jedis.hsetnx(key, fieid, value);
832 | jedis.close();
833 | return s;
834 | }
835 |
836 | /**
837 | * 获取hash中value的集合
838 | *
839 | * @param key
840 | * @return List
841 | */
842 | public List hvals(String key) {
843 | // ShardedJedis sjedis = getShardedJedis();
844 | Jedis sjedis = getJedis();
845 | List list = sjedis.hvals(key);
846 | sjedis.close();
847 | return list;
848 | }
849 |
850 | /**
851 | * 在指定的存储位置加上指定的数字,存储位置的值必须可转为数字类型
852 | *
853 | * @param key
854 | * @param fieid 存储位置
855 | * @param value 要增加的值,可以是负数
856 | * @return 增加指定数字后,存储位置的值
857 | */
858 | public long hincrby(String key, String fieid, long value) {
859 | Jedis jedis = getJedis();
860 | long s = jedis.hincrBy(key, fieid, value);
861 | jedis.close();
862 | return s;
863 | }
864 |
865 | /**
866 | * 返回指定hash中的所有存储名字,类似Map中的keySet方法
867 | *
868 | * @param key
869 | * @return Set 存储名称的集合
870 | */
871 | public Set hkeys(String key) {
872 | // ShardedJedis sjedis = getShardedJedis();
873 | Jedis sjedis = getJedis();
874 | Set set = sjedis.hkeys(key);
875 | sjedis.close();
876 | return set;
877 | }
878 |
879 | /**
880 | * 获取hash中存储的个数,类似Map中size方法
881 | *
882 | * @param key
883 | * @return long 存储的个数
884 | */
885 | public long hlen(String key) {
886 | // ShardedJedis sjedis = getShardedJedis();
887 | Jedis sjedis = getJedis();
888 | long len = sjedis.hlen(key);
889 | sjedis.close();
890 | return len;
891 | }
892 |
893 | /**
894 | * 根据多个key,获取对应的value,返回List,如果指定的key不存在,List对应位置为null
895 | *
896 | * @param key
897 | * @param fieids 存储位置
898 | * @return List
899 | */
900 | public List hmget(String key, String... fieids) {
901 | // ShardedJedis sjedis = getShardedJedis();
902 | Jedis sjedis = getJedis();
903 | List list = sjedis.hmget(key, fieids);
904 | sjedis.close();
905 | return list;
906 | }
907 |
908 | public List hmget(byte[] key, byte[]... fieids) {
909 | // ShardedJedis sjedis = getShardedJedis();
910 | Jedis sjedis = getJedis();
911 | List list = sjedis.hmget(key, fieids);
912 | sjedis.close();
913 | return list;
914 | }
915 |
916 | /**
917 | * 添加对应关系,如果对应关系已存在,则覆盖
918 | *
919 | * @param key
920 | * @param map 对应关系
921 | * @return 状态,成功返回OK
922 | */
923 | public String hmset(String key, Map map) {
924 | Jedis jedis = getJedis();
925 | String s = jedis.hmset(key, map);
926 | jedis.close();
927 | return s;
928 | }
929 |
930 | /**
931 | * 添加对应关系,如果对应关系已存在,则覆盖
932 | *
933 | * @param key
934 | * @param map 对应关系
935 | * @return 状态,成功返回OK
936 | */
937 | public String hmset(byte[] key, Map map) {
938 | Jedis jedis = getJedis();
939 | String s = jedis.hmset(key, map);
940 | jedis.close();
941 | return s;
942 | }
943 |
944 | }
945 |
946 | // *******************************************Lists*******************************************//
947 | public class Lists {
948 | /**
949 | * List长度
950 | *
951 | * @param key
952 | * @return 长度
953 | */
954 | public long llen(String key) {
955 | return llen(SafeEncoder.encode(key));
956 | }
957 |
958 | /**
959 | * List长度
960 | *
961 | * @param key
962 | * @return 长度
963 | */
964 | public long llen(byte[] key) {
965 | // ShardedJedis sjedis = getShardedJedis();
966 | Jedis sjedis = getJedis();
967 | long count = sjedis.llen(key);
968 | sjedis.close();
969 | return count;
970 | }
971 |
972 | /**
973 | * 覆盖操作,将覆盖List中指定位置的值
974 | *
975 | * @param key
976 | * @param index 位置
977 | * @param value 值
978 | * @return 状态码
979 | */
980 | public String lset(byte[] key, int index, byte[] value) {
981 | Jedis jedis = getJedis();
982 | String status = jedis.lset(key, index, value);
983 | jedis.close();
984 | return status;
985 | }
986 |
987 | /**
988 | * 覆盖操作,将覆盖List中指定位置的值
989 | *
990 | * @param key
991 | * @param index 位置
992 | * @param value 值
993 | * @return 状态码
994 | */
995 | public String lset(String key, int index, String value) {
996 | return lset(SafeEncoder.encode(key), index, SafeEncoder.encode(value));
997 | }
998 |
999 | /**
1000 | * 在value的相对位置插入记录
1001 | *
1002 | * @param key
1003 | * @param where 前面插入或后面插入
1004 | * @param pivot 相对位置的内容
1005 | * @param value 插入的内容
1006 | * @return 记录总数
1007 | */
1008 | public long linsert(String key, BinaryClient.LIST_POSITION where, String pivot, String value) {
1009 | return linsert(SafeEncoder.encode(key), where, SafeEncoder.encode(pivot), SafeEncoder.encode(value));
1010 | }
1011 |
1012 | /**
1013 | * 在指定位置插入记录
1014 | * @param key
1015 | * @param where 前面插入或后面插入
1016 | * @param pivot 相对位置的内容
1017 | * @param value 插入的内容
1018 | * @return 记录总数
1019 | */
1020 | public long linsert(byte[] key, BinaryClient.LIST_POSITION where, byte[] pivot, byte[] value) {
1021 | Jedis jedis = getJedis();
1022 | long count = jedis.linsert(key, where, pivot, value);
1023 | jedis.close();
1024 | return count;
1025 | }
1026 |
1027 | /**
1028 | * 获取List中指定位置的值
1029 | *
1030 | * @param key
1031 | * @param index 位置
1032 | * @return 值
1033 | **/
1034 | public String lindex(String key, int index) {
1035 | return SafeEncoder.encode(lindex(SafeEncoder.encode(key), index));
1036 | }
1037 |
1038 | /**
1039 | * 获取List中指定位置的值
1040 | *
1041 | * @param key
1042 | * @param index 位置
1043 | * @return 值
1044 | **/
1045 | public byte[] lindex(byte[] key, int index) {
1046 | // ShardedJedis sjedis = getShardedJedis();
1047 | Jedis sjedis = getJedis();
1048 | byte[] value = sjedis.lindex(key, index);
1049 | sjedis.close();
1050 | return value;
1051 | }
1052 |
1053 | /**
1054 | * 将List中的第一条记录移出List
1055 | * @param key
1056 | * @return 移出的记录
1057 | */
1058 | public String lpop(String key) {
1059 | return SafeEncoder.encode(lpop(SafeEncoder.encode(key)));
1060 | }
1061 |
1062 | /**
1063 | * 将List中的第一条记录移出List
1064 | *
1065 | * @param key
1066 | * @return 移出的记录
1067 | */
1068 | public byte[] lpop(byte[] key) {
1069 | Jedis jedis = getJedis();
1070 | byte[] value = jedis.lpop(key);
1071 | jedis.close();
1072 | return value;
1073 | }
1074 |
1075 | /**
1076 | * 将List中最后第一条记录移出List
1077 | *
1078 | * @param key
1079 | * @return 移出的记录
1080 | */
1081 | public String rpop(String key) {
1082 | Jedis jedis = getJedis();
1083 | String value = jedis.rpop(key);
1084 | jedis.close();
1085 | return value;
1086 | }
1087 |
1088 | /**
1089 | * 向List尾部追加记录
1090 | *
1091 | * @param key
1092 | * @param value
1093 | * @return 记录总数
1094 | */
1095 | public long lpush(String key, String value) {
1096 | return lpush(SafeEncoder.encode(key), SafeEncoder.encode(value));
1097 | }
1098 |
1099 | /**
1100 | * 向List头部追加记录
1101 | *
1102 | * @param key
1103 | * @param value
1104 | * @return 记录总数
1105 | */
1106 | public long rpush(String key, String value) {
1107 | Jedis jedis = getJedis();
1108 | long count = jedis.rpush(key, value);
1109 | jedis.close();
1110 | return count;
1111 | }
1112 |
1113 | /**
1114 | * 向List头部追加记录
1115 | *
1116 | * @param key
1117 | * @param value
1118 | * @return 记录总数
1119 | */
1120 | public long rpush(byte[] key, byte[] value) {
1121 | Jedis jedis = getJedis();
1122 | long count = jedis.rpush(key, value);
1123 | jedis.close();
1124 | return count;
1125 | }
1126 |
1127 | /**
1128 | * 向List中追加记录
1129 | *
1130 | * @param key
1131 | * @param value
1132 | * @return 记录总数
1133 | */
1134 | public long lpush(byte[] key, byte[] value) {
1135 | Jedis jedis = getJedis();
1136 | long count = jedis.lpush(key, value);
1137 | jedis.close();
1138 | return count;
1139 | }
1140 |
1141 | /**
1142 | * 获取指定范围的记录,可以做为分页使用
1143 | * @param key
1144 | * @param start
1145 | * @param end
1146 | * @return List
1147 | */
1148 | public List lrange(String key, long start, long end) {
1149 | // ShardedJedis sjedis = getShardedJedis();
1150 | Jedis sjedis = getJedis();
1151 | List list = sjedis.lrange(key, start, end);
1152 | sjedis.close();
1153 | return list;
1154 | }
1155 |
1156 | /**
1157 | * 获取指定范围的记录,可以做为分页使用
1158 | *
1159 | * @param key
1160 | * @param start
1161 | * @param end 如果为负数,则尾部开始计算
1162 | * @return List
1163 | */
1164 | public List lrange(byte[] key, int start, int end) {
1165 | // ShardedJedis sjedis = getShardedJedis();
1166 | Jedis sjedis = getJedis();
1167 | List list = sjedis.lrange(key, start, end);
1168 | sjedis.close();
1169 | return list;
1170 | }
1171 |
1172 | /**
1173 | * 删除List中c条记录,被删除的记录值为value
1174 | *
1175 | * @param key
1176 | * @param c 要删除的数量,如果为负数则从List的尾部检查并删除符合的记录
1177 | * @param value 要匹配的值
1178 | * @return 删除后的List中的记录数
1179 | */
1180 | public long lrem(byte[] key, int c, byte[] value) {
1181 | Jedis jedis = getJedis();
1182 | long count = jedis.lrem(key, c, value);
1183 | jedis.close();
1184 | return count;
1185 | }
1186 |
1187 | /**
1188 | * 删除List中c条记录,被删除的记录值为value
1189 | *
1190 | * @param key
1191 | * @param c 要删除的数量,如果为负数则从List的尾部检查并删除符合的记录
1192 | * @param value 要匹配的值
1193 | * @return 删除后的List中的记录数
1194 | */
1195 | public long lrem(String key, int c, String value) {
1196 | return lrem(SafeEncoder.encode(key), c, SafeEncoder.encode(value));
1197 | }
1198 |
1199 | /**
1200 | * 算是删除吧,只保留start与end之间的记录
1201 | *
1202 | * @param key
1203 | * @param start 记录的开始位置(0表示第一条记录)
1204 | * @param end 记录的结束位置(如果为-1则表示最后一个,-2,-3以此类推)
1205 | * @return 执行状态码
1206 | */
1207 | public String ltrim(byte[] key, int start, int end) {
1208 | Jedis jedis = getJedis();
1209 | String str = jedis.ltrim(key, start, end);
1210 | jedis.close();
1211 | return str;
1212 | }
1213 |
1214 | /**
1215 | * 算是删除吧,只保留start与end之间的记录
1216 | *
1217 | * @param key
1218 | * @param start 记录的开始位置(0表示第一条记录)
1219 | * @param end 记录的结束位置(如果为-1则表示最后一个,-2,-3以此类推)
1220 | * @return 执行状态码
1221 | */
1222 | public String ltrim(String key, int start, int end) {
1223 | return ltrim(SafeEncoder.encode(key), start, end);
1224 | }
1225 | }
1226 | }
1227 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/config/redis/RedisConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.config.redis;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import redis.clients.jedis.JedisPoolConfig;
7 |
8 | import javax.annotation.Resource;
9 |
10 | /**
11 | * @Author: Mr_OO
12 | * @Date: 2022/3/3 14:12
13 | */
14 | @Configuration
15 | public class RedisConfiguration {
16 | private String hostname = "127.0.0.1";
17 | private int port = 6379;
18 | private int maxTotal = 200;
19 | private int maxIdle = 50;
20 | private long maxWaitMillis = 3000;
21 | private boolean testOnBorrow = true;
22 |
23 | @Resource
24 | private JedisPoolConfig jedisPoolConfig;
25 | @Resource
26 | private JedisPoolFactory jedisPoolFactory;
27 | @Resource
28 | private JedisUtil jedisUtil;
29 |
30 | /**
31 | * 创建redis连接池的设置
32 | * @return
33 | */
34 | @Bean(name = "jedisPoolConfig")
35 | public JedisPoolConfig createJedisPoolConfig() {
36 | JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
37 | // 控制一个pool可分配多少个jedis实例
38 | jedisPoolConfig.setMaxTotal(maxTotal);
39 | // 连接池中最多可空闲maxIdle个连接 ,这里取值为20,
40 | // 表示即使没有数据库连接时依然可以保持20空闲的连接,
41 | // 而不被清除,随时处于待命状态。
42 | jedisPoolConfig.setMaxIdle(maxIdle);
43 | // 最大等待时间:当没有可用连接时,
44 | // 连接池等待连接被归还的最大时间(以毫秒计数),超过时间则抛出异常
45 | jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
46 | // 在获取连接的时候检查有效性
47 | jedisPoolConfig.setTestOnBorrow(testOnBorrow);
48 | return jedisPoolConfig;
49 | }
50 |
51 | /**
52 | * 创建Redis连接池,并做相关配置
53 | * @return
54 | */
55 | @Bean(name = "jedisWritePool")
56 | public JedisPoolFactory createJedisPoolWriper() {
57 | JedisPoolFactory jedisPoolWriper = new JedisPoolFactory(jedisPoolConfig, hostname, port);
58 | return jedisPoolWriper;
59 | }
60 |
61 | /**
62 | * 创建Redis工具类,封装好Redis的连接以进行相关的操作
63 | * @return
64 | */
65 | @Bean(name = "jedisUtil")
66 | public JedisUtil createJedisUtil() {
67 | JedisUtil jedisUtil = new JedisUtil();
68 | jedisUtil.setJedisPool(jedisPoolFactory);
69 | return jedisUtil;
70 | }
71 |
72 | /**
73 | * Redis的key操作
74 | * @return
75 | */
76 | @Bean(name = "jedisKeys")
77 | public JedisUtil.Keys createJedisKeys() {
78 | JedisUtil.Keys jedisKeys = jedisUtil.new Keys();
79 | return jedisKeys;
80 | }
81 |
82 | /**
83 | * Redis的Strings操作
84 | * @return
85 | */
86 | @Bean(name = "jedisStrings")
87 | public JedisUtil.Strings createJedisStrings() {
88 | JedisUtil.Strings jedisStrings = jedisUtil.new Strings( );
89 | return jedisStrings;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/config/service/TransactionManagementConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.config.service;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.jdbc.datasource.DataSourceTransactionManager;
5 | import org.springframework.transaction.TransactionManager;
6 | import org.springframework.transaction.annotation.EnableTransactionManagement;
7 | import org.springframework.transaction.annotation.TransactionManagementConfigurer;
8 |
9 | import javax.annotation.Resource;
10 | import javax.sql.DataSource;
11 |
12 | /**
13 | * @Author: Mr_OO
14 | * @Date: 2022/3/1 13:36
15 | */
16 | @Configuration
17 | @EnableTransactionManagement
18 | public class TransactionManagementConfiguration implements TransactionManagementConfigurer {
19 |
20 | /**
21 | * 注入DataSourceConfiguration里边的dataSource,通过createDataSource()获取
22 | */
23 | @Resource
24 | private DataSource dataSource;
25 |
26 | @Override
27 | public TransactionManager annotationDrivenTransactionManager() {
28 | return new DataSourceTransactionManager(dataSource);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/config/shiro/MySessionManager.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.config.shiro;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
5 | import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
6 | import org.apache.shiro.web.util.WebUtils;
7 |
8 | import javax.servlet.ServletRequest;
9 | import javax.servlet.ServletResponse;
10 | import java.io.Serializable;
11 |
12 | /**
13 | * 自定义session管理
14 | * 传统结构项目中,shiro从cookie中读取sessionId以此来维持会话,在前后端分离的项目中(也可在移动APP项目使用),
15 | * 我们选择在ajax的请求头中传递sessionId,因此需要重写shiro获取sessionId的方式
16 | * 自定义MySessionManager类继承 DefaultWebSessionManager类,重写getSessionId方法
17 | * @Author: Mr_OO
18 | * @Date: 2022/3/3 17:21
19 | */
20 | public class MySessionManager extends DefaultWebSessionManager {
21 |
22 | private static final String AUTHORIZATION = "userToken";
23 |
24 | private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
25 |
26 | @Override
27 | protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
28 | String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
29 | //如果请求头中有 userToken 则其值为 sessionId
30 | if (!StringUtils.isEmpty(id)) {
31 | request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);
32 | request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
33 | request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
34 | return id;
35 | } else {
36 | //否则按默认规则从cookie取sessionId
37 | return super.getSessionId(request, response);
38 | }
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/config/shiro/MyShiroRealm.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.config.shiro;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.oym.cms.dto.UserDTO;
5 | import com.oym.cms.entity.User;
6 | import com.oym.cms.enums.DTOMsgEnum;
7 | import com.oym.cms.mapper.JurisdictionMapper;
8 | import com.oym.cms.mapper.UserMapper;
9 | import org.apache.shiro.authc.AuthenticationException;
10 | import org.apache.shiro.authc.AuthenticationInfo;
11 | import org.apache.shiro.authc.AuthenticationToken;
12 | import org.apache.shiro.authc.SimpleAuthenticationInfo;
13 | import org.apache.shiro.authz.AuthorizationInfo;
14 | import org.apache.shiro.authz.SimpleAuthorizationInfo;
15 | import org.apache.shiro.realm.AuthorizingRealm;
16 | import org.apache.shiro.subject.PrincipalCollection;
17 | import org.apache.shiro.util.ByteSource;
18 |
19 | import javax.annotation.Resource;
20 | import java.util.*;
21 |
22 | /**
23 | * @Author: Mr_OO
24 | * @Date: 2022/3/3 17:21
25 | */
26 | public class MyShiroRealm extends AuthorizingRealm {
27 |
28 | @Resource
29 | private JurisdictionMapper jurisdictionMapper;
30 | @Resource
31 | private UserMapper userMapper;
32 |
33 | /**
34 | * 授权
35 | * @param principalCollection
36 | * @return
37 | */
38 | @Override
39 | protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
40 | SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
41 | //取出用户权限URL表数据
42 | List urlList = jurisdictionMapper.queryAllUrls();
43 | //授权
44 | for (String s : urlList) {
45 | authorizationInfo.addStringPermission(s);
46 | }
47 | return authorizationInfo;
48 | }
49 |
50 | /**
51 | * 身份认证
52 | *
53 | * @param token
54 | * @return
55 | * @throws AuthenticationException
56 | */
57 | @Override
58 | protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
59 |
60 | //获取用户的输入的账号.
61 | String userId = (String) token.getPrincipal();
62 | //通过userId从数据库中查找 User对象.
63 | User user = userMapper.queryUserById(userId);
64 | if (Objects.isNull(user)) {
65 | return null;
66 | }
67 | return new SimpleAuthenticationInfo(
68 | //传入对象(一定要是对象!!!getPrimaryPrincipal()要取得)
69 | user,
70 | //传入的是加密后的密码
71 | user.getUserPassword(),
72 | //传入salt
73 | ByteSource.Util.bytes(user.getUserId()),
74 | getName());
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/config/shiro/ShiroConfig.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.config.shiro;
2 |
3 | import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
4 | import org.apache.shiro.mgt.SecurityManager;
5 | import org.apache.shiro.session.mgt.SessionManager;
6 | import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
7 | import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
8 | import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
9 | import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
10 | import org.apache.shiro.web.servlet.SimpleCookie;
11 | import org.crazycake.shiro.RedisCacheManager;
12 | import org.crazycake.shiro.RedisManager;
13 | import org.crazycake.shiro.RedisSessionDAO;
14 | import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
15 | import org.springframework.context.annotation.Bean;
16 | import org.springframework.context.annotation.Configuration;
17 |
18 | import java.util.LinkedHashMap;
19 | import java.util.Map;
20 |
21 | /**
22 | * @Author: Mr_OO
23 | * @Date: 2022/3/3 17:25
24 | */
25 | @Configuration
26 | public class ShiroConfig {
27 |
28 | /**
29 | * Filter工厂,设置对应的过滤条件和跳转条件
30 | * @return ShiroFilterFactoryBean
31 | */
32 | @Bean
33 | public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
34 |
35 | ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
36 | shiroFilterFactoryBean.setSecurityManager(securityManager);
37 |
38 | // 过滤器链定义映射
39 | Map filterChainDefinitionMap = new LinkedHashMap<>();
40 | /*
41 | * anon:所有url都都可以匿名访问,authc:所有url都必须认证通过才可以访问;
42 | * 过滤链定义,从上向下顺序执行,authc 应放在 anon 下面
43 | */
44 | filterChainDefinitionMap.put("/user/login", "anon");
45 | filterChainDefinitionMap.put("/user/changeUserPassword", "anon");
46 | // 所有url都必须认证通过才可以访问
47 | filterChainDefinitionMap.put("/**", "authc");
48 | // 配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了, 位置放在 anon、authc下面
49 | filterChainDefinitionMap.put("/logout", "logout");
50 | // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
51 | // 配器shiro默认登录地址,前后端分离中登录累面跳转应由前端路由控制,后台仅返回json数据, 对应LoginController中unAuth请求
52 | shiroFilterFactoryBean.setLoginUrl("/user/login");
53 | // 未授权界面, 对应LoginController中 unauthorized 请求
54 | shiroFilterFactoryBean.setUnauthorizedUrl("/user/login");
55 | shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
56 | return shiroFilterFactoryBean;
57 | }
58 |
59 | /**
60 | * 凭证匹配器(由于我们的密码校验交给 Shiro的 SimpleAuthenticationInfo进行处理了)
61 | *
62 | * @return HashedCredentialsMatcher
63 | */
64 | @Bean
65 | public HashedCredentialsMatcher hashedCredentialsMatcher() {
66 | HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
67 | // 散列算法:这里使用MD5算法;
68 | hashedCredentialsMatcher.setHashAlgorithmName("md5");
69 | // 散列的次数,比如散列两次,相当于 md5(md5(""));
70 | hashedCredentialsMatcher.setHashIterations(20);
71 | hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
72 | return hashedCredentialsMatcher;
73 | }
74 |
75 | /**
76 | * 将自己的验证方式加入容器
77 | *
78 | * @return MyShiroRealm
79 | */
80 | @Bean
81 | public MyShiroRealm myShiroRealm() {
82 | MyShiroRealm myShiroRealm = new MyShiroRealm();
83 | myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
84 | return myShiroRealm;
85 | }
86 |
87 | /**
88 | * RedisSessionDAO shiro sessionDao层的实现 通过redis, 使用的是shiro-redis开源插件
89 | *
90 | * @return RedisSessionDAO
91 | */
92 | @Bean
93 | public RedisSessionDAO redisSessionDAO() {
94 | RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
95 | redisSessionDAO.setRedisManager(redisManager());
96 | redisSessionDAO.setSessionIdGenerator(sessionIdGenerator());
97 | redisSessionDAO.setExpire(1800);
98 | return redisSessionDAO;
99 | }
100 |
101 | /**
102 | * Session ID 生成器
103 | *
104 | * @return JavaUuidSessionIdGenerator
105 | */
106 | @Bean
107 | public JavaUuidSessionIdGenerator sessionIdGenerator() {
108 | return new JavaUuidSessionIdGenerator();
109 | }
110 |
111 | /**
112 | * 自定义sessionManager
113 | *
114 | * @return SessionManager
115 | */
116 | @Bean
117 | public SessionManager sessionManager() {
118 | MySessionManager mySessionManager = new MySessionManager();
119 | mySessionManager.setSessionDAO(redisSessionDAO());
120 | return mySessionManager;
121 | }
122 |
123 | private static final String HOST = "127.0.0.1:6379";
124 | private static final int TIMEOUT = 1800;
125 |
126 | /**
127 | * 配置shiro redisManager, 使用的是shiro-redis开源插件
128 | *
129 | * @return RedisManager
130 | */
131 | private RedisManager redisManager() {
132 | RedisManager redisManager = new RedisManager();
133 | redisManager.setHost(HOST);
134 | redisManager.setTimeout(TIMEOUT);
135 | return redisManager;
136 | }
137 |
138 | /**
139 | * cacheManager 缓存 redis实现, 使用的是shiro-redis开源插件
140 | *
141 | * @return RedisCacheManager
142 | */
143 | @Bean
144 | public RedisCacheManager cacheManager() {
145 | RedisCacheManager redisCacheManager = new RedisCacheManager();
146 | redisCacheManager.setRedisManager(redisManager());
147 | // 必须要设置主键名称,shiro-redis 插件用过这个缓存用户信息
148 | redisCacheManager.setPrincipalIdFieldName("userId");
149 | return redisCacheManager;
150 | }
151 |
152 | /**
153 | * description: 权限管理,配置主要是Realm的管理认证
154 | *
155 | * @return SecurityManager
156 | */
157 | @Bean
158 | public SecurityManager securityManager() {
159 | DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
160 | securityManager.setRealm(myShiroRealm());
161 | // 自定义session管理 使用redis
162 | securityManager.setSessionManager(sessionManager());
163 | // 自定义缓存实现 使用redis
164 | securityManager.setCacheManager(cacheManager());
165 | return securityManager;
166 | }
167 |
168 | /**
169 | * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
170 | * 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能
171 | * @return
172 | */
173 | @Bean
174 | public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
175 | DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
176 | advisorAutoProxyCreator.setProxyTargetClass(true);
177 | return advisorAutoProxyCreator;
178 | }
179 |
180 | @Bean
181 | public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
182 | AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
183 | authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
184 | return authorizationAttributeSourceAdvisor;
185 | }
186 |
187 | @Bean
188 | public SimpleCookie cookie() {
189 | // cookie的name,对应的默认是 JSESSIONID
190 | SimpleCookie cookie = new SimpleCookie("SHARE_JSESSIONID");
191 | cookie.setHttpOnly(true);
192 | // path为 / 用于多个系统共享 JSESSIONID
193 | cookie.setPath("/");
194 | return cookie;
195 | }
196 |
197 | }
198 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/config/web/MvcConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.config.web;
2 |
3 | import org.springframework.beans.BeansException;
4 | import org.springframework.boot.web.servlet.FilterRegistrationBean;
5 | import org.springframework.context.ApplicationContext;
6 | import org.springframework.context.ApplicationContextAware;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.http.HttpStatus;
10 | import org.springframework.web.multipart.commons.CommonsMultipartResolver;
11 | import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
12 | import org.springframework.web.servlet.config.annotation.EnableWebMvc;
13 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
14 |
15 | import javax.servlet.*;
16 | import javax.servlet.http.HttpServletRequest;
17 | import javax.servlet.http.HttpServletResponse;
18 | import java.io.IOException;
19 |
20 | /**
21 | * @Author: Mr_OO
22 | * @Date: 2022/3/1 13:37
23 | */
24 | @Configuration
25 | @EnableWebMvc
26 | public class MvcConfiguration implements WebMvcConfigurer, ApplicationContextAware {
27 |
28 | /**
29 | * Spring容器
30 | */
31 | private ApplicationContext applicationContext;
32 |
33 | @Override
34 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
35 | this.applicationContext = applicationContext;
36 | }
37 |
38 | /**
39 | * 定义默认的请求处理器
40 | * @param configurer
41 | */
42 | @Override
43 | public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
44 | configurer.enable();
45 | }
46 |
47 | /**
48 | * 跨域的过滤机制
49 | *
50 | * @return
51 | */
52 | @Bean
53 | public FilterRegistrationBean corsFilter() {
54 | return new FilterRegistrationBean(new Filter() {
55 | @Override
56 | public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
57 | throws IOException, ServletException {
58 | HttpServletRequest request = (HttpServletRequest) req;
59 | HttpServletResponse response = (HttpServletResponse) res;
60 | String method = request.getMethod();
61 | response.setHeader("Access-Control-Allow-Origin", "*");
62 | response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, OPTIONS");
63 | response.setHeader("Access-Control-Max-Age", "3600");
64 | response.setHeader("Access-Control-Allow-Credentials", "true");
65 | response.setHeader("Access-Control-Allow-Headers", "Accept, Origin, " +
66 | "X-Requested-With, Content-Type,Last-Modified,device,token,userToken");
67 | //检测是options方法则直接返回200,用于跳过预检机制
68 | if ("OPTIONS".equals(method)) {
69 | response.setStatus(HttpStatus.OK.value());
70 | } else {
71 | chain.doFilter(req, res);
72 | }
73 | }
74 |
75 | @Override
76 | public void init(FilterConfig filterConfig) {}
77 |
78 | @Override
79 | public void destroy() {}
80 | });
81 | }
82 |
83 | /**
84 | * 文件上传解析器
85 | * @return
86 | */
87 | @Bean(name = "multipartResolver")
88 | public CommonsMultipartResolver createMultipartResolver() {
89 | CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
90 | multipartResolver.setDefaultEncoding("utf-8");
91 | // 1024 * 1024 * 2 = 2M
92 | multipartResolver.setMaxUploadSize(5242880);
93 | multipartResolver.setMaxInMemorySize(5242880);
94 | return multipartResolver;
95 | }
96 |
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/controller/CertificateController.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.controller;
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper;
4 | import com.oym.cms.dto.CertificateDTO;
5 | import com.oym.cms.dto.ImageHolder;
6 | import com.oym.cms.entity.Certificate;
7 | import com.oym.cms.enums.CertificateTypeEnum;
8 | import com.oym.cms.enums.DTOMsgEnum;
9 | import com.oym.cms.exceptions.CertificateException;
10 | import com.oym.cms.service.CertificateService;
11 | import com.oym.cms.util.HttpServletRequestUtil;
12 | import org.apache.commons.lang3.StringUtils;
13 | import org.apache.shiro.authz.annotation.RequiresPermissions;
14 | import org.slf4j.Logger;
15 | import org.slf4j.LoggerFactory;
16 | import org.springframework.web.bind.annotation.CrossOrigin;
17 | import org.springframework.web.bind.annotation.PostMapping;
18 | import org.springframework.web.bind.annotation.RestController;
19 | import org.springframework.web.multipart.MultipartHttpServletRequest;
20 | import org.springframework.web.multipart.commons.CommonsMultipartFile;
21 | import org.springframework.web.multipart.commons.CommonsMultipartResolver;
22 |
23 | import javax.annotation.Resource;
24 | import javax.servlet.http.HttpServletRequest;
25 | import java.util.HashMap;
26 | import java.util.Map;
27 |
28 | /**
29 | * @Author: Mr_OO
30 | * @Date: 2022/3/6 11:04
31 | */
32 | @CrossOrigin
33 | @RestController
34 | public class CertificateController {
35 | @Resource
36 | private CertificateService certificateService;
37 |
38 | /**
39 | * UserController log
40 | */
41 | private static final Logger LOGGER = LoggerFactory.getLogger(CertificateController.class);
42 |
43 | /**
44 | * 存储新证书
45 | * @param request
46 | * @return
47 | */
48 | @PostMapping("/certificate/addNewOne")
49 | @RequiresPermissions("/certificate/addNewOne")
50 | public Map addNewOneCertificate(HttpServletRequest request) {
51 | Map modelMap = new HashMap<>(16);
52 | String certificateStr = HttpServletRequestUtil.getString(request,"certificate");
53 | LOGGER.info("CertificateController addNewOneCertificate certificate:{}", certificateStr);
54 | if (StringUtils.isEmpty(certificateStr)) {
55 | modelMap.put("success",false);
56 | modelMap.put("errMsg", DTOMsgEnum.EMPTY_INPUT_STR.getStatusInfo());
57 | LOGGER.error("CertificateController addNewOneCertificate empty certificate:{}", certificateStr);
58 | return modelMap;
59 | }
60 | ObjectMapper mapper = new ObjectMapper();
61 | Certificate certificate = null;
62 | try {
63 | certificate = mapper.readValue(certificateStr, Certificate.class);
64 | if (certificate == null) {
65 | modelMap.put("success", false);
66 | modelMap.put("errMsg", DTOMsgEnum.ERROR_INPUT_STR.getStatusInfo());
67 | LOGGER.error("CertificateController addNewOneCertificate empty certificate:{}", certificateStr);
68 | return modelMap;
69 | }
70 | } catch (Exception e) {
71 | modelMap.put("success", false);
72 | modelMap.put("errMsg", DTOMsgEnum.ERROR_INPUT_STR.getStatusInfo());
73 | LOGGER.error("CertificateController addNewOneCertificate error certificate:{}", certificateStr);
74 | return modelMap;
75 | }
76 | ImageHolder thumbnail = null;
77 | try {
78 | //获取文件流
79 | CommonsMultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
80 | if (resolver.isMultipart(request)) {
81 | MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
82 | CommonsMultipartFile thumbnailFile = (CommonsMultipartFile) multipartHttpServletRequest.getFile("image");
83 | if (thumbnailFile != null) {
84 | thumbnail = new ImageHolder(thumbnailFile.getOriginalFilename(), thumbnailFile.getInputStream());
85 | } else {
86 | throw new Exception();
87 | }
88 | }
89 | } catch (Exception e) {
90 | modelMap.put("success", false);
91 | modelMap.put("errMsg", DTOMsgEnum.ERROR_IMAGE.getStatusInfo());
92 | LOGGER.error("CertificateController addNewOneCertificate error certificate:{}", certificateStr);
93 | }
94 | try {
95 | //执行存储证书逻辑
96 | CertificateDTO res = certificateService.addCertificate(certificate, thumbnail);
97 | if (res.getMsg() != DTOMsgEnum.OK.getStatus()) {
98 | modelMap.put("success", false);
99 | modelMap.put("errMsg", res.getMsg());
100 | LOGGER.info("CertificateController addNewOneCertificate fail certificate:{}", certificateStr);
101 | return modelMap;
102 | }
103 | LOGGER.info("CertificateController addNewOneCertificate success certificate:{}", certificateStr);
104 | modelMap.put("success", true);
105 | } catch (CertificateException e) {
106 | modelMap.put("success",false);
107 | modelMap.put("errMsg", DTOMsgEnum.ERROR_EXCEPTION.getStatusInfo());
108 | LOGGER.error("CertificateController addNewOneCertificate error certificate:{}", certificateStr);
109 | return modelMap;
110 | } catch (Exception e ){
111 | modelMap.put("success", false);
112 | modelMap.put("errMsg", DTOMsgEnum.ERROR_EXCEPTION.getStatusInfo());
113 | LOGGER.error("CertificateController addNewOneCertificate error certificate:{}", certificateStr);
114 | return modelMap;
115 | }
116 | return modelMap;
117 | }
118 |
119 | /**
120 | * 查询用户拥有的证书
121 | * @param request
122 | * @return
123 | */
124 | @PostMapping("/certificate/userQueryById")
125 | @RequiresPermissions("/certificate/userQueryById")
126 | public Map queryCertificateByUserId(HttpServletRequest request) {
127 | Map modelMap = new HashMap<>(16);
128 | int pageIndex = HttpServletRequestUtil.getInt(request, "pageIndex");
129 | int pageSize = HttpServletRequestUtil.getInt(request, "pageSize");
130 | String userId = HttpServletRequestUtil.getString(request, "userId");
131 | int certificateType = HttpServletRequestUtil.getInt(request, "certificateType");
132 | if (userId == null) {
133 | modelMap.put("success",false);
134 | modelMap.put("errMsg", DTOMsgEnum.EMPTY_INPUT_STR.getStatusInfo());
135 | LOGGER.error("CertificateController queryCertificateByUserId empty userId");
136 | return modelMap;
137 | }
138 | pageIndex = getPageIndex(pageIndex);
139 | pageSize = getPageSize(pageSize);
140 | try {
141 | //先判断证书类型合法性
142 | if (certificateType == -1000) {
143 | certificateType = CertificateTypeEnum.ALL_TYPE.getStatus();
144 | } else {
145 | checkCertificateType(certificateType);
146 | }
147 | CertificateDTO certificateDTOList = certificateService.queryCertificateByUserId(userId, certificateType, pageIndex, pageSize);
148 | if (certificateDTOList.getMsg() != DTOMsgEnum.OK.getStatus()) {
149 | modelMap.put("success", false);
150 | modelMap.put("errMsg", DTOMsgEnum.stateOf(certificateDTOList.getMsg()).getStatusInfo());
151 | LOGGER.info("CertificateController queryCertificateByUserId fail, certificateType:{}, userId:{}", certificateType, userId);
152 | return modelMap;
153 | }
154 | LOGGER.info("CertificateController queryCertificateByUserId success, certificateType:{}, userId:{}", certificateType, userId);
155 | modelMap.put("CertificateList", certificateDTOList.getCertificateList());
156 | modelMap.put("certificateCount", certificateDTOList.getCount());
157 | modelMap.put("success", true);
158 | } catch (CertificateException e) {
159 | modelMap.put("success",false);
160 | modelMap.put("errMsg", DTOMsgEnum.ERROR_EXCEPTION.getStatusInfo());
161 | LOGGER.error("CertificateController queryCertificateByUserId error userId:{}", userId);
162 | return modelMap;
163 | } catch (Exception e ){
164 | modelMap.put("success", false);
165 | modelMap.put("errMsg", DTOMsgEnum.ERROR_EXCEPTION.getStatusInfo());
166 | LOGGER.error("CertificateController queryCertificateByUserId error userId:{}", userId);
167 | return modelMap;
168 | }
169 | return modelMap;
170 | }
171 |
172 | private int getPageIndex(int pageIndex) {
173 | if (pageIndex < 0 || pageIndex > 1000) {
174 | return 0;
175 | }
176 | return pageIndex;
177 | }
178 |
179 | private int getPageSize(int pageSize) {
180 | if (pageSize <= 0 || pageSize > 100) {
181 | return 5;
182 | }
183 | return pageSize;
184 | }
185 |
186 | private void checkCertificateType(int type) {
187 | if (CertificateTypeEnum.stateOf(type) == null) {
188 | LOGGER.info("CertificateController queryCertificateByUserId fail,no such cmsType");
189 | throw new CertificateException(DTOMsgEnum.ERROR_INPUT_STR.getStatusInfo());
190 | }
191 | }
192 |
193 | }
194 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/controller/UserController.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.controller;
2 |
3 | import com.oym.cms.dto.UserDTO;
4 | import com.oym.cms.entity.User;
5 | import com.oym.cms.enums.DTOMsgEnum;
6 | import com.oym.cms.service.UserService;
7 | import com.oym.cms.util.HttpServletRequestUtil;
8 | import org.apache.commons.lang3.StringUtils;
9 | import org.apache.shiro.SecurityUtils;
10 | import org.apache.shiro.authz.annotation.RequiresPermissions;
11 | import org.apache.shiro.subject.Subject;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 | import org.springframework.web.bind.annotation.*;
15 |
16 | import javax.annotation.Resource;
17 | import javax.servlet.http.HttpServletRequest;
18 | import java.util.HashMap;
19 | import java.util.Map;
20 |
21 | /**
22 | * @Author: Mr_OO
23 | * @Date: 2022/3/4 10:00
24 | */
25 | @CrossOrigin
26 | @RestController
27 | public class UserController {
28 | @Resource
29 | private UserService userService;
30 |
31 | /**
32 | * UserController log
33 | */
34 | private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);
35 |
36 | /**
37 | * 登录
38 | * @param request
39 | * @return
40 | */
41 | @PostMapping("/user/login")
42 | public Map userLogin(HttpServletRequest request) {
43 | Map modelMap = new HashMap<>(16);
44 | String userId = HttpServletRequestUtil.getString(request, "userId");
45 | String userPassword = HttpServletRequestUtil.getString(request, "userPassword");
46 | if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(userPassword)) {
47 | modelMap.put("success",false);
48 | modelMap.put("errMsg", DTOMsgEnum.EMPTY_INPUT_STR.getStatusInfo());
49 | return modelMap;
50 | }
51 | try {
52 | LOGGER.info("UserController userLogin userId:{}", userId);
53 | UserDTO userDTO = userService.userLogin(userId, userPassword);
54 | if (DTOMsgEnum.OK.getStatus() != userDTO.getMsg()) {
55 | modelMap.put("success",false);
56 | modelMap.put("errMsg", DTOMsgEnum.stateOf(userDTO.getMsg()).getStatusInfo());
57 | LOGGER.info("UserController userLogin fail userId:{}, info:{}",
58 | userId, DTOMsgEnum.stateOf(userDTO.getMsg()).getStatusInfo());
59 | return modelMap;
60 | }
61 | userDTO.getUser().setUserPassword("");
62 | //保护隐私
63 | userDTO.getUser().setId("");
64 | LOGGER.info("UserController userLogin success userId:{}", userId);
65 | modelMap.put("user", userDTO.getUser());
66 | modelMap.put("success",true);
67 | } catch (Exception e) {
68 | modelMap.put("success",false);
69 | LOGGER.error("UserController userLogin exception userId:{}", userId);
70 | modelMap.put("errMsg", DTOMsgEnum.LOGIN_FAIL.getStatusInfo());
71 | return modelMap;
72 | }
73 | return modelMap;
74 | }
75 |
76 | /**
77 | * 更改密码
78 | * @param request
79 | * @return
80 | */
81 | @PostMapping("/user/changeUserPassword")
82 | public Map userChangePassword(HttpServletRequest request) {
83 | Map modelMap = new HashMap<>(16);
84 | String userId = HttpServletRequestUtil.getString(request, "userId");
85 | String ID = HttpServletRequestUtil.getString(request, "ID");
86 | String newPassword = HttpServletRequestUtil.getString(request, "newPassword");
87 | if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(ID)|| StringUtils.isEmpty(newPassword)) {
88 | modelMap.put("success",false);
89 | modelMap.put("errMsg", DTOMsgEnum.EMPTY_INPUT_STR.getStatusInfo());
90 | return modelMap;
91 | }
92 | try {
93 | LOGGER.info("UserController userChangePassword userId:{}", userId);
94 | UserDTO userDTOQuery = userService.queryUserById(userId);
95 | if (DTOMsgEnum.OK.getStatus() != userDTOQuery.getMsg()) {
96 | LOGGER.info("UserController userChangePassword exception userId:{}", userId);
97 | modelMap.put("success", false);
98 | modelMap.put("errMsg", DTOMsgEnum.stateOf(userDTOQuery.getMsg()).getStatusInfo());
99 | }
100 | User user = new User();
101 | user.setUserId(userId);
102 | user.setUserPassword(newPassword);
103 | user.setId(ID);
104 | UserDTO userDTOUpdate = userService.updateUser(user);
105 | if (DTOMsgEnum.OK.getStatus() != userDTOUpdate.getMsg()) {
106 | modelMap.put("success",false);
107 | modelMap.put("errMsg", DTOMsgEnum.stateOf(userDTOUpdate.getMsg()).getStatusInfo());
108 | LOGGER.info("UserController userChangePassword fail userId:{}, info:{}",
109 | userId, DTOMsgEnum.stateOf(userDTOUpdate.getMsg()).getStatusInfo());
110 | return modelMap;
111 | }
112 | LOGGER.info("UserController userChangePassword success userId:{}", userId);
113 | modelMap.put("success",true);
114 | } catch (Exception e) {
115 | modelMap.put("success",false);
116 | LOGGER.error("UserController userChangePassword exception userId:{}", userId);
117 | modelMap.put("errMsg", DTOMsgEnum.ERROR_EXCEPTION.getStatusInfo());
118 | return modelMap;
119 | }
120 | return modelMap;
121 | }
122 |
123 | /**
124 | * 用户退出系统
125 | *
126 | * @param request
127 | */
128 | @PostMapping("/logout")
129 | public void staffLogout(HttpServletRequest request) {
130 | try {
131 | Subject subject = SecurityUtils.getSubject();
132 | User user = (User) subject.getPrincipals().getPrimaryPrincipal();
133 | LOGGER.info("UserController staffLogout userId:{}", user.getUserId());
134 | subject.logout();
135 | } catch (Exception e) {}
136 | }
137 |
138 | }
139 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/dto/CertificateDTO.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.dto;
2 |
3 | import com.oym.cms.entity.Certificate;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 证书数据传输对象
9 | * @Author: Mr_OO
10 | * @Date: 2022/3/5 20:46
11 | */
12 | public class CertificateDTO {
13 | private Certificate certificate;
14 | private List certificateList;
15 | private Integer msg;
16 | private Integer count;
17 |
18 | public CertificateDTO() {}
19 |
20 | public CertificateDTO(Integer msg) {
21 | this.msg = msg;
22 | }
23 |
24 | public CertificateDTO(Certificate certificate, Integer msg) {
25 | this.certificate = certificate;
26 | this.msg = msg;
27 | }
28 |
29 | public CertificateDTO(Integer msg, List certificateList) {
30 | this.certificateList = certificateList;
31 | this.msg = msg;
32 | }
33 |
34 | public List getCertificateList() {
35 | return certificateList;
36 | }
37 |
38 | public void setCertificateList(List certificateList) {
39 | this.certificateList = certificateList;
40 | }
41 |
42 | public Certificate getCertificate() {
43 | return certificate;
44 | }
45 |
46 | public void setCertificate(Certificate certificate) {
47 | this.certificate = certificate;
48 | }
49 |
50 | public Integer getMsg() {
51 | return msg;
52 | }
53 |
54 | public void setMsg(Integer msg) {
55 | this.msg = msg;
56 | }
57 |
58 | public Integer getCount() {
59 | return count;
60 | }
61 |
62 | public void setCount(Integer count) {
63 | this.count = count;
64 | }
65 |
66 | @Override
67 | public String toString() {
68 | return "CertificateDTO{" +
69 | "certificate=" + certificate +
70 | ", certificateList=" + certificateList +
71 | ", msg=" + msg +
72 | ", count=" + count +
73 | '}';
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/dto/ImageHolder.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.dto;
2 |
3 | import java.io.InputStream;
4 |
5 | /**
6 | * @Author: Mr_OO
7 | * @Date: 2022/4/6 20:00
8 | */
9 | public class ImageHolder {
10 | private String imageName;
11 | private InputStream image;
12 |
13 | public ImageHolder(String imageName, InputStream image) {
14 | this.imageName = imageName;
15 | this.image = image;
16 | }
17 |
18 | public ImageHolder(InputStream image, String imageName) {
19 | this.imageName = imageName;
20 | this.image = image;
21 | }
22 |
23 | public String getImageName() {
24 | return imageName;
25 | }
26 |
27 | public void setImageName(String imageName) {
28 | this.imageName = imageName;
29 | }
30 |
31 | public InputStream getImage() {
32 | return image;
33 | }
34 |
35 | public void setImage(InputStream image) {
36 | this.image = image;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/dto/UserDTO.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.dto;
2 |
3 | import com.oym.cms.entity.User;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * 用户数据传输对象
9 | * @Author: Mr_OO
10 | * @Date: 2022/3/3 18:23
11 | */
12 | public class UserDTO {
13 | private User user;
14 | private Integer msg;
15 | private List userList;
16 |
17 | public UserDTO() {}
18 |
19 | public UserDTO(User user, Integer msg) {
20 | this.user = user;
21 | this.msg = msg;
22 | }
23 |
24 | public UserDTO(Integer msg, List userList) {
25 | this.msg = msg;
26 | this.userList = userList;
27 | }
28 |
29 | public List getUserList() {
30 | return userList;
31 | }
32 |
33 | public void setUserList(List userList) {
34 | this.userList = userList;
35 | }
36 |
37 | public User getUser() {
38 | return user;
39 | }
40 |
41 | public void setUser(User user) {
42 | this.user = user;
43 | }
44 |
45 | public Integer getMsg() {
46 | return msg;
47 | }
48 |
49 | public void setMsg(Integer msg) {
50 | this.msg = msg;
51 | }
52 |
53 | @Override
54 | public String toString() {
55 | return "UserDTO{" +
56 | "user=" + user +
57 | ", msg='" + msg + '\'' +
58 | '}';
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/entity/Certificate.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.entity;
2 |
3 | import java.io.Serializable;
4 | import java.util.Date;
5 |
6 | /**
7 | * 证书信息类
8 | * @Author: Mr_OO
9 | * @Date: 2022/3/2 15:04
10 | */
11 | public class Certificate implements Serializable {
12 | private static final long serialVersionUID = 7383159382779976173L;
13 |
14 | /**
15 | * 证书名称
16 | */
17 | private String certificateName;
18 |
19 | /**
20 | * 证书类别
21 | */
22 | private Integer certificateType;
23 |
24 | /**
25 | * 用户学号,对应stuNumber
26 | */
27 | private String userId;
28 |
29 | /**
30 | * 证书获奖时间
31 | */
32 | private Date certificateWinTime;
33 |
34 | /**
35 | * 证书描述
36 | */
37 | private String certificateDescription;
38 |
39 | /**
40 | * 证书凭证URL
41 | */
42 | private String certificateUrl;
43 |
44 | public String getCertificateUrl() {
45 | return certificateUrl;
46 | }
47 |
48 | public void setCertificateUrl(String certificateUrl) {
49 | this.certificateUrl = certificateUrl;
50 | }
51 |
52 | public String getCertificateDescription() {
53 | return certificateDescription;
54 | }
55 |
56 | public void setCertificateDescription(String certificateDescription) {
57 | this.certificateDescription = certificateDescription;
58 | }
59 |
60 | public String getCertificateName() {
61 | return certificateName;
62 | }
63 |
64 | public void setCertificateName(String certificateName) {
65 | this.certificateName = certificateName;
66 | }
67 |
68 | public Integer getCertificateType() {
69 | return certificateType;
70 | }
71 |
72 | public void setCertificateType(Integer certificateType) {
73 | this.certificateType = certificateType;
74 | }
75 |
76 | public String getUserId() {
77 | return userId;
78 | }
79 |
80 | public void setUserId(String userId) {
81 | this.userId = userId;
82 | }
83 |
84 | public Date getCertificateWinTime() {
85 | return certificateWinTime;
86 | }
87 |
88 | public void setCertificateWinTime(Date certificateWinTime) {
89 | this.certificateWinTime = certificateWinTime;
90 | }
91 |
92 | @Override
93 | public String toString() {
94 | return "Certificate{" +
95 | "certificateName='" + certificateName + '\'' +
96 | ", certificateType=" + certificateType +
97 | ", userId='" + userId + '\'' +
98 | ", certificateWinTime=" + certificateWinTime +
99 | ", certificateDescription='" + certificateDescription + '\'' +
100 | ", certificateUrl='" + certificateUrl + '\'' +
101 | '}';
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/entity/User.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.entity;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 用户类
7 | * @Author: Mr_OO
8 | * @Date: 2022/3/2 14:43
9 | */
10 | public class User implements Serializable {
11 | private static final long serialVersionUID = 238357573261740184L;
12 |
13 | /**
14 | * 用户id(学号)
15 | */
16 | private String userId;
17 | /**
18 | * 用户密码
19 | */
20 | private String userPassword;
21 | /**
22 | * 用户名字
23 | */
24 | private String userName;
25 | /**
26 | * 用户职别
27 | */
28 | private Integer userPosition;
29 | /**
30 | * 用户账号状态
31 | */
32 | private Integer userStatus;
33 | /**
34 | * token
35 | */
36 | private String userToken;
37 |
38 | /**
39 | * 学校标识
40 | */
41 | private String schoolFlag;
42 |
43 | /**
44 | * 身份证号码
45 | */
46 | private String Id;
47 |
48 | public String getId() {
49 | return Id;
50 | }
51 |
52 | public void setId(String id) {
53 | Id = id;
54 | }
55 |
56 | public String getSchoolFlag() {
57 | return schoolFlag;
58 | }
59 |
60 | public void setSchoolFlag(String schoolFlag) {
61 | this.schoolFlag = schoolFlag;
62 | }
63 |
64 | public String getUserToken() {
65 | return userToken;
66 | }
67 |
68 | public void setUserToken(String userToken) {
69 | this.userToken = userToken;
70 | }
71 |
72 | public String getUserId() {
73 | return userId;
74 | }
75 |
76 | public void setUserId(String userId) {
77 | this.userId = userId;
78 | }
79 |
80 | public String getUserPassword() {
81 | return userPassword;
82 | }
83 |
84 | public void setUserPassword(String userPassword) {
85 | this.userPassword = userPassword;
86 | }
87 |
88 | public String getUserName() {
89 | return userName;
90 | }
91 |
92 | public void setUserName(String userName) {
93 | this.userName = userName;
94 | }
95 |
96 | public Integer getUserPosition() {
97 | return userPosition;
98 | }
99 |
100 | public void setUserPosition(Integer userPosition) {
101 | this.userPosition = userPosition;
102 | }
103 |
104 | public Integer getUserStatus() {
105 | return userStatus;
106 | }
107 |
108 | public void setUserStatus(Integer userStatus) {
109 | this.userStatus = userStatus;
110 | }
111 |
112 | @Override
113 | public String toString() {
114 | return "User{" +
115 | "userId='" + userId + '\'' +
116 | ", userPassword='" + userPassword + '\'' +
117 | ", userName='" + userName + '\'' +
118 | ", userPosition=" + userPosition +
119 | ", userStatus=" + userStatus +
120 | '}';
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/enums/CertificateTypeEnum.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.enums;
2 |
3 | /**
4 | * @Author: Mr_OO
5 | * @Date: 2022/3/5 20:09
6 | */
7 | public enum CertificateTypeEnum {
8 | ALL_TYPE(0, "所有类型(用于后端程序查询注入)"),
9 | SCHOLARSHIP_AND_HONORARY_TITLE(1001, "奖学金及荣誉称号类"),
10 | DISCIPLINE_COMPETITION(1002, "学科竞赛类"),
11 | QUALIFICATION_LEVEL(1003, "资格等级类"),
12 | VOLUNTARY_SERVICE(1004, "志愿服务类"),
13 | ART_EXHIBITION(1005, "艺术展览类"),
14 | SPORTS_COMPETITION(1006, "体育竞技类"),
15 | OTHER(1007, "其他类");
16 |
17 | private Integer status;
18 | private String statusInfo;
19 |
20 | CertificateTypeEnum(Integer status, String statusInfo) {
21 | this.status = status;
22 | this.statusInfo = statusInfo;
23 | }
24 |
25 | public Integer getStatus() {
26 | return status;
27 | }
28 |
29 | public String getStatusInfo() {
30 | return statusInfo;
31 | }
32 |
33 | public static CertificateTypeEnum stateOf(int number) {
34 | for (CertificateTypeEnum value : values()) {
35 | if (value.getStatus() == number) {
36 | return value;
37 | }
38 | }
39 | return null;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/enums/DTOMsgEnum.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.enums;
2 |
3 | /**
4 | * @Author: Mr_OO
5 | * @Date: 2022/3/3 18:28
6 | */
7 | public enum DTOMsgEnum {
8 | OK(1, "请求成功"),
9 |
10 | EMPTY_INPUT_STR(-1000, "输入数据为空"),
11 | ERROR_INPUT_STR(-1001, "输入数据不符合规范"),
12 | ERROR_EXCEPTION(-1002, "请求失败"),
13 |
14 | ACCOUNT_NOT_EXIST(-2001, "账号不存在"),
15 | WRONG_PASSWORD(-2002, "密码不正确"),
16 | LOGIN_FAIL(-2003, "用户验证失败"),
17 | ACCOUNT_INVALID(-2004, "该用户账号已失效"),
18 | WRONG_ID(-2005,"身份证号码有误"),
19 |
20 | ERROR_IMAGE(-3001, "图片提交失败"),
21 |
22 | NO_SEND_IMMEDIATELY(-4001, "请勿在短时间内重复提交");
23 |
24 | private int status;
25 | private String statusInfo;
26 |
27 | DTOMsgEnum(int status, String statusInfo) {
28 | this.status = status;
29 | this.statusInfo = statusInfo;
30 | }
31 |
32 | public int getStatus() {
33 | return status;
34 | }
35 |
36 | public String getStatusInfo() {
37 | return statusInfo;
38 | }
39 |
40 | public static DTOMsgEnum stateOf(int number) {
41 | for (DTOMsgEnum value : values()) {
42 | if (value.getStatus() == number) {
43 | return value;
44 | }
45 | }
46 | return null;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/enums/UserIdStatusEnum.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.enums;
2 |
3 | /**
4 | * 用户账号状态枚举
5 | * @Author: Mr_OO
6 | * @Date: 2022/3/3 18:02
7 | */
8 | public enum UserIdStatusEnum {
9 | OK(1, "账号正常"),INVALID(-1, "账号已失效");
10 |
11 | private Integer status;
12 | private String statusInfo;
13 |
14 | UserIdStatusEnum(Integer status, String statusInfo) {
15 | this.status = status;
16 | this.statusInfo = statusInfo;
17 | }
18 |
19 | public Integer getStatus() {
20 | return status;
21 | }
22 |
23 | public String getStatusInfo() {
24 | return statusInfo;
25 | }
26 |
27 | public static UserIdStatusEnum stateOf(int number) {
28 | for (UserIdStatusEnum value : values()) {
29 | if (value.getStatus() == number) {
30 | return value;
31 | }
32 | }
33 | return null;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/enums/UserPositionEnum.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.enums;
2 |
3 | /**
4 | * @Author: Mr_OO
5 | * @Date: 2022/3/4 9:46
6 | */
7 | public enum UserPositionEnum {
8 | STUDENT(1, "学生"),
9 | TEACHER(-1, "老师");
10 |
11 | private Integer status;
12 | private String statusInfo;
13 |
14 | UserPositionEnum(Integer status, String statusInfo) {
15 | this.status = status;
16 | this.statusInfo = statusInfo;
17 | }
18 |
19 | public Integer getStatus() {
20 | return status;
21 | }
22 |
23 | public String getStatusInfo() {
24 | return statusInfo;
25 | }
26 |
27 | public static UserPositionEnum stateOf(int number) {
28 | for (UserPositionEnum value : values()) {
29 | if (value.getStatus() == number) {
30 | return value;
31 | }
32 | }
33 | return null;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/exceptions/CertificateException.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.exceptions;
2 |
3 | /**
4 | * @Author: Mr_OO
5 | * @Date: 2022/3/5 21:11
6 | */
7 | public class CertificateException extends RuntimeException {
8 | private static final long serialVersionUID = 1058940050993043833L;
9 |
10 | public CertificateException(String message) {
11 | super(message);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/exceptions/UserException.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.exceptions;
2 |
3 | /**
4 | * 用户异常类
5 | * @Author: Mr_OO
6 | * @Date: 2022/3/3 18:16
7 | */
8 | public class UserException extends RuntimeException {
9 | private static final long serialVersionUID = 7688456332310845557L;
10 |
11 | public UserException(String message) {
12 | super(message);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/mapper/JurisdictionMapper.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.mapper;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @Author: Mr_OO
7 | * @Date: 2022/3/3 22:13
8 | */
9 | public interface JurisdictionMapper {
10 | /**
11 | * 查询路由集合
12 | * @return
13 | */
14 | List queryAllUrls();
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/mapper/UserMapper.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.mapper;
2 |
3 | import com.oym.cms.entity.User;
4 | import org.apache.ibatis.annotations.Param;
5 |
6 | /**
7 | * @Author: Mr_OO
8 | * @Date: 2022/3/3 18:08
9 | */
10 | public interface UserMapper {
11 | /**
12 | * 通过账号查询用户
13 | *
14 | * @param userId
15 | * @return
16 | */
17 | User queryUserById(@Param("userId") String userId);
18 |
19 | /**
20 | * 更新账户信息
21 | *
22 | * @param user
23 | * @return
24 | */
25 | int updateUser(User user);
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/service/CacheService.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.service;
2 |
3 | /**
4 | * @Author: Mr_OO
5 | * @Date: 2022/3/3 18:13
6 | */
7 | public interface CacheService {
8 | /**
9 | * 依据 key前缀删除匹配该模式下的所有key-value
10 | * @param keyPrefix
11 | * @return
12 | */
13 | void removeFromCache(String keyPrefix);
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/service/CertificateService.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.service;
2 |
3 | import com.oym.cms.dto.CertificateDTO;
4 | import com.oym.cms.dto.ImageHolder;
5 | import com.oym.cms.entity.Certificate;
6 |
7 | /**
8 | * @Author: Mr_OO
9 | * @Date: 2022/3/5 20:44
10 | */
11 | public interface CertificateService {
12 | /**
13 | * 添加证书
14 | * @param certificate
15 | * @param imageHolder
16 | * @return
17 | */
18 | CertificateDTO addCertificate(Certificate certificate, ImageHolder imageHolder);
19 |
20 | /**
21 | * 查询该用户已存储的证书
22 | * @param userId
23 | * @param certificateType
24 | * @param pageIndex
25 | * @param pageSize
26 | * @return
27 | */
28 | CertificateDTO queryCertificateByUserId(String userId, int certificateType, int pageIndex, int pageSize);
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/service/UserService.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.service;
2 |
3 | import com.oym.cms.dto.UserDTO;
4 | import com.oym.cms.entity.User;
5 | import org.apache.ibatis.annotations.Param;
6 |
7 | /**
8 | * @Author: Mr_OO
9 | * @Date: 2022/3/3 18:13
10 | */
11 | public interface UserService {
12 | /**
13 | * 通过账号查询用户
14 | *
15 | * @param userId
16 | * @return
17 | */
18 | UserDTO queryUserById(@Param("userId") String userId);
19 |
20 | /**
21 | * 登录
22 | *
23 | * @param userId
24 | * @param userPassword
25 | * @return
26 | */
27 | UserDTO userLogin(@Param("userId") String userId, @Param("userPassword") String userPassword);
28 |
29 | /**
30 | * 更新账户信息
31 | *
32 | * @param user
33 | * @return
34 | */
35 | UserDTO updateUser(User user);
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/service/impl/CacheServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.service.impl;
2 |
3 | import com.oym.cms.config.redis.JedisUtil;
4 | import com.oym.cms.service.CacheService;
5 | import org.springframework.stereotype.Service;
6 |
7 | import javax.annotation.Resource;
8 | import java.util.Set;
9 |
10 | /**
11 | * @Author: Mr_OO
12 | * @Date: 2020/11/23 14:05
13 | */
14 | @Service
15 | public class CacheServiceImpl implements CacheService {
16 |
17 | @Resource
18 | private JedisUtil.Keys jedisKeys;
19 |
20 | @Override
21 | public void removeFromCache(String keyPrefix) {
22 | Set keySet = jedisKeys.keys(keyPrefix + "*");
23 | for (String key : keySet) {
24 | if (jedisKeys.exists(key)) {
25 | jedisKeys.del(key);
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/service/impl/CertificateServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.service.impl;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.fasterxml.jackson.core.JsonProcessingException;
5 | import com.fasterxml.jackson.databind.JavaType;
6 | import com.fasterxml.jackson.databind.ObjectMapper;
7 | import com.google.common.cache.Cache;
8 | import com.google.common.cache.CacheBuilder;
9 | import com.oym.cms.client.ContractClient;
10 | import com.oym.cms.client.FastDFSClient;
11 | import com.oym.cms.config.redis.JedisUtil;
12 | import com.oym.cms.dto.CertificateDTO;
13 | import com.oym.cms.dto.ImageHolder;
14 | import com.oym.cms.entity.Certificate;
15 | import com.oym.cms.entity.User;
16 | import com.oym.cms.enums.CertificateTypeEnum;
17 | import com.oym.cms.enums.DTOMsgEnum;
18 | import com.oym.cms.exceptions.CertificateException;
19 | import com.oym.cms.mapper.UserMapper;
20 | import com.oym.cms.service.CacheService;
21 | import com.oym.cms.service.CertificateService;
22 | import com.oym.cms.util.ImageUtil;
23 | import com.oym.cms.util.PageCalculator;
24 | import org.slf4j.Logger;
25 | import org.slf4j.LoggerFactory;
26 | import org.springframework.stereotype.Service;
27 |
28 | import javax.annotation.Resource;
29 | import java.time.Duration;
30 | import java.util.ArrayList;
31 | import java.util.List;
32 |
33 | /**
34 | * @Author: Mr_OO
35 | * @Date: 2022/3/5 20:52
36 | */
37 | @Service
38 | public class CertificateServiceImpl implements CertificateService {
39 |
40 | /**
41 | * CertificateServiceImpl log
42 | */
43 | private static final Logger LOGGER = LoggerFactory.getLogger(CertificateServiceImpl.class);
44 |
45 | /**
46 | * 缓存前缀
47 | */
48 | private final static String CERTIFICATE_QUERY_SERVICE = "CertificateQueryService";
49 |
50 | @Resource
51 | private ContractClient contractClient;
52 | @Resource
53 | private UserMapper userMapper;
54 |
55 | @Resource
56 | private JedisUtil.Keys jedisKeys;
57 | @Resource
58 | private JedisUtil.Strings jedisStrings;
59 | @Resource
60 | private CacheService cacheService;
61 |
62 | /**
63 | * 本地缓存引入,防止恶意上传
64 | */
65 | private Cache dataCache = CacheBuilder.newBuilder()
66 | .expireAfterWrite(Duration.ofSeconds(30))
67 | .maximumSize(10240)
68 | .concurrencyLevel(4)
69 | .initialCapacity(2048)
70 | .build();
71 |
72 | @Override
73 | public CertificateDTO addCertificate(Certificate certificate, ImageHolder thumbnail) throws CertificateException {
74 | if (certificate != null
75 | && certificate.getCertificateDescription() != null
76 | && certificate.getCertificateWinTime() != null
77 | && certificate.getCertificateName() != null
78 | && certificate.getCertificateType() != null
79 | && certificate.getUserId() != null) {
80 | try {
81 | //先经过本地缓存判断用户是否恶意上传
82 | String value = dataCache.getIfPresent(certificate.getUserId());
83 | if (value == null) {
84 | dataCache.put("addCertificate" + certificate.getUserId(), "v");
85 | } else {
86 | //恶意上传直接跳出方法
87 | LOGGER.info("CertificateServiceImpl addCertificate fail, NO_SEND_IMMEDIATELY, certificate:{}", JSON.toJSONString(certificate));
88 | return new CertificateDTO(null, DTOMsgEnum.NO_SEND_IMMEDIATELY.getStatus());
89 | }
90 | //生成文件名
91 | String imageName = ImageUtil.getRandomFileName(certificate.getUserId(), thumbnail.getImageName());
92 | //存储图片到分布式服务器系统
93 | String[] result = FastDFSClient.uploadFile(thumbnail.getImage(), imageName);
94 | //result结果示例:[group1, M00/00/00/CgAYCGJFpQKACftIAAAbnjkyo8A652.png], 生成图片URL后半截用于存储
95 | String imageUrl = ImageUtil.getImageUrl(result);
96 | if (imageUrl == null) {
97 | LOGGER.info("CertificateServiceImpl addCertificate fail,imageUrl get fail certificate:{}", JSON.toJSONString(certificate));
98 | return new CertificateDTO(null, DTOMsgEnum.ERROR_EXCEPTION.getStatus());
99 | }
100 | //获取存储证书的用户信息
101 | User user = userMapper.queryUserById(certificate.getUserId());
102 | if (user == null) {
103 | LOGGER.info("CertificateServiceImpl addCertificate fail, no such user certificate:{}", JSON.toJSONString(certificate));
104 | return new CertificateDTO(null, DTOMsgEnum.ACCOUNT_NOT_EXIST.getStatus());
105 | }
106 | //存储区块链
107 | int res = contractClient.registerCertificate(
108 | user.getSchoolFlag(), user.getUserId(), user.getUserName(), certificate.getCertificateName(),
109 | String.valueOf(certificate.getCertificateType()), String.valueOf(certificate.getCertificateWinTime().getTime()),
110 | certificate.getCertificateDescription(), imageUrl);
111 | if (DTOMsgEnum.OK.getStatus() != res) {
112 | LOGGER.info("CertificateServiceImpl addCertificate fail certificate:{}", JSON.toJSONString(certificate));
113 | return new CertificateDTO(null, DTOMsgEnum.ERROR_EXCEPTION.getStatus());
114 | }
115 | //清空该账号查询缓存
116 | cacheService.removeFromCache(CERTIFICATE_QUERY_SERVICE + "type"
117 | + certificate.getCertificateType() + "id" + user.getUserId());
118 | LOGGER.info("CertificateServiceImpl addCertificate success certificate:{}", JSON.toJSONString(certificate));
119 | return new CertificateDTO(null, DTOMsgEnum.OK.getStatus());
120 | } catch (CertificateException e) {
121 | LOGGER.error("CertificateServiceImpl addCertificate Exception certificate:{}", JSON.toJSONString(certificate));
122 | return new CertificateDTO(null, DTOMsgEnum.ERROR_EXCEPTION.getStatus());
123 | }
124 | }
125 | return new CertificateDTO(null, DTOMsgEnum.EMPTY_INPUT_STR.getStatus());
126 | }
127 |
128 | @Override
129 | public CertificateDTO queryCertificateByUserId(String userId, int certificateType, int pageIndex, int pageSize) {
130 | if (userId != null) {
131 | try {
132 | //查询起始索引
133 | int rowIndex = PageCalculator.calculatorRowIndex(pageIndex, pageSize);
134 | //查询截止索引边界
135 | int rowEndIndex = rowIndex + pageSize;
136 | //生成缓存key
137 | StringBuilder redisKey = new StringBuilder();
138 | redisKey.append(CERTIFICATE_QUERY_SERVICE)
139 | .append("type")
140 | .append(certificateType)
141 | .append("id")
142 | .append(userId)
143 | .append("index")
144 | .append(pageIndex)
145 | .append("size")
146 | .append(pageSize);
147 | //查询证书列表 先走redis缓存
148 | List certificateList = null;
149 | ObjectMapper mapper = new ObjectMapper();
150 | if (jedisKeys.exists(redisKey.toString())) {
151 | String jsonString = jedisStrings.get(redisKey.toString());
152 | JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class, Certificate.class);
153 | try {
154 | certificateList = mapper.readValue(jsonString, javaType);
155 | } catch (JsonProcessingException e) {
156 | LOGGER.error("CertificateServiceImpl queryCertificateByUserId REDIS Exception userId:{}", userId);
157 | return new CertificateDTO(null, DTOMsgEnum.ERROR_EXCEPTION.getStatus());
158 | }
159 | } else {
160 | //缓存不存在该列表信息
161 | certificateList = contractClient.queryCertificateList(userId);
162 | String jsonString = null;
163 | try {
164 | jsonString = mapper.writeValueAsString(certificateList);
165 | } catch (JsonProcessingException e) {
166 | LOGGER.error("CertificateServiceImpl queryCertificateByUserId REDIS Exception userId:{}", userId);
167 | return new CertificateDTO(null, DTOMsgEnum.ERROR_EXCEPTION.getStatus());
168 | }
169 | jedisStrings.set(redisKey.toString(), jsonString);
170 | }
171 | if (certificateList == null) {
172 | LOGGER.error("CertificateServiceImpl queryCertificateByUserId BCOS Exception userId:{}", userId);
173 | return new CertificateDTO(null, DTOMsgEnum.ERROR_EXCEPTION.getStatus());
174 | }
175 | int size = certificateList.size();
176 | CertificateDTO certificateDTO = new CertificateDTO();
177 | List res = new ArrayList<>();
178 | if (CertificateTypeEnum.ALL_TYPE.getStatus().equals(certificateType)) {
179 | //所有类别证书查询
180 | //起始点超过总数情况
181 | if (rowIndex > size) {
182 | return new CertificateDTO(DTOMsgEnum.OK.getStatus(), new ArrayList());
183 | }
184 | //边界判断
185 | if (size < rowEndIndex) {
186 | rowEndIndex = size;
187 | }
188 | //注入证书总数量
189 | certificateDTO.setCount(size);
190 | for (int i = rowIndex; i < rowEndIndex; i++) {
191 | res.add(certificateList.get(i));
192 | }
193 | } else {
194 | List typeList = new ArrayList<>();
195 | for (Certificate certificate : certificateList) {
196 | if (certificate.getCertificateType().equals(certificateType)) {
197 | typeList.add(certificate);
198 | }
199 | }
200 | int count = typeList.size();
201 | //注入该类证书总数量
202 | certificateDTO.setCount(count);
203 | if (rowIndex > count) {
204 | return new CertificateDTO(DTOMsgEnum.OK.getStatus(), new ArrayList());
205 | }
206 | if (count < rowEndIndex) {
207 | rowEndIndex = count;
208 | }
209 | for (int i = rowIndex; i < rowEndIndex; i++) {
210 | res.add(typeList.get(i));
211 | }
212 | }
213 | certificateDTO.setCertificateList(res);
214 | certificateDTO.setMsg(DTOMsgEnum.OK.getStatus());
215 | return certificateDTO;
216 | } catch (Exception e) {
217 | LOGGER.error("CertificateServiceImpl queryCertificateByUserId Exception userId:{}", userId);
218 | return new CertificateDTO(null, DTOMsgEnum.ERROR_EXCEPTION.getStatus());
219 | }
220 | }
221 | return new CertificateDTO(null, DTOMsgEnum.EMPTY_INPUT_STR.getStatus());
222 | }
223 | }
224 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/service/impl/UserServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.service.impl;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.google.common.cache.Cache;
5 | import com.google.common.cache.CacheBuilder;
6 | import com.oym.cms.dto.UserDTO;
7 | import com.oym.cms.entity.User;
8 | import com.oym.cms.enums.DTOMsgEnum;
9 | import com.oym.cms.enums.UserIdStatusEnum;
10 | import com.oym.cms.exceptions.UserException;
11 | import com.oym.cms.mapper.UserMapper;
12 | import com.oym.cms.service.UserService;
13 | import com.oym.cms.util.PasswordHelper;
14 | import org.apache.shiro.SecurityUtils;
15 | import org.apache.shiro.authc.AuthenticationException;
16 | import org.apache.shiro.authc.IncorrectCredentialsException;
17 | import org.apache.shiro.authc.UnknownAccountException;
18 | import org.apache.shiro.authc.UsernamePasswordToken;
19 | import org.apache.shiro.subject.Subject;
20 | import org.slf4j.Logger;
21 | import org.slf4j.LoggerFactory;
22 | import org.springframework.stereotype.Service;
23 |
24 | import javax.annotation.Resource;
25 | import java.time.Duration;
26 |
27 | /**
28 | * @Author: Mr_OO
29 | * @Date: 2022/3/3 18:13
30 | */
31 | @Service
32 | public class UserServiceImpl implements UserService {
33 |
34 | /**
35 | * UserServiceImpl log
36 | */
37 | private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);
38 |
39 | @Resource
40 | private UserMapper userMapper;
41 |
42 | /**
43 | * 本地缓存引入,防止恶意上传
44 | */
45 | private Cache dataCache = CacheBuilder.newBuilder()
46 | .expireAfterWrite(Duration.ofSeconds(3))
47 | .maximumSize(10240)
48 | .concurrencyLevel(4)
49 | .initialCapacity(2048)
50 | .build();
51 |
52 | @Override
53 | public UserDTO queryUserById(String userId) throws UserException {
54 | LOGGER.info("UserServiceImpl queryUserById userId:{}", userId);
55 | if (userId != null) {
56 | try {
57 | User user = userMapper.queryUserById(userId);
58 | LOGGER.info("UserServiceImpl queryUserById userId:{}, user:{}", userId, JSON.toJSONString(user));
59 | if (user == null || UserIdStatusEnum.INVALID.getStatus().equals(user.getUserStatus())) {
60 | return new UserDTO(null, DTOMsgEnum.OK.getStatus());
61 | }
62 | return new UserDTO(user, DTOMsgEnum.OK.getStatus());
63 | } catch (UserException e) {
64 | LOGGER.error("UserServiceImpl queryUserById error userId:{}", userId);
65 | return new UserDTO(null, DTOMsgEnum.ERROR_EXCEPTION.getStatus());
66 | }
67 | }
68 | return new UserDTO(null, DTOMsgEnum.EMPTY_INPUT_STR.getStatus());
69 | }
70 |
71 | @Override
72 | public UserDTO userLogin(String userId, String userPassword) throws UserException {
73 | LOGGER.info("UserServiceImpl userLogin userId:{}", userId);
74 | if (userId != null && userPassword != null) {
75 | try {
76 | //先经过本地缓存判断用户是否恶意上传
77 | String value = dataCache.getIfPresent(userId);
78 | if (value == null) {
79 | dataCache.put("userLogin" + userId, "v");
80 | } else {
81 | //恶意上传直接跳出方法
82 | LOGGER.info("UserServiceImpl userLogin fail, NO_SEND_IMMEDIATELY, userId:{}", userId);
83 | return new UserDTO(null, DTOMsgEnum.NO_SEND_IMMEDIATELY.getStatus());
84 | }
85 | User userQuery = userMapper.queryUserById(userId);
86 | if (userQuery == null) {
87 | LOGGER.info("UserServiceImpl userLogin userId:{}, Nonexistent Account", userId);
88 | return new UserDTO(null, DTOMsgEnum.ACCOUNT_NOT_EXIST.getStatus());
89 | }
90 | if (UserIdStatusEnum.INVALID.getStatus().equals(userQuery.getUserStatus())) {
91 | LOGGER.info("UserServiceImpl userLogin userId:{}, invalid Account", userId);
92 | return new UserDTO(null, DTOMsgEnum.ACCOUNT_INVALID.getStatus());
93 | }
94 | // 获取Subject实例对象,用户实例
95 | Subject currentUser = SecurityUtils.getSubject();
96 | // 将用户名和密码封装到UsernamePasswordToken
97 | UsernamePasswordToken token = new UsernamePasswordToken(userId, userPassword);
98 | // 传到 MyShiroRealm 类中的方法进行认证
99 | currentUser.login(token);
100 | // 构建缓存用户信息返回给前端
101 | User user = (User) currentUser.getPrincipals().getPrimaryPrincipal();
102 | //设置TOKEN返回给前端
103 | user.setUserToken(currentUser.getSession().getId().toString());
104 | LOGGER.info("UserServiceImpl userLogin userId:{}, success", userId);
105 | return new UserDTO(user, DTOMsgEnum.OK.getStatus());
106 | } catch (UnknownAccountException e) {
107 | LOGGER.error("UserServiceImpl queryUserById error userId:{}", userId);
108 | return new UserDTO(null, DTOMsgEnum.ACCOUNT_NOT_EXIST.getStatus());
109 | } catch (IncorrectCredentialsException e) {
110 | LOGGER.error("UserServiceImpl queryUserById error userId:{}", userId);
111 | return new UserDTO(null, DTOMsgEnum.WRONG_PASSWORD.getStatus());
112 | } catch (AuthenticationException e) {
113 | LOGGER.error("UserServiceImpl queryUserById error userId:{}", userId);
114 | return new UserDTO(null, DTOMsgEnum.LOGIN_FAIL.getStatus());
115 | }catch (UserException e) {
116 | LOGGER.error("UserServiceImpl queryUserById error userId:{}", userId);
117 | return new UserDTO(null, DTOMsgEnum.LOGIN_FAIL.getStatus());
118 | }
119 | }
120 | return new UserDTO(null, DTOMsgEnum.EMPTY_INPUT_STR.getStatus());
121 | }
122 |
123 | @Override
124 | public UserDTO updateUser(User user) {
125 | if (user != null && user.getUserId() != null) {
126 | try {
127 | //先经过本地缓存判断用户是否恶意上传
128 | String value = dataCache.getIfPresent(user.getUserId());
129 | if (value == null) {
130 | dataCache.put("updateUser" + user.getUserId(), "v");
131 | } else {
132 | //恶意上传直接跳出方法
133 | LOGGER.info("UserServiceImpl updateUser fail, NO_SEND_IMMEDIATELY, userId:{}", user.getUserId());
134 | return new UserDTO(null, DTOMsgEnum.NO_SEND_IMMEDIATELY.getStatus());
135 | }
136 | User userQuery = userMapper.queryUserById(user.getUserId());
137 | if (userQuery == null) {
138 | LOGGER.info("UserServiceImpl updateUser user:{}, Nonexistent Account", JSON.toJSONString(user));
139 | return new UserDTO(null, DTOMsgEnum.ACCOUNT_NOT_EXIST.getStatus());
140 | }
141 | //更改密码逻辑
142 | if (user.getUserPassword() != null && user.getId() != null) {
143 | if (!userQuery.getId().equals(user.getId())) {
144 | LOGGER.info("UserServiceImpl updateUser user:{}, ID WRONG", JSON.toJSONString(user));
145 | return new UserDTO(null, DTOMsgEnum.WRONG_ID.getStatus());
146 | }
147 | //对新密码进行加密
148 | PasswordHelper.encryptPassword(user);
149 | }
150 | int res = userMapper.updateUser(user);
151 | if (res == 0) {
152 | LOGGER.info("UserServiceImpl updateUser user:{}, update fail", JSON.toJSONString(user));
153 | return new UserDTO(null, DTOMsgEnum.ERROR_EXCEPTION.getStatus());
154 | }
155 | return new UserDTO(user, DTOMsgEnum.OK.getStatus());
156 | } catch (UserException e) {
157 | LOGGER.error("UserServiceImpl updateUser exception user:{}", JSON.toJSONString(user));
158 | return new UserDTO(null, DTOMsgEnum.ERROR_EXCEPTION.getStatus());
159 | }
160 | }
161 | return new UserDTO(null, DTOMsgEnum.EMPTY_INPUT_STR.getStatus());
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/util/CertificateIdBuildUtil.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.util;
2 |
3 | /**
4 | * 证书序列号生成器
5 | * @Author: Mr_OO
6 | * @Date: 2022/3/5 19:49
7 | */
8 | public class CertificateIdBuildUtil {
9 |
10 | /**
11 | * 机构名称
12 | */
13 | private static final String ORGANIZATION_NAME = "sicnu";
14 |
15 | /**
16 | * 生成证书序列号
17 | * @param userId 证书所有者账户ID
18 | * @param count 证书所有者已存储证书数量
19 | * @return
20 | */
21 | public static String bornNewId(String userId, int count) {
22 | StringBuilder result = new StringBuilder();
23 | result.append(ORGANIZATION_NAME).append(userId).append(count + 1);
24 | return result.toString();
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/util/DESUtil.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.util;
2 |
3 | import javax.crypto.Cipher;
4 | import javax.crypto.KeyGenerator;
5 | import java.security.Key;
6 | import java.security.SecureRandom;
7 | import java.util.Base64;
8 |
9 | /**
10 | * DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法
11 | * @Author: Mr_OO
12 | * @Date: 2022/3/1 13:28
13 | */
14 | public class DESUtil {
15 | private static Key key;
16 | /**
17 | * 密钥key
18 | */
19 | private static String KEY_STR = "myKey";
20 | private static String CHARSET_NAME = "UTF-8";
21 | private static String ALGORITHM = "DES";
22 |
23 | static {
24 | try {
25 | // 生成DES算法对象
26 | KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
27 | // 运用SHA1安全策略
28 | SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
29 | // 设置上密钥种子
30 | secureRandom.setSeed(KEY_STR.getBytes());
31 | // 初始化基于SHA1的算法对象
32 | generator.init(secureRandom);
33 | // 生成密钥对象
34 | key = generator.generateKey();
35 | generator = null;
36 | } catch (Exception e) {
37 | throw new RuntimeException(e);
38 | }
39 | }
40 |
41 | /**
42 | * 获取加密后的信息
43 | * @param str
44 | * @return
45 | */
46 | public static String getEncryptString(String str) {
47 | try {
48 | // 按UTF8编码
49 | byte[] bytes = str.getBytes(CHARSET_NAME);
50 | // 获取加密对象
51 | Cipher cipher = Cipher.getInstance(ALGORITHM);
52 | // 初始化密码信息
53 | cipher.init(Cipher.ENCRYPT_MODE, key);
54 | // 加密
55 | byte[] doFinal = cipher.doFinal(bytes);
56 | // byte[]to encode好的String并返回
57 | return Base64.getEncoder().encodeToString(doFinal);
58 | } catch (Exception e) {
59 | // TODO: handle exception
60 | throw new RuntimeException(e);
61 | }
62 | }
63 |
64 | /**
65 | * 获取解密之后的信息
66 | * @param str
67 | * @return
68 | */
69 | public static String getDecryptString(String str) {
70 | try {
71 | // 将字符串decode成byte[]
72 | byte[] bytes = Base64.getDecoder().decode(str);
73 | // 获取解密对象
74 | Cipher cipher = Cipher.getInstance(ALGORITHM);
75 | // 初始化解密信息
76 | cipher.init(Cipher.DECRYPT_MODE, key);
77 | // 解密
78 | byte[] doFinal = cipher.doFinal(bytes);
79 | // 返回解密之后的信息
80 | return new String(doFinal, CHARSET_NAME);
81 | } catch (Exception e) {
82 | // TODO: handle exception
83 | throw new RuntimeException(e);
84 | }
85 | }
86 |
87 | public static void main(String[] args) {
88 | //输入自己数据库的账号和密码进行获取
89 | System.out.println(getEncryptString("root"));
90 | System.out.println(getEncryptString("666666"));
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/util/EncryptionUtil.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.util;
2 |
3 | import java.security.MessageDigest;
4 |
5 | /**
6 | * 密码加密工具类
7 | * @Author: Mr_OO
8 | * @Date: 2022/3/1 13:47
9 | */
10 | public class EncryptionUtil {
11 | /**
12 | * 对传入的String进行MD5加密
13 | *
14 | * @param s
15 | * @return
16 | */
17 | public static final String getMd5(String s) {
18 | // 16进制数组
19 | char[] hexDigits = { '1', '2', '3', '4', '5', '5', '4', '3', '2', '1', 'a', 'b', 'c', 'd', 'e', 'f' };
20 | try {
21 | char[] str;
22 | // 将传入的字符串转换成byte数组
23 | byte[] strTemp = s.getBytes();
24 | // 获取MD5加密对象
25 | MessageDigest mdTemp = MessageDigest.getInstance("MD5");
26 | // 传入需要加密的目标数组
27 | mdTemp.update(strTemp);
28 | // 获取加密后的数组
29 | byte[] md = mdTemp.digest();
30 | int j = md.length;
31 | str = new char[j * 2];
32 | int k = 0;
33 | // 将数组做位移
34 | for (int i = 0; i < j; i++) {
35 | byte byte0 = md[i];
36 | str[k++] = hexDigits[byte0 >>> 4 & 0xf];
37 | str[k++] = hexDigits[byte0 & 0xf];
38 | }
39 | // 转换成String并返回
40 | return new String(str);
41 | } catch (Exception e) {
42 | return null;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/util/HttpServletRequestUtil.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.util;
2 |
3 | import javax.servlet.http.HttpServletRequest;
4 |
5 | /**
6 | * 获取Request中的键值对数据
7 | * @Author: Mr_OO
8 | * @Date: 2022/3/1 13:48
9 | */
10 | public class HttpServletRequestUtil {
11 | public static int getInt(HttpServletRequest request, String key) {
12 | try {
13 | return Integer.decode(request.getParameter(key));
14 | } catch (Exception e) {
15 | return -1000;
16 | }
17 | }
18 |
19 | public static long getLong(HttpServletRequest request,String key) {
20 | try {
21 | return Long.valueOf(request.getParameter(key));
22 | } catch (Exception e) {
23 | return -1000L;
24 | }
25 | }
26 |
27 | public static double getDouble(HttpServletRequest request,String key) {
28 | try {
29 | return Double.valueOf(request.getParameter(key));
30 | } catch (Exception e) {
31 | return -1000d;
32 | }
33 | }
34 |
35 | public static boolean getBoolean(HttpServletRequest request,String key) {
36 | try {
37 | return Boolean.valueOf(request.getParameter(key));
38 | } catch (Exception e) {
39 | return false;
40 | }
41 | }
42 |
43 | public static String getString(HttpServletRequest request,String key) {
44 | try {
45 | String result = request.getParameter(key);
46 | if (result != null) {
47 | result = result.trim();
48 | }
49 | if("".equals(result)) {
50 | result = null;
51 | }
52 | return result;
53 | } catch (Exception e) {
54 | return null;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/util/ImageUtil.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.util;
2 |
3 | import java.text.SimpleDateFormat;
4 | import java.util.Date;
5 | import java.util.Random;
6 |
7 | /**
8 | * 图片处理工具类
9 | * @Author: Mr_OO
10 | * @Date: 2022/3/31 21:13
11 | */
12 | public class ImageUtil {
13 |
14 | public static final String IMAGE_URL_PRE = "http://101.43.139.237:8081/";
15 |
16 | /**
17 | * 日期格式
18 | */
19 | private static final SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
20 | /**
21 | * 随机数生成对象
22 | */
23 | private static final Random random = new Random();
24 |
25 | /**
26 | * 随机文件名生成算法
27 | * @return
28 | */
29 | public static String getRandomFileName(String userId, String fileName) {
30 | //获取随机的五位数
31 | int ranNum = random.nextInt(89999) + 10000;
32 | //当前年月日小时分秒
33 | String nowTimeStr = sDateFormat.format(new Date()).substring(7);
34 | //账号后半部分
35 | String userIdLast = userId.substring(userId.length() / 2);
36 | //文件后缀
37 | String imageEx = fileName.substring(fileName.lastIndexOf("."));
38 | return userIdLast + nowTimeStr + ranNum + imageEx;
39 | }
40 |
41 | /**
42 | * 获取图片远程访问URL后缀
43 | * @param result
44 | * @return
45 | */
46 | public static String getImageUrl(String[] result) {
47 | if (result.length < 2) {
48 | return null;
49 | } else {
50 | return "/" + result[0] + "/" + result[1];
51 | }
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/util/PageCalculator.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.util;
2 |
3 | /**
4 | * 分页查询 —— 行索引计算工具
5 | * @Author: Mr_OO
6 | * @Date: 2022/3/8 12:38
7 | */
8 | public class PageCalculator {
9 | public static int calculatorRowIndex(int pageIndex, int pageSize) {
10 | return (pageIndex >= 0) ? pageIndex * pageSize : 0;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/oym/cms/util/PasswordHelper.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.util;
2 |
3 | import com.oym.cms.entity.User;
4 | import com.oym.cms.enums.UserIdStatusEnum;
5 | import com.oym.cms.enums.UserPositionEnum;
6 | import org.apache.shiro.crypto.hash.SimpleHash;
7 | import org.apache.shiro.util.ByteSource;
8 |
9 | /**
10 | * 密码生成工具
11 | * @Author: Mr_OO
12 | * @Date: 2022/3/4 9:41
13 | */
14 | public class PasswordHelper {
15 | private final static String ALGORITHM_NAME = "MD5";
16 | private final static int HASH_ITERATIONS = 20;
17 |
18 | /**
19 | * 对用户密码加密,并将密码注入对象
20 | * @param user
21 | */
22 | public static void encryptPassword(User user) {
23 | String newPassword = new SimpleHash(ALGORITHM_NAME, user.getUserPassword(),
24 | ByteSource.Util.bytes(user.getUserId()), HASH_ITERATIONS).toHex();
25 | user.setUserPassword(newPassword);
26 | }
27 |
28 | /**
29 | * 获取加密后的新密码
30 | * @param userId
31 | * @param userPassword
32 | * @return
33 | */
34 | public static String encryptPassword(String userId, String userPassword) {
35 | String newPassword = new SimpleHash(ALGORITHM_NAME, userPassword,
36 | ByteSource.Util.bytes(userId), HASH_ITERATIONS).toHex();
37 | return newPassword;
38 | }
39 |
40 |
41 | public static void main(String[] args) {
42 | User user = new User();
43 | user.setUserId("2018110429");
44 | user.setUserName("欧阳鸣");
45 | user.setUserPosition(UserPositionEnum.STUDENT.getStatus());
46 | user.setUserStatus(UserIdStatusEnum.OK.getStatus());
47 |
48 | //密码生成
49 | String newPassword = new SimpleHash(ALGORITHM_NAME, "20000602",
50 | ByteSource.Util.bytes(user.getUserId()), HASH_ITERATIONS).toHex();
51 | System.out.println("加密后的密码是:" + newPassword);
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/resources/FastDFSConfig.properties:
--------------------------------------------------------------------------------
1 | #FastDFS
2 | connect_timeout=10
3 | network_timeout=30
4 | charset=UTF-8
5 | http.tracker_http_port=9080
6 | tracker_server=101.43.139.237:22122
--------------------------------------------------------------------------------
/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8080
3 | servlet:
4 | context-path: /
5 | encoding:
6 | charset: UTF-8
7 | enabled: true
8 | force: true
9 | tomcat:
10 | uri-encoding: UTF-8
11 |
12 | #数据库驱动
13 | jdbc:
14 | driver: com.mysql.cj.jdbc.Driver
15 | url: jdbc:mysql://localhost:3306/cms?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
16 | username: WnplV/ietfQ=
17 | password: DAnmDPxeeqw=
18 |
19 | #Mybatis
20 | mybatis_config_file: mybatis-config.xml
21 | mybatis:
22 | mapper-locations: /mapper/**.xml
23 | type_alias_package: com.oym.cms.entity
24 |
25 | #Redis
26 | redis:
27 | hostname: 127.0.0.1
28 | port: 6379
29 | pool:
30 | maxActive: 200
31 | maxIdle: 50
32 | maxWait: 3000
33 | testOnBorrow: true
34 | expire: 1800
35 | timeout: 1800
36 |
37 | com.mchange.v2.log.MLog: com.mchange.v2.log.FallbackMLog
38 | com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL: OFF
39 | multipart.enabled: true
40 |
41 | #区块链
42 | cryptoMaterial:
43 | certPath: "conf"
44 | network:
45 | peers:
46 | - "101.43.139.237:20200"
47 | - "101.43.139.237:20201"
48 | account:
49 | keyStoreDir: "account"
50 | accountFileFormat: "pem"
51 | threadPool:
52 | maxBlockingQueueSize: "102400"
--------------------------------------------------------------------------------
/src/main/resources/conf/ca.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIBVzCB/wIJAP6oLZBaSpIRMAoGCCqGSM49BAMCMDUxDjAMBgNVBAMMBWNoYWlu
3 | MRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAgFw0yMjA0MTAx
4 | MDMwMjdaGA8yMTIyMDMxNzEwMzAyN1owNTEOMAwGA1UEAwwFY2hhaW4xEzARBgNV
5 | BAoMCmZpc2NvLWJjb3MxDjAMBgNVBAsMBWNoYWluMFYwEAYHKoZIzj0CAQYFK4EE
6 | AAoDQgAEjEyAQieq4FuCZ7wdZF7jvPn4sA43t3lfkQsFSOyT0Axp8X7jp+qE5tf3
7 | /sQcWGcYS13QCjAFFgzGGhhVWHTh/TAKBggqhkjOPQQDAgNHADBEAiBYd9GeGaxH
8 | ITkuYUF7LXg5P+5M/T6fshM8SBRGcgLEnQIgJemL3vvjxnhx9ppubTmH+dEtaMSt
9 | kBCanizxTTJRdyo=
10 | -----END CERTIFICATE-----
11 |
--------------------------------------------------------------------------------
/src/main/resources/conf/sdk.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIBdzCCAR6gAwIBAgIJAKvKWQu12aZUMAoGCCqGSM49BAMCMDcxDzANBgNVBAMM
3 | BmFnZW5jeTETMBEGA1UECgwKZmlzY28tYmNvczEPMA0GA1UECwwGYWdlbmN5MCAX
4 | DTIyMDQxMDEwMzAyN1oYDzIxMjIwMzE3MTAzMDI3WjAxMQwwCgYDVQQDDANzZGsx
5 | EzARBgNVBAoMCmZpc2NvLWJjb3MxDDAKBgNVBAsMA3NkazBWMBAGByqGSM49AgEG
6 | BSuBBAAKA0IABCdXt4kiIW/ygiQLrbnBRL537h/Um2fQtkL300KCmMfkxQ7p3Mrk
7 | Jru52gLsBcq/yha9lq0Py0VH0bnvZEHZ/4WjGjAYMAkGA1UdEwQCMAAwCwYDVR0P
8 | BAQDAgXgMAoGCCqGSM49BAMCA0cAMEQCIGLSMOKw6qRE4wMN9nfca+Tz1TA9mo7F
9 | rnyZ6VOnKptzAiBNEYWqH4nghlBuj0RbOg9urqZOW+O3Ztpu5J34nI3YXA==
10 | -----END CERTIFICATE-----
11 | -----BEGIN CERTIFICATE-----
12 | MIIBcDCCARagAwIBAgIJAPibx2ORKjqCMAoGCCqGSM49BAMCMDUxDjAMBgNVBAMM
13 | BWNoYWluMRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAeFw0y
14 | MjA0MTAxMDMwMjdaFw0zMjA0MDcxMDMwMjdaMDcxDzANBgNVBAMMBmFnZW5jeTET
15 | MBEGA1UECgwKZmlzY28tYmNvczEPMA0GA1UECwwGYWdlbmN5MFYwEAYHKoZIzj0C
16 | AQYFK4EEAAoDQgAEcyfITnCsXa1ce/v9AbqTEuKGtpROtY1T1CfKwjkDnIInJWTa
17 | DOMWWfl/uij7iMZ/cTCYQTHpJ5cPO3DFV/wrSaMQMA4wDAYDVR0TBAUwAwEB/zAK
18 | BggqhkjOPQQDAgNIADBFAiEAslS3O8UnlYzzn8ZabrD9cLotoSLzT064cwnnQ9jc
19 | gJgCIBRx+PXZ0Xyv+1vTisOT5Z8q/y7p6gxkR3DTxyPOOVtz
20 | -----END CERTIFICATE-----
21 | -----BEGIN CERTIFICATE-----
22 | MIIBVzCB/wIJAP6oLZBaSpIRMAoGCCqGSM49BAMCMDUxDjAMBgNVBAMMBWNoYWlu
23 | MRMwEQYDVQQKDApmaXNjby1iY29zMQ4wDAYDVQQLDAVjaGFpbjAgFw0yMjA0MTAx
24 | MDMwMjdaGA8yMTIyMDMxNzEwMzAyN1owNTEOMAwGA1UEAwwFY2hhaW4xEzARBgNV
25 | BAoMCmZpc2NvLWJjb3MxDjAMBgNVBAsMBWNoYWluMFYwEAYHKoZIzj0CAQYFK4EE
26 | AAoDQgAEjEyAQieq4FuCZ7wdZF7jvPn4sA43t3lfkQsFSOyT0Axp8X7jp+qE5tf3
27 | /sQcWGcYS13QCjAFFgzGGhhVWHTh/TAKBggqhkjOPQQDAgNHADBEAiBYd9GeGaxH
28 | ITkuYUF7LXg5P+5M/T6fshM8SBRGcgLEnQIgJemL3vvjxnhx9ppubTmH+dEtaMSt
29 | kBCanizxTTJRdyo=
30 | -----END CERTIFICATE-----
31 |
--------------------------------------------------------------------------------
/src/main/resources/conf/sdk.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQguMc21S4gO+dM57mivj5U
3 | oduzl/Kzx4fw9YEN4K7Ua4ahRANCAAQnV7eJIiFv8oIkC625wUS+d+4f1Jtn0LZC
4 | 99NCgpjH5MUO6dzK5Ca7udoC7AXKv8oWvZatD8tFR9G572RB2f+F
5 | -----END PRIVATE KEY-----
6 |
--------------------------------------------------------------------------------
/src/main/resources/conf/sdk.publickey:
--------------------------------------------------------------------------------
1 | 2757b78922216ff282240badb9c144be77ee1fd49b67d0b642f7d3428298c7e4c50ee9dccae426bbb9da02ec05cabfca16bd96ad0fcb4547d1b9ef6441d9ff85
2 |
--------------------------------------------------------------------------------
/src/main/resources/contract/CertificateIQ.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.4.25;
2 | pragma experimental ABIEncoderV2;
3 |
4 | import "./Table.sol";
5 |
6 | contract CertificateIQ{
7 |
8 | event registerResult(int ret);
9 | event createResult(int ret);
10 |
11 | /*用于临时接收查询得到的数据*/
12 | struct CertificateItem {
13 | uint256 size;
14 | uint256[] ID;
15 | string[] schoolFlag;
16 | string[] stuNumber;
17 | string[] userName;
18 | string[] cmsName;
19 | string[] cmsType;
20 | string[] cmsWinTime;
21 | string[] cmsDesc;
22 | string[] cmsUrl;
23 | }
24 |
25 | string constant TABLE_NAME = "t_cms";
26 |
27 | // 证书信息表
28 | // | 证书id | 学校标识 | 学号 | 姓名 | 证书名称 | 证书类别 | 颁发时间 | 证书描述 | 证书凭证URL |
29 | // |---------|------------|-----------|----------|---------|---------|------------|---------|-----------|
30 | // | ID | schoolFlag | stuNumber | userName | cmsName | cmsType | cmsWinTime | cmsDesc | cmsUrl |
31 | // |---------|------------|-----------|----------|---------|---------|------------|---------|-----------|
32 | //
33 |
34 | // 创建表
35 | function create()
36 | public
37 | returns(int)
38 | {
39 | TableFactory tf = TableFactory(0x1001);
40 | int count = tf.createTable(TABLE_NAME, "ID", "schoolFlag,stuNumber,userName,cmsName,cmsType,cmsWinTime,cmsDesc,cmsUrl");
41 | emit createResult(count);
42 | return count;
43 | }
44 |
45 | //添加证书基本信息
46 | function register(string schoolFlag, string stuNumber, string userName,
47 | string cmsName, string cmsType, string cmsWinTime, string cmsDesc, string cmsUrl)
48 | public
49 | returns(int)
50 | {
51 | Table table = TableFactory(0x1001).openTable(TABLE_NAME);
52 | Entry entry = table.newEntry();
53 | entry.set("ID",int(1));
54 | entry.set("schoolFlag", schoolFlag);
55 | entry.set("stuNumber", stuNumber);
56 | entry.set("userName", userName);
57 | entry.set("cmsName", cmsName);
58 | entry.set("cmsType", cmsType);
59 | entry.set("cmsWinTime", cmsWinTime);
60 | entry.set("cmsDesc", cmsDesc);
61 | entry.set("cmsUrl", cmsUrl);
62 | int count = table.insert(uint2str(1), entry);
63 | int ret = 0;
64 | if (count != 1) {
65 | ret = 2;
66 | }
67 | emit registerResult(ret);
68 | return ret;
69 | }
70 |
71 | /*根据学号查询证书集合,备注:只返回部分重要信息*/
72 | function select(string stuNumber)
73 | public
74 | view
75 | returns(uint256, string[], string[], string[], string[], string[])
76 | {
77 | Table table = TableFactory(0x1001).openTable(TABLE_NAME);
78 | Condition condition = table.newCondition();
79 | condition.EQ("stuNumber", stuNumber);
80 | Entries entries = table.select(uint2str(1), condition);
81 | uint256 size= uint256(entries.size());
82 | CertificateItem memory item = CertificateItem(size, new uint[](size),
83 | new string[](size), new string[](size), new string[](size), new string[](size),
84 | new string[](size), new string[](size), new string[](size), new string[](size));
85 | item.size = size;
86 | for (uint256 i = 0; i < size; i++) {
87 | Entry entry = entries.get(int(i));
88 | item.cmsName[i] = entry.getString("cmsName");
89 | item.cmsType[i] = entry.getString("cmsType");
90 | item.cmsWinTime[i] = entry.getString("cmsWinTime");
91 | item.cmsDesc[i] = entry.getString("cmsDesc");
92 | item.cmsUrl[i] = entry.getString("cmsUrl");
93 | }
94 | return (item.size, item.cmsName, item.cmsType, item.cmsWinTime, item.cmsDesc, item.cmsUrl);
95 | }
96 |
97 | function uint2str(uint256 i) constant returns (string) {
98 | if (i == 0) return "0";
99 | uint j = i;
100 | uint length;
101 | while (j != 0){
102 | length++;
103 | j /= 10;
104 | }
105 | bytes memory bstr = new bytes(length);
106 | uint k = length - 1;
107 | while (i != 0){
108 | bstr[k--] = byte(48 + i % 10);
109 | i /= 10;
110 | }
111 | return string(bstr);
112 | }
113 | }
--------------------------------------------------------------------------------
/src/main/resources/contract/Table.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.4.25;
2 | pragma experimental ABIEncoderV2;
3 |
4 | contract TableFactory {
5 | function openTable(string memory) public view returns (Table); //open table
6 | function createTable(string, string, string) public returns (int256); //create table
7 | }
8 |
9 | //select condition
10 | contract Condition {
11 | function EQ(string, int256) public;
12 | function EQ(string, string) public;
13 |
14 | function NE(string, int256) public;
15 | function NE(string, string) public;
16 |
17 | function GT(string, int256) public;
18 | function GE(string, int256) public;
19 |
20 | function LT(string, int256) public;
21 | function LE(string, int256) public;
22 |
23 | function limit(int256) public;
24 | function limit(int256, int256) public;
25 | }
26 |
27 | //one record
28 | contract Entry {
29 | function getInt(string) public view returns (int256);
30 | function getUInt(string) public view returns (int256);
31 | function getAddress(string) public view returns (address);
32 | function getBytes64(string) public view returns (bytes1[64]);
33 | function getBytes32(string) public view returns (bytes32);
34 | function getString(string) public view returns (string);
35 |
36 | function set(string, int256) public;
37 | function set(string, uint256) public;
38 | function set(string, string) public;
39 | function set(string, address) public;
40 | }
41 |
42 | //record sets
43 | contract Entries {
44 | function get(int256) public view returns (Entry);
45 | function size() public view returns (int256);
46 | }
47 |
48 | //Table main contract
49 | contract Table {
50 | function select(string, Condition) public view returns (Entries);
51 | function insert(string, Entry) public returns (int256);
52 | function update(string, Entry, Condition) public returns (int256);
53 | function remove(string, Condition) public returns (int256);
54 |
55 | function newEntry() public view returns (Entry);
56 | function newCondition() public view returns (Condition);
57 | }
58 |
59 | contract KVTableFactory {
60 | function openTable(string) public view returns (KVTable);
61 | function createTable(string, string, string) public returns (int256);
62 | }
63 |
64 | //KVTable per permiary key has only one Entry
65 | contract KVTable {
66 | function get(string) public view returns (bool, Entry);
67 | function set(string, Entry) public returns (int256);
68 | function newEntry() public view returns (Entry);
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/resources/mapper/JurisdicitonMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
14 |
--------------------------------------------------------------------------------
/src/main/resources/mapper/UserMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
14 |
15 |
16 | UPDATE
17 | tb_user
18 |
19 | user_password = #{userPassword}
20 |
21 | WHERE
22 | user_id = #{userId}
23 |
24 |
--------------------------------------------------------------------------------
/src/main/resources/mybatis-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/main/resources/slf4j.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | %d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/test/java/com/oym/cms/CmsApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class CmsApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/test/java/com/oym/cms/contract/ContractTest.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.contract;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.oym.cms.client.ContractClient;
5 | import com.oym.cms.entity.Certificate;
6 | import com.oym.cms.enums.DTOMsgEnum;
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 | import org.springframework.boot.test.context.SpringBootTest;
10 | import org.springframework.test.context.junit4.SpringRunner;
11 |
12 | import javax.annotation.Resource;
13 | import java.util.Date;
14 | import java.util.List;
15 |
16 | /**
17 | * @Author: Mr_OO
18 | * @Date: 2022/4/10 21:33
19 | */
20 | @RunWith(SpringRunner.class)
21 | @SpringBootTest
22 | public class ContractTest {
23 |
24 | @Resource
25 | private ContractClient contractClient;
26 |
27 | @Test
28 | public void insertTest() {
29 | String schoolFlag = "sicnu";
30 | String stuNumber = "2018110428";
31 | String userName = "罗胜";
32 | String cmsName = "英语CET-4证书";
33 | String cmsType = "1003";
34 | String cmsWinTime = String.valueOf(new Date().getTime());
35 | String cmsDesc = "大学英语四级证书";
36 | String cmsUrl = "/group1/M00/00/00/CgAYCGJS1fyABmBfAAACk-NVe_Q056.png";
37 | int res = contractClient.registerCertificate(schoolFlag, stuNumber, userName, cmsName, cmsType,
38 | cmsWinTime, cmsDesc, cmsUrl);
39 | System.out.println("插入结果为:" + DTOMsgEnum.stateOf(res).getStatusInfo());
40 | }
41 |
42 | @Test
43 | public void queryTest() {
44 | List res = contractClient.queryCertificateList("2018110429");
45 | System.out.println("查询结果为:" + JSON.toJSONString(res));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/java/com/oym/cms/mapper/JurisdictionMapperTest.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.mapper;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | import javax.annotation.Resource;
9 | import java.util.List;
10 |
11 | /**
12 | * @Author: Mr_OO
13 | * @Date: 2022/3/4 10:57
14 | */
15 | @RunWith(SpringRunner.class)
16 | @SpringBootTest
17 | public class JurisdictionMapperTest {
18 |
19 | @Resource
20 | private JurisdictionMapper jurisdictionMapper;
21 |
22 | @Test
23 | public void queryAllUrls() {
24 | List list = jurisdictionMapper.queryAllUrls();
25 | for (String s : list) {
26 | System.out.println(s);
27 | }
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/java/com/oym/cms/mapper/UserMapperTest.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.mapper;
2 |
3 | import com.oym.cms.entity.User;
4 | import org.junit.Test;
5 | import org.junit.runner.RunWith;
6 | import org.springframework.boot.test.context.SpringBootTest;
7 | import org.springframework.test.context.junit4.SpringRunner;
8 |
9 | import javax.annotation.Resource;
10 |
11 | /**
12 | * @Author: Mr_OO
13 | * @Date: 2022/3/4 20:45
14 | */
15 | @RunWith(SpringRunner.class)
16 | @SpringBootTest
17 | public class UserMapperTest {
18 |
19 | @Resource
20 | private UserMapper userMapper;
21 |
22 | @Test
23 | public void queryById() {
24 | User user = userMapper.queryUserById("2019110117");
25 | System.out.println(user.toString());
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/test/java/com/oym/cms/service/CertificateServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.service;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.oym.cms.config.redis.JedisUtil;
5 | import org.junit.Test;
6 | import org.junit.runner.RunWith;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 | import org.springframework.test.context.junit4.SpringRunner;
9 |
10 | import javax.annotation.Resource;
11 |
12 | /**
13 | * @Author: Mr_OO
14 | * @Date: 2022/3/7 19:36
15 | */
16 | @RunWith(SpringRunner.class)
17 | @SpringBootTest
18 | public class CertificateServiceImpl {
19 |
20 | @Resource
21 | private CertificateService certificateService;
22 | @Resource
23 | private JedisUtil.Keys jedisKeys;
24 | @Resource
25 | private JedisUtil.Strings jedisStrings;
26 |
27 | @Test
28 | public void addTest() {
29 |
30 | }
31 |
32 | @Test
33 | public void queryTest() {
34 | System.out.println(JSON.toJSONString(certificateService
35 | .queryCertificateByUserId("2018110429", 1001, 0, 5)));
36 | }
37 |
38 | @Test
39 | public void redisTest() {
40 | jedisStrings.set("1", "111");
41 | System.out.println(jedisStrings.get("1"));
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/test/java/com/oym/cms/service/UserServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.oym.cms.service;
2 |
3 | import com.oym.cms.dto.UserDTO;
4 | import com.oym.cms.enums.DTOMsgEnum;
5 | import org.junit.Test;
6 | import org.junit.runner.RunWith;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 | import org.springframework.test.context.junit4.SpringRunner;
9 |
10 | import javax.annotation.Resource;
11 |
12 | /**
13 | * @Author: Mr_OO
14 | * @Date: 2022/3/4 20:52
15 | */
16 | @RunWith(SpringRunner.class)
17 | @SpringBootTest
18 | public class UserServiceTest {
19 |
20 | @Resource
21 | private UserService userService;
22 |
23 | @Test
24 | public void queryById() {
25 | UserDTO user = userService.queryUserById("2019110117");
26 | System.out.println("接口调用情况:" + DTOMsgEnum.stateOf(user.getMsg()).getStatusInfo());
27 | System.out.println("用户信息为:" + user.getUser().toString());
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------