commit aa5fad5c0b2166776026940a2c61a6c14050c680 Author: wuchunlei Date: Wed Dec 10 15:32:48 2025 +0800 新建 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3b41682 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +/mvnw text eol=lf +*.cmd text eol=crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..667aaef --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..c0bcafe --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,3 @@ +wrapperVersion=3.3.4 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..bd8896b --- /dev/null +++ b/mvnw @@ -0,0 +1,295 @@ +#!/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 +# +# http://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.3.4 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + 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" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..92450f9 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,189 @@ +<# : batch portion +@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 http://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.3.4 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..94c7f41 --- /dev/null +++ b/pom.xml @@ -0,0 +1,175 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.5.8 + + + org.example + financial + 0.0.1-SNAPSHOT + financial + financial + + + + + + + + + + + + + + + 17 + + + + + + com.alibaba + druid-spring-boot-3-starter + 1.2.18 + + + + com.baomidou + dynamic-datasource-spring-boot-starter + 3.6.1 + + + + com.baomidou + mybatis-plus-spring-boot3-starter + 3.5.9 + + + com.github.yulichang + mybatis-plus-join-boot-starter + 1.4.6 + + + + com.baomidou + mybatis-plus-jsqlparser + 3.5.9 + + + + com.baomidou + mybatis-plus-generator + 3.5.15 + + + + org.freemarker + freemarker + 2.3.31 + + + + org.apache.shiro + shiro-spring + jakarta + 1.12.0 + + + + org.apache.shiro + shiro-core + + + org.apache.shiro + shiro-web + + + + + + org.apache.shiro + shiro-core + jakarta + 1.12.0 + + + org.apache.shiro + shiro-web + jakarta + 1.12.0 + + + org.apache.shiro + shiro-core + + + + + commons-lang + commons-lang + 2.6 + + + + com.google.code.gson + gson + 2.11.0 + + + + + org.springframework.boot + spring-boot-starter-web + + + com.mysql + mysql-connector-j + runtime + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/src/main/java/com/zmzm/financial/FinancialApplication.java b/src/main/java/com/zmzm/financial/FinancialApplication.java new file mode 100644 index 0000000..6a6b9e9 --- /dev/null +++ b/src/main/java/com/zmzm/financial/FinancialApplication.java @@ -0,0 +1,13 @@ +package com.zmzm.financial; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class FinancialApplication { + + public static void main(String[] args) { + SpringApplication.run(FinancialApplication.class, args); + } + +} diff --git a/src/main/java/com/zmzm/financial/common/controller/AuthController.java b/src/main/java/com/zmzm/financial/common/controller/AuthController.java new file mode 100644 index 0000000..9ec2690 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/controller/AuthController.java @@ -0,0 +1,67 @@ +package com.zmzm.financial.common.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zmzm.financial.common.entity.User; +import com.zmzm.financial.common.entity.UserToken; +import com.zmzm.financial.common.service.IUserService; +import com.zmzm.financial.common.service.IUserTokenService; +import com.zmzm.financial.util.MD5Utils; +import com.zmzm.financial.util.R; +import com.zmzm.financial.util.ShiroUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import java.util.Date; + +@Slf4j +@RestController("auth") +@RequestMapping("auth") +public class AuthController { + + @Autowired + private IUserService userService; + @Autowired + private IUserTokenService userTokenService; + + //登录 + @RequestMapping("/login") + public R login(@RequestBody User user){ + User userEntity = userService.getOne(new LambdaQueryWrapper() + .eq(User::getAccount, user.getAccount())); + if(userEntity == null){ + return R.error(500,"账号不存在"); + }else { + if (MD5Utils.getSaltverifyMD5(user.getPassword(),userEntity.getPassword())){ + UserToken userToken = userTokenService.createToken(userEntity.getId()); + return R.ok("登录成功").put("userToken",userToken); + }else { + return R.error(500,"密码不正确,请重试"); + } + } + } + + //注册 + @RequestMapping("/register") + public R register(@RequestBody User user){ + long count = userService.count(new LambdaQueryWrapper().eq(User::getAccount, user.getAccount())); + if(count>0){ + return R.error(500,"账号已注册"); + } + String saltMD5 = MD5Utils.getSaltMD5(user.getPassword()); + user.setPassword(saltMD5); + userService.save(user); + return R.ok(); + } + + //退出 + @RequestMapping("/logout") + public R logout(){ + UserToken userToken = userTokenService.getById(ShiroUtils.getUserId()); + userToken.setExpireTime(new Date()); + userTokenService.updateById(userToken); + return R.ok(); + } + +} diff --git a/src/main/java/com/zmzm/financial/common/controller/UserController.java b/src/main/java/com/zmzm/financial/common/controller/UserController.java new file mode 100644 index 0000000..d9116dc --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/controller/UserController.java @@ -0,0 +1,34 @@ +package com.zmzm.financial.common.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.extern.slf4j.Slf4j; +import com.zmzm.financial.common.entity.Customer; +import com.zmzm.financial.common.entity.WumenUser; +import com.zmzm.financial.common.service.CustomerService; +import com.zmzm.financial.common.service.WumenUserService; +import com.zmzm.financial.util.R; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController("commonUser") +@RequestMapping("common/user") +public class UserController { + + @Autowired + private WumenUserService wumenUserService; + @Autowired + private CustomerService customerService; + + //获取我的湖分列表 + @RequestMapping("/getUser") + public R getUserContribution(){ + WumenUser wumenUser = wumenUserService.getById("12301"); + Customer customer = customerService.getOne(new LambdaQueryWrapper() + .eq(Customer::getCellPhone,"15674886255")); + return R.ok().put("wumenUser",wumenUser).put("customer",customer); + } + + +} diff --git a/src/main/java/com/zmzm/financial/common/controller/UserTokenController.java b/src/main/java/com/zmzm/financial/common/controller/UserTokenController.java new file mode 100644 index 0000000..c3717f8 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/controller/UserTokenController.java @@ -0,0 +1,18 @@ +package com.zmzm.financial.common.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 用户token 前端控制器 + *

+ * + * @author baomidou + * @since 2025-12-10 + */ +@RestController +@RequestMapping("/common/userToken") +public class UserTokenController { + +} diff --git a/src/main/java/com/zmzm/financial/common/dao/CustomerDao.java b/src/main/java/com/zmzm/financial/common/dao/CustomerDao.java new file mode 100644 index 0000000..98942e9 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/dao/CustomerDao.java @@ -0,0 +1,11 @@ +package com.zmzm.financial.common.dao; + +import com.baomidou.dynamic.datasource.annotation.DS; +import com.github.yulichang.base.MPJBaseMapper; +import org.apache.ibatis.annotations.Mapper; +import com.zmzm.financial.common.entity.Customer; + +@Mapper +@DS("yljk") +public interface CustomerDao extends MPJBaseMapper { +} diff --git a/src/main/java/com/zmzm/financial/common/dao/UserMapper.java b/src/main/java/com/zmzm/financial/common/dao/UserMapper.java new file mode 100644 index 0000000..98b1de7 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/dao/UserMapper.java @@ -0,0 +1,18 @@ +package com.zmzm.financial.common.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zmzm.financial.common.entity.User; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author baomidou + * @since 2025-12-10 + */ +@Mapper +public interface UserMapper extends BaseMapper { + +} diff --git a/src/main/java/com/zmzm/financial/common/dao/UserTokenMapper.java b/src/main/java/com/zmzm/financial/common/dao/UserTokenMapper.java new file mode 100644 index 0000000..64ae137 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/dao/UserTokenMapper.java @@ -0,0 +1,18 @@ +package com.zmzm.financial.common.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zmzm.financial.common.entity.UserToken; +import org.apache.ibatis.annotations.Mapper; + +/** + *

+ * 用户token Mapper 接口 + *

+ * + * @author baomidou + * @since 2025-12-10 + */ +@Mapper +public interface UserTokenMapper extends BaseMapper { + +} diff --git a/src/main/java/com/zmzm/financial/common/dao/WumenUserDao.java b/src/main/java/com/zmzm/financial/common/dao/WumenUserDao.java new file mode 100644 index 0000000..766c10a --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/dao/WumenUserDao.java @@ -0,0 +1,11 @@ +package com.zmzm.financial.common.dao; + +import com.baomidou.dynamic.datasource.annotation.DS; +import com.github.yulichang.base.MPJBaseMapper; +import org.apache.ibatis.annotations.Mapper; +import com.zmzm.financial.common.entity.WumenUser; + +@Mapper +@DS("wumen") +public interface WumenUserDao extends MPJBaseMapper { +} diff --git a/src/main/java/com/zmzm/financial/common/entity/Customer.java b/src/main/java/com/zmzm/financial/common/entity/Customer.java new file mode 100644 index 0000000..e5ce7a8 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/entity/Customer.java @@ -0,0 +1,131 @@ +package com.zmzm.financial.common.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import java.io.Serializable; +import java.util.Date; + +@Data +@TableName("t_customer") +public class Customer implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId("oid") + private String oid; + @TableField("description") + private String description = ""; + + // 客户编号 + @TableField("customerID") + private String customerID = ""; + // 创建日期 + @TableField("createDate") + private Date createDate = new Date(); + // 唯一码 + @TableField("uniqueKey") + private String uniqueKey = ""; + // 邀请码 + @TableField("inviteCode") + private String inviteCode = ""; + // 推荐人 + @TableField("commendCode") + private String commendCode = ""; + // 客户类型(健康人群H 肿瘤患者C 医生D) + @TableField("customerType") + private String customerType = ""; + // 昵称 + @TableField("nickName") + private String nickName = ""; + // 真实姓名 + @TableField("nameCN") + private String nameCN = ""; + // 电话 + @TableField("cellPhone") + private String cellPhone = ""; + // 头像 + @TableField("icons") + private String icons = ""; + // 登录密码 + @TableField("loginPwd") + private String loginPwd = ""; + // 灵兰币 + @TableField("point") + private int point = 0; + // 总灵兰币 + @TableField("totalPoint") + private int totalPoint = 0; + // 积分 + @TableField("pointByJF") + private int pointByJF = 0; + // 总积分 + @TableField("totalPointByJF") + private int totalPointByJF = 0; + // 省oid + @TableField("provinceOid") + private String provinceOid = ""; + // 市oid + @TableField("cityOid") + private String cityOid = ""; + // 设备类型(苹果i 安卓a) + @TableField("deviceType") + private String deviceType = ""; + // 推送状态(不推送0 推送1) + @TableField("pushStatus") + private String pushStatus = "1"; + // 推送标识 + @TableField("pushCID") + private String pushCID = ""; + // 付费状态(未付费0 付费1 VIP2) + @TableField("payStatus") + private String payStatus = "0"; + // 付费日期 + @TableField("payDate") + private Date payDate; + // 付费有效日期 + @TableField("payValidDate") + private Date payValidDate; + // 登录中(是1 否0) + @TableField("isLogin") + private String isLogin = "1"; + // 最后登录时间 + @TableField("loginDateTime") + private Date loginDateTime; + // 当天已登录(是1 否0) + @TableField("logined") + private String logined = "1"; + // 设备版本 + @TableField("deviceVersion") + private String deviceVersion = ""; + // 推荐日期 + @TableField("commendDate") + private Date commendDate; + // 推荐批次号 + @TableField("commendBatchNo") + private String commendBatchNo = ""; + // 推荐人数差 + @TableField("subCommends") + private int subCommends = 9; + // 超级VIP + @TableField("superVIP") + private String superVIP = "0"; + // 学生标志 + @TableField("studentFlg") + private String studentFlg = "0"; + // 学生证截止日期 + @TableField("endDateByStudent") + private Date endDateByStudent = null; + // 公司标志 + @TableField("companyFlg") + private String companyFlg = "0"; + // 公司 + @TableField("companyOid") + private String companyOid = ""; + // + @TableField("luckFlg") + private String luckFlg = ""; + // 邀请人数 + @TableField("inviteNum") + private int inviteNum = 0; +} diff --git a/src/main/java/com/zmzm/financial/common/entity/User.java b/src/main/java/com/zmzm/financial/common/entity/User.java new file mode 100644 index 0000000..4750e73 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/entity/User.java @@ -0,0 +1,62 @@ +package com.zmzm.financial.common.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + *

+ * + *

+ * + * @author baomidou + * @since 2025-12-10 + */ +@Getter +@Setter +@ToString +public class User implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + /** + * 用户名 + */ + private String name; + + /** + * 账户 + */ + private String account; + + /** + * 密码 + */ + private String password; + + /** + * 0管理员1财务 + */ + private Byte role; + + /** + * 最后登录时间 + */ + private LocalDateTime lastTime; + + /** + * 状态0初始1删除 + */ + private Byte state; +} diff --git a/src/main/java/com/zmzm/financial/common/entity/UserToken.java b/src/main/java/com/zmzm/financial/common/entity/UserToken.java new file mode 100644 index 0000000..84d94d7 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/entity/UserToken.java @@ -0,0 +1,35 @@ +package com.zmzm.financial.common.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 用户token + *

+ * + * @author baomidou + * @since 2025-12-10 + */ +@Getter +@Setter +@ToString +@TableName("user_token") +public class UserToken implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId("user_id") + private Integer userId; + + private Date expireTime; + + private String token; + + private Date updateTime; +} diff --git a/src/main/java/com/zmzm/financial/common/entity/WumenUser.java b/src/main/java/com/zmzm/financial/common/entity/WumenUser.java new file mode 100644 index 0000000..743aed9 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/entity/WumenUser.java @@ -0,0 +1,140 @@ +package com.zmzm.financial.common.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +@Data +@TableName("user") +public class WumenUser implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * + */ + @TableId + private Integer id; + /** + * 姓名 + */ + private String name; + /** + * 证件照 + */ + private String photo; + /** + * 年龄 + */ + private Integer age; + /** + * 性别 + */ + private Integer sex; + /** + * 头像 + */ + private String avatar; + /** + * 昵称 + */ + private String nickname; + /** + * 电话 + */ + private String tel; + /** + * 邮箱 + */ + private String email; + /** + * 密码 + */ + private String password; + /** + * 0-普通 1-vip //0-普通 1超级vip 2医学vip 3国学vip + */ + private String vip; + /** + * vip 有效期 + */ + private Date vipStartTime; + /** + * vip 有效期 + */ + private Date vipValidtime; + /** + * 花生币 + */ + private BigDecimal peanutCoin; + /** + * 积分 + */ + private BigDecimal jf; + + /** + * 邀请码 + */ + private String inviteCode; + /** + * 阅读时间 + */ + private Date readTime; + /** + * 最后登录时间 + */ + private Date lastLoginTime; + + /** + * 一路健康oid + */ + private String yljkOid; + + /** + * 是否有脉穴的查看权限 + */ + private Integer pointPower; + + /** + * 是否有时辰取穴的权限 + */ + private Integer tgdzPower; + + /** + * 五运六气权限 + */ + private Integer wylqPower; + + /** + * 吴门验方权限 + */ + private Integer prescriptAPower; + + /** + * 肿瘤古方权限 + */ + private Integer prescriptBPower; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT)//创建注解 + private Date createTime; + /** + * 更新时间 + */ + @TableField(fill = FieldFill.INSERT_UPDATE)//更新注解 + private Date updateTime; + /** + * 删除标记 + */ + @TableLogic + private Integer delFlag; + + private String migrationCode; + + private String remark; + + +} \ No newline at end of file diff --git a/src/main/java/com/zmzm/financial/common/mapper/xml/UserTokenMapper.xml b/src/main/java/com/zmzm/financial/common/mapper/xml/UserTokenMapper.xml new file mode 100644 index 0000000..e0adaf6 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/mapper/xml/UserTokenMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/java/com/zmzm/financial/common/service/CustomerService.java b/src/main/java/com/zmzm/financial/common/service/CustomerService.java new file mode 100644 index 0000000..cf8c8cc --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/service/CustomerService.java @@ -0,0 +1,7 @@ +package com.zmzm.financial.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zmzm.financial.common.entity.Customer; + +public interface CustomerService extends IService { +} diff --git a/src/main/java/com/zmzm/financial/common/service/IUserService.java b/src/main/java/com/zmzm/financial/common/service/IUserService.java new file mode 100644 index 0000000..4e787f7 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/service/IUserService.java @@ -0,0 +1,16 @@ +package com.zmzm.financial.common.service; + +import com.zmzm.financial.common.entity.User; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 服务类 + *

+ * + * @author baomidou + * @since 2025-12-10 + */ +public interface IUserService extends IService { + +} diff --git a/src/main/java/com/zmzm/financial/common/service/IUserTokenService.java b/src/main/java/com/zmzm/financial/common/service/IUserTokenService.java new file mode 100644 index 0000000..3aa3266 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/service/IUserTokenService.java @@ -0,0 +1,18 @@ +package com.zmzm.financial.common.service; + +import com.zmzm.financial.common.entity.UserToken; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 用户token 服务类 + *

+ * + * @author baomidou + * @since 2025-12-10 + */ +public interface IUserTokenService extends IService { + + UserToken createToken(int userId); + +} diff --git a/src/main/java/com/zmzm/financial/common/service/WumenUserService.java b/src/main/java/com/zmzm/financial/common/service/WumenUserService.java new file mode 100644 index 0000000..411f8fd --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/service/WumenUserService.java @@ -0,0 +1,7 @@ +package com.zmzm.financial.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zmzm.financial.common.entity.WumenUser; + +public interface WumenUserService extends IService { +} diff --git a/src/main/java/com/zmzm/financial/common/service/impl/CustomerServiceImpl.java b/src/main/java/com/zmzm/financial/common/service/impl/CustomerServiceImpl.java new file mode 100644 index 0000000..b1172c0 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/service/impl/CustomerServiceImpl.java @@ -0,0 +1,13 @@ +package com.zmzm.financial.common.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import com.zmzm.financial.common.dao.CustomerDao; +import com.zmzm.financial.common.entity.Customer; +import com.zmzm.financial.common.service.CustomerService; +import org.springframework.stereotype.Service; + +@Slf4j +@Service("commonCustomerService") +public class CustomerServiceImpl extends ServiceImpl implements CustomerService { +} diff --git a/src/main/java/com/zmzm/financial/common/service/impl/UserServiceImpl.java b/src/main/java/com/zmzm/financial/common/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..f02e9af --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/service/impl/UserServiceImpl.java @@ -0,0 +1,20 @@ +package com.zmzm.financial.common.service.impl; + +import com.zmzm.financial.common.entity.User; +import com.zmzm.financial.common.dao.UserMapper; +import com.zmzm.financial.common.service.IUserService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author baomidou + * @since 2025-12-10 + */ +@Service +public class UserServiceImpl extends ServiceImpl implements IUserService { + +} diff --git a/src/main/java/com/zmzm/financial/common/service/impl/UserTokenServiceImpl.java b/src/main/java/com/zmzm/financial/common/service/impl/UserTokenServiceImpl.java new file mode 100644 index 0000000..1be7982 --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/service/impl/UserTokenServiceImpl.java @@ -0,0 +1,40 @@ +package com.zmzm.financial.common.service.impl; + +import com.zmzm.financial.common.entity.UserToken; +import com.zmzm.financial.common.dao.UserTokenMapper; +import com.zmzm.financial.common.service.IUserTokenService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zmzm.financial.util.TokenGenerator; +import org.springframework.stereotype.Service; + +import java.util.Date; + +/** + *

+ * 用户token 服务实现类 + *

+ * + * @author baomidou + * @since 2025-12-10 + */ +@Service +public class UserTokenServiceImpl extends ServiceImpl implements IUserTokenService { + + @Override + public UserToken createToken(int userId) { + String token = TokenGenerator.generateValue(); + Date now = new Date(); + Date expireTime = new Date(now.getTime() + 3600 * 3 * 1000); + //判断是否生成过token + UserToken userToken = this.getById(userId); + if (userToken == null) { + userToken = new UserToken(); + userToken.setUserId(userId); + } + userToken.setExpireTime(expireTime); + userToken.setToken(token); + userToken.setUpdateTime(now); + this.saveOrUpdate(userToken); + return userToken; + } +} diff --git a/src/main/java/com/zmzm/financial/common/service/impl/WumenUserServiceImpl.java b/src/main/java/com/zmzm/financial/common/service/impl/WumenUserServiceImpl.java new file mode 100644 index 0000000..b3300fc --- /dev/null +++ b/src/main/java/com/zmzm/financial/common/service/impl/WumenUserServiceImpl.java @@ -0,0 +1,13 @@ +package com.zmzm.financial.common.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import com.zmzm.financial.common.dao.WumenUserDao; +import com.zmzm.financial.common.entity.WumenUser; +import com.zmzm.financial.common.service.WumenUserService; +import org.springframework.stereotype.Service; + +@Slf4j +@Service("commonWumenUserService") +public class WumenUserServiceImpl extends ServiceImpl implements WumenUserService { +} diff --git a/src/main/java/com/zmzm/financial/config/CorsConfig.java b/src/main/java/com/zmzm/financial/config/CorsConfig.java new file mode 100644 index 0000000..690d1c2 --- /dev/null +++ b/src/main/java/com/zmzm/financial/config/CorsConfig.java @@ -0,0 +1,18 @@ +package com.zmzm.financial.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class CorsConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOriginPatterns("*") + .allowCredentials(true) + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") + .maxAge(3600); + } +} \ No newline at end of file diff --git a/src/main/java/com/zmzm/financial/config/CustomRealm.java b/src/main/java/com/zmzm/financial/config/CustomRealm.java new file mode 100644 index 0000000..4c53d4c --- /dev/null +++ b/src/main/java/com/zmzm/financial/config/CustomRealm.java @@ -0,0 +1,63 @@ +package com.zmzm.financial.config; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zmzm.financial.common.entity.User; +import com.zmzm.financial.common.entity.UserToken; +import com.zmzm.financial.common.service.IUserService; +import com.zmzm.financial.common.service.IUserTokenService; +import org.apache.shiro.authc.*; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.authz.SimpleAuthorizationInfo; +import org.apache.shiro.realm.AuthorizingRealm; +import org.apache.shiro.subject.PrincipalCollection; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Date; + +@Component +public class CustomRealm extends AuthorizingRealm { + + @Autowired + private IUserService userService; + @Autowired + private IUserTokenService userTokenService; + + @Override + public boolean supports(AuthenticationToken token) { + return token instanceof OAuth2Token; + } + + @Override + protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { + String account = (String) principals.getPrimaryPrincipal(); + User user = userService.getOne(new LambdaQueryWrapper().eq(User::getAccount, account)); + SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); +// info.addRoles(user.getRole()); + return info; + } + + @Override + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) + throws AuthenticationException { + String accessToken = token.getPrincipal().toString(); + UserToken userToken = userTokenService.getOne(new LambdaQueryWrapper() + .eq(UserToken::getToken, accessToken)); + //token失效 + if(userToken == null || userToken.getExpireTime().getTime() < System.currentTimeMillis()){ + throw new IncorrectCredentialsException("token失效,请重新登录"); + } + User user = userService.getById(userToken.getUserId()); + if (user == null) throw new UnknownAccountException(); + Long timeout = (userToken.getExpireTime().getTime() - System.currentTimeMillis())/(1000 * 60 * 60); + if (timeout <= 1){ + // token 续期 + Date now = new Date(); + Date expireTime = new Date(now.getTime() + (3600 * 3 * 1000) ); + userToken.setExpireTime(expireTime); + userTokenService.updateById(userToken); + } + return new SimpleAuthenticationInfo(user, token.getCredentials(), getName()); + } +} + diff --git a/src/main/java/com/zmzm/financial/config/MybatisPlusConfig.java b/src/main/java/com/zmzm/financial/config/MybatisPlusConfig.java new file mode 100644 index 0000000..515c1c6 --- /dev/null +++ b/src/main/java/com/zmzm/financial/config/MybatisPlusConfig.java @@ -0,0 +1,19 @@ +package com.zmzm.financial.config; + + +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MybatisPlusConfig { + + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // 添加分页插件 + interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); + return interceptor; + } +} diff --git a/src/main/java/com/zmzm/financial/config/OAuth2Filter.java b/src/main/java/com/zmzm/financial/config/OAuth2Filter.java new file mode 100644 index 0000000..f7118cc --- /dev/null +++ b/src/main/java/com/zmzm/financial/config/OAuth2Filter.java @@ -0,0 +1,95 @@ +package com.zmzm.financial.config; + +import com.google.gson.Gson; +import com.zmzm.financial.util.HttpContextUtils; +import com.zmzm.financial.util.R; +import org.apache.commons.lang.StringUtils; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.web.filter.authc.AuthenticatingFilter; +import org.springframework.web.bind.annotation.RequestMethod; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * oauth2过滤器 + * + * @author Mark sunlightcs@gmail.com + */ +public class OAuth2Filter extends AuthenticatingFilter { + + @Override + protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception { + //获取请求token + String token = getRequestToken((HttpServletRequest) request); + if(StringUtils.isBlank(token)){ + return null; + } + return new OAuth2Token(token); + } + + @Override + protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { + if(((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name())){ + return true; + } + return false; + } + + @Override + protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { + //获取请求token,如果token不存在,直接返回401 + String token = getRequestToken((HttpServletRequest) request); + if(StringUtils.isBlank(token)){ + HttpServletResponse httpResponse = (HttpServletResponse) response; + httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); + httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin()); + + String json = new Gson().toJson(R.error(401, "invalid token")); + + httpResponse.getWriter().print(json); + + return false; + } + + return executeLogin(request, response); + } + + @Override + protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) { + HttpServletResponse httpResponse = (HttpServletResponse) response; + httpResponse.setContentType("application/json;charset=utf-8"); + httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); + httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin()); + try { + //处理登录失败的异常 + Throwable throwable = e.getCause() == null ? e : e.getCause(); + R r = R.error(401, throwable.getMessage()); + + String json = new Gson().toJson(r); + httpResponse.getWriter().print(json); + } catch (IOException e1) { + + } + + return false; + } + + /** + * 获取请求的token + */ + private String getRequestToken(HttpServletRequest httpRequest){ + //从header中获取token + String token = httpRequest.getHeader("token"); + //如果header中不存在token,则从参数中获取token + if(StringUtils.isBlank(token)){ + token = httpRequest.getParameter("token"); + } + return token; + } + + +} diff --git a/src/main/java/com/zmzm/financial/config/OAuth2Token.java b/src/main/java/com/zmzm/financial/config/OAuth2Token.java new file mode 100644 index 0000000..0309539 --- /dev/null +++ b/src/main/java/com/zmzm/financial/config/OAuth2Token.java @@ -0,0 +1,29 @@ +package com.zmzm.financial.config; + +import org.apache.shiro.authc.AuthenticationToken; + +/** + * token + * + * @author Mark sunlightcs@gmail.com + */ +public class OAuth2Token implements AuthenticationToken { + + private String token; + + public OAuth2Token(String token){ + this.token = token; + } + + @Override + public String getPrincipal() { + return token; + } + + @Override + public Object getCredentials() { + return token; + } + +} + diff --git a/src/main/java/com/zmzm/financial/config/ShiroConfig.java b/src/main/java/com/zmzm/financial/config/ShiroConfig.java new file mode 100644 index 0000000..cdd6cb1 --- /dev/null +++ b/src/main/java/com/zmzm/financial/config/ShiroConfig.java @@ -0,0 +1,51 @@ +package com.zmzm.financial.config; + +import jakarta.servlet.Filter; +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.realm.Realm; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +@Configuration +public class ShiroConfig { + + @Bean + public Realm realm() { + CustomRealm customRealm = new CustomRealm(); + customRealm.setAuthenticationTokenClass(OAuth2Token.class); + return customRealm; + } + + @Bean + public DefaultWebSecurityManager securityManager(Realm realm) { + DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); + securityManager.setRealm(realm); + securityManager.setRememberMeManager(null); + return securityManager; + } + + @Bean + public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { + ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); + shiroFilter.setSecurityManager(securityManager); + + //oauth过滤 + Map filters = new HashMap<>(); + filters.put("oauth2", new OAuth2Filter()); + shiroFilter.setFilters(filters); + + Map filterMap = new LinkedHashMap<>(); + filterMap.put("/auth/login", "anon"); + filterMap.put("/auth/register", "anon"); + filterMap.put("/**", "oauth2"); + shiroFilter.setFilterChainDefinitionMap(filterMap); + + return shiroFilter; + } + +} diff --git a/src/main/java/com/zmzm/financial/util/CodeGenerator.java b/src/main/java/com/zmzm/financial/util/CodeGenerator.java new file mode 100644 index 0000000..596b498 --- /dev/null +++ b/src/main/java/com/zmzm/financial/util/CodeGenerator.java @@ -0,0 +1,48 @@ +package com.zmzm.financial.util; + +import com.baomidou.mybatisplus.generator.*; +import com.baomidou.mybatisplus.generator.config.rules.DbColumnType; +import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; +import java.nio.file.Paths; +import java.sql.Types; + +public class CodeGenerator { + + public static void main(String[] args) { + FastAutoGenerator.create( + "jdbc:mysql://rm-2zev4157t67trxuu3yo.mysql.rds.aliyuncs.com:3306/finance?rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai", + "nuttyreading", + "Wu751019!") + .globalConfig(builder -> { + builder.outputDir(Paths.get(System.getProperty("user.dir")) + "/src/main/java"); // 指定输出目录 + }) + .dataSourceConfig(builder -> + builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> { + int typeCode = metaInfo.getJdbcType().TYPE_CODE; + if (typeCode == Types.SMALLINT) { + // 自定义类型转换 + return DbColumnType.INTEGER; + } + return typeRegistry.getColumnType(metaInfo); + }) + ) + .packageConfig(builder -> + builder.parent("com.zmzm.financial") // 设置父包名 + .moduleName("common") // 设置父包模块名 + .entity("entity") + .mapper("dao") + .service("service") + .serviceImpl("service.impl") + ) + .strategyConfig(builder -> + builder.addInclude("user_token") // 设置需要生成的表名 + .addTablePrefix("t_", "c_") // 设置过滤表前缀 + .entityBuilder() + .enableLombok() + .controllerBuilder() + .enableRestStyle() + ) + .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板 + .execute(); + } +} \ No newline at end of file diff --git a/src/main/java/com/zmzm/financial/util/HttpContextUtils.java b/src/main/java/com/zmzm/financial/util/HttpContextUtils.java new file mode 100644 index 0000000..2852bf8 --- /dev/null +++ b/src/main/java/com/zmzm/financial/util/HttpContextUtils.java @@ -0,0 +1,24 @@ +package com.zmzm.financial.util; + +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import jakarta.servlet.http.HttpServletRequest; + +public class HttpContextUtils { + + public static HttpServletRequest getHttpServletRequest() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + } + + public static String getDomain(){ + HttpServletRequest request = getHttpServletRequest(); + StringBuffer url = request.getRequestURL(); + return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString(); + } + + public static String getOrigin(){ + HttpServletRequest request = getHttpServletRequest(); + return request.getHeader("Origin"); + } +} + diff --git a/src/main/java/com/zmzm/financial/util/MD5Utils.java b/src/main/java/com/zmzm/financial/util/MD5Utils.java new file mode 100644 index 0000000..1a3d9b9 --- /dev/null +++ b/src/main/java/com/zmzm/financial/util/MD5Utils.java @@ -0,0 +1,256 @@ +package com.zmzm.financial.util; + +import org.apache.shiro.codec.Hex; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Random; + + +/** + * @author hh@163.com: + * @version 创建时间:2018-3-20 下午2:40:13 + * @introduction + */ +public class MD5Utils { + + /** + * 普通MD5加密 01 + *

+ * + * @Title : getStrMD5 + *

+ *

+ * @Description : TODO + *

+ *

+ * @Author : HuaZai + *

+ *

+ * @Date : 2017年12月26日 下午2:49:44 + *

+ */ + public static String getStrMD5(String inStr) { + // 获取MD5实例 + MessageDigest md5 = null; + try { + md5 = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + System.out.println(e.toString()); + return ""; + } + + // 将加密字符串转换为字符数组 + char[] charArray = inStr.toCharArray(); + byte[] byteArray = new byte[charArray.length]; + + // 开始加密 + for (int i = 0; i < charArray.length; i++) + byteArray[i] = (byte) charArray[i]; + byte[] digest = md5.digest(byteArray); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < digest.length; i++) { + int var = digest[i] & 0xff; + if (var < 16) + sb.append("0"); + sb.append(Integer.toHexString(var)); + } + return sb.toString(); + } + + /** + * 普通MD5加密 02 + *

+ * + * @Title : getStrrMD5 + *

+ *

+ * @Description : TODO + *

+ *

+ * @Author : HuaZai + *

+ *

+ * @Date : 2017年12月27日 上午11:18:39 + *

+ */ + public static String getStrrMD5(String password) { + + char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + try { + byte strTemp[] = password.getBytes("UTF-8"); + MessageDigest mdTemp = MessageDigest.getInstance("MD5"); + mdTemp.update(strTemp); + byte md[] = mdTemp.digest(); + int j = md.length; + char str[] = new char[j * 2]; + int k = 0; + for (int i = 0; i < j; i++) { + byte byte0 = md[i]; + str[k++] = hexDigits[byte0 >>> 4 & 15]; + str[k++] = hexDigits[byte0 & 15]; + } + + return new String(str); + } catch (Exception e) { + return null; + } + } + + /** + * MD5双重解密 + *

+ * + * @Title : getconvertMD5 + *

+ *

+ * @Description : TODO + *

+ *

+ * @Author : HuaZai + *

+ *

+ * @Date : 2017年12月26日 下午3:34:17 + *

+ */ + public static String getconvertMD5(String inStr) { + char[] charArray = inStr.toCharArray(); + for (int i = 0; i < charArray.length; i++) { + charArray[i] = (char) (charArray[i] ^ 't'); + } + String str = String.valueOf(charArray); + return str; + } + + /** + * 使用Apache的Hex类实现Hex(16进制字符串和)和字节数组的互转 + *

+ * + * @Title : md5Hex + *

+ *

+ * @Description : TODO + *

+ *

+ * @Author : HuaZai + *

+ *

+ * @Date : 2017年12月27日 上午11:28:25 + *

+ */ + @SuppressWarnings("unused") + private static String md5Hex(String str) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] digest = md.digest(str.getBytes()); + return new String(new Hex().encode(digest)); + } catch (Exception e) { + e.printStackTrace(); + System.out.println(e.toString()); + return ""; + } + } + + /** + * 加盐MD5加密 + *

+ * + * @Title : getSaltMD5 + *

+ *

+ * @Description : TODO + *

+ *

+ * @Author : HuaZai + *

+ *

+ * @Date : 2017年12月27日 上午11:21:00 + *

+ */ + public static String getSaltMD5(String password) { + // 生成一个16位的随机数 + Random random = new Random(); + StringBuilder sBuilder = new StringBuilder(16); + sBuilder.append(random.nextInt(99999999)).append(random.nextInt(99999999)); + int len = sBuilder.length(); + if (len < 16) { + for (int i = 0; i < 16 - len; i++) { + sBuilder.append("0"); + } + } + // 生成最终的加密盐 + String Salt = sBuilder.toString(); + password = md5Hex(password + Salt); + char[] cs = new char[48]; + for (int i = 0; i < 48; i += 3) { + cs[i] = password.charAt(i / 3 * 2); + char c = Salt.charAt(i / 3); + cs[i + 1] = c; + cs[i + 2] = password.charAt(i / 3 * 2 + 1); + } + return String.valueOf(cs); + } + + /** + * 验证加盐后是否和原文一致 + *

+ * + * @Title : verifyMD5 + *

+ *

+ * @Description : TODO + *

+ *

+ * @Author : HuaZai + *

+ *

+ * @Date : 2017年12月27日 下午2:22:22 + *

+ */ + public static boolean getSaltverifyMD5(String password, String md5str) { + char[] cs1 = new char[32]; + char[] cs2 = new char[16]; + for (int i = 0; i < 48; i += 3) { + cs1[i / 3 * 2] = md5str.charAt(i); + cs1[i / 3 * 2 + 1] = md5str.charAt(i + 2); + cs2[i / 3] = md5str.charAt(i + 1); + } + String Salt = new String(cs2); + return md5Hex(password + Salt).equals(String.valueOf(cs1)); + } + public static void main(String[] args) { + MD5Utils md = new MD5Utils(); + String strMD5 = new String("696c23c1e04f330c55a635f571ee949f"); + + System.out.println("原始:" + strMD5); + System.out.println("东东的:" + md.getStrrMD5(strMD5)); + System.out.println("MD5后:" + md.getStrMD5(strMD5)); + System.out.println("加密的:" + md.getconvertMD5(strMD5)); + System.out.println("解密的:" + md.getconvertMD5(md.getconvertMD5(strMD5))); + + System.out.println("\t\t======================================="); + // 原文 + String plaintext = "huazai"; + // plaintext = "123456"; + System.out.println("原始:" + plaintext); + System.out.println("普通MD5后:" + MD5Utils.getStrMD5(plaintext)); + + // 获取加盐后的MD5值 + String ciphertext = MD5Utils.getSaltMD5(plaintext); + System.out.println("加盐后MD5:" + ciphertext); + System.out.println("是否是同一字符串:" + MD5Utils.getSaltverifyMD5(plaintext, ciphertext)); + /** + * 其中某次DingSai字符串的MD5值 + */ + String[] tempSalt = { "810e1ee9ee5e28188658f431451a29c2d81048de6a108e8a", + "66db82d9da2e35c95416471a147d12e46925d38e1185c043", + "61a718e4c15d914504a41d95230087a51816632183732b5a" }; + + for (String temp : tempSalt) { + System.out.println("是否是同一字符串:" + MD5Utils.getSaltverifyMD5(plaintext, temp)); + } + + } + +} diff --git a/src/main/java/com/zmzm/financial/util/R.java b/src/main/java/com/zmzm/financial/util/R.java new file mode 100644 index 0000000..1c639a2 --- /dev/null +++ b/src/main/java/com/zmzm/financial/util/R.java @@ -0,0 +1,60 @@ +package com.zmzm.financial.util; + +import lombok.Data; +import java.util.HashMap; +import java.util.Map; + +/** + * 返回数据 + */ +@Data +public class R extends HashMap { + private static final long serialVersionUID = 1L; + + public R() { + put("code", 0); + put("msg", "success"); + } + + public static R error(int code, String msg) { + R r = new R(); + r.put("code", code); + r.put("msg", msg); + return r; + } + + public static R code(int code){ + R r = new R(); + r.put("code",code); + return r; + } + + public static R code(int code,String msg){ + R r = new R(); + r.put("code",code); + r.put("msg",msg); + return r; + } + + public static R ok(String msg) { + R r = new R(); + r.put("msg", msg); + return r; + } + + public static R ok(Map map) { + R r = new R(); + r.putAll(map); + return r; + } + + public static R ok() { + return new R(); + } + + public R put(String key, Object value) { + super.put(key, value); + return this; + } +} + diff --git a/src/main/java/com/zmzm/financial/util/ShiroUtils.java b/src/main/java/com/zmzm/financial/util/ShiroUtils.java new file mode 100644 index 0000000..a301a10 --- /dev/null +++ b/src/main/java/com/zmzm/financial/util/ShiroUtils.java @@ -0,0 +1,45 @@ +package com.zmzm.financial.util; + +import com.zmzm.financial.common.entity.User; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.session.Session; +import org.apache.shiro.subject.Subject; + +/** + * Shiro工具类 + * + * @author Mark sunlightcs@gmail.com + */ +public class ShiroUtils { + + public static Session getSession() { + return SecurityUtils.getSubject().getSession(); + } + + public static Subject getSubject() { + return SecurityUtils.getSubject(); + } + + public static User getUserEntity() { + return (User)SecurityUtils.getSubject().getPrincipal(); + } + + public static Integer getUserId() { + return getUserEntity().getId(); + } + + public static void setSessionAttribute(Object key, Object value) { + getSession().setAttribute(key, value); + } + + public static Object getSessionAttribute(Object key) { + return getSession().getAttribute(key); + } + + public static boolean isLogin() { + return SecurityUtils.getSubject().getPrincipal() != null; + } + + +} + diff --git a/src/main/java/com/zmzm/financial/util/TokenGenerator.java b/src/main/java/com/zmzm/financial/util/TokenGenerator.java new file mode 100644 index 0000000..5f07835 --- /dev/null +++ b/src/main/java/com/zmzm/financial/util/TokenGenerator.java @@ -0,0 +1,43 @@ +package com.zmzm.financial.util; + +import java.security.MessageDigest; +import java.util.UUID; + +/** + * 生成token + * + * @author Mark sunlightcs@gmail.com + */ +public class TokenGenerator { + + public static String generateValue() { + return generateValue(UUID.randomUUID().toString()); + } + + private static final char[] hexCode = "0123456789abcdef".toCharArray(); + + public static String toHexString(byte[] data) { + if(data == null) { + return null; + } + StringBuilder r = new StringBuilder(data.length*2); + for ( byte b : data) { + r.append(hexCode[(b >> 4) & 0xF]); + r.append(hexCode[(b & 0xF)]); + } + return r.toString(); + } + + public static String generateValue(String param) { + try { + MessageDigest algorithm = MessageDigest.getInstance("MD5"); + algorithm.reset(); + algorithm.update(param.getBytes()); + byte[] messageDigest = algorithm.digest(); + return toHexString(messageDigest); + } catch (Exception e) { + throw new RuntimeException("生成Token失败", e); + } + } +} + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..3802a04 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,64 @@ +server: + port: 9000 + servlet: + context-path: /financial +spring: + servlet: + multipart: + max-file-size: 1000MB + max-request-size: 1000MB + datasource: + type: com.alibaba.druid.pool.DruidDataSource + druid: + validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + stat-view-servlet: + enabled: true + url-pattern: /druid/* + filter: + stat: + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: false + wall: + config: + multi-statement-allow: true + dynamic: + druid: + initial-size: 10 + max-active: 100 + min-idle: 10 + max-wait: 60000 + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 20 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + primary: master #设置默认的数据源或者数据源组,默认值即为master + datasource: + master: #主数据库 + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://rm-2zev4157t67trxuu3yo.mysql.rds.aliyuncs.com:3306/finance?rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai + username: nuttyreading + password: Wu751019! + wumen: #吴门医述数据库 + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://rm-2zev4157t67trxuu3yo.mysql.rds.aliyuncs.com:3306/e_book_test?rewriteBatchedStatements=true + username: nuttyreading + password: Wu751019! + yljk: #一路健康数据库 + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://goldorchid.mysql.rds.aliyuncs.com:3309/everhealth?rewriteBatchedStatements=true + username: yljkmaster + password: Wu751019!@ +#mybatis +mybatis-plus: + mapper-locations: classpath*:/mapper/**/*.xml + #原生配置 + configuration: + map-underscore-to-camel-case: true + cache-enabled: false + call-setters-on-nulls: true + jdbc-type-for-null: 'null' + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl \ No newline at end of file diff --git a/src/test/java/com/zmzm/financial/FinancialApplicationTests.java b/src/test/java/com/zmzm/financial/FinancialApplicationTests.java new file mode 100644 index 0000000..f09474f --- /dev/null +++ b/src/test/java/com/zmzm/financial/FinancialApplicationTests.java @@ -0,0 +1,13 @@ +package com.zmzm.financial; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class FinancialApplicationTests { + + @Test + void contextLoads() { + } + +}