mirror of
https://github.com/luoye663/e5.git
synced 2024-12-25 03:08:52 +00:00
修复保存client_id时除了判断github_id存在,还需要判断client_id
This commit is contained in:
commit
34ddc4d656
310
mvnw
vendored
Normal file
310
mvnw
vendored
Normal file
@ -0,0 +1,310 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`which java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=`cd "$wdir/.."; pwd`
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
else
|
||||
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
fi
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||
esac
|
||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if $cygwin; then
|
||||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
|
||||
fi
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget "$jarUrl" -O "$wrapperJarPath"
|
||||
else
|
||||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
|
||||
fi
|
||||
elif command -v curl > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl -o "$wrapperJarPath" "$jarUrl" -f
|
||||
else
|
||||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
|
||||
fi
|
||||
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaClass=`cygpath --path --windows "$javaClass"`
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
182
mvnw.cmd
vendored
Normal file
182
mvnw.cmd
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
|
||||
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
174
pom.xml
Normal file
174
pom.xml
Normal file
@ -0,0 +1,174 @@
|
||||
<?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>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.2.4.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>io.qyi</groupId>
|
||||
<artifactId>e5</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<name>e5</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- log4j2 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-log4j2</artifactId>
|
||||
</dependency>
|
||||
<!-- freemarker 模板引擎-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||
</dependency>
|
||||
<!--权限管理插件-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<!--thymeleaf-->
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<!--<version>4.12</version>-->
|
||||
<!--<scope>test</scope>-->
|
||||
</dependency>
|
||||
<!-- lombok插件 -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.16.22</version>
|
||||
</dependency>
|
||||
<!-- commons-lang -->
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.62</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.21</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.2.0</version>
|
||||
</dependency>
|
||||
<!--Mybatis plus代码生成器-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-generator</artifactId>
|
||||
<version>3.2.0</version>
|
||||
</dependency>
|
||||
<!--添加redis缓存依赖-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<!-- redis依赖commons-pool 这个依赖一定要添加 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--OKHTTP-->
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>3.10.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>28.1-jre</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.9</version>
|
||||
</dependency>
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
<!– <version>4.3.9.RELEASE</version>–>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<!-- <version>1.8.9</version>-->
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<!-- <version>1.8.9</version>-->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!--quartz 定时任务-->
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz</artifactId>
|
||||
<version>2.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.quartz-scheduler</groupId>
|
||||
<artifactId>quartz-jobs</artifactId>
|
||||
<version>2.2.1</version>
|
||||
</dependency>
|
||||
<!--因为quartz 需要有Spring context 所有引入mail包-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
147
src/main/java/io/qyi/e5/AutoGenerator_.java
Normal file
147
src/main/java/io/qyi/e5/AutoGenerator_.java
Normal file
@ -0,0 +1,147 @@
|
||||
package io.qyi.e5;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.baomidou.mybatisplus.generator.AutoGenerator;
|
||||
import com.baomidou.mybatisplus.generator.InjectionConfig;
|
||||
import com.baomidou.mybatisplus.generator.config.*;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
|
||||
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* @program: demo
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2019-10-23 01:15
|
||||
**/
|
||||
public class AutoGenerator_ {
|
||||
/**
|
||||
* <p>
|
||||
* 读取控制台内容
|
||||
* </p>
|
||||
*/
|
||||
public static String scanner(String tip) {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
StringBuilder help = new StringBuilder();
|
||||
help.append("请输入" + tip + ":");
|
||||
System.out.println(help.toString());
|
||||
if (scanner.hasNext()) {
|
||||
String ipt = scanner.next();
|
||||
if (StringUtils.isNotEmpty(ipt)) {
|
||||
return ipt;
|
||||
}
|
||||
}
|
||||
throw new MybatisPlusException("请输入正确的" + tip + "!");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 代码生成器
|
||||
AutoGenerator mpg = new AutoGenerator();
|
||||
|
||||
// 全局配置
|
||||
GlobalConfig gc = new GlobalConfig();
|
||||
String projectPath = System.getProperty("user.dir");
|
||||
gc.setOutputDir(projectPath + "/src/main/java");
|
||||
gc.setAuthor("落叶");
|
||||
gc.setOpen(false);
|
||||
// 是否覆盖
|
||||
gc.setFileOverride(true);
|
||||
// gc.setSwagger2(true); 实体属性 Swagger2 注解
|
||||
mpg.setGlobalConfig(gc);
|
||||
|
||||
|
||||
|
||||
// 数据源配置
|
||||
DataSourceConfig dsc = new DataSourceConfig();
|
||||
dsc.setUrl("jdbc:mysql://127.0.0.1:3306/e5?charset=utf8mb4&useSSL=false");
|
||||
// dsc.setSchemaName("public");
|
||||
dsc.setDriverName("com.mysql.jdbc.Driver");
|
||||
dsc.setUsername("root");
|
||||
dsc.setPassword("123456");
|
||||
mpg.setDataSource(dsc);
|
||||
|
||||
// 包配置
|
||||
PackageConfig pc = new PackageConfig();
|
||||
pc.setModuleName(scanner("模块名"));
|
||||
// pc.setModuleName("demo");
|
||||
pc.setParent("io.qyi.e5");
|
||||
mpg.setPackageInfo(pc);
|
||||
|
||||
// 自定义配置
|
||||
InjectionConfig cfg = new InjectionConfig() {
|
||||
@Override
|
||||
public void initMap() {
|
||||
// to do nothing
|
||||
}
|
||||
};
|
||||
|
||||
// 如果模板引擎是 freemarker
|
||||
String templatePath = "/templates/mapper.xml.ftl";
|
||||
// 如果模板引擎是 velocity
|
||||
// String templatePath = "/templates/mapper.xml.vm";
|
||||
|
||||
// 自定义输出配置
|
||||
List<FileOutConfig> focList = new ArrayList<>();
|
||||
// 自定义配置会被优先输出
|
||||
focList.add(new FileOutConfig(templatePath) {
|
||||
@Override
|
||||
public String outputFile(TableInfo tableInfo) {
|
||||
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
|
||||
return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
|
||||
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
|
||||
}
|
||||
});
|
||||
/*
|
||||
cfg.setFileCreate(new IFileCreate() {
|
||||
@Override
|
||||
public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
|
||||
// 判断自定义文件夹是否需要创建
|
||||
checkDir("调用默认方法创建的目录");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
*/
|
||||
cfg.setFileOutConfigList(focList);
|
||||
mpg.setCfg(cfg);
|
||||
|
||||
// 配置模板
|
||||
TemplateConfig templateConfig = new TemplateConfig();
|
||||
|
||||
// 配置自定义输出模板
|
||||
//指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
|
||||
// templateConfig.setEntity("templates/entity2.java");
|
||||
// templateConfig.setService();
|
||||
// templateConfig.setController();
|
||||
|
||||
templateConfig.setXml(null);
|
||||
// templateConfig.setController(null);
|
||||
mpg.setTemplate(templateConfig);
|
||||
|
||||
// 策略配置
|
||||
StrategyConfig strategy = new StrategyConfig();
|
||||
strategy.setNaming(NamingStrategy.underline_to_camel);
|
||||
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
|
||||
// strategy.setSuperEntityClass("com.baomidou.ant.common.BaseEntity");
|
||||
strategy.setEntityLombokModel(true);
|
||||
// 是否生成Controller
|
||||
strategy.setRestControllerStyle(true);
|
||||
// 公共父类
|
||||
// strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");
|
||||
// 写于父类中的公共字段
|
||||
// strategy.setSuperEntityColumns("id");
|
||||
strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
|
||||
// strategy.setInclude(new String[]{"t_user","t_role","t_permission"});
|
||||
strategy.setControllerMappingHyphenStyle(true);
|
||||
strategy.setTablePrefix(pc.getModuleName() + "_");
|
||||
mpg.setStrategy(strategy);
|
||||
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
|
||||
mpg.execute();
|
||||
}
|
||||
}
|
13
src/main/java/io/qyi/e5/E5Application.java
Normal file
13
src/main/java/io/qyi/e5/E5Application.java
Normal file
@ -0,0 +1,13 @@
|
||||
package io.qyi.e5;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class E5Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(E5Application.class, args);
|
||||
}
|
||||
|
||||
}
|
20
src/main/java/io/qyi/e5/bean/AppQuartz.java
Normal file
20
src/main/java/io/qyi/e5/bean/AppQuartz.java
Normal file
@ -0,0 +1,20 @@
|
||||
package io.qyi.e5.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-03-03 16:20
|
||||
**/
|
||||
@Data
|
||||
public class AppQuartz {
|
||||
private Integer quartzId; //id 主键
|
||||
private String jobName; //任务名称
|
||||
private String jobGroup; //任务分组
|
||||
private String startTime; //任务开始时间
|
||||
private String cronExpression; //corn表达式
|
||||
private String invokeParam;//需要传递的参数
|
||||
|
||||
}
|
84
src/main/java/io/qyi/e5/bean/core/WebExceptionAspect.java
Normal file
84
src/main/java/io/qyi/e5/bean/core/WebExceptionAspect.java
Normal file
@ -0,0 +1,84 @@
|
||||
package io.qyi.e5.bean.core;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.qyi.e5.util.ResultUtil;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.AfterThrowing;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* @program: msgpush
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-16 01:11
|
||||
**/
|
||||
@Aspect
|
||||
@Component
|
||||
public class WebExceptionAspect {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Pointcut("execution(* io.qyi.e5..*.*(..))")
|
||||
private void bountyHunterPointcut() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截web层异常,记录异常日志,并返回友好信息到前端
|
||||
*
|
||||
* @param e
|
||||
* 异常对象
|
||||
*/
|
||||
@AfterThrowing(pointcut = "bountyHunterPointcut()", throwing = "e")
|
||||
public void handleThrowing(JoinPoint joinPoint, Exception e) {
|
||||
//e.printStackTrace();
|
||||
/*if (null != user){
|
||||
log.error("发现异常!操作用户手机号:"+user.getMobile());
|
||||
}*/
|
||||
logger.error("发现异常!方法:"+ joinPoint.getSignature().getName()+"--->异常",e);
|
||||
//这里输入友好性信息
|
||||
if (!StringUtils.isEmpty(e.getMessage())){
|
||||
logger.error("异常",e.getMessage());
|
||||
writeContent(500,e.getMessage());
|
||||
}else {
|
||||
writeContent(500,"十分抱歉,出现异常!程序猿小哥正在紧急抢修...");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将内容输出到浏览器
|
||||
*
|
||||
* @param content
|
||||
* 输出内容
|
||||
*/
|
||||
public static void writeContent(Integer code,String content) {
|
||||
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
|
||||
.getResponse();
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setHeader("Content-Type", "text/json;charset=UTF-8");
|
||||
response.setHeader("icop-content-type", "exception");
|
||||
PrintWriter writer = null;
|
||||
JsonGenerator jsonGenerator = null;
|
||||
try {
|
||||
writer = response.getWriter();
|
||||
jsonGenerator = (new ObjectMapper()).getFactory().createGenerator(writer);
|
||||
jsonGenerator.writeObject(ResultUtil.error(code,content));
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}finally {
|
||||
writer.flush();
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
21
src/main/java/io/qyi/e5/bean/result/Result.java
Normal file
21
src/main/java/io/qyi/e5/bean/result/Result.java
Normal file
@ -0,0 +1,21 @@
|
||||
package io.qyi.e5.bean.result;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @program: msgpush
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2019-12-26 15:21
|
||||
**/
|
||||
@Data
|
||||
public class Result<T> {
|
||||
/** 错误码. */
|
||||
private Integer code;
|
||||
|
||||
/** 提示信息. */
|
||||
private String msg;
|
||||
|
||||
/** 具体的内容. */
|
||||
private T data;
|
||||
}
|
45
src/main/java/io/qyi/e5/bean/result/ResultEnum.java
Normal file
45
src/main/java/io/qyi/e5/bean/result/ResultEnum.java
Normal file
@ -0,0 +1,45 @@
|
||||
package io.qyi.e5.bean.result;
|
||||
|
||||
/**
|
||||
* @program: msgpush
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-06 00:24
|
||||
**/
|
||||
public enum ResultEnum {
|
||||
SUCCESS(0, "ok"),
|
||||
UNKNOWN_ERROR(-1, "unknown error"),
|
||||
INVALID_TOKEN(-10000,"Invalid token"),
|
||||
TOKEN_IS_NOT_FOUND(-10001,"This token was not found"),
|
||||
INVALID_TYPE(-10002,"Invalid type"),
|
||||
INVALID_FROM(-10003,"Invalid from"),
|
||||
TITLE_OR_MSG_IS_NULL(-10004,"title or msg is null"),
|
||||
INVALID_TOKEN_(-10005,"Invalid token"),
|
||||
NO_ROBOT_FOUND(-10006,"No QQ robot corresponding to this token was found"),
|
||||
NO_ROBOT_FOUND_(-10007,"No QQ robot corresponding to this token was found"),
|
||||
STATE_HAS_EXPIRED(-10008,"state has expired, please re-authorize."),
|
||||
INVALID_EMAIL(-10009,"Invalid Email!");
|
||||
private Integer code;
|
||||
private String msg;
|
||||
|
||||
ResultEnum(Integer code, String msg) {
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
26
src/main/java/io/qyi/e5/config/MybatisPlusConfig.java
Normal file
26
src/main/java/io/qyi/e5/config/MybatisPlusConfig.java
Normal file
@ -0,0 +1,26 @@
|
||||
package io.qyi.e5.config;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @program: demo
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2019-10-22 04:06
|
||||
**/
|
||||
@Configuration
|
||||
@MapperScan(basePackages = {"io.qyi.e5.*.mapper"})
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
|
||||
/**
|
||||
* 分页插件
|
||||
*/
|
||||
@Bean
|
||||
public PaginationInterceptor paginationInterceptor() {
|
||||
return new PaginationInterceptor();
|
||||
}
|
||||
}
|
28
src/main/java/io/qyi/e5/config/quartz/JobFactory.java
Normal file
28
src/main/java/io/qyi/e5/config/quartz/JobFactory.java
Normal file
@ -0,0 +1,28 @@
|
||||
package io.qyi.e5.config.quartz;
|
||||
|
||||
import org.quartz.spi.TriggerFiredBundle;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.scheduling.quartz.AdaptableJobFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-03-03 16:14
|
||||
**/
|
||||
@Component
|
||||
public class JobFactory extends AdaptableJobFactory {
|
||||
@Autowired
|
||||
private AutowireCapableBeanFactory capableBeanFactory;
|
||||
|
||||
@Override
|
||||
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
|
||||
//调用父类的方法
|
||||
Object jobInstance = super.createJobInstance(bundle);
|
||||
//进行注入
|
||||
capableBeanFactory.autowireBean(jobInstance);
|
||||
return jobInstance;
|
||||
}
|
||||
}
|
63
src/main/java/io/qyi/e5/config/quartz/SchedulerConfig.java
Normal file
63
src/main/java/io/qyi/e5/config/quartz/SchedulerConfig.java
Normal file
@ -0,0 +1,63 @@
|
||||
package io.qyi.e5.config.quartz;
|
||||
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.ee.servlet.QuartzInitializerListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.PropertiesFactoryBean;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-03-03 16:16
|
||||
**/
|
||||
public class SchedulerConfig implements ApplicationListener<ContextRefreshedEvent> {
|
||||
|
||||
@Autowired
|
||||
private JobFactory jobFactory;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
|
||||
System.out.println("任务已经启动..." + contextRefreshedEvent.getSource());
|
||||
}
|
||||
@Bean
|
||||
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
|
||||
//获取配置属性
|
||||
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
|
||||
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
|
||||
//在quartz.properties中的属性被读取并注入后再初始化对象
|
||||
propertiesFactoryBean.afterPropertiesSet();
|
||||
//创建SchedulerFactoryBean
|
||||
SchedulerFactoryBean factory = new SchedulerFactoryBean();
|
||||
factory.setQuartzProperties(propertiesFactoryBean.getObject());
|
||||
//使用数据源,自定义数据源
|
||||
// factory.setDataSource(this.primaryDataSource);
|
||||
factory.setJobFactory(jobFactory);
|
||||
factory.setWaitForJobsToCompleteOnShutdown(true);//这样当spring关闭时,会等待所有已经启动的quartz job结束后spring才能完全shutdown。
|
||||
factory.setOverwriteExistingJobs(false);
|
||||
factory.setStartupDelay(1);
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 通过SchedulerFactoryBean获取Scheduler的实例
|
||||
*/
|
||||
@Bean(name="scheduler")
|
||||
public Scheduler scheduler() throws IOException {
|
||||
return schedulerFactoryBean().getScheduler();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public QuartzInitializerListener executorListener() {
|
||||
return new QuartzInitializerListener();
|
||||
}
|
||||
}
|
120
src/main/java/io/qyi/e5/config/redis/RedisConfig.java
Normal file
120
src/main/java/io/qyi/e5/config/redis/RedisConfig.java
Normal file
@ -0,0 +1,120 @@
|
||||
package io.qyi.e5.config.redis;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author JiaweiWu
|
||||
* @description: redis配置
|
||||
*/
|
||||
@Configuration
|
||||
//@AutoConfigureAfter(RedisAutoConfiguration.class)
|
||||
//@EnableCaching
|
||||
public class RedisConfig extends CachingConfigurerSupport {
|
||||
|
||||
/**
|
||||
* 自定义生成key的规则
|
||||
*/
|
||||
/* @Override
|
||||
public KeyGenerator keyGenerator() {
|
||||
return new KeyGenerator() {
|
||||
@Override
|
||||
public Object generate(Object o, Method method, Object... objects) {
|
||||
//格式化缓存key字符串
|
||||
StringBuilder sb = new StringBuilder();
|
||||
//追加类名
|
||||
sb.append(o.getClass().getName());
|
||||
//追加方法名
|
||||
sb.append(method.getName());
|
||||
//遍历参数并且追加
|
||||
for (Object obj : objects) {
|
||||
sb.append(obj.toString());
|
||||
}
|
||||
System.out.println("调用Redis缓存Key : " + sb.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* 采用RedisCacheManager作为缓存管理器
|
||||
*
|
||||
* @param connectionFactory
|
||||
*/
|
||||
@Bean
|
||||
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
|
||||
RedisCacheManager redisCacheManager = RedisCacheManager.create(connectionFactory);
|
||||
//设置缓存过期时间
|
||||
//rcm.setDefaultExpiration(60);//秒
|
||||
return redisCacheManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置自定义redisTemplate
|
||||
* @return
|
||||
*/
|
||||
/*@Bean
|
||||
RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||
|
||||
RedisTemplate<String, Object> template = new RedisTemplate<>();
|
||||
template.setConnectionFactory(redisConnectionFactory);
|
||||
|
||||
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
|
||||
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
serializer.setObjectMapper(mapper);
|
||||
|
||||
template.setValueSerializer(serializer);
|
||||
//使用StringRedisSerializer来序列化和反序列化redis的key值
|
||||
template.setKeySerializer(new StringRedisSerializer());
|
||||
template.setHashKeySerializer(new StringRedisSerializer());
|
||||
template.setHashValueSerializer(serializer);
|
||||
template.afterPropertiesSet();
|
||||
return template;
|
||||
}*/
|
||||
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("all")
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
|
||||
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
|
||||
template.setConnectionFactory(factory);
|
||||
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
jackson2JsonRedisSerializer.setObjectMapper(om);
|
||||
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
|
||||
// key采用String的序列化方式
|
||||
template.setKeySerializer(stringRedisSerializer);
|
||||
// hash的key也采用String的序列化方式
|
||||
template.setHashKeySerializer(stringRedisSerializer);
|
||||
// value序列化方式采用jackson
|
||||
template.setValueSerializer(jackson2JsonRedisSerializer);
|
||||
// hash的value序列化方式采用jackson
|
||||
template.setHashValueSerializer(jackson2JsonRedisSerializer);
|
||||
template.afterPropertiesSet();
|
||||
return template;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package io.qyi.e5.config.security;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* @program: msgpush
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2019-12-27 08:57
|
||||
**/
|
||||
@Component
|
||||
public class SecurityAuthenticationHandler implements AuthenticationSuccessHandler, AuthenticationFailureHandler , LogoutSuccessHandler {
|
||||
@Override
|
||||
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
|
||||
httpServletResponse.setStatus(302);
|
||||
httpServletResponse.setHeader("Location", "/user/home");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
|
||||
httpServletResponse.setContentType("application/json;charset=utf-8");
|
||||
PrintWriter writer = httpServletResponse.getWriter();
|
||||
writer.write("Failure");
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
|
||||
httpServletResponse.setContentType("application/json;charset=utf-8");
|
||||
PrintWriter writer = httpServletResponse.getWriter();
|
||||
writer.write("logout success");
|
||||
writer.flush();
|
||||
}
|
||||
}
|
94
src/main/java/io/qyi/e5/config/security/SecurityConfig.java
Normal file
94
src/main/java/io/qyi/e5/config/security/SecurityConfig.java
Normal file
@ -0,0 +1,94 @@
|
||||
package io.qyi.e5.config.security;
|
||||
|
||||
import io.qyi.e5.service.security.SecurityUserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
/**
|
||||
* @program: msgpush
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2019-12-26 14:15
|
||||
**/
|
||||
@Configuration
|
||||
@EnableWebSecurity //开启wen安全功能
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
SecurityAuthenticationHandler securityAuthenticationHandler;
|
||||
|
||||
@Autowired
|
||||
private SecurityUserService securityUserService;
|
||||
|
||||
@Autowired
|
||||
UsernamePasswordAuthenticationConfig usernamePasswordAuthenticationConfig;
|
||||
|
||||
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
System.out.println("AuthenticationManagerBuilder auth");
|
||||
// auth.userDetailsService(securityUserService).passwordEncoder(new BCryptPasswordEncoder());
|
||||
// auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
|
||||
// .withUser("user").password(new BCryptPasswordEncoder().encode("123")).roles("user").and()
|
||||
// .withUser("admin").password(new BCryptPasswordEncoder().encode("admin")).roles("USER", "ADMIN");
|
||||
}
|
||||
|
||||
// 通过重载该方法,可配置如何通过拦截器保护请求。
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
System.out.println("HttpSecurity http");
|
||||
/*http.authorizeRequests().antMatchers("/").permitAll();
|
||||
http.authorizeRequests().anyRequest().authenticated();
|
||||
http.logout().permitAll();
|
||||
http.formLogin()
|
||||
.loginPage("/login")
|
||||
.loginProcessingUrl("/login1")
|
||||
.successHandler(securityAuthenticationHandler)
|
||||
.failureHandler(securityAuthenticationHandler)
|
||||
// .loginProcessingUrl("api/getInfo")
|
||||
.permitAll()
|
||||
.and()
|
||||
.logout()
|
||||
.logoutUrl("logout")
|
||||
.logoutSuccessHandler( securityAuthenticationHandler);*/
|
||||
http.csrf().disable()
|
||||
.apply(usernamePasswordAuthenticationConfig);
|
||||
|
||||
http.formLogin()
|
||||
.loginPage("/user/login")// 登陆页面
|
||||
.loginProcessingUrl("/user/loginFrom")// 登陆表单提交请求
|
||||
.and()
|
||||
.authorizeRequests().antMatchers("/user/login", "/user/loginFrom", "/auth2/getGithubUrl").permitAll()// 指定相应的请求 不需要验证
|
||||
.and()
|
||||
.authorizeRequests().antMatchers("/quartz/**").permitAll()//测试
|
||||
.anyRequest()// 任何请求
|
||||
.authenticated();// 都需要身份认证
|
||||
|
||||
// http.exceptionHandling().accessDeniedHandler();
|
||||
// http.formLogin().loginProcessingUrl("api/getInfo");
|
||||
|
||||
// http.formLogin().usernameParameter("username");
|
||||
// http.formLogin().passwordParameter("password");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*@Bean
|
||||
public AccessDeniedHandler getAccessDeniedHandler() {
|
||||
return new RestAuthenticationAccessDeniedHandler();
|
||||
}*/
|
||||
|
||||
/* @Override
|
||||
public void configure(WebSecurity web) {
|
||||
System.out.println("WebSecurity web");
|
||||
String antPatterns = "/pdfjs-2.1.266/**,/favicon.ico,/css/**,/js/**,/ico/**,/images/**,/jquery-1.12.4/**,/uuid-1.4/**,/layui-2.4.5/**,/jquery-easyui-1.6.11/**,/zTree-3.5.33/**,/select2-4.0.5/**,/greensock-js-1.20.5/**";
|
||||
web.ignoring().antMatchers(antPatterns.split(","));
|
||||
}*/
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package io.qyi.e5.config.security;
|
||||
|
||||
import io.qyi.e5.config.security.filter.LoginAuthenticationFilter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.web.DefaultSecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-28 16:24
|
||||
**/
|
||||
@Component
|
||||
public class UsernamePasswordAuthenticationConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
@Autowired
|
||||
UsernamePasswordAuthenticationProvider usernamePasswordAuthenticationProvider;
|
||||
@Autowired
|
||||
SecurityAuthenticationHandler securityAuthenticationHandler;
|
||||
|
||||
@Override
|
||||
public void configure(HttpSecurity http) throws Exception {
|
||||
LoginAuthenticationFilter authenticationFilter = new LoginAuthenticationFilter();
|
||||
|
||||
logger.info("自定义用户认证处理逻辑");
|
||||
// 自定义用户认证处理逻辑时,需要指定AuthenticationManager,否则无法认证
|
||||
authenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
|
||||
|
||||
// 指定自定义的认证成功和失败的处理器
|
||||
authenticationFilter.setAuthenticationSuccessHandler(securityAuthenticationHandler);
|
||||
authenticationFilter.setAuthenticationFailureHandler(securityAuthenticationHandler);
|
||||
|
||||
// 把自定义的用户名密码认证过滤器和处理器添加到UsernamePasswordAuthenticationFilter过滤器之前
|
||||
http.authenticationProvider(usernamePasswordAuthenticationProvider)
|
||||
.addFilterBefore(authenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
package io.qyi.e5.config.security;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import io.qyi.e5.bean.result.ResultEnum;
|
||||
import io.qyi.e5.github.entity.Github;
|
||||
import io.qyi.e5.github.entity.UserInfo;
|
||||
import io.qyi.e5.github.mapper.GithubMapper;
|
||||
import io.qyi.e5.service.github.GithubService;
|
||||
import io.qyi.e5.util.ResultUtil;
|
||||
import io.qyi.e5.util.redis.RedisUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-28 15:48
|
||||
**/
|
||||
//自定义的用户名密码认证实现类
|
||||
@Component
|
||||
public class UsernamePasswordAuthenticationProvider implements AuthenticationProvider {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
@Value("${redis.auth2.github}")
|
||||
String states;
|
||||
|
||||
@Value("${isdebug}")
|
||||
boolean isDebug;
|
||||
|
||||
@Autowired
|
||||
RedisUtil redisUtil;
|
||||
|
||||
@Autowired
|
||||
GithubMapper githubMapper;
|
||||
|
||||
@Autowired
|
||||
GithubService githubService;
|
||||
|
||||
// 验证
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
// 将未认证的Authentication转换成自定义的用户认证Token
|
||||
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) authentication;
|
||||
// 根据用户Token中的用户名查找用户信息,如果有该用户信息,则验证用户密码是否正确
|
||||
String code = authenticationToken.getCode();
|
||||
String state = authenticationToken.getState();
|
||||
logger.info("Github 认证: code:{} state:{} Token:", code, state);
|
||||
if (isDebug) {
|
||||
UsernamePasswordAuthenticationToken authenticationToken1 = new UsernamePasswordAuthenticationToken("debugName",
|
||||
"DebugAvatar",19658189, AuthorityUtils.createAuthorityList("user"));
|
||||
authenticationToken1.setDetails(authenticationToken);
|
||||
return authenticationToken1;
|
||||
}
|
||||
if (!redisUtil.hasKey(states + state)) {
|
||||
throw new UsernameNotFoundException("status不存在");
|
||||
// return ResultUtil.error(ResultEnum.STATE_HAS_EXPIRED);
|
||||
}
|
||||
redisUtil.del(states + state);
|
||||
String accessToken = githubService.getAccessToken(code);
|
||||
if (accessToken == null) {
|
||||
logger.error("accessToken 为空!");
|
||||
throw new BadCredentialsException("accessToken 为空!");
|
||||
}
|
||||
UserInfo userInfo = githubService.getUserInfo(accessToken);
|
||||
if (userInfo == null) {
|
||||
logger.error("获取github用户信息失败!");
|
||||
throw new BadCredentialsException("获取github用户信息失败!");
|
||||
}
|
||||
QueryWrapper<Github> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("github_id", userInfo.getGithub_id());
|
||||
Github github = githubMapper.selectOne(queryWrapper);
|
||||
// 未注册就进行注册
|
||||
if (github == null) {
|
||||
github = new Github();
|
||||
github.setAccessToken(accessToken)
|
||||
.setAvatarUrl(userInfo.getAvatar_url())
|
||||
.setGithubId(userInfo.getGithub_id())
|
||||
.setName(userInfo.getName())
|
||||
.setLogin(userInfo.getLogin());
|
||||
githubMapper.insert(github);
|
||||
} else {
|
||||
// 已注册就进行更新 AccessToken
|
||||
github.setAccessToken(accessToken);
|
||||
githubMapper.update(github, queryWrapper);
|
||||
}
|
||||
|
||||
|
||||
// 创建一个已认证的token
|
||||
UsernamePasswordAuthenticationToken authenticationToken1 = new UsernamePasswordAuthenticationToken(github.getName(),
|
||||
github.getAvatarUrl(),github.getGithubId(), AuthorityUtils.createAuthorityList("user"));
|
||||
|
||||
// 设置一些详细信息
|
||||
authenticationToken1.setDetails(authenticationToken);
|
||||
|
||||
return authenticationToken1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> authentication) {
|
||||
// 指定该认证处理器能对 UsernamePasswordAuthenticationToken 对象进行认证
|
||||
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package io.qyi.e5.config.security;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-28 15:23
|
||||
* setAuthenticated():判断是否已认证 生成登录session,同用户不用再校验
|
||||
**/
|
||||
public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
/**
|
||||
* token
|
||||
*/
|
||||
private String code;
|
||||
|
||||
private String state;
|
||||
|
||||
private String name;
|
||||
|
||||
private String avatar_url;
|
||||
private int github_id;
|
||||
|
||||
|
||||
// 创建未认证的用户名密码认证对象
|
||||
public UsernamePasswordAuthenticationToken(String code) {
|
||||
super(null);
|
||||
this.code = code;
|
||||
super.setAuthenticated(false);
|
||||
logger.info("MobileLoginAuthenticationToken setAuthenticated ->false loading ...");
|
||||
}
|
||||
|
||||
// 创建未认证的用户名密码认证对象
|
||||
public UsernamePasswordAuthenticationToken(String code, String state) {
|
||||
super(null);
|
||||
this.code = code;
|
||||
this.state = state;
|
||||
super.setAuthenticated(false);
|
||||
logger.info("MobileLoginAuthenticationToken setAuthenticated ->false loading ...");
|
||||
}
|
||||
|
||||
|
||||
// 创建已认证的用户密码认证对象
|
||||
public UsernamePasswordAuthenticationToken( String name, String avatar_url, int github_id,Collection<? extends GrantedAuthority> authorities) {
|
||||
super(authorities);
|
||||
this.name = name;
|
||||
this.avatar_url = avatar_url;
|
||||
this.github_id = github_id;
|
||||
super.setAuthenticated(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCredentials() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrincipal() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAvatar_url() {
|
||||
return avatar_url;
|
||||
}
|
||||
|
||||
public void setAvatar_url(String avatar_url) {
|
||||
this.avatar_url = avatar_url;
|
||||
}
|
||||
|
||||
public int getGithub_id() {
|
||||
return github_id;
|
||||
}
|
||||
|
||||
public void setGithub_id(int github_id) {
|
||||
this.github_id = github_id;
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package io.qyi.e5.config.security.filter;
|
||||
|
||||
import io.qyi.e5.config.security.UsernamePasswordAuthenticationToken;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.authentication.InternalAuthenticationServiceException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-28 11:56
|
||||
**/
|
||||
public class LoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
|
||||
protected LoginAuthenticationFilter(String defaultFilterProcessesUrl) {
|
||||
super(defaultFilterProcessesUrl);
|
||||
}
|
||||
|
||||
protected LoginAuthenticationFilter(RequestMatcher requiresAuthenticationRequestMatcher) {
|
||||
super(requiresAuthenticationRequestMatcher);
|
||||
}
|
||||
|
||||
public LoginAuthenticationFilter() {
|
||||
super(new AntPathRequestMatcher("/auth2/receive", "GET"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
|
||||
/*if (!httpServletRequest.getMethod().equals(HttpMethod.POST.name())) {
|
||||
throw new AuthenticationServiceException("不支持该验证方法: " + httpServletRequest.getMethod());
|
||||
} else {
|
||||
|
||||
}*/
|
||||
/**
|
||||
* 从http请求中获取用户输入的用户名和密码信息
|
||||
* 这里接收的是form形式的参数,如果要接收json形式的参数,修改这里即可
|
||||
*/
|
||||
String code = httpServletRequest.getParameter("code");
|
||||
String state = httpServletRequest.getParameter("state");
|
||||
if (StringUtils.isEmpty(code) || StringUtils.isEmpty(state)) {
|
||||
throw new UsernameNotFoundException("CustomUsernamePasswordAuthenticationFilter获取用户认证信息失败");
|
||||
}
|
||||
/**
|
||||
* 使用用户输入的用户名和密码信息创建一个未认证的用户认证Token
|
||||
*/
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(code, state);
|
||||
// 设置身份认证的详情信息
|
||||
this.setDetails(httpServletRequest, authRequest);
|
||||
|
||||
// 通过AuthenticationManager调用相应的AuthenticationProvider进行用户认证
|
||||
return this.getAuthenticationManager().authenticate(authRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置身份认证的详情信息
|
||||
*/
|
||||
private void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
|
||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
|
||||
}
|
||||
}
|
94
src/main/java/io/qyi/e5/controller/auth2/Auth.java
Normal file
94
src/main/java/io/qyi/e5/controller/auth2/Auth.java
Normal file
@ -0,0 +1,94 @@
|
||||
package io.qyi.e5.controller.auth2;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import io.qyi.e5.bean.result.Result;
|
||||
import io.qyi.e5.bean.result.ResultEnum;
|
||||
import io.qyi.e5.github.entity.Github;
|
||||
import io.qyi.e5.github.entity.UserInfo;
|
||||
import io.qyi.e5.github.mapper.GithubMapper;
|
||||
import io.qyi.e5.service.github.GithubService;
|
||||
import io.qyi.e5.user.mapper.UserMapper;
|
||||
import io.qyi.e5.util.EncryptUtil;
|
||||
import io.qyi.e5.util.ResultUtil;
|
||||
import io.qyi.e5.util.redis.RedisUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @program: msgpush
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-19 00:23
|
||||
**/
|
||||
@RequestMapping("/auth2")
|
||||
@RestController
|
||||
public class Auth {
|
||||
@Autowired
|
||||
RedisUtil redisUtil;
|
||||
|
||||
@Autowired
|
||||
GithubService githubService;
|
||||
|
||||
@Autowired
|
||||
UserMapper userMapper;
|
||||
|
||||
@Autowired
|
||||
GithubMapper githubMapper;
|
||||
|
||||
@Value("${redis.auth2.github}")
|
||||
String states;
|
||||
|
||||
@Value("${github.client_id}")
|
||||
String client_id;
|
||||
|
||||
|
||||
@RequestMapping("/getGithubUrl")
|
||||
public void getGithubUrl(HttpServletResponse response) {
|
||||
String state = EncryptUtil.getInstance().SHA1Hex(UUID.randomUUID().toString());
|
||||
redisUtil.set(states + state, true, 600);
|
||||
response.setStatus(302);
|
||||
response.setHeader("Location", "https://github.com/login/oauth/authorize?client_id=" + client_id + "&redirect_uri=https://e5.qyi.io/auth2/receive&state=" + state);
|
||||
}
|
||||
|
||||
/* @RequestMapping("/receive")
|
||||
public Result Receive(String code, String state, HttpServletResponse response) throws Exception {
|
||||
System.out.println(code);
|
||||
System.out.println(state);
|
||||
if (!redisUtil.hasKey(states + state)) {
|
||||
return ResultUtil.error(ResultEnum.STATE_HAS_EXPIRED);
|
||||
}
|
||||
redisUtil.del(states + state);
|
||||
String accessToken = githubService.getAccessToken(code);
|
||||
if (accessToken != null) {
|
||||
UserInfo userInfo = githubService.getUserInfo(accessToken);
|
||||
if (userInfo != null) {
|
||||
QueryWrapper<Github> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("github_id", userInfo.getGithub_id());
|
||||
Github github = githubMapper.selectOne(queryWrapper);
|
||||
// 未注册就进行注册
|
||||
if (github == null) {
|
||||
github = new Github();
|
||||
github.setAccessToken(accessToken)
|
||||
.setAvatarUrl(userInfo.getAvatar_url())
|
||||
.setGithubId(userInfo.getGithub_id())
|
||||
.setName(userInfo.getName())
|
||||
.setLogin(userInfo.getLogin());
|
||||
githubMapper.insert(github);
|
||||
} else {
|
||||
// 已注册就进行更新 AccessToken
|
||||
github.setAccessToken(accessToken);
|
||||
githubMapper.update(github, queryWrapper);
|
||||
}
|
||||
return ResultUtil.success();
|
||||
}
|
||||
}
|
||||
return ResultUtil.error(ResultEnum.INVALID_EMAIL);
|
||||
}*/
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package io.qyi.e5.controller.quartz;
|
||||
|
||||
import io.qyi.e5.bean.AppQuartz;
|
||||
import io.qyi.e5.service.quartz.JobUtil;
|
||||
import io.qyi.e5.service.quartz.MyQuartzJobService;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.TriggerKey;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-03-03 14:59
|
||||
**/
|
||||
@Controller
|
||||
@RequestMapping("/quartz")
|
||||
public class QuartzController {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Value("${qz_cron}")
|
||||
private String qz_cron;
|
||||
|
||||
@Autowired
|
||||
private JobUtil jobUtil;
|
||||
|
||||
@GetMapping("/add")
|
||||
public void add() throws Exception {
|
||||
logger.info("添加定时任务");
|
||||
JobDataMap jobDataMap = new JobDataMap();
|
||||
jobDataMap.put("aaa", "test");
|
||||
JobKey jobKey = new JobKey("crom任务", "我的cron任务组名1");
|
||||
TriggerKey triggerKey1 = new TriggerKey("我的cron触发器名1", "我的cron触发器组名1");
|
||||
|
||||
AppQuartz appQuartz = new AppQuartz();
|
||||
appQuartz.setJobGroup("t1");
|
||||
appQuartz.setJobName("t1");
|
||||
appQuartz.setQuartzId(1);
|
||||
appQuartz.setCronExpression(qz_cron);
|
||||
appQuartz.setStartTime("2020-03-03 16:03:11");
|
||||
jobUtil.addJob(appQuartz,MyQuartzJobService.class);
|
||||
|
||||
// quartzManager.addJob(jobKey,triggerKey1, MyQuartzJobService.class, "0/20 * * * * ?", jobDataMap);
|
||||
|
||||
}
|
||||
}
|
60
src/main/java/io/qyi/e5/controller/web/WebController.java
Normal file
60
src/main/java/io/qyi/e5/controller/web/WebController.java
Normal file
@ -0,0 +1,60 @@
|
||||
package io.qyi.e5.controller.web;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import io.qyi.e5.config.security.UsernamePasswordAuthenticationToken;
|
||||
import io.qyi.e5.outlook.entity.Outlook;
|
||||
import io.qyi.e5.outlook.service.IOutlookService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-27 16:03
|
||||
**/
|
||||
@Controller
|
||||
public class WebController {
|
||||
|
||||
@Autowired
|
||||
IOutlookService outlookService;
|
||||
|
||||
@RequestMapping("/")
|
||||
public void index(HttpServletResponse httpServletResponse) {
|
||||
httpServletResponse.setStatus(302);
|
||||
httpServletResponse.setHeader("Location", "/user/home");
|
||||
}
|
||||
|
||||
@RequestMapping("/user/login")
|
||||
public String login(Model model) {
|
||||
model.addAttribute("welcome", "hello fishpro");
|
||||
return "user/login";
|
||||
}
|
||||
|
||||
@RequestMapping("/user/home")
|
||||
public String home(Model model) {
|
||||
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
int github_id = authentication.getGithub_id();
|
||||
QueryWrapper<Outlook> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("github_id", github_id);
|
||||
Outlook one = outlookService.getOne(queryWrapper);
|
||||
if (one != null) {
|
||||
model.addAttribute("client_id", one.getClientId());
|
||||
model.addAttribute("client_secret", one.getClientSecret());
|
||||
} else {
|
||||
model.addAttribute("client_id", "");
|
||||
model.addAttribute("client_secret", "");
|
||||
}
|
||||
|
||||
model.addAttribute("welcome", "hello fishpro");
|
||||
return "user/home";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package io.qyi.e5.github.controller;
|
||||
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/github/github")
|
||||
public class GithubController {
|
||||
|
||||
}
|
56
src/main/java/io/qyi/e5/github/entity/Github.java
Normal file
56
src/main/java/io/qyi/e5/github/entity/Github.java
Normal file
@ -0,0 +1,56 @@
|
||||
package io.qyi.e5.github.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class Github implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private Integer userId;
|
||||
|
||||
private String accessToken;
|
||||
|
||||
/**
|
||||
* 登录名
|
||||
*/
|
||||
private String login;
|
||||
|
||||
/**
|
||||
* github的用户名
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 头像url
|
||||
*/
|
||||
private String avatarUrl;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Integer githubId;
|
||||
|
||||
|
||||
}
|
19
src/main/java/io/qyi/e5/github/entity/UserInfo.java
Normal file
19
src/main/java/io/qyi/e5/github/entity/UserInfo.java
Normal file
@ -0,0 +1,19 @@
|
||||
package io.qyi.e5.github.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-24 15:20
|
||||
**/
|
||||
@Data
|
||||
public class UserInfo {
|
||||
String login;
|
||||
String name;
|
||||
int github_id;
|
||||
String node_id;
|
||||
String avatar_url;
|
||||
|
||||
}
|
16
src/main/java/io/qyi/e5/github/mapper/GithubMapper.java
Normal file
16
src/main/java/io/qyi/e5/github/mapper/GithubMapper.java
Normal file
@ -0,0 +1,16 @@
|
||||
package io.qyi.e5.github.mapper;
|
||||
|
||||
import io.qyi.e5.github.entity.Github;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
public interface GithubMapper extends BaseMapper<Github> {
|
||||
|
||||
}
|
16
src/main/java/io/qyi/e5/github/service/IGithubService.java
Normal file
16
src/main/java/io/qyi/e5/github/service/IGithubService.java
Normal file
@ -0,0 +1,16 @@
|
||||
package io.qyi.e5.github.service;
|
||||
|
||||
import io.qyi.e5.github.entity.Github;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
public interface IGithubService extends IService<Github> {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package io.qyi.e5.github.service.impl;
|
||||
|
||||
import io.qyi.e5.github.entity.Github;
|
||||
import io.qyi.e5.github.mapper.GithubMapper;
|
||||
import io.qyi.e5.github.service.IGithubService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@Service
|
||||
public class GithubServiceImpl extends ServiceImpl<GithubMapper, Github> implements IGithubService {
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package io.qyi.e5.outlook.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import io.qyi.e5.config.security.UsernamePasswordAuthenticationToken;
|
||||
import io.qyi.e5.outlook.entity.Outlook;
|
||||
import io.qyi.e5.outlook.mapper.OutlookMapper;
|
||||
import io.qyi.e5.outlook.service.IOutlookService;
|
||||
import io.qyi.e5.util.EncryptUtil;
|
||||
import io.qyi.e5.util.redis.RedisUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-24 16:02
|
||||
**/
|
||||
@Controller
|
||||
@RequestMapping("/outlook/auth2")
|
||||
public class AuthController {
|
||||
@Autowired
|
||||
RedisUtil redisUtil;
|
||||
|
||||
@Autowired
|
||||
OutlookMapper outlookMapper;
|
||||
|
||||
@Autowired
|
||||
IOutlookService outlookService;
|
||||
|
||||
@Value("${redis.auth2.outlook}")
|
||||
String states;
|
||||
|
||||
@Value("${outlook.authorize.url}")
|
||||
String authorizeUrl;
|
||||
|
||||
@RequestMapping("/receive")
|
||||
public String Receive(Model model, String code, String state, String session_state, HttpServletResponse response) throws Exception {
|
||||
model.addAttribute("result", false);
|
||||
if (!redisUtil.hasKey(states + state)) {
|
||||
model.addAttribute("msg", "state已过期,重新点击授权!");
|
||||
return "/user/authorization_outlook";
|
||||
}
|
||||
// 这里不应该查询,在进行授权时因该把基础数据丢到redis
|
||||
QueryWrapper<Outlook> outlookQueryWrapper = new QueryWrapper<>();
|
||||
outlookQueryWrapper.eq("github_id", redisUtil.get(states + state));
|
||||
Outlook outlook = outlookMapper.selectOne(outlookQueryWrapper);
|
||||
// 删除redis中的此键
|
||||
redisUtil.del(states + state);
|
||||
if (outlook == null) {
|
||||
model.addAttribute("msg", "没有查询到此用户,请检查是否在系统中注册!");
|
||||
return "/user/authorization_outlook";
|
||||
}
|
||||
System.out.println(outlook);
|
||||
boolean authorization_code = outlookService.getTokenAndSave(code, outlook.getClientId(), outlook.getClientSecret(), "https://e5.qyi.io/outlook/auth2/receive"
|
||||
, "authorization_code");
|
||||
if (authorization_code) {
|
||||
model.addAttribute("result", true);
|
||||
} else {
|
||||
model.addAttribute("msg", "未知错误,请联系管理员~");
|
||||
}
|
||||
return "/user/authorization_outlook";
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping("/getAuthorizeUrl")
|
||||
public void getAuthorizeUrl(HttpServletResponse response) {
|
||||
// 查询此用户的github_id与
|
||||
QueryWrapper<Outlook> outlookQueryWrapper = new QueryWrapper<>();
|
||||
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
outlookQueryWrapper.eq("github_id", authentication.getGithub_id());
|
||||
Outlook outlook = outlookMapper.selectOne(outlookQueryWrapper);
|
||||
|
||||
if (outlook != null) {
|
||||
// 生成随机uuid标识用户
|
||||
String state = EncryptUtil.getInstance().SHA1Hex(UUID.randomUUID().toString());
|
||||
redisUtil.set(states + state, outlook.getGithubId(), 600);
|
||||
|
||||
System.out.println(outlook);
|
||||
String url = String.format(authorizeUrl, outlook.getClientId(), "https://e5.qyi.io/outlook/auth2/receive", state);
|
||||
System.out.println(url);
|
||||
response.setStatus(302);
|
||||
response.setHeader("Location", url);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package io.qyi.e5.outlook.controller;
|
||||
|
||||
|
||||
import io.qyi.e5.bean.result.Result;
|
||||
import io.qyi.e5.bean.result.ResultEnum;
|
||||
import io.qyi.e5.config.security.UsernamePasswordAuthenticationToken;
|
||||
import io.qyi.e5.outlook.service.IOutlookService;
|
||||
import io.qyi.e5.util.ResultUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/outlook/outlook")
|
||||
public class OutlookController {
|
||||
|
||||
@Autowired
|
||||
IOutlookService outlookService;
|
||||
|
||||
@PostMapping("/save")
|
||||
public Result save(@RequestParam String client_id, @RequestParam String client_secret) {
|
||||
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
if (outlookService.save(client_id, client_secret,authentication.getGithub_id())) {
|
||||
return ResultUtil.success();
|
||||
}
|
||||
return ResultUtil.error(ResultEnum.UNKNOWN_ERROR);
|
||||
}
|
||||
}
|
47
src/main/java/io/qyi/e5/outlook/entity/Outlook.java
Normal file
47
src/main/java/io/qyi/e5/outlook/entity/Outlook.java
Normal file
@ -0,0 +1,47 @@
|
||||
package io.qyi.e5.outlook.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class Outlook implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private Integer githubId;
|
||||
|
||||
private String idToken;
|
||||
|
||||
private String clientId;
|
||||
|
||||
private String clientSecret;
|
||||
|
||||
/**
|
||||
* 刷新令牌
|
||||
*/
|
||||
private String refreshToken;
|
||||
|
||||
private String accessToken;
|
||||
|
||||
|
||||
}
|
16
src/main/java/io/qyi/e5/outlook/mapper/OutlookMapper.java
Normal file
16
src/main/java/io/qyi/e5/outlook/mapper/OutlookMapper.java
Normal file
@ -0,0 +1,16 @@
|
||||
package io.qyi.e5.outlook.mapper;
|
||||
|
||||
import io.qyi.e5.outlook.entity.Outlook;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
public interface OutlookMapper extends BaseMapper<Outlook> {
|
||||
|
||||
}
|
26
src/main/java/io/qyi/e5/outlook/service/IOutlookService.java
Normal file
26
src/main/java/io/qyi/e5/outlook/service/IOutlookService.java
Normal file
@ -0,0 +1,26 @@
|
||||
package io.qyi.e5.outlook.service;
|
||||
|
||||
import io.qyi.e5.outlook.entity.Outlook;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
public interface IOutlookService extends IService<Outlook> {
|
||||
|
||||
boolean getTokenAndSave(String code,String client_id,String client_secret,String redirect_uri,String grant_type) throws Exception;
|
||||
|
||||
boolean save(String client_id,String client_secret,int github_id);
|
||||
|
||||
boolean getMailList(Outlook outlook);
|
||||
|
||||
List<Outlook> findAll();
|
||||
|
||||
}
|
@ -0,0 +1,195 @@
|
||||
package io.qyi.e5.outlook.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import io.qyi.e5.github.entity.Github;
|
||||
import io.qyi.e5.outlook.entity.Outlook;
|
||||
import io.qyi.e5.outlook.mapper.OutlookMapper;
|
||||
import io.qyi.e5.outlook.service.IOutlookService;
|
||||
import io.qyi.e5.outlook_log.service.IOutlookLogService;
|
||||
import io.qyi.e5.util.netRequest.OkHttpClientUtil;
|
||||
import io.qyi.e5.util.netRequest.OkHttpRequestUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@Service
|
||||
public class OutlookServiceImpl extends ServiceImpl<OutlookMapper, Outlook> implements IOutlookService {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
IOutlookLogService outlookLogService;
|
||||
|
||||
|
||||
// 2020-03-2 10:38 这里需要进行查询判断数据库是否有内容再进行插入。
|
||||
@Override
|
||||
public boolean getTokenAndSave(String code, String client_id, String client_secret, String redirect_uri, String grant_type) throws Exception {
|
||||
Map<String, Object> head = new HashMap<>();
|
||||
head.put("Content-Type", "application/x-www-form-urlencoded");
|
||||
Map<String, Object> par = new HashMap<>();
|
||||
par.put("client_id", client_id);
|
||||
par.put("client_secret", client_secret);
|
||||
par.put("code", code);
|
||||
par.put("redirect_uri", redirect_uri);
|
||||
par.put("grant_type", grant_type);
|
||||
String s = OkHttpClientUtil.doPost("https://login.microsoftonline.com/common/oauth2/v2.0/token", head, par);
|
||||
JSONObject jsonObject = JSON.parseObject(s);
|
||||
logger.info("请求access_token返回数据:" + s);
|
||||
if (jsonObject.get("error") != null) {
|
||||
logger.error("错授权误!");
|
||||
return false;
|
||||
} else {
|
||||
int expires_in = jsonObject.getIntValue("expires_in");
|
||||
String access_token = jsonObject.getString("access_token");
|
||||
String refresh_token = jsonObject.getString("refresh_token");
|
||||
String id_token = jsonObject.getString("id_token");
|
||||
|
||||
Outlook outlook = new Outlook();
|
||||
outlook.setAccessToken(access_token)
|
||||
.setRefreshToken(refresh_token)
|
||||
.setIdToken(id_token);
|
||||
UpdateWrapper<Outlook> outlookUpdateWrapper = new UpdateWrapper<>();
|
||||
outlookUpdateWrapper.eq("client_id", client_id);
|
||||
baseMapper.update(outlook, outlookUpdateWrapper);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save(String client_id, String client_secret, int github_id) {
|
||||
if (github_id == 0) {
|
||||
return false;
|
||||
}
|
||||
QueryWrapper<Outlook> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("github_id", github_id)
|
||||
.or().eq("client_id",client_id);
|
||||
Outlook outlook1 = baseMapper.selectOne(queryWrapper);
|
||||
// 有数据
|
||||
if (outlook1 != null) {
|
||||
outlook1.setClientId(client_id)
|
||||
.setClientSecret(client_secret);
|
||||
|
||||
int i = baseMapper.update(outlook1, queryWrapper);
|
||||
if (i == 1) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
Outlook outlook = new Outlook();
|
||||
outlook.setClientId(client_id)
|
||||
.setClientSecret(client_secret)
|
||||
.setGithubId(github_id);
|
||||
int i = baseMapper.insert(outlook);
|
||||
if (i == 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Outlook> findAll() {
|
||||
return baseMapper.selectList(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getMailList(Outlook outlook) {
|
||||
try {
|
||||
String s = MailList(outlook.getAccessToken());
|
||||
JSONObject json = JSON.parseObject(s);
|
||||
// 报错
|
||||
if (json.containsKey("error")) {
|
||||
String code = json.getJSONObject("error").getString("code");
|
||||
String message = json.getJSONObject("error").getString("message");
|
||||
if (!("Access token has expired.".equals(message) || "Access token validation failure.".equals(message))) {
|
||||
outlookLogService.addLog(outlook.getGithubId(), "无法刷新令牌!code:3", "0", json.getJSONObject("error").getString("message"));
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.info("令牌过期!");
|
||||
String token = refresh_token(outlook);
|
||||
if (token == null) {
|
||||
return false;
|
||||
}
|
||||
s = MailList(token);
|
||||
json = JSON.parseObject(s);
|
||||
if (json.containsKey("error")) {
|
||||
outlookLogService.addLog(outlook.getGithubId(), "无法刷新令牌!code:2", "0", json.getJSONObject("error").getString("message"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
outlookLogService.addLog(outlook.getGithubId(), "ok", "1", "");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String MailList(String access_token) throws Exception {
|
||||
Map<String, Object> head = new HashMap<>();
|
||||
head.put("Content-Type", "application/json");
|
||||
head.put("Authorization", access_token);
|
||||
String s = OkHttpRequestUtils.doGet("https://graph.microsoft.com/v1.0/me/messages?$select=sender,subject", head, null);
|
||||
logger.info("请求邮件列表返回数据:" + s);
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
// 刷新令牌,同时更新数据库中的令牌
|
||||
public String refresh_token(Outlook outlook) {
|
||||
Map<String, Object> head = new HashMap<>();
|
||||
head.put("Content-Type", "application/x-www-form-urlencoded");
|
||||
Map<String, Object> par = new HashMap<>();
|
||||
par.put("client_id", outlook.getClientId());
|
||||
par.put("scope", "openid offline_access Mail.Read");
|
||||
par.put("client_secret", outlook.getClientSecret());
|
||||
par.put("grant_type", "refresh_token");
|
||||
par.put("refresh_token", outlook.getRefreshToken());
|
||||
String s = null;
|
||||
try {
|
||||
s = OkHttpClientUtil.doPost("https://login.microsoftonline.com/common/oauth2/v2.0/token", head, par);
|
||||
logger.info("请求刷新列表返回数据:" + s);
|
||||
JSONObject jsonObject = JSON.parseObject(s);
|
||||
if (!jsonObject.containsKey("access_token")) {
|
||||
logger.info("返回的access_token字段不存在");
|
||||
outlookLogService.addLog(outlook.getGithubId(), "无法刷新令牌! 需要重新授权!", "0", s);
|
||||
// 字段不存在
|
||||
return null;
|
||||
}
|
||||
outlook.setRefreshToken(jsonObject.getString("refresh_token"));
|
||||
outlook.setAccessToken(jsonObject.getString("access_token"));
|
||||
outlook.setIdToken(jsonObject.getString("id_token"));
|
||||
QueryWrapper<Outlook> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("client_id", outlook.getClientId());
|
||||
if (baseMapper.update(outlook, queryWrapper) != 1) {
|
||||
logger.info("返更新行数不为1");
|
||||
outlookLogService.addLog(outlook.getGithubId(), "更新数据库时发现有重复的key", "0", "");
|
||||
return null;
|
||||
}
|
||||
return outlook.getAccessToken();
|
||||
// 更新数据库
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
outlookLogService.addLog(outlook.getGithubId(), e.getMessage(), "0", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package io.qyi.e5.outlook_log.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.qyi.e5.config.security.UsernamePasswordAuthenticationToken;
|
||||
import io.qyi.e5.outlook.entity.Outlook;
|
||||
import io.qyi.e5.outlook.service.IOutlookService;
|
||||
import io.qyi.e5.outlook_log.entity.OutlookLog;
|
||||
import io.qyi.e5.outlook_log.mapper.OutlookLogMapper;
|
||||
import io.qyi.e5.outlook_log.service.IOutlookLogService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-03-03
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/outlookLog")
|
||||
public class OutlookLogController {
|
||||
|
||||
// @Autowired
|
||||
// private OutlookLogMapper outlookLogMapper;
|
||||
|
||||
@Autowired
|
||||
private IOutlookLogService outlookLogService;
|
||||
@Autowired
|
||||
IOutlookService outlookService;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Value("${page.size}")
|
||||
private int pageSize;
|
||||
|
||||
@GetMapping("/findLog")
|
||||
public String findLog(Model model){
|
||||
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
int github_id = authentication.getGithub_id();
|
||||
/*QueryWrapper<OutlookLog> wrapper = new QueryWrapper();
|
||||
wrapper.eq("github_id", github_id);
|
||||
Page<OutlookLog> page = new Page<>(8,pageSize);
|
||||
|
||||
IPage<Map<String, Object>> mapIPage = outlookLogMapper.selectMapsPage(page, wrapper);
|
||||
System.out.println("总页数"+mapIPage.getPages());
|
||||
System.out.println("总记录数"+mapIPage.getTotal());
|
||||
List<Map<String, Object>> records = mapIPage.getRecords();
|
||||
records.forEach(System.out::println);*/
|
||||
|
||||
QueryWrapper<OutlookLog> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("github_id", github_id);
|
||||
List<OutlookLog> list = outlookLogService.list(queryWrapper);
|
||||
model.addAttribute("list_log", list);
|
||||
return "/outlookLog/findLog";
|
||||
}
|
||||
|
||||
@GetMapping("/exec111111")
|
||||
public void s(){
|
||||
List<Outlook> list = outlookService.findAll();
|
||||
logger.info(String.valueOf(list.size()));
|
||||
for (Outlook outlook :list) {
|
||||
logger.info(outlook.toString());
|
||||
outlookService.getMailList(outlook);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
54
src/main/java/io/qyi/e5/outlook_log/entity/OutlookLog.java
Normal file
54
src/main/java/io/qyi/e5/outlook_log/entity/OutlookLog.java
Normal file
@ -0,0 +1,54 @@
|
||||
package io.qyi.e5.outlook_log.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-03-03
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class OutlookLog implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* github_id
|
||||
*/
|
||||
private Integer githubId;
|
||||
|
||||
/**
|
||||
* 调用时间
|
||||
*/
|
||||
private String callTime;
|
||||
|
||||
/**
|
||||
* 调用结果
|
||||
*/
|
||||
private String result;
|
||||
|
||||
/**
|
||||
* 如果有错误原因则记录
|
||||
*/
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 原始错误消息
|
||||
*/
|
||||
private String originalMsg;
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package io.qyi.e5.outlook_log.mapper;
|
||||
|
||||
import io.qyi.e5.outlook_log.entity.OutlookLog;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-03-03
|
||||
*/
|
||||
public interface OutlookLogMapper extends BaseMapper<OutlookLog> {
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package io.qyi.e5.outlook_log.service;
|
||||
|
||||
import io.qyi.e5.outlook_log.entity.OutlookLog;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-03-03
|
||||
*/
|
||||
public interface IOutlookLogService extends IService<OutlookLog> {
|
||||
void addLog(int githubId, String msg,String result,String original_msg);
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package io.qyi.e5.outlook_log.service.impl;
|
||||
|
||||
import io.qyi.e5.outlook_log.entity.OutlookLog;
|
||||
import io.qyi.e5.outlook_log.mapper.OutlookLogMapper;
|
||||
import io.qyi.e5.outlook_log.service.IOutlookLogService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-03-03
|
||||
*/
|
||||
@Service
|
||||
public class OutlookLogServiceImpl extends ServiceImpl<OutlookLogMapper, OutlookLog> implements IOutlookLogService {
|
||||
@Override
|
||||
public void addLog(int githubId, String msg, String result,String original_msg) {
|
||||
OutlookLog outlookLog = new OutlookLog();
|
||||
outlookLog.setGithubId(githubId)
|
||||
.setResult(result.equals("1") ? "1" : "0")
|
||||
.setCallTime(String.valueOf(System.currentTimeMillis() / 1000))
|
||||
.setMsg(msg)
|
||||
.setOriginalMsg(original_msg);
|
||||
|
||||
baseMapper.insert(outlookLog);
|
||||
}
|
||||
}
|
18
src/main/java/io/qyi/e5/service/github/GithubService.java
Normal file
18
src/main/java/io/qyi/e5/service/github/GithubService.java
Normal file
@ -0,0 +1,18 @@
|
||||
package io.qyi.e5.service.github;
|
||||
|
||||
import io.qyi.e5.github.entity.UserInfo;
|
||||
|
||||
/**
|
||||
* @program: msgpush
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-20 00:47
|
||||
**/
|
||||
public interface GithubService {
|
||||
String getAccessToken(String code);
|
||||
|
||||
String getUserEmail(String access_token) throws Exception;
|
||||
|
||||
UserInfo getUserInfo(String access_token);
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package io.qyi.e5.service.github.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.qyi.e5.github.entity.UserInfo;
|
||||
import io.qyi.e5.service.github.GithubService;
|
||||
import io.qyi.e5.util.StringUtil;
|
||||
import io.qyi.e5.util.netRequest.OkHttpRequestUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @program: msgpush
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-20 00:56
|
||||
**/
|
||||
@Service("GithubService")
|
||||
public class GithubServiceImpl implements GithubService {
|
||||
@Value("${github.client_id}")
|
||||
private String client_id;
|
||||
@Value("${github.client_secret}")
|
||||
private String client_secret;
|
||||
|
||||
@Override
|
||||
public String getAccessToken(String code) {
|
||||
Map<String, Object> par = new HashMap<>();
|
||||
par.put("client_id", client_id);
|
||||
par.put("client_secret", client_secret);
|
||||
par.put("code", code);
|
||||
Map<String, Object> head = new HashMap<>();
|
||||
head.put("Content-Type", "application/x-www-form-urlencoded");
|
||||
String s = null;
|
||||
try {
|
||||
s = OkHttpRequestUtils.doPost("https://github.com/login/oauth/access_token", head, par);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println(s);
|
||||
Map<String, String> map = StringUtil.ParsingUrl(s);
|
||||
return map.get("access_token");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserEmail(String access_token) throws Exception {
|
||||
Map<String, Object> head = new HashMap<>();
|
||||
head.put("Authorization", "token " + access_token);
|
||||
head.put("Content-Type", "application/vnd.github.machine-man-preview+json");
|
||||
String s = OkHttpRequestUtils.doGet("https://api.github.com/user/emails", head, null);
|
||||
System.out.println(s);
|
||||
JSONArray jsonArray = JSON.parseArray(s);
|
||||
if (!jsonArray.isEmpty()) {
|
||||
for (int i = 0; i < jsonArray.size(); i++) {
|
||||
JSONObject jsonObject = jsonArray.getJSONObject(i);
|
||||
// 电子邮件是主要的并且已通过验证。
|
||||
if (jsonObject.getBoolean("primary") && jsonObject.getBoolean("verified")) {
|
||||
return jsonObject.getString("email");
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserInfo getUserInfo(String access_token) {
|
||||
Map<String, Object> head = new HashMap<>();
|
||||
head.put("Authorization", "token " + access_token);
|
||||
head.put("Content-Type", "application/vnd.github.machine-man-preview+json");
|
||||
try {
|
||||
String s = OkHttpRequestUtils.doGet("https://api.github.com/user", head, null);
|
||||
JSONObject jsonObject = JSON.parseObject(s);
|
||||
UserInfo userInfo = new UserInfo();
|
||||
if (!jsonObject.isEmpty()) {
|
||||
userInfo.setLogin(jsonObject.getString("login"));
|
||||
userInfo.setName(jsonObject.getString("name"));
|
||||
userInfo.setAvatar_url(jsonObject.getString("avatar_url"));
|
||||
userInfo.setGithub_id(jsonObject.getIntValue("id"));
|
||||
userInfo.setNode_id(jsonObject.getString("node_id"));
|
||||
}
|
||||
return userInfo;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
152
src/main/java/io/qyi/e5/service/quartz/JobUtil.java
Normal file
152
src/main/java/io/qyi/e5/service/quartz/JobUtil.java
Normal file
@ -0,0 +1,152 @@
|
||||
package io.qyi.e5.service.quartz;
|
||||
|
||||
import io.qyi.e5.bean.AppQuartz;
|
||||
import org.quartz.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-03-03 16:18
|
||||
**/
|
||||
@Service
|
||||
public class JobUtil {
|
||||
@Autowired
|
||||
private Scheduler scheduler;
|
||||
|
||||
|
||||
/**
|
||||
* 新建一个任务
|
||||
*/
|
||||
public String addJob(AppQuartz appQuartz, Class aClass) throws Exception {
|
||||
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
// Date date = df.parse(appQuartz.getStartTime());
|
||||
|
||||
if (!CronExpression.isValidExpression(appQuartz.getCronExpression())) {
|
||||
return "Illegal cron expression"; //表达式格式不正确
|
||||
}
|
||||
// JobDetail jobDetail = null;
|
||||
//构建job信息
|
||||
/*if("JobOne".equals(appQuartz.getJobGroup())) {
|
||||
jobDetail = JobBuilder.newJob(JobOne.class).withIdentity(appQuartz.getJobName(), appQuartz.getJobGroup()).build();
|
||||
}
|
||||
if("JobTwo".equals(appQuartz.getJobGroup())) {
|
||||
jobDetail = JobBuilder.newJob(JobTwo.class).withIdentity(appQuartz.getJobName(), appQuartz.getJobGroup()).build();
|
||||
}*/
|
||||
JobDetail jobDetail = JobBuilder.newJob(aClass).withIdentity(appQuartz.getJobName(), appQuartz.getJobGroup()).build();
|
||||
|
||||
//表达式调度构建器(即任务执行的时间,不立即执行)
|
||||
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(appQuartz.getCronExpression()).withMisfireHandlingInstructionDoNothing();
|
||||
|
||||
//按新的cronExpression表达式构建一个新的trigger
|
||||
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(appQuartz.getJobName(), appQuartz.getJobGroup()).startNow()
|
||||
.withSchedule(scheduleBuilder).build();
|
||||
|
||||
//传递参数
|
||||
if (appQuartz.getInvokeParam() != null && !"".equals(appQuartz.getInvokeParam())) {
|
||||
trigger.getJobDataMap().put("invokeParam", appQuartz.getInvokeParam());
|
||||
}
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
// pauseJob(appQuartz.getJobName(),appQuartz.getJobGroup());
|
||||
return "success";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Job状态
|
||||
*
|
||||
* @param jobName
|
||||
* @param jobGroup
|
||||
* @return
|
||||
* @throws SchedulerException
|
||||
*/
|
||||
public String getJobState(String jobName, String jobGroup) throws SchedulerException {
|
||||
TriggerKey triggerKey = new TriggerKey(jobName, jobGroup);
|
||||
return scheduler.getTriggerState(triggerKey).name();
|
||||
}
|
||||
|
||||
//暂停所有任务
|
||||
public void pauseAllJob() throws SchedulerException {
|
||||
scheduler.pauseAll();
|
||||
}
|
||||
|
||||
//暂停任务
|
||||
public String pauseJob(String jobName, String jobGroup) throws SchedulerException {
|
||||
JobKey jobKey = new JobKey(jobName, jobGroup);
|
||||
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
|
||||
if (jobDetail == null) {
|
||||
return "fail";
|
||||
} else {
|
||||
scheduler.pauseJob(jobKey);
|
||||
return "success";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//恢复所有任务
|
||||
public void resumeAllJob() throws SchedulerException {
|
||||
scheduler.resumeAll();
|
||||
}
|
||||
|
||||
// 恢复某个任务
|
||||
public String resumeJob(String jobName, String jobGroup) throws SchedulerException {
|
||||
|
||||
JobKey jobKey = new JobKey(jobName, jobGroup);
|
||||
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
|
||||
if (jobDetail == null) {
|
||||
return "fail";
|
||||
} else {
|
||||
scheduler.resumeJob(jobKey);
|
||||
return "success";
|
||||
}
|
||||
}
|
||||
|
||||
//删除某个任务
|
||||
public String deleteJob(AppQuartz appQuartz) throws SchedulerException {
|
||||
JobKey jobKey = new JobKey(appQuartz.getJobName(), appQuartz.getJobGroup());
|
||||
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
|
||||
if (jobDetail == null) {
|
||||
return "jobDetail is null";
|
||||
} else if (!scheduler.checkExists(jobKey)) {
|
||||
return "jobKey is not exists";
|
||||
} else {
|
||||
scheduler.deleteJob(jobKey);
|
||||
return "success";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//修改任务
|
||||
public String modifyJob(AppQuartz appQuartz) throws SchedulerException {
|
||||
if (!CronExpression.isValidExpression(appQuartz.getCronExpression())) {
|
||||
return "Illegal cron expression";
|
||||
}
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(appQuartz.getJobName(), appQuartz.getJobGroup());
|
||||
JobKey jobKey = new JobKey(appQuartz.getJobName(), appQuartz.getJobGroup());
|
||||
if (scheduler.checkExists(jobKey) && scheduler.checkExists(triggerKey)) {
|
||||
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
//表达式调度构建器,不立即执行
|
||||
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(appQuartz.getCronExpression()).withMisfireHandlingInstructionDoNothing();
|
||||
//按新的cronExpression表达式重新构建trigger
|
||||
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
|
||||
.withSchedule(scheduleBuilder).build();
|
||||
//修改参数
|
||||
if (!trigger.getJobDataMap().get("invokeParam").equals(appQuartz.getInvokeParam())) {
|
||||
trigger.getJobDataMap().put("invokeParam", appQuartz.getInvokeParam());
|
||||
}
|
||||
//按新的trigger重新设置job执行
|
||||
scheduler.rescheduleJob(triggerKey, trigger);
|
||||
return "success";
|
||||
} else {
|
||||
return "job or trigger not exists";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package io.qyi.e5.service.quartz;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import io.qyi.e5.outlook.entity.Outlook;
|
||||
import io.qyi.e5.outlook.service.IOutlookService;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-03-03 14:37
|
||||
**/
|
||||
public class MyQuartzJobService implements Job {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Autowired
|
||||
IOutlookService outlookService;
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||
logger.info("定时任务被调用~");
|
||||
// QueryWrapper<Outlook> queryWrapper = new QueryWrapper<>();
|
||||
List<Outlook> list = outlookService.findAll();
|
||||
logger.info(String.valueOf(list.size()));
|
||||
for (Outlook outlook :list) {
|
||||
logger.info(outlook.toString());
|
||||
outlookService.getMailList(outlook);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package io.qyi.e5.service.security;
|
||||
|
||||
import io.qyi.e5.user.mapper.UserMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-26 21:38
|
||||
**/
|
||||
@Component
|
||||
public class SecurityUserService implements UserDetailsService {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
|
||||
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
|
||||
String encode = bCryptPasswordEncoder.encode("123");
|
||||
String encodePasswd = encode;
|
||||
logger.info("登录用户名: {} , 密码:{}",s,encodePasswd);
|
||||
UserDetails userDetails = new User(s, encode, AuthorityUtils.createAuthorityList("admin"));
|
||||
return userDetails;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package io.qyi.e5.user.controller;
|
||||
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/user/permission")
|
||||
public class PermissionController {
|
||||
|
||||
}
|
20
src/main/java/io/qyi/e5/user/controller/RoleController.java
Normal file
20
src/main/java/io/qyi/e5/user/controller/RoleController.java
Normal file
@ -0,0 +1,20 @@
|
||||
package io.qyi.e5.user.controller;
|
||||
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/user/role")
|
||||
public class RoleController {
|
||||
|
||||
}
|
20
src/main/java/io/qyi/e5/user/controller/UserController.java
Normal file
20
src/main/java/io/qyi/e5/user/controller/UserController.java
Normal file
@ -0,0 +1,20 @@
|
||||
package io.qyi.e5.user.controller;
|
||||
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/user/user")
|
||||
public class UserController {
|
||||
|
||||
}
|
34
src/main/java/io/qyi/e5/user/entity/Permission.java
Normal file
34
src/main/java/io/qyi/e5/user/entity/Permission.java
Normal file
@ -0,0 +1,34 @@
|
||||
package io.qyi.e5.user.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class Permission implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 所拥有的权限
|
||||
*/
|
||||
private String permission;
|
||||
|
||||
|
||||
}
|
39
src/main/java/io/qyi/e5/user/entity/Role.java
Normal file
39
src/main/java/io/qyi/e5/user/entity/Role.java
Normal file
@ -0,0 +1,39 @@
|
||||
package io.qyi.e5.user.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class Role implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 角色名称
|
||||
*/
|
||||
private String rolename;
|
||||
|
||||
/**
|
||||
* 权限id
|
||||
*/
|
||||
private String permission;
|
||||
|
||||
|
||||
}
|
51
src/main/java/io/qyi/e5/user/entity/User.java
Normal file
51
src/main/java/io/qyi/e5/user/entity/User.java
Normal file
@ -0,0 +1,51 @@
|
||||
package io.qyi.e5.user.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
public class User implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 密码使用sha512
|
||||
*/
|
||||
private String passwd;
|
||||
|
||||
/**
|
||||
* 角色id
|
||||
*/
|
||||
private String role;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 账户状态,1、启用 0、禁用
|
||||
*/
|
||||
private String status;
|
||||
|
||||
|
||||
}
|
16
src/main/java/io/qyi/e5/user/mapper/PermissionMapper.java
Normal file
16
src/main/java/io/qyi/e5/user/mapper/PermissionMapper.java
Normal file
@ -0,0 +1,16 @@
|
||||
package io.qyi.e5.user.mapper;
|
||||
|
||||
import io.qyi.e5.user.entity.Permission;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
public interface PermissionMapper extends BaseMapper<Permission> {
|
||||
|
||||
}
|
16
src/main/java/io/qyi/e5/user/mapper/RoleMapper.java
Normal file
16
src/main/java/io/qyi/e5/user/mapper/RoleMapper.java
Normal file
@ -0,0 +1,16 @@
|
||||
package io.qyi.e5.user.mapper;
|
||||
|
||||
import io.qyi.e5.user.entity.Role;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
public interface RoleMapper extends BaseMapper<Role> {
|
||||
|
||||
}
|
16
src/main/java/io/qyi/e5/user/mapper/UserMapper.java
Normal file
16
src/main/java/io/qyi/e5/user/mapper/UserMapper.java
Normal file
@ -0,0 +1,16 @@
|
||||
package io.qyi.e5.user.mapper;
|
||||
|
||||
import io.qyi.e5.user.entity.User;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
public interface UserMapper extends BaseMapper<User> {
|
||||
|
||||
}
|
16
src/main/java/io/qyi/e5/user/service/IPermissionService.java
Normal file
16
src/main/java/io/qyi/e5/user/service/IPermissionService.java
Normal file
@ -0,0 +1,16 @@
|
||||
package io.qyi.e5.user.service;
|
||||
|
||||
import io.qyi.e5.user.entity.Permission;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
public interface IPermissionService extends IService<Permission> {
|
||||
|
||||
}
|
16
src/main/java/io/qyi/e5/user/service/IRoleService.java
Normal file
16
src/main/java/io/qyi/e5/user/service/IRoleService.java
Normal file
@ -0,0 +1,16 @@
|
||||
package io.qyi.e5.user.service;
|
||||
|
||||
import io.qyi.e5.user.entity.Role;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
public interface IRoleService extends IService<Role> {
|
||||
|
||||
}
|
16
src/main/java/io/qyi/e5/user/service/IUserService.java
Normal file
16
src/main/java/io/qyi/e5/user/service/IUserService.java
Normal file
@ -0,0 +1,16 @@
|
||||
package io.qyi.e5.user.service;
|
||||
|
||||
import io.qyi.e5.user.entity.User;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
public interface IUserService extends IService<User> {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package io.qyi.e5.user.service.impl;
|
||||
|
||||
import io.qyi.e5.user.entity.Permission;
|
||||
import io.qyi.e5.user.mapper.PermissionMapper;
|
||||
import io.qyi.e5.user.service.IPermissionService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@Service
|
||||
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package io.qyi.e5.user.service.impl;
|
||||
|
||||
import io.qyi.e5.user.entity.Role;
|
||||
import io.qyi.e5.user.mapper.RoleMapper;
|
||||
import io.qyi.e5.user.service.IRoleService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@Service
|
||||
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package io.qyi.e5.user.service.impl;
|
||||
|
||||
import io.qyi.e5.user.entity.User;
|
||||
import io.qyi.e5.user.mapper.UserMapper;
|
||||
import io.qyi.e5.user.service.IUserService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author 落叶
|
||||
* @since 2020-02-24
|
||||
*/
|
||||
@Service
|
||||
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
|
||||
|
||||
}
|
339
src/main/java/io/qyi/e5/util/EncryptUtil.java
Normal file
339
src/main/java/io/qyi/e5/util/EncryptUtil.java
Normal file
@ -0,0 +1,339 @@
|
||||
package io.qyi.e5.util;
|
||||
|
||||
|
||||
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class EncryptUtil {
|
||||
public static final String MD5 = "MD5";
|
||||
public static final String SHA1 = "SHA1";
|
||||
public static final String HmacMD5 = "HmacMD5";
|
||||
public static final String HmacSHA1 = "HmacSHA1";
|
||||
public static final String DES = "DES";
|
||||
public static final String AES = "AES";
|
||||
|
||||
/**
|
||||
* 编码格式;默认使用uft-8
|
||||
*/
|
||||
public String charset = "utf-8";
|
||||
/**
|
||||
* DES
|
||||
*/
|
||||
public int keysizeDES = 0;
|
||||
/**
|
||||
* AES
|
||||
*/
|
||||
public int keysizeAES = 128;
|
||||
|
||||
public static EncryptUtil me;
|
||||
|
||||
private EncryptUtil() {
|
||||
//单例
|
||||
}
|
||||
|
||||
//双重锁
|
||||
public static EncryptUtil getInstance() {
|
||||
if (me == null) {
|
||||
synchronized (EncryptUtil.class) {
|
||||
if (me == null) {
|
||||
me = new EncryptUtil();
|
||||
}
|
||||
}
|
||||
}
|
||||
return me;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用MessageDigest进行单向加密(无密码)
|
||||
*
|
||||
* @param res 被加密的文本
|
||||
* @param algorithm 加密算法名称
|
||||
* @return
|
||||
*/
|
||||
private String messageDigest(String res, String algorithm) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance(algorithm);
|
||||
byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
|
||||
return base64(md.digest(resBytes));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 使用MessageDigest进行单向加密(无密码)
|
||||
*
|
||||
* @param res 被加密的文本
|
||||
* @param algorithm 加密算法名称
|
||||
* @return
|
||||
*/
|
||||
private String messageDigestHex(String res, String algorithm) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance(algorithm);
|
||||
byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
|
||||
return NumConvertUtil.bytesToHexString(md.digest(resBytes));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用KeyGenerator进行单向/双向加密(可设密码)
|
||||
*
|
||||
* @param res 被加密的原文
|
||||
* @param algorithm 加密使用的算法名称
|
||||
* @param key 加密使用的秘钥
|
||||
* @return
|
||||
*/
|
||||
private String keyGeneratorMac(String res, String algorithm, String key) {
|
||||
try {
|
||||
SecretKey sk = null;
|
||||
if (key == null) {
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algorithm);
|
||||
sk = kg.generateKey();
|
||||
} else {
|
||||
byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
|
||||
sk = new SecretKeySpec(keyBytes, algorithm);
|
||||
}
|
||||
Mac mac = Mac.getInstance(algorithm);
|
||||
mac.init(sk);
|
||||
byte[] result = mac.doFinal(res.getBytes());
|
||||
return base64(result);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用KeyGenerator双向加密,DES/AES,注意这里转化为字符串的时候是将2进制转为16进制格式的字符串,不是直接转,因为会出错
|
||||
*
|
||||
* @param res 加密的原文
|
||||
* @param algorithm 加密使用的算法名称
|
||||
* @param key 加密的秘钥
|
||||
* @param keysize
|
||||
* @param isEncode
|
||||
* @return
|
||||
*/
|
||||
private String keyGeneratorES(String res, String algorithm, String key, int keysize, boolean isEncode) {
|
||||
try {
|
||||
KeyGenerator kg = KeyGenerator.getInstance(algorithm);
|
||||
if (keysize == 0) {
|
||||
byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
|
||||
kg.init(new SecureRandom(keyBytes));
|
||||
} else if (key == null) {
|
||||
kg.init(keysize);
|
||||
} else {
|
||||
byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
|
||||
kg.init(keysize, new SecureRandom(keyBytes));
|
||||
}
|
||||
SecretKey sk = kg.generateKey();
|
||||
SecretKeySpec sks = new SecretKeySpec(sk.getEncoded(), algorithm);
|
||||
Cipher cipher = Cipher.getInstance(algorithm);
|
||||
if (isEncode) {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, sks);
|
||||
byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
|
||||
return parseByte2HexStr(cipher.doFinal(resBytes));
|
||||
} else {
|
||||
cipher.init(Cipher.DECRYPT_MODE, sks);
|
||||
return new String(cipher.doFinal(parseHexStr2Byte(res)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String base64(byte[] res) {
|
||||
return Base64.encode(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将二进制转换成16进制
|
||||
*/
|
||||
public static String parseByte2HexStr(byte buf[]) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < buf.length; i++) {
|
||||
String hex = Integer.toHexString(buf[i] & 0xFF);
|
||||
if (hex.length() == 1) {
|
||||
hex = '0' + hex;
|
||||
}
|
||||
sb.append(hex.toUpperCase());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将16进制转换为二进制
|
||||
*/
|
||||
public static byte[] parseHexStr2Byte(String hexStr) {
|
||||
if (hexStr.length() < 1)
|
||||
return null;
|
||||
byte[] result = new byte[hexStr.length() / 2];
|
||||
for (int i = 0; i < hexStr.length() / 2; i++) {
|
||||
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
|
||||
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
|
||||
result[i] = (byte) (high * 16 + low);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* md5加密算法进行加密(不可逆)
|
||||
*
|
||||
* @param res 需要加密的原文
|
||||
* @return
|
||||
*/
|
||||
public String MD5(String res) {
|
||||
return messageDigest(res, MD5);
|
||||
}
|
||||
|
||||
/**
|
||||
* md5加密算法进行加密(不可逆)
|
||||
*
|
||||
* @param res 需要加密的原文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public String MD5(String res, String key) {
|
||||
return keyGeneratorMac(res, HmacMD5, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用SHA1加密算法进行加密(不可逆)
|
||||
*
|
||||
* @param res 需要加密的原文
|
||||
* @return
|
||||
*/
|
||||
public String SHA1(String res) {
|
||||
return messageDigest(res, SHA1);
|
||||
}
|
||||
|
||||
public String SHA1Hex(String res) {
|
||||
return messageDigestHex(res, SHA1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用SHA1加密算法进行加密(不可逆)
|
||||
*
|
||||
* @param res 需要加密的原文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public String SHA1(String res, String key) {
|
||||
return keyGeneratorMac(res, HmacSHA1, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用DES加密算法进行加密(可逆)
|
||||
*
|
||||
* @param res 需要加密的原文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public String DESencode(String res, String key) {
|
||||
return keyGeneratorES(res, DES, key, keysizeDES, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对使用DES加密算法的密文进行解密(可逆)
|
||||
*
|
||||
* @param res 需要解密的密文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public String DESdecode(String res, String key) {
|
||||
return keyGeneratorES(res, DES, key, keysizeDES, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用AES加密算法经行加密(可逆)
|
||||
*
|
||||
* @param res 需要加密的密文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public String AESencode(String res, String key) {
|
||||
return keyGeneratorES(res, AES, key, keysizeAES, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对使用AES加密算法的密文进行解密
|
||||
*
|
||||
* @param res 需要解密的密文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public String AESdecode(String res, String key) {
|
||||
return keyGeneratorES(res, AES, key, keysizeAES, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用异或进行加密
|
||||
*
|
||||
* @param res 需要加密的密文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public String XORencode(String res, String key) {
|
||||
byte[] bs = res.getBytes();
|
||||
for (int i = 0; i < bs.length; i++) {
|
||||
bs[i] = (byte) ((bs[i]) ^ key.hashCode());
|
||||
}
|
||||
return parseByte2HexStr(bs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用异或进行解密
|
||||
*
|
||||
* @param res 需要解密的密文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public String XORdecode(String res, String key) {
|
||||
byte[] bs = parseHexStr2Byte(res);
|
||||
for (int i = 0; i < bs.length; i++) {
|
||||
bs[i] = (byte) ((bs[i]) ^ key.hashCode());
|
||||
}
|
||||
return new String(bs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接使用异或(第一调用加密,第二次调用解密)
|
||||
*
|
||||
* @param res 密文
|
||||
* @param key 秘钥
|
||||
* @return
|
||||
*/
|
||||
public int XOR(int res, String key) {
|
||||
return res ^ key.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用Base64进行加密
|
||||
*
|
||||
* @param res 密文
|
||||
* @return
|
||||
*/
|
||||
public String Base64Encode(String res) {
|
||||
return Base64.encode(res.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用Base64进行解密
|
||||
*
|
||||
* @param res
|
||||
* @return
|
||||
*/
|
||||
public String Base64Decode(String res) {
|
||||
return new String(Base64.decode(res));
|
||||
}
|
||||
}
|
185
src/main/java/io/qyi/e5/util/NumConvertUtil.java
Normal file
185
src/main/java/io/qyi/e5/util/NumConvertUtil.java
Normal file
@ -0,0 +1,185 @@
|
||||
package io.qyi.e5.util;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
* 数据类型转换工具类
|
||||
* @author cyf
|
||||
*
|
||||
*/
|
||||
public class NumConvertUtil{
|
||||
|
||||
|
||||
/**
|
||||
* bytes 转16进制字符串
|
||||
* @param bArray
|
||||
* @return
|
||||
*/
|
||||
public static final String bytesToHexString(byte[] bArray) {
|
||||
StringBuffer sb = new StringBuffer(bArray.length);
|
||||
String sTemp;
|
||||
for (int i = 0; i < bArray.length; i++) {
|
||||
sTemp = Integer.toHexString(0xFF & bArray[i]);
|
||||
if (sTemp.length() < 2)
|
||||
sb.append(0);
|
||||
sb.append(sTemp.toUpperCase());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 16进制字符串转bytes
|
||||
* @param hex
|
||||
* @return
|
||||
*/
|
||||
public static byte[] hexStringToByte(String hex) {
|
||||
|
||||
int len = 0;
|
||||
int num=0;
|
||||
|
||||
//判断字符串的长度是否是两位
|
||||
if(hex.length()>=2){
|
||||
|
||||
//判断字符喜欢是否是偶数
|
||||
len=(hex.length() / 2);
|
||||
num = (hex.length() % 2);
|
||||
|
||||
if (num == 1) {
|
||||
hex = "0" + hex;
|
||||
len=len+1;
|
||||
}
|
||||
|
||||
|
||||
}else{
|
||||
|
||||
hex = "0" + hex;
|
||||
len=1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
byte[] result = new byte[len];
|
||||
char[] achar = hex.toCharArray();
|
||||
for (int i = 0; i < len; i++) {
|
||||
int pos = i * 2;
|
||||
result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
|
||||
}
|
||||
return result;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static int toByte(char c) {
|
||||
|
||||
|
||||
if (c >= 'a')
|
||||
return (c - 'a' + 10) & 0x0f;
|
||||
if (c >= 'A')
|
||||
return (c - 'A' + 10) & 0x0f;
|
||||
return (c - '0') & 0x0f;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 16进制字符串转十进制int
|
||||
* @param HexString
|
||||
* @return
|
||||
*/
|
||||
public static int HexStringToInt(String HexString) {
|
||||
|
||||
int inJTFingerLockAddress = Integer.valueOf(HexString, 16);
|
||||
|
||||
return inJTFingerLockAddress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 十进制int转16进制字符串
|
||||
* @param HexString
|
||||
* @return
|
||||
*/
|
||||
public static String IntToHexString(int num) {
|
||||
|
||||
String hexString = Integer.toHexString(num);
|
||||
|
||||
return hexString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 16进制String转BCD
|
||||
* @param asc
|
||||
* @return
|
||||
*/
|
||||
public static byte[] strToBcd(String asc) {
|
||||
int len = asc.length();
|
||||
int mod = len % 2;
|
||||
|
||||
if (mod != 0) {
|
||||
asc = "0" + asc;
|
||||
len = asc.length();
|
||||
}
|
||||
|
||||
byte abt[] = new byte[len];
|
||||
if (len >= 2) {
|
||||
len = len / 2;
|
||||
}
|
||||
|
||||
byte bbt[] = new byte[len];
|
||||
abt = asc.getBytes();
|
||||
int j, k;
|
||||
|
||||
for (int p = 0; p < asc.length()/2; p++) {
|
||||
if ( (abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
|
||||
j = abt[2 * p] - '0';
|
||||
} else if ( (abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
|
||||
j = abt[2 * p] - 'a' + 0x0a;
|
||||
} else {
|
||||
j = abt[2 * p] - 'A' + 0x0a;
|
||||
}
|
||||
|
||||
if ( (abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
|
||||
k = abt[2 * p + 1] - '0';
|
||||
} else if ( (abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
|
||||
k = abt[2 * p + 1] - 'a' + 0x0a;
|
||||
}else {
|
||||
k = abt[2 * p + 1] - 'A' + 0x0a;
|
||||
}
|
||||
|
||||
int a = (j << 4) + k;
|
||||
byte b = (byte) a;
|
||||
bbt[p] = b;
|
||||
}
|
||||
return bbt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* String 类型数字转化为Double 保留置顶小数位(用于显示金额等。)
|
||||
* @param money
|
||||
* @param type 保留小数点位数 #.00保留两位 #.0保留一位 #保留整数
|
||||
* @return
|
||||
*/
|
||||
public static String strToDouble(String money,String type){
|
||||
|
||||
String toDouble= new DecimalFormat(type).format(Double.parseDouble(money));
|
||||
|
||||
return toDouble;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
49
src/main/java/io/qyi/e5/util/ResultUtil.java
Normal file
49
src/main/java/io/qyi/e5/util/ResultUtil.java
Normal file
@ -0,0 +1,49 @@
|
||||
package io.qyi.e5.util;
|
||||
|
||||
import io.qyi.e5.bean.result.Result;
|
||||
import io.qyi.e5.bean.result.ResultEnum;
|
||||
|
||||
/**
|
||||
* @program: msgpush
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-05 21:05
|
||||
**/
|
||||
public class ResultUtil extends Throwable {
|
||||
|
||||
|
||||
|
||||
public static Result success(Object object) {
|
||||
Result result = new Result();
|
||||
result.setCode(0);
|
||||
result.setMsg("ok");
|
||||
result.setData(object);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Result success() {
|
||||
return success(null);
|
||||
}
|
||||
|
||||
public static Result error(Integer code, String msg) {
|
||||
Result result = new Result();
|
||||
result.setCode(code);
|
||||
result.setMsg(msg);
|
||||
return result;
|
||||
}
|
||||
public static Result success(ResultEnum resultEnum, Object object) {
|
||||
Result result = new Result();
|
||||
result.setCode(resultEnum.getCode());
|
||||
result.setMsg(resultEnum.getMsg());
|
||||
result.setData(object);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static Result error(ResultEnum msg) {
|
||||
Result result = new Result();
|
||||
result.setCode(msg.getCode());
|
||||
result.setMsg(msg.getMsg());
|
||||
return result;
|
||||
}
|
||||
}
|
48
src/main/java/io/qyi/e5/util/SpringUtil.java
Normal file
48
src/main/java/io/qyi/e5/util/SpringUtil.java
Normal file
@ -0,0 +1,48 @@
|
||||
package io.qyi.e5.util;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @program: lotter2
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2019-10-09 01:26
|
||||
**/
|
||||
@Component
|
||||
public class SpringUtil implements ApplicationContextAware {
|
||||
private static ApplicationContext applicationContext;
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
if(this.applicationContext == null) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
|
||||
System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="+SpringUtil.applicationContext+"========");
|
||||
|
||||
System.out.println("---------------------------------------------------------------------");
|
||||
}
|
||||
//获取applicationContext
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
//通过name获取 Bean.
|
||||
public static Object getBean(String name){
|
||||
return getApplicationContext().getBean(name);
|
||||
}
|
||||
|
||||
//通过class获取Bean.
|
||||
public static <T> T getBean(Class<T> clazz){
|
||||
return getApplicationContext().getBean(clazz);
|
||||
}
|
||||
|
||||
//通过name,以及Clazz返回指定的Bean
|
||||
public static <T> T getBean(String name,Class<T> clazz){
|
||||
return getApplicationContext().getBean(name, clazz);
|
||||
}
|
||||
|
||||
}
|
27
src/main/java/io/qyi/e5/util/StringUtil.java
Normal file
27
src/main/java/io/qyi/e5/util/StringUtil.java
Normal file
@ -0,0 +1,27 @@
|
||||
package io.qyi.e5.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @program: msgpush
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-20 23:59
|
||||
**/
|
||||
public class StringUtil {
|
||||
public static Map<String, String> ParsingUrl(String url){
|
||||
String[] split = url.split("&");
|
||||
Map<String, String> map = new HashMap<>();
|
||||
for (int i = 0; i < split.length; i++) {
|
||||
String[] split1 = split[i].split("=");
|
||||
if (split1.length > 1) {
|
||||
System.out.println(split1[0] + " --- " + split1[1]);
|
||||
map.put(split1[0], split1[1]);
|
||||
} else {
|
||||
map.put(split1[0], "");
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
260
src/main/java/io/qyi/e5/util/VerifyCode.java
Normal file
260
src/main/java/io/qyi/e5/util/VerifyCode.java
Normal file
@ -0,0 +1,260 @@
|
||||
package io.qyi.e5.util;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author yellowcong
|
||||
* 创建日期:2018/02/06
|
||||
* 验证码信息
|
||||
*/
|
||||
public class VerifyCode {
|
||||
|
||||
//宽度
|
||||
private static final int CAPTCHA_WIDTH = 100;
|
||||
//高度
|
||||
private static final int CAPTCHA_HEIGHT = 35;
|
||||
//数字的长度
|
||||
private static final int NUMBER_CNT = 6;
|
||||
//图片类型
|
||||
private static final String IMAGE_TYPE = "JPEG";
|
||||
|
||||
private Random r = new Random();
|
||||
// 字体
|
||||
// private String[] fontNames = { "宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312" };
|
||||
private String[] fontNames = {"宋体", "黑体", "微软雅黑"};
|
||||
|
||||
// 可选字符
|
||||
private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
|
||||
|
||||
// 背景色,白色
|
||||
private Color bgColor = new Color(255, 255, 255);
|
||||
|
||||
// 验证码上的文本
|
||||
private String text;
|
||||
|
||||
private static VerifyCode utils = null;
|
||||
|
||||
/**
|
||||
* 实例化对象
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static VerifyCode getInstance() {
|
||||
if (utils == null) {
|
||||
synchronized (VerifyCode.class) {
|
||||
if (utils == null) {
|
||||
utils = new VerifyCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
return utils;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建验证码
|
||||
*
|
||||
* @param path 路径地址
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public String getCode(String path) throws Exception {
|
||||
BufferedImage bi = utils.getImage();
|
||||
output(bi, new FileOutputStream(path));
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建日期:2018年2月6日<br/>
|
||||
* 创建时间:下午7:22:36<br/>
|
||||
* 创建用户:yellowcong<br/>
|
||||
* 机能概要:生成图片对象,并返回
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public CaptchaCode getCode() throws Exception {
|
||||
BufferedImage img = utils.getImage();
|
||||
|
||||
//返回验证码对象
|
||||
CaptchaCode code = new CaptchaCode();
|
||||
code.setText(this.text);
|
||||
code.setData(this.copyImage2Byte(img));
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建日期:2018年2月6日<br/>
|
||||
* 创建时间:下午7:17:28<br/>
|
||||
* 创建用户:yellowcong<br/>
|
||||
* 机能概要:将图片转化为 二进制数据
|
||||
*
|
||||
* @param img
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public byte[] copyImage2Byte(BufferedImage img) throws Exception {
|
||||
//字节码输出流
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
|
||||
//写数据到输出流中
|
||||
ImageIO.write(img, IMAGE_TYPE, bout);
|
||||
|
||||
//返回数据
|
||||
return bout.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建日期:2018年2月6日<br/>
|
||||
* 创建时间:下午7:20:50<br/>
|
||||
* 创建用户:yellowcong<br/>
|
||||
* 机能概要:将二进制数据转化为文件
|
||||
*
|
||||
* @param data
|
||||
* @param file
|
||||
* @throws Exception
|
||||
*/
|
||||
public boolean copyByte2File(byte[] data, String file) throws Exception {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(data);
|
||||
FileOutputStream out = new FileOutputStream(file);
|
||||
try {
|
||||
byte[] buff = new byte[1024];
|
||||
int len = 0;
|
||||
while ((len = in.read(buff)) > -1) {
|
||||
out.write(buff, 0, len);
|
||||
}
|
||||
out.flush();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} finally {
|
||||
out.close();
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建日期:2018年2月6日<br/>
|
||||
* 创建时间:下午7:03:57<br/>
|
||||
* 创建用户:yellowcong<br/>
|
||||
* 机能概要:生成随机的颜色
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Color randomColor() {
|
||||
int red = r.nextInt(150);
|
||||
int green = r.nextInt(150);
|
||||
int blue = r.nextInt(150);
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建日期:2018年2月6日<br/>
|
||||
* 创建时间:下午7:03:20<br/>
|
||||
* 创建用户:yellowcong<br/>
|
||||
* 机能概要:生成随机的字体
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Font randomFont() {
|
||||
int index = r.nextInt(fontNames.length);
|
||||
String fontName = fontNames[index];// 生成随机的字体名称
|
||||
int style = r.nextInt(4);// 生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体)
|
||||
int size = r.nextInt(5) + 24; // 生成随机字号, 24 ~ 28
|
||||
return new Font(fontName, style, size);
|
||||
}
|
||||
|
||||
// 画干扰线
|
||||
private void drawLine(BufferedImage image) {
|
||||
int num = 9;// 一共画9条
|
||||
Graphics2D g2 = (Graphics2D) image.getGraphics();
|
||||
for (int i = 0; i < num; i++) {// 生成两个点的坐标,即4个值
|
||||
int x1 = r.nextInt(CAPTCHA_WIDTH);
|
||||
int y1 = r.nextInt(CAPTCHA_HEIGHT);
|
||||
int x2 = r.nextInt(CAPTCHA_WIDTH);
|
||||
int y2 = r.nextInt(CAPTCHA_HEIGHT);
|
||||
g2.setStroke(new BasicStroke(1.5F));
|
||||
g2.setColor(randomColor()); // 随机生成干扰线颜色
|
||||
g2.drawLine(x1, y1, x2, y2);// 画线
|
||||
}
|
||||
}
|
||||
|
||||
// 随机生成一个字符
|
||||
private char randomChar() {
|
||||
int index = r.nextInt(codes.length());
|
||||
return codes.charAt(index);
|
||||
}
|
||||
|
||||
// 创建BufferedImage
|
||||
private BufferedImage createImage() {
|
||||
BufferedImage image = new BufferedImage(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g2 = (Graphics2D) image.getGraphics();
|
||||
g2.setColor(this.bgColor);
|
||||
g2.fillRect(0, 0, CAPTCHA_WIDTH, CAPTCHA_HEIGHT);
|
||||
return image;
|
||||
}
|
||||
|
||||
// 调用这个方法得到验证码
|
||||
public BufferedImage getImage() {
|
||||
BufferedImage image = createImage();// 创建图片缓冲区
|
||||
Graphics2D g2 = (Graphics2D) image.getGraphics();// 得到绘制环境
|
||||
StringBuilder sb = new StringBuilder();// 用来装载生成的验证码文本
|
||||
// 向图片中画4个字符
|
||||
for (int i = 0; i < NUMBER_CNT; i++) {// 循环四次,每次生成一个字符
|
||||
String s = randomChar() + "";// 随机生成一个字母
|
||||
sb.append(s); // 把字母添加到sb中
|
||||
float x = i * 1.0F * CAPTCHA_WIDTH / NUMBER_CNT; // 设置当前字符的x轴坐标
|
||||
g2.setFont(randomFont()); // 设置随机字体
|
||||
g2.setColor(randomColor()); // 设置随机颜色
|
||||
g2.drawString(s, x, CAPTCHA_HEIGHT - 5); // 画图
|
||||
}
|
||||
this.text = sb.toString(); // 把生成的字符串赋给了this.text
|
||||
drawLine(image); // 添加干扰线
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建日期:2018年2月6日<br/>
|
||||
* 创建时间:下午7:09:49<br/>
|
||||
* 创建用户:yellowcong<br/>
|
||||
* 机能概要:
|
||||
*
|
||||
* @return 返回验证码图片上的文本
|
||||
*/
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
// 保存图片到指定的输出流
|
||||
public static void output(BufferedImage image, OutputStream out) throws IOException {
|
||||
ImageIO.write(image, IMAGE_TYPE, out);
|
||||
}
|
||||
|
||||
//图片验证码对象
|
||||
static class CaptchaCode {
|
||||
//验证码文字信息
|
||||
private String text;
|
||||
//验证码二进制数据
|
||||
private byte[] data;
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
}
|
130
src/main/java/io/qyi/e5/util/netRequest/OkHttpClientUtil.java
Normal file
130
src/main/java/io/qyi/e5/util/netRequest/OkHttpClientUtil.java
Normal file
@ -0,0 +1,130 @@
|
||||
package io.qyi.e5.util.netRequest;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class OkHttpClientUtil {
|
||||
private static int connTimeOut = 5;
|
||||
private static int readTimeOut = 20;
|
||||
private static int writeTimeOut = 10;
|
||||
public static OkHttpClient client = null;
|
||||
|
||||
static {
|
||||
client = new OkHttpClient.Builder()
|
||||
.connectTimeout(5L, TimeUnit.SECONDS)
|
||||
.readTimeout(20L, TimeUnit.SECONDS)
|
||||
.writeTimeout(10L, TimeUnit.SECONDS)
|
||||
.retryOnConnectionFailure(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
public static String doGet(String host, String path, Map<String, String> headers, Map<String, String> querys) throws Exception {
|
||||
StringBuffer url = new StringBuffer(host + (path == null ? "" : path));
|
||||
if (querys != null) {
|
||||
url.append("?");
|
||||
Iterator iterator = querys.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, String> e = (Map.Entry) iterator.next();
|
||||
url.append((String) e.getKey()).append("=").append((String) e.getValue() + "&");
|
||||
}
|
||||
url = new StringBuffer(url.substring(0, url.length() - 1));
|
||||
}
|
||||
Request.Builder requestBuilder = new Request.Builder();
|
||||
if (headers != null && headers.size() > 0) {
|
||||
Iterator iterator = headers.keySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String key = (String) iterator.next();
|
||||
requestBuilder.addHeader(key, (String) headers.get(key));
|
||||
}
|
||||
}
|
||||
Request request = (requestBuilder).url(url.toString()).build();
|
||||
Response response = client.newCall(request).execute();
|
||||
String responseStr = response.body() == null ? "" : response.body().string();
|
||||
return responseStr;
|
||||
}
|
||||
|
||||
public static String doPost(String url, Map<String, Object> headers, Map<String, Object> querys) throws Exception {
|
||||
FormBody.Builder formbody = new FormBody.Builder();
|
||||
if (null != querys) {
|
||||
Iterator iterator = querys.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, String> elem = (Map.Entry) iterator.next();
|
||||
formbody.add((String) elem.getKey(), (String) elem.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
RequestBody body = formbody.build();
|
||||
Request.Builder requestBuilder = (new Request.Builder()).url(url);
|
||||
if (headers != null && headers.size() > 0) {
|
||||
Iterator iteratorHeader = headers.keySet().iterator();
|
||||
while (iteratorHeader.hasNext()) {
|
||||
String key = (String) iteratorHeader.next();
|
||||
requestBuilder.addHeader(key, (String) headers.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
Request requet = requestBuilder.post(body).build();
|
||||
Response response = client.newCall(requet).execute();
|
||||
String responseStr = response.body() == null ? "" : response.body().string();
|
||||
return responseStr;
|
||||
}
|
||||
|
||||
public static String doPost(String url, Map<String, String> headers, String sendMessage) throws Exception {
|
||||
|
||||
RequestBody body = FormBody.create(MediaType.parse("application/json"), sendMessage);
|
||||
;
|
||||
Request.Builder requestBuilder = (new Request.Builder()).url(url);
|
||||
if (headers != null && headers.size() > 0) {
|
||||
Iterator iteratorHeader = headers.keySet().iterator();
|
||||
while (iteratorHeader.hasNext()) {
|
||||
String key = (String) iteratorHeader.next();
|
||||
requestBuilder.addHeader(key, (String) headers.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
Request requet = requestBuilder.post(body).build();
|
||||
Response response = client.newCall(requet).execute();
|
||||
String responseStr = response.body() == null ? "" : response.body().string();
|
||||
return responseStr;
|
||||
}
|
||||
|
||||
public static String doPut(String host, String path, Map<String, String> headers, Map<String, String> querys) throws Exception {
|
||||
FormBody.Builder builder = new FormBody.Builder();
|
||||
Iterator iterator = querys.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, String> elem = (Map.Entry) iterator.next();
|
||||
builder.add((String) elem.getKey(), (String) elem.getValue());
|
||||
}
|
||||
|
||||
RequestBody body = builder.build();
|
||||
Request.Builder requestBuilder = (new Request.Builder()).url(host + path);
|
||||
if (headers != null && headers.size() > 0) {
|
||||
Iterator iteratorHeader = headers.keySet().iterator();
|
||||
while (iteratorHeader.hasNext()) {
|
||||
String key = (String) iteratorHeader.next();
|
||||
requestBuilder.addHeader(key, (String) headers.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
Request requet = requestBuilder.put(body).build();
|
||||
Response response = client.newCall(requet).execute();
|
||||
String responseStr = response.body() == null ? "" : response.body().string();
|
||||
return responseStr;
|
||||
}
|
||||
}
|
322
src/main/java/io/qyi/e5/util/netRequest/OkHttpRequestUtils.java
Normal file
322
src/main/java/io/qyi/e5/util/netRequest/OkHttpRequestUtils.java
Normal file
@ -0,0 +1,322 @@
|
||||
package io.qyi.e5.util.netRequest;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import okhttp3.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 封装请求
|
||||
*
|
||||
* @author weiximei
|
||||
*/
|
||||
public class OkHttpRequestUtils {
|
||||
|
||||
/**
|
||||
* 定义请求客户端
|
||||
*/
|
||||
private static OkHttpClient client = new OkHttpClient();
|
||||
|
||||
/**
|
||||
* get 请求
|
||||
*
|
||||
* @param url 请求URL
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String doGet(String url) throws Exception {
|
||||
return doGet(url, Maps.newHashMap());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get 请求
|
||||
*
|
||||
* @param url 请求URL
|
||||
* @param query 携带参数参数
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String doGet(String url, Map<String, Object> query) throws Exception {
|
||||
|
||||
return doGet(url, Maps.newHashMap(), query);
|
||||
}
|
||||
|
||||
/**
|
||||
* get 请求
|
||||
*
|
||||
* @param url url
|
||||
* @param header 请求头参数
|
||||
* @param query 参数
|
||||
* @return
|
||||
*/
|
||||
public static String doGet(String url, Map<String, Object> header, Map<String, Object> query) throws Exception {
|
||||
|
||||
// 创建一个请求 Builder
|
||||
Request.Builder builder = new Request.Builder();
|
||||
// 创建一个 request
|
||||
Request request = builder.url(url).build();
|
||||
|
||||
// 创建一个 HttpUrl.Builder
|
||||
HttpUrl.Builder urlBuilder = request.url().newBuilder();
|
||||
// 创建一个 Headers.Builder
|
||||
Headers.Builder headerBuilder = request.headers().newBuilder();
|
||||
|
||||
// 装载请求头参数
|
||||
if (header != null) {
|
||||
Iterator<Map.Entry<String, Object>> headerIterator = header.entrySet().iterator();
|
||||
headerIterator.forEachRemaining(e -> {
|
||||
headerBuilder.add(e.getKey(), (String) e.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
if (query != null) {
|
||||
// 装载请求的参数
|
||||
Iterator<Map.Entry<String, Object>> queryIterator = query.entrySet().iterator();
|
||||
queryIterator.forEachRemaining(e -> urlBuilder.addQueryParameter(e.getKey(), (String) e.getValue()));
|
||||
}
|
||||
// 设置自定义的 builder
|
||||
// 因为 get 请求的参数,是在 URL 后面追加 http://xxxx:8080/user?name=xxxx?sex=1
|
||||
builder.url(urlBuilder.build()).headers(headerBuilder.build());
|
||||
|
||||
try (Response execute = client.newCall(builder.build()).execute()) {
|
||||
return execute.body().string();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* post 请求, 请求参数 并且 携带文件上传
|
||||
*
|
||||
* @param url
|
||||
* @param header
|
||||
* @param parameter
|
||||
* @param file 文件
|
||||
* @param fileFormName 远程接口接收 file 的参数
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String doPost(String url, Map<String, Object> header, Map<String, Object> parameter, File file, String fileFormName) throws Exception {
|
||||
|
||||
// 创建一个请求 Builder
|
||||
Request.Builder builder = new Request.Builder();
|
||||
// 创建一个 request
|
||||
Request request = builder.url(url).build();
|
||||
|
||||
// 创建一个 Headers.Builder
|
||||
Headers.Builder headerBuilder = request.headers().newBuilder();
|
||||
|
||||
// 装载请求头参数
|
||||
Iterator<Map.Entry<String, Object>> headerIterator = header.entrySet().iterator();
|
||||
headerIterator.forEachRemaining(e -> headerBuilder.add(e.getKey(), (String) e.getValue()));
|
||||
|
||||
// 或者 FormBody.create 方式,只适用于接口只接收文件流的情况
|
||||
// RequestBody requestBody = FormBody.create(MediaType.parse("application/octet-stream"), file);
|
||||
MultipartBody.Builder requestBuilder = new MultipartBody.Builder();
|
||||
|
||||
// 状态请求参数
|
||||
Iterator<Map.Entry<String, Object>> queryIterator = parameter.entrySet().iterator();
|
||||
queryIterator.forEachRemaining(e -> requestBuilder.addFormDataPart(e.getKey(), (String) e.getValue()));
|
||||
|
||||
if (null != file) {
|
||||
// application/octet-stream
|
||||
requestBuilder.addFormDataPart(StringUtils.isNotBlank(fileFormName) ? fileFormName : "file", file.getName(), RequestBody.create(MediaType.parse("application/octet-stream"), file));
|
||||
}
|
||||
|
||||
// 设置自定义的 builder
|
||||
builder.headers(headerBuilder.build()).post(requestBuilder.build());
|
||||
|
||||
// 然后再 build 一下
|
||||
try (Response execute = client.newCall(builder.build()).execute()) {
|
||||
return execute.body().string();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* post 请求, 请求参数
|
||||
*
|
||||
* @param url
|
||||
* @param header
|
||||
* @param parameter
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String doPostFrom(String url, Map<String, Object> header, Map<String, Object> parameter) throws Exception {
|
||||
|
||||
// 创建一个请求 Builder
|
||||
Request.Builder builder = new Request.Builder();
|
||||
// 创建一个 request
|
||||
Request request = builder.url(url).build();
|
||||
|
||||
// 创建一个 Headers.Builder
|
||||
Headers.Builder headerBuilder = request.headers().newBuilder();
|
||||
|
||||
// 装载请求头参数
|
||||
Iterator<Map.Entry<String, Object>> headerIterator = header.entrySet().iterator();
|
||||
headerIterator.forEachRemaining(e -> headerBuilder.add(e.getKey(), (String) e.getValue()));
|
||||
|
||||
// 或者 FormBody.create 方式,只适用于接口只接收文件流的情况
|
||||
// RequestBody requestBody = FormBody.create(MediaType.parse("application/octet-stream"), file);
|
||||
FormBody.Builder FormBody = new FormBody.Builder();
|
||||
|
||||
// 状态请求参数
|
||||
Iterator<Map.Entry<String, Object>> queryIterator = parameter.entrySet().iterator();
|
||||
queryIterator.forEachRemaining(e -> FormBody.add(e.getKey(), (String) e.getValue()));
|
||||
|
||||
|
||||
// 设置自定义的 builder
|
||||
builder.headers(headerBuilder.build()).post(FormBody.build());
|
||||
|
||||
// 然后再 build 一下
|
||||
try (Response execute = client.newCall(builder.build()).execute()) {
|
||||
return execute.body().string();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* post 请求, 请求参数 并且 携带文件上传二进制流
|
||||
*
|
||||
* @param url
|
||||
* @param header
|
||||
* @param parameter
|
||||
* @param fileName 文件名
|
||||
* @param fileByte 文件的二进制流
|
||||
* @param fileFormName 远程接口接收 file 的参数
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String doPost(String url, Map<String, Object> header, Map<String, Object> parameter, String fileName, byte[] fileByte, String fileFormName) throws Exception {
|
||||
// 创建一个请求 Builder
|
||||
Request.Builder builder = new Request.Builder();
|
||||
// 创建一个 request
|
||||
Request request = builder.url(url).build();
|
||||
|
||||
// 创建一个 Headers.Builder
|
||||
Headers.Builder headerBuilder = request.headers().newBuilder();
|
||||
|
||||
// 装载请求头参数
|
||||
Iterator<Map.Entry<String, Object>> headerIterator = header.entrySet().iterator();
|
||||
headerIterator.forEachRemaining(e -> {
|
||||
headerBuilder.add(e.getKey(), (String) e.getValue());
|
||||
});
|
||||
|
||||
MultipartBody.Builder requestBuilder = new MultipartBody.Builder();
|
||||
|
||||
// 状态请求参数
|
||||
Iterator<Map.Entry<String, Object>> queryIterator = parameter.entrySet().iterator();
|
||||
queryIterator.forEachRemaining(e -> {
|
||||
requestBuilder.addFormDataPart(e.getKey(), (String) e.getValue());
|
||||
});
|
||||
|
||||
if (fileByte.length > 0) {
|
||||
// application/octet-stream
|
||||
requestBuilder.addFormDataPart(StringUtils.isNotBlank(fileFormName) ? fileFormName : "file", fileName, RequestBody.create(MediaType.parse("application/octet-stream"), fileByte));
|
||||
}
|
||||
|
||||
// 设置自定义的 builder
|
||||
builder.headers(headerBuilder.build()).post(requestBuilder.build());
|
||||
|
||||
try (Response execute = client.newCall(builder.build()).execute()) {
|
||||
return execute.body().string();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* post 请求 携带文件上传
|
||||
*
|
||||
* @param url
|
||||
* @param file
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String doPost(String url, File file, String fileFormName) throws Exception {
|
||||
return doPost(url, Maps.newHashMap(), Maps.newHashMap(), file, fileFormName);
|
||||
}
|
||||
|
||||
/**
|
||||
* post 请求
|
||||
*
|
||||
* @param url
|
||||
* @param header 请求头
|
||||
* @param parameter 参数
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String doPost(String url, Map<String, Object> header, Map<String, Object> parameter) throws Exception {
|
||||
return doPostFrom(url, header, parameter);
|
||||
}
|
||||
|
||||
/**
|
||||
* post 请求
|
||||
*
|
||||
* @param url
|
||||
* @param parameter 参数
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String doPost(String url, Map<String, Object> parameter) throws Exception {
|
||||
return doPost(url, Maps.newHashMap(), parameter, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON数据格式请求
|
||||
*
|
||||
* @param url
|
||||
* @param header
|
||||
* @param json
|
||||
* @return
|
||||
*/
|
||||
private static String json(String url, Map<String, Object> header, String json) throws IOException {
|
||||
// 创建一个请求 Builder
|
||||
Request.Builder builder = new Request.Builder();
|
||||
// 创建一个 request
|
||||
Request request = builder.url(url).build();
|
||||
|
||||
// 创建一个 Headers.Builder
|
||||
Headers.Builder headerBuilder = request.headers().newBuilder();
|
||||
|
||||
// 装载请求头参数
|
||||
Iterator<Map.Entry<String, Object>> headerIterator = header.entrySet().iterator();
|
||||
headerIterator.forEachRemaining(e -> {
|
||||
headerBuilder.add(e.getKey(), (String) e.getValue());
|
||||
});
|
||||
|
||||
// application/octet-stream
|
||||
RequestBody requestBody = FormBody.create(MediaType.parse("application/json"), json);
|
||||
|
||||
// 设置自定义的 builder
|
||||
builder.headers(headerBuilder.build()).post(requestBody);
|
||||
|
||||
try (Response execute = client.newCall(builder.build()).execute()) {
|
||||
return execute.body().string();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* post请求 参数JSON格式
|
||||
*
|
||||
* @param url
|
||||
* @param header 请求头
|
||||
* @param json JSON数据
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String doPost(String url, Map<String, Object> header, String json) throws IOException {
|
||||
return json(url, header, json);
|
||||
}
|
||||
|
||||
/**
|
||||
* post请求 参数JSON格式
|
||||
*
|
||||
* @param url
|
||||
* @param json JSON数据
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String doPost(String url, String json) throws IOException {
|
||||
return json(url, Maps.newHashMap(), json);
|
||||
}
|
||||
}
|
592
src/main/java/io/qyi/e5/util/redis/RedisUtil.java
Normal file
592
src/main/java/io/qyi/e5/util/redis/RedisUtil.java
Normal file
@ -0,0 +1,592 @@
|
||||
package io.qyi.e5.util.redis;
|
||||
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @program: msgpush
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-02-04 00:31
|
||||
**/
|
||||
@Component
|
||||
public class RedisUtil {
|
||||
@Resource
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
public Set<String> keys(String keys) {
|
||||
try {
|
||||
return redisTemplate.keys(keys);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定缓存失效时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean expire(String key, long time) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.expire(key, time, TimeUnit.SECONDS);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据key 获取过期时间
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @return 时间(秒) 返回0代表为永久有效
|
||||
*/
|
||||
public long getExpire(String key) {
|
||||
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断key是否存在
|
||||
*
|
||||
* @param key 键
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean hasKey(String key) {
|
||||
try {
|
||||
return redisTemplate.hasKey(key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
*
|
||||
* @param key 可以传一个值 或多个
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void del(String... key) {
|
||||
if (key != null && key.length > 0) {
|
||||
if (key.length == 1) {
|
||||
redisTemplate.delete(key[0]);
|
||||
} else {
|
||||
redisTemplate.delete(CollectionUtils.arrayToList(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存获取
|
||||
*
|
||||
* @param key 键
|
||||
* @return 值
|
||||
*/
|
||||
public Object get(String key) {
|
||||
return key == null ? null : redisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存放入
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return true成功 false失败
|
||||
*/
|
||||
public boolean set(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存放入并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
|
||||
* @return true成功 false 失败
|
||||
*/
|
||||
public boolean set(String key, Object value, long time) {
|
||||
try {
|
||||
if (time > 0) {
|
||||
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
||||
} else {
|
||||
set(key, value);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递增
|
||||
*
|
||||
* @param key 键
|
||||
* @param delta 要增加几(大于0)
|
||||
* @return
|
||||
*/
|
||||
public long incr(String key, long delta) {
|
||||
if (delta < 0) {
|
||||
throw new RuntimeException("递增因子必须大于0");
|
||||
}
|
||||
return redisTemplate.opsForValue().increment(key, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递减
|
||||
*
|
||||
* @param key 键
|
||||
* @param delta 要减少几(小于0)
|
||||
* @return
|
||||
*/
|
||||
public long decr(String key, long delta) {
|
||||
if (delta < 0) {
|
||||
throw new RuntimeException("递减因子必须大于0");
|
||||
}
|
||||
return redisTemplate.opsForValue().increment(key, -delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* HashGet
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 不能为null
|
||||
* @return 值
|
||||
*/
|
||||
public Object hget(String key, String item) {
|
||||
return redisTemplate.opsForHash().get(key, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取hashKey对应的所有键值
|
||||
*
|
||||
* @param key 键
|
||||
* @return 对应的多个键值
|
||||
*/
|
||||
public Map<Object, Object> hmget(String key) {
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* HashSet
|
||||
*
|
||||
* @param key 键
|
||||
* @param map 对应多个键值
|
||||
* @return true 成功 false 失败
|
||||
*/
|
||||
public boolean hmset(String key, Map<String, Object> map) {
|
||||
try {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HashSet 并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param map 对应多个键值
|
||||
* @param time 时间(秒)
|
||||
* @return true成功 false失败
|
||||
*/
|
||||
public boolean hmset(String key, Map<String, Object> map, long time) {
|
||||
try {
|
||||
redisTemplate.opsForHash().putAll(key, map);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向一张hash表中放入数据,如果不存在将创建
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param value 值
|
||||
* @return true 成功 false失败
|
||||
*/
|
||||
public boolean hset(String key, String item, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, item, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向一张hash表中放入数据,如果不存在将创建
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param value 值
|
||||
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
|
||||
* @return true 成功 false失败
|
||||
*/
|
||||
public boolean hset(String key, String item, Object value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, item, value);
|
||||
if (time > 0) {
|
||||
expire(key, time);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除hash表中的值
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 可以使多个 不能为null
|
||||
*/
|
||||
public void hdel(String key, Object... item) {
|
||||
redisTemplate.opsForHash().delete(key, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断hash表中是否有该项的值
|
||||
*
|
||||
* @param key 键 不能为null
|
||||
* @param item 项 不能为null
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean hHasKey(String key, String item) {
|
||||
return redisTemplate.opsForHash().hasKey(key, item);
|
||||
}
|
||||
|
||||
/**
|
||||
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param by 要增加几(大于0)
|
||||
* @return
|
||||
*/
|
||||
public double hincr(String key, String item, double by) {
|
||||
return redisTemplate.opsForHash().increment(key, item, by);
|
||||
}
|
||||
|
||||
/**
|
||||
* hash递减
|
||||
*
|
||||
* @param key 键
|
||||
* @param item 项
|
||||
* @param by 要减少记(小于0)
|
||||
* @return
|
||||
*/
|
||||
public double hdecr(String key, String item, double by) {
|
||||
return redisTemplate.opsForHash().increment(key, item, -by);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据key获取Set中的所有值
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public Set<Object> sGet(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().members(key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据value从一个set中查询,是否存在
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return true 存在 false不存在
|
||||
*/
|
||||
public boolean sHasKey(String key, Object value) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().isMember(key, value);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据放入set缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param values 值 可以是多个
|
||||
* @return 成功个数
|
||||
*/
|
||||
public long sSet(String key, Object... values) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().add(key, values);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将set数据放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param time 时间(秒)
|
||||
* @param values 值 可以是多个
|
||||
* @return 成功个数
|
||||
*/
|
||||
public long sSetAndTime(String key, long time, Object... values) {
|
||||
try {
|
||||
Long count = redisTemplate.opsForSet().add(key, values);
|
||||
if (time > 0)
|
||||
expire(key, time);
|
||||
return count;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取set缓存的长度
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public long sGetSetSize(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForSet().size(key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除值为value的
|
||||
*
|
||||
* @param key 键
|
||||
* @param values 值 可以是多个
|
||||
* @return 移除的个数
|
||||
*/
|
||||
public long setRemove(String key, Object... values) {
|
||||
try {
|
||||
Long count = redisTemplate.opsForSet().remove(key, values);
|
||||
return count;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// ===============================list=================================
|
||||
|
||||
/**
|
||||
* 获取list缓存的内容
|
||||
*
|
||||
* @param key 键
|
||||
* @param start 开始
|
||||
* @param end 结束 0 到 -1代表所有值
|
||||
* @return
|
||||
*/
|
||||
public List<Object> lGet(String key, long start, long end) {
|
||||
try {
|
||||
return redisTemplate.opsForList().range(key, start, end);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取list缓存的长度
|
||||
*
|
||||
* @param key 键
|
||||
* @return
|
||||
*/
|
||||
public long lGetListSize(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForList().size(key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过索引 获取list中的值
|
||||
*
|
||||
* @param key 键
|
||||
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
|
||||
* @return
|
||||
*/
|
||||
public Object lGetIndex(String key, long index) {
|
||||
try {
|
||||
return redisTemplate.opsForList().index(key, index);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPush(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, Object value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPush(key, value);
|
||||
if (time > 0)
|
||||
expire(key, time);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, List<Object> value) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPushAll(key, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list放入缓存
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(秒)
|
||||
* @return
|
||||
*/
|
||||
public boolean lSet(String key, List<Object> value, long time) {
|
||||
try {
|
||||
redisTemplate.opsForList().rightPushAll(key, value);
|
||||
if (time > 0)
|
||||
expire(key, time);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据索引修改list中的某条数据
|
||||
*
|
||||
* @param key 键
|
||||
* @param index 索引
|
||||
* @param value 值
|
||||
* @return
|
||||
*/
|
||||
public boolean lUpdateIndex(String key, long index, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForList().set(key, index, value);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除N个值为value
|
||||
*
|
||||
* @param key 键
|
||||
* @param count 移除多少个
|
||||
* @param value 值
|
||||
* @return 移除的个数
|
||||
*/
|
||||
public long lRemove(String key, long count, Object value) {
|
||||
try {
|
||||
Long remove = redisTemplate.opsForList().remove(key, count, value);
|
||||
return remove;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @title lRemove
|
||||
* @description
|
||||
* @author 落叶随风
|
||||
* @param: key
|
||||
* @param: count
|
||||
* @param: value
|
||||
* @updateTime 2020/2/4 14:59
|
||||
* @return: long
|
||||
* @throws
|
||||
*/
|
||||
public boolean lTrim(String key, long start, long end) {
|
||||
try {
|
||||
redisTemplate.opsForList().trim(key,start,end);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
100
src/main/resources/log4j2.xml
Normal file
100
src/main/resources/log4j2.xml
Normal file
@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--设置log4j2的自身log级别为warn-->
|
||||
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
|
||||
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,
|
||||
当设置成trace时,会看到log4j2内部各种详细输出-->
|
||||
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
|
||||
<configuration status="DEBUG" monitorInterval="5">
|
||||
<Properties>
|
||||
<!-- 日志模板 -->
|
||||
<Property name="log_pattern" value="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
|
||||
<!-- 存储日志文件路径 -->
|
||||
<Property name="file_path" value="logs/log"/>
|
||||
<!-- 日志文件的最大容量,超过该值就进行备份 -->
|
||||
<Property name="file_max_size" value="30MB"/>
|
||||
<!-- 备份的文件夹名称 -->
|
||||
<Property name="backup_folder" value="$${date:yyyy-MM}"/>
|
||||
<!-- 备份文件的后缀 -->
|
||||
<Property name="backup_file_suffix" value="-%d{yyyy-MM-dd}-%i.log"/>
|
||||
</Properties>
|
||||
|
||||
<!--定义appender-->
|
||||
<appenders>
|
||||
|
||||
<!--控制台的输出配置-->
|
||||
<console name="Console" target="SYSTEM_OUT">
|
||||
<!--输出日志的格式-->
|
||||
<PatternLayout pattern="${log_pattern}"/>
|
||||
</console>
|
||||
|
||||
<!-- 所有级别的日志会存入该文件,当append属性设置为false时,每次启动程序会自动清空 -->
|
||||
<File name="AllLog" fileName="${file_path}/all_log.log" append="false">
|
||||
<!-- <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> -->
|
||||
<PatternLayout pattern="${log_pattern}"/>
|
||||
</File>
|
||||
|
||||
<!--
|
||||
该RollingFile存储INFO级别的日志,
|
||||
默认存储到 fileName 文件中
|
||||
超过SizeBasedTriggeringPolicy的设定值,则存储到 filePattern 文件中
|
||||
-->
|
||||
<RollingFile name="RollingFileInfo" fileName="${file_path}/info.log"
|
||||
filePattern="${file_path}/${backup_folder}/info${backup_file_suffix}">
|
||||
<Filters>
|
||||
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
|
||||
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
|
||||
</Filters>
|
||||
<!-- 写入日志文件的模板 -->
|
||||
<PatternLayout pattern="${log_pattern}"/>
|
||||
<Policies>
|
||||
<TimeBasedTriggeringPolicy/>
|
||||
<SizeBasedTriggeringPolicy size="${file_max_size}"/>
|
||||
</Policies>
|
||||
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,超过该数量,会滚动删除前面的记录 -->
|
||||
<DefaultRolloverStrategy max="20"/>
|
||||
</RollingFile>
|
||||
|
||||
<RollingFile name="RollingFileWarn" fileName="${file_path}/warn.log"
|
||||
filePattern="${file_path}/${backup_folder}/warn${backup_file_suffix}">
|
||||
<Filters>
|
||||
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
<ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
|
||||
</Filters>
|
||||
<PatternLayout pattern="${log_pattern}"/>
|
||||
<Policies>
|
||||
<TimeBasedTriggeringPolicy/>
|
||||
<SizeBasedTriggeringPolicy size="${file_max_size}"/>
|
||||
</Policies>
|
||||
</RollingFile>
|
||||
|
||||
<RollingFile name="RollingFileError" fileName="${file_path}/error.log"
|
||||
filePattern="${file_path}/${backup_folder}/error${backup_file_suffix}">
|
||||
<ThresholdFilter level="ERROR"/>
|
||||
<PatternLayout pattern="${log_pattern}"/>
|
||||
<Policies>
|
||||
<TimeBasedTriggeringPolicy/>
|
||||
<SizeBasedTriggeringPolicy size="${file_max_size}"/>
|
||||
</Policies>
|
||||
</RollingFile>
|
||||
|
||||
</appenders>
|
||||
|
||||
<!-- 只有定义了logger并使用appender-ref,appender才会生效 -->
|
||||
<loggers>
|
||||
<!--过滤掉spring和hibernate的一些无用的debug信息-->
|
||||
<logger name="org.springframework" level="INFO"/>
|
||||
<logger name="org.mybatis" level="INFO">
|
||||
<!-- 添加如下设置,控制台会再打印一次 -->
|
||||
<AppenderRef ref="Console"/>
|
||||
</logger>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="Console"/>
|
||||
<appender-ref ref="RollingFileInfo"/>
|
||||
<appender-ref ref="RollingFileWarn"/>
|
||||
<appender-ref ref="RollingFileError"/>
|
||||
<appender-ref ref="AllLog"/>
|
||||
</root>
|
||||
</loggers>
|
||||
|
||||
</configuration>
|
5
src/main/resources/mapper/github/GithubMapper.xml
Normal file
5
src/main/resources/mapper/github/GithubMapper.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.qyi.e5.github.mapper.GithubMapper">
|
||||
|
||||
</mapper>
|
5
src/main/resources/mapper/outlook/OutlookMapper.xml
Normal file
5
src/main/resources/mapper/outlook/OutlookMapper.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.qyi.e5.outlook.mapper.OutlookMapper">
|
||||
|
||||
</mapper>
|
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.qyi.e5.outlook_log.mapper.OutlookLogMapper">
|
||||
|
||||
</mapper>
|
5
src/main/resources/mapper/user/PermissionMapper.xml
Normal file
5
src/main/resources/mapper/user/PermissionMapper.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.qyi.e5.user.mapper.PermissionMapper">
|
||||
|
||||
</mapper>
|
5
src/main/resources/mapper/user/RoleMapper.xml
Normal file
5
src/main/resources/mapper/user/RoleMapper.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.qyi.e5.user.mapper.RoleMapper">
|
||||
|
||||
</mapper>
|
5
src/main/resources/mapper/user/UserMapper.xml
Normal file
5
src/main/resources/mapper/user/UserMapper.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.qyi.e5.user.mapper.UserMapper">
|
||||
|
||||
</mapper>
|
21
src/main/resources/quartz.properties
Normal file
21
src/main/resources/quartz.properties
Normal file
@ -0,0 +1,21 @@
|
||||
#org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
|
||||
#org.quartz.jobStore.tablePrefix = QRTZ_
|
||||
#org.quartz.scheduler.instanceName = MyScheduler
|
||||
#org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
|
||||
#org.quartz.jobStore.dataSource = mysqlDatabase
|
||||
#
|
||||
#org.quartz.dataSource.mysqlDatabase.driver = com.mysql.jdbc.Driver
|
||||
#org.quartz.dataSource.mysqlDatabase.URL = jdbc:mysql://localhost:3306/e5?characterEncoding=utf-8
|
||||
#org.quartz.dataSource.mysqlDatabase.user = root
|
||||
#org.quartz.dataSource.mysqlDatabase.password = 123456
|
||||
#org.quartz.dataSource.mysqlDatabase.maxConnections = 10
|
||||
#
|
||||
#
|
||||
#Ï̳߳ØÅäÖÃ
|
||||
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
|
||||
org.quartz.threadPool.threadCount = 10
|
||||
org.quartz.threadPool.threadPriority = 5
|
||||
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
|
||||
#
|
||||
##³Ö¾Ã»¯ÅäÖÃ
|
||||
#org.quartz.jobStore.misfireThreshold = 50000
|
835
src/main/resources/static/error/4xx.html
Normal file
835
src/main/resources/static/error/4xx.html
Normal file
@ -0,0 +1,835 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>404</title>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display:block;
|
||||
margin: 50px auto 200px;
|
||||
margin-left: 300px;
|
||||
border: 1px solid #333;
|
||||
box-shadow: 0 0 16px 2px rgba(0,0,0,0.8);
|
||||
}
|
||||
|
||||
p, a {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 20px;
|
||||
color: #777;
|
||||
display: block;
|
||||
width: 400px;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin:50px auto;
|
||||
text-align: justify;
|
||||
font-size: 20px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
a {
|
||||
color:#3377ee;
|
||||
}
|
||||
#info{
|
||||
position: absolute;
|
||||
z-index: 55;
|
||||
width: 400px;
|
||||
right: 100px;
|
||||
top: 200px;
|
||||
}
|
||||
/* TENTH BUTTON */
|
||||
|
||||
#tenth>button{
|
||||
letter-spacing:0;
|
||||
}
|
||||
|
||||
#tenth span{
|
||||
letter-spacing:0;
|
||||
display:inline-block;
|
||||
position:relative;
|
||||
width:8px;
|
||||
transition:all .5s ease-in-out;
|
||||
}
|
||||
|
||||
#tenth span:nth-of-type(4){
|
||||
width:5px;
|
||||
}
|
||||
|
||||
#tenth span:nth-of-type(6){
|
||||
width:1px;
|
||||
}
|
||||
|
||||
#tenth span:nth-of-type(8){
|
||||
width:4px;
|
||||
}
|
||||
|
||||
#tenth:hover span:nth-of-type(1){
|
||||
animation:h .5s;
|
||||
}
|
||||
|
||||
#tenth:hover span:nth-of-type(2){
|
||||
animation:o .5s;
|
||||
}
|
||||
|
||||
#tenth:hover span:nth-of-type(3){
|
||||
animation:v .5s;
|
||||
}
|
||||
|
||||
#tenth:hover span:nth-of-type(4){
|
||||
animation:e .5s;
|
||||
}
|
||||
|
||||
#tenth:hover span:nth-of-type(5){
|
||||
animation:r .5s;
|
||||
}
|
||||
|
||||
#tenth:hover span:nth-of-type(7){
|
||||
animation:t .5s;
|
||||
}
|
||||
|
||||
#tenth:hover span:nth-of-type(8){
|
||||
animation:e .5s;
|
||||
}
|
||||
|
||||
#tenth:hover span:nth-of-type(9){
|
||||
animation:n .5s;
|
||||
}
|
||||
|
||||
@keyframes h{
|
||||
0%{transform:translate(0, 0);}
|
||||
50%{transform:translate(50px, 5px);}
|
||||
75%{transform:translate(5px, 5px);}
|
||||
80%{transform:translate(0, 0);}
|
||||
100%{transform:translate(0, 0);}
|
||||
}
|
||||
|
||||
@keyframes o{
|
||||
0%{transform:translate(0, 0);}
|
||||
25%{transform:translate(-4px, 0);}
|
||||
50%{transform:translate(3px, 4px);}
|
||||
80%{transform:translate(0, 0);}
|
||||
100%{transform:translate(0, 0);}
|
||||
}
|
||||
|
||||
@keyframes v{
|
||||
0%{transform:translate(0, 0);}
|
||||
20%{transform:rotate(360deg);}
|
||||
50%{transform:scale(2);}
|
||||
80%{transform:translate(0, 0);}
|
||||
100%{transform:translate(0, 0);}
|
||||
}
|
||||
|
||||
@keyframes e{
|
||||
0%{transform:translate(0, 0);}
|
||||
20%{transform:translate(-10px, -2px);}
|
||||
80%{transform:translate(0, 0);}
|
||||
100%{transform:translate(0, 0);}
|
||||
}
|
||||
|
||||
@keyframes r{
|
||||
0%{transform:translate(0, 0);}
|
||||
20%{transform:translate(0, 10px);}
|
||||
80%{transform:translate(0, 32px);}
|
||||
100%{transform:translate(0, 0);}
|
||||
}
|
||||
|
||||
@keyframes t{
|
||||
0%{transform:translate(0, 0);}
|
||||
20%{transform:translate(0, -10px);}
|
||||
40%{transform:translate(0, 0);}
|
||||
60%{transform:translate(0, -10px);}
|
||||
80%{transform:translate(0, 0);}
|
||||
100%{transform:translate(0, 0);}
|
||||
}
|
||||
|
||||
@keyframes n{
|
||||
0%{transform:translate(0, 0);}
|
||||
50%{transform:skewY(50deg);}
|
||||
80%{transform:translate(0, 0);}
|
||||
100%{transform:translate(0, 0);}
|
||||
}
|
||||
button{
|
||||
position: absolute;
|
||||
right: 400px;
|
||||
top: 500px;
|
||||
z-index: 99;
|
||||
width:180px;
|
||||
height:60px;
|
||||
background:transparent;
|
||||
color:black;
|
||||
font-weight:700;
|
||||
letter-spacing:1px;
|
||||
border:none;
|
||||
font-size:18px;
|
||||
outline:none;
|
||||
cursor: pointer;
|
||||
} </style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<canvas id="canvas"></canvas>
|
||||
<div id="info">
|
||||
<p style="color: #333333;font-size: 100px;font-weight: 700;margin-bottom: 50px;">404</p>
|
||||
<p>没找到页面,倒有个小游戏可以先玩一哈。</p>
|
||||
<p class="info">使用左键、右键和上箭头键移动。</p>
|
||||
</div>
|
||||
|
||||
<div id="tenth" class="buttonBox">
|
||||
<button>
|
||||
<a href="/user/home">
|
||||
<span>返</span>
|
||||
<span> </span>
|
||||
|
||||
<span>回</span>
|
||||
<span> </span>
|
||||
|
||||
<span>首</span>
|
||||
<span> </span>
|
||||
|
||||
<span>页</span>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
<script>
|
||||
/* Customisable map data */
|
||||
|
||||
var map = {
|
||||
|
||||
tile_size: 16,
|
||||
|
||||
/*
|
||||
|
||||
Key vairables:
|
||||
|
||||
id [required] - an integer that corresponds with a tile in the data array.
|
||||
colour [required] - any javascript compatible colour variable.
|
||||
solid [optional] - whether the tile is solid or not, defaults to false.
|
||||
bounce [optional] - how much velocity is preserved upon hitting the tile, 0.5 is half.
|
||||
jump [optional] - whether the player can jump while over the tile, defaults to false.
|
||||
friction [optional] - friction of the tile, must have X and Y values (e.g {x:0.5, y:0.5}).
|
||||
gravity [optional] - gravity of the tile, must have X and Y values (e.g {x:0.5, y:0.5}).
|
||||
fore [optional] - whether the tile is drawn in front of the player, defaults to false.
|
||||
script [optional] - refers to a script in the scripts section, executed if it is touched.
|
||||
|
||||
*/
|
||||
|
||||
keys: [
|
||||
{id: 0, colour: '#333', solid: 0},
|
||||
{id: 1, colour: '#888', solid: 0},
|
||||
{id: 2,colour: '#555',solid: 1,bounce: 0.35},
|
||||
{id: 3,colour: 'rgba(121, 220, 242, 0.4)',friction: {x: 0.9,y: 0.9},gravity: {x: 0,y: 0.1},jump: 1,fore: 1},
|
||||
{id: 4,colour: '#777',jump: 1},
|
||||
{id: 5,colour: '#E373FA',solid: 1,bounce: 1.1},
|
||||
{id: 6,colour: '#666',solid: 1,bounce: 0},
|
||||
{id: 7,colour: '#73C6FA',solid: 0,script: 'change_colour'},
|
||||
{id: 8,colour: '#FADF73',solid: 0,script: 'next_level'},
|
||||
{id: 9,colour: '#C93232',solid: 0,script: 'death'},
|
||||
{id: 10,colour: '#555',solid: 1},
|
||||
{id: 11,colour: '#0FF',solid: 0,script: 'unlock'}
|
||||
],
|
||||
|
||||
/* An array representing the map tiles. Each number corresponds to a key */
|
||||
data: [
|
||||
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 6, 6, 6, 6, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 7, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 4, 2, 2, 2, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 1, 2, 2, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 2, 1, 2],
|
||||
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
|
||||
[2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2],
|
||||
[2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2],
|
||||
[2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2],
|
||||
[2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 8, 1, 1, 1, 2],
|
||||
[2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2],
|
||||
[2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 9, 9, 9, 2, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1, 1, 1, 11, 2, 2, 2, 2, 4, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2],
|
||||
[2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2],
|
||||
[2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
|
||||
[2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 5, 5, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2],
|
||||
[2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2],
|
||||
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
|
||||
],
|
||||
|
||||
/* Default gravity of the map */
|
||||
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: 0.3
|
||||
},
|
||||
|
||||
/* Velocity limits */
|
||||
|
||||
vel_limit: {
|
||||
x: 2,
|
||||
y: 16
|
||||
},
|
||||
|
||||
/* Movement speed when the key is pressed */
|
||||
|
||||
movement_speed: {
|
||||
jump: 6,
|
||||
left: 0.3,
|
||||
right: 0.3
|
||||
},
|
||||
|
||||
/* The coordinates at which the player spawns and the colour of the player */
|
||||
|
||||
player: {
|
||||
x: 2,
|
||||
y: 2,
|
||||
colour: '#FF9900'
|
||||
},
|
||||
|
||||
/* scripts refered to by the "script" variable in the tile keys */
|
||||
|
||||
scripts: {
|
||||
/* you can just use "this" instead of your engine variable ("game"), but Codepen doesn't like it */
|
||||
change_colour: 'game.player.colour = "#"+(Math.random()*0xFFFFFF<<0).toString(16);',
|
||||
/* you could load a new map variable here */
|
||||
next_level: 'alert("过关啦!");game.load_map(map);',
|
||||
death: 'alert("再来一次?");game.load_map(map);',
|
||||
unlock: 'game.current_map.keys[10].solid = 0;game.current_map.keys[10].colour = "#888";'
|
||||
}
|
||||
};
|
||||
|
||||
/* Clarity engine */
|
||||
|
||||
var Clarity = function () {
|
||||
|
||||
this.alert_errors = false;
|
||||
this.log_info = true;
|
||||
this.tile_size = 16;
|
||||
this.limit_viewport = false;
|
||||
this.jump_switch = 0;
|
||||
|
||||
this.viewport = {
|
||||
x: 200,
|
||||
y: 200
|
||||
};
|
||||
|
||||
this.camera = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
|
||||
this.key = {
|
||||
left: false,
|
||||
right: false,
|
||||
up: false
|
||||
};
|
||||
|
||||
this.player = {
|
||||
|
||||
loc: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
|
||||
vel: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
|
||||
can_jump: true
|
||||
};
|
||||
|
||||
window.onkeydown = this.keydown.bind(this);
|
||||
window.onkeyup = this.keyup.bind(this);
|
||||
};
|
||||
|
||||
Clarity.prototype.error = function (message) {
|
||||
|
||||
if (this.alert_errors) alert(message);
|
||||
if (this.log_info) console.log(message);
|
||||
};
|
||||
|
||||
Clarity.prototype.log = function (message) {
|
||||
|
||||
if (this.log_info) console.log(message);
|
||||
};
|
||||
|
||||
Clarity.prototype.set_viewport = function (x, y) {
|
||||
|
||||
this.viewport.x = x;
|
||||
this.viewport.y = y;
|
||||
};
|
||||
|
||||
Clarity.prototype.keydown = function (e) {
|
||||
|
||||
var _this = this;
|
||||
|
||||
switch (e.keyCode) {
|
||||
case 37:
|
||||
_this.key.left = true;
|
||||
break;
|
||||
case 38:
|
||||
_this.key.up = true;
|
||||
break;
|
||||
case 39:
|
||||
_this.key.right = true;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
Clarity.prototype.keyup = function (e) {
|
||||
|
||||
var _this = this;
|
||||
|
||||
switch (e.keyCode) {
|
||||
case 37:
|
||||
_this.key.left = false;
|
||||
break;
|
||||
case 38:
|
||||
_this.key.up = false;
|
||||
break;
|
||||
case 39:
|
||||
_this.key.right = false;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
Clarity.prototype.load_map = function (map) {
|
||||
|
||||
if (typeof map === 'undefined'
|
||||
|| typeof map.data === 'undefined'
|
||||
|| typeof map.keys === 'undefined') {
|
||||
|
||||
this.error('Error: Invalid map data!');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
this.current_map = map;
|
||||
|
||||
this.current_map.background = map.background || '#333';
|
||||
this.current_map.gravity = map.gravity || {x: 0, y: 0.3};
|
||||
this.tile_size = map.tile_size || 16;
|
||||
|
||||
var _this = this;
|
||||
|
||||
this.current_map.width = 0;
|
||||
this.current_map.height = 0;
|
||||
|
||||
map.keys.forEach(function (key) {
|
||||
|
||||
map.data.forEach(function (row, y) {
|
||||
|
||||
_this.current_map.height = Math.max(_this.current_map.height, y);
|
||||
|
||||
row.forEach(function (tile, x) {
|
||||
|
||||
_this.current_map.width = Math.max(_this.current_map.width, x);
|
||||
|
||||
if (tile == key.id)
|
||||
_this.current_map.data[y][x] = key;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
this.current_map.width_p = this.current_map.width * this.tile_size;
|
||||
this.current_map.height_p = this.current_map.height * this.tile_size;
|
||||
|
||||
this.player.loc.x = map.player.x * this.tile_size || 0;
|
||||
this.player.loc.y = map.player.y * this.tile_size || 0;
|
||||
this.player.colour = map.player.colour || '#000';
|
||||
|
||||
this.key.left = false;
|
||||
this.key.up = false;
|
||||
this.key.right = false;
|
||||
|
||||
this.camera = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
|
||||
this.player.vel = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
|
||||
this.log('Successfully loaded map data.');
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
Clarity.prototype.get_tile = function (x, y) {
|
||||
|
||||
return (this.current_map.data[y] && this.current_map.data[y][x]) ? this.current_map.data[y][x] : 0;
|
||||
};
|
||||
|
||||
Clarity.prototype.draw_tile = function (x, y, tile, context) {
|
||||
|
||||
if (!tile || !tile.colour) return;
|
||||
|
||||
context.fillStyle = tile.colour;
|
||||
context.fillRect(
|
||||
x,
|
||||
y,
|
||||
this.tile_size,
|
||||
this.tile_size
|
||||
);
|
||||
};
|
||||
|
||||
Clarity.prototype.draw_map = function (context, fore) {
|
||||
|
||||
for (var y = 0; y < this.current_map.data.length; y++) {
|
||||
|
||||
for (var x = 0; x < this.current_map.data[y].length; x++) {
|
||||
|
||||
if ((!fore && !this.current_map.data[y][x].fore) || (fore && this.current_map.data[y][x].fore)) {
|
||||
|
||||
var t_x = (x * this.tile_size) - this.camera.x;
|
||||
var t_y = (y * this.tile_size) - this.camera.y;
|
||||
|
||||
if(t_x < -this.tile_size
|
||||
|| t_y < -this.tile_size
|
||||
|| t_x > this.viewport.x
|
||||
|| t_y > this.viewport.y) continue;
|
||||
|
||||
this.draw_tile(
|
||||
t_x,
|
||||
t_y,
|
||||
this.current_map.data[y][x],
|
||||
context
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!fore) this.draw_map(context, true);
|
||||
};
|
||||
|
||||
Clarity.prototype.move_player = function () {
|
||||
|
||||
var tX = this.player.loc.x + this.player.vel.x;
|
||||
var tY = this.player.loc.y + this.player.vel.y;
|
||||
|
||||
var offset = Math.round((this.tile_size / 2) - 1);
|
||||
|
||||
var tile = this.get_tile(
|
||||
Math.round(this.player.loc.x / this.tile_size),
|
||||
Math.round(this.player.loc.y / this.tile_size)
|
||||
);
|
||||
|
||||
if(tile.gravity) {
|
||||
|
||||
this.player.vel.x += tile.gravity.x;
|
||||
this.player.vel.y += tile.gravity.y;
|
||||
|
||||
} else {
|
||||
|
||||
this.player.vel.x += this.current_map.gravity.x;
|
||||
this.player.vel.y += this.current_map.gravity.y;
|
||||
}
|
||||
|
||||
if (tile.friction) {
|
||||
|
||||
this.player.vel.x *= tile.friction.x;
|
||||
this.player.vel.y *= tile.friction.y;
|
||||
}
|
||||
|
||||
var t_y_up = Math.floor(tY / this.tile_size);
|
||||
var t_y_down = Math.ceil(tY / this.tile_size);
|
||||
var y_near1 = Math.round((this.player.loc.y - offset) / this.tile_size);
|
||||
var y_near2 = Math.round((this.player.loc.y + offset) / this.tile_size);
|
||||
|
||||
var t_x_left = Math.floor(tX / this.tile_size);
|
||||
var t_x_right = Math.ceil(tX / this.tile_size);
|
||||
var x_near1 = Math.round((this.player.loc.x - offset) / this.tile_size);
|
||||
var x_near2 = Math.round((this.player.loc.x + offset) / this.tile_size);
|
||||
|
||||
var top1 = this.get_tile(x_near1, t_y_up);
|
||||
var top2 = this.get_tile(x_near2, t_y_up);
|
||||
var bottom1 = this.get_tile(x_near1, t_y_down);
|
||||
var bottom2 = this.get_tile(x_near2, t_y_down);
|
||||
var left1 = this.get_tile(t_x_left, y_near1);
|
||||
var left2 = this.get_tile(t_x_left, y_near2);
|
||||
var right1 = this.get_tile(t_x_right, y_near1);
|
||||
var right2 = this.get_tile(t_x_right, y_near2); if (tile.jump && this.jump_switch > 15) {
|
||||
|
||||
this.player.can_jump = true;
|
||||
|
||||
this.jump_switch = 0;
|
||||
|
||||
} else this.jump_switch++;
|
||||
|
||||
this.player.vel.x = Math.min(Math.max(this.player.vel.x, -this.current_map.vel_limit.x), this.current_map.vel_limit.x);
|
||||
this.player.vel.y = Math.min(Math.max(this.player.vel.y, -this.current_map.vel_limit.y), this.current_map.vel_limit.y);
|
||||
|
||||
this.player.loc.x += this.player.vel.x;
|
||||
this.player.loc.y += this.player.vel.y;
|
||||
|
||||
this.player.vel.x *= .9;
|
||||
|
||||
if (left1.solid || left2.solid || right1.solid || right2.solid) {
|
||||
|
||||
/* fix overlap */
|
||||
|
||||
while (this.get_tile(Math.floor(this.player.loc.x / this.tile_size), y_near1).solid
|
||||
|| this.get_tile(Math.floor(this.player.loc.x / this.tile_size), y_near2).solid)
|
||||
this.player.loc.x += 0.1;
|
||||
|
||||
while (this.get_tile(Math.ceil(this.player.loc.x / this.tile_size), y_near1).solid
|
||||
|| this.get_tile(Math.ceil(this.player.loc.x / this.tile_size), y_near2).solid)
|
||||
this.player.loc.x -= 0.1;
|
||||
|
||||
/* tile bounce */
|
||||
|
||||
var bounce = 0;
|
||||
|
||||
if (left1.solid && left1.bounce > bounce) bounce = left1.bounce;
|
||||
if (left2.solid && left2.bounce > bounce) bounce = left2.bounce;
|
||||
if (right1.solid && right1.bounce > bounce) bounce = right1.bounce;
|
||||
if (right2.solid && right2.bounce > bounce) bounce = right2.bounce;
|
||||
|
||||
this.player.vel.x *= -bounce || 0;
|
||||
|
||||
}
|
||||
|
||||
if (top1.solid || top2.solid || bottom1.solid || bottom2.solid) {
|
||||
|
||||
/* fix overlap */
|
||||
|
||||
while (this.get_tile(x_near1, Math.floor(this.player.loc.y / this.tile_size)).solid
|
||||
|| this.get_tile(x_near2, Math.floor(this.player.loc.y / this.tile_size)).solid)
|
||||
this.player.loc.y += 0.1;
|
||||
|
||||
while (this.get_tile(x_near1, Math.ceil(this.player.loc.y / this.tile_size)).solid
|
||||
|| this.get_tile(x_near2, Math.ceil(this.player.loc.y / this.tile_size)).solid)
|
||||
this.player.loc.y -= 0.1;
|
||||
|
||||
/* tile bounce */
|
||||
|
||||
var bounce = 0;
|
||||
|
||||
if (top1.solid && top1.bounce > bounce) bounce = top1.bounce;
|
||||
if (top2.solid && top2.bounce > bounce) bounce = top2.bounce;
|
||||
if (bottom1.solid && bottom1.bounce > bounce) bounce = bottom1.bounce;
|
||||
if (bottom2.solid && bottom2.bounce > bounce) bounce = bottom2.bounce;
|
||||
|
||||
this.player.vel.y *= -bounce || 0;
|
||||
|
||||
if ((bottom1.solid || bottom2.solid) && !tile.jump) {
|
||||
|
||||
this.player.on_floor = true;
|
||||
this.player.can_jump = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// adjust camera
|
||||
|
||||
var c_x = Math.round(this.player.loc.x - this.viewport.x/2);
|
||||
var c_y = Math.round(this.player.loc.y - this.viewport.y/2);
|
||||
var x_dif = Math.abs(c_x - this.camera.x);
|
||||
var y_dif = Math.abs(c_y - this.camera.y);
|
||||
|
||||
if(x_dif > 5) {
|
||||
|
||||
var mag = Math.round(Math.max(1, x_dif * 0.1));
|
||||
|
||||
if(c_x != this.camera.x) {
|
||||
|
||||
this.camera.x += c_x > this.camera.x ? mag : -mag;
|
||||
|
||||
if(this.limit_viewport) {
|
||||
|
||||
this.camera.x =
|
||||
Math.min(
|
||||
this.current_map.width_p - this.viewport.x + this.tile_size,
|
||||
this.camera.x
|
||||
);
|
||||
|
||||
this.camera.x =
|
||||
Math.max(
|
||||
0,
|
||||
this.camera.x
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(y_dif > 5) {
|
||||
|
||||
var mag = Math.round(Math.max(1, y_dif * 0.1));
|
||||
|
||||
if(c_y != this.camera.y) {
|
||||
|
||||
this.camera.y += c_y > this.camera.y ? mag : -mag;
|
||||
|
||||
if(this.limit_viewport) {
|
||||
|
||||
this.camera.y =
|
||||
Math.min(
|
||||
this.current_map.height_p - this.viewport.y + this.tile_size,
|
||||
this.camera.y
|
||||
);
|
||||
|
||||
this.camera.y =
|
||||
Math.max(
|
||||
0,
|
||||
this.camera.y
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(this.last_tile != tile.id && tile.script) {
|
||||
|
||||
eval(this.current_map.scripts[tile.script]);
|
||||
}
|
||||
|
||||
this.last_tile = tile.id;
|
||||
};
|
||||
|
||||
Clarity.prototype.update_player = function () {
|
||||
|
||||
if (this.key.left) {
|
||||
|
||||
if (this.player.vel.x > -this.current_map.vel_limit.x)
|
||||
this.player.vel.x -= this.current_map.movement_speed.left;
|
||||
}
|
||||
|
||||
if (this.key.up) {
|
||||
|
||||
if (this.player.can_jump && this.player.vel.y > -this.current_map.vel_limit.y) {
|
||||
|
||||
this.player.vel.y -= this.current_map.movement_speed.jump;
|
||||
this.player.can_jump = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.key.right) {
|
||||
|
||||
if (this.player.vel.x < this.current_map.vel_limit.x)
|
||||
this.player.vel.x += this.current_map.movement_speed.left;
|
||||
}
|
||||
|
||||
this.move_player();
|
||||
};
|
||||
|
||||
Clarity.prototype.draw_player = function (context) {
|
||||
|
||||
context.fillStyle = this.player.colour;
|
||||
|
||||
context.beginPath();
|
||||
|
||||
context.arc(
|
||||
this.player.loc.x + this.tile_size / 2 - this.camera.x,
|
||||
this.player.loc.y + this.tile_size / 2 - this.camera.y,
|
||||
this.tile_size / 2 - 1,
|
||||
0,
|
||||
Math.PI * 2
|
||||
);
|
||||
|
||||
context.fill();
|
||||
};
|
||||
|
||||
Clarity.prototype.update = function () {
|
||||
|
||||
this.update_player();
|
||||
};
|
||||
|
||||
Clarity.prototype.draw = function (context) {
|
||||
|
||||
this.draw_map(context, false);
|
||||
this.draw_player(context);
|
||||
};
|
||||
|
||||
/* Setup of the engine */
|
||||
|
||||
window.requestAnimFrame =
|
||||
window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.oRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame ||
|
||||
function(callback) {
|
||||
return window.setTimeout(callback, 1000 / 60);
|
||||
};
|
||||
|
||||
var canvas = document.getElementById('canvas'),
|
||||
ctx = canvas.getContext('2d');
|
||||
|
||||
canvas.width = 600;
|
||||
canvas.height = 600;
|
||||
|
||||
var game = new Clarity();
|
||||
game.set_viewport(canvas.width, canvas.height);
|
||||
game.load_map(map);
|
||||
|
||||
/* Limit the viewport to the confines of the map */
|
||||
game.limit_viewport = true;
|
||||
|
||||
var Loop = function() {
|
||||
|
||||
ctx.fillStyle = '#333';
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
game.update();
|
||||
game.draw(ctx);
|
||||
|
||||
window.requestAnimFrame(Loop);
|
||||
};
|
||||
|
||||
Loop();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
32
src/main/resources/templates/outlookLog/findLog.ftl
Normal file
32
src/main/resources/templates/outlookLog/findLog.ftl
Normal file
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>日志查询</title>
|
||||
<body>
|
||||
<table border="1" cellpadding="3" cellspacing="0">
|
||||
<tr>
|
||||
<th style="width: 15%">调用时间</th>
|
||||
<th style="width: 5%">调用结果</th>
|
||||
<th style="width: 15%">信息</th>
|
||||
<th>原始信息</th>
|
||||
</tr>
|
||||
<#list list_log?sort_by('callTime')?reverse as log>
|
||||
<#-- <span>${log},-->
|
||||
<#-- ${log.result}</span></br>-->
|
||||
<tr>
|
||||
<#assign dlong = (log.callTime + '000')?number?number_to_datetime/>
|
||||
<#-- <td>${num?log.callTime?number_to_datetime?string('yyyy-MM-dd')}</td>-->
|
||||
<td >${dlong?string("yyyy-MM-dd HH:mm:ss")}</td>
|
||||
<#if log.result == '1'>
|
||||
<td >成功</td>
|
||||
<#else >
|
||||
<td style="background: red">失败</td>
|
||||
</#if>
|
||||
<td>${log.msg}</td>
|
||||
<td>${log.originalMsg}</td>
|
||||
</tr>
|
||||
</#list>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
16
src/main/resources/templates/user/authorization_outlook.ftl
Normal file
16
src/main/resources/templates/user/authorization_outlook.ftl
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>outlook授权结果</title>
|
||||
</head>
|
||||
<body>
|
||||
<#if result>
|
||||
<h3>授权成功!</h3>
|
||||
<#else >
|
||||
<h3>授权失败!</h3>
|
||||
<h4>错误: ${msg}</h4>
|
||||
</#if>
|
||||
<a href="/user/home">返回用户中心</a>
|
||||
</body>
|
||||
</html>
|
117
src/main/resources/templates/user/home.ftl
Normal file
117
src/main/resources/templates/user/home.ftl
Normal file
@ -0,0 +1,117 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Home</title>
|
||||
<link rel="stylesheet" href="//cdnjs.loli.net/ajax/libs/mdui/0.4.3/css/mdui.min.css">
|
||||
<script src="//cdnjs.loli.net/ajax/libs/mdui/0.4.3/js/mdui.min.js"></script>
|
||||
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
|
||||
</head>
|
||||
<body class="mdui-appbar-with-toolbar mdui-theme-primary-indigo mdui-theme-accent-blue mdui-loaded">
|
||||
<header class="mdui-appbar mdui-appbar-fixed">
|
||||
<div class="mdui-toolbar mdui-color-theme">
|
||||
<span class="mdui-typo-title">Office E5 自动续订</span>
|
||||
<div class="mdui-toolbar-spacer"></div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="mdui-card-media in floats">
|
||||
使用说明
|
||||
<ol>
|
||||
<#--<li>输入 client_id 与 client_secret 保存</li>
|
||||
<li>点击 “授权”,请用不使用的空账号登录授权</li>
|
||||
<li>授权成功后就不用管了,系统会自动调用你的out api</li>-->
|
||||
<li>程序会读取授权的outlook账号邮箱邮件,但不会保存任何信息,仅仅是调用api。</li>
|
||||
<li>请单独创建一个同域 E5 子账号,不要使用此账号进行发送、接收个人邮件,以免发生误会。</li>
|
||||
</ol>
|
||||
</div>
|
||||
<#--数据输入-->
|
||||
<div class="mdui-card-media in floats">
|
||||
<div class="mdui-textfield">
|
||||
<label class="mdui-textfield-label" style="font-weight: 500;">client_id</label>
|
||||
<input id="client_id" class="mdui-textfield-input" type="text" value="${client_id!}"/>
|
||||
</div>
|
||||
<div class="mdui-textfield">
|
||||
<label class="mdui-textfield-label" style="font-weight: 500;">client_secret</label>
|
||||
<input id="client_secret" class="mdui-textfield-input" type="text" value="${client_secret!}"/>
|
||||
</div>
|
||||
<button id="authorization" class="mdui-btn mdui-color-theme-accent mdui-ripple">授权</button>
|
||||
<button id="save" class="mdui-btn mdui-color-theme-accent mdui-ripple">保存</button>
|
||||
</div>
|
||||
<div class="mdui-divider"></div>
|
||||
<#--日志表格-->
|
||||
<div class="mdui-table-fluid table-container floats">
|
||||
<p>日志会在每日0点清空。</p>
|
||||
<button id="findLog" class="mdui-btn mdui-color-theme-accent mdui-ripple">查询日志</button>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
<script src="//www.mdui.org/source/dist/js/mdui.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
//日志查询
|
||||
$("#findLog").click(function () {
|
||||
var url = "/outlookLog/findLog"
|
||||
window.open(url,'_blank')
|
||||
})
|
||||
// 授权
|
||||
$("#authorization").click(function () {
|
||||
var url = "/outlook/auth2/getAuthorizeUrl"
|
||||
window.location.href = url;
|
||||
})
|
||||
//保存
|
||||
$("#save").click(function () {
|
||||
var client_id = $("#client_id").val();
|
||||
var client_secret = $("#client_secret").val();
|
||||
if ((client_id || client_secret) == "") {
|
||||
alert("client_id 或 client_secret 不能为空!")
|
||||
return;
|
||||
}
|
||||
;
|
||||
$.post("/outlook/outlook/save", {
|
||||
client_id: client_id,
|
||||
client_secret: client_secret
|
||||
}, function (data, status) {
|
||||
console.log(data);
|
||||
if (status != "success") {
|
||||
alert("未知错误,请联系管理员!")
|
||||
return;
|
||||
}
|
||||
if (data.code == 0) {
|
||||
alert("保存成功!");
|
||||
} else {
|
||||
alert("错误: + " + data.msg);
|
||||
}
|
||||
|
||||
})
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.table-container {
|
||||
border-radius: 15px;
|
||||
background-clip: padding-box;
|
||||
margin: 1% 1%;
|
||||
width: 25%;
|
||||
padding: 35px 35px 15px 35px;
|
||||
background: #fff;
|
||||
border: 1px solid #eaeaea;
|
||||
box-shadow: 0 0 25px #cac6c6;
|
||||
}
|
||||
|
||||
.in {
|
||||
border-radius: 15px;
|
||||
background-clip: padding-box;
|
||||
margin: 1% 1%;
|
||||
width: 25%;
|
||||
padding: 35px 35px 15px 35px;
|
||||
background: #fff;
|
||||
border: 1px solid #eaeaea;
|
||||
box-shadow: 0 0 25px #cac6c6;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.floats {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
</html>
|
34
src/main/resources/templates/user/login.ftl
Normal file
34
src/main/resources/templates/user/login.ftl
Normal file
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>登录</title>
|
||||
</head>
|
||||
<body class="mdui-theme-primary-indigo mdui-theme-accent-light-blue">
|
||||
<div class="mdui-card login-container">
|
||||
<div style="margin: auto;">
|
||||
<a href="/auth2/getGithubUrl" data-hotkey="g d" aria-label="Homepage"
|
||||
data-ga-click="Header, go to dashboard, icon:logo">
|
||||
<svg class="octicon octicon-mark-github v-align-middle" height="64" width="64" viewBox="0 0 16 16"
|
||||
version="1.1" aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
<style>
|
||||
.login-container {
|
||||
border-radius: 15px;
|
||||
background-clip: padding-box;
|
||||
margin: 5% auto;
|
||||
width: 5%;
|
||||
padding: 35px 35px 15px 35px;
|
||||
background: #fff;
|
||||
border: 1px solid #eaeaea;
|
||||
box-shadow: 0 0 25px #cac6c6;
|
||||
}
|
||||
</style>
|
||||
</html>
|
13
src/test/java/io/qyi/e5/E5ApplicationTests.java
Normal file
13
src/test/java/io/qyi/e5/E5ApplicationTests.java
Normal file
@ -0,0 +1,13 @@
|
||||
package io.qyi.e5;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class E5ApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
33
src/test/java/io/qyi/e5/test/MailJobListener.java
Normal file
33
src/test/java/io/qyi/e5/test/MailJobListener.java
Normal file
@ -0,0 +1,33 @@
|
||||
package io.qyi.e5.test;
|
||||
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.quartz.JobListener;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-03-03 09:39
|
||||
**/
|
||||
public class MailJobListener implements JobListener {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "listener of mail job";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jobToBeExecuted(JobExecutionContext context) {
|
||||
System.out.println("取消执行:\t "+context.getJobDetail().getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jobExecutionVetoed(JobExecutionContext context) {
|
||||
System.out.println("准备执行:\t "+context.getJobDetail().getKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
|
||||
System.out.println("执行结束:\t "+context.getJobDetail().getKey());
|
||||
}
|
||||
}
|
25
src/test/java/io/qyi/e5/test/RamJob.java
Normal file
25
src/test/java/io/qyi/e5/test/RamJob.java
Normal file
@ -0,0 +1,25 @@
|
||||
package io.qyi.e5.test;
|
||||
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
|
||||
import java.time.LocalTime;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-03-02 16:37
|
||||
**/
|
||||
public class RamJob implements Job {
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||
System.out.println("启动定时任务......每十秒执行一次,共执行三次");
|
||||
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
|
||||
System.out.println(LocalTime.now().toString());
|
||||
System.out.println(jobDataMap.get("level") + "" + jobDataMap.get("job"));
|
||||
}
|
||||
}
|
65
src/test/java/io/qyi/e5/test/quartzDome01.java
Normal file
65
src/test/java/io/qyi/e5/test/quartzDome01.java
Normal file
@ -0,0 +1,65 @@
|
||||
package io.qyi.e5.test;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.quartz.*;
|
||||
import org.quartz.impl.StdSchedulerFactory;
|
||||
import org.quartz.impl.matchers.KeyMatcher;
|
||||
|
||||
/**
|
||||
* @program: e5
|
||||
* @description:
|
||||
* @author: 落叶随风
|
||||
* @create: 2020-03-02 16:37
|
||||
**/
|
||||
public class quartzDome01 {
|
||||
|
||||
@Test
|
||||
public void d0() throws Exception {
|
||||
try {
|
||||
demo01();
|
||||
} catch (SchedulerException e) {
|
||||
System.err.println("发现任务已经在数据库存在了,直接从数据库里运行:"+ e.getMessage());
|
||||
// TODO Auto-generated catch block
|
||||
resumeJobFromDatabase();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void resumeJobFromDatabase() throws Exception {
|
||||
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
|
||||
scheduler.start();
|
||||
// 等待200秒,让前面的任务都执行完了之后,再关闭调度器
|
||||
Thread.sleep(200000);
|
||||
scheduler.shutdown(true);
|
||||
}
|
||||
|
||||
public void demo01() throws SchedulerException {
|
||||
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
|
||||
JobDetail jobDetail = JobBuilder.newJob(RamJob.class)
|
||||
.withDescription("this is a job")
|
||||
.withIdentity("job1", "group1")
|
||||
.usingJobData("level", "老")
|
||||
.build();
|
||||
JobDataMap jobDataMap = jobDetail.getJobDataMap();
|
||||
jobDataMap.put("job","司机");
|
||||
|
||||
CronTrigger trigger = TriggerBuilder.newTrigger()
|
||||
.startNow()
|
||||
// .withDescription("this is a trigger1")
|
||||
// .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(3))
|
||||
.withIdentity("mailjob1", "mailgroup") //定义任务名称和分组
|
||||
.withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
|
||||
.build();
|
||||
//增加Job监听
|
||||
MailJobListener mailJobListener = new MailJobListener();
|
||||
KeyMatcher<JobKey> uKeyMatcher = KeyMatcher.keyEquals(jobDetail.getKey());
|
||||
scheduler.getListenerManager().addJobListener(mailJobListener,uKeyMatcher);
|
||||
|
||||
|
||||
//将触发器以及调度任务详情绑定到调度器上
|
||||
scheduler.scheduleJob(jobDetail,trigger);
|
||||
//启动调度器
|
||||
scheduler.start();
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user