初步搭建,后面需要细化用户管理,和文件管理
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