初步搭建,后面需要细化用户管理,和文件管理
commit
c9b686fcf3
|
|
@ -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/
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,2 @@
|
||||||
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
|
||||||
|
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
|
||||||
|
|
@ -0,0 +1,308 @@
|
||||||
|
#!/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.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Apache Maven Wrapper startup batch script, version 3.2.0
|
||||||
|
#
|
||||||
|
# Required ENV vars:
|
||||||
|
# ------------------
|
||||||
|
# JAVA_HOME - location of a JDK home dir
|
||||||
|
#
|
||||||
|
# Optional ENV vars
|
||||||
|
# -----------------
|
||||||
|
# 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 /usr/local/etc/mavenrc ] ; then
|
||||||
|
. /usr/local/etc/mavenrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
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
|
||||||
|
JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
|
||||||
|
else
|
||||||
|
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
|
if [ -r /etc/gentoo-release ] ; then
|
||||||
|
JAVA_HOME=$(java-config --jre-home)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -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 "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); 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="$(\unset -f command 2>/dev/null; \command -v 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
|
||||||
|
|
||||||
|
# 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/.." || exit 1; pwd)
|
||||||
|
fi
|
||||||
|
# end of workaround
|
||||||
|
done
|
||||||
|
printf '%s' "$(cd "$basedir" || exit 1; pwd)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# concatenates all lines of a file
|
||||||
|
concat_lines() {
|
||||||
|
if [ -f "$1" ]; then
|
||||||
|
# Remove \r in case we run on Windows within Git Bash
|
||||||
|
# and check out the repository with auto CRLF management
|
||||||
|
# enabled. Otherwise, we may read lines that are delimited with
|
||||||
|
# \r\n and produce $'-Xarg\r' rather than -Xarg due to word
|
||||||
|
# splitting rules.
|
||||||
|
tr -s '\r\n' ' ' < "$1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
log() {
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
printf '%s\n' "$1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
|
||||||
|
if [ -z "$BASE_DIR" ]; then
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
|
||||||
|
log "$MAVEN_PROJECTBASEDIR"
|
||||||
|
|
||||||
|
##########################################################################################
|
||||||
|
# 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.
|
||||||
|
##########################################################################################
|
||||||
|
wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
|
||||||
|
if [ -r "$wrapperJarPath" ]; then
|
||||||
|
log "Found $wrapperJarPath"
|
||||||
|
else
|
||||||
|
log "Couldn't find $wrapperJarPath, downloading it ..."
|
||||||
|
|
||||||
|
if [ -n "$MVNW_REPOURL" ]; then
|
||||||
|
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||||
|
else
|
||||||
|
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||||
|
fi
|
||||||
|
while IFS="=" read -r key value; do
|
||||||
|
# Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
|
||||||
|
safeValue=$(echo "$value" | tr -d '\r')
|
||||||
|
case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
|
||||||
|
esac
|
||||||
|
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
|
||||||
|
log "Downloading from: $wrapperUrl"
|
||||||
|
|
||||||
|
if $cygwin; then
|
||||||
|
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v wget > /dev/null; then
|
||||||
|
log "Found wget ... using wget"
|
||||||
|
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
|
||||||
|
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||||
|
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||||
|
else
|
||||||
|
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||||
|
fi
|
||||||
|
elif command -v curl > /dev/null; then
|
||||||
|
log "Found curl ... using curl"
|
||||||
|
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
|
||||||
|
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||||
|
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
|
||||||
|
else
|
||||||
|
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log "Falling back to using Java to download"
|
||||||
|
javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||||
|
javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
|
||||||
|
# For Cygwin, switch paths to Windows format before running javac
|
||||||
|
if $cygwin; then
|
||||||
|
javaSource=$(cygpath --path --windows "$javaSource")
|
||||||
|
javaClass=$(cygpath --path --windows "$javaClass")
|
||||||
|
fi
|
||||||
|
if [ -e "$javaSource" ]; then
|
||||||
|
if [ ! -e "$javaClass" ]; then
|
||||||
|
log " - Compiling MavenWrapperDownloader.java ..."
|
||||||
|
("$JAVA_HOME/bin/javac" "$javaSource")
|
||||||
|
fi
|
||||||
|
if [ -e "$javaClass" ]; then
|
||||||
|
log " - Running MavenWrapperDownloader.java ..."
|
||||||
|
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
##########################################################################################
|
||||||
|
# End of extension
|
||||||
|
##########################################################################################
|
||||||
|
|
||||||
|
# If specified, validate the SHA-256 sum of the Maven wrapper jar file
|
||||||
|
wrapperSha256Sum=""
|
||||||
|
while IFS="=" read -r key value; do
|
||||||
|
case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
|
||||||
|
esac
|
||||||
|
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
|
||||||
|
if [ -n "$wrapperSha256Sum" ]; then
|
||||||
|
wrapperSha256Result=false
|
||||||
|
if command -v sha256sum > /dev/null; then
|
||||||
|
if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
|
||||||
|
wrapperSha256Result=true
|
||||||
|
fi
|
||||||
|
elif command -v shasum > /dev/null; then
|
||||||
|
if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
|
||||||
|
wrapperSha256Result=true
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
|
||||||
|
echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ $wrapperSha256Result = false ]; then
|
||||||
|
echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
|
||||||
|
echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
|
||||||
|
echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
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 "$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
|
||||||
|
|
||||||
|
# shellcheck disable=SC2086 # safe args
|
||||||
|
exec "$JAVACMD" \
|
||||||
|
$MAVEN_OPTS \
|
||||||
|
$MAVEN_DEBUG_OPTS \
|
||||||
|
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||||
|
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||||
|
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
||||||
|
|
@ -0,0 +1,205 @@
|
||||||
|
@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 Apache Maven Wrapper startup batch script, version 3.2.0
|
||||||
|
@REM
|
||||||
|
@REM Required ENV vars:
|
||||||
|
@REM JAVA_HOME - location of a JDK home dir
|
||||||
|
@REM
|
||||||
|
@REM Optional ENV vars
|
||||||
|
@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 "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
|
||||||
|
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\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 WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||||
|
|
||||||
|
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||||
|
IF "%%A"=="wrapperUrl" SET WRAPPER_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 WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
|
||||||
|
)
|
||||||
|
if "%MVNW_VERBOSE%" == "true" (
|
||||||
|
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||||
|
echo Downloading from: %WRAPPER_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('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
|
||||||
|
"}"
|
||||||
|
if "%MVNW_VERBOSE%" == "true" (
|
||||||
|
echo Finished downloading %WRAPPER_JAR%
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@REM End of extension
|
||||||
|
|
||||||
|
@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
|
||||||
|
SET WRAPPER_SHA_256_SUM=""
|
||||||
|
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||||
|
IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
|
||||||
|
)
|
||||||
|
IF NOT %WRAPPER_SHA_256_SUM%=="" (
|
||||||
|
powershell -Command "&{"^
|
||||||
|
"$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
|
||||||
|
"If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
|
||||||
|
" Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
|
||||||
|
" Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
|
||||||
|
" Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
|
||||||
|
" exit 1;"^
|
||||||
|
"}"^
|
||||||
|
"}"
|
||||||
|
if ERRORLEVEL 1 goto error
|
||||||
|
)
|
||||||
|
|
||||||
|
@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 "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
|
||||||
|
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\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%
|
||||||
|
|
||||||
|
cmd /C exit /B %ERROR_CODE%
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<name>ray</name>
|
||||||
|
<description>rayc.top 服务端程序</description>
|
||||||
|
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>ray-dependencies</module>
|
||||||
|
<module>ray-infrastructure-utility</module>
|
||||||
|
<module>ray-admin</module>
|
||||||
|
<module>ray-user</module>
|
||||||
|
<module>ray-file</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<maven-resources-plugin.version>3.1.0</maven-resources-plugin.version>
|
||||||
|
<spring-boot-maven-plugin.version>2.6.8</spring-boot-maven-plugin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray-dependencies</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>ray-admin</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>ray-admin</name>
|
||||||
|
<description>ray-admin</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray-infrastructure-utility</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray-user</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray-file</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package top.rayc;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class Application {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Application.class, args);
|
||||||
|
// log.info("**************************************************");
|
||||||
|
// log.info("******************** Ray Backend *****************");
|
||||||
|
// log.info("**************************************************");
|
||||||
|
System.out.println("Ray Backend");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
server:
|
||||||
|
port: 8091
|
||||||
|
|
||||||
|
management:
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
exposure:
|
||||||
|
include: "*"
|
||||||
|
endpoint:
|
||||||
|
health:
|
||||||
|
show-details: always
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: ray
|
||||||
|
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
enabled: true
|
||||||
|
max-file-size: 50MB
|
||||||
|
max-request-size: 100MB
|
||||||
|
|
||||||
|
jackson:
|
||||||
|
date-format: yyyy-MM-dd HH:mm:ss
|
||||||
|
time-zone: GMT+8
|
||||||
|
serialization:
|
||||||
|
FAIL_ON_EMPTY_BEANS: false
|
||||||
|
|
||||||
|
datasource:
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://mysql.rayc.top:3308/ray-dev?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
|
||||||
|
username: root
|
||||||
|
password: "#Ray970217"
|
||||||
|
type: com.alibaba.druid.pool.DruidDataSource
|
||||||
|
druid:
|
||||||
|
initial-size: 3
|
||||||
|
min-idle: 3
|
||||||
|
max-active: 40
|
||||||
|
max-wait: 6000
|
||||||
|
|
||||||
|
mybatis-plus:
|
||||||
|
mapper-locations: classpath:mapperXml/*.xml
|
||||||
|
configuration:
|
||||||
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
|
|
||||||
|
jwt:
|
||||||
|
signing:
|
||||||
|
key: .ymLTU8rq83j4fmJZj60wh4OrMNuntIj4fmJ1refreywscascsa
|
||||||
|
|
||||||
|
file:
|
||||||
|
root:
|
||||||
|
path: /home/ray/data/ray
|
||||||
|
|
||||||
|
# springdoc-openapi
|
||||||
|
springdoc:
|
||||||
|
swagger-ui:
|
||||||
|
path: /swagger-ui.html
|
||||||
|
tags-sorter: alpha
|
||||||
|
operations-sorter: alpha
|
||||||
|
api-docs:
|
||||||
|
path: /v3/api-docs
|
||||||
|
group-configs:
|
||||||
|
- group: "default"
|
||||||
|
paths-to-match: "/**"
|
||||||
|
packages-to-scan:
|
||||||
|
- top.rayc.file.controller
|
||||||
|
- top.rayc.user.controller
|
||||||
|
|
||||||
|
# knife4j
|
||||||
|
knife4j:
|
||||||
|
enable: true
|
||||||
|
setting:
|
||||||
|
language: zh_cn
|
||||||
|
|
||||||
|
---
|
||||||
|
#spring:
|
||||||
|
# boot:
|
||||||
|
# admin:
|
||||||
|
# client:
|
||||||
|
# url: http://localhost:9000
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray-dependencies</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<name>ray-dependencies</name>
|
||||||
|
<description>ray-backend 项目依赖</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
<spring.boot.version>3.1.2</spring.boot.version>
|
||||||
|
|
||||||
|
<fastjson.version>2.0.5</fastjson.version>
|
||||||
|
|
||||||
|
<hutool.version>5.8.20</hutool.version>
|
||||||
|
<mapstruct.version>1.4.1.Final</mapstruct.version>
|
||||||
|
|
||||||
|
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
|
||||||
|
<mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version>
|
||||||
|
|
||||||
|
<tika.version>2.6.0</tika.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
|
<version>${spring.boot.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<version>${spring.boot.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>0.11.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
|
<version>0.11.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.xml.bind</groupId>
|
||||||
|
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jaxb</groupId>
|
||||||
|
<artifactId>jaxb-runtime</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- DB -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>8.0.29</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>druid-spring-boot-starter</artifactId>
|
||||||
|
<version>1.2.8</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
|
<version>${mybatis-plus.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
<version>3.5.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-generator</artifactId>
|
||||||
|
<version>${mybatis-plus-generator.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.12.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.tika</groupId>
|
||||||
|
<artifactId>tika-core</artifactId>
|
||||||
|
<version>${tika.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct</artifactId>
|
||||||
|
<version>${mapstruct.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-jdk8</artifactId>
|
||||||
|
<version>${mapstruct.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-processor</artifactId>
|
||||||
|
<version>${mapstruct.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>${hutool.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
<version>${fastjson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>ray-file</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>ray-file</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray-infrastructure-utility</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray-user</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package top.rayc.file.controller;
|
||||||
|
|
||||||
|
public class FileController {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package top.rayc.file.controller.vo.req;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FileChunkDownloadReq {
|
||||||
|
private String hash;
|
||||||
|
private Integer chunkIdx;
|
||||||
|
private Long chunkSize;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package top.rayc.file.controller.vo.req;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FileChunkMergeReq {
|
||||||
|
private String filename;
|
||||||
|
private String hash;
|
||||||
|
private String extension;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package top.rayc.file.controller.vo.req;
|
||||||
|
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import io.micrometer.common.lang.NonNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FileChunkUploadReq {
|
||||||
|
private String filename;
|
||||||
|
private String hash;
|
||||||
|
@NonNull
|
||||||
|
private MultipartFile chunk;
|
||||||
|
private Long chunkSize;
|
||||||
|
private Integer chunkIdx;
|
||||||
|
private Integer chunkCount;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package top.rayc.file.controller.vo.req;
|
||||||
|
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FileUploadReq {
|
||||||
|
private String filename;
|
||||||
|
private MultipartFile file;
|
||||||
|
private String hash;
|
||||||
|
private Long size;
|
||||||
|
private String extension;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package top.rayc.file.controller.vo.resp;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class FileResp {
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String hash;
|
||||||
|
private String filename;
|
||||||
|
private String extension;
|
||||||
|
private String realFilename;
|
||||||
|
private Long size;
|
||||||
|
private String storePath;
|
||||||
|
private Boolean staticAccess;
|
||||||
|
private String staticUri;
|
||||||
|
private String contentType;
|
||||||
|
private Boolean isDeleted;
|
||||||
|
private Long uploadBy;
|
||||||
|
private LocalDateTime uploadAt;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package top.rayc.file.converter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import top.rayc.file.controller.vo.req.FileUploadReq;
|
||||||
|
import top.rayc.file.controller.vo.resp.FileResp;
|
||||||
|
import top.rayc.file.entity.File;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface FileConverter {
|
||||||
|
FileConverter INSTANCE = Mappers.getMapper(FileConverter.class);
|
||||||
|
|
||||||
|
File convertFromFileUploadReq(FileUploadReq fileUpload);
|
||||||
|
|
||||||
|
FileResp convertToResp(File file);
|
||||||
|
|
||||||
|
List<FileResp> convertToResps(List<File> files);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package top.rayc.file.entity;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("file")
|
||||||
|
public class File {
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String hash;
|
||||||
|
private String filename;
|
||||||
|
private String extension;
|
||||||
|
private String realFilename;
|
||||||
|
private Long size;
|
||||||
|
private String storePath;
|
||||||
|
private Boolean staticAccess;
|
||||||
|
private String staticUri;
|
||||||
|
private String contentType;
|
||||||
|
private Boolean isDeleted;
|
||||||
|
private Long uploadBy;
|
||||||
|
private LocalDateTime uploadAt;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package top.rayc.file.entity;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("file_chunk")
|
||||||
|
public class FileChunk {
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String hash;
|
||||||
|
private String filename;
|
||||||
|
private String chunkPath;
|
||||||
|
private Integer chunkIdx;
|
||||||
|
private Integer chunkCount;
|
||||||
|
private Long chunkSize;
|
||||||
|
private Boolean isMerged;
|
||||||
|
private Long uploadBy;
|
||||||
|
private LocalDateTime uploadAt;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package top.rayc.file.mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
import top.rayc.file.entity.FileChunk;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface FileChunkMapper extends BaseMapper<FileChunk> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package top.rayc.file.mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
import top.rayc.file.entity.File;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface FileMapper extends BaseMapper<File> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package top.rayc.file.service;
|
||||||
|
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import top.rayc.file.controller.vo.req.FileChunkMergeReq;
|
||||||
|
import top.rayc.file.controller.vo.req.FileChunkUploadReq;
|
||||||
|
import top.rayc.file.controller.vo.req.FileUploadReq;
|
||||||
|
import top.rayc.file.controller.vo.resp.FileResp;
|
||||||
|
import top.rayc.utility.page.PageObject;
|
||||||
|
import top.rayc.utility.vo.BaseResult;
|
||||||
|
|
||||||
|
public interface IFileService {
|
||||||
|
ResponseEntity<BaseResult<FileResp>> uploadFileSingle(FileUploadReq fileUpload);
|
||||||
|
|
||||||
|
ResponseEntity<BaseResult<FileResp>> uploadFileChunk(FileChunkUploadReq fileChunkUpload);
|
||||||
|
|
||||||
|
ResponseEntity<BaseResult<FileResp>> mergeFileChunk(FileChunkMergeReq fileChunkMergeReq);
|
||||||
|
|
||||||
|
ResponseEntity<BaseResult<PageObject<FileResp>>> pageFileInfo(Long pageIdx, Long pageSize);
|
||||||
|
|
||||||
|
ResponseEntity<BaseResult<String>> changeFileStaticAccessStatus(Long id, Boolean newStatus);
|
||||||
|
|
||||||
|
ResponseEntity<BaseResult> downloadFile(String hash, HttpServletResponse response);
|
||||||
|
|
||||||
|
ResponseEntity<BaseResult> downloadFileChunk(String hash, Integer chunkIdx, Integer chunkSize, HttpServletResponse response);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
package top.rayc.file.service.impl;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import top.rayc.file.controller.vo.req.FileChunkMergeReq;
|
||||||
|
import top.rayc.file.controller.vo.req.FileChunkUploadReq;
|
||||||
|
import top.rayc.file.controller.vo.req.FileUploadReq;
|
||||||
|
import top.rayc.file.controller.vo.resp.FileResp;
|
||||||
|
import top.rayc.file.entity.File;
|
||||||
|
import top.rayc.file.mapper.FileChunkMapper;
|
||||||
|
import top.rayc.file.mapper.FileMapper;
|
||||||
|
import top.rayc.file.service.IFileService;
|
||||||
|
import top.rayc.user.utils.UserHelper;
|
||||||
|
import top.rayc.utility.page.PageObject;
|
||||||
|
import top.rayc.utility.utils.FileUtil;
|
||||||
|
import top.rayc.utility.vo.BaseResult;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class FileService extends ServiceImpl<FileMapper, File> implements IFileService {
|
||||||
|
|
||||||
|
@Value("${file.root.path}")
|
||||||
|
private String rootPath;
|
||||||
|
|
||||||
|
private final String DEFAULT_RELATIVE_PATH = "default/";
|
||||||
|
private final String DEFAULT_CHUNK_RELATIVE_PATH = "default.chunk/";
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FileChunkMapper fileChunkMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserHelper userHelper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<BaseResult<FileResp>> uploadFileSingle(FileUploadReq fileUpload) {
|
||||||
|
log.info("开始处理单文件上传");
|
||||||
|
String storeName = fileUpload.getHash() + "." + fileUpload.getExtension();
|
||||||
|
String contentType = "";
|
||||||
|
try {
|
||||||
|
contentType = FileUtil.contentType(fileUpload.getFile().getInputStream());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
// String parentPath = ""
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'uploadFileSingle'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<BaseResult<FileResp>> uploadFileChunk(FileChunkUploadReq fileChunkUpload) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'uploadFileChunk'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<BaseResult<FileResp>> mergeFileChunk(FileChunkMergeReq fileChunkMergeReq) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'mergeFileChunk'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<BaseResult<PageObject<FileResp>>> pageFileInfo(Long pageIdx, Long pageSize) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'pageFileInfo'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<BaseResult<String>> changeFileStaticAccessStatus(Long id, Boolean newStatus) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'changeFileStaticAccessStatus'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<BaseResult> downloadFile(String hash, HttpServletResponse response) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'downloadFile'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<BaseResult> downloadFileChunk(String hash, Integer chunkIdx, Integer chunkSize,
|
||||||
|
HttpServletResponse response) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'downloadFileChunk'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,154 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>ray-infrastructure-utility</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>${project.artifactId}</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>8.0.29</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>druid-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Mybatis-Plus自动生成代码依赖包-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-generator</artifactId>
|
||||||
|
<version>3.5.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-jdk8</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-processor</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-test</artifactId>
|
||||||
|
<!-- <scope>test</scope>-->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<!-- <scope>test</scope>-->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-api</artifactId>
|
||||||
|
<version>0.11.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>0.11.1</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
|
<version>0.11.1</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.tika</groupId>
|
||||||
|
<artifactId>tika-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
package top.rayc.utility.aop;
|
||||||
|
|
||||||
|
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||||
|
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import top.rayc.utility.exception.BizException;
|
||||||
|
import top.rayc.utility.vo.BaseResult;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
/**
|
||||||
|
* 请求体为空处理
|
||||||
|
*
|
||||||
|
* @param req
|
||||||
|
* @param e
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = HttpMessageNotReadableException.class)
|
||||||
|
public BaseResult exceptionHandler(HttpServletRequest req, HttpMessageNotReadableException e) {
|
||||||
|
// log.error("请求体request body不能为空:", e);
|
||||||
|
return BaseResult.error("请求体request body不能为空!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数校验异常处理
|
||||||
|
*
|
||||||
|
* @param req
|
||||||
|
* @param e
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = MethodArgumentNotValidException.class)
|
||||||
|
public BaseResult exceptionHandler(HttpServletRequest req, MethodArgumentNotValidException e) {
|
||||||
|
// log.error("参数校验异常:", e);
|
||||||
|
return BaseResult.error(e.getBindingResult().getFieldError().getDefaultMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求方法不支持异常处理
|
||||||
|
*
|
||||||
|
* @param req
|
||||||
|
* @param e
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
|
||||||
|
public BaseResult exceptionHandler(HttpServletRequest req, HttpRequestMethodNotSupportedException e) {
|
||||||
|
// log.error("参数校验异常:", e);
|
||||||
|
return BaseResult.error(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务异常处理
|
||||||
|
*
|
||||||
|
* @param req
|
||||||
|
* @param e
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = BizException.class)
|
||||||
|
public BaseResult exceptionHandler(HttpServletRequest req, BizException e) {
|
||||||
|
log.error("业务异常:", e);
|
||||||
|
return BaseResult.error(e.findMessageCode().getStatus(), e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未知异常处理
|
||||||
|
*
|
||||||
|
* @param req
|
||||||
|
* @param e
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = Exception.class)
|
||||||
|
public BaseResult exceptionHandler(HttpServletRequest req, Exception e) {
|
||||||
|
log.error("系统异常:", e);
|
||||||
|
return BaseResult.error("系统内部异常!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
package top.rayc.utility.aop;
|
||||||
|
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.slf4j.MDC;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.UUID;
|
||||||
|
import io.micrometer.common.util.StringUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import top.rayc.utility.vo.BaseReq;
|
||||||
|
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class LogAspect {
|
||||||
|
private static final String TRACE_LOG_ID = "traceId";
|
||||||
|
|
||||||
|
@Pointcut("execution(* top.rayc.*.impl.*.*(..))")
|
||||||
|
public void logPointCut() {}
|
||||||
|
|
||||||
|
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
|
||||||
|
String traceId = MDC.get(TRACE_LOG_ID);
|
||||||
|
if (StringUtils.isBlank(traceId)) {
|
||||||
|
if (pjp.getArgs().length > 0 && pjp.getArgs()[0] instanceof BaseReq) {
|
||||||
|
BaseReq req = (BaseReq) pjp.getArgs()[0];
|
||||||
|
if (StringUtils.isNotBlank(req.getTraceId())) {
|
||||||
|
traceId = req.getTraceId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(traceId)) {
|
||||||
|
MDC.put(TRACE_LOG_ID, traceId);
|
||||||
|
} else {
|
||||||
|
MDC.put(TRACE_LOG_ID, UUID.randomUUID().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Long startTime = System.currentTimeMillis();
|
||||||
|
log.info("入参: {}", JSON.toJSONString(pjp.getArgs()));
|
||||||
|
|
||||||
|
Object result = pjp.proceed();
|
||||||
|
log.info("耗时: {}ms; 出参: {}", System.currentTimeMillis() - startTime, JSON.toJSONString(result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package top.rayc.utility.event;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public abstract class DomainEvent {
|
||||||
|
private String eventId;
|
||||||
|
private Date eventTime;
|
||||||
|
|
||||||
|
public DomainEvent() {
|
||||||
|
this.eventId = "Event" + UUID.randomUUID().toString().toUpperCase();
|
||||||
|
this.eventTime = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEventId() {
|
||||||
|
return eventId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getEventTime() {
|
||||||
|
return eventTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package top.rayc.utility.event;
|
||||||
|
|
||||||
|
public class HealthEvent extends DomainEvent {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package top.rayc.utility.exception;
|
||||||
|
|
||||||
|
public class BizException extends RuntimeException implements ExceptionMessage {
|
||||||
|
/**
|
||||||
|
* 错误信息
|
||||||
|
*/
|
||||||
|
private final MessageCode messageCode;
|
||||||
|
|
||||||
|
public BizException(MessageCode messageCode) {
|
||||||
|
super(messageCode.getMessage());
|
||||||
|
this.messageCode = messageCode;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public BizException(MessageCode messageCode, Throwable cause) {
|
||||||
|
super(messageCode.getMessage(), cause);
|
||||||
|
this.messageCode = messageCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BizException(MessageCode messageCode, String... sub) {
|
||||||
|
super(messageCode.getSubMsg(sub));
|
||||||
|
this.messageCode = messageCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BizException(MessageCode messageCode, Throwable cause, String... sub) {
|
||||||
|
super(messageCode.getSubMsg(sub), cause);
|
||||||
|
this.messageCode = messageCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageCode findMessageCode() {
|
||||||
|
return this.messageCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package top.rayc.utility.exception;
|
||||||
|
|
||||||
|
public interface ExceptionMessage {
|
||||||
|
public MessageCode findMessageCode();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package top.rayc.utility.exception;
|
||||||
|
|
||||||
|
public interface GlobalExceptionCode {
|
||||||
|
int NOT_FOUND = 10001;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
package top.rayc.utility.exception;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Data
|
||||||
|
public class MessageCode {
|
||||||
|
|
||||||
|
private Integer status;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public Integer getStatus() { return this.status; }
|
||||||
|
|
||||||
|
public void setStatus(Integer status) { this.status = status; }
|
||||||
|
|
||||||
|
public String getMessage() { return this.message; }
|
||||||
|
|
||||||
|
public void setMessage(String message) { this.message = message; }
|
||||||
|
|
||||||
|
private MessageCode(Integer code, String msg) {
|
||||||
|
this.status = code;
|
||||||
|
this.message = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MessageCode build(Integer code, String msg) {
|
||||||
|
return new MessageCode(code, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static MessageCode SUCCESS = MessageCode.build(200, "ok");
|
||||||
|
public static MessageCode UN_KNOWN = MessageCode.build(200, "");
|
||||||
|
public static MessageCode SYSTEM_ERROR = MessageCode.build(200, "systemError");
|
||||||
|
public static MessageCode COMPONENT_ERROR = MessageCode.build(200, "componentError");
|
||||||
|
public static MessageCode RUNTIME_ERROR = MessageCode.build(200, "runtimeError");
|
||||||
|
public static MessageCode REMOTE_ERROR = MessageCode.build(200, "callRemoteError");
|
||||||
|
public static MessageCode CHECK_ERROR = MessageCode.build(200, "校验失败:{0}");
|
||||||
|
|
||||||
|
public String getSubMsg(String[] sub) {
|
||||||
|
if (this.message == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (sub == null || sub.length == 0) {
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
String[] subArr = Arrays.stream(sub)
|
||||||
|
.map(item -> {
|
||||||
|
if (item.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.toArray(String[]::new);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return MessageFormat.format(this.message, subArr);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
return this.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static org.slf4j.Logger getLog() {
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package top.rayc.utility.id;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
|
||||||
|
public class DistributedId {
|
||||||
|
|
||||||
|
private static DistributedId instance = new DistributedId();
|
||||||
|
|
||||||
|
public String getFastSimpleUUID(){
|
||||||
|
return IdUtil.fastSimpleUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getSnowflake(long workerId, long datacenterId){
|
||||||
|
return IdUtil.createSnowflake(workerId, datacenterId).nextId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DistributedId getInstance(){
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package top.rayc.utility.page;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class PageObject<T> {
|
||||||
|
|
||||||
|
private Long total;
|
||||||
|
|
||||||
|
private Long pageIdx;
|
||||||
|
|
||||||
|
private Long pageSize;
|
||||||
|
|
||||||
|
private List<T> list;
|
||||||
|
|
||||||
|
public void buildPage(List<T> list, Long total, Long pageIdx, Long pageSize) {
|
||||||
|
this.list = list;
|
||||||
|
this.total = total;
|
||||||
|
this.pageIdx = pageIdx;
|
||||||
|
this.pageSize = pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package top.rayc.utility.security.authentication;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
|
||||||
|
public class UsernamePasswordAuthentication extends UsernamePasswordAuthenticationToken {
|
||||||
|
|
||||||
|
public UsernamePasswordAuthentication(
|
||||||
|
Object principal,
|
||||||
|
Object credentials,
|
||||||
|
Collection<? extends GrantedAuthority> authorities
|
||||||
|
) {
|
||||||
|
super(principal, credentials, authorities);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
package top.rayc.utility.security.authentication.filter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
import ch.qos.logback.core.subst.Token;
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import top.rayc.utility.security.authentication.UsernamePasswordAuthentication;
|
||||||
|
import top.rayc.utility.utils.JwtTokenUtils;
|
||||||
|
|
||||||
|
// @Component
|
||||||
|
@Slf4j
|
||||||
|
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
private static final String TOKEN_HEADER_KEY = "Authorization";
|
||||||
|
private static final String LOGIN_PATH = "/login";
|
||||||
|
private static final String AUTHORIZATION_PREFIX = "Bearer ";
|
||||||
|
|
||||||
|
@Value("${jwt.signing.key:ymLTU8rq83j4fmJZj60wh4OrMNuntIj4fmJ}")
|
||||||
|
private String jwtSigningKey;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
FilterChain filterChain
|
||||||
|
) throws ServletException, IOException {
|
||||||
|
Claims claims = JwtTokenUtils.getClaimsFromToken(request.getHeader(TOKEN_HEADER_KEY).substring(7), jwtSigningKey);
|
||||||
|
if (claims != null) {
|
||||||
|
String username = claims.getSubject();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<SimpleGrantedAuthority> authorities = ((List<String>)claims.get("role", List.class))
|
||||||
|
.stream()
|
||||||
|
.map(SimpleGrantedAuthority::new)
|
||||||
|
.toList();
|
||||||
|
UsernamePasswordAuthentication auth = new UsernamePasswordAuthentication(username, null, authorities);
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||||
|
}
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
|
||||||
|
String bearerToken = request.getHeader(TOKEN_HEADER_KEY);
|
||||||
|
if (LOGIN_PATH.equals(request.getServletPath())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (bearerToken.isBlank() || bearerToken.isEmpty() || !bearerToken.startsWith(AUTHORIZATION_PREFIX)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !JwtTokenUtils.validateToken(bearerToken.substring(7), jwtSigningKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package top.rayc.utility.security.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class CommonSecurityConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder passwordEncoder() {
|
||||||
|
return new BCryptPasswordEncoder();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package top.rayc.utility.utils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import org.apache.tika.Tika;
|
||||||
|
|
||||||
|
public class FileUtil {
|
||||||
|
|
||||||
|
public static String contentType(File file) throws IOException {
|
||||||
|
return new Tika().detect(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String contentType(InputStream stream) throws IOException {
|
||||||
|
return new Tika().detect(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void delete(Path path) throws IOException {
|
||||||
|
Files.delete(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
package top.rayc.utility.utils;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
|
import io.jsonwebtoken.security.Keys;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class JwtTokenUtils {
|
||||||
|
|
||||||
|
public static String generateJwtToken(
|
||||||
|
String jwtSigningKey,
|
||||||
|
Authentication authentication,
|
||||||
|
Long jwtDuration
|
||||||
|
) {
|
||||||
|
Long signAt = System.currentTimeMillis();
|
||||||
|
Long expireAt = signAt + jwtDuration;
|
||||||
|
|
||||||
|
log.error("jwtDuration: {} signAt: {} expireAt: {}",
|
||||||
|
jwtDuration,
|
||||||
|
LocalDateTime.ofInstant(Instant.ofEpochMilli(signAt), ZoneId.systemDefault()),
|
||||||
|
LocalDateTime.ofInstant(Instant.ofEpochMilli(expireAt), ZoneId.systemDefault())
|
||||||
|
);
|
||||||
|
|
||||||
|
Claims claims = Jwts.claims();
|
||||||
|
claims.put("role", authentication.getAuthorities().stream().map(item -> item.getAuthority()).toList());
|
||||||
|
claims.setSubject((String) authentication.getPrincipal());
|
||||||
|
claims.setIssuedAt(new Date(signAt));
|
||||||
|
claims.setExpiration(new Date(expireAt));
|
||||||
|
|
||||||
|
SecretKey key = Keys.hmacShaKeyFor(jwtSigningKey.getBytes());
|
||||||
|
|
||||||
|
return Jwts.builder()
|
||||||
|
.signWith(key, SignatureAlgorithm.HS256)
|
||||||
|
.setClaims(claims)
|
||||||
|
.compact();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Claims getClaimsFromToken(String token, String jwtSigningKey) {
|
||||||
|
try {
|
||||||
|
SecretKey key = Keys.hmacShaKeyFor(jwtSigningKey.getBytes());
|
||||||
|
return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean validateToken(String token, String jwtSigningKey) {
|
||||||
|
Claims claims = getClaimsFromToken(token, jwtSigningKey);
|
||||||
|
log.info("claims: {} ; expire: {} ; now: {}",
|
||||||
|
claims,
|
||||||
|
claims.getExpiration().getTime(),
|
||||||
|
System.currentTimeMillis());
|
||||||
|
if (claims == null || claims.getExpiration() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return claims.getExpiration().after(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
package top.rayc.utility.utils;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class StringUtils extends org.springframework.util.StringUtils {
|
||||||
|
|
||||||
|
private static Charset encoding = StandardCharsets.UTF_8;
|
||||||
|
|
||||||
|
public static final String EMPTY = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目 字符串 处理编码
|
||||||
|
*
|
||||||
|
* @param charset default UTF-8
|
||||||
|
* @see StandardCharsets
|
||||||
|
*/
|
||||||
|
public static void setGlobalCharset(Charset charset) {
|
||||||
|
encoding = charset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Charset charset() {
|
||||||
|
return encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常 转字符串
|
||||||
|
*
|
||||||
|
* @param throwable error
|
||||||
|
* @return error string
|
||||||
|
*/
|
||||||
|
public static String getTraceString(Throwable throwable) {
|
||||||
|
if (throwable == null) {
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
StringWriter stackTrace = new StringWriter();
|
||||||
|
throwable.printStackTrace(new PrintWriter(stackTrace));
|
||||||
|
stackTrace.flush();
|
||||||
|
return stackTrace.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param str string
|
||||||
|
* @return not null
|
||||||
|
*/
|
||||||
|
public static boolean isNotEmpty(String str) {
|
||||||
|
return hasLength(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 没有长度
|
||||||
|
*
|
||||||
|
* @param str string value
|
||||||
|
* @return hasNotLength
|
||||||
|
*/
|
||||||
|
public static boolean hasNotLength(String str) {
|
||||||
|
return str == null || !str.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 没有长度
|
||||||
|
*
|
||||||
|
* @param str string value
|
||||||
|
* @return hasNotLength
|
||||||
|
*/
|
||||||
|
public static boolean hasNotLength(CharSequence str) {
|
||||||
|
return str == null || str.length() <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认字符串替换
|
||||||
|
*
|
||||||
|
* @param nullAbleString 为空字符串
|
||||||
|
* @param defaultString 默认字符串
|
||||||
|
* @return 转换后字符串
|
||||||
|
*/
|
||||||
|
public static String defaultString(String nullAbleString, String defaultString) {
|
||||||
|
return StringUtils.hasLength(nullAbleString) ? defaultString : nullAbleString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 首字母变小写
|
||||||
|
*
|
||||||
|
* @param str 字符串
|
||||||
|
* @return {String}
|
||||||
|
*/
|
||||||
|
public static String firstCharToLower(String str) {
|
||||||
|
char firstChar = str.charAt(0);
|
||||||
|
if (firstChar >= 'A' && firstChar <= 'Z') {
|
||||||
|
char[] arr = str.toCharArray();
|
||||||
|
arr[0] += ('a' - 'A');
|
||||||
|
return new String(arr);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是空白字符串
|
||||||
|
*
|
||||||
|
* @param cs
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean isBlank(final CharSequence cs) {
|
||||||
|
return !hasText(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下划线 分隔转驼峰
|
||||||
|
*/
|
||||||
|
public static String underScoreToLowerCamelCase(String userScoreStr) {
|
||||||
|
if (userScoreStr == null) {
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
char[] chars = userScoreStr.toCharArray();
|
||||||
|
boolean meetUnderScore = false;
|
||||||
|
int scoreCount = 0;
|
||||||
|
for (int i = 0, j = chars.length; i < j; i++) {
|
||||||
|
if (chars[i] == '_') {
|
||||||
|
meetUnderScore = true;
|
||||||
|
++scoreCount;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (meetUnderScore) {
|
||||||
|
meetUnderScore = false;
|
||||||
|
int a = chars[i];
|
||||||
|
if (a >= 'a' && a <= 'z') {
|
||||||
|
chars[i] = (char) (a - 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char[] newChars = new char[chars.length - scoreCount];
|
||||||
|
int scoreIndex = 0;
|
||||||
|
for (int i = 0, j = newChars.length; i < j; ) {
|
||||||
|
if (chars[scoreIndex] != '_') {
|
||||||
|
newChars[i] = chars[scoreIndex];
|
||||||
|
++scoreIndex;
|
||||||
|
++i;
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
++scoreIndex;
|
||||||
|
} while (chars[scoreIndex] == '_');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new String(newChars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package top.rayc.utility.vo;
|
||||||
|
|
||||||
|
public class BaseReq {
|
||||||
|
private String traceId;
|
||||||
|
private Integer pageSize;
|
||||||
|
private Integer pageNumber;
|
||||||
|
|
||||||
|
public String getTraceId() {
|
||||||
|
return traceId;
|
||||||
|
}
|
||||||
|
public void setTraceId(String traceId) {
|
||||||
|
this.traceId = traceId;
|
||||||
|
}
|
||||||
|
public Integer getPageSize() {
|
||||||
|
return pageSize;
|
||||||
|
}
|
||||||
|
public void setPageSize(Integer pageSize) {
|
||||||
|
this.pageSize = pageSize;
|
||||||
|
}
|
||||||
|
public Integer getPageNumber() {
|
||||||
|
return pageNumber;
|
||||||
|
}
|
||||||
|
public void setPageNumber(Integer pageNumber) {
|
||||||
|
this.pageNumber = pageNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
package top.rayc.utility.vo;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.jboss.logging.MDC;
|
||||||
|
|
||||||
|
import top.rayc.utility.exception.MessageCode;
|
||||||
|
|
||||||
|
public class BaseResult<T> implements Serializable {
|
||||||
|
|
||||||
|
private Integer status;
|
||||||
|
private String msg;
|
||||||
|
private T data;
|
||||||
|
private String traceId;
|
||||||
|
private String errMsg;
|
||||||
|
|
||||||
|
private static final String TRACE_LOG_ID = "traceId";
|
||||||
|
|
||||||
|
private BaseResult (Integer status, String msg, String traceId) {
|
||||||
|
this.status = status;
|
||||||
|
this.msg = msg;
|
||||||
|
this.traceId = traceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseResult (Integer status, String msg, T data, String traceId) {
|
||||||
|
this.status = status;
|
||||||
|
this.msg = msg;
|
||||||
|
this.data = data;
|
||||||
|
this.traceId = traceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseResult (Integer status, String msg, T data, String traceId, String errMsg) {
|
||||||
|
this.status = status;
|
||||||
|
this.msg = msg;
|
||||||
|
this.data = data;
|
||||||
|
this.traceId = traceId;
|
||||||
|
this.errMsg = errMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BaseResult success(MessageCode messageCode) {
|
||||||
|
return new BaseResult(
|
||||||
|
messageCode.getStatus(),
|
||||||
|
messageCode.getMessage(),
|
||||||
|
MDC.get(TRACE_LOG_ID).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> BaseResult success(Integer code, String msg, T data) {
|
||||||
|
return new BaseResult(
|
||||||
|
MessageCode.SUCCESS.getStatus(),
|
||||||
|
MessageCode.SUCCESS.getMessage(),
|
||||||
|
data,
|
||||||
|
MDC.get(TRACE_LOG_ID).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> BaseResult error(Integer code, String msg, T data) {
|
||||||
|
return new BaseResult(
|
||||||
|
code,
|
||||||
|
msg,
|
||||||
|
data,
|
||||||
|
MDC.get(TRACE_LOG_ID).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BaseResult error(String msg) {
|
||||||
|
return new BaseResult(
|
||||||
|
MessageCode.SYSTEM_ERROR.getStatus(),
|
||||||
|
msg,
|
||||||
|
MDC.get(TRACE_LOG_ID).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BaseResult error(Integer code, String msg) {
|
||||||
|
return new BaseResult(
|
||||||
|
code,
|
||||||
|
msg,
|
||||||
|
MDC.get(TRACE_LOG_ID).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(Integer 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTraceId() {
|
||||||
|
return traceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTraceId(String traceId) {
|
||||||
|
this.traceId = traceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrMsg() {
|
||||||
|
return errMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setErrMsg(String errMsg) {
|
||||||
|
this.errMsg = errMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Result {"
|
||||||
|
+ "status=" + status
|
||||||
|
+ ", msg='" + msg + "'"
|
||||||
|
+ ", data=" + data
|
||||||
|
+ ", traceId='" + traceId + "'"
|
||||||
|
+ ", errMsg='" + errMsg + "'"
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>ray-user</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>${project.artifactId}</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.rayc</groupId>
|
||||||
|
<artifactId>ray-infrastructure-utility</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package top.rayc.user.controller;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class UserController {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package top.rayc.user.controller.vo.req;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Email;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UserCreateReq {
|
||||||
|
@Email
|
||||||
|
private String email;
|
||||||
|
@NotEmpty
|
||||||
|
private String password;
|
||||||
|
@NotEmpty
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
private String verifyCode;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package top.rayc.user.controller.vo.req;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UserLoginReq {
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private String optCode;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package top.rayc.user.controller.vo.resp;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UserResp {
|
||||||
|
private Long id;
|
||||||
|
private Long accountId;
|
||||||
|
private String username;
|
||||||
|
private String nickname;
|
||||||
|
private String phone;
|
||||||
|
private String email;
|
||||||
|
private String gender;
|
||||||
|
private String shortBio;
|
||||||
|
private String avatar;
|
||||||
|
private LocalDate birthday;
|
||||||
|
private LocalDateTime createAt;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package top.rayc.user.converter;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import top.rayc.user.controller.vo.req.UserCreateReq;
|
||||||
|
import top.rayc.user.controller.vo.resp.UserResp;
|
||||||
|
import top.rayc.user.entity.User;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface UserConverter {
|
||||||
|
|
||||||
|
UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);
|
||||||
|
|
||||||
|
User converterFromUserCreateReq(UserCreateReq userReq);
|
||||||
|
|
||||||
|
UserResp converterToUserResp(User user);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package top.rayc.user.entity;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("role")
|
||||||
|
public class Role {
|
||||||
|
@TableId(value="id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
private String roleName;
|
||||||
|
private String description;
|
||||||
|
private LocalDateTime createAt;
|
||||||
|
private LocalDateTime updateAt;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package top.rayc.user.entity;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("user")
|
||||||
|
public class User {
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
private Long accountId;
|
||||||
|
private String username;
|
||||||
|
private String nickname;
|
||||||
|
private String phone;
|
||||||
|
private String email;
|
||||||
|
private String password;
|
||||||
|
private String gender;
|
||||||
|
private String shortBio;
|
||||||
|
private String avatar;
|
||||||
|
private LocalDate birthday;
|
||||||
|
private Boolean isDeleted;
|
||||||
|
private LocalDateTime createAt;
|
||||||
|
private LocalDateTime updateAt;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package top.rayc.user.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName("user_role")
|
||||||
|
public class UserRole {
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
private Long userId;
|
||||||
|
private Long roleId;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package top.rayc.user.mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
import top.rayc.user.entity.Role;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface RoleMapper extends BaseMapper<Role> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package top.rayc.user.mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
import top.rayc.user.entity.User;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface UserMapper extends BaseMapper<User> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package top.rayc.user.mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
import top.rayc.user.entity.UserRole;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface UserRoleMapper extends BaseMapper<UserRole> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package top.rayc.user.security;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.ProviderManager;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||||
|
|
||||||
|
import top.rayc.user.security.dsl.SecurityConfigDsl;
|
||||||
|
import top.rayc.user.security.provider.UsernamePasswordAuthenticationProvider;
|
||||||
|
import top.rayc.utility.security.authentication.filter.JwtAuthenticationFilter;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
@EnableMethodSecurity(prePostEnabled = true)
|
||||||
|
public class SecurityConfig {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UsernamePasswordAuthenticationProvider usernamePasswordAuthenticationProvider;
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.csrf(csrf -> csrf.disable())
|
||||||
|
.authorizeHttpRequests(auth -> {
|
||||||
|
auth.anyRequest().permitAll();
|
||||||
|
})
|
||||||
|
.sessionManagement(management -> management.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||||
|
.addFilterBefore(new JwtAuthenticationFilter(), BasicAuthenticationFilter.class)
|
||||||
|
.apply( new SecurityConfigDsl() );
|
||||||
|
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public AuthenticationManager authenticationManager() {
|
||||||
|
return new ProviderManager(usernamePasswordAuthenticationProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
package top.rayc.user.security.authentication;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
|
||||||
|
import lombok.val;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import top.rayc.user.controller.vo.req.UserLoginReq;
|
||||||
|
import top.rayc.utility.security.authentication.UsernamePasswordAuthentication;
|
||||||
|
import top.rayc.utility.utils.JwtTokenUtils;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class InitialJsonAuthenticationFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
private AuthenticationManager manager;
|
||||||
|
|
||||||
|
public InitialJsonAuthenticationFilter(AuthenticationManager manager) {
|
||||||
|
this.manager = manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String signingKey = ".ymLTU8rq83j4fmJZj60wh4OrMNuntIj4fmJ1refreywscascsa";
|
||||||
|
private final Long jwtDuration = 1000L * 60 * 60 * 10;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
FilterChain filterChain
|
||||||
|
) throws ServletException, IOException {
|
||||||
|
UserLoginReq loginReq = new UserLoginReq();
|
||||||
|
|
||||||
|
try {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
loginReq = objectMapper.readValue(request.getInputStream(), UserLoginReq.class);
|
||||||
|
if ("null".equals(loginReq.getUsername())) {
|
||||||
|
loginReq.setUsername(null);
|
||||||
|
}
|
||||||
|
if ("null".equals(loginReq.getPassword())) {
|
||||||
|
loginReq.setPassword(null);
|
||||||
|
}
|
||||||
|
if ("null".equals(loginReq.getOptCode())) {
|
||||||
|
loginReq.setOptCode(null);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthentication(loginReq.getUsername(), loginReq.getPassword(), null);
|
||||||
|
this.manager.authenticate(authentication);
|
||||||
|
|
||||||
|
String jwt = JwtTokenUtils.generateJwtToken(signingKey, authentication, jwtDuration);
|
||||||
|
|
||||||
|
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||||
|
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||||
|
response.setStatus(HttpStatus.OK.value());
|
||||||
|
response.setHeader("Authorization", jwt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
|
||||||
|
return !request.getServletPath().equals("/login") ||
|
||||||
|
!request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE) ||
|
||||||
|
!request.getMethod().equals("POST");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package top.rayc.user.security.dsl;
|
||||||
|
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
|
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||||
|
|
||||||
|
import top.rayc.user.security.authentication.InitialJsonAuthenticationFilter;
|
||||||
|
|
||||||
|
public class SecurityConfigDsl extends AbstractHttpConfigurer<SecurityConfigDsl, HttpSecurity> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(HttpSecurity builder) throws Exception {
|
||||||
|
super.configure(builder);
|
||||||
|
AuthenticationManager manager = builder.getSharedObject(AuthenticationManager.class);
|
||||||
|
builder.addFilterAfter(new InitialJsonAuthenticationFilter(manager), BasicAuthenticationFilter.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SecurityConfigDsl newInstance() {
|
||||||
|
return new SecurityConfigDsl();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package top.rayc.user.security.handler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class JwtAuthenticationFailedHandler implements AuthenticationFailureHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAuthenticationFailure(
|
||||||
|
HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
AuthenticationException exception
|
||||||
|
) throws IOException, ServletException {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package top.rayc.user.security.handler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class JwtAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||||
|
Authentication authentication) throws IOException, ServletException {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package top.rayc.user.security.provider;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import top.rayc.user.service.impl.AuthService;
|
||||||
|
import top.rayc.utility.security.authentication.UsernamePasswordAuthentication;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class UsernamePasswordAuthenticationProvider implements AuthenticationProvider {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthService authService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||||
|
String username = (String) authentication.getPrincipal();
|
||||||
|
String password = (String) authentication.getCredentials();
|
||||||
|
|
||||||
|
return authService.auth(username, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(Class<?> authentication) {
|
||||||
|
if (authentication == null) return false;
|
||||||
|
return UsernamePasswordAuthentication.class.isAssignableFrom(authentication);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package top.rayc.user.service;
|
||||||
|
|
||||||
|
import top.rayc.utility.security.authentication.UsernamePasswordAuthentication;
|
||||||
|
|
||||||
|
public interface IAuthService {
|
||||||
|
UsernamePasswordAuthentication auth(String username, String password);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package top.rayc.user.service;
|
||||||
|
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
import top.rayc.user.controller.vo.req.UserCreateReq;
|
||||||
|
import top.rayc.user.controller.vo.resp.UserResp;
|
||||||
|
import top.rayc.utility.vo.BaseResult;
|
||||||
|
|
||||||
|
public interface IUserService {
|
||||||
|
|
||||||
|
ResponseEntity<BaseResult<UserResp>> createUser(UserCreateReq userReq);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
package top.rayc.user.service.impl;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import top.rayc.user.entity.Role;
|
||||||
|
import top.rayc.user.entity.User;
|
||||||
|
import top.rayc.user.entity.UserRole;
|
||||||
|
import top.rayc.user.mapper.RoleMapper;
|
||||||
|
import top.rayc.user.mapper.UserMapper;
|
||||||
|
import top.rayc.user.mapper.UserRoleMapper;
|
||||||
|
import top.rayc.user.service.IAuthService;
|
||||||
|
import top.rayc.utility.security.authentication.UsernamePasswordAuthentication;
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class AuthService implements IAuthService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserMapper userMapper;
|
||||||
|
@Autowired
|
||||||
|
private RoleMapper roleMapper;
|
||||||
|
@Autowired
|
||||||
|
private UserRoleMapper userRoleMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UsernamePasswordAuthentication auth(String username, String password) {
|
||||||
|
User storedUser = findUser(username);
|
||||||
|
|
||||||
|
log.info("username: {}; password: {}; storedUser: {}", username, password, storedUser);
|
||||||
|
|
||||||
|
if (storedUser == null || !verifyPassrword(password, storedUser.getPassword())) {
|
||||||
|
throw new BadCredentialsException("密码错误");
|
||||||
|
}
|
||||||
|
List<Role> roles = findRoles(storedUser);
|
||||||
|
|
||||||
|
return new UsernamePasswordAuthentication(
|
||||||
|
storedUser.getUsername(),
|
||||||
|
password,
|
||||||
|
roles.stream().map(role -> new SimpleGrantedAuthority(role.getRoleName())).toList()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Role> findRoles(User user) {
|
||||||
|
LambdaQueryWrapper<UserRole> userRoleWrapper = new LambdaQueryWrapper<>();
|
||||||
|
userRoleWrapper.eq(UserRole::getUserId, user.getId());
|
||||||
|
|
||||||
|
List<UserRole> userRoles = userRoleMapper.selectList(userRoleWrapper);
|
||||||
|
if (userRoles.isEmpty()) {
|
||||||
|
return new ArrayList<Role>();
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<Role> roleWrapper = new LambdaQueryWrapper<>();
|
||||||
|
roleWrapper.in(Role::getId,
|
||||||
|
userRoles.stream()
|
||||||
|
.map(UserRole::getRoleId)
|
||||||
|
.toList());
|
||||||
|
return roleMapper.selectList(roleWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean verifyPassrword(String password, String storedPassword) {
|
||||||
|
return passwordEncoder.matches(password, storedPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
private User findUser(String username) {
|
||||||
|
LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<>();
|
||||||
|
userWrapper.eq(User::getEmail, username);
|
||||||
|
return userMapper.selectOne(userWrapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
package top.rayc.user.service.impl;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
|
||||||
|
import top.rayc.user.controller.vo.req.UserCreateReq;
|
||||||
|
import top.rayc.user.controller.vo.resp.UserResp;
|
||||||
|
import top.rayc.user.converter.UserConverter;
|
||||||
|
import top.rayc.user.entity.Role;
|
||||||
|
import top.rayc.user.entity.User;
|
||||||
|
import top.rayc.user.entity.UserRole;
|
||||||
|
import top.rayc.user.mapper.RoleMapper;
|
||||||
|
import top.rayc.user.mapper.UserMapper;
|
||||||
|
import top.rayc.user.mapper.UserRoleMapper;
|
||||||
|
import top.rayc.user.service.IUserService;
|
||||||
|
import top.rayc.utility.id.DistributedId;
|
||||||
|
import top.rayc.utility.vo.BaseResult;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserService extends ServiceImpl<UserMapper, User> implements IUserService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RoleMapper roleMapper;
|
||||||
|
@Autowired
|
||||||
|
private UserRoleMapper userRoleMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity<BaseResult<UserResp>> createUser(UserCreateReq userReq) {
|
||||||
|
if (userReq.getCode() == "1234") throw new RuntimeException("验证码错误");
|
||||||
|
User newUser = UserConverter.INSTANCE.converterFromUserCreateReq(userReq);
|
||||||
|
newUser.setAccountId(DistributedId.getInstance().getSnowflake(1, 1));
|
||||||
|
|
||||||
|
Boolean result = this.save(newUser);
|
||||||
|
initializeUserRole(newUser, "Normal");
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
return ResponseEntity.ok(BaseResult.success(200, "Register Successful!!!", UserConverter.INSTANCE.converterToUserResp(newUser)));
|
||||||
|
} else {
|
||||||
|
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR.value())
|
||||||
|
.body(BaseResult.error(500,"failed!!!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'createUser'");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeUserRole(User user, String roleName) {
|
||||||
|
LambdaQueryWrapper<Role> query = new LambdaQueryWrapper<>();
|
||||||
|
query.eq(Role::getRoleName, roleName);
|
||||||
|
|
||||||
|
Role role = roleMapper.selectOne(query);
|
||||||
|
if (role != null) {
|
||||||
|
UserRole userRole = new UserRole();
|
||||||
|
userRole.setUserId(user.getId());
|
||||||
|
userRole.setRoleId(role.getId());
|
||||||
|
userRoleMapper.insert(userRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package top.rayc.user.utils;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
|
||||||
|
import top.rayc.user.entity.User;
|
||||||
|
import top.rayc.user.service.impl.UserService;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class UserHelper {
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
public User currentUser() {
|
||||||
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
|
||||||
|
if (authentication instanceof AnonymousAuthenticationToken) {
|
||||||
|
String email = authentication.getName();
|
||||||
|
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(User::getEmail, email);
|
||||||
|
|
||||||
|
return userService.getOne(wrapper);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue