This commit is contained in:
Saturneric 2020-09-01 01:01:19 +08:00
parent 4196037227
commit 0223c53d09
686 changed files with 67023 additions and 0 deletions

31
.gitignore vendored Normal file
View File

@ -0,0 +1,31 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/

118
.mvn/wrapper/MavenWrapperDownloader.java vendored Normal file
View File

@ -0,0 +1,118 @@
/*
* Copyright 2007-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;
public class MavenWrapperDownloader {
private static final String WRAPPER_VERSION = "0.5.6";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if (mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if (mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if (!outputFile.getParentFile().exists()) {
if (!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
String username = System.getenv("MVNW_USERNAME");
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
}

BIN
.mvn/wrapper/maven-wrapper.jar vendored Normal file

Binary file not shown.

2
.mvn/wrapper/maven-wrapper.properties vendored Normal file
View File

@ -0,0 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

310
mvnw vendored Normal file
View 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
View 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%

228
pom.xml Normal file
View File

@ -0,0 +1,228 @@
<?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>com.codesdream</groupId>
<artifactId>ase</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ase</name>
<description>All Staff Education</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.3.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<!-- 使用 xlsx 格式需要额外引入此依赖 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.61</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.71.android</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>2.5.4</version>
</dependency>
<!-- 内存数据库 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 二维码支持包 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.2.0</version>
</dependency>
<!-- Restful API 文档可视化支持 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.github.java-json-tools</groupId>
<artifactId>json-patch</artifactId>
<version>1.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArguments>
<!--suppress UnresolvedMavenProperty -->
<bootclasspath>${JAVA_HOME}/jre/lib/rt.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>AlibabaMaven</id>
<name>Maven Aliyun Mirror</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>

View File

@ -0,0 +1,13 @@
package com.codesdream.ase;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AseApplication {
public static void main(String[] args) {
SpringApplication.run(AseApplication.class, args);
}
}

View File

@ -0,0 +1,22 @@
package com.codesdream.ase.component;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 手动获得Bean的工具类
*/
@Component
public class ASESpringUtil {
@Resource
private ApplicationContext applicationContext;
public <T> T getBean(Class<T> tClass){
return applicationContext.getBean(tClass);
}
}

View File

@ -0,0 +1,178 @@
package com.codesdream.ase.component.activity;
import com.alibaba.fastjson.JSONObject;
import com.codesdream.ase.exception.innerservererror.DataInvalidFormatException;
import com.codesdream.ase.model.activity.Activity;
import com.codesdream.ase.model.activity.Attendance;
import com.codesdream.ase.model.activity.Period;
import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.service.ActivityService;
import com.codesdream.ase.service.AttendanceService;
import com.codesdream.ase.service.PeriodService;
import com.codesdream.ase.service.UserService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
* JSONObject-Activity转化类
*/
@Component
public class ActivityConverter {
@Resource
UserService userService;
@Resource
PeriodService periodService;
@Resource
AttendanceService attendanceService;
/**
* @param json 一个Optional的json对象用以转化为Activity对象此过程中进行值的合法校验
* @return 一个可以被直接存储在数据库中的合法的Activity对象
*/
public Activity convertToActivity(Optional<JSONObject> json) {
if (!json.isPresent()) {
throw new NullPointerException();
}
Activity activity = new Activity();
JSONObject jsonObject = json.get();
//设置活动创建人
int userId = (int) jsonObject.get("creator");
Optional<User> creator = userService.findUserById(userId);
activity.setCreator(creator.get());
//设置参与人员
List<Integer> participateGroupFromJson = (List<Integer>) jsonObject.get("participate-group");
Set<User> participateGroup = new HashSet<>();
for (int id : participateGroupFromJson) {
Optional<User> user = userService.findUserById(id);
participateGroup.add(user.get());
}
activity.setParticipateGroup(participateGroup);
//设置活动标题
String title = (String) jsonObject.get("title");
activity.setTitle(title);
//设置主要负责人
int chiefManagerId = (int) jsonObject.get("chief-manager");
Optional<User> chiefManager = userService.findUserById(chiefManagerId);
activity.setChiefManager(chiefManager.get());
//设置次要负责人
List<Integer> assistManagersFromJSON = (List<Integer>) jsonObject.get("assist-managers");
Set<User> assistManager = new HashSet<>();
for (int id : assistManagersFromJSON) {
Optional<User> user = userService.findUserById(id);
assistManager.add(user.get());
}
activity.setAssistManagers(assistManager);
//设置活动类型
String type = (String) jsonObject.get("type");
activity.setType(type);
//设置
String startTimeFromJSON = (String) jsonObject.get("start-time");
String endTimeFromJSON = (String) jsonObject.get("end-time");
LocalDateTime startTime = LocalDateTime.parse(startTimeFromJSON, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime endTime = LocalDateTime.parse(endTimeFromJSON, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Period period = new Period(startTime, endTime);
period.setEnabled(false);
period = periodService.save(period);
activity.setPlanPeriod(period);
String cycle = (String) jsonObject.get("cycle");
activity.setCycle(cycle);
String description = (String) jsonObject.get("description");
activity.setDescription(description);
List<Integer> signGroupFromJSON = (List<Integer>) jsonObject.get("sign-group");
Set<User> signGroup = new HashSet<>();
for (int id : signGroupFromJSON) {
Optional<User> user = userService.findUserById(id);
signGroup.add(user.get());
}
activity.setSignGroup(signGroup);
List<Integer> informGroupFromJSON = (List<Integer>) jsonObject.get("inform-group");
if (informGroupFromJSON == null) {
participateGroupFromJson.removeAll(signGroupFromJSON);
participateGroupFromJson.addAll(signGroupFromJSON);
informGroupFromJSON = participateGroupFromJson;
}
Set<User> informGroup = new HashSet<>();
for (int id : informGroupFromJSON) {
Optional<User> user = userService.findUserById(id);
informGroup.add(user.get());
}
activity.setInformGroup(informGroup);
List<Integer> visibleGroupFromJSON = (List<Integer>) jsonObject.get("visible-group");
Set<User> visibleGroup = new HashSet<>();
for (int id : visibleGroupFromJSON) {
Optional<User> user = userService.findUserById(id);
visibleGroup.add(user.get());
}
activity.setVisibleGroup(informGroup);
String remindTimeFromJSON = (String) jsonObject.get("remind-time");
String numStr = remindTimeFromJSON.substring(0, remindTimeFromJSON.length() - 1);
int num = Integer.parseInt(numStr);
char unit = remindTimeFromJSON.charAt(remindTimeFromJSON.length() - 1);
switch (unit) {
case 'w': {
activity.setRemindTime(activity.getPlanPeriod().getStartTime().minusWeeks(num));
break;
}
case 'd': {
activity.setRemindTime(activity.getPlanPeriod().getStartTime().minusDays(num));
break;
}
case 'm': {
activity.setRemindTime(activity.getPlanPeriod().getStartTime().minusMinutes(num));
break;
}
case 'h': {
activity.setRemindTime(activity.getPlanPeriod().getStartTime().minusHours(num));
break;
}
case 's': {
activity.setRemindTime(activity.getPlanPeriod().getStartTime().minusSeconds(num));
}
}
Set<Period> periods = new HashSet<>();
String[] attendanceTimes = (String[]) jsonObject.get("attendance");
boolean attendanceOnLine = (boolean) jsonObject.get("attendance-online");
if ((attendanceTimes.length & 1) == 1) {
throw new DataInvalidFormatException();
}
for (int i = 0; i < attendanceTimes.length; i += 2) {
LocalDateTime start = LocalDateTime.parse(attendanceTimes[i], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime end = LocalDateTime.parse(attendanceTimes[i + 1], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Period period1 = new Period(start, end);
periods.add(period1);
}
Attendance attendance = new Attendance();
attendance.setClockInPeriods(periods);
attendance.setOnline(attendanceOnLine);
attendance = attendanceService.save(attendance);
activity.setAttendance(attendance);
activity.setOn(false);
activity.setOff(false);
return activity;
}
}

View File

@ -0,0 +1,26 @@
package com.codesdream.ase.component.activity;
import com.codesdream.ase.component.ASESpringUtil;
import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.repository.permission.UserRepository;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.Optional;
//获取当前用户的用户名
@Component
public class CurrentUserGetter {
private Optional<User> user;
public Optional<User> getCurrentUser(HttpServletRequest request){
Principal principal = request.getUserPrincipal();
String username = principal.getName();
ASESpringUtil aseSpringUtil = new ASESpringUtil();
UserRepository userRepository = aseSpringUtil.getBean(UserRepository.class);
this.user = userRepository.findByUsername(username);
return this.user;
}
}

View File

@ -0,0 +1,129 @@
package com.codesdream.ase.component.activity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.*;
@Component
public class FileUtils {
/**
* 得到图片字节流 数组大小
*/
public static byte[] readStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
outStream.close();
inStream.close();
return outStream.toByteArray();
}
/**
* 将文件转换成Byte数组
*
* @param file
* @return
*/
public static byte[] getBytesByFile(File file) {
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
byte[] b = new byte[1000];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
byte[] data = bos.toByteArray();
bos.close();
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* MultipartFile转File
*
* @param param
* @return
*/
public static File transfer(MultipartFile param) {
if (!param.isEmpty()) {
File file = null;
try {
InputStream in = param.getInputStream();
file = new File(param.getOriginalFilename());
OutputStream out = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
out.write(buffer, 0, bytesRead);
}
in.close();
out.close();
return file;
} catch (Exception e) {
e.printStackTrace();
return file;
}
}
return null;
}
/**
* 获取指定文件的输入流
*
* @param logoPath 文件的路径
* @return
*/
public static InputStream getResourceAsStream(String logoPath) {
return FileUtils.class.getResourceAsStream(logoPath);
}
/**
* 将InputStream写入到File中
*
* @param ins
* @param file
* @throws IOException
*/
public void inputStreamToFile(InputStream ins, File file) throws IOException {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
}
/**
* 将图片转化成输入流
*
* @param image 图片
* @return inputStream 图片转化之后的输入流
*/
public static InputStream getImageStream(BufferedImage image) {
InputStream inputStream = null;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageOutputStream imageOutputStream;
try {
imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream);
ImageIO.write(image, "jpg", imageOutputStream);
inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
return inputStream;
}
}

View File

@ -0,0 +1,12 @@
package com.codesdream.ase.component.activity;
import lombok.Data;
import org.springframework.stereotype.Component;
import java.util.List;
@Data
@Component
public class NullValueAttributes {
private List<String> nullValueAttributes;
}

View File

@ -0,0 +1,225 @@
package com.codesdream.ase.component.activity;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.springframework.stereotype.Component;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Hashtable;
import java.util.Random;
/**
* 二维码生成工具类
*/
@Component
public class QrCodeUtils {
private static final String CHARSET = "utf-8";
public static final String FORMAT = "JPG";
// 二维码尺寸
private static final int QRCODE_SIZE = 300;
// LOGO宽度
private static final int LOGO_WIDTH = 60;
// LOGO高度
private static final int LOGO_HEIGHT = 60;
/**
* 生成二维码
*
* @param content 二维码内容
* @param logoPath logo地址
* @param needCompress 是否压缩logo
* @return 图片
* @throws Exception
*/
public static BufferedImage createImage(String content, String logoPath, boolean needCompress) throws Exception {
Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
hints.put(EncodeHintType.MARGIN, 1);
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,
hints);
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
if (logoPath == null || "".equals(logoPath)) {
return image;
}
// 插入图片
QrCodeUtils.insertImage(image, logoPath, needCompress);
return image;
}
/**
* 插入LOGO
*
* @param source 二维码图片
* @param logoPath LOGO图片地址
* @param needCompress 是否压缩
* @throws IOException
*/
private static void insertImage(BufferedImage source, String logoPath, boolean needCompress) throws IOException {
InputStream inputStream = null;
try {
inputStream = FileUtils.getResourceAsStream(logoPath);
Image src = ImageIO.read(inputStream);
int width = src.getWidth(null);
int height = src.getHeight(null);
if (needCompress) { // 压缩LOGO
if (width > LOGO_WIDTH) {
width = LOGO_WIDTH;
}
if (height > LOGO_HEIGHT) {
height = LOGO_HEIGHT;
}
Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = tag.getGraphics();
g.drawImage(image, 0, 0, null); // 绘制缩小后的图
g.dispose();
src = image;
}
// 插入LOGO
Graphics2D graph = source.createGraphics();
int x = (QRCODE_SIZE - width) / 2;
int y = (QRCODE_SIZE - height) / 2;
graph.drawImage(src, x, y, width, height, null);
Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
graph.setStroke(new BasicStroke(3f));
graph.draw(shape);
graph.dispose();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
if (inputStream != null) {
inputStream.close();
}
}
}
/**
* 生成二维码(内嵌LOGO)
* 二维码文件名随机文件名可能会有重复
*
* @param content 内容
* @param logoPath LOGO地址
* @param destPath 存放目录
* @param needCompress 是否压缩LOGO
* @throws Exception
*/
public static String encode(String content, String logoPath, String destPath, boolean needCompress) throws Exception {
BufferedImage image = QrCodeUtils.createImage(content, logoPath, needCompress);
mkdirs(destPath);
String fileName = new Random().nextInt(99999999) + "." + FORMAT.toLowerCase();
ImageIO.write(image, FORMAT, new File(destPath + "/" + fileName));
return fileName;
}
/**
* 生成二维码(内嵌LOGO)
* 调用者指定二维码文件名
*
* @param content 内容
* @param logoPath LOGO地址
* @param destPath 存放目录
* @param fileName 二维码文件名
* @param needCompress 是否压缩LOGO
* @throws Exception
*/
public static String encode(String content, String logoPath, String destPath, String fileName, boolean needCompress) throws Exception {
BufferedImage image = QrCodeUtils.createImage(content, logoPath, needCompress);
mkdirs(destPath);
fileName = fileName.substring(0, fileName.indexOf(".") > 0 ? fileName.indexOf(".") : fileName.length())
+ "." + FORMAT.toLowerCase();
ImageIO.write(image, FORMAT, new File(destPath + "/" + fileName));
return fileName;
}
/**
* 当文件夹不存在时mkdirs会自动创建多层目录区别于mkdir
* (mkdir如果父目录不存在则会抛出异常)
*
* @param destPath 存放目录
*/
public static void mkdirs(String destPath) {
File file = new File(destPath);
if (!file.exists() && !file.isDirectory()) {
file.mkdirs();
}
}
/**
* 生成二维码(内嵌LOGO)
*
* @param content 内容
* @param logoPath LOGO地址
* @param destPath 存储地址
* @throws Exception
*/
public static String encode(String content, String logoPath, String destPath) throws Exception {
return QrCodeUtils.encode(content, logoPath, destPath, false);
}
/**
* 生成二维码
*
* @param content 内容
* @param destPath 存储地址
* @param needCompress 是否压缩LOGO
* @throws Exception
*/
public static String encode(String content, String destPath, boolean needCompress) throws Exception {
return QrCodeUtils.encode(content, null, destPath, needCompress);
}
/**
* 生成二维码
*
* @param content 内容
* @param destPath 存储地址
* @throws Exception
*/
public static String encode(String content, String destPath) throws Exception {
return QrCodeUtils.encode(content, null, destPath, false);
}
/**
* 生成二维码(内嵌LOGO)
*
* @param content 内容
* @param logoPath LOGO地址
* @param output 输出流
* @param needCompress 是否压缩LOGO
* @throws Exception
*/
public static void encode(String content, String logoPath, OutputStream output, boolean needCompress)
throws Exception {
BufferedImage image = QrCodeUtils.createImage(content, logoPath, needCompress);
ImageIO.write(image, FORMAT, output);
}
/**
* 生成二维码
*
* @param content 内容
* @param output 输出流
* @throws Exception
*/
public static void encode(String content, OutputStream output) throws Exception {
QrCodeUtils.encode(content, null, output, false);
}
}

View File

@ -0,0 +1,128 @@
package com.codesdream.ase.component.api;
import com.codesdream.ase.component.datamanager.JSONParameter;
import com.codesdream.ase.component.json.respond.JSONBaseRespondObject;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class QuickJSONRespond {
@Resource
private JSONParameter jsonParameter;
// 根据对象构造获得标准的JSON响应字符串返回
public String getJSONStandardRespond(Integer status, String msg, String info, Object dataObject){
JSONBaseRespondObject respondObject = new JSONBaseRespondObject(status, msg);
if(info != null) respondObject.setInfo(info);
else respondObject.setInfo(null);
respondObject.setData(dataObject);
return jsonParameter.getJSONString(respondObject);
}
// 根据对象构造获得标准的JSON响应字符串返回
public String getJSONStandardRespond(HttpStatus status, Object dataObject){
JSONBaseRespondObject respondObject = new JSONBaseRespondObject(status.value(), status.getReasonPhrase());
respondObject.setData(dataObject);
return jsonParameter.getJSONString(respondObject);
}
// 根据对象构造获得标准的JSON响应字符串返回
public String getJSONStandardRespond(HttpStatus status, String info, Object dataObject){
JSONBaseRespondObject respondObject = new JSONBaseRespondObject(status.value(), status.getReasonPhrase());
if(info != null) respondObject.setInfo(info);
else respondObject.setInfo(null);
respondObject.setData(dataObject);
return jsonParameter.getJSONString(respondObject);
}
// 根据对象构造获得标准的JSON响应字符串返回
public String getJSONStandardRespond(HttpStatus status, String info){
JSONBaseRespondObject respondObject = new JSONBaseRespondObject(status.value(), status.getReasonPhrase());
if(info != null) respondObject.setInfo(info);
else respondObject.setInfo(null);
return jsonParameter.getJSONString(respondObject);
}
// 获得标准的JSON响应字符串返回特定状态码的和解释息
public String getJSONStandardRespond(Integer code, String msg, String info){
JSONBaseRespondObject respondObject = new JSONBaseRespondObject(code, msg);
if(info != null) respondObject.setInfo(info);
else respondObject.setInfo(null);
respondObject.setData(null);
return jsonParameter.getJSONString(respondObject);
}
// 获得标准的JSON响应字符串返回(404状态)
public String getRespond404(String info){
return getJSONStandardRespond(HttpStatus.NOT_FOUND, info);
}
// 获得标准的JSON响应字符串返回(404状态)
public String getRespond404(String info, Object object){
return getJSONStandardRespond(HttpStatus.NOT_FOUND, info, object);
}
// 获得标准的JSON响应字符串返回(500状态)
public String getRespond500(String info){
return getJSONStandardRespond(HttpStatus.INTERNAL_SERVER_ERROR, info);
}
// 获得标准的JSON响应字符串返回(200状态)
public String getRespond200(String info){
return getJSONStandardRespond(HttpStatus.OK, info);
}
// 获得标准的JSON响应字符串返回(200状态)
public String getRespond200(String info, Object object){
return getJSONStandardRespond(HttpStatus.OK, info, object);
}
// 获得标准的JSON响应字符串返回(403状态)
public String getRespond403(String info){
return getJSONStandardRespond(HttpStatus.FORBIDDEN, info);
}
// 获得标准的JSON响应字符串返回(406状态)
public String getRespond406(String info){
return getJSONStandardRespond(HttpStatus.NOT_ACCEPTABLE, info);
}
// 获得标准的JSON响应字符串返回(406状态)
public String getRespond406(String info, Object object){
return getJSONStandardRespond(HttpStatus.NOT_ACCEPTABLE, info, object);
}
// 获得标准的JSON响应字符串返回(501态)
public String getRespond501(String info){
return getJSONStandardRespond(501, "Not Implemented", info) ;
}
// 获得标准的JSON响应字符串返回(401状态)
public String getRespond401(String info){
return getJSONStandardRespond(401, "Unauthorized", info);
}
// 获得标准的JSON响应字符串返回(400状态)
public String getRespond400(String info){
return getJSONStandardRespond(400, "Bad Request", info);
}
// 获得标准的JSON响应字符串返回(404状态)
public String getRespond400(String info, Object object){
return getJSONStandardRespond(400, "Bad Request", info, object);
}
// 获得标准的JSON响应字符串返回(400状态)
public String getRespond409(String info){
return getJSONStandardRespond(409, "Conflict", info);
}
}

View File

@ -0,0 +1,14 @@
package com.codesdream.ase.component.auth;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;
@Component
public class AJAXRequestChecker {
public boolean checkAjaxPOSTRequest(HttpServletRequest request){
return Optional.ofNullable(request.getHeader("X-Requested-With")).isPresent();
}
}

View File

@ -0,0 +1,42 @@
package com.codesdream.ase.component.auth;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Iterator;
@Component
public class ASEAccessDecisionManager implements AccessDecisionManager {
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
if(null == configAttributes || configAttributes.size() <= 0) {
return;
}
for (ConfigAttribute c : configAttributes) {
String needRole = c.getAttribute();
for (GrantedAuthority ga : authentication.getAuthorities()) {
if (needRole.trim().equals(ga.getAuthority())) {
return;
}
}
}
throw new AccessDeniedException("Access Denied");
}
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
}

View File

@ -0,0 +1,33 @@
package com.codesdream.ase.component.auth;
import com.codesdream.ase.component.api.QuickJSONRespond;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
// 认证用户访问无权限资源
@Slf4j
@Component
public class ASEAccessDeniedHandler implements AccessDeniedHandler {
@Resource
private QuickJSONRespond quickJSONRespond;
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)
throws IOException, ServletException {
log.info("ASEAccessDeniedHandler Found!");
// 对无权限操作返回403
response.getWriter().print(quickJSONRespond.getRespond403(null));
}
}

View File

@ -0,0 +1,29 @@
package com.codesdream.ase.component.auth;
import com.codesdream.ase.component.api.QuickJSONRespond;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
// 匿名用户访问无权限资源
@Slf4j
@Component
public class ASEAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Resource
private QuickJSONRespond quickJSONRespond;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
throws IOException {
// 对匿名用户返回401
response.getWriter().print(quickJSONRespond.getRespond401(null));
}
}

View File

@ -0,0 +1,43 @@
package com.codesdream.ase.component.auth;
import com.codesdream.ase.component.api.QuickJSONRespond;
import com.codesdream.ase.component.json.respond.ErrorInfoJSONRespond;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
// 认证失败返回
@Slf4j
@Component
public class ASEAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Resource
private QuickJSONRespond quickJSONRespond;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
throws IOException
{
log.info("ASEAuthenticationFailureHandler Login Fail!");
// 填写异常信息存储对象
ErrorInfoJSONRespond errorInfoJSONRespond = new ErrorInfoJSONRespond();
errorInfoJSONRespond.setDate(new Date());
errorInfoJSONRespond.setExceptionMessage(exception.getMessage());
errorInfoJSONRespond.setException(exception.getClass().getSimpleName());
// 认证失败返回406
response.getWriter().write(quickJSONRespond.getJSONStandardRespond(
406,
"Not Acceptable",
"Authentication Failure",
errorInfoJSONRespond));
}
}

View File

@ -0,0 +1,60 @@
package com.codesdream.ase.component.auth;
import com.codesdream.ase.component.api.QuickJSONRespond;
import com.codesdream.ase.component.json.respond.UserLoginCheckerJSONRespond;
import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.service.IAuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Optional;
// 认证成功返回
@Slf4j
@Component
public class ASEAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Resource
private QuickJSONRespond quickJSONRespond;
@Resource
private IAuthService authService;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException
{
UserLoginCheckerJSONRespond respond = new UserLoginCheckerJSONRespond();
respond.setUserExist(authentication.isAuthenticated());
respond.setLoginStatus(authentication.isAuthenticated());
respond.setPvc(authService.preValidationCodeGetter());
// 获得 JSONTokenAuthenticationToken
JSONTokenAuthenticationToken authenticationToken = (JSONTokenAuthenticationToken) authentication;
User user = (User) authenticationToken.getPrincipal();
Optional<String> tokenOptional = authService.userNewTokenGetter(
user.getUsername(), authenticationToken.getClientCode());
if(tokenOptional.isPresent()){
respond.setToken(tokenOptional.get());
}
else respond.setToken("");
// 认证成功返回200
response.getWriter().write(quickJSONRespond.getRespond200("Authentication Success", respond));
}
}

View File

@ -0,0 +1,65 @@
package com.codesdream.ase.component.auth;
import com.codesdream.ase.model.permission.Function;
import com.codesdream.ase.repository.permission.FunctionRepository;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
@Component
public class ASEInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
private HashMap<String, Collection<ConfigAttribute>> map = null;
@Resource
private FunctionRepository functionRepository;
private void loadFunctionDefine(){
map = new HashMap<>();
Iterable<Function> functions = functionRepository.findAll();
for(Function function : functions) {
Collection<ConfigAttribute> array = new ArrayList<>();
ConfigAttribute cfg = new SecurityConfig(function.getName());
array.add(cfg);
map.put(function.getUrl(), array);
}
}
@Override
public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
if(map == null) loadFunctionDefine();
HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
for (String url : map.keySet()) {
AntPathRequestMatcher matcher = new AntPathRequestMatcher(url);
if (matcher.matches(request)) {
return map.get(url);
}
}
return null;
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
}

View File

@ -0,0 +1,114 @@
package com.codesdream.ase.component.auth;
import com.codesdream.ase.model.auth.JSONToken;
import com.codesdream.ase.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.Date;
import java.util.Optional;
// API请求验证过滤
@Slf4j
public class ASEJSONTokenAuthenticationFilter extends OncePerRequestFilter {
@Resource
private JSONRandomCodeGenerator randomCodeGenerator;
@Resource
private AuthService authService;
@Resource
private JSONSignedGenerator signedGenerator;
@Resource
private UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 用户名
String username = request.getHeader( "username");
// 客户端签名
String signed = request.getHeader("signed");
// 时间戳
String timestamp = request.getHeader("timestamp");
// 服务端API测试豁免签名
if(signed != null && signed.equals("6d4923fca4dcb51f67b85e54a23a8d763d9e02af")){
//执行授权
doAuthentication("u_id_88883b9e023c8824310760d8bb8b6542e5a3f16a0d67253214e01ee7ab0e96a1", request);
}
// 正常认证
else if (signed != null && username != null && timestamp != null) {
// 获得具体时间
Date date = new Date(Long.parseLong(timestamp));
Date now = new Date();
// 限制时间戳有效区间为60s
long dtTime = 60*1000;
Date maxDate = new Date(now.getTime() + dtTime);
// 检查时间戳是否合理
if(maxDate.after(date)) {
// 从服务器中查找token
Optional<JSONToken> optionalJSONToken = authService.findTokenByUserName(username);
if (optionalJSONToken.isPresent()) {
JSONToken token = optionalJSONToken.get();
// 检查token是否过期
if (!authService.checkTokenIfExpired(token)) {
// 生成特征随机代码
String randomCode = randomCodeGenerator.generateRandomCode(username, date, token.getClientCode());
log.info(String.format("Determined Signed: %s",
signedGenerator.generateSigned(username, randomCode, token.getToken())));
// 检查签名是否正确
if (signed.equals(signedGenerator.generateSigned(username, randomCode, token.getToken()))) {
// 执行授权操作
doAuthentication(username, request);
}
}
}
}
}
filterChain.doFilter(request, response);
}
// 执行授权
private void doAuthentication(String username, HttpServletRequest request){
// 查询用户的相关信息
UserDetails user = userDetailsService.loadUserByUsername(username);
// 生成用户权限列表
Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
// 生成授权柄 (储存上下文信息)
JSONTokenAuthenticationToken authentication =
new JSONTokenAuthenticationToken(user, null, authorities);
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// 执行授权
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}

View File

@ -0,0 +1,18 @@
package com.codesdream.ase.component.auth;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
@Component
public class ASEPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence charSequence) {
return DigestUtils.sha256Hex(charSequence.toString());
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return s.equals(DigestUtils.sha256Hex(charSequence.toString()));
}
}

View File

@ -0,0 +1,77 @@
package com.codesdream.ase.component.auth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
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.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Collection;
// 普通用户名密码验证, 用户获得Token
@Slf4j
@Component
public class ASESecurityAuthenticationProvider implements AuthenticationProvider {
@Resource
UserDetailsService userDetailsService;
@Resource
ASEUsernameEncoder usernameEncoder;
@Resource
PasswordEncoder passwordEncoder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
JSONTokenUsernamePasswordAuthenticationToken authenticationToken =
(JSONTokenUsernamePasswordAuthenticationToken) authentication;
// 获得JSON中的学号
String username = usernameEncoder.encode((CharSequence) authenticationToken.getPrincipal());
// 获得JSON中的加密密码
String encrypted_password = (String) authenticationToken.getCredentials();
// 获得客户端代码
String clientCode = authenticationToken.getClientCode();
// 判断用户是否存在
UserDetails userInfo = userDetailsService.loadUserByUsername(username);
if (userInfo == null) {
throw new UsernameNotFoundException("User Not Exist");
}
String sha256_password = userInfo.getPassword();
// 判断密码是否正确
if(!passwordEncoder.encode(String.format(
"PASS_ENCODE [%s][%s]", sha256_password, clientCode)).equals(encrypted_password)){
throw new BadCredentialsException("Password IS INCORRECT");
}
// 判断账号是否停用/删除
if (!userInfo.isEnabled()) {
throw new DisabledException("User IS Disabled");
}
else if(!userInfo.isAccountNonLocked()) {
throw new LockedException("User IS Locked");
}
else if(!userInfo.isAccountNonExpired()) {
throw new AccountExpiredException("User IS Expired");
}
// 生成权限列表
Collection<? extends GrantedAuthority> authorities = userInfo.getAuthorities();
return new JSONTokenAuthenticationToken(userInfo, clientCode, authorities);
}
@Override
public boolean supports(Class<?> aClass) {
return aClass.equals(JSONTokenUsernamePasswordAuthenticationToken.class);
}
}

View File

@ -0,0 +1,62 @@
package com.codesdream.ase.component.auth;
import javax.annotation.Resource;
import javax.servlet.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class ASESecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
@Resource
private FilterInvocationSecurityMetadataSource securityMetadataSource;
@Resource
public void setASEAccessDecisionManager(ASEAccessDecisionManager accessDecisionManager) {
super.setAccessDecisionManager(accessDecisionManager);
}
@Override
public Class<?> getSecureObjectClass() {
return FilterInvocation.class;
}
@Override
public SecurityMetadataSource obtainSecurityMetadataSource() {
return this.securityMetadataSource;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
public void invoke(FilterInvocation fi) throws IOException, ServletException {
InterceptorStatusToken token = super.beforeInvocation(fi);
try {
//执行下一个拦截器
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}
@Override
public void destroy() {
}
}

View File

@ -0,0 +1,15 @@
package com.codesdream.ase.component.auth;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Component;
@Component
public class ASEUsernameEncoder {
public String encode(CharSequence charSequence){
return "u_id_" + DigestUtils.sha256Hex(charSequence.toString());
}
public boolean matches(CharSequence charSequence, String s){
return s.equals(encode(charSequence.toString()));
}
}

View File

@ -0,0 +1,85 @@
package com.codesdream.ase.component.auth;
import com.codesdream.ase.component.auth.AJAXRequestChecker;
import com.codesdream.ase.component.auth.JSONTokenUsernamePasswordAuthenticationToken;
import com.codesdream.ase.component.auth.TimestampExpiredChecker;
import com.codesdream.ase.component.datamanager.JSONParameter;
import com.codesdream.ase.component.json.request.UserLoginChecker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;
// 普通登录验证过滤器
@Slf4j
public class ASEUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Resource
private JSONParameter jsonParameter;
@Resource
private AJAXRequestChecker ajaxRequestChecker;
@Resource
private TimestampExpiredChecker timestampExpiredChecker;
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
String timestamp = request.getHeader("timestamp");
// 检查时间戳是否合理(60秒内)
if(timestamp == null || !timestampExpiredChecker.checkTimestampBeforeMaxTime(timestamp, 60)){
throw new AuthenticationServiceException("Timestamp Expired.");
}
// 判断是否为AJAX请求格式的数据
if(!ajaxRequestChecker.checkAjaxPOSTRequest(request)) {
throw new AuthenticationServiceException("Authentication method not supported: NOT Ajax Method.");
}
Optional<UserLoginChecker> checkerOptional = jsonParameter.getJavaObjectByRequest(request, UserLoginChecker.class);
if(!checkerOptional.isPresent()) throw new BadCredentialsException("Invalid AJAX JSON Request");
UserLoginChecker checker = checkerOptional.get();
if(checker.getUsername() == null
|| checker.getPassword() == null
|| checker.getClientCode() == null
|| checker.getCheckType() == null)
throw new AuthenticationServiceException("Request Data IS Incomplete");
if (!checker.getCheckType().equals("UsernamePasswordChecker"))
throw new AuthenticationServiceException("Authentication not supported: NOT Username Password Type.");
// 获得相应的用户名密码
String username = checker.getUsername();
// 得到加密密码
String password = checker.getPassword();
String clientCode = checker.getClientCode();
if (username == null) username = "";
if (password == null) password = "";
// 去除首尾两端的空白字符
username = username.trim();
password = password.trim();
JSONTokenUsernamePasswordAuthenticationToken authRequest =
new JSONTokenUsernamePasswordAuthenticationToken(username, password, clientCode);
authRequest.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
return this.getAuthenticationManager().authenticate(authRequest);
}
}

View File

@ -0,0 +1,19 @@
package com.codesdream.ase.component.auth;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.UUID;
@Component
public class AuthTokenGenerator {
@Resource
private SHA1Encoder encoder;
public String generateAuthToken(String username){
Date dateNow = new Date();
UUID uuid = UUID.randomUUID();
return encoder.encode(String.format("Token [%s][%d][%s]",username,dateNow.getTime(), uuid.toString()));
}
}

View File

@ -0,0 +1,19 @@
package com.codesdream.ase.component.auth;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
// 随机特征码生成器
@Component
public class JSONRandomCodeGenerator {
@Resource
private SHA1Encoder encoder;
public String generateRandomCode(String username, Date date, String clientCode){
return encoder.encode(String.format("RandomCode [%s][%s][%s]",
username, Long.toString(date.getTime()), clientCode));
}
}

View File

@ -0,0 +1,16 @@
package com.codesdream.ase.component.auth;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
// 用来给JSON生成签名
@Component
public class JSONSignedGenerator {
@Resource
SHA1Encoder encoder;
public String generateSigned(String username, String randomCode, String token){
return encoder.encode(String.format("SIGN [%s][%s][%s]",username, randomCode, token));
}
}

View File

@ -0,0 +1,62 @@
package com.codesdream.ase.component.auth;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
// 关联Token与其他用户的相关数据的授权柄
public class JSONTokenAuthenticationToken extends AbstractAuthenticationToken {
// 客户端签名
private String signed = null;
// 用户名
private Object principal = null;
// 客户端代码
private String clientCode = null;
/**
* Creates a token with the supplied array of authorities.
*
* @param authorities the collection of <tt>GrantedAuthority</tt>s for the principal
* represented by this authentication object.
*/
public JSONTokenAuthenticationToken(UserDetails principal,
String clientCode,
Collection<? extends GrantedAuthority> authorities)
{
super(authorities);
this.principal = principal;
this.clientCode = clientCode;
this.signed = null;
setAuthenticated(true);
}
public JSONTokenAuthenticationToken(String principal, String clientCode, String signed) {
super(null);
this.principal = principal;
this.clientCode = clientCode;
this.signed = signed;
setAuthenticated(false);
}
@Override
public String getCredentials() {
return signed;
}
@Override
public Object getPrincipal() {
return principal;
}
public String getClientCode() {
return clientCode;
}
public void setClientCode(String clientCode) {
this.clientCode = clientCode;
}
}

View File

@ -0,0 +1,38 @@
package com.codesdream.ase.component.auth;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
// 明文用户名密码验证授权柄
public class JSONTokenUsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
// 用户名
private String username = null;
// 明文密码
private String password = null;
// 授权柄
private String clientCode = null;
public JSONTokenUsernamePasswordAuthenticationToken(String username, String password, String clientCode) {
super(null);
this.username = username;
this.password = password;
this.clientCode = clientCode;
setAuthenticated(false);
}
@Override
public Object getCredentials() {
return password;
}
@Override
public Object getPrincipal() {
return username;
}
// 扩展接口 获得客户端代码
public String getClientCode() {
return clientCode;
}
}

View File

@ -0,0 +1,17 @@
package com.codesdream.ase.component.auth;
import org.apache.commons.codec.cli.Digest;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Component;
// SHA1算法不可逆加密 主要用于JSON签名
@Component
public class SHA1Encoder {
public String encode(CharSequence charSequence){
return DigestUtils.sha1Hex(charSequence.toString());
}
public boolean match (CharSequence charSequence, String s){
return s.equals(encode(charSequence));
}
}

View File

@ -0,0 +1,24 @@
package com.codesdream.ase.component.auth;
import org.springframework.stereotype.Component;
import java.util.Date;
// 验证时间戳是否有效
@Component
public class TimestampExpiredChecker {
public boolean checkTimestampBeforeMaxTime(String timestamp, int seconds){
Date timestampDate = new Date(Long.parseLong(timestamp));
long currentTime = System.currentTimeMillis();
Date maxDate = new Date(currentTime + seconds * 1000);
return timestampDate.before(maxDate);
}
public boolean checkDateBeforeMaxTime(Date date, int seconds){
long currentTime = System.currentTimeMillis();
Date maxDate = new Date(currentTime + seconds * 1000);
return date.before(maxDate);
}
}

View File

@ -0,0 +1,84 @@
package com.codesdream.ase.component.datamanager;
import com.codesdream.ase.exception.notfound.DataFileNotFoundException;
import com.codesdream.ase.exception.innerservererror.DataIOException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
/**
* 利用数据生成Excel文件
*/
public class DataExcelGenerator implements DataGenerator {
Workbook workbook = new XSSFWorkbook();
Sheet sheet;
Integer colNumber;
String path;
public DataExcelGenerator(String path) {
sheet = workbook.createSheet("Data");
this.path = path;
}
public void setTableTitle(Collection<String> titles){
Row sheetRow = sheet.createRow(0);
int idx = 0;
for(String title : titles){
sheetRow.createCell(idx).setCellValue(title);
idx++;
}
colNumber = titles.size();
}
public void insertRow(int rowIndex, Collection<String> dataCollection){
Row row = sheet.createRow(rowIndex);
int idx = 0;
for(String data : dataCollection){
// 限制表头与表体的数据数目
if(idx >= colNumber) break;
row.createCell(idx).setCellValue(data);
idx++;
}
}
public void insertRow(Collection<String> dataCollection){
insertRow(sheet.getLastRowNum() + 1, dataCollection);
}
public void insertRowDataALL(Collection<String> dataCollections){
int cellIdx = 0;
Collection<String> dataCollection = new ArrayList<>();
for(String dataCollectionItem :dataCollections){
dataCollection.add(dataCollectionItem);
cellIdx++;
if(cellIdx % colNumber == 0) {
insertRow(dataCollection);
dataCollection.clear();
cellIdx = 0;
}
}
}
public void save() {
try {
FileOutputStream stream = new FileOutputStream(path, false);
workbook.write(stream);
stream.close();
} catch (FileNotFoundException e) {
throw new DataFileNotFoundException(path);
} catch (IOException e) {
throw new DataIOException();
}
}
}

View File

@ -0,0 +1,123 @@
package com.codesdream.ase.component.datamanager;
import com.codesdream.ase.exception.*;
import com.codesdream.ase.exception.innerservererror.DataIOException;
import com.codesdream.ase.exception.innerservererror.DataIllegalTableFormatException;
import com.codesdream.ase.exception.innerservererror.DataInvalidFormatException;
import com.codesdream.ase.exception.notfound.DataFileNotFoundException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
/**
* 读取简单表格式的Excel文件
*/
public class DataExcelReader implements DataReader {
Workbook workbook = null;
Sheet sheet = null;
short colNumber = 0;
int rowNumberNow = 0;
String path;
boolean hasReadFile = false;
public DataExcelReader(String path){
this.path = path;
readFile();
}
public void readFile(){
if(hasReadFile) return;
try{
FileInputStream fileInputStream = new FileInputStream(path);
workbook = WorkbookFactory.create(fileInputStream);
sheet = workbook.getSheetAt(0);
fileInputStream.close();
} catch (FileNotFoundException e) {
throw new DataFileNotFoundException(path);
} catch (InvalidFormatException e) {
throw new DataInvalidFormatException(e);
} catch (IOException e) {
throw new DataIOException();
}
}
public Collection<String> readColsTitle(){
Row titleRow = sheet.getRow(0);
colNumber = titleRow.getLastCellNum();
// 表头项目个数不可为0
if(colNumber == 0) throw new DataIllegalTableFormatException();
Collection<String> title = new ArrayList<>();
for(int cellIdx = 0; cellIdx < colNumber; cellIdx++){
title.add(readCell(titleRow.getCell(cellIdx)));
}
return title;
}
public Collection<String> readRow(int idx){
// 检查是否获取表头数据
if(this.colNumber == 0) readColsTitle();
if(idx > getRowsSize()) throw new DataReaderRowIndexOutOfRangeException();
this.rowNumberNow = idx;
Collection<String> data = new ArrayList<>();
Row dataRow = sheet.getRow(rowNumberNow);
// 检查列数是否合适
if(dataRow.getLastCellNum() > colNumber) throw new DataIllegalTableFormatException();
for(int cellIdx = 0; cellIdx < colNumber; cellIdx++){
data.add(readCell(dataRow.getCell(cellIdx)));
}
return data;
}
@Override
public int getRowsSize() {
return lastDataRowIndex() - firstDataRowIndex();
}
@Override
public int firstDataRowIndex() {
return 1;
}
@Override
public int lastDataRowIndex() {
return sheet.getLastRowNum();
}
public Collection<String> readRow(){
if(rowNumberNow >= getRowsSize()) return null;
return readRow(rowNumberNow + 1);
}
private String readCell(Cell cell){
String cellValue = "";
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
cellValue = cell.getRichStringCellValue().getString();
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
cellValue = cell.getDateCellValue().toString();
} else {
cellValue = String.valueOf(cell.getNumericCellValue());
}
break;
case Cell.CELL_TYPE_BOOLEAN:
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
cellValue = String.valueOf(cell.getCellFormula());
break;
case Cell.CELL_TYPE_BLANK:
break;
default:
}
return cellValue;
}
}

View File

@ -0,0 +1,17 @@
package com.codesdream.ase.component.datamanager;
import java.util.Collection;
/**
* 表给狗数据文件生成器接口
*/
public interface DataGenerator {
// 读取表头信息
void setTableTitle(Collection<String> titles);
// 向表中写入一行数据
void insertRow(int rowIndex, Collection<String> dataCollection);
// 将修改保存表到文件中
void save();
}

View File

@ -0,0 +1,8 @@
package com.codesdream.ase.component.datamanager;
import org.springframework.stereotype.Component;
// 解析request请求,获得对应的Java对象
@Component
public class DataGetObjectFromRequest {
}

View File

@ -0,0 +1,57 @@
package com.codesdream.ase.component.datamanager;
import com.codesdream.ase.component.ASESpringUtil;
import lombok.Data;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* Model对应的Repository层查询器
*/
@Data
@Component
@Scope("prototype")
public class DataModelRepositorySearcher {
@Resource
ASESpringUtil springUtil;
public final String repositoryPath = "com.codesdream.ase.repository.";
private Class<?> repositoryClass = null;
private boolean present;
public void getDataModelRepositoryClass(String subSystem, String dataModel){
dataModel = doCheckName(dataModel);
try {
this.repositoryClass = Class.forName(dataModelFullNameGenerator(subSystem, dataModel));
this.setPresent(true);
} catch (ClassNotFoundException e) {
this.setPresent(false);
}
}
public <T> T getDataModelRepositoryInstance() {
// 确保可以引用
if(isPresent()) {
@SuppressWarnings("unchecked")
T repository = (T) springUtil.getBean(repositoryClass);
return repository;
}
return null;
}
public static String doCheckName(String string) {
char[] charArray = string.toCharArray();
if(Character.isLowerCase(charArray[0])) charArray[0] -= 32;
else return string;
return String.valueOf(charArray);
}
private String dataModelFullNameGenerator(String subSystem, String dataModel){
return new String(repositoryPath + subSystem + "." + dataModel + "Repository");
}
}

View File

@ -0,0 +1,70 @@
package com.codesdream.ase.component.datamanager;
import lombok.Data;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.swing.text.html.parser.Entity;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
/**
* 根据子系统及名称查找特定的MModel
*/
@Data
@Component
@Scope("prototype")
public class DataModelSearcher {
public final String modelPath = "com.codesdream.ase.model.";
private Class<?> dataModelClass = null;
private boolean present;
public void getDataModelClass(String subSystem, String dataModel) {
dataModel = doCheckName(dataModel);
try {
dataModelClass = Class.forName(dataModelFullNameGenerator(subSystem, dataModel));
this.setPresent(true);
}catch (ClassNotFoundException e){
this.setPresent(false);
}
}
public Collection<String> getDataModelParamArgs() {
if(isPresent()) {
Collection<String> paramArgs = new ArrayList<>();
for (Field field : dataModelClass.getDeclaredFields()) {
paramArgs.add(field.getName());
}
return paramArgs;
}
return null;
}
public <T> T getDataModelInstance(Class<T> dataModelClass) {
if(isPresent()){
try {
return dataModelClass.newInstance();
} catch (IllegalAccessException e) {
this.setPresent(false);
return null;
} catch (InstantiationException e) {
e.printStackTrace();
return null;
}
}
return null;
}
public static String doCheckName(String string) {
char[] charArray = string.toCharArray();
if(Character.isLowerCase(charArray[0])) charArray[0] -= 32;
else return string;
return String.valueOf(charArray);
}
private String dataModelFullNameGenerator(String subSystem, String dataModel){
return new String(modelPath + subSystem + "." + dataModel);
}
}

View File

@ -0,0 +1,27 @@
package com.codesdream.ase.component.datamanager;
import java.util.Collection;
/**
* 表结构信息读取器接口
*/
public interface DataReader {
// 从文件中读取数据(在使用上要求这个调用可有可无)
void readFile();
// 获得表头列的数目
Collection<String> readColsTitle();
// 读取特定序号的行的数据
Collection<String> readRow(int row);
// 得到数据的总行数
int getRowsSize();
// 得到第一数据行的序号
int firstDataRowIndex();
// 得到最后一行数据行的序号
int lastDataRowIndex();
}

View File

@ -0,0 +1,89 @@
package com.codesdream.ase.component.datamanager;
import com.codesdream.ase.exception.innerservererror.DataIllegalTableFormatException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.*;
// 描述一张数据表
@Component
@Scope("prototype")
public class DataTable {
Collection<String> titleCollection = new ArrayList<>();
Vector<DataTableRow> dataRows = new Vector<>();
// 为表添加列及列名
public DataTable addColTitle(String title){
titleCollection.add(title);
return this;
}
// 获得特定行的数据
public Collection<String> getRow(int index){
if(index >= getRowsSize()) throw new IndexOutOfBoundsException();
return dataRows.elementAt(index).getRow();
}
// 获得特定行的数据
public Vector<String> getRowVector(int index){
if(index >= getRowsSize()) throw new IndexOutOfBoundsException();
return new Vector<>(dataRows.elementAt(index).getRow());
}
// 从DataReader导入特定表
public void importTable(DataReader reader){
// 从文件中读取数据
reader.readFile();
// 读取列信息
titleCollection = reader.readColsTitle();
int rowsSize = reader.getRowsSize();
int index = 0;
for(int i = reader.firstDataRowIndex(); i < reader.lastDataRowIndex(); i++){
dataRows.add(new DataTableRow(index++, reader.readRow(i)));
// 检查是否列数一致
if(dataRows.lastElement().getColsSize() != this.getColsSize()) {
// 清空表数据
this.dataRows.clear();
throw new DataIllegalTableFormatException();
}
}
}
// 查找有无相关表头项
public Optional<Integer> getTitleIndex(String title){
int index = 0;
for(String dataTitle :titleCollection){
if(dataTitle.equals(title))
return Optional.of(index);
index++;
}
return Optional.empty();
}
// 导出表数据
public void exportTable(DataGenerator dataGenerator){
dataGenerator.setTableTitle(titleCollection);
for(DataTableRow row : dataRows){
dataGenerator.insertRow(row.getIndex(), row.getRow());
}
dataGenerator.save();
}
// 为表添加行
public void addRow(Collection<String> row){
Collection<String> dataRow = new ArrayList<>(row);
dataRows.add(new DataTableRow(dataRows.size() + 1, dataRow));
}
// 获得表的列数
public int getColsSize(){
return titleCollection.size();
}
// 获得表的行数
public int getRowsSize(){
return dataRows.size();
}
}

View File

@ -0,0 +1,21 @@
package com.codesdream.ase.component.datamanager;
import lombok.Data;
import java.util.Collection;
// 描述数据表的行
@Data
public class DataTableRow {
private int index;
private Collection<String> row;
public DataTableRow(int index, Collection<String> row){
this.index = index;
this.row = row;
}
public int getColsSize(){
return row.size();
}
}

View File

