commit 07498b55adc161e1a6bca38569b1f829bc0240a7
Author: DESKTOP-4U0TDEF\20371 <2037158277@qq.com>
Date: Mon Jul 12 14:51:34 2021 +0800
搭建项目的框架
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java
new file mode 100644
index 0000000..a45eb6b
--- /dev/null
+++ b/.mvn/wrapper/MavenWrapperDownloader.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+ private static final String WRAPPER_VERSION = "0.5.6";
+ /**
+ * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+ */
+ private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+ /**
+ * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+ * use instead of the default one.
+ */
+ private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+ ".mvn/wrapper/maven-wrapper.properties";
+
+ /**
+ * Path where the maven-wrapper.jar will be saved to.
+ */
+ private static final String MAVEN_WRAPPER_JAR_PATH =
+ ".mvn/wrapper/maven-wrapper.jar";
+
+ /**
+ * Name of the property which should be used to override the default download url for the wrapper.
+ */
+ private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+ public static void main(String args[]) {
+ System.out.println("- Downloader started");
+ File baseDirectory = new File(args[0]);
+ System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+ // If the maven-wrapper.properties exists, read it and check if it contains a custom
+ // wrapperUrl parameter.
+ File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+ String url = DEFAULT_DOWNLOAD_URL;
+ if (mavenWrapperPropertyFile.exists()) {
+ FileInputStream mavenWrapperPropertyFileInputStream = null;
+ try {
+ mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+ Properties mavenWrapperProperties = new Properties();
+ mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+ url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+ } catch (IOException e) {
+ System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+ } finally {
+ try {
+ if (mavenWrapperPropertyFileInputStream != null) {
+ mavenWrapperPropertyFileInputStream.close();
+ }
+ } catch (IOException e) {
+ // Ignore ...
+ }
+ }
+ }
+ System.out.println("- Downloading from: " + url);
+
+ File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+ if (!outputFile.getParentFile().exists()) {
+ if (!outputFile.getParentFile().mkdirs()) {
+ System.out.println(
+ "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+ }
+ }
+ System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+ try {
+ downloadFileFromURL(url, outputFile);
+ System.out.println("Done");
+ System.exit(0);
+ } catch (Throwable e) {
+ System.out.println("- Error downloading");
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+ if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+ String username = System.getenv("MVNW_USERNAME");
+ char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+ Authenticator.setDefault(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(username, password);
+ }
+ });
+ }
+ URL website = new URL(urlString);
+ ReadableByteChannel rbc;
+ rbc = Channels.newChannel(website.openStream());
+ FileOutputStream fos = new FileOutputStream(destination);
+ fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+ fos.close();
+ rbc.close();
+ }
+
+}
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000..2cc7d4a
Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..ffdc10e
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
diff --git a/mvnw b/mvnw
new file mode 100644
index 0000000..a16b543
--- /dev/null
+++ b/mvnw
@@ -0,0 +1,310 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`which java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+ if [ -z "$1" ]
+ then
+ echo "Path not specified to find_maven_basedir"
+ return 1
+ fi
+
+ basedir="$1"
+ wdir="$1"
+ while [ "$wdir" != '/' ] ; do
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+ if [ -d "${wdir}" ]; then
+ wdir=`cd "$wdir/.."; pwd`
+ fi
+ # end of workaround
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found .mvn/wrapper/maven-wrapper.jar"
+ fi
+else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+ fi
+ if [ -n "$MVNW_REPOURL" ]; then
+ jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ fi
+ wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
+
+ if command -v wget > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ # Running the downloader
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Running MavenWrapperDownloader.java ..."
+ fi
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+ fi
+ fi
+ fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+ MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
new file mode 100644
index 0000000..c8d4337
--- /dev/null
+++ b/mvnw.cmd
@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Found %WRAPPER_JAR%
+ )
+) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_URL%
+ )
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..04c884d
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,183 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.4.1
+
+
+ com.xkrs
+ fire_point
+ 0.0.1-SNAPSHOT
+ fire_point
+ 火点项目
+
+ 5.19
+ 0.11.2
+ 4.5.12
+ 6.1.5.Final
+ 5.4.20.Final
+ UTF-8
+ UTF-8
+ 11
+ 11
+ 11
+ 1.2.76
+ 2.10.5
+ 2.10.5
+ 5.0.0
+ 5.0.0
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.apache.commons
+ commons-pool2
+
+
+ org.postgresql
+ postgresql
+
+
+ mysql
+ mysql-connector-java
+
+
+ io.jsonwebtoken
+ jjwt-api
+ ${jjwt.version}
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ ${jjwt.version}
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ ${jjwt.version}
+ runtime
+
+
+ nl.basjes.parse.useragent
+ yauaa
+ ${yauaa.version}
+
+
+ org.apache.httpcomponents
+ httpmime
+ ${httpmime.version}
+
+
+ org.hibernate.validator
+ hibernate-validator
+ ${hibernate-validator.version}
+
+
+ org.hibernate
+ hibernate-spatial
+ ${hibernate-spatial.version}
+
+
+ com.alibaba
+ fastjson
+ ${fastjson.version}
+
+
+
+
+ io.springfox
+ springfox-swagger-ui
+ ${springfox-swagger-ui.version}
+
+
+
+ io.springfox
+ springfox-swagger2
+ ${springfox-swagger2.version}
+
+
+
+
+ org.apache.poi
+ poi
+ ${poi.version}
+
+
+
+ org.apache.poi
+ poi-ooxml
+ ${poi-ooxml.version}
+
+
+
+
+
+
+
+
+ src/main/java
+
+ **/*.properties
+ **/*.xml
+
+ false
+
+
+ src/main/resources
+
+ **/*.properties
+ **/*.xml
+ **/*.txt
+
+ false
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/src/main/java/com/xkrs/FirePointApplication.java b/src/main/java/com/xkrs/FirePointApplication.java
new file mode 100644
index 0000000..3222b01
--- /dev/null
+++ b/src/main/java/com/xkrs/FirePointApplication.java
@@ -0,0 +1,13 @@
+package com.xkrs;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class FirePointApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(FirePointApplication.class, args);
+ }
+
+}
diff --git a/src/main/java/com/xkrs/common/account/AccountCredentials.java b/src/main/java/com/xkrs/common/account/AccountCredentials.java
new file mode 100644
index 0000000..8513b0f
--- /dev/null
+++ b/src/main/java/com/xkrs/common/account/AccountCredentials.java
@@ -0,0 +1,36 @@
+package com.xkrs.common.account;
+
+/**
+ * 账户实体
+ * @author tajochen
+ */
+public class AccountCredentials {
+
+ private String userName;
+ private String password;
+ private boolean remember;
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public boolean isRemember() {
+ return remember;
+ }
+
+ public void setRemember(boolean remember) {
+ this.remember = remember;
+ }
+}
diff --git a/src/main/java/com/xkrs/common/account/CustomAuthenticationProvider.java b/src/main/java/com/xkrs/common/account/CustomAuthenticationProvider.java
new file mode 100644
index 0000000..908f562
--- /dev/null
+++ b/src/main/java/com/xkrs/common/account/CustomAuthenticationProvider.java
@@ -0,0 +1,113 @@
+package com.xkrs.common.account;
+
+import com.xkrs.model.entity.SysAuthorityEntity;
+import com.xkrs.model.entity.SysUserEntity;
+import com.xkrs.service.SysAuthorityService;
+import com.xkrs.service.SysRoleService;
+import com.xkrs.service.SysUserService;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.DisabledException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.xkrs.utils.EncryptDecryptUtil.encry256;
+
+/**
+ * 自定义认证Provider
+ * @author tajochen
+ */
+@Component
+public class CustomAuthenticationProvider implements AuthenticationProvider {
+
+ @Resource
+ private SysUserService sysUserService;
+
+ @Resource
+ private SysRoleService sysRoleService;
+
+ @Resource
+ private SysAuthorityService sysAuthorityService;
+
+ /**
+ * 初使化时将已静态化的Service实例化
+ */
+ protected static CustomAuthenticationProvider customAuthenticationProvider;
+
+ /**
+ * 通过@PostConstruct实现初始化bean之前进行的操作
+ */
+ @PostConstruct
+ public void init() {
+ customAuthenticationProvider = this;
+ customAuthenticationProvider.sysUserService = this.sysUserService;
+ customAuthenticationProvider.sysRoleService = this.sysRoleService;
+ customAuthenticationProvider.sysAuthorityService = this.sysAuthorityService;
+ }
+
+ /**
+ * 用户认证授权
+ * @param authentication
+ * @return
+ * @throws AuthenticationException
+ */
+ @Override
+ public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+ // 获取认证的用户名 & 密码
+ String userName = authentication.getName();
+ String password = authentication.getCredentials().toString();
+
+ SysUserEntity userEntity = customAuthenticationProvider.sysUserService.getSysUserByUserName(userName);
+
+ // 检查用户是否存在
+ if(userEntity == null){
+ throw new BadCredentialsException("user don't exist");
+ }
+
+ // 检查用户是否激活
+ if(userEntity.getActiveFlag().intValue() != 0){
+ throw new DisabledException("user not activated");
+ }
+
+ //检查用户状态是否正常
+ if(userEntity.getStatusCode() != 0){
+ throw new DisabledException("user state exception");
+ }
+
+ // 认证逻辑
+ String encryptPassword = encry256(password + userEntity.getSalt());
+ if (encryptPassword.equals(userEntity.getPassword())) {
+ // 设置权限列表
+ ArrayList permissions = new ArrayList<>();
+ List integers = customAuthenticationProvider.sysAuthorityService.selectAuthorityByUserId(userEntity.getId());
+ List permissionList = customAuthenticationProvider.sysAuthorityService.findAllByIdIn(integers);
+ for(SysAuthorityEntity sysAuthorityEntity : permissionList) {
+ permissions.add(new GrantedAuthorityImpl(sysAuthorityEntity.getAuthorityName()));
+ }
+ // 生成令牌
+ Authentication authToken = new UsernamePasswordAuthenticationToken(userName, encryptPassword, permissions);
+ return authToken;
+ }
+ else {
+ throw new BadCredentialsException("user password error");
+ }
+ }
+
+ /**
+ * 是否可以提供输入类型的认证服务
+ * @param authentication
+ * @return
+ */
+ @Override
+ public boolean supports(Class> authentication) {
+ return authentication.equals(UsernamePasswordAuthenticationToken.class);
+ }
+}
diff --git a/src/main/java/com/xkrs/common/account/GrantedAuthorityImpl.java b/src/main/java/com/xkrs/common/account/GrantedAuthorityImpl.java
new file mode 100644
index 0000000..318a217
--- /dev/null
+++ b/src/main/java/com/xkrs/common/account/GrantedAuthorityImpl.java
@@ -0,0 +1,25 @@
+package com.xkrs.common.account;
+
+import org.springframework.security.core.GrantedAuthority;
+
+/**
+ * 权限认证服务
+ * @author tajochen
+ */
+public class GrantedAuthorityImpl implements GrantedAuthority {
+
+ private String authority;
+
+ public GrantedAuthorityImpl(String authority) {
+ this.authority = authority;
+ }
+
+ public void setAuthority(String authority) {
+ this.authority = authority;
+ }
+
+ @Override
+ public String getAuthority() {
+ return this.authority;
+ }
+}
diff --git a/src/main/java/com/xkrs/common/account/JwtAuthenticationFilter.java b/src/main/java/com/xkrs/common/account/JwtAuthenticationFilter.java
new file mode 100644
index 0000000..da3a512
--- /dev/null
+++ b/src/main/java/com/xkrs/common/account/JwtAuthenticationFilter.java
@@ -0,0 +1,28 @@
+package com.xkrs.common.account;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.filter.GenericFilterBean;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * 拦截所有需要JWT的请求,然后调用TokenAuthenticationService类的静态方法去做JWT验证
+ * @author tajochen
+ */
+public class JwtAuthenticationFilter extends GenericFilterBean {
+
+ @Override
+ public void doFilter(ServletRequest request,
+ ServletResponse response,
+ FilterChain filterChain) throws IOException, ServletException {
+ Authentication authentication = TokenAuthenticationService.getAuthentication((HttpServletRequest)request);
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ filterChain.doFilter(request,response);
+ }
+}
diff --git a/src/main/java/com/xkrs/common/account/JwtLoginFilter.java b/src/main/java/com/xkrs/common/account/JwtLoginFilter.java
new file mode 100644
index 0000000..c28d3ad
--- /dev/null
+++ b/src/main/java/com/xkrs/common/account/JwtLoginFilter.java
@@ -0,0 +1,132 @@
+package com.xkrs.common.account;
+
+import com.xkrs.common.encapsulation.OutputEncapsulation;
+import com.xkrs.common.encapsulation.PromptMessageEnum;
+import com.xkrs.model.entity.SysUserEntity;
+import com.xkrs.service.SysUserService;
+import com.xkrs.utils.IpUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import javax.annotation.Resource;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Locale;
+
+/**
+ * jwt登录过滤器
+ * @author tajochen
+ */
+public class JwtLoginFilter extends AbstractAuthenticationProcessingFilter {
+
+ private static final Logger logger = LoggerFactory.getLogger(JwtLoginFilter.class);
+
+
+ @Resource
+ private SysUserService sysUserService;
+
+ public JwtLoginFilter(String url, AuthenticationManager authManager) {
+ super(new AntPathRequestMatcher(url));
+ setAuthenticationManager(authManager);
+ }
+
+ /**
+ * 登录时验证
+ * @param req
+ * @param res
+ * @return
+ */
+ @Override
+ public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws UnsupportedEncodingException {
+ req.setCharacterEncoding("UTF-8");
+ res.setHeader("Access-Control-Allow-Origin","*");
+ res.setHeader("Access-Control-Allow-Credentials", "false");
+ AccountCredentials creds = new AccountCredentials();
+ //获取表单数据
+ String userName = req.getParameter("userName");
+ String password = req.getParameter("password");
+ String rememberMe = req.getParameter("remember");
+ //如果用户名密码为空
+ if(userName == null||password == null|| userName.trim().isEmpty()||password.trim().isEmpty()){
+ throw new BadCredentialsException("user or password is null");
+ }
+ if(rememberMe == null||rememberMe.isEmpty()){
+ rememberMe = "false";
+ }
+ creds.setUserName(userName.trim());
+ creds.setPassword(password.trim());
+ creds.setRemember(Boolean.parseBoolean(rememberMe));
+ // 返回一个验证令牌
+ return getAuthenticationManager().authenticate(
+ new UsernamePasswordAuthenticationToken(
+ creds.getUserName(),
+ creds.getPassword()
+ )
+ );
+ }
+
+ /**
+ * 验证成功后调用
+ * @param req
+ * @param response
+ * @param chain
+ * @param auth
+ * @throws IOException
+ * @throws ServletException
+ */
+ @Override
+ protected void successfulAuthentication(
+ HttpServletRequest req, HttpServletResponse response, FilterChain chain, Authentication auth) {
+ if(sysUserService==null){
+ ServletContext servletContext = req.getServletContext();
+ WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
+ sysUserService = webApplicationContext.getBean(SysUserService.class);
+ }
+ //更新用户登录信息
+ sysUserService.updateSysUserLogin(auth.getName(), IpUtil.getIpAddr(req));
+ SysUserEntity sysUserByUserName = sysUserService.getSysUserByUserName(auth.getName());
+ response.setHeader("Access-Control-Allow-Origin", "*");
+ response.setHeader("Access-Control-Allow-Credentials", "false");
+ response.setContentType("application/json");
+ response.setCharacterEncoding("UTF-8");
+ TokenAuthenticationService.addAuthentication(response, auth.getName(),auth.getAuthorities(),sysUserByUserName);
+ }
+
+ /**
+ * 验证失败后调用
+ * @param request
+ * @param response
+ * @param failed
+ * @throws IOException
+ */
+ @Override
+ protected void unsuccessfulAuthentication(HttpServletRequest request,
+ HttpServletResponse response,
+ AuthenticationException failed) throws IOException {
+ Locale locale = LocaleContextHolder.getLocale();
+ response.setHeader("Access-Control-Allow-Origin", "*");
+ response.setHeader("Access-Control-Allow-Credentials", "false");
+ response.setContentType("application/json");
+ response.setCharacterEncoding("UTF-8");
+ // 将 JWT 写入 body
+ PrintWriter out = response.getWriter();
+ out.append(OutputEncapsulation.outputEncapsulationObject(PromptMessageEnum.DATA_WRONG, failed.getLocalizedMessage(), locale));
+ response.setStatus(HttpServletResponse.SC_OK);
+ }
+}
diff --git a/src/main/java/com/xkrs/common/account/TokenAuthenticationService.java b/src/main/java/com/xkrs/common/account/TokenAuthenticationService.java
new file mode 100644
index 0000000..19b37cf
--- /dev/null
+++ b/src/main/java/com/xkrs/common/account/TokenAuthenticationService.java
@@ -0,0 +1,129 @@
+package com.xkrs.common.account;
+
+import com.xkrs.common.encapsulation.OutputEncapsulation;
+import com.xkrs.common.encapsulation.PromptMessageEnum;
+import com.xkrs.model.entity.SysUserEntity;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.security.Keys;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
+
+import javax.crypto.SecretKey;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.*;
+
+/**
+ * token认证服务
+ * @author tajochen
+ */
+public class TokenAuthenticationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(TokenAuthenticationService.class);
+ /**
+ * 过期时间6小时
+ */
+ static public final long EXPIRATIONTIME = 21_600_000;
+ /**
+ * 加密密钥
+ */
+ static public final String SECRET_KEY = "0Y9H364Q9Y908262F25LMXGIKIN5N858XM3674GWL2DD8X1DS4W6I722IRY8PS4XPNB6U303" +
+ "45HBVCUL94STG8C3Z53T7A09JJ100I56YE9894CI11PX9J71HIZ8L5Y2O504C4E2K8276425UA8734833F45K36878FXAG799QV9LXU" +
+ "JOI3XA2046UPG8TB2OT84R5T6ZB127N9ZPJ7AJMC41JVHB2WK2B6H8NL45LZNAZ666KHZH3QUT65UX6F8";
+ /**
+ * Token前缀
+ */
+ static public final String TOKEN_PREFIX = "Bearer";
+
+ /**
+ * 存放Token的Header Key
+ */
+ static final String HEADER_STRING = "Authorization";
+ static SecretKey key = Keys.hmacShaKeyFor(SECRET_KEY.getBytes());
+
+ /**
+ * JWT生成方法
+ * @param response
+ * @param userName
+ * @param authorities
+ */
+ static void addAuthentication(HttpServletResponse response, String userName,
+ Collection extends GrantedAuthority> authorities,SysUserEntity sysUserEntity) {
+
+ Locale locale = new Locale("zh", "CN");
+ Map map = new HashMap(3);
+ StringBuffer auths = new StringBuffer();
+ String authsList = "";
+ for(GrantedAuthority r : authorities) {
+ auths.append("," + r.getAuthority());
+ }
+ authsList = auths.toString();
+ if(authsList.length()>1){
+ authsList=authsList.substring(1,authsList.length());
+ }else{
+ logger.warn(userName +" has no permission!");
+ }
+ // 生成JWT
+ String jwt = Jwts.builder()
+ .setSubject(userName)
+ .setIssuer("https://www.microservice.com")
+ .setAudience(userName)
+ // 保存权限
+ .claim("auths", authsList)
+ // 有效期设置
+ .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
+ // 签名设置
+ .signWith(key)
+ .compact();
+ map.put("token",jwt);
+ map.put("role",authsList);
+ map.put("user",sysUserEntity);
+ // 将 JWT 写入 body
+ PrintWriter out = null;
+ try {
+ out = response.getWriter();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ response.setStatus(HttpServletResponse.SC_OK);
+ out.append(OutputEncapsulation.outputEncapsulationObject(PromptMessageEnum.SUCCESS, map, locale));
+ }
+
+ /**
+ * JWT验证方法
+ * @param request
+ * @return
+ */
+ static Authentication getAuthentication(HttpServletRequest request) {
+ // 从Header中拿到token
+ String token = request.getHeader(HEADER_STRING);
+ if (token != null) {
+ try {
+ // 解析 Token
+ Claims claims = Jwts.parserBuilder()
+ .setSigningKey(key).build()
+ // 去掉 Bearer
+ .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
+ .getBody();
+ // 获取用户名
+ String userName = claims.getSubject();
+ // 获取权限
+ List authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get("auths"));
+ return new UsernamePasswordAuthenticationToken(userName, null, authorities);
+ } catch(Exception e) {
+ // the sub field was missing or did not have a value
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/com/xkrs/common/config/CorsConfig.java b/src/main/java/com/xkrs/common/config/CorsConfig.java
new file mode 100644
index 0000000..7f8c32f
--- /dev/null
+++ b/src/main/java/com/xkrs/common/config/CorsConfig.java
@@ -0,0 +1,23 @@
+package com.xkrs.common.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import javax.annotation.Resource;
+
+/**
+ * 系统跨域配置
+ * @author tajochen
+ */
+@Configuration
+public class CorsConfig implements WebMvcConfigurer {
+
+ @Resource
+ private CorsInterceptor corsInterceptor;
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(corsInterceptor);
+ }
+}
diff --git a/src/main/java/com/xkrs/common/config/CorsInterceptor.java b/src/main/java/com/xkrs/common/config/CorsInterceptor.java
new file mode 100644
index 0000000..e2103c5
--- /dev/null
+++ b/src/main/java/com/xkrs/common/config/CorsInterceptor.java
@@ -0,0 +1,29 @@
+package com.xkrs.common.config;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 跨域处理
+ * @author tajochen
+ */
+@Component
+public class CorsInterceptor implements HandlerInterceptor {
+
+ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+
+ //添加跨域CORS
+ response.setHeader("Access-Control-Allow-Origin", "*");
+ response.setHeader("Access-Control-Allow-Credentials", "false");
+ response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
+ response.setHeader("Access-Control-Allow-Headers", "Content-Type , Authorization," +
+ "Accept,Origin,X-Requested-With");
+ response.setHeader("Access-Control-Max-Age", "216000");
+ response.setHeader("Content-Type","application/json;charset=UTF-8");
+ return true;
+ }
+}
+
diff --git a/src/main/java/com/xkrs/common/config/MvcConfig.java b/src/main/java/com/xkrs/common/config/MvcConfig.java
new file mode 100644
index 0000000..edce463
--- /dev/null
+++ b/src/main/java/com/xkrs/common/config/MvcConfig.java
@@ -0,0 +1,37 @@
+package com.xkrs.common.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.TaskScheduler;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * WebMVC配置
+ * @author Tajochen
+ */
+@Configuration
+public class MvcConfig implements WebMvcConfigurer {
+
+ /**
+ * 放行跨域请求
+ */
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ .allowedOrigins("*")
+ .allowedMethods("*")
+ .allowedHeaders("*");
+ }
+
+ /**
+ * 定时任务线程池更改,防止多个任务并行
+ */
+ @Bean
+ public TaskScheduler taskScheduler() {
+ final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+ scheduler.setPoolSize(5);
+ return scheduler;
+ }
+}
diff --git a/src/main/java/com/xkrs/common/config/WebSecurityConfig.java b/src/main/java/com/xkrs/common/config/WebSecurityConfig.java
new file mode 100644
index 0000000..8a8f40e
--- /dev/null
+++ b/src/main/java/com/xkrs/common/config/WebSecurityConfig.java
@@ -0,0 +1,65 @@
+package com.xkrs.common.config;
+
+import com.xkrs.common.account.CustomAuthenticationProvider;
+import com.xkrs.common.account.JwtAuthenticationFilter;
+import com.xkrs.common.account.JwtLoginFilter;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled=true)
+class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+ /**
+ * 设置 HTTP 验证规则
+ * @param http
+ * @throws Exception
+ */
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ // 关闭csrf验证
+ http.csrf().disable()
+ // 对请求进行认证
+ .authorizeRequests()
+ // 所有 / 的所有请求 都放行
+ //.antMatchers("/").permitAll()
+ // 所有OPTIONS请求都放行
+ .antMatchers(HttpMethod.OPTIONS).permitAll()
+ // 所有 /user/add 用户注册 的POST请求 都放行
+ .antMatchers(HttpMethod.POST, "/api/user/add").permitAll()
+ // 所有 /user/check/duplicate 检查用户名是否重复 的POST请求 都放行
+ .antMatchers(HttpMethod.POST, "/api/user/check/duplicate").permitAll()
+ // 所有 /login 用户登录 的POST请求 都放行
+ .antMatchers(HttpMethod.POST, "/api/login").permitAll()
+ // 所有 app 用户注册 的POST请求 都放行
+ .antMatchers(HttpMethod.POST, "/api/person-investigator/add").permitAll()
+ .antMatchers(HttpMethod.GET,"/api/user/booleanUserName").permitAll()
+ .antMatchers(HttpMethod.POST,"/importRsProjectExcel").permitAll()
+ .antMatchers(HttpMethod.POST,"/importCvProjectExcel").permitAll()
+ .antMatchers(HttpMethod.GET,"/excelOutWork").permitAll()
+ .antMatchers(HttpMethod.GET,"/selectMemberAndWorkHour").permitAll()
+ // 所有其它请求需要身份认证
+ .anyRequest().authenticated()
+ .and()
+ // 添加一个过滤器 所有访问 /login 的请求交给 JWTLoginFilter 来处理 这个类处理所有的JWT相关内容
+ .addFilterBefore(new JwtLoginFilter("/api/login", authenticationManager()),
+ UsernamePasswordAuthenticationFilter.class)
+ // 添加一个过滤器验证其他请求的Token是否合法
+ .addFilterBefore(new JwtAuthenticationFilter(),
+ UsernamePasswordAuthenticationFilter.class);
+ ;}
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ // 使用自定义身份验证组件
+ auth.authenticationProvider(new CustomAuthenticationProvider());
+ }
+}
+
diff --git a/src/main/java/com/xkrs/common/encapsulation/EncapsulationObejct.java b/src/main/java/com/xkrs/common/encapsulation/EncapsulationObejct.java
new file mode 100644
index 0000000..e11fea7
--- /dev/null
+++ b/src/main/java/com/xkrs/common/encapsulation/EncapsulationObejct.java
@@ -0,0 +1,59 @@
+package com.xkrs.common.encapsulation;
+
+import java.io.Serializable;
+
+/**
+ * 输出信息对象
+ * @author tajochen
+ * @param
+ */
+public class EncapsulationObejct implements Serializable {
+
+ /**
+ * 状态码
+ */
+ int status;
+
+ /**
+ * 提示信息
+ */
+ String msg;
+
+ /**
+ * 数据
+ */
+ T data;
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+ @Override
+ public String toString() {
+ return "EncapsulationObejct{" +
+ "status=" + status +
+ ", msg='" + msg + '\'' +
+ ", data=" + data +
+ '}';
+ }
+}
diff --git a/src/main/java/com/xkrs/common/encapsulation/OutputEncapsulation.java b/src/main/java/com/xkrs/common/encapsulation/OutputEncapsulation.java
new file mode 100644
index 0000000..9bee083
--- /dev/null
+++ b/src/main/java/com/xkrs/common/encapsulation/OutputEncapsulation.java
@@ -0,0 +1,96 @@
+package com.xkrs.common.encapsulation;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.MessageSource;
+import org.springframework.context.support.ResourceBundleMessageSource;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.FieldError;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Properties;
+
+/**
+ * 输出信息封装
+ * @author tajochen
+ */
+@Component
+public class OutputEncapsulation {
+
+ private static final Logger logger = LoggerFactory.getLogger(OutputEncapsulation.class);
+
+ /**
+ * 读取多国语言文件
+ * @return
+ */
+ public static MessageSource messageSource() {
+ Properties properties = new Properties();
+ // 使用ClassLoader加载properties配置文件生成对应的输入流
+ InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties");
+ // 使用properties对象加载输入流
+ try {
+ properties.load(in);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
+ messageSource.setBasename("i18n/messages");
+ messageSource.setDefaultEncoding("UTF-8");
+ return messageSource;
+ }
+
+ /**
+ * 封装输出数据
+ * @param promptMessageEnum
+ * @param obj
+ * @return
+ */
+ public static String outputEncapsulationObject(PromptMessageEnum promptMessageEnum, Object obj, Locale locale) {
+
+ EncapsulationObejct encapsulationObejct = new EncapsulationObejct();
+ encapsulationObejct.setStatus(promptMessageEnum.getCode());
+ encapsulationObejct.setMsg(messageSource().getMessage(promptMessageEnum.getText(),null,locale));
+ encapsulationObejct.setData(obj);
+
+ ObjectMapper objectMapper = new ObjectMapper();
+ // 忽略无法转换的对象
+ objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
+ // 忽略json字符串中不识别的属性
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ // 解决jackson无法反序列化LocalDateTime的问题,引入jsr310标准
+ JavaTimeModule javaTimeModule = new JavaTimeModule();
+ objectMapper.registerModule(javaTimeModule);
+ objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+ String strByEo = "";
+ try {
+ strByEo = objectMapper.writeValueAsString(encapsulationObejct);
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ logger.warn(e.toString());
+ }
+ return strByEo;
+ }
+
+ /**
+ * 输出请求值检验错误信息
+ * @param fieldErrors
+ * @return
+ */
+ public static String outputEncapsulationErrorList(List fieldErrors, Locale locale){
+ List errorMsg = new ArrayList<>();
+ for (FieldError fieldError : fieldErrors) {
+ String errMessage = fieldError.getDefaultMessage().subSequence(1,fieldError.getDefaultMessage().length()-1).toString();
+ errorMsg.add(messageSource().getMessage(errMessage,null,locale));
+ }
+ return outputEncapsulationObject(PromptMessageEnum.PARAM_ILLEGAL,errorMsg,locale);
+ }
+}
diff --git a/src/main/java/com/xkrs/common/encapsulation/PromptMessageEnum.java b/src/main/java/com/xkrs/common/encapsulation/PromptMessageEnum.java
new file mode 100644
index 0000000..8af04a8
--- /dev/null
+++ b/src/main/java/com/xkrs/common/encapsulation/PromptMessageEnum.java
@@ -0,0 +1,64 @@
+package com.xkrs.common.encapsulation;
+
+/**
+ * 提示信息枚举
+ * @author tajochen
+ */
+public enum PromptMessageEnum{
+
+ // 执行成功
+ SUCCESS(0, "sys.message.success"),
+
+
+ // 用户权限错误或非法操作: 1001-1999
+ USER_NOT_LOGGED(1001, "sys.message.user.not_logged_in"),
+ USER_LOGIN_ERROR(1002, "sys.message.user.login_error"),
+ USER_ACCOUNT_FORBIDDEN(1003, "sys.message.user.account_forbidden"),
+ USER_ACCOUNT_NOT_ACTIVATED(1004, "sys.message.user.account_not_activated"),
+ USER_HAS_OVERTIME(1005, "sys.message.user.overtime"),
+ USER_NO_PERMISSION(1006,"sys.message.user.no_permission"),
+ USER_ALREADY_LOGGED(1007, "sys.message.user.already_logged"),
+
+ // 请求参数错误或非法:2001-2999
+ PARAM_NULL(2001, "sys.message.param.null"),
+ PARAM_ILLEGAL(2002, "sys.message.param.illegal"),
+
+ // 数据返回错误:3001-3999
+ DATA_NONE(3001, "sys.message.data.none"),
+ DATA_WRONG(3002, "sys.message.data.wrong"),
+ DATA_EXIT(3003,"sys.message.exit"),
+
+ // 操作失败:4001-4999
+ PROCESS_FAIL(4001,"sys.message.process.fail"),
+ PROCESS_OVERTIME(4002,"sys.message.process.overtime"),
+ FILE_EXISTS(4003,"sys.message.file.exists"),
+ FILE_WRITE_ERROR(4004,"sys.message.file.write.error"),
+ FILE_READ_ERROR(4005,"sys.message.file.read.error"),
+
+ // 系统内部错误或异常:5001-5999
+ SYSTEM_INNER_ERROR(5001,"sys.message.system.inner_error"),
+ SYSTEM_ABNORMAL(5002,"sys.message.system.abnormal"),
+ SYSTEM_BUSY(5003,"sys.message.system.busy"),
+ SYSTEM_MAINTAIN(5004,"sys.message.system.maintain"),
+
+ // 数据库错误:6001-6999
+ DATABASE_ERROR(6001,"sys.message.database.error");
+
+ private int code;
+
+ private String text;
+
+ private PromptMessageEnum(int code,String text) {
+ this.code = code;
+ this.text = text;
+ }
+
+ public String getText() {
+ return this.text;
+ }
+
+ public int getCode() {
+ return this.code;
+ }
+
+}
diff --git a/src/main/java/com/xkrs/common/tool/CompareVersion.java b/src/main/java/com/xkrs/common/tool/CompareVersion.java
new file mode 100644
index 0000000..7d2d6e7
--- /dev/null
+++ b/src/main/java/com/xkrs/common/tool/CompareVersion.java
@@ -0,0 +1,33 @@
+package com.xkrs.common.tool;
+
+/**
+ * CompareVersion 比较版本号
+ * @author tajochen
+ */
+public class CompareVersion {
+
+ /**
+ * 比较三位版本号 ,若 版本1>版本2 返回 1,若版本1<版本2 返回 -1,否则返回0
+ * @param version1 版本1
+ * @param version2 版本2
+ * @return
+ */
+ public static int compareVersion(String version1, String version2) {
+ String[] v1 = version1.split("\\.");
+ String[] v2 = version2.split("\\.");
+ int n = Math.max(v1.length, v2.length);
+ for (int i = 0; i < n; i++) {
+ int v1Int = i < v1.length ? Integer.parseInt(v1[i]) : 0;
+ int v2Int = i < v2.length ? Integer.parseInt(v2[i]) : 0;
+ if (v1Int == v2Int) {
+ continue;
+ }
+ if (v1Int > v2Int){
+ return 1;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/com/xkrs/common/tool/EntityUtil.java b/src/main/java/com/xkrs/common/tool/EntityUtil.java
new file mode 100644
index 0000000..70c54b6
--- /dev/null
+++ b/src/main/java/com/xkrs/common/tool/EntityUtil.java
@@ -0,0 +1,98 @@
+package com.xkrs.common.tool;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * dao接口类处理工具
+ * @author tajochen
+ */
+public class EntityUtil {
+ private static final Logger logger = LoggerFactory.getLogger(EntityUtil.class);
+
+ /**
+ * 将数组数据转换为实体类
+ * 此处数组元素的顺序必须与实体类构造函数中的属性顺序一致
+ * @param list 数组对象集合
+ * @param clazz 实体类
+ * @param 实体类
+ * @param model 实例化的实体类
+ * @return 实体类集合
+ */
+ public static List castEntity(List