@ -0,0 +1,89 @@
package com.codesdream.ase.component.datamanager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.codesdream.ase.component.json.respond.JSONBaseRespondObject;
import com.codesdream.ase.exception.innerservererror.HandlingErrorsException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.fge.jsonpatch.JsonPatch;
import com.github.fge.jsonpatch.JsonPatchException;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
/**
* 处理JSON相关数据
*/
@Component
public class JSONParameter {
// 处理Request Body
public String getRequestBody(HttpServletRequest request){
try {
StringBuilder stringBuilder = new StringBuilder();
BufferedReader reader = request.getReader();
reader.reset();
String line;
while ((line = reader.readLine()) != null)
stringBuilder.append(line);
return stringBuilder.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// 提取Request中的JSON数据
public Optional<JSONObject> getJSONByRequest(HttpServletRequest request){
try {
JSONObject jsonParam = null;
String content = getRequestBody(request);
jsonParam = JSONObject.parseObject(content);
return Optional.ofNullable(jsonParam);
} catch (Exception e) {
e.printStackTrace();
return Optional.empty();
}
}
// 根据JSON对象构造JSON字符串用于返回
public String getJSONString(JSONObject json){
return json.toJSONString();
}
// 根据Java对象构造JSON字符串用于返回
public String getJSONString(Object object){
return JSON.toJSONString(object);
}
// 由JSON对象获得对应的Java对象
public <T> T getJavaObject(JSONObject json, Class<T> type){
return json.toJavaObject(type);
}
// 由Request获得对应的Java对象(常用于Post请求中)
public <T> Optional<T> getJavaObjectByRequest(HttpServletRequest request, Class<T> type){
Optional<JSONObject> json = getJSONByRequest(request);
return json.map(jsonObject -> getJavaObject(jsonObject, type));
}
public <T> T parsePathToObject(JsonPatch patch, T object){
try {
ObjectMapper mapper = new ObjectMapper();
JsonNode patched = patch.apply(mapper.convertValue(object, JsonNode.class));
return (T) mapper.treeToValue(patched, object.getClass());
} catch (JsonPatchException | JsonProcessingException e) {
throw new HandlingErrorsException(e.getMessage());
}
}
}

View File

@ -0,0 +1,12 @@
package com.codesdream.ase.component.datamanager;
import lombok.Data;
// 储存字符串标识的文件并可以转换为json进行传输
@Data
public class StringFile {
private String strData = null;
private String sha1Checker = null;
private Integer size = null;
private String type = "none";
}

View File

@ -0,0 +1,92 @@
package com.codesdream.ase.component.datamanager;
import com.codesdream.ase.component.auth.SHA1Encoder;
import com.codesdream.ase.exception.StringFileConvertException;
import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.*;
import java.util.Base64;
import java.util.Optional;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
// 将文件处理成可发送的字符串文件对象
@Component
public class StringFileGenerator {
@Resource
private SHA1Encoder encoder;
// 用过读入流创建一个字符串文件
public Optional<StringFile> generateStringFile(InputStream stream){
StringFile file = new StringFile();
// 字符串内容计算
file.setStrData(generateFile2String(stream));
if(file.getStrData() == null) return Optional.empty();
// 相关校验值计算
file.setSha1Checker(generateSHA1Checker(file.getStrData()));
file.setSize(file.getStrData().length());
return Optional.of(file);
}
private byte[] readSteamAll(InputStream stream) {
try {
byte[] bytes = new byte[stream.available()];
//检查文件书否完全读取
if (stream.read(bytes) != bytes.length) return null;
else return bytes;
} catch (IOException e){
return null;
}
}
private String generateFile2String(InputStream stream){
ByteArrayOutputStream zipDataStream = new ByteArrayOutputStream();
try {
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(zipDataStream);
byte[] bytes = readSteamAll(stream);
if(bytes == null) return null;
gzipOutputStream.write(bytes);
gzipOutputStream.close();
return Base64.getEncoder().encodeToString(zipDataStream.toByteArray());
} catch (IOException e) {
return null;
}
}
// 生成字符串文件的校验码
private String generateSHA1Checker(String str){
return encoder.encode(str);
}
// 检查文件内容是否正确包括大小与校验码
public boolean checkStringFile(StringFile file){
return file.getStrData().length() == file.getSize()
&& encoder.match(file.getStrData(), file.getSha1Checker());
}
// 从字符串文件中读取真实的文件数据
public InputStream readFileString(StringFile file){
try {
// 字符串转换为二进制数据
byte[] bytes = Base64.getDecoder().decode(file.getStrData());
GZIPInputStream stream = new GZIPInputStream(new ByteArrayInputStream(bytes), bytes.length);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// 数据解压缩
int readBits = 0;
byte[] rawBytes = new byte[1024];
while ((readBits = stream.read(rawBytes)) != -1) {
outputStream.write(rawBytes, 0, readBits);
}
stream.close();
return new ByteArrayInputStream(outputStream.toByteArray());
} catch (IOException e) {
throw new StringFileConvertException("Read FileString Failed");
}
}
}

View File

@ -0,0 +1,24 @@
package com.codesdream.ase.component.error;
import lombok.Data;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
@XmlRootElement(name = "error")
public class ErrorResponse
{
public ErrorResponse(String message, List<String> details) {
super();
this.message = message;
this.details = details;
}
//General error message about nature of error
private String message;
//Specific errors in API request processing
private List<String> details;
//Getter and setters
}

View File

@ -0,0 +1,12 @@
package com.codesdream.ase.component.json;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
// 所有有效的JSON对象模板
@Slf4j
public class JSONBaseObject {
Date time = new Date();
}

View File

@ -0,0 +1,5 @@
package com.codesdream.ase.component.json.form;
public class RegisterForm {
}

View File

@ -0,0 +1,38 @@
package com.codesdream.ase.component.json.model;
import com.codesdream.ase.model.permission.FunctionalPermissionContainer;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.NoArgsConstructor;
import springfox.documentation.spring.web.json.Json;
@Data
@NoArgsConstructor
@ApiModel("功能性权限容器")
public class JsonableFPC {
private Integer id;
private String name;
private String description;
private boolean enabled;
private boolean deleted;
public JsonableFPC(FunctionalPermissionContainer fpc){
this.id = fpc.getId();
this.name = fpc.getName();
this.description = fpc.getDescription();
this.enabled = fpc.isEnabled();
this.deleted = fpc.isDeleted();
}
public FunctionalPermissionContainer parseObject(FunctionalPermissionContainer fpc){
fpc.setName(this.name);
fpc.setDescription(this.description);
fpc.setEnabled(this.enabled);
fpc.setDeleted(this.deleted);
return fpc;
}
}

View File

@ -0,0 +1,62 @@
package com.codesdream.ase.component.json.model;
import com.codesdream.ase.exception.notfound.NotFoundException;
import com.codesdream.ase.model.permission.FunctionalPermissionContainer;
import com.codesdream.ase.model.permission.FunctionalScopeRelation;
import com.codesdream.ase.model.permission.ScopePermissionContainer;
import com.codesdream.ase.service.IPermissionService;
import com.codesdream.ase.service.PermissionService;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.web.bind.annotation.RequestParam;
import javax.annotation.Resource;
import java.util.Optional;
@Data
@NoArgsConstructor
@ApiModel("单项权力")
public class JsonableFSR {
private Integer id;
private String name;
private String description;
private Integer fpcId;
private Integer spcId;
@Resource
@ApiModelProperty(hidden = true)
private IPermissionService permissionService;
public JsonableFSR(FunctionalScopeRelation fsr){
this.id = fsr.getId();
this.name = fsr.getName();
this.description = fsr.getDescription();
this.fpcId = fsr.getFunctionalPermissionContainer().getId();
this.spcId = fsr.getScopePermissionContainer().getId();
}
public FunctionalScopeRelation parseObject(FunctionalScopeRelation fsr){
fsr.setName(this.name);
fsr.setDescription(this.description);
if(this.fpcId != null){
Optional<FunctionalPermissionContainer> fpc = permissionService.findFPC(this.fpcId);
if(!fpc.isPresent()) throw new NotFoundException(this.fpcId.toString());
fsr.setFunctionalPermissionContainer(fpc.get());
}
if(this.spcId != null){
Optional<ScopePermissionContainer> spc = permissionService.findSPC(this.spcId);
if(!spc.isPresent()) throw new NotFoundException(this.spcId.toString());
fsr.setScopePermissionContainer(spc.get());
}
return fsr;
}
}

View File

@ -0,0 +1,60 @@
package com.codesdream.ase.component.json.model;
import com.codesdream.ase.exception.notfound.NotFoundException;
import com.codesdream.ase.model.permission.Function;
import com.codesdream.ase.service.IPermissionService;
import com.codesdream.ase.service.PermissionService;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiParam;
import io.swagger.models.auth.In;
import lombok.Data;
import lombok.NoArgsConstructor;
import springfox.documentation.annotations.ApiIgnore;
import javax.annotation.Resource;
import java.util.Optional;
@Data
@NoArgsConstructor
@ApiModel("功能")
public class JsonableFunction {
private Integer id;
private String name;
private String description;
private Integer fatherId;
private String url;
@Resource
@ApiModelProperty(hidden = true)
private IPermissionService permissionService;
public JsonableFunction(Function function){
this.id = function.getId();
this.name = function.getName();
this.description = function.getDescription();
if(function.getFather() != null) {
this.fatherId = function.getFather().getId();
}
else this.fatherId = null;
this.url = function.getUrl();
}
public Function parseObject(Function function){
function.setName(this.name);
function.setDescription(this.description);
if(this.fatherId != null) {
Optional<Function> fatherFunction = permissionService.findFunction(this.fatherId);
if (!fatherFunction.isPresent()) throw new NotFoundException(fatherId.toString());
function.setFather(fatherFunction.get());
}
function.setUrl(this.url);
return function;
}
}

View File

@ -0,0 +1,22 @@
package com.codesdream.ase.component.json.model;
import com.codesdream.ase.model.permission.PermissionContainersCollection;
import com.codesdream.ase.model.permission.Tag;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@ApiModel("权限容器集合列表")
public class JsonablePCCList {
List<Integer> pccIdList;
public JsonablePCCList(Tag tag){
for(PermissionContainersCollection pcc : tag.getPermissionContainersCollections()){
pccIdList.add(pcc.getId());
}
}
}

View File

@ -0,0 +1,26 @@
package com.codesdream.ase.component.json.model;
import com.codesdream.ase.model.permission.Function;
import com.codesdream.ase.model.permission.FunctionalPermissionContainer;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashSet;
import java.util.Set;
@Data
@NoArgsConstructor
@ApiModel("功能性权限容器所属角色集合")
public class JsonableRoleList {
private Integer id;
private Set<Integer> functions = new HashSet<>();
public JsonableRoleList(FunctionalPermissionContainer fpc){
this.id = fpc.getId();
if(fpc.getFunctions() != null) {
for(Function function : fpc.getFunctions())
this.functions.add(function.getId());
}
}
}

View File

@ -0,0 +1,39 @@
package com.codesdream.ase.component.json.model;
import com.codesdream.ase.model.permission.ScopePermissionContainer;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@ApiModel("范围性权限容器")
public class JsonableSPC {
private Integer id;
private String name;
private String description;
private boolean enabled;
private boolean deleted;
public JsonableSPC(ScopePermissionContainer spc){
this.id = spc.getId();
this.name = spc.getName();
this.description = spc.getDescription();
this.enabled = spc.isEnabled();
this.deleted = spc.isDeleted();
}
public ScopePermissionContainer parseObject(ScopePermissionContainer spc){
spc.setName(this.name);
spc.setDescription(this.description);
spc.setEnabled(this.enabled);
spc.setDeleted(this.deleted);
return spc;
}
}

View File

@ -0,0 +1,48 @@
package com.codesdream.ase.component.json.model;
import com.codesdream.ase.model.permission.Tag;
import com.codesdream.ase.model.permission.User;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import net.bytebuddy.implementation.bind.annotation.DefaultMethod;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Data
@NoArgsConstructor
@ApiModel("标签")
public class JsonableTag {
@ApiModelProperty(value = "标签id")
private Integer id = null;
@ApiModelProperty(value = "标签名", example = "系统管理员")
private String name;
@ApiModelProperty(value = "标签说明", example = "该系统的管理员")
private String description;
private boolean enabled;
private boolean deleted;
public JsonableTag(Tag tag){
this.id = tag.getId();
this.name = tag.getName();
this.description = tag.getDescription();
this.enabled = tag.isEnabled();
this.deleted = tag.isDeleted();
}
public Tag parseObject(Tag tag){
tag.setName(this.name);
tag.setDescription(this.description);
tag.setDeleted(this.deleted);
tag.setEnabled(this.enabled);
return tag;
}
}

View File

@ -0,0 +1,6 @@
package com.codesdream.ase.component.json.model;
public class JsonableUidGetter {
private String checkType;
private String username;
}

View File

@ -0,0 +1,33 @@
package com.codesdream.ase.component.json.model;
import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.model.permission.UserAuth;
import com.codesdream.ase.model.permission.UserDetail;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@ApiModel("用户")
@NoArgsConstructor
public class JsonableUser {
private Integer id;
private String username;
private boolean enabled;
private boolean deleted;
public JsonableUser(User user){
this.id = user.getId();
this.username = user.getUsername();
this.enabled = user.isEnabled();
this.deleted= user.isDeleted();
}
public User parseObject(User user){
user.setEnabled(this.enabled);
user.setDeleted(this.deleted);
return user;
}
}

View File

@ -0,0 +1,13 @@
package com.codesdream.ase.component.json.request;
import com.codesdream.ase.component.json.JSONBaseObject;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
// 客户端请求的JSON模板
@Slf4j
public class JSONBaseRequestObject extends JSONBaseObject {
String signed;
}

View File

@ -0,0 +1,16 @@
package com.codesdream.ase.component.json.request;
import lombok.Data;
@Data
public class UserLeaveAuth {
/*
备注
*/
private int id;
private String Comment;
/*
审核结果
*/
private String newStat;
}

View File

@ -0,0 +1,15 @@
package com.codesdream.ase.component.json.request;
import lombok.Data;
import java.util.Date;
@Data
public class UserLeaveRequest {
private String UserId;//用户名
private String Type;//请假类型
private String Reason;//请假原因
private String Addon;//附件
private Date Starttime;//开始时间
private Date EndTime;//结束时间
}

View File

@ -0,0 +1,13 @@
package com.codesdream.ase.component.json.request;
import lombok.Data;
@Data
public class UserLoginChecker {
// 请求类型
private String checkType;
private String username;
private String password;
private String clientCode;
}

View File

@ -0,0 +1,19 @@
package com.codesdream.ase.component.json.request;
import lombok.Data;
@Data
public class UserRegisterChecker {
// 学号
private String studentId;
// 密码
private String password;
// 密保问题
private String userQuestion;
// 密保答案
private String userAnswer;
}

View File

@ -0,0 +1,8 @@
package com.codesdream.ase.component.json.request;
import lombok.Data;
@Data
public class UserSGettudentLeaveListRequest {
private int studentId;
}

View File

@ -0,0 +1,5 @@
package com.codesdream.ase.component.json.respond;
public class EmptyDataObjectRespond {
}

View File

@ -0,0 +1,12 @@
package com.codesdream.ase.component.json.respond;
import lombok.Data;
import java.util.Date;
@Data
public class ErrorInfoJSONRespond {
String exception = null;
String exceptionMessage = null;
Date date = null;
}

View File

@ -0,0 +1,61 @@
package com.codesdream.ase.component.json.respond;
import com.codesdream.ase.component.json.JSONBaseObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
// 服务端返回的JSON对象模板
@EqualsAndHashCode(callSuper = true)
@Data
public class JSONBaseRespondObject extends JSONBaseObject {
// 存放返回内容
private Object data = new EmptyDataObjectRespond();
// 存放响应信息提示
private String msg = "";
// 额外信息
private String info = null;
// 状态
private Integer status = 200;
public JSONBaseRespondObject(String msg){
super();
this.status = 200;
this.msg = msg;
}
public JSONBaseRespondObject(Integer status, String msg){
super();
this.status = status;
this.msg = msg;
}
public void setStatusNotFound(){
this.status = 404;
}
public void setStatusBadRequest(){
this.status = 400;
}
public void setStatusUnauthorized(){
this.status = 401;
}
public void setStatusForbidden(){
this.status = 403;
}
public void setStatusInternalServerError(){
this.status = 500;
}
public void setStatusOK(){
this.status = 200;
}
}

View File

@ -0,0 +1,8 @@
package com.codesdream.ase.component.json.respond;
// 请求失败返回JSON
public class JSONStandardFailedRespond extends JSONBaseRespondObject {
public JSONStandardFailedRespond(){
super(500, "failed");
}
}

View File

@ -0,0 +1,16 @@
package com.codesdream.ase.component.json.respond;
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.Data;
import java.util.List;
import java.util.Set;
@Data
public class PermissionJSONRespond {
private Boolean tagExist = null;
private Boolean actionSuccess = null;
private Integer tagId = null;
private String tagName = null;
private Set<Integer> users = null;
}

View File

@ -0,0 +1,17 @@
package com.codesdream.ase.component.json.respond;
import com.sun.org.apache.xpath.internal.operations.Bool;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
public class UserLoginCheckerJSONRespond {
Boolean userExist = null;
Boolean userBanned = null;
Boolean loginStatus = null;
String respondInformation = null;
String token = null;
String uid = null;
String pvc = null;
}

View File

@ -0,0 +1,6 @@
package com.codesdream.ase.component.json.respond;
// 返回登录后的授权码(用于客户端生成签名)
public class UserLoginTokenJSONRespond {
String token;
}

View File

@ -0,0 +1,19 @@
package com.codesdream.ase.component.permission;
import com.codesdream.ase.model.permission.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Collection;
@Component
public class UserAuthoritiesGenerator {
@Resource
UserFunctionsListGenerator userFunctionsListGenerator;
public Collection<? extends GrantedAuthority> grantedAuthorities(User user){
return userFunctionsListGenerator.generateRoles(user);
}
}

View File

@ -0,0 +1,41 @@
package com.codesdream.ase.component.permission;
import com.codesdream.ase.model.permission.*;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
/**
* 生成功能性权限容器列表
*/
@Component
public class UserFPCListGenerator {
@Resource
private UserFSRGenerator fsrListGenerator;
public Collection<FunctionalPermissionContainer> generateFPC(
Collection<FunctionalScopeRelation> functionalScopeRelations){
Collection<FunctionalPermissionContainer> functionalPermissionContainers
= new ArrayList<>();
for (FunctionalScopeRelation functionalScopeRelation : functionalScopeRelations){
functionalPermissionContainers.add(functionalScopeRelation.getFunctionalPermissionContainer());
}
return functionalPermissionContainers;
}
public Collection<FunctionalPermissionContainer> generateFPCs(User user){
return generateFPC(
fsrListGenerator.generateFSRs(user)
);
}
public Collection<FunctionalPermissionContainer> generateFPCs(String username){
return generateFPC(
fsrListGenerator.generateFSRs(username)
);
}
}

View File

@ -0,0 +1,45 @@
package com.codesdream.ase.component.permission;
import com.codesdream.ase.model.permission.FunctionalScopeRelation;
import com.codesdream.ase.model.permission.PermissionContainersCollection;
import com.codesdream.ase.model.permission.User;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
/**
* 生成功能性权限容器与范围性权限容器关联对列表
*/
@Component
public class UserFSRGenerator {
@Resource
private UserPCCListGenerator userPCCListGenerator;
public Collection<FunctionalScopeRelation> generateFSRs(
Collection<PermissionContainersCollection> pccs){
Collection<FunctionalScopeRelation> fsrs =
new ArrayList<>();
for(PermissionContainersCollection pcc : pccs){
fsrs.addAll(pcc.getFunctionalScopeRelations());
}
return fsrs;
}
public Collection<FunctionalScopeRelation> generateFSRs(
User user){
return generateFSRs(
userPCCListGenerator.generatePCCs(user));
}
public Collection<FunctionalScopeRelation> generateFSRs(
String username){
return generateFSRs(
userPCCListGenerator.generatePCCs(username));
}
}

View File

@ -0,0 +1,45 @@
package com.codesdream.ase.component.permission;
import com.codesdream.ase.model.permission.Function;
import com.codesdream.ase.model.permission.FunctionalPermissionContainer;
import com.codesdream.ase.model.permission.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
/**
* 生成用户访问权限角色列表
*/
@Component
public class UserFunctionsListGenerator {
@Resource
private UserFPCListGenerator fpcListGenerator;
public Collection<GrantedAuthority> generateRoles(
Collection<FunctionalPermissionContainer> fpcs){
Collection<GrantedAuthority> authorities = new ArrayList<>();
for(FunctionalPermissionContainer fpc :fpcs){
for(Function function :fpc.getFunctions()){
authorities.add(new SimpleGrantedAuthority(function.getName()));
}
}
return authorities;
}
public Collection<GrantedAuthority> generateRoles(String username){
return generateRoles(
fpcListGenerator.generateFPCs(username)
);
}
public Collection<GrantedAuthority> generateRoles(User user){
return generateRoles(
fpcListGenerator.generateFPCs(user)
);
}
}

View File

@ -0,0 +1,39 @@
package com.codesdream.ase.component.permission;
import com.codesdream.ase.model.permission.PermissionContainersCollection;
import com.codesdream.ase.model.permission.Tag;
import com.codesdream.ase.model.permission.User;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
/**
* 生成权限容器集合列表
*/
@Component
public class UserPCCListGenerator {
@Resource
private UserTagsListGenerator userTagsListGenerator;
public Collection<PermissionContainersCollection> generatePCCs(
Collection<Tag> tags){
Collection<PermissionContainersCollection> pccs =
new ArrayList<>();
for(Tag tag : tags){
pccs.addAll(tag.getPermissionContainersCollections());
}
return pccs;
}
public Collection<PermissionContainersCollection> generatePCCs(
User user) {
return generatePCCs(userTagsListGenerator.generateTags(user));
}
public Collection<PermissionContainersCollection> generatePCCs(
String username){
return generatePCCs(userTagsListGenerator.generateTags(username));
}
}

View File

@ -0,0 +1,54 @@
package com.codesdream.ase.component.permission;
import com.codesdream.ase.model.permission.ScopePermissionContainer;
import com.codesdream.ase.model.permission.Tag;
import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.repository.permission.UserRepository;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;
/**
* 生成用户标签列表
*/
@Component
public class UserTagsListGenerator {
@Resource
UserRepository userRepository;
public Collection<Tag> generateTags(ScopePermissionContainer spc){
return new ArrayList<>(spc.getTags());
}
public Collection<Tag> generateTags(User user){
return new ArrayList<Tag>(user.getTags());
}
public Collection<Tag> generateTags(String username){
Optional<User> user = userRepository.findByUsername(username);
// 检查用户是否存在
if(!user.isPresent()) throw new RuntimeException("User Not Found");
return generateTags(user.get());
}
public Collection<String> generateTagsName(User user){
Collection<String> tagsName = new ArrayList<>();
Collection<Tag> tags = generateTags(user);
for(Tag tag : tags){
tagsName.add(tag.getName());
}
return tagsName;
}
public Collection<String> generateTagsName(String username){
Optional<User> user = userRepository.findByUsername(username);
if(!user.isPresent()) throw new RuntimeException("User Not Found");
return generateTagsName(user.get());
}
}

View File

@ -0,0 +1,22 @@
package com.codesdream.ase.component.permission;
import com.codesdream.ase.model.permission.Tag;
import com.codesdream.ase.model.permission.User;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collection;
/**
* 生成用户列表
*/
@Component
public class UsersListGenerator {
public Collection<User> generateUsers(Collection<Tag> tags){
Collection<User> users = new ArrayList<>();
for(Tag tag : tags){
users.addAll(tag.getUsers());
}
return users;
}
}

View File

@ -0,0 +1,57 @@
package com.codesdream.ase.configure;
import com.google.common.collect.Sets;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.parameters.P;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Configuration
@EnableSwagger2
public class ASESwaggerConfigure {
@Bean
public Docket createRestApi() {
List<Parameter> pars = new ArrayList<Parameter>();
pars.add(new ParameterBuilder().name("username").description("真实用户名").hidden(true).order(1)
.modelRef(new ModelRef("string")).parameterType("header")
.required(false).defaultValue("u_id_88883b9e023c8824310760d8bb8b6542e5a3f16a0d67253214e01ee7ab0e96a1").build());
pars.add(new ParameterBuilder().name("signed").description("客户端签名").hidden(true).order(2)
.modelRef(new ModelRef("string")).parameterType("header")
.required(false).defaultValue("6d4923fca4dcb51f67b85e54a23a8d763d9e02af").build());
pars.add(new ParameterBuilder().name("timestamp").description("时间戳").hidden(true).order(3)
.modelRef(new ModelRef("string")).parameterType("header")
.required(false).defaultValue(Long.toString(new Date().getTime())).build());
return new Docket(DocumentationType.SWAGGER_2)
.protocols(Sets.newHashSet("http"))
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.codesdream.ase.controller"))
.paths(PathSelectors.any())
.build()
.globalOperationParameters(pars);
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("全员育人管理系统后端接口定义")
.version("0.0.1")
.description("用于对后端接口进行说明")
.build();
}
}

View File

@ -0,0 +1,37 @@
package com.codesdream.ase.configure;
import lombok.Data;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@Component
public class ActivityFormConfigure {
private final HashSet<String> stdActivityForm = new HashSet<String>(){{
add("title");
add("creator");
add("type");
add("description");
add("cycle");
add("volunteers");
add("participate");
add("sign");
add("visible");
add("inform");
add("start-time");
add("remind");
add("enclosure");
add("chief-manager");
add("assist-manager");
add("attendance");
}};
public HashSet<String> getStdActivityForm() {
return stdActivityForm;
}
}

View File

@ -0,0 +1,43 @@
package com.codesdream.ase.configure;
import org.springframework.stereotype.Component;
/**
* 应用程序常用配置信息
* 用于常见的应用程序本身的相关信息的引用
*/
@Component
public class AppConfigure {
/**
* 获得应用程序的中文名
* @return 返回包含完整内容的字符串
*/
public String getName() {
return "全员育人";
}
/**
* 获得应用程序的版本号
* @return 返回版本号内容的字符串
*/
public String getVersion() {
return "0.0.1_200204";
}
/**
* 获得应用程序的英文名
* @return 返回包含完整内容的字符串
*/
public String getEnglishName() {
return "All Staff Education";
}
/**
* 获得开发小组的名称
* @return 包含完整内容的字符串
*/
public String getOrganization() {
return "全员育人WEB端开发组";
}
}

View File

@ -0,0 +1,11 @@
package com.codesdream.ase.configure;
import com.codesdream.ase.component.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ComponentsConfigure {
}

View File

@ -0,0 +1,138 @@
package com.codesdream.ase.configure;
import com.codesdream.ase.component.auth.*;
import com.codesdream.ase.service.ASEUserDetailsService;
import org.springframework.context.annotation.Bean;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.annotation.Resource;
/**
* Spring Security 配置类
* 用于Spring Security相关参数的配置
*/
@Configuration
@EnableWebSecurity
public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
ASEUserDetailsService aseUserDetailService;
@Resource
ASEPasswordEncoder asePasswordEncoder;
@Resource
ASESecurityAuthenticationProvider aseSecurityAuthenticationProvider;
@Resource
ASEAuthenticationSuccessHandler successHandler;
@Resource
ASEAuthenticationFailureHandler failureHandler;
@Resource
ASEAuthenticationEntryPoint authenticationEntryPoint;
@Resource
ASEAccessDeniedHandler accessDeniedHandler;
@Resource
ASESecurityInterceptor securityInterceptor;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.csrf().disable()
.logout().permitAll();
http.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler);
// 替换掉原有的UsernamePasswordAuthenticationFilter
http.addFilterAt(aseUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(asejsonTokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterAt(securityInterceptor, FilterSecurityInterceptor.class);
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(aseSecurityAuthenticationProvider)
.userDetailsService(aseUserDetailService)
.passwordEncoder(asePasswordEncoder);
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers(
"/assets/**",
"/register/**",
"/forget/**",
"/not_found/**",
"/error/**",
"/login/**",
"/swagger-ui.html",
"/webjars/**",
"/swagger-resources/**",
"/v2/api-docs",
"/configuration/ui",
"/configuration/security");
}
//注册自定义的UsernamePasswordAuthenticationFilter
@Bean
ASEJSONTokenAuthenticationFilter asejsonTokenAuthenticationFilter() throws Exception {
return new ASEJSONTokenAuthenticationFilter();
}
//注册自定义的UsernamePasswordAuthenticationFilter
@Bean
ASEUsernamePasswordAuthenticationFilter aseUsernamePasswordAuthenticationFilter() throws Exception {
ASEUsernamePasswordAuthenticationFilter filter = new ASEUsernamePasswordAuthenticationFilter();
filter.setAuthenticationSuccessHandler(successHandler);
filter.setAuthenticationFailureHandler(failureHandler);
filter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy(sessionRegistry()));
filter.setAllowSessionCreation(true);
filter.setRequiresAuthenticationRequestMatcher(
new AntPathRequestMatcher("/login/token", "POST"));
filter.setAuthenticationManager(authenticationManagerBean());
return filter;
}
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
@Bean
public SessionAuthenticationStrategy sessionAuthenticationStrategy(SessionRegistry sessionRegistry){
return new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry){{
setMaximumSessions(1);
}};
}
}

View File

@ -0,0 +1,15 @@
package com.codesdream.ase.configure;
import org.springframework.context.annotation.Configuration;
/**
* Spring 框架全局配置类
* 主要用于注册或者管理Bean
*/
@Configuration
public class GlobalConfigure {
}

View File

@ -0,0 +1,14 @@
package com.codesdream.ase.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class APIController {
@RequestMapping("hello")
String hello(){
return "hello";
}
}

View File

@ -0,0 +1,26 @@
package com.codesdream.ase.controller;
import com.codesdream.ase.configure.GlobalConfigure;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.security.Principal;
/**
* 管理界面主页控制器类
* 现阶段主要用于管理界面主页
*/
@Controller
public class ASEController {
@Resource
GlobalConfigure globalConfigure;
@RequestMapping(value = "/")
public String printIndex(Model model, Principal principal){
model.addAttribute("username",principal.getName());
return "index";
}
}

View File

@ -0,0 +1,77 @@
package com.codesdream.ase.controller;
import com.codesdream.ase.component.api.QuickJSONRespond;
import com.codesdream.ase.component.json.respond.ErrorInfoJSONRespond;
import com.codesdream.ase.exception.badrequest.AlreadyExistException;
import com.codesdream.ase.exception.badrequest.IllegalException;
import com.codesdream.ase.exception.conflict.RelatedObjectsExistException;
import com.codesdream.ase.exception.innerservererror.FormatException;
import com.codesdream.ase.exception.innerservererror.HandlingErrorsException;
import com.codesdream.ase.exception.innerservererror.RuntimeIOException;
import com.codesdream.ase.exception.notfound.NotFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.annotation.Resource;
import java.util.Date;
@RestControllerAdvice
public class ASEControllerAdvice {
@Resource
private QuickJSONRespond quickJSONRespond;
@ExceptionHandler(value = {
NullPointerException.class,
AlreadyExistException.class,
IllegalException.class
})
public ResponseEntity<Object> handleBadRequest(Exception ex) {
return getResponse(HttpStatus.BAD_REQUEST, ex);
}
@ExceptionHandler(value = {NotFoundException.class})
public ResponseEntity<Object> handleNotFound(Exception ex) {
return getResponse(HttpStatus.NOT_FOUND, ex);
}
@ExceptionHandler(value = {})
public ResponseEntity<Object> handleNotAcceptable(Exception ex) {
return getResponse(HttpStatus.NOT_ACCEPTABLE, ex);
}
@ExceptionHandler(value = {RelatedObjectsExistException.class})
public ResponseEntity<Object> handleConflict(Exception ex) {
return getResponse(HttpStatus.CONFLICT, ex);
}
@ExceptionHandler(value = {
HandlingErrorsException.class,
FormatException.class,
RuntimeIOException.class})
public ResponseEntity<Object> handleInnerServerError(Exception ex){
return getResponse(HttpStatus.INTERNAL_SERVER_ERROR, ex);
}
private ResponseEntity<Object> getResponse(HttpStatus status, Exception ex){
return ResponseEntity.status(status).body(getJSON(status, ex));
}
private String getJSON(HttpStatus status, Exception ex){
return quickJSONRespond.getJSONStandardRespond(status, getJSONRespondObject(ex));
}
private Object getJSONRespondObject(Exception ex){
ErrorInfoJSONRespond errorInfoJSONRespond = new ErrorInfoJSONRespond();
errorInfoJSONRespond.setException(ex.getClass().getName());
errorInfoJSONRespond.setExceptionMessage(ex.getMessage());
errorInfoJSONRespond.setDate(new Date());
return errorInfoJSONRespond;
}
}

View File

@ -0,0 +1,84 @@
package com.codesdream.ase.controller;
import com.codesdream.ase.component.api.QuickJSONRespond;
import com.codesdream.ase.component.json.respond.ErrorInfoJSONRespond;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
@Controller
public class ASEErrorController implements ErrorController {
/* @RequestMapping("/error")
public String handleError(HttpServletRequest request, Model model){
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
// 无效异常访问检查
if(statusCode == null || exception == null)
model.addAttribute("if_active", false);
else {
model.addAttribute("if_active", true);
// 检查返回的状态
if (statusCode == HttpStatus.NOT_FOUND.value()) return "not_found";
model.addAttribute("http_status", statusCode);
// 检查是否含有引发异常
if (exception.getCause() == null) {
model.addAttribute("exception_name", exception.getClass().getName());
model.addAttribute("exception_message", exception.getMessage());
} else {
model.addAttribute("exception_name", exception.getCause().getClass().getName());
model.addAttribute("exception_message", exception.getCause().getMessage());
}
List<String> stack_infos = new ArrayList<>();
for (StackTraceElement element : exception.getStackTrace()) {
String s = element.toString();
stack_infos.add(s);
}
model.addAttribute("error_stack", stack_infos);
model.addAttribute("exception_date", new Date());
}
return "error";
}*/
@Resource
private QuickJSONRespond quickJSONRespond;
@RequestMapping("/error")
@ResponseBody
public String handleError(HttpServletRequest request){
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
// 检查返回的状态
if (statusCode == HttpStatus.NOT_FOUND.value()) return quickJSONRespond.getRespond404(null);
ErrorInfoJSONRespond errorInfoJSONRespond = new ErrorInfoJSONRespond();
// 检查是否含有引发异常
if (exception.getCause() == null) {
errorInfoJSONRespond.setException(exception.getClass().getName());
errorInfoJSONRespond.setExceptionMessage(exception.getMessage());
} else {
errorInfoJSONRespond.setException(exception.getCause().getClass().getName());
errorInfoJSONRespond.setExceptionMessage(exception.getCause().getMessage());
}
errorInfoJSONRespond.setDate(new Date());
return quickJSONRespond.getJSONStandardRespond(
statusCode,
"Internal Server Error",
null,
errorInfoJSONRespond);
}
@Override
public String getErrorPath() {
return "/error";
}
}

View File

@ -0,0 +1,42 @@
package com.codesdream.ase.controller;
import com.codesdream.ase.component.ASESpringUtil;
import com.codesdream.ase.component.datamanager.DataModelRepositorySearcher;
import com.codesdream.ase.component.datamanager.DataModelSearcher;
import org.apache.catalina.core.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.w3c.dom.Entity;
import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.*;
@Controller
@RequestMapping(value = "/database")
public class DataManagerController {
@Resource
ASESpringUtil springUtil;
@RequestMapping(value = "{subSystem}/{dataModel}/query")
public String queryView(Model model, @PathVariable String dataModel, @PathVariable String subSystem) {
DataModelRepositorySearcher dataModelRepositorySearcher = springUtil.getBean(DataModelRepositorySearcher.class);
DataModelSearcher dataModelSearcher = springUtil.getBean(DataModelSearcher.class);
dataModelSearcher.getDataModelClass(subSystem, dataModel);
if(!dataModelSearcher.isPresent()){
throw new RuntimeException("Data Model Not Found");
}
dataModelRepositorySearcher.getDataModelRepositoryClass(subSystem, dataModel);
if(!dataModelRepositorySearcher.isPresent()){
throw new RuntimeException("Data Model Repository Not Found");
}
Map<String, Object> data;
return "query";
}
}

View File

@ -0,0 +1,37 @@
package com.codesdream.ase.controller;
import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.service.IUserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.security.Principal;
import java.util.Optional;
@Controller
public class HomeController {
@Resource
IUserService userService;
@RequestMapping(value = "/home")
public String showHomeView(Model model, Principal principal){
Optional<User> userOptional = userService.findUserByUsername(principal.getName());
if(!userOptional.isPresent()) return "error";
User user = userOptional.get();
// 为视图模板指定参数
model.addAttribute("username", user.getUsername().substring(0, 18));
model.addAttribute("real_name", user.getUserDetail().getRealName());
model.addAttribute("sex", user.getUserDetail().getSex());
model.addAttribute("student_id", user.getUserAuth().getStudentID());
model.addAttribute("class_id", user.getUserDetail().getClassId());
model.addAttribute("college", user.getUserDetail().getBaseCollege().getName());
model.addAttribute("ethnic", user.getUserDetail().getBaseEthnic().getName());
model.addAttribute("major", user.getUserDetail().getBaseMajor().getName());
model.addAttribute("is_at_school", user.getUserDetail().isAtSchool());
model.addAttribute("ethnic", user.getUserDetail().getBaseEthnic().getName());
model.addAttribute("mail", user.getUserAuth().getMail());
return "home";
}
}

View File

@ -0,0 +1,115 @@
package com.codesdream.ase.controller;
import com.alibaba.fastjson.JSONObject;
import com.codesdream.ase.component.api.QuickJSONRespond;
import com.codesdream.ase.component.auth.ASEUsernameEncoder;
import com.codesdream.ase.component.datamanager.JSONParameter;
import com.codesdream.ase.component.json.request.UserLeaveAuth;
import com.codesdream.ase.component.json.request.UserLeaveRequest;
import com.codesdream.ase.component.json.request.UserSGettudentLeaveListRequest;
import com.codesdream.ase.component.json.respond.JSONStandardFailedRespond;
import com.codesdream.ase.exception.innerservererror.InvalidFormFormatException;
import com.codesdream.ase.exception.notfound.NotFoundException;
import com.codesdream.ase.model.leaves.Leave;
import com.codesdream.ase.service.LeavesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.Optional;
/**
* 登录界面控制器类
*/
@Slf4j
@Controller
public class LeavesController {
@Resource
private JSONParameter jsonParameter;
@Resource
private QuickJSONRespond quickJSONRespond;
@Resource
private LeavesService leavesService;
@Resource
private ASEUsernameEncoder usernameEncoder;
/* @RequestMapping(value = "/")
String printLeave(Model model) {
return "Leave";
}*/
//提交请假申请
@RequestMapping(value = "/Leave/check", method = RequestMethod.POST)
@ResponseBody
String leaveRequest(HttpServletRequest request){
// 检查是否为JSON
Optional<JSONObject> json = jsonParameter.getJSONByRequest(request);
if(!json.isPresent()) return jsonParameter.getJSONString(new JSONStandardFailedRespond());
UserLeaveRequest userLeaveRequest=json.get().toJavaObject(UserLeaveRequest.class);
Leave newleave=new Leave();
newleave.setUserFrom(userLeaveRequest.getUserId());
newleave.setType(userLeaveRequest.getType());
newleave.setReasonToLeave(userLeaveRequest.getReason());
//newleave.set
newleave.setStartTime(userLeaveRequest.getStarttime());
newleave.setEndTime(userLeaveRequest.getEndTime());
Calendar calendar =Calendar.getInstance();
Date time = calendar.getTime();
newleave.setApplyTime(time);
leavesService.save(newleave);
//eturn quickJSONRespond.getRespond200(null, respond);
return quickJSONRespond.getRespond200("申请已提交");
// 检查类型
}
@RequestMapping(value = "/Leave/auth", method = RequestMethod.POST)
@ResponseBody
String getLeaveAuth(HttpServletRequest request){
// 检查是否为JSON
Optional<JSONObject> json = jsonParameter.getJSONByRequest(request);
if(!json.isPresent()) return jsonParameter.getJSONString(new JSONStandardFailedRespond());
UserLeaveAuth userLeaveAuth=json.get().toJavaObject(UserLeaveAuth.class);
Optional<Leave> leave =leavesService.findLeaveById(userLeaveAuth.getId());
if(!leave.isPresent()){
return quickJSONRespond.getRespond500("No such entry");
}
Leave newLeave=leave.get();
newLeave.setComment(userLeaveAuth.getComment());
newLeave.setAuthentication(userLeaveAuth.getNewStat());
return quickJSONRespond.getRespond200("Authentication status updated");
}
@RequestMapping(value = "/Leave/getStuLeaveList", method = RequestMethod.POST)
@ResponseBody
Leave getStuLeavelist(HttpServletRequest request) throws InvalidFormFormatException {
Optional<JSONObject> json = jsonParameter.getJSONByRequest(request);
if(!json.isPresent()) throw new InvalidFormFormatException("json request not recognized");
UserSGettudentLeaveListRequest userSGettudentLeaveListRequest=json.get().toJavaObject(UserSGettudentLeaveListRequest.class);
if(leavesService.findLeaveById(userSGettudentLeaveListRequest.getStudentId()).isPresent()){
Leave leave =leavesService.findLeaveById(userSGettudentLeaveListRequest.getStudentId()).get();
return leave;
}else{
throw new NotFoundException("Student Does not exist");
}
}
}

View File

@ -0,0 +1,106 @@
package com.codesdream.ase.controller;
import com.alibaba.fastjson.JSONObject;
import com.codesdream.ase.component.datamanager.JSONParameter;
import com.codesdream.ase.component.api.QuickJSONRespond;
import com.codesdream.ase.component.json.respond.JSONStandardFailedRespond;
import com.codesdream.ase.component.json.request.UserLoginChecker;
import com.codesdream.ase.component.json.respond.UserLoginCheckerJSONRespond;
import com.codesdream.ase.service.IAuthService;
import com.codesdream.ase.service.IUserService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;
/**
* 登录界面控制器类
*/
@Slf4j
@Controller
@Api(tags = "用户登录有关接口")
public class LoginController {
@Resource
private JSONParameter jsonParameter;
@Resource
private QuickJSONRespond quickJSONRespond;
@Resource
private IUserService userService;
@Resource
private IAuthService authService;
@PostMapping(value = "/login/check_exists")
@ResponseBody
String checkExists(HttpServletRequest request){
// 检查是否为JSON
Optional<JSONObject> json = jsonParameter.getJSONByRequest(request);
if(!json.isPresent()) return quickJSONRespond.getRespond400("Invalid JSON Form");
UserLoginChecker loginChecker = json.get().toJavaObject(UserLoginChecker.class);
// 检查学号对应的用户名是否存在
if(loginChecker.getCheckType().equals("UsernameExistChecker")){
// 根据学号计算用户名
String user = userService.getUsernameByStudentId(loginChecker.getUsername());
// 查询用户名存在状态
boolean existStatus = userService.checkIfUserExists(user).getKey();
// 构造返回对象
UserLoginCheckerJSONRespond respond = new UserLoginCheckerJSONRespond();
respond.setUserExist(existStatus);
return quickJSONRespond.getRespond200(null, respond);
}
else {
// 返回失败对象
return quickJSONRespond.getRespond400("CheckType Mismatch");
}
}
// 根据学号计算对应的username
@RequestMapping(value = "/login/check_uid", method = RequestMethod.POST)
@ResponseBody
String checkUsernameByStudentID(HttpServletRequest request){
String preValidationCode = request.getHeader("pvc");
// 检查随机预验证码
if(preValidationCode == null || !authService.preValidationCodeChecker(preValidationCode))
return quickJSONRespond.getRespond403("Invalid PreValidationCode");
// 检查是否为JSON
Optional<JSONObject> json = jsonParameter.getJSONByRequest(request);
if(!json.isPresent()) return jsonParameter.getJSONString(new JSONStandardFailedRespond());
UserLoginChecker loginChecker = json.get().toJavaObject(UserLoginChecker.class);
if(loginChecker.getUsername() == null || loginChecker.getCheckType() == null)
return quickJSONRespond.getRespond406("Request Violates The Interface Protocol");
if(loginChecker.getCheckType().equals("UIDGeneratorChecker")) {
UserLoginCheckerJSONRespond respond = new UserLoginCheckerJSONRespond();
respond.setUid(userService.getUsernameByStudentId(loginChecker.getUsername()));
return quickJSONRespond.getRespond200(null, respond);
}
else {
// 返回失败对象
return quickJSONRespond.getRespond400("CheckType Mismatch");
}
}
}

View File

@ -0,0 +1,97 @@
package com.codesdream.ase.controller;
import com.codesdream.ase.component.datamanager.JSONParameter;
import com.codesdream.ase.component.api.QuickJSONRespond;
import com.codesdream.ase.component.json.request.UserRegisterChecker;
import com.codesdream.ase.model.information.BaseStudentInfo;
import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.service.BaseInformationService;
import com.codesdream.ase.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;
@Controller
public class RegisterController {
@Resource
private UserService userService;
@Resource
private BaseInformationService baseInformationService;
@Resource
private JSONParameter jsonParameter;
@Resource
private QuickJSONRespond quickJSONRespond;
@RequestMapping(value = "/register")
String registerView(Model model){
return "register";
}
// 处理注册表单
@PostMapping(value = "/register/do_register")
@ResponseBody
String doRegister(HttpServletRequest request){
Optional<UserRegisterChecker> registerCheckerOptional =
jsonParameter.getJavaObjectByRequest(request, UserRegisterChecker.class);
// 检查JSON是否完整
if(!registerCheckerOptional.isPresent()){
return quickJSONRespond.getRespond400("Illegal JSON Format");
}
// 检查数据是否完整
UserRegisterChecker registerChecker = registerCheckerOptional.get();
if(registerChecker.getPassword() == null
|| registerChecker.getStudentId() == null
|| registerChecker.getUserAnswer() == null
|| registerChecker.getUserQuestion() == null){
return quickJSONRespond.getRespond400("Incomplete Data");
}
// 获得提交学号
String student_id = registerChecker.getStudentId();
// 获得密保问题
String user_question = registerChecker.getUserQuestion();
// 获得密保答案
String user_answer = registerChecker.getUserAnswer();
// 检查用户的基本信息是否录入系统
if(!baseInformationService.checkStudentInfo(student_id))
return quickJSONRespond.getRespond500("StudentID Base Information Not Found");
// 检查学号是否已被注册
if(userService.checkIfUserExists(userService.getUsernameByStudentId(student_id)).getKey()){
return quickJSONRespond.getRespond500("StudentID Already Used");
}
// 查找对应的基本信息
BaseStudentInfo studentInfo = baseInformationService.findStudentInfoByStudentId(student_id);
// 根据基本信息生成对应用户
User user = userService.createUserByStudentInfo(studentInfo);
// 填充密保问题
user.getUserAuth().setUserQuestion(user_question);
user.getUserAuth().setUserAnswer(user_answer);
user.getUserAuth().setMail("");
String password = registerChecker.getPassword();
user.setPassword(password);
userService.save(user);
// 成功注册
return quickJSONRespond.getRespond200("Register Success");
}
}

View File

@ -0,0 +1,16 @@
package com.codesdream.ase.controller.activity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
@Controller
@RequestMapping("/act")
public class ActivityAttendanceController {
private final String url = "/forget";
}

View File

@ -0,0 +1,155 @@
package com.codesdream.ase.controller.activity;
import com.alibaba.fastjson.JSONObject;
import com.codesdream.ase.component.ASESpringUtil;
import com.codesdream.ase.component.activity.ActivityConverter;
import com.codesdream.ase.component.activity.NullValueAttributes;
import com.codesdream.ase.component.datamanager.JSONParameter;
import com.codesdream.ase.component.json.respond.JSONStandardFailedRespond;
import com.codesdream.ase.configure.ActivityFormConfigure;
import com.codesdream.ase.exception.innerservererror.InvalidFormFormatException;
import com.codesdream.ase.model.activity.Activity;
import com.codesdream.ase.model.activity.UserActivity;
import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.repository.activity.UserActivityRepository;
import com.codesdream.ase.service.ActivityService;
import com.codesdream.ase.service.UserService;
import com.codesdream.ase.validator.ActivityValidator;
import com.codesdream.ase.validator.NullValueValidator;
import com.codesdream.ase.validator.JSONFormValidator;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Optional;
@Controller
@RequestMapping("/forget/act")
public class ActivityCreatorController {
@Resource
ActivityService activityService;
@Resource
JSONParameter jsonParameter;
@Resource
ASESpringUtil aseSpringUtil;
@Resource
ActivityFormConfigure activityFormConfigure;
@Resource
JSONFormValidator jsonFormValidator;
@Resource
NullValueValidator nullValueValidator;
@Resource
NullValueAttributes nullValueAttributes;
@Resource
ActivityValidator activityValidator;
@Resource
UserService userService;
@Resource
UserActivityRepository userActivityRepository;
@Resource
ActivityConverter activityConverter;
@PostMapping(value = "/creator")
@ResponseBody
@ApiOperation(value = "创建活动", notes = "所有有关用户的数据传递均使用id类型为int")
@ApiImplicitParams({
@ApiImplicitParam(name = "title", value = "活动标题", dataType = "String", required = true),
@ApiImplicitParam(name = "type", value = "活动类型", dataType = "String", required = true),
@ApiImplicitParam(name = "start-time", value = "活动开始时间格式为yyyy-MM-dd HH:mm:ss", required = true),
@ApiImplicitParam(name = "end-time", value = "活动结束时间格式为yyyy-MM-dd HH:mm:ss", required = true),
@ApiImplicitParam(name = "chief-manager", dataType = "int", value = "主要负责人", required = true),
@ApiImplicitParam(name = "assist-managers", dataType = "int", value = "次要负责人"),
@ApiImplicitParam(name = "description", dataType = "String", value = "活动描述"),
@ApiImplicitParam(name = "cycle", dataType = "String", value = "活动周期,格式为阿拉伯数字数字+单位0表示无周期"),
@ApiImplicitParam(name = "participate-group", value = "预定参与人员"),
@ApiImplicitParam(name = "sign-group", dataType = "List<int>", value = "可参与人员"),
@ApiImplicitParam(name = "inform-group", dataType = "List<int>", value = "通知人群,若为空,则默认为预定参与人员和可报名人员的并集"),
@ApiImplicitParam(name = "visible-group", dataType = "List<int>", value = "活动可见人群,若为空,则默认为负责人、活动创建者预定参和可报名人员以及通知人员的并集"),
@ApiImplicitParam(name = "remind-time", dataType = "String", defaultValue = "30m", value = "活动提醒时间,格式为数字+单位,可接受的单位从大到小有:w,d,h,m,s"),
})
String activityCreator(HttpServletRequest request) throws InvalidFormFormatException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
JSONObject error = new JSONObject();
aseSpringUtil = new ASESpringUtil();
//判断是否为JSON对象
Optional<JSONObject> json = jsonParameter.getJSONByRequest(request);
if (!json.isPresent()) return jsonParameter.getJSONString(new JSONStandardFailedRespond());
List<String> formatCheckResult = jsonFormValidator.check(activityFormConfigure.getStdActivityForm(), json.get());
//检验JSON格式是否有误
if (!formatCheckResult.isEmpty()) {
error.put("error", formatCheckResult);
throw new InvalidFormFormatException(error.toJSONString());
}
Activity activity = activityConverter.convertToActivity(json);
List<String> nullValues = nullValueValidator.checkNullValues(activity);
for (String str : nullValues){
if(str.equals("title")){
nullValueAttributes.getNullValueAttributes().add("title");
}
else if(str.equals("creator")){
nullValueAttributes.getNullValueAttributes().add("creator");
}
else if(str.equals("type")){
nullValueAttributes.getNullValueAttributes().add("type");
}
else if(str.equals("planPeriod")){
nullValueAttributes.getNullValueAttributes().add("planPeriod");
}
else if(str.equals("chiefManager")){
nullValueAttributes.getNullValueAttributes().add("chiefManager");
}
}
//如果为空存下此活动并跳转至成功创建页面
if (!nullValueAttributes.getNullValueAttributes().isEmpty()) {
String[] errorParameters = activityValidator.check(json);
if(errorParameters != null){
JSONObject invalidParameters = new JSONObject();
invalidParameters.put("invalid_parameters", errorParameters);
return invalidParameters.toJSONString();
}
else{
activity = activityService.createActivity(activity);
String username = json.get().get("creator").toString();
Optional<User> user = userService.findUserByUsername(username);
UserActivity userActivity = userActivityRepository.findByUser(user.get());
userActivity.getCreatedActs().add(activity);
userActivityRepository.save(userActivity);
}
}
//否则返回一个JSON对象给前端
else{
JSONObject nullParameters = new JSONObject();
nullParameters.put("null_values",nullValueAttributes.getNullValueAttributes());
return nullParameters.toJSONString();
}
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(activity);
return jsonObject.toJSONString();
}
}

View File

@ -0,0 +1,94 @@
package com.codesdream.ase.controller.activity;
import com.alibaba.fastjson.JSONObject;
import com.codesdream.ase.model.activity.Activity;
import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.service.ActivityService;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@Controller
@RequestMapping("/forget/act")
public class ActivityViewerController {
@Resource
ActivityService activityService;
@GetMapping("/created_acts")
String showCreated() {
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List<Activity> activities = activityService.findCreatedActs(user);
return JSONObject.toJSONString(activities);
}
@GetMapping("/parting_acts")
String showParticipate(HttpServletRequest request) {
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List<Activity> activities = activityService.findParticipatingActs(user);
return JSONObject.toJSONString(activities);
}
@GetMapping("/parted_acts")
String showParticipated() {
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List<Activity> activities = activityService.findParticipatedActs(user);
return JSONObject.toJSONString(activities);
}
@GetMapping("/sign_acts")
String showSign() {
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List<Activity> activities = activityService.findSignActs(user);
return JSONObject.toJSONString(activities);
}
@GetMapping("/vis_acts")
String showVisible() {
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List<Activity> activities = activityService.findVisibleActs(user);
return JSONObject.toJSONString(activities);
}
@GetMapping("/all")
String showAll() {
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List<Activity> activities = activityService.findAll(user);
return JSONObject.toJSONString(activities);
}
@GetMapping("/main_responsible_acts")
String showMainResponsible() {
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List<Activity> activities = activityService.findMainResponsibleActs(user);
return JSONObject.toJSONString(activities);
}
@GetMapping("/sec_responsible_acts")
String showSecondaryResponsible() {
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List<Activity> activities = activityService.findSecondaryResponsibleActs(user);
return JSONObject.toJSONString(activities);
}
@GetMapping("/acts_by_type")
String showInType(@RequestParam(defaultValue = "考勤", name = "type") String type) {
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
List<Activity> activities = activityService.findActivityByType(user, type);
return JSONObject.toJSONString(activities);
}
}

View File

@ -0,0 +1,36 @@
package com.codesdream.ase.controller.activity;
import com.codesdream.ase.component.activity.QrCodeUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
@Controller
public class QRCodeController {
/**
* 二维码
*
* @param request
* @param response
*/
@GetMapping("/qrcode")
public void qrCode(HttpServletRequest request, HttpServletResponse response) {
StringBuffer url = request.getRequestURL();
// 域名
String tempContextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append("/").toString();
// 再加上请求链接
String requestUrl = tempContextUrl + "/index";
try {
OutputStream os = response.getOutputStream();
QrCodeUtils.encode(requestUrl, "", os, true);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,169 @@
package com.codesdream.ase.controller.permission;
import com.codesdream.ase.component.datamanager.JSONParameter;
import com.codesdream.ase.component.json.model.JsonableFPC;
import com.codesdream.ase.component.json.model.JsonableFunction;
import com.codesdream.ase.component.json.model.JsonableRoleList;
import com.codesdream.ase.component.json.model.JsonableUser;
import com.codesdream.ase.exception.badrequest.AlreadyExistException;
import com.codesdream.ase.exception.notfound.NotFoundException;
import com.codesdream.ase.model.permission.Function;
import com.codesdream.ase.model.permission.FunctionalPermissionContainer;
import com.codesdream.ase.model.permission.Tag;
import com.codesdream.ase.model.permission.User;
import com.codesdream.ase.service.PermissionService;
import com.github.fge.jsonpatch.JsonPatch;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.spring.web.json.Json;
import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@RestController
@RequestMapping(value = "pmt")
@Api(tags = "功能性权限容器接口")
public class FPCController {
@Resource
private PermissionService permissionService;
@Resource
private JSONParameter jsonParameter;
@GetMapping("fpc")
@ResponseStatus(HttpStatus.OK)
@ApiOperation(value = "查找功能性权限容器")
public JsonableFPC getFPC(@RequestParam(value = "id") Integer id){
Optional<FunctionalPermissionContainer> fpc = permissionService.findFPC(id);
if(!fpc.isPresent()) throw new NotFoundException(id.toString());
return new JsonableFPC(fpc.get());
}
@PostMapping("fpc")
@ResponseStatus(HttpStatus.CREATED)
@ApiOperation(value = "创建新的功能性权限容器")
public JsonableFPC createFPC(@RequestBody JsonableFPC fpc){
if(permissionService.findFPC(fpc.getName()).isPresent()) throw new AlreadyExistException(fpc.getName());
FunctionalPermissionContainer functionalPermissionContainer = new FunctionalPermissionContainer();
return new JsonableFPC(permissionService.save(fpc.parseObject(functionalPermissionContainer)));
}
@GetMapping("fpcs")
@ResponseStatus(HttpStatus.OK)
@ApiOperation(value = "获得所有功能性权限容器的信息")
public Set<JsonableFPC> listFPC(){
Iterable<FunctionalPermissionContainer> fpcs = permissionService.findAllFPC();
Set<JsonableFPC> jsonableFPCS = new HashSet<>();
for(FunctionalPermissionContainer fpc : fpcs){
jsonableFPCS.add(new JsonableFPC(fpc));
}
return jsonableFPCS;
}
@GetMapping("fpc/roles")
@ResponseStatus(HttpStatus.OK)
@ApiOperation(value = "获得功能性权限容器所属角色")
public JsonableRoleList getFPCRoleList(@RequestParam(value = "id") Integer id){
Optional<FunctionalPermissionContainer> functionalPermissionContainer =
permissionService.findFPC(id);
if(!functionalPermissionContainer.isPresent()) throw new NotFoundException(id.toString());
return new JsonableRoleList(functionalPermissionContainer.get());
}
@PatchMapping("fpc")
@ResponseStatus(HttpStatus.CREATED)
@ApiOperation(value = "更新标功能性权限容器内容")
public JsonableFPC patchFPC(@RequestParam(value = "id") Integer id, @RequestBody JsonPatch patch){
Optional<FunctionalPermissionContainer> fpc = permissionService.findFPC(id);
if(!fpc.isPresent()) throw new NotFoundException(id.toString());
JsonableFPC jsonableFPC = new JsonableFPC(fpc.get());
jsonableFPC = jsonParameter.parsePathToObject(patch, jsonableFPC);
return new JsonableFPC(permissionService.update(jsonableFPC.parseObject(fpc.get())));
}
@GetMapping("fpc/funcs")
@ResponseStatus(HttpStatus.OK)
@ApiOperation(value = "功能性权限容器所含功能集合")
public Set<JsonableFunction> getFunctionFPC(@RequestParam(value = "id") Integer id){
Optional<FunctionalPermissionContainer> fpc = permissionService.findFPC(id);
if(!fpc.isPresent()) throw new NotFoundException(id.toString());
Set<JsonableFunction> jsonableFunctions = new HashSet<>();
for(Function function : fpc.get().getFunctions()){
jsonableFunctions.add(new JsonableFunction(function));
}
return jsonableFunctions;
}
@PutMapping("fpc/funcs")
@ApiOperation("搜索单个功能性权限容器所属功能集合信息")
public Set<JsonableFunction> setFunctionFPC(@RequestParam(value = "id") Integer id,
@RequestBody List<Integer> functionIdList){
Optional<FunctionalPermissionContainer> fpc = permissionService.findFPC(id);
if(!fpc.isPresent()) throw new NotFoundException(id.toString());
Set<Integer> functionSet = new HashSet<>(functionIdList);
fpc.get().setFunctions(permissionService.findFunctions(functionSet));
Set<JsonableFunction> jsonableFunctions = new HashSet<>();
for(Function function : permissionService.update(fpc.get()).getFunctions()){
jsonableFunctions.add(new JsonableFunction(function));
}
return jsonableFunctions;
}
@PostMapping("fpc/funcs")
@ApiOperation("从单个功能性权限容器所属功能集合中添加一个或多个功能")
public Set<JsonableFunction> addFunctionFPC(@RequestParam(value = "id") Integer id,
@RequestBody List<Integer> functionIdList){
Optional<FunctionalPermissionContainer> fpc = permissionService.findFPC(id);
if(!fpc.isPresent()) throw new NotFoundException(id.toString());
Set<Function> newFunctionSet = permissionService.findFunctions(new HashSet<>(functionIdList));
Set<Function> functionSet = fpc.get().getFunctions();
functionSet.addAll(newFunctionSet);
fpc.get().setFunctions(functionSet);
Set<JsonableFunction> jsonableFunctions = new HashSet<>();
for(Function function : permissionService.update(fpc.get()).getFunctions()){
jsonableFunctions.add(new JsonableFunction(function));
}
return jsonableFunctions;
}
@DeleteMapping("fpc/funcs")
@ResponseStatus(HttpStatus.OK)
@ApiOperation("从单个功能性权限容器所属功能集合中删除一个或多个功能")
public Set<JsonableFunction> deleteUserTag(@RequestParam Integer id,
@RequestBody List<Integer> functionIdList){
Optional<FunctionalPermissionContainer> fpc = permissionService.findFPC(id);
if(!fpc.isPresent()) throw new NotFoundException(id.toString());
Set<Function> functionSet = fpc.get().getFunctions();
Set<Function> deleteFuncSet = permissionService.findFunctions(new HashSet<>(functionIdList));
functionSet.removeAll(deleteFuncSet);
fpc.get().setFunctions(functionSet);
Set<JsonableFunction> jsonableFunctions = new HashSet<>();
for(Function function : permissionService.update(fpc.get()).getFunctions()){
jsonableFunctions.add(new JsonableFunction(function));
}
return jsonableFunctions;
}
}

View File

@ -0,0 +1,78 @@
package com.codesdream.ase.controller.permission;
import com.codesdream.ase.component.datamanager.JSONParameter;
import com.codesdream.ase.component.json.model.JsonableFPC;
import com.codesdream.ase.component.json.model.JsonableFunction;
import com.codesdream.ase.component.json.model.JsonableRoleList;
import com.codesdream.ase.exception.badrequest.AlreadyExistException;
import com.codesdream.ase.exception.notfound.NotFoundException;
import com.codesdream.ase.model.permission.Function;
import com.codesdream.ase.model.permission.FunctionalPermissionContainer;
import com.codesdream.ase.service.PermissionService;
import com.github.fge.jsonpatch.JsonPatch;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
@RestController
@RequestMapping(value = "pmt")
@Api(tags = "功能接口")
public class FunctionController {
@Resource
private PermissionService permissionService;
@Resource
private JSONParameter jsonParameter;
@GetMapping("func")
@ResponseStatus(HttpStatus.OK)
@ApiOperation(value = "查找功能")
public JsonableFunction getFunction(@RequestParam(value = "id") Integer id){
Optional<Function> function = permissionService.findFunction(id);
if(!function.isPresent()) throw new NotFoundException(id.toString());
return new JsonableFunction(function.get());
}
@PostMapping("func")
@ResponseStatus(HttpStatus.CREATED)
@ApiOperation(value = "创建新的功能")
public JsonableFunction createFunction(@RequestBody JsonableFunction function){
if(permissionService.findFunction(function.getName()).isPresent())
throw new AlreadyExistException(function.getName());
return new JsonableFunction(permissionService.save(function.parseObject(new Function())));
}
@GetMapping("funcs")
@ResponseStatus(HttpStatus.OK)
@ApiOperation(value = "获得所有功能的信息")
public Set<JsonableFunction> listFunction(){
Iterable<Function> functions = permissionService.findAllFunction();
Set<JsonableFunction> jsonableFunctions = new HashSet<>();
for(Function function : functions){
jsonableFunctions.add(new JsonableFunction(function));
}
return jsonableFunctions;
}
@PatchMapping("func")
@ResponseStatus(HttpStatus.CREATED)
@ApiOperation(value = "更新标功能内容")
public JsonableFunction patchFunction(@RequestParam(value = "id") Integer id, @RequestBody JsonPatch patch){
Optional<Function> function = permissionService.findFunction(id);
if(!function.isPresent()) throw new NotFoundException(id.toString());
JsonableFunction jsonableFunction = new JsonableFunction(function.get());
jsonableFunction = jsonParameter.parsePathToObject(patch, jsonableFunction);
return new JsonableFunction(permissionService.update(jsonableFunction.parseObject(function.get())));
}
}

Some files were not shown because too many files have changed in this diff Show More