diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b38d1e5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,34 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+.log
+
+### VS Code ###
+.vscode/
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000..c1dd12f
Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..b74bf7f
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
diff --git a/mvnw b/mvnw
new file mode 100644
index 0000000..8a8fb22
--- /dev/null
+++ b/mvnw
@@ -0,0 +1,316 @@
+#!/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 /usr/local/etc/mavenrc ] ; then
+ . /usr/local/etc/mavenrc
+ fi
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+ # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+ if [ -z "$JAVA_HOME" ]; then
+ if [ -x "/usr/libexec/java_home" ]; then
+ 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="`\\unset -f command; \\command -v java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+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/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.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" || rm -f "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$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 \
+ $MAVEN_DEBUG_OPTS \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
new file mode 100644
index 0000000..1d8ab01
--- /dev/null
+++ b/mvnw.cmd
@@ -0,0 +1,188 @@
+@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 "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq 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%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.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 "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..092fa33
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,180 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.2
+
+
+ com
+ WMS
+ 3.0
+ WMS
+ WMS
+
+ 17
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+
+ com.baomidou
+ mybatis-plus-spring-boot3-starter
+ 3.5.6
+
+
+ com.baomidou
+ dynamic-datasource-spring-boot-starter
+ 4.3.0
+
+
+ com.baomidou
+ mybatis-plus-boot-starter-test
+ 3.5.6
+
+
+ com.mysql
+ mysql-connector-j
+ 8.2.0
+ runtime
+
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ cn.hutool
+ hutool-all
+ 5.8.25
+
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
+
+ com.alibaba
+ fastjson
+ 2.0.21
+
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.13
+
+
+
+
+ com.google.guava
+ guava
+ 32.0.0-android
+
+
+
+ com.github.pagehelper
+ pagehelper
+ 5.3.1
+
+
+ com.github.jsqlparser
+ jsqlparser
+ 4.4
+
+
+
+
+ org.apache.httpcomponents
+ httpmime
+ 4.5.14
+
+
+
+ org.apache.poi
+ poi-ooxml
+ 5.2.3
+
+
+ org.apache.poi
+ poi
+ 5.2.3
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+ org.apache.oltu.oauth2
+ org.apache.oltu.oauth2.client
+ 1.0.1
+
+
+
+ com.auth0
+ java-jwt
+ 4.4.0
+
+
+
+ io.springfox
+ springfox-swagger2
+ 2.9.2
+
+
+ io.springfox
+ springfox-swagger-ui
+ 2.9.2
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+ 3.2.1
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 16
+ 16
+
+
+
+
+
+
diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..6382671
--- /dev/null
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: com.wuxiShenNan_W8.WmsTestversionApplication
+
diff --git a/src/main/java/com/wms/WmsApplication.java b/src/main/java/com/wms/WmsApplication.java
new file mode 100644
index 0000000..f650d98
--- /dev/null
+++ b/src/main/java/com/wms/WmsApplication.java
@@ -0,0 +1,44 @@
+package com.wms;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@SpringBootApplication
+@EnableScheduling
+@EnableTransactionManagement
+@MapperScan("com.wms.mapper")
+@EnableAsync
+public class WmsApplication {
+ /**
+ * 用于重启程序的上下文
+ */
+ private static ConfigurableApplicationContext context;
+
+ /**
+ * 主函数,程序的入口
+ *
+ * @param args 命令行参数,以字符串数组形式传入
+ */
+ public static void main(String[] args) {
+ context = SpringApplication.run(WmsApplication.class, args);
+ }
+
+ /**
+ * 重启程序
+ */
+ public static void restart() {
+ ApplicationArguments args = context.getBean(ApplicationArguments.class);
+ Thread thread = new Thread(() -> {
+ context.close();
+ context = SpringApplication.run(WmsApplication.class, args.getSourceArgs());
+ });
+ thread.setDaemon(false);
+ thread.start();
+ }
+}
diff --git a/src/main/java/com/wms/annotation/MyLog.java b/src/main/java/com/wms/annotation/MyLog.java
new file mode 100644
index 0000000..75f3eed
--- /dev/null
+++ b/src/main/java/com/wms/annotation/MyLog.java
@@ -0,0 +1,23 @@
+package com.wms.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 日志注解
+ */
+@Target({ ElementType.PARAMETER, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MyLog {
+ /**
+ * 日志标题
+ */
+ String logTitle() default "";
+
+ /**
+ * 方法名
+ */
+ String logMethod() default "";
+}
diff --git a/src/main/java/com/wms/annotation/MyLogAspect.java b/src/main/java/com/wms/annotation/MyLogAspect.java
new file mode 100644
index 0000000..26e8a94
--- /dev/null
+++ b/src/main/java/com/wms/annotation/MyLogAspect.java
@@ -0,0 +1,133 @@
+package com.wms.annotation;
+
+import com.wms.entity.table.WmsLog;
+import com.wms.service.LogService;
+import com.wms.utils.HttpUtils;
+import com.wms.utils.WmsUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.*;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+
+import java.lang.reflect.Method;
+import java.time.LocalDateTime;
+
+@Aspect
+@Component
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MyLogAspect {
+ private final LogService logService;
+ // 为了记录运行时间
+ ThreadLocal startTime = new ThreadLocal<>();
+
+ /**
+ * 设置操作日志切入点,这里介绍两种方式:
+ * 1、基于注解切入(也就是打了自定义注解的方法才会切入)
+ * //@Pointcut("@annotation(com.wms.annotation.MyLog)")
+ * 2、基于包扫描切入
+ * //@Pointcut("execution(public * com.wms.controller..*.*(..))")
+ */
+ @Pointcut("@annotation(com.wms.annotation.MyLog)")//在注解的位置切入代码
+ public void operLogPointCut() {
+ }
+ @Before("operLogPointCut()")
+ public void beforeMethod(JoinPoint point){
+ startTime.set(System.currentTimeMillis());
+ }
+
+ /**
+ * 设置操作异常切入点记录异常日志 扫描所有controller包下操作
+ */
+ @Pointcut("execution(* com.wms.controller..*.*(..))")
+ public void operExceptionLogPointCut() {
+ }
+
+ /**
+ * 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行
+ * @param joinPoint 切入点
+ * @param result 返回结果
+ */
+ @AfterReturning(value = "operLogPointCut()", returning = "result")
+ public void saveOperLog(JoinPoint joinPoint, Object result) {
+ // 获取RequestAttributes
+ RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
+ // 从获取RequestAttributes中获取HttpServletRequest的信息
+ HttpServletRequest request = null;
+ if (requestAttributes != null) {
+ request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
+ }
+ try {
+ // 从切面织入点处通过反射机制获取织入点处的方法
+ MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+ // 获取切入点所在的方法
+ Method method = signature.getMethod();
+ // 获取操作
+ MyLog myLog = method.getAnnotation(MyLog.class);
+ WmsLog wmsLog = new WmsLog();
+ wmsLog.setLogId(WmsUtils.generateId("LOG_"));
+ if (myLog != null) {
+ wmsLog.setLogTitle(myLog.logTitle());
+ wmsLog.setLogMethod(myLog.logMethod());
+ }
+ // 设置日志表详情
+ wmsLog.setLogRequest(joinPoint.getArgs());
+ wmsLog.setLogResponse(result);
+ if (request != null) {
+ wmsLog.setLogIp(HttpUtils.getIpAddr(request));
+ }
+ wmsLog.setLogTime(LocalDateTime.now());
+ // TODO 操作人员姓名待实现
+ wmsLog.setLogUser("");
+ logService.save(wmsLog);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 异常返回通知,用于拦截异常日志信息
+ * @param joinPoint 切点
+ * @param e 异常
+ */
+ @AfterThrowing(pointcut = "operExceptionLogPointCut()", throwing = "e")
+ public void saveExceptionLog(JoinPoint joinPoint, Throwable e) {
+ // 获取RequestAttributes
+ RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
+ // 从获取RequestAttributes中获取HttpServletRequest的信息
+ HttpServletRequest request = null;
+ if (requestAttributes != null) {
+ request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
+ }
+ try {
+ // 从切面织入点处通过反射机制获取织入点处的方法
+ MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+ // 获取切入点所在的方法
+ Method method = signature.getMethod();
+ // 获取操作
+ MyLog myLog = method.getAnnotation(MyLog.class);
+ WmsLog wmsLog = new WmsLog();
+ wmsLog.setLogId(WmsUtils.generateId("LOG_"));
+ if (myLog != null) {
+ wmsLog.setLogTitle(myLog.logTitle());
+ wmsLog.setLogMethod(myLog.logMethod());
+ }
+ // 设置日志表详情
+ wmsLog.setLogRequest(joinPoint.getArgs());
+ wmsLog.setLogResponse(e);
+ if (request != null) {
+ wmsLog.setLogIp(HttpUtils.getIpAddr(request));
+ }
+ wmsLog.setLogTime(LocalDateTime.now());
+ // TODO 操作人员姓名待实现
+ wmsLog.setLogUser("");
+ logService.save(wmsLog);
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/config/InitLocalConfig.java b/src/main/java/com/wms/config/InitLocalConfig.java
new file mode 100644
index 0000000..dbf1e68
--- /dev/null
+++ b/src/main/java/com/wms/config/InitLocalConfig.java
@@ -0,0 +1,38 @@
+package com.wms.config;
+
+import com.wms.entity.table.Config;
+import com.wms.service.ConfigService;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Component
+@Order(1)
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class InitLocalConfig implements ApplicationRunner {
+ /**
+ * 配置类
+ */
+ private final ConfigService configService;
+ protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+ public static Map configMap = new HashMap();
+ @Override
+ public void run(ApplicationArguments args) {
+ List configs = configService.selectConfigs("");
+ if (configs.size() > 0) {
+ for (Config config : configs) {
+ configMap.put(config.getConfigKey(), config.getConfigValue());
+ logger.info("导入系统配置成功---{}:{}", config.getConfigName(), config.getConfigValue());
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/wms/config/MybatisPlusConfig.java b/src/main/java/com/wms/config/MybatisPlusConfig.java
new file mode 100644
index 0000000..518335d
--- /dev/null
+++ b/src/main/java/com/wms/config/MybatisPlusConfig.java
@@ -0,0 +1,26 @@
+package com.wms.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * mp配置类
+ */
+@SpringBootConfiguration
+@MapperScan("com.wms.mapper")
+public class MybatisPlusConfig {
+ @Bean
+ public MybatisPlusInterceptor mybatisPlusInterceptor() {
+ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
+ // 添加分页插件
+ PaginationInnerInterceptor pageInnerInterceptor = new PaginationInnerInterceptor();
+ pageInnerInterceptor.setDbType(DbType.MYSQL);
+ pageInnerInterceptor.setMaxLimit(1000L);
+ interceptor.addInnerInterceptor(pageInnerInterceptor);
+ return interceptor;
+ }
+}
diff --git a/src/main/java/com/wms/config/PageHelperConfig.java b/src/main/java/com/wms/config/PageHelperConfig.java
new file mode 100644
index 0000000..2bed06f
--- /dev/null
+++ b/src/main/java/com/wms/config/PageHelperConfig.java
@@ -0,0 +1,24 @@
+package com.wms.config;
+
+import com.github.pagehelper.PageHelper;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Properties;
+
+@SpringBootConfiguration
+public class PageHelperConfig {
+ @Bean
+ public PageHelper pageHelper() {
+ PageHelper pageHelper = new PageHelper();
+ //添加配置,也可以指定文件路径
+ Properties p = new Properties();
+ p.setProperty("helperDialect", "mysql");
+ p.setProperty("reasonable", "true");
+ p.setProperty("supportMethodsArguments", "true");
+ p.setProperty("params", "count=countSql");
+ pageHelper.setProperties(p);
+ return pageHelper;
+ }
+}
diff --git a/src/main/java/com/wms/config/ThreadPoolConfig.java b/src/main/java/com/wms/config/ThreadPoolConfig.java
new file mode 100644
index 0000000..a7f54bf
--- /dev/null
+++ b/src/main/java/com/wms/config/ThreadPoolConfig.java
@@ -0,0 +1,37 @@
+package com.wms.config;
+
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.task.TaskExecutor;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.ThreadPoolExecutor;
+
+/**
+ * 线程池配置
+ */
+@SpringBootConfiguration
+public class ThreadPoolConfig {
+ @Bean
+// @Bean("pool1")
+ public TaskExecutor taskExecutor() {
+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+ // 设置核心线程数
+ executor.setCorePoolSize(10);
+ // 设置最大线程数
+ executor.setMaxPoolSize(20);
+ // 设置队列容量
+ executor.setQueueCapacity(100);
+ // 设置线程活跃时间(秒)
+ executor.setKeepAliveSeconds(60);
+ // 设置线程默认名称前缀
+ executor.setThreadNamePrefix("wmsThreadPool-");
+ // 设置拒绝策略
+ executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+ // 等待所有任务结束后关闭线程池
+ executor.setWaitForTasksToCompleteOnShutdown(true);
+
+ return executor;
+ }
+}
diff --git a/src/main/java/com/wms/constants/WmsConstants.java b/src/main/java/com/wms/constants/WmsConstants.java
new file mode 100644
index 0000000..4b5cdc1
--- /dev/null
+++ b/src/main/java/com/wms/constants/WmsConstants.java
@@ -0,0 +1,18 @@
+package com.wms.constants;
+
+import java.math.BigDecimal;
+import java.util.Map;
+
+import com.google.common.collect.ImmutableMap;
+import com.wms.constants.enums.WcsTaskStatus;
+import com.wms.constants.enums.WmsTaskStatus;
+
+/**
+ * WMS系统所需的常量
+ * @author 梁州
+ * @date 2023/2/13
+ */
+public class WmsConstants {
+ public static String EMPTY_STRING = "";
+ public static String ROOT_MENU_ID = "0";
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/constants/enums/GoodsStatus.java b/src/main/java/com/wms/constants/enums/GoodsStatus.java
new file mode 100644
index 0000000..e132ec1
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/GoodsStatus.java
@@ -0,0 +1,29 @@
+package com.wms.constants.enums;
+
+/**
+ * 物料状态枚举
+ */
+public enum GoodsStatus {
+ OK(0, "合格"),
+ BAD(1, "不合格"),
+ DELAY(2, "延期"),
+ OVERDUE(3, "过期"),
+ SCRAP(5, "长时间未使用");
+
+ private final Integer code;
+
+ private final String value;
+
+ GoodsStatus(Integer code, String value) {
+ this.code = code;
+ this.value = value;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/com/wms/constants/enums/KateTaskStatus.java b/src/main/java/com/wms/constants/enums/KateTaskStatus.java
new file mode 100644
index 0000000..9bc5846
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/KateTaskStatus.java
@@ -0,0 +1,25 @@
+package com.wms.constants.enums;
+
+public enum KateTaskStatus {
+ NEW(0, "待下发"),
+ WAIT(1, "已下发"),
+ RUN(2, "执行中"),
+ PICKING(3, "正在拣货"),
+ FINISH(5, "任务完成");
+
+ private final Integer code;
+ private final String name;
+
+ KateTaskStatus(Integer code, String name) {
+ this.code = code;
+ this.name = name;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/src/main/java/com/wms/constants/enums/LocationStatus.java b/src/main/java/com/wms/constants/enums/LocationStatus.java
new file mode 100644
index 0000000..e034378
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/LocationStatus.java
@@ -0,0 +1,27 @@
+package com.wms.constants.enums;
+
+/**
+ * 库位状态枚举
+ * /// 托盘状态和站台状态通用
+ */
+public enum LocationStatus {
+ EMPTY(0, "空闲"),
+ OCCUPY(1, "占用");
+
+ private final Integer code;
+
+ private final String value;
+
+ LocationStatus(Integer code, String value) {
+ this.code = code;
+ this.value = value;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/com/wms/constants/enums/MesStatus.java b/src/main/java/com/wms/constants/enums/MesStatus.java
new file mode 100644
index 0000000..99e915f
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/MesStatus.java
@@ -0,0 +1,27 @@
+package com.wms.constants.enums;
+
+/**
+ * 向mes反馈的任务状态码
+ */
+public enum MesStatus {
+ WAIT(0, "等待执行"),
+ RUN(1, "执行中"),
+ FINISH(2, "执行完成"),
+ EXCEPTION(3, "任务异常");
+
+ private final Integer statusCode;
+ private final String statusInfo;
+
+ MesStatus(Integer statusCode, String statusInfo) {
+ this.statusCode = statusCode;
+ this.statusInfo = statusInfo;
+ }
+
+ public Integer getStatusCode() {
+ return statusCode;
+ }
+
+ public String getStatusInfo() {
+ return statusInfo;
+ }
+}
diff --git a/src/main/java/com/wms/constants/enums/ResponseCode.java b/src/main/java/com/wms/constants/enums/ResponseCode.java
new file mode 100644
index 0000000..92fc841
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/ResponseCode.java
@@ -0,0 +1,27 @@
+package com.wms.constants.enums;
+
+/**
+ * 接口响应码枚举
+ */
+public enum ResponseCode {
+ OK(0, "正常"),
+ WARNING(200, "警告"),
+ ERROR(999, "异常");
+
+ private final Integer code;
+
+ private final String value;
+
+ ResponseCode(Integer code, String value) {
+ this.code = code;
+ this.value = value;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/com/wms/constants/enums/StandStatus.java b/src/main/java/com/wms/constants/enums/StandStatus.java
new file mode 100644
index 0000000..5a8a4bf
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/StandStatus.java
@@ -0,0 +1,26 @@
+package com.wms.constants.enums;
+
+/**
+ * 站台状态的枚举
+ */
+public enum StandStatus {
+ OK(0, "可用"),
+ OCCUPY(1, "占用");
+
+ private final Integer code;
+
+ private final String value;
+
+ StandStatus(Integer code, String value) {
+ this.code = code;
+ this.value = value;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/com/wms/constants/enums/StockStatus.java b/src/main/java/com/wms/constants/enums/StockStatus.java
new file mode 100644
index 0000000..c0eee3f
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/StockStatus.java
@@ -0,0 +1,29 @@
+package com.wms.constants.enums;
+
+/**
+ * 库存状态枚举
+ */
+public enum StockStatus {
+ OK(0, "库存正常"),
+ OUT(1, "出库中"),
+ INVENTORY(2, "盘点中"),
+ MOVE(3, "移库中"),
+ LOCK(9, "库存锁定");
+
+ private final Integer code;
+
+ private final String value;
+
+ StockStatus(Integer code, String value) {
+ this.code = code;
+ this.value = value;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/com/wms/constants/enums/TaskType.java b/src/main/java/com/wms/constants/enums/TaskType.java
new file mode 100644
index 0000000..c6d126a
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/TaskType.java
@@ -0,0 +1,28 @@
+package com.wms.constants.enums;
+
+/**
+ * 任务类型枚举
+ */
+public enum TaskType {
+ IN(1, "入库"),
+ OUT(2, "出库"),
+ INVENTORY(3, "盘点"),
+ MOVE(9, "移库");
+
+ private final Integer code;
+
+ private final String value;
+
+ TaskType(Integer code, String value) {
+ this.code = code;
+ this.value = value;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/com/wms/constants/enums/UrlEnums.java b/src/main/java/com/wms/constants/enums/UrlEnums.java
new file mode 100644
index 0000000..8dedbd5
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/UrlEnums.java
@@ -0,0 +1,22 @@
+package com.wms.constants.enums;
+
+public enum UrlEnums {
+ URL_WMS_TO_WCS_SEND_TASK("WMS向WCS发送任务", "/api/Wms/WmsTask/SetStackerTask"),
+ URL_WMS_TO_WCS_CHANGE_TASK("WMS请求变更任务状态", "/api/Wms/WmsTask/ChangeTaskStatus");
+
+ private final String description;
+ private final String value;
+
+ UrlEnums(String description, String value) {
+ this.description = description;
+ this.value = value;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/com/wms/constants/enums/VehicleStatus.java b/src/main/java/com/wms/constants/enums/VehicleStatus.java
new file mode 100644
index 0000000..7a17731
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/VehicleStatus.java
@@ -0,0 +1,27 @@
+package com.wms.constants.enums;
+
+/**
+ * 载具状态
+ */
+public enum VehicleStatus {
+ IN(1, "入库中"),
+ ON(2, "在库中"),
+ OUT(3, "出库中");
+
+ private final Integer code;
+
+ private final String value;
+
+ VehicleStatus(Integer code, String value) {
+ this.code = code;
+ this.value = value;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/com/wms/constants/enums/WcsChangeTaskStatus.java b/src/main/java/com/wms/constants/enums/WcsChangeTaskStatus.java
new file mode 100644
index 0000000..c641aa6
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/WcsChangeTaskStatus.java
@@ -0,0 +1,26 @@
+package com.wms.constants.enums;
+
+/**
+ * 向Wcs发送任务变更时的任务状态枚举
+ */
+public enum WcsChangeTaskStatus {
+ FINISH(0, "重新执行任务"),
+ CANCEL(1, "取消/删除任务"),
+ EXCEPTION(2, "完成任务");
+
+ private final Integer code;
+ private final String message;
+
+ WcsChangeTaskStatus(Integer code, String message) {
+ this.code = code;
+ this.message = message;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/src/main/java/com/wms/constants/enums/WcsTaskStatus.java b/src/main/java/com/wms/constants/enums/WcsTaskStatus.java
new file mode 100644
index 0000000..5c15ec7
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/WcsTaskStatus.java
@@ -0,0 +1,31 @@
+package com.wms.constants.enums;
+
+/**
+ * Wcs任务状态的枚举
+ */
+public enum WcsTaskStatus {
+ WAIT(1, "任务排队中"),
+ RUN(2, "任务开始执行"),
+ LEAVE(3, "任务已经离开初始位置"),
+ PARK(4, "任务到达中间点"),
+ ARRIVE(5, "任务到达目的地"),
+ FINISH(100, "任务完成"),
+ CANCEL(998, "任务取消"),
+ EXCEPTION(999, "任务异常");
+
+ private final Integer code;
+ private final String name;
+
+ WcsTaskStatus(Integer code, String name) {
+ this.code = code;
+ this.name = name;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/src/main/java/com/wms/constants/enums/WmsTaskStatus.java b/src/main/java/com/wms/constants/enums/WmsTaskStatus.java
new file mode 100644
index 0000000..f48b134
--- /dev/null
+++ b/src/main/java/com/wms/constants/enums/WmsTaskStatus.java
@@ -0,0 +1,31 @@
+package com.wms.constants.enums;
+
+/**
+ * Wms任务状态的枚举
+ */
+public enum WmsTaskStatus {
+ TEMP(-1, "暂存任务"),
+ NEW(0, "任务新建,待下发"),
+ WAIT(1, "任务已下发"),
+ RUN(2, "任务开始执行"),
+ INVENTORY(8, "盘点中"),
+ FINISH(100, "任务完成"),
+ CANCEL(998, "任务取消"),
+ EXCEPTION(999, "任务异常");
+
+ private final Integer code;
+ private final String name;
+
+ WmsTaskStatus(Integer code, String name) {
+ this.code = code;
+ this.name = name;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/src/main/java/com/wms/controller/ConfigController.java b/src/main/java/com/wms/controller/ConfigController.java
new file mode 100644
index 0000000..c985040
--- /dev/null
+++ b/src/main/java/com/wms/controller/ConfigController.java
@@ -0,0 +1,83 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.wms.constants.enums.ResponseCode;
+import com.wms.entity.app.ResponseEntity;
+import com.wms.entity.table.Config;
+import com.wms.service.ConfigService;
+import com.wms.utils.HttpUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * WMS系统配置控制类
+ * @author 梁州
+ * @date 2023/3/23
+ */
+@Controller
+@CrossOrigin
+@RequestMapping(value = "/wms/config")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class ConfigController{
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ /**
+ * 系统配置服务
+ */
+ private final ConfigService configService;
+ /**
+ * 请求头部信息
+ */
+ private final HttpServletRequest servletRequest;
+
+ /**
+ * 查找所有配置
+ * @return 配置
+ */
+ @GetMapping("/getConfigs")
+ @ResponseBody
+ public List getConfigs(){
+ logger.info("查询系统配置,查询ip:{}", HttpUtils.getIpAddr(servletRequest));
+ return configService.selectConfigs("");
+ }
+
+ /**
+ * 更新系统配置
+ *
+ * @param config 配置
+ * @return 结果
+ */
+ @PostMapping("/updateConfig")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String updateConfig(@RequestBody Config config) {
+ logger.info("更新系统配置,{}:{},请求ip:{}", config.getConfigName(), config.getConfigValue(), HttpUtils.getIpAddr(servletRequest));
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ configService.updateConfig(config);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("更新系统配置错误:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("更新系统配置成功!");
+ return JSON.toJSONString(rsp);
+ }
+}
diff --git a/src/main/java/com/wms/controller/ExcelController.java b/src/main/java/com/wms/controller/ExcelController.java
new file mode 100644
index 0000000..f1f6af4
--- /dev/null
+++ b/src/main/java/com/wms/controller/ExcelController.java
@@ -0,0 +1,121 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.wms.constants.enums.*;
+import com.wms.entity.app.ResponseEntity;
+import com.wms.entity.app.dto.StockDto;
+import com.wms.entity.app.dto.TaskRecordDto;
+import com.wms.entity.app.query.StockQuery;
+import com.wms.entity.app.query.TaskRecordQuery;
+import com.wms.service.*;
+import com.wms.utils.excel.ExcelUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+import static com.wms.utils.HttpUtils.getIpAddr;
+import static com.wms.utils.StringUtils.convertJsonString;
+
+/**
+ *
+ */
+@Controller
+@CrossOrigin
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+@RequestMapping(value = "/wms/excel")
+public class ExcelController {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ private final StockService stockService;// 库存服务
+ private final HttpServletRequest servletRequest;// 请求服务
+ private final TaskRecordService taskRecordService;// 任务记录服务
+
+ /**
+ * 导入库存信息
+ *
+ * @param file 文件
+ * @return 导入结果
+ */
+ @PostMapping("/uploadStocks")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String uploadStocks(@RequestPart("file") MultipartFile file) {
+ logger.info("导入库存,请求ip:{}", getIpAddr(servletRequest));
+ ResponseEntity response = new ResponseEntity();
+ try {
+ response.setCode(ResponseCode.OK.getCode());
+ response.setMessage("导入库存成功");
+ response.setReturnData(file);
+ } catch (Exception e) {
+ convertJsonString(e);
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ response.setCode(ResponseCode.ERROR.getCode());
+ response.setMessage(e.getMessage());
+ }
+ return JSON.toJSONString(response);
+ }
+
+ /**
+ * 导出库存数据
+ *
+ * @param response 请求
+ */
+ @GetMapping("/downloadStockExcel")
+ @ResponseBody
+ public void downloadStockExcel(@RequestParam("stockQuery") StockQuery query, HttpServletResponse response) {
+ logger.info("导出库存记录,请求ip:{}", getIpAddr(servletRequest));
+ List stocks = stockService.selectStocks(query.toStockPO());
+ ExcelUtils.export(response, "库存报表", stocks, StockDto.class);
+ }
+
+ /**
+ * 导出入库记录
+ *
+ * @param response 请求
+ */
+ @GetMapping("/downloadInRecordExcel")
+ @ResponseBody
+ public void downloadInRecordExcel(@RequestParam("recordQuery") TaskRecordQuery query, HttpServletResponse response) {
+ logger.info("导出入库记录,请求ip:{}", getIpAddr(servletRequest));
+ List inRecord = taskRecordService.selectInTaskRecord(query.toTaskRecordPO());
+ ExcelUtils.export(response, "入库记录报表", inRecord, TaskRecordDto.class);
+ }
+
+ /**
+ * 导出入库记录
+ *
+ * @param response 请求
+ */
+ @GetMapping("/downloadOutRecordExcel")
+ @ResponseBody
+ public void downloadOutRecordExcel(@RequestParam("recordQuery") TaskRecordQuery query, HttpServletResponse response) {
+ logger.info("导出出库记录,请求ip:{}", getIpAddr(servletRequest));
+ List outRecord = taskRecordService.selectOutTaskRecord(query.toTaskRecordPO());
+ ExcelUtils.export(response, "出库记录报表", outRecord, TaskRecordDto.class);
+ }
+
+ /**
+ * 导出盘点记录
+ *
+ * @param response 请求
+ */
+ @GetMapping("/downloadInventoryRecordExcel")
+ @ResponseBody
+ public void downloadInventoryRecordExcel(@RequestParam("recordQuery") TaskRecordQuery query, HttpServletResponse response) {
+ logger.info("导出盘点记录,请求ip:{}", getIpAddr(servletRequest));
+ List inventoryRecord = taskRecordService.selectInventoryTaskRecord(query.toTaskRecordPO());
+ ExcelUtils.export(response, "盘点记录报表", inventoryRecord, TaskRecordDto.class);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/controller/GoodsController.java b/src/main/java/com/wms/controller/GoodsController.java
new file mode 100644
index 0000000..d1008ee
--- /dev/null
+++ b/src/main/java/com/wms/controller/GoodsController.java
@@ -0,0 +1,240 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.wms.constants.enums.ResponseCode;
+import com.wms.entity.app.ResponseEntity;
+import com.wms.entity.page.PageDomain;
+import com.wms.entity.page.TableResponse;
+import com.wms.service.GoodsService;
+import com.wms.utils.HttpUtils;
+import com.wms.utils.StringUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * WMS物料控制类
+ * @author 梁州
+ * @date 2023/3/9
+ */
+@Controller
+@CrossOrigin
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+@RequestMapping(value = "/wms/goods")
+public class GoodsController {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ /**
+ * 物料服务
+ */
+ private final GoodsService goodsService;
+ /**
+ * 请求头部信息
+ */
+ private final HttpServletRequest servletRequest;
+
+ /**
+ * 查找所有物料
+ */
+ @PostMapping("/getPartInfo")
+ @ResponseBody
+ public String getPartInfo(@RequestBody TableRequest tableRequest){
+ logger.info("请求的ip地址:{}", HttpUtils.getIpAddr(servletRequest));
+ logger.info("接收到查询物料数据请求:{}", JSON.toJSONString(tableRequest));
+ TableResponse tblResp = new TableResponse();
+ // 解析请求数据
+ if (tableRequest == null || tableRequest.getPage() == null) {
+ tblResp.setCode(ResponseCode.ERROR.getCode());
+ tblResp.setMessage("请求数据为空,无法处理!");
+ logger.error("请求数据为空,无法处理!");
+ return JSON.toJSONString(tblResp);
+ }
+ // 处理分页信息
+ PageDomain pageRequest = tableRequest.getPage();
+ String orderByStr = "goodsId asc";
+
+ PageHelper.startPage(pageRequest.getPageNum(), pageRequest.getPageSize(), orderByStr);
+ List goodsList = goodsService.selGoods(tableRequest.getParam());
+ PageInfo goodsPageInfo = new PageInfo<>(goodsList);
+ tblResp.setCode(ResponseCode.OK.getCode());
+ tblResp.setMessage("查询物料信息成功!");
+ tblResp.setRows(goodsPageInfo.getList());
+ tblResp.setTotal(goodsPageInfo.getTotal());
+ return JSON.toJSONString(tblResp);
+ }
+
+ /**
+ * 更新物料信息
+ *
+ * @param goods 物料信息
+ * @return 结果
+ */
+ @PostMapping("/updatePartInfo")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String updatePartInfo(@RequestBody GoodsDto goods) {
+ logger.info("请求的ip地址:{}", HttpUtils.getIpAddr(servletRequest));
+ logger.info("接收到更新零件信息请求:{}", JSON.toJSONString(goods));
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ if (StringUtils.isEmpty(goods.getGoodsId())) {// 物料编码为空,不执行
+ logger.error("请求物料编码为空");
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("请求物料编码为空");
+ return JSON.toJSONString(rsp);
+ }
+ goodsService.modifyGoods(goods);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("发生异常:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("更新物料信息成功");
+ return JSON.toJSONString(rsp);
+ }
+
+ /**
+ * 查询物料信息
+ * @param goods 参数
+ * @return 结果
+ */
+ @PostMapping("/queryPartInfoByPartNo")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String queryPartInfoByPartNo(@RequestBody GoodsDto goods) {
+ logger.info("前台查询物料数据");
+ ResponseEntity rsp = new ResponseEntity();
+ if (goods == null || StringUtils.isEmpty(goods.getGoodsId())) {
+ logger.info("请求查询的参数为空");
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("请求查询的参数为空");
+ return JSON.toJSONString(rsp);
+ }
+ try {
+ GoodsDto goodsInfoNeed = goodsService.selGoodsByGoodsId(goods.getGoodsId());
+ if (goodsInfoNeed == null) {
+ logger.info("查询物料信息发生错误,物料编码:{}", goods.getGoodsId());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("查询的物料信息为空");
+ return JSON.toJSONString(rsp);
+ }
+ rsp.setReturnData(goodsInfoNeed);
+ logger.info("查询物料信息成功");
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("查询物料信息成功");
+ return JSON.toJSONString(rsp);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("查询物料信息发生错误:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ }
+
+ /**
+ * 自动补全物料编码信息
+ * @param goods 参数
+ * @return 结果
+ */
+ @PostMapping("/queryPartNo")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String queryPartNo(@RequestBody GoodsDto goods) {
+ ResponseEntity rsp = new ResponseEntity();
+ if (goods == null || StringUtils.isEmpty(goods.getGoodsId())) {
+ logger.info("请求查询的参数为空");
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("请求查询的参数为空");
+ return JSON.toJSONString(rsp);
+ }
+ try {
+ GoodsDto query = new GoodsDto();
+ query.setGoodsId(goods.getGoodsId());
+ List goodsInfoNeed = goodsService.selGoods(query);
+ if (goodsInfoNeed.size() == 0) {
+ logger.info("查询物料信息失败,物料编码:{}", goods.getGoodsId());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("查询物料信息为空");
+ return JSON.toJSONString(rsp);
+ }
+ rsp.setReturnData(goodsInfoNeed);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("查询物料信息发生错误:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ logger.info("查询物料信息成功");
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("查询物料信息成功");
+ return JSON.toJSONString(rsp);
+ }
+
+ /**
+ * 删除当前物料信息
+ *
+ * @param goods 物料
+ * @return 结果
+ */
+ @PostMapping("/deletePartInfo")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String deleteVehicle(@RequestBody GoodsDto goods) {
+ logger.info("请求的ip地址:{}", HttpUtils.getIpAddr(servletRequest));
+ logger.info("接收到更新物料信息请求:{}", JSON.toJSONString(goods));
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ if (StringUtils.isEmpty(goods.getGoodsId())) {// 物料编码为空,不做处理
+ logger.error("请求删除的物料编码为空");
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("请求删除的物料编码为空");
+ return JSON.toJSONString(rsp);
+ }
+ goodsService.deleteGoods(goods.getGoodsId());
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("删除物料信息成功");
+ return JSON.toJSONString(rsp);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("发生异常:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ }
+}
diff --git a/src/main/java/com/wms/controller/JobComponent.java b/src/main/java/com/wms/controller/JobComponent.java
new file mode 100644
index 0000000..1111ee8
--- /dev/null
+++ b/src/main/java/com/wms/controller/JobComponent.java
@@ -0,0 +1,183 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.wms.constants.enums.*;
+import com.wms.entity.app.ResponseEntity;
+import com.wms.entity.table.StockDto;
+import com.wms.entity.table.TaskDto;
+import com.wms.entity.table.WmsLogDto;
+import com.wms.service.*;
+import com.wms.utils.HttpUtils;
+import com.wms.utils.StringUtils;
+import com.wms.utils.WmsUtils;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import static com.wms.utils.StringUtils.convertJsonString;
+
+import java.util.*;
+
+import static com.wms.config.InitLocalConfig.configMap;
+
+/**
+ * 定期任务类
+ */
+@Component
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class JobComponent {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ /**
+ * 任务服务
+ */
+ private final TaskService taskService;
+ /**
+ * 库存服务
+ */
+ private final StockService stockService;
+ /**
+ * 任务记录服务
+ */
+ private final TaskRecordService taskRecordService;
+ /**
+ * 日志服务
+ */
+ private final LogService logService;
+
+
+ /**
+ * 每隔一秒检索一遍任务列表,同时向WCS下发任务
+ */
+ @Scheduled(fixedDelay = 1000)
+ public void executeTasks() {
+ try {
+ // 检索任务列表,查询状态为等待状态的任务
+ TaskDto taskForQuery = new TaskDto();
+ taskForQuery.setTaskStatus(WmsTaskStatus.NEW.getCode());
+ List tasks = taskService.selTasks(taskForQuery);
+ List request = new ArrayList<>();
+ if (tasks.size() > 0) {// 存在等待中的任务
+ for (TaskDto task : tasks) {
+ if (StringUtils.isNotEmpty(task.getPreTask())) {// 该任务拥有前置任务,不下发
+ // 查询一下前置的任务有没有存在,存在则不下发
+ List preTasks = taskService.selTasks(new TaskDto(task.getPreTask()));
+ if (preTasks.size() > 0) {
+ continue;
+ }
+ }
+ // 创建发送的任务
+ WcsTask tempTask = new WcsTask();
+ tempTask.setTaskId(task.getTaskId());
+ if (Objects.equals(task.getTaskType(), TaskType.INVENTORY_OUT.getCode())) {
+ tempTask.setTaskType(TaskType.OUT.getCode());
+ } else if (Objects.equals(task.getTaskType(), TaskType.INVENTORY_IN.getCode())) {
+ tempTask.setTaskType(TaskType.IN.getCode());
+ } else {
+ tempTask.setTaskType(task.getTaskType());
+ }
+ tempTask.setOrigin(task.getOrigin());
+ tempTask.setDestination(task.getDestination());
+ tempTask.setVehicleNo(task.getVehicleNo());
+ tempTask.setVehicleSize(task.getVehicleSize());
+ tempTask.setWeight(task.getWeight());
+ tempTask.setPriority(task.getTaskPriority());
+ request.add(tempTask);
+ task.setTaskStatus(WmsTaskStatus.WAIT.getCode());
+ }
+ if (request.size() == 0) {
+ return;
+ }
+ // 发送任务
+ String url = configMap.get("WCS_TASK");
+ if (url != null) {
+ logger.info("向WCS发送任务,地址:{},请求详情:{}", url, convertJsonString(request));
+ ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(request)), ResponseEntity.class);
+ try {
+ logService.addWmsLog(new WmsLogDto(WmsUtils.generateId("LOG_"), "向WCS发送任务", "SetStackerTask", JSON.toJSONString(request), JSON.toJSONString(result), url, new Date(), "WMS"));
+ } catch (Exception e) {
+ logger.error("插入日志错误");
+ }
+ if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) {
+ // 更新任务列表
+ for (TaskDto task : tasks) {
+ // 更新任务
+ taskService.executeTask(task);
+ }
+ } else {
+ if (result != null) {
+ logger.error("存在错误:{}", result.getMessage());
+ } else {
+ logger.error("请求无返回");
+ }
+ }
+ } else {
+ logger.error("WCS发送任务地址为空");
+ }
+ }
+ } catch (Exception exception) {
+ logger.error("发生异常:{}", convertJsonString(exception));
+ }
+ }
+
+ /**
+ * 每天查询一次是否有过期的库存
+ * 每天晚上8点执行一次
+ */
+// @Scheduled(cron = "0 0 20 * * ?")
+ public void detectOutOfDateStock() {
+ logger.info("执行定时任务:查询过期库存");
+ List outOfDateStocks = stockService.selStockOutOfDate();
+ if (outOfDateStocks.size() > 0) {
+ logger.info("过期库存数量不为0,准备更新过期库存");
+ for (StockDto outOfDateStock : outOfDateStocks) {
+ try {
+ outOfDateStock.setGoodsStatus(GoodsStatus.OVERDUE.getCode());
+ stockService.modifyStock(outOfDateStock);
+ logger.info("过期库存更新成功");
+ } catch (Exception e) {
+ logger.error("过期库存更新异常:{}", e.getMessage());
+ }
+ }
+ }
+ }
+
+ /**
+ * TODO 更新呆滞时间
+ * 每天查询一次是否有入库后长期未使用的库存
+ * 每天晚上9点执行一次
+ */
+// @Scheduled(cron = "0 0 21 * * ?")
+ public void detectStockLongTimeNoUse() {
+ logger.info("执行定时任务:查询是否有入库后长期未使用的库存");
+ List stocksLongTimeNoUse = stockService.selStockLongTimeNoUse(7);
+ if (stocksLongTimeNoUse.size() > 0) {
+ logger.info("有入库后长期未使用的库存, 准备更新库存状态");
+ for (StockDto stockLongTimeNoUse : stocksLongTimeNoUse) {
+ try {
+ stockLongTimeNoUse.setGoodsStatus(GoodsStatus.SCRAP.getCode());
+ stockService.modifyStock(stockLongTimeNoUse);
+ logger.info("长时间未使用库存状态更新成功");
+ } catch (Exception e) {
+ logger.error("长时间未使用库存状态更新异常:{}", e.getMessage());
+ }
+ }
+ }
+ }
+
+ /**
+ * 每天查询一次是否有过期记录
+ * 每天晚上10点执行一次
+ */
+// @Scheduled(cron = "0 0 22 * * ?")
+ public void deleteOutOfDateData() {
+ logger.info("执行定时任务:删除过期数据");
+ taskRecordService.deleteTaskRecordRegularly();
+ if (logService.deleteWmsLogsRegularly(90)) {
+ logger.info("删除过期日志数据成功");
+ } else {
+ logger.info("删除过期日志数据失败");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/controller/LocationController.java b/src/main/java/com/wms/controller/LocationController.java
new file mode 100644
index 0000000..c2f86dd
--- /dev/null
+++ b/src/main/java/com/wms/controller/LocationController.java
@@ -0,0 +1,319 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.wms.constants.enums.ResponseCode;
+import com.wms.entity.app.dto.VehicleDto;
+import com.wms.entity.app.dto.extend.VehicleDetailInfo;
+import com.wms.entity.app.vo.LayerLocation;
+import com.wms.entity.app.ResponseEntity;
+import com.wms.entity.app.vo.RowLocation;
+import com.wms.entity.page.PageDomain;
+import com.wms.entity.page.TableRequest;
+import com.wms.entity.page.TableResponse;
+import com.wms.entity.table.LocationDto;
+import com.wms.entity.table.Vehicle;
+import com.wms.entity.table.VehicleDto;
+import com.wms.constants.enums.LocationStatus;
+import com.wms.service.LocationService;
+import com.wms.service.VehicleService;
+import com.wms.utils.HttpUtils;
+import com.wms.utils.StringUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+/**
+ * WMS库位控制类
+ *
+ * @author 梁州
+ * @date 2023/3/6
+ */
+@Controller
+@CrossOrigin
+@RequestMapping(value = "/wms/location")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class LocationController {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ /**
+ * 库位服务
+ */
+ private final LocationService locationService;
+ /**
+ * 料箱服务
+ */
+ private final VehicleService vehicleService;
+ /**
+ * 请求头部信息
+ */
+ private final HttpServletRequest servletRequest;
+
+
+ /**
+ * 查询库位
+ *
+ * @param location 查询参数
+ * @return 结果
+ */
+ @PostMapping("/getLocations")
+ @ResponseBody
+ public String getLocations(@RequestBody LocationDto location) {
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ // 查询出所有符合条件的库位
+ List locations = locationService.selLocations(location);
+ if (locations.size() < 1) {
+ logger.error("查询库位发生错误:库位不存在");
+ // 返回错误
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("查询库位发生错误:库位不存在");
+ return JSON.toJSONString(rsp);
+ }
+ List rowLocations = new LinkedList<>();
+ // 查找到最大的排
+ locations.sort(Comparator.comparing(LocationDto::getQueue).reversed());
+ int maxRow = locations.get(0).getQueue();
+ // 按排查找库位
+ for (int i = 0; i < maxRow; i++) {
+ int finalI = i;
+ List currentRowLocations = new ArrayList<>(locations.stream()
+ .filter(l -> l.getQueue().equals(finalI + 1))
+ .toList());
+ // 先查找每一层的库位
+ List layerLocations = new LinkedList<>();
+ // 找到这一排最大的层
+ currentRowLocations.sort(Comparator.comparing(LocationDto::getLayer).reversed());
+ int maxLayer = currentRowLocations.get(0).getLayer();
+ // 按照每一列查找库位
+ for (int j = 0; j < maxLayer; j++) {
+ int finalJ = j;
+ List currentLayerLocations = currentRowLocations.stream()
+ .filter(l -> l.getLayer().equals(finalJ + 1))
+ .toList();
+ LayerLocation tempLayerLocation = new LayerLocation();
+ tempLayerLocation.setLayer(finalJ + 1);
+ tempLayerLocation.setCurrentColLocations(currentLayerLocations);
+ layerLocations.add(tempLayerLocation);
+ }
+ RowLocation tempRowLocation = new RowLocation();
+ tempRowLocation.setRow(finalI + 1);
+ tempRowLocation.setCurrentLayerLocations(layerLocations);
+ rowLocations.add(tempRowLocation);
+ }
+ logger.info("查询库位数据成功,库区:{}", location.getAreaId());
+ // 设置最终数据
+ rsp.setReturnData(rowLocations);
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("查询库位成功");
+ return JSON.toJSONString(rsp);
+ } catch (Exception e) {
+ logger.info("查询库位发生错误:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ }
+
+ /**
+ * 更新库位状态
+ *
+ * @param location 库位
+ * @return 结果
+ */
+ @PostMapping("/updateLocation")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String updateLocation(@RequestBody LocationDto location) {
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ locationService.modifyLocation(location);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("更新库位状态发生错误:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("更新库位状态成功");
+ return JSON.toJSONString(rsp);
+ }
+
+ /**
+ * 更新库位状态
+ *
+ * @param location 库位
+ * @return 结果
+ */
+ @PostMapping("/getAvailableLocations")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String getAvailableLocations(@RequestBody LocationDto location) {
+ logger.info("查询空闲可用库位");
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ LocationDto locationQuery = new LocationDto();
+ locationQuery.setAreaId(location.getAreaId());
+ locationQuery.setLocationStatus(LocationStatus.EMPTY.getCode());
+ locationQuery.setIsLock(0);
+ List availableLocations = locationService.selLocations(locationQuery);
+ rsp.setReturnData(availableLocations);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("查询可用库位错误:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("查询可用库位成功");
+ return JSON.toJSONString(rsp);
+ }
+
+ /**
+ * 查询料箱信息
+ * @param tableRequest 请求
+ * @return 结果
+ */
+ @PostMapping("/getVehicles")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String getVehicles(@RequestBody TableRequest tableRequest) {
+ logger.info("请求的ip地址:{}", HttpUtils.getIpAddr(servletRequest));
+ logger.info("接收到查询料箱请求:{}", JSON.toJSONString(tableRequest));
+ TableResponse tblResp = new TableResponse();
+ // 解析请求数据
+ if (tableRequest == null || tableRequest.getPage() == null) {
+ tblResp.setCode(ResponseCode.ERROR.getCode());
+ tblResp.setMessage("请求数据为空,无法处理!");
+ logger.error("请求数据为空,无法处理!");
+ return JSON.toJSONString(tblResp);
+ }
+ // 处理分页信息
+ PageDomain pageRequest = tableRequest.getPage();
+// String[] orderByArr = {"task_id", "task_type", "task_status", "goods_id", "goods_name", "task_priority", "expiration_date", "create_time"};
+ String orderByStr = "";
+
+// if (StringUtils.isNotEmpty(pageRequest.getOrderByColumn()) && Arrays.asList(orderByArr).contains(StringUtils.toUnderScoreCase(pageRequest.getOrderByColumn()))) {
+// orderByStr = pageRequest.getOrderBy();
+// } else {
+// // 默认排序
+// orderByStr = "";
+// }
+
+ Vehicle vehicleQuery = new Vehicle<>();
+ vehicleQuery.setVehicleId(tableRequest.getParam().getVehicleId());
+ PageHelper.startPage(pageRequest.getPageNum(), pageRequest.getPageSize(), orderByStr);
+ List> vehicles = vehicleService.selVehicles(vehicleQuery);
+ PageInfo vehiclePageInfo = new PageInfo<>(vehicles);
+ tblResp.setCode(ResponseCode.OK.getCode());
+ tblResp.setMessage("查询料箱成功!");
+ tblResp.setRows(vehiclePageInfo.getList());
+ tblResp.setTotal(vehiclePageInfo.getTotal());
+ return JSON.toJSONString(tblResp);
+ }
+
+ /**
+ * 更新料箱信息
+ *
+ * @param vehicle 料箱
+ * @return 结果
+ */
+ @PostMapping("/updateVehicleInfo")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String updateVehicleInfo(@RequestBody VehicleDto vehicle) {
+ logger.info("请求的ip地址:{}", HttpUtils.getIpAddr(servletRequest));
+ logger.info("接收到更新料箱信息请求:{}", JSON.toJSONString(vehicle));
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ if (StringUtils.isEmpty(vehicle.getVehicleId())) {// 箱号为空,不执行
+ logger.error("请求箱号为空");
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("请求箱号为空");
+ return JSON.toJSONString(rsp);
+ }
+ vehicleService.modifyVehicle(vehicle);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("发生异常:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("更新料箱信息成功");
+ return JSON.toJSONString(rsp);
+ }
+
+ /**
+ * 删除当前料箱信息
+ *
+ * @param vehicle 料箱
+ * @return 结果
+ */
+ @PostMapping("/deleteVehicle")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String deleteVehicle(@RequestBody VehicleDto vehicle) {
+ logger.info("请求的ip地址:{}", HttpUtils.getIpAddr(servletRequest));
+ logger.info("接收到更新料箱信息请求:{}", JSON.toJSONString(vehicle));
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ if (StringUtils.isEmpty(vehicle.getVehicleId())) {// 箱号为空,不执行
+ logger.error("请求箱号为空");
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("请求箱号为空");
+ return JSON.toJSONString(rsp);
+ }
+ // 判断当前料箱是不是空箱,带料不允许删除
+ VehicleDto currentVehicle = vehicleService.selVehicleById(vehicle.getVehicleId());
+ if (currentVehicle != null && currentVehicle.getIsEmpty() != 1) {// 非空箱
+ logger.error("非空箱不允许删除");
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("非空箱不允许删除");
+ return JSON.toJSONString(rsp);
+ }
+ vehicleService.deleteVehicle(vehicle);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("发生异常:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("删除料箱成功");
+ return JSON.toJSONString(rsp);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/controller/RecordController.java b/src/main/java/com/wms/controller/RecordController.java
new file mode 100644
index 0000000..b8a852d
--- /dev/null
+++ b/src/main/java/com/wms/controller/RecordController.java
@@ -0,0 +1,93 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.wms.constants.enums.ResponseCode;
+import com.wms.entity.page.PageDomain;
+import com.wms.entity.page.TableRequest;
+import com.wms.entity.page.TableResponse;
+import com.wms.entity.table.TaskDto;
+import com.wms.service.TaskRecordService;
+import com.wms.utils.HttpUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * WMS记录控制类
+ *
+ * @author 梁州
+ * @date 2023/2/14
+ */
+@Controller
+@CrossOrigin
+@RequestMapping(value = "/wms/record")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class RecordController {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ /**
+ * 任务记录服务
+ */
+ private final TaskRecordService taskRecordService;
+ /**
+ * 请求头部信息
+ */
+ private final HttpServletRequest servletRequest;
+
+ /**
+ * 查询任务记录
+ *
+ * @param tableRequest 请求
+ * @return 结果
+ */
+ @PostMapping("/getTaskRecords")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String getVehicles(@RequestBody TableRequest tableRequest) {
+ logger.info("请求的ip地址:{}", HttpUtils.getIpAddr(servletRequest));
+ logger.info("接收到查询任务记录请求:{}", JSON.toJSONString(tableRequest));
+ TableResponse tblResp = new TableResponse();
+ // 解析请求数据
+ if (tableRequest == null || tableRequest.getPage() == null) {
+ tblResp.setCode(ResponseCode.ERROR.getCode());
+ tblResp.setMessage("请求数据为空,无法处理!");
+ logger.error("请求数据为空,无法处理!");
+ return JSON.toJSONString(tblResp);
+ }
+ // 处理分页信息
+ PageDomain pageRequest = tableRequest.getPage();
+// String[] orderByArr = {"task_id", "task_type", "task_status", "goods_id", "goods_name", "task_priority", "expiration_date", "create_time"};
+ String orderByStr = "";
+
+// if (StringUtils.isNotEmpty(pageRequest.getOrderByColumn()) && Arrays.asList(orderByArr).contains(StringUtils.toUnderScoreCase(pageRequest.getOrderByColumn()))) {
+// orderByStr = pageRequest.getOrderBy();
+// } else {
+// // 默认排序
+// orderByStr = "";
+// }
+
+ TaskDto taskRecordQuery = new TaskDto();
+ taskRecordQuery.setTaskType(tableRequest.getParam().getTaskType());
+ taskRecordQuery.setGoodsType(tableRequest.getParam().getGoodsType());
+ taskRecordQuery.setSpecification(tableRequest.getParam().getSpecification());
+ PageHelper.startPage(pageRequest.getPageNum(), pageRequest.getPageSize(), orderByStr);
+ List records = taskRecordService.selTasks(taskRecordQuery);
+ PageInfo taskRecordPageInfo = new PageInfo<>(records);
+ tblResp.setCode(ResponseCode.OK.getCode());
+ tblResp.setMessage("查询任务记录成功!");
+ tblResp.setRows(taskRecordPageInfo.getList());
+ tblResp.setTotal(taskRecordPageInfo.getTotal());
+ return JSON.toJSONString(tblResp);
+
+ }
+}
diff --git a/src/main/java/com/wms/controller/StandController.java b/src/main/java/com/wms/controller/StandController.java
new file mode 100644
index 0000000..701a091
--- /dev/null
+++ b/src/main/java/com/wms/controller/StandController.java
@@ -0,0 +1,136 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.wms.constants.enums.ResponseCode;
+import com.wms.entity.app.ResponseEntity;
+import com.wms.entity.page.PageDomain;
+import com.wms.entity.page.TableRequest;
+import com.wms.entity.page.TableResponse;
+import com.wms.entity.table.StandDto;
+import com.wms.service.StandService;
+import com.wms.utils.HttpUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 站台控制类
+ */
+@Controller
+@CrossOrigin
+@RequestMapping(value = "/wms/stand")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class StandController {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ /**
+ * 站台服务
+ */
+ private final StandService standService;
+ /**
+ * 请求头部信息
+ */
+ private final HttpServletRequest servletRequest;
+
+ /**
+ * 查询可用站台列表
+ * @return 符合条件的站台列表
+ */
+ @PostMapping("/getAllStands")
+ @ResponseBody
+ public List getAllStands(@RequestBody JSONObject type){
+ logger.info("查询站台{}", JSON.toJSONString(type));
+ int type_int = type.getIntValue("type");
+ StandDto query = new StandDto();
+ if (type_int == 1) {// 入库站台
+ query.setAllowIn(1);
+ } else if (type_int == 2) {// 出库站台
+ query.setAllowOut(1);
+ } else if (type_int == 3) {// 盘点站台
+ query.setAllowIn(1);
+ query.setAllowOut(1);
+ }
+ return standService.selStands(query);
+ }
+
+ /**
+ * 更新站台状态
+ *
+ * @param stand 站台
+ * @return 结果
+ */
+ @PostMapping("/updateStandInfo")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String updateStandInfo(@RequestBody StandDto stand) {
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ standService.modifyStand(stand);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("更新站台信息发生错误:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ logger.info("更新站台信息成功:{}", stand.toLoggerString());
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("更新站台信息成功");
+ return JSON.toJSONString(rsp);
+ }
+
+ /**
+ * 查找所有库存
+ */
+ @PostMapping("/getStands")
+ @ResponseBody
+ public String getStands(@RequestBody TableRequest tableRequest){
+ logger.info("请求的ip地址:{}", HttpUtils.getIpAddr(servletRequest));
+ logger.info("接收到查询库存请求:{}", JSON.toJSONString(tableRequest));
+ TableResponse tblResp = new TableResponse();
+ // 解析请求数据
+ if (tableRequest == null || tableRequest.getPage() == null) {
+ tblResp.setCode(ResponseCode.ERROR.getCode());
+ tblResp.setMessage("请求数据为空,无法处理!");
+ logger.error("请求数据为空,无法处理!");
+ return JSON.toJSONString(tblResp);
+ }
+ // 处理分页信息
+ PageDomain pageRequest = tableRequest.getPage();
+// String[] orderByArr = {"location_id", "vehicle_id", "goods_id", "batch_no", "remain_num", "expiration_date", "create_time"};
+ String orderByStr = "";
+
+// if (StringUtils.isNotEmpty(pageRequest.getOrderByColumn()) && Arrays.asList(orderByArr).contains(StringUtils.toUnderScoreCase(pageRequest.getOrderByColumn()))) {
+// orderByStr = pageRequest.getOrderBy();
+// } else {
+// // 默认排序
+// orderByStr = "expiration_date desc";
+// }
+
+ PageHelper.startPage(pageRequest.getPageNum(), pageRequest.getPageSize(), orderByStr);
+ List stands = standService.selStands(tableRequest.getParam());
+ PageInfo standPageInfo = new PageInfo<>(stands);
+ tblResp.setCode(ResponseCode.OK.getCode());
+ tblResp.setMessage("查询库存成功!");
+ tblResp.setRows(standPageInfo.getList());
+ tblResp.setTotal(standPageInfo.getTotal());
+ logger.info("查询库存成功,总数:{},当前页:{},当前页数量:{}", standPageInfo.getTotal(), standPageInfo.getPageNum(), standPageInfo.getPageSize());
+ return JSON.toJSONString(tblResp);
+ }
+}
diff --git a/src/main/java/com/wms/controller/StockController.java b/src/main/java/com/wms/controller/StockController.java
new file mode 100644
index 0000000..6084672
--- /dev/null
+++ b/src/main/java/com/wms/controller/StockController.java
@@ -0,0 +1,164 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.wms.constants.enums.ResponseCode;
+import com.wms.entity.app.ResponseEntity;
+import com.wms.entity.page.PageDomain;
+import com.wms.entity.page.TableRequest;
+import com.wms.entity.page.TableResponse;
+import com.wms.entity.table.StockDto;
+import com.wms.service.StockService;
+import com.wms.utils.HttpUtils;
+import com.wms.utils.StringUtils;
+import com.wms.utils.WmsUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * WMS库存控制类
+ * @author 梁州
+ * @date 2023/2/14
+ */
+@Controller
+@CrossOrigin
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+@RequestMapping(value = "/wms/stock")
+public class StockController {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ /**
+ * 库存服务
+ */
+ private final StockService stockService;
+
+ /**
+ * 请求头部信息
+ */
+ private final HttpServletRequest servletRequest;
+
+ /**
+ * 查找所有库存
+ */
+ @PostMapping("/getAllStocks")
+ @ResponseBody
+ public String getAllStocks(@RequestBody TableRequest tableRequest){
+ logger.info("请求的ip地址:{}", HttpUtils.getIpAddr(servletRequest));
+ logger.info("接收到查询库存请求:{}", JSON.toJSONString(tableRequest));
+ TableResponse tblResp = new TableResponse();
+ // 解析请求数据
+ if (tableRequest == null || tableRequest.getPage() == null) {
+ tblResp.setCode(ResponseCode.ERROR.getCode());
+ tblResp.setMessage("请求数据为空,无法处理!");
+ logger.error("请求数据为空,无法处理!");
+ return JSON.toJSONString(tblResp);
+ }
+ // 处理分页信息
+ PageDomain pageRequest = tableRequest.getPage();
+ String[] orderByArr = {"location_id", "vehicle_id", "goods_id", "batch_no", "remain_num", "expiration_date", "create_time"};
+ String orderByStr;
+
+ if (StringUtils.isNotEmpty(pageRequest.getOrderByColumn()) && Arrays.asList(orderByArr).contains(StringUtils.toUnderScoreCase(pageRequest.getOrderByColumn()))) {
+ orderByStr = pageRequest.getOrderBy();
+ } else {
+ // 默认排序
+ orderByStr = "expiration_date desc";
+ }
+
+ PageHelper.startPage(pageRequest.getPageNum(), pageRequest.getPageSize(), orderByStr);
+ List stocks = stockService.selStocksFront(tableRequest.getParam());
+ PageInfo stockPageInfo = new PageInfo<>(stocks);
+ tblResp.setCode(ResponseCode.OK.getCode());
+ tblResp.setMessage("查询库存成功!");
+ tblResp.setRows(stockPageInfo.getList());
+ tblResp.setTotal(stockPageInfo.getTotal());
+ logger.info("查询库存成功,总数:{},当前页:{},当前页数量:{}", stockPageInfo.getTotal(), stockPageInfo.getPageNum(), stockPageInfo.getPageSize());
+ return JSON.toJSONString(tblResp);
+ }
+
+ /**
+ * 更新库存信息
+ *
+ * @param stock 库存
+ * @return 结果
+ */
+ @PostMapping("/updateStockInfo")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String updateStockInfo(@RequestBody StockDto stock) {
+ logger.info("接收到更新库存信息请求:{},ip地址:{}", JSON.toJSONString(stock), HttpUtils.getIpAddr(servletRequest));
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ if (StringUtils.isEmpty(stock.getStockId())) {// 库存编号为空,不允许执行
+ logger.error("请求的库存编号为空,不允许修改");
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("请求的库存编号为空,不允许修改");
+ return JSON.toJSONString(rsp);
+ }
+ if (stock.getRealNum() == 0) {
+ stockService.deleteStock(stock.getStockId());
+ } else {
+ stockService.modifyStock(stock);
+ }
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("发生异常:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("更新库存信息成功");
+ return JSON.toJSONString(rsp);
+ }
+
+ /**
+ * 新增库存
+ *
+ * @param stock 库存
+ * @return 结果
+ */
+ @PostMapping("/addNewStock")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String addNewStock(@RequestBody StockDto stock) {
+ logger.info("请求的ip地址:{}", HttpUtils.getIpAddr(servletRequest));
+ logger.info("接收到人工添加库存:{}", JSON.toJSONString(stock));
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ StockDto tempStock = new StockDto();
+ tempStock.setStockId(WmsUtils.generateId("ST"));
+
+
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("发生异常:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ // 返回成功
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("添加库存信息成功");
+ return JSON.toJSONString(rsp);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/controller/SystemController.java b/src/main/java/com/wms/controller/SystemController.java
new file mode 100644
index 0000000..7f60964
--- /dev/null
+++ b/src/main/java/com/wms/controller/SystemController.java
@@ -0,0 +1,90 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.wms.constants.enums.ResponseCode;
+import com.wms.entity.app.ResponseEntity;
+import com.wms.entity.table.UserDto;
+import com.wms.system_service.ISystemService;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import static com.wms.utils.StringUtils.convertJsonString;
+
+@Controller
+@CrossOrigin
+@RequestMapping(value = "/wms/system")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class SystemController {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ /**
+ * 系统服务
+ */
+ private final ISystemService systemService;
+
+ /**
+ * 重启系统
+ *
+ * @param user 用户
+ * @return 结果
+ */
+ @PostMapping("/restartSystem")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String restartSystem(@RequestBody UserDto user) {
+ logger.info("接收到重启系统请求:{}", convertJsonString(user));
+ ResponseEntity response = new ResponseEntity();
+ if (user == null || user.getRoleId() != 1) {// 不是管理员不允许重启
+ logger.error("非管理员不允许重启");
+ response.setCode(ResponseCode.ERROR.getCode());
+ response.setMessage("非管理员不允许重启");
+ return JSON.toJSONString(convertJsonString(response));
+ }
+ if (systemService.restartSystem()) {
+ logger.info("重启成功");
+ response.setCode(ResponseCode.OK.getCode());
+ response.setMessage("重启成功");
+ } else {
+ logger.error("重启失败");
+ response.setCode(ResponseCode.ERROR.getCode());
+ response.setMessage("重启失败");
+ }
+ return convertJsonString(response);
+ }
+
+ /**
+ * 重新载入配置
+ *
+ * @param user 用户
+ * @return 结果
+ */
+ @PostMapping("/reloadConfig")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String reloadConfig(@RequestBody UserDto user) {
+ logger.info("接收到重载配置请求:{}", convertJsonString(user));
+ ResponseEntity response = new ResponseEntity();
+ if (user == null || user.getRoleId() != 1) {// 不是管理员不允许重启
+ logger.error("非管理员不允许重载配置");
+ response.setCode(ResponseCode.ERROR.getCode());
+ response.setMessage("非管理员不允许重载配置");
+ return JSON.toJSONString(convertJsonString(response));
+ }
+ if (systemService.reloadConfig()) {
+ logger.info("重载配置成功");
+ response.setCode(ResponseCode.OK.getCode());
+ response.setMessage("重载配置成功");
+ } else {
+ logger.error("重载配置失败");
+ response.setCode(ResponseCode.ERROR.getCode());
+ response.setMessage("重载配置失败");
+ }
+ return convertJsonString(response);
+ }
+}
diff --git a/src/main/java/com/wms/controller/TaskController.java b/src/main/java/com/wms/controller/TaskController.java
new file mode 100644
index 0000000..e291b09
--- /dev/null
+++ b/src/main/java/com/wms/controller/TaskController.java
@@ -0,0 +1,93 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.wms.annotation.MyLog;
+import com.wms.constants.enums.*;
+import com.wms.entity.app.*;
+import com.wms.service.*;
+import com.wms.utils.HttpUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.web.bind.annotation.*;
+import static com.wms.utils.StringUtils.convertJsonString;
+
+/**
+ * WMS任务控制类
+ *
+ * @author 梁州
+ * @date 2023/2/14
+ */
+@Controller
+@CrossOrigin
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+@RequestMapping(value = "/wms/task")
+public class TaskController {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ /**
+ * 任务服务
+ */
+ private final TaskService taskService;
+ /**
+ * 库存服务
+ */
+ private final StockService stockService;
+ /**
+ * 库位服务
+ */
+ private final LocationService locationService;
+ /**
+ * 任务记录服务
+ */
+ private final TaskRecordService taskRecordService;
+ /**
+ * 站台服务
+ */
+ private final StandService standService;
+ /**
+ * 请求头部信息
+ */
+ private final HttpServletRequest servletRequest;
+ /**
+ * 日志服务
+ */
+ private final LogService logService;
+
+ /**
+ * 接收入库任务请求
+ *
+ * @param taskInRequest 入库任务
+ * @return 结果
+ */
+ @PostMapping("/sendGoodsInTask")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ @MyLog(logTitle = "入库请求", logMethod = "sendGoodsInTask")
+ public String receiveGoodsInTask(@RequestBody TaskInRequestEntity taskInRequest) {
+ logger.info("接收到入库请求:{},ip地址:{}", JSON.toJSONString(taskInRequest), HttpUtils.getIpAddr(servletRequest));
+ // 创建响应信息
+ ResponseEntity response = new ResponseEntity();
+ try {
+
+ logger.info("接收入库请求成功!");
+ response.setCode(ResponseCode.OK.getCode());
+ response.setMessage("接收入库请求成功!");
+ return convertJsonString(response);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.error("发生异常:{}", e.getMessage());
+ // 返回其他异常
+ response.setCode(ResponseCode.ERROR.getCode());
+ response.setMessage("发生意料之外的错误");
+ return convertJsonString(response);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/controller/TaskDealController.java b/src/main/java/com/wms/controller/TaskDealController.java
new file mode 100644
index 0000000..a7fe901
--- /dev/null
+++ b/src/main/java/com/wms/controller/TaskDealController.java
@@ -0,0 +1,172 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.wms.constants.enums.*;
+import com.wms.entity.app.ResponseEntity;
+import com.wms.entity.table.LocationDto;
+import com.wms.entity.table.TaskDto;
+import com.wms.entity.table.WmsLogDto;
+import com.wms.service.*;
+import com.wms.utils.HttpUtils;
+import com.wms.utils.StringUtils;
+import com.wms.utils.WmsUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+import static com.wms.config.InitLocalConfig.configMap;
+
+/**
+ * 这个类处理任务反馈信息
+ */
+@Controller
+@CrossOrigin
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+@RequestMapping(value = "/wms/taskDeal")
+public class TaskDealController {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ private final TaskService taskService;
+ private final HttpServletRequest servletRequest;
+ private final TaskController taskController;
+ private final StockService stockService;
+ private final LocationService locationService;
+ private final ConfigService configService;
+ private final LogService logService;
+
+ /**
+ * 更改任务状态
+ *
+ * @param request 请求参数
+ * @return 结果
+ */
+ @PostMapping("/changeTaskStatus")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String changeTaskStatus(@RequestBody TaskDto request) {
+ logger.info("用户请求更改任务状态,用户名:{},ip地址:{}", request.getUserName(), HttpUtils.getIpAddr(servletRequest));
+ logger.info("请求详细:{}", JSON.toJSONString(request));
+ ResponseEntity response = new ResponseEntity();
+ try {
+ if (request.getTaskStatus() == null) {
+ logger.error("请选择任务状态");
+ response.setCode(ResponseCode.ERROR.getCode());
+ response.setMessage("请选择任务状态");
+ return JSON.toJSONString(response);
+ }
+ // 更改后的任务状态
+ int taskStatusRequest = request.getTaskStatus();
+ int wcsTaskStatusAfter = 0;
+ // 查询任务
+ TaskDto taskQuery = new TaskDto();
+ taskQuery.setTaskId(request.getTaskId());
+ List tasks = taskService.selTasks(taskQuery);
+ if (tasks.size() == 0) {
+ logger.error("当前任务不存在");
+ response.setCode(ResponseCode.ERROR.getCode());
+ response.setMessage("当前任务不存在");
+ return JSON.toJSONString(response);
+ }
+ TaskDto currentTask = tasks.get(0);
+ String newDestination = "";
+ if (Objects.equals(currentTask.getTaskType(), TaskType.IN.getCode()) && StringUtils.isNotEmpty(request.getDestination()) && !Objects.equals(request.getDestination(), currentTask.getDestination())) {// 入库任务库位变更
+ if (taskStatusRequest != 0) {
+ logger.error("更改库位必须重置任务");
+ response.setCode(ResponseCode.ERROR.getCode());
+ response.setMessage("更改库位必须重置任务");
+ return JSON.toJSONString(response);
+ }
+ newDestination = request.getDestination();
+ }
+ String taskGroupId = currentTask.getTaskGroup();
+ if (taskStatusRequest == 0) {// 重置任务
+ logger.info("任务重置");
+ // 将当前taskGroup的所有任务都设置为新建状态
+ TaskDto taskQuery2 = new TaskDto();
+ taskQuery2.setTaskGroup(taskGroupId);
+ List tasks2 = taskService.selTasks(taskQuery2);
+ for (TaskDto task2 : tasks2) {
+ if (StringUtils.isNotEmpty(newDestination)) {
+ task2.setDestination(newDestination);
+ }
+ task2.setTaskStatus(WmsTaskStatus.NEW.getCode());
+ task2.setUserName(request.getUserName());
+ taskService.executeTask(task2);
+ }
+ // 如果更新了任务,那么该库位信息也要变更
+ if (Objects.equals(currentTask.getTaskType(), TaskType.IN.getCode()) && StringUtils.isNotEmpty(newDestination)) {
+ LocationDto newLocationQuery = new LocationDto(newDestination);
+ List newLocations = locationService.selLocations(newLocationQuery);
+ for (LocationDto newLocation : newLocations) {
+ newLocation.setLocationStatus(LocationStatus.EMPTY.getCode());
+ locationService.modifyLocation(newLocation);
+ break;
+ }
+ }
+ // WCS取消任务
+ } else if (taskStatusRequest == 1) {// 取消任务
+ logger.info("任务取消");
+ WmsReceiveTaskResultEntity sendToWmsRequest = new WmsReceiveTaskResultEntity();
+ sendToWmsRequest.setTaskId(taskGroupId);
+ sendToWmsRequest.setTaskStatus(WcsTaskStatus.CANCEL.getCode());
+ sendToWmsRequest.setVehicleNo(currentTask.getVehicleNo());
+ sendToWmsRequest.setDestination(currentTask.getDestination());
+ taskController.receiveTaskResult(sendToWmsRequest);
+ wcsTaskStatusAfter = 999;
+ } else if (taskStatusRequest == 2) {// 完成任务
+ logger.info("任务完成");
+ WmsReceiveTaskResultEntity sendToWmsRequest = new WmsReceiveTaskResultEntity();
+ sendToWmsRequest.setTaskId(taskGroupId);
+ sendToWmsRequest.setTaskStatus(WcsTaskStatus.FINISH.getCode());
+ sendToWmsRequest.setVehicleNo(currentTask.getVehicleNo());
+ sendToWmsRequest.setDestination(currentTask.getDestination());
+ taskController.receiveTaskResult(sendToWmsRequest);
+ wcsTaskStatusAfter = 3;
+ }
+ // 向WCS反馈
+ WmsReceiveTaskResultEntity sendToWcsRequest = new WmsReceiveTaskResultEntity();
+ sendToWcsRequest.setTaskId(taskGroupId);
+ sendToWcsRequest.setTaskStatus(wcsTaskStatusAfter);
+ if (StringUtils.isNotEmpty(newDestination)) {
+ sendToWcsRequest.setDestination(newDestination);
+ }
+ ResponseEntity response1;
+ for (int i = 0; i < 5; i++) {
+ // 发送请求
+ String url = configMap.get("WCS_TASK_CHANGE") ;
+ response1 = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, JSON.toJSONString(sendToWcsRequest)), ResponseEntity.class);
+ try {
+ logService.addWmsLog(new WmsLogDto(WmsUtils.generateId("LOG_"), "向WCS请求更改任务状态", "ChangeTaskStatus", JSON.toJSONString(sendToWcsRequest), JSON.toJSONString(response1), url, new Date(), "WMS"));
+ } catch (Exception e) {
+ logger.error("插入日志错误");
+ }
+ logger.info("向WCS反馈任务状态变更");
+ if (Objects.equals(response1.getCode(), 0)) {// 发送成功,则不再发送;不成功,一共尝试发送5次
+ break;
+ }
+ }
+ logger.info("更新任务状态成功");
+ response.setCode(ResponseCode.OK.getCode());
+ response.setMessage("更新任务状态成功");
+ return JSON.toJSONString(response);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.error("发生异常{}", e.getMessage());
+ response.setCode(ResponseCode.ERROR.getCode());
+ response.setMessage("发生异常" + e.getMessage());
+ return JSON.toJSONString(response);
+ }
+ }
+}
diff --git a/src/main/java/com/wms/controller/TestController.java b/src/main/java/com/wms/controller/TestController.java
new file mode 100644
index 0000000..b509b88
--- /dev/null
+++ b/src/main/java/com/wms/controller/TestController.java
@@ -0,0 +1,221 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.wms.constants.enums.LocationStatus;
+import com.wms.constants.enums.ResponseCode;
+import com.wms.constants.enums.VehicleStatus;
+import com.wms.entity.app.ResponseEntity;
+import com.wms.entity.table.LocationDto;
+import com.wms.entity.table.UserDto;
+import com.wms.entity.table.VehicleDto;
+import com.wms.entity.test.ExcelTest;
+import com.wms.service.LocationService;
+import com.wms.service.VehicleService;
+import com.wms.utils.MyPassword;
+import com.wms.utils.excel.ExcelUtils;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 测试控制类
+ */
+@Controller
+@CrossOrigin
+@RequestMapping(value = "/wms/test")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class TestController {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ /**
+ * 库位服务
+ */
+ private final LocationService locationService;
+ private final VehicleService vehicleService;
+
+ @PostMapping("/genLocations")
+ @ResponseBody
+ public String genLocations() {
+ // 巷道1 一共2排45列12层
+ for (int i = 1; i <= 18; i++) {// 列
+ for (int j = 1; j <= 11; j++) {// 层
+ // 1排
+ int markDepth1 = 1;
+ for (int m = 3; m >= 1; m--) {
+ String locationId = StringUtils.leftPad(String.valueOf(1), 2, "0") + StringUtils.leftPad(String.valueOf(i), 2, "0") + StringUtils.leftPad(String.valueOf(j), 2, "0") + "-" + StringUtils.leftPad(String.valueOf(m), 2, "0");
+ LocationDto tempLocation = new LocationDto();
+ tempLocation.setLocationId(locationId);
+ tempLocation.setAreaId(1);
+ tempLocation.setTunnelId(1);
+ tempLocation.setEquipmentId(1);
+ tempLocation.setLocationType(0);
+ tempLocation.setQueue(1);
+ tempLocation.setLine(i);
+ tempLocation.setLayer(j);
+ tempLocation.setDepth(m);
+ tempLocation.setIsLock(0);
+ tempLocation.setLocationStatus(0);
+ tempLocation.setMarkDepth(markDepth1);
+ if (locationService.selLocations(tempLocation).size() == 0) {
+ locationService.addLocation(tempLocation);
+ markDepth1++;
+ }
+ }
+ // 2排
+ int markDepth2 = 4;
+ for (int m = 1; m <= 3; m++) {
+ String locationId = StringUtils.leftPad(String.valueOf(2), 2, "0") + StringUtils.leftPad(String.valueOf(i), 2, "0") + StringUtils.leftPad(String.valueOf(j), 2, "0") + "-" + StringUtils.leftPad(String.valueOf(m), 2, "0");
+ LocationDto tempLocation = new LocationDto();
+ tempLocation.setLocationId(locationId);
+ tempLocation.setAreaId(1);
+ tempLocation.setTunnelId(1);
+ tempLocation.setEquipmentId(1);
+ tempLocation.setLocationType(0);
+ tempLocation.setQueue(2);
+ tempLocation.setLine(i);
+ tempLocation.setLayer(j);
+ tempLocation.setDepth(m);
+ tempLocation.setIsLock(0);
+ tempLocation.setLocationStatus(0);
+ tempLocation.setMarkDepth(markDepth2);
+ if (locationService.selLocations(tempLocation).size() == 0) {
+ locationService.addLocation(tempLocation);
+ markDepth2++;
+ }
+ }
+ // 3排
+ int markDepth3 = 4;
+ for (int m = 1; m <= 3; m++) {
+ String locationId = StringUtils.leftPad(String.valueOf(3), 2, "0") + StringUtils.leftPad(String.valueOf(i), 2, "0") + StringUtils.leftPad(String.valueOf(j), 2, "0") + "-" + StringUtils.leftPad(String.valueOf(m), 2, "0");
+ LocationDto tempLocation = new LocationDto();
+ tempLocation.setLocationId(locationId);
+ tempLocation.setAreaId(1);
+ tempLocation.setTunnelId(2);
+ tempLocation.setEquipmentId(2);
+ tempLocation.setLocationType(0);
+ tempLocation.setQueue(3);
+ tempLocation.setLine(i);
+ tempLocation.setLayer(j);
+ tempLocation.setDepth(m);
+ tempLocation.setIsLock(0);
+ tempLocation.setLocationStatus(0);
+ tempLocation.setMarkDepth(markDepth3);
+ if (locationService.selLocations(tempLocation).size() == 0) {
+ locationService.addLocation(tempLocation);
+ markDepth3++;
+ }
+ }
+ // 4排
+ int markDepth4 = 1;
+ for (int m = 3; m >= 1; m--) {
+ String locationId = StringUtils.leftPad(String.valueOf(4), 2, "0") + StringUtils.leftPad(String.valueOf(i), 2, "0") + StringUtils.leftPad(String.valueOf(j), 2, "0") + "-" + StringUtils.leftPad(String.valueOf(m), 2, "0");
+ LocationDto tempLocation = new LocationDto();
+ tempLocation.setLocationId(locationId);
+ tempLocation.setAreaId(1);
+ tempLocation.setTunnelId(2);
+ tempLocation.setEquipmentId(2);
+ tempLocation.setLocationType(0);
+ tempLocation.setQueue(4);
+ tempLocation.setLine(i);
+ tempLocation.setLayer(j);
+ tempLocation.setDepth(m);
+ tempLocation.setIsLock(0);
+ tempLocation.setLocationStatus(0);
+ tempLocation.setMarkDepth(markDepth4);
+ if (locationService.selLocations(tempLocation).size() == 0) {
+ locationService.addLocation(tempLocation);
+ markDepth4++;
+ }
+ }
+ }
+ }
+ return "success";
+ }
+
+ /**
+ * 测试导入
+ *
+ * @param file 文件
+ * @return 导入结果
+ */
+ @PostMapping("/testExcelImport")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String testExcelImport(@RequestPart("file") MultipartFile file) {
+ ResponseEntity response = new ResponseEntity();
+ try {
+ List tests = ExcelUtils.readMultipartFile(file, ExcelTest.class);
+ for (ExcelTest test : tests) {
+ // 更新库位
+ LocationDto locationQuery = new LocationDto();
+ locationQuery.setLocationId(test.getLocationId());
+ List locations = locationService.selLocations(locationQuery);
+ if (locations.size() > 0) {
+ LocationDto currentLocation = locations.get(0);
+ currentLocation.setLocationStatus(LocationStatus.OCCUPY.getCode());
+ locationService.modifyLocation(currentLocation);
+ // 添加载具
+ VehicleDto vehicle = new VehicleDto();
+ vehicle.setVehicleId("XZBK" + StringUtils.leftPad(test.getVehicleId().trim(), 4, "0"));
+ vehicle.setCurrentLocation(test.getLocationId());
+ vehicle.setVehicleStatus(VehicleStatus.ON.getCode());
+ vehicle.setIsEmpty(1);
+ if (vehicleService.selVehicleById(test.getVehicleId()) == null) {
+ vehicleService.addVehicle(vehicle);
+ } else {
+ vehicleService.modifyVehicle(vehicle);
+ }
+ }
+ }
+ response.setCode(ResponseCode.OK.getCode());
+ response.setMessage("导入excel成功");
+ response.setReturnData(tests);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ response.setCode(ResponseCode.ERROR.getCode());
+ response.setMessage("导入excel发生错误");
+ }
+ logger.info(JSON.toJSONString(response));
+ return JSON.toJSONString(response);
+ }
+
+ /**
+ * 测试导出
+ *
+ * @param response 请求
+ */
+ @GetMapping("/testExcelExport")
+ @ResponseBody
+ public void testExcelExport(HttpServletResponse response) {
+ List tests = new ArrayList<>();
+ ExcelTest temp1 = new ExcelTest("010101", "XZBK0001");
+ ExcelTest temp2 = new ExcelTest("020101", "XZBK0002");
+ tests.add(temp1);
+ tests.add(temp2);
+ ExcelUtils.export(response, "测试导出", tests, ExcelTest.class);
+ }
+
+ @PostMapping("/genPassword")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String genPassword(@RequestBody UserDto user) {
+ ResponseEntity response = new ResponseEntity();
+ response.setCode(ResponseCode.OK.getCode());
+ response.setMessage("创建密码成功");
+ response.setReturnData(MyPassword.encrypt(user.getLoginPassword()));
+ return JSON.toJSONString(response);
+ }
+}
diff --git a/src/main/java/com/wms/controller/UserController.java b/src/main/java/com/wms/controller/UserController.java
new file mode 100644
index 0000000..1e44af0
--- /dev/null
+++ b/src/main/java/com/wms/controller/UserController.java
@@ -0,0 +1,208 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.wms.constants.enums.ResponseCode;
+import com.wms.entity.app.vo.MenuEntity;
+import com.wms.entity.app.ResponseEntity;
+import com.wms.entity.app.vo.UserConfigEntity;
+import com.wms.entity.table.MenuDto;
+import com.wms.entity.table.UserDto;
+import com.wms.service.MenuService;
+import com.wms.service.UserService;
+import com.wms.utils.MyPassword;
+import com.wms.constants.WmsConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * WMS用户控制类
+ * @author 梁州
+ * @date 2023/2/14
+ */
+@Controller
+@CrossOrigin
+@RequestMapping(value = "/wms/user")
+public class UserController {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ /**
+ * 用户服务
+ */
+ final UserService userService;
+ /**
+ * 菜单服务
+ */
+ final MenuService menuService;
+
+ @Autowired
+ public UserController(UserService userService, MenuService menuService) {
+ this.userService = userService;
+ this.menuService = menuService;
+ }
+
+ /**
+ * 带密码登录
+ * @param user 用户
+ * @return 结果
+ */
+ @PostMapping("/loginWithAuth")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String loginWithAuth(@RequestBody UserDto user) {
+ logger.info("WMS前端用户登录,登录账户名:{}", user.getLoginAccount());
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ // 查找对应用户的信息
+ UserDto userForQuery = new UserDto();
+ userForQuery.setLoginAccount(user.getLoginAccount());
+ List waitForAuthUsers = userService.selectUsers(userForQuery);
+ if (waitForAuthUsers.size() < 1) {
+ logger.error("用户不存在,登录账户名:{}", user.getLoginAccount());
+ // 返回错误
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("用户不存在");
+ return JSON.toJSONString(rsp);
+ }
+ // 验证密码
+ UserDto waitForAuthUser = waitForAuthUsers.get(0);
+ if (!Objects.equals(MyPassword.encrypt(user.getLoginPassword()), waitForAuthUser.getLoginPassword())) {
+ logger.error("密码错误,登录账户名:{}", user.getLoginAccount());
+ // 返回错误
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("密码错误");
+ return JSON.toJSONString(rsp);
+ }
+ // 当前用户
+ UserDto currentUser = waitForAuthUsers.get(0);
+
+ // 返回成功
+ logger.info("登录成功,登录账户名:{}", currentUser.getLoginAccount());
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("登录成功");
+ // 返回用户数据
+ rsp.setReturnData(generateUserInfo(currentUser));
+ return JSON.toJSONString(rsp);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("数据库错误:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage(e.getMessage());
+ return JSON.toJSONString(rsp);
+ }
+ }
+
+ /**
+ * 无密码登录
+ * @param user 用户
+ * @return 结果
+ */
+ @PostMapping("/loginWithoutAuth")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String loginWithoutAuth(@RequestBody UserDto user) {
+ logger.info("WMS前端用户登录,登录账户名:{}", user.getLoginAccount());
+ // 创建响应信息
+ ResponseEntity rsp = new ResponseEntity();
+ try {
+ // 查找对应用户的信息
+ UserDto userForQuery = new UserDto();
+ userForQuery.setLoginAccount(user.getLoginAccount());
+ List waitForAuthUsers = userService.selectUsers(userForQuery);
+ if (waitForAuthUsers.size() < 1) {
+ // 返回错误
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("用户不存在");
+ return JSON.toJSONString(rsp);
+ }
+ UserDto currentUser = waitForAuthUsers.get(0);
+ // 返回成功
+ logger.info("登录成功,登录账户名:{}", currentUser.getLoginAccount());
+ rsp.setCode(ResponseCode.OK.getCode());
+ rsp.setMessage("登录成功");
+ // 返回用户数据
+ rsp.setReturnData(generateUserInfo(currentUser));
+ return JSON.toJSONString(rsp);
+ } catch (Exception e) {
+ // 回滚事务
+ TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+ logger.info("数据库错误:{}", e.getMessage());
+ // 返回其他异常
+ rsp.setCode(ResponseCode.ERROR.getCode());
+ rsp.setMessage("数据库错误");
+ return JSON.toJSONString(rsp);
+ }
+ }
+
+ /**
+ * 构造用户信息(菜单、按钮等权限)
+ * @param currentUser 当前用户
+ * @return 用户信息
+ */
+ private UserConfigEntity generateUserInfo (UserDto currentUser) {
+ UserConfigEntity userConfigEntity = new UserConfigEntity();
+ try {
+ List menus = menuService.selMenuByRoleId(currentUser.getRoleId());
+ List menuList = new LinkedList<>();
+ // 查找一级菜单
+ for (MenuDto firstMenu : menus) {
+ if (WmsConstants.ROOT_MENU_ID.equals(firstMenu.getParentId())) {// 查找到所有的一级子菜单
+ MenuEntity tempFirstMenu = new MenuEntity();
+ tempFirstMenu.setId(firstMenu.getMenuId());// ID
+ tempFirstMenu.setLabelName(firstMenu.getLabelName());// 菜单显示名称
+ tempFirstMenu.setIconValue(firstMenu.getIconValue());// 图标
+ tempFirstMenu.setPath(firstMenu.getPath());// 路径
+ // 设置子菜单
+ List tempFirstMenuChildren = new LinkedList<>();
+ for (MenuDto secondMenu : menus) {
+ if (firstMenu.getMenuId().equals(secondMenu.getParentId())) {
+ MenuEntity tempSecondMenu = new MenuEntity();
+ tempSecondMenu.setId(secondMenu.getMenuId());// ID
+ tempSecondMenu.setLabelName(secondMenu.getLabelName());// 菜单显示名称
+ tempSecondMenu.setIconValue(secondMenu.getIconValue());// 图标
+ tempSecondMenu.setPath(secondMenu.getPath());// 路径
+ // 设置子菜单
+ List tempSecondMenuChildren = new LinkedList<>();
+ for (MenuDto thirdMenu : menus) {
+ if (secondMenu.getMenuId().equals(thirdMenu.getParentId())) {
+ MenuEntity tempThirdMenu = new MenuEntity();
+ tempSecondMenu.setId(thirdMenu.getMenuId());// ID
+ tempSecondMenu.setLabelName(thirdMenu.getLabelName());// 菜单显示名称
+ tempSecondMenu.setIconValue(thirdMenu.getIconValue());// 图标
+ tempSecondMenu.setPath(thirdMenu.getPath());// 路径
+ // 添加按钮
+ tempSecondMenuChildren.add(tempThirdMenu);
+ }
+ }
+ tempSecondMenu.setChildren(tempSecondMenuChildren);
+ // 添加二级菜单
+ tempFirstMenuChildren.add(tempSecondMenu);
+ }
+ }
+ tempFirstMenu.setChildren(tempFirstMenuChildren);
+ // 添加一级菜单
+ menuList.add(tempFirstMenu);
+ }
+ }
+ logger.info("构造用户信息成功,当前用户:{}", currentUser.getUserName());
+ // 设置返回信息
+ userConfigEntity.setUser(currentUser);
+ userConfigEntity.setMenuList(menuList);
+ } catch (Exception e) {
+ logger.error("构造用户信息失败,当前用户:{}", currentUser.getUserName());
+ }
+ return userConfigEntity;
+ }
+}
diff --git a/src/main/java/com/wms/controller/WmsLogController.java b/src/main/java/com/wms/controller/WmsLogController.java
new file mode 100644
index 0000000..75f9789
--- /dev/null
+++ b/src/main/java/com/wms/controller/WmsLogController.java
@@ -0,0 +1,70 @@
+package com.wms.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.wms.constants.enums.ResponseCode;
+import com.wms.entity.page.PageDomain;
+import com.wms.entity.page.TableRequest;
+import com.wms.entity.page.TableResponse;
+import com.wms.entity.table.WmsLogDto;
+import com.wms.service.LogService;
+import com.wms.utils.HttpUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@Controller
+@CrossOrigin
+@RequestMapping(value = "/wms/log")
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class WmsLogController {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ /**
+ * 请求头部信息
+ */
+ private final HttpServletRequest servletRequest;
+ /**
+ * 日志服务
+ */
+ private final LogService logService;
+
+ /**
+ * 查询日志
+ *
+ * @param tableRequest 请求参数
+ * @return 结果
+ */
+ @PostMapping("/queryWmsLog")
+ @ResponseBody
+ @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
+ public String queryLogs(@RequestBody TableRequest tableRequest) {
+ logger.info("查询日志,ip地址:{}, 用户名:{}", HttpUtils.getIpAddr(servletRequest), tableRequest.getParam().getLogUser());
+ TableResponse tblResp = new TableResponse();
+ try {
+ // 处理分页信息
+ PageDomain pageRequest = tableRequest.getPage();
+ PageHelper.startPage(pageRequest.getPageNum(), pageRequest.getPageSize());
+ List logList = logService.selWmsLogs(tableRequest.getParam().getLogRequest());
+ PageInfo logListPage = new PageInfo<>(logList);
+ tblResp.setCode(ResponseCode.OK.getCode());
+ tblResp.setMessage("查询日志成功!");
+ tblResp.setRows(logListPage.getList());
+ tblResp.setTotal(logListPage.getTotal());
+ return JSON.toJSONString(tblResp);
+ } catch (Exception e) {
+ tblResp.setCode(ResponseCode.ERROR.getCode());
+ tblResp.setMessage("查询日志失败");
+ }
+ return JSON.toJSONString(tblResp);
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/ResponseEntity.java b/src/main/java/com/wms/entity/app/ResponseEntity.java
new file mode 100644
index 0000000..0f48344
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/ResponseEntity.java
@@ -0,0 +1,46 @@
+package com.wms.entity.app;
+
+/**
+ * 接口响应实体类
+ */
+public class ResponseEntity {
+
+ /**
+ * 响应代码
+ */
+ private Integer code;
+
+ /**
+ * 错误信息
+ */
+ private String message;
+
+ /**
+ * 返回数据(非必须)
+ */
+ private Object returnData;
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public Object getReturnData() {
+ return returnData;
+ }
+
+ public void setReturnData(Object returnData) {
+ this.returnData = returnData;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/display/LocationData.java b/src/main/java/com/wms/entity/app/display/LocationData.java
new file mode 100644
index 0000000..2c9f2b9
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/display/LocationData.java
@@ -0,0 +1,55 @@
+package com.wms.entity.app.display;
+
+/**
+ * 大屏用数据详细类
+ */
+public class LocationData {
+ /**
+ * 零件号
+ */
+ private String goodsId;
+ /**
+ * 零件名称
+ */
+ private String goodsName;
+ /**
+ * 数量
+ */
+ private Integer goodsNum;
+ /**
+ * 备注
+ */
+ private String remark;
+
+ public String getGoodsId() {
+ return goodsId;
+ }
+
+ public void setGoodsId(String goodsId) {
+ this.goodsId = goodsId;
+ }
+
+ public String getGoodsName() {
+ return goodsName;
+ }
+
+ public void setGoodsName(String goodsName) {
+ this.goodsName = goodsName;
+ }
+
+ public Integer getGoodsNum() {
+ return goodsNum;
+ }
+
+ public void setGoodsNum(Integer goodsNum) {
+ this.goodsNum = goodsNum;
+ }
+
+ public String getRemark() {
+ return remark;
+ }
+
+ public void setRemark(String remark) {
+ this.remark = remark;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/display/LocationInfo.java b/src/main/java/com/wms/entity/app/display/LocationInfo.java
new file mode 100644
index 0000000..10eeee1
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/display/LocationInfo.java
@@ -0,0 +1,45 @@
+package com.wms.entity.app.display;
+
+import java.util.List;
+
+/**
+ * 大屏用库位信息
+ */
+public class LocationInfo {
+ /**
+ * 库位编号
+ */
+ private String locationId;
+ /**
+ * 料箱号
+ */
+ private String vehicleNo;
+ /**
+ * 详细数据
+ */
+ private List locationData;
+
+ public String getLocationId() {
+ return locationId;
+ }
+
+ public void setLocationId(String locationId) {
+ this.locationId = locationId;
+ }
+
+ public String getVehicleNo() {
+ return vehicleNo;
+ }
+
+ public void setVehicleNo(String vehicleNo) {
+ this.vehicleNo = vehicleNo;
+ }
+
+ public List getLocationData() {
+ return locationData;
+ }
+
+ public void setLocationData(List locationData) {
+ this.locationData = locationData;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/dto/ConfigDto.java b/src/main/java/com/wms/entity/app/dto/ConfigDto.java
new file mode 100644
index 0000000..d8dff40
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/ConfigDto.java
@@ -0,0 +1,34 @@
+package com.wms.entity.app.dto;
+
+import lombok.Data;
+
+/**
+ * 配置
+ */
+@Data
+public class ConfigDto {
+ /**
+ * 配置ID
+ */
+ private Integer configId;
+
+ /**
+ * 配置键
+ */
+ private String configKey;
+
+ /**
+ * 配置值
+ */
+ private String configValue;
+
+ /**
+ * 配置类型
+ */
+ private String configType;
+
+ /**
+ * 配置名称
+ */
+ private String configName;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/GoodsDto.java b/src/main/java/com/wms/entity/app/dto/GoodsDto.java
new file mode 100644
index 0000000..3d9e056
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/GoodsDto.java
@@ -0,0 +1,56 @@
+package com.wms.entity.app.dto;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 物料
+ */
+@Data
+public class GoodsDto {
+ /**
+ * 物料编号
+ */
+ private String goodsId;
+ /**
+ * 物料名称
+ */
+ private String goodsName;
+ /**
+ * 单位
+ */
+ private String goodsUnit;
+ /**
+ * 物料ID
+ */
+ private String itemId;
+ /**
+ * 用户物料类型
+ */
+ private String itemType;
+ /**
+ * 库存类别
+ */
+ private String invCategory;
+ /**
+ * 存储天数
+ */
+ private Integer lifeDays;
+ /**
+ * 库存组织Id
+ */
+ private String organizationId;
+ /**
+ * 库存组织代码
+ */
+ private String organizationCode;
+ /**
+ * 最后更新日期
+ */
+ private Date lastUpdateTime;
+ /**
+ * 最后更新用户
+ */
+ private String lastUpdateUser;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/LocationDto.java b/src/main/java/com/wms/entity/app/dto/LocationDto.java
new file mode 100644
index 0000000..865c8a9
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/LocationDto.java
@@ -0,0 +1,50 @@
+package com.wms.entity.app.dto;
+
+import lombok.Data;
+
+/**
+ * 库位
+ */
+@Data
+public class LocationDto {
+ /**
+ * 库位编号
+ */
+ private String locationId;
+ /**
+ * 库区编号
+ */
+ private Integer areaId;
+ /**
+ * 设备编号
+ */
+ private Integer equipmentId;
+ /**
+ * 库位类型
+ */
+ private Integer locationType;
+ /**
+ * 排
+ */
+ private Integer wRow;
+ /**
+ * 列
+ */
+ private Integer wCol;
+ /**
+ * 层
+ */
+ private Integer wLayer;
+ /**
+ * 深度
+ */
+ private Integer wDepth;
+ /**
+ * 是否锁定
+ */
+ private Integer isLock;
+ /**
+ * 库位状态
+ */
+ private Integer locationStatus;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/MenuDto.java b/src/main/java/com/wms/entity/app/dto/MenuDto.java
new file mode 100644
index 0000000..4a34392
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/MenuDto.java
@@ -0,0 +1,30 @@
+package com.wms.entity.app.dto;
+
+import lombok.Data;
+
+/**
+ * 菜单
+ */
+@Data
+public class MenuDto {
+ /**
+ * 菜单Id
+ */
+ private String menuId;
+ /**
+ * 菜单名称
+ */
+ private String labelName;
+ /**
+ * 图标值
+ */
+ private String iconValue;
+ /**
+ * 地址
+ */
+ private String path;
+ /**
+ * 父菜单Id
+ */
+ private String parentId;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/PageDto.java b/src/main/java/com/wms/entity/app/dto/PageDto.java
new file mode 100644
index 0000000..5996657
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/PageDto.java
@@ -0,0 +1,43 @@
+package com.wms.entity.app.dto;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Function;
+
+@Data
+@ApiModel(value = "分页数据实体")
+public class PageDto {
+ @ApiModelProperty(value ="总行数")
+ private Long total;
+ @ApiModelProperty(value ="总页数")
+ private Long pages;
+ @ApiModelProperty(value ="数据集合")
+ private List lists;
+
+ /**
+ * 将数据库集合转换为分页结果
+ * @param page 数据库查询结果
+ * @param converter 转换方法
+ * @return 转换后的分页结果
+ * @param 数据库结果集
+ * @param 前端显示结果集
+ */
+ public static PageDto of(Page page, Function converter) {
+ PageDto pageDto = new PageDto<>();
+ // 设置总数
+ pageDto.setTotal(page.getTotal());
+ // 设置总页数
+ pageDto.setPages(page.getPages());
+ if (page.getRecords().isEmpty()) {
+ pageDto.setLists(Collections.emptyList());
+ return pageDto;
+ }
+ pageDto.setLists(page.getRecords().stream().map(converter).toList());
+ return pageDto;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/dto/StandDto.java b/src/main/java/com/wms/entity/app/dto/StandDto.java
new file mode 100644
index 0000000..cf68593
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/StandDto.java
@@ -0,0 +1,57 @@
+package com.wms.entity.app.dto;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 站台表
+ */
+@Data
+public class StandDto {
+ /**
+ * 站台id
+ */
+ private String standId;
+ /**
+ * 是否允许入库
+ */
+ private Integer allowIn;
+ /**
+ * 是否允许出库
+ */
+ private Integer allowOut;
+ /**
+ * 站台是否锁定
+ */
+ private Integer isLock;
+ /**
+ * 站台状态
+ */
+ private Integer standStatus;
+ /**
+ * 设备编号
+ */
+ private Integer equipmentId;
+ /**
+ * 库区编号
+ */
+ private Integer areaId;
+ /**
+ * 站台类型
+ */
+ private Integer standType;
+ /**
+ * 站台ip
+ */
+ private String standIp;
+ /**
+ * 外部id
+ * 如果对接,其它系统的站台id
+ */
+ private String outerId;
+ /**
+ * 最近一次的使用时间
+ */
+ private LocalDateTime lastUseTime;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/StockDto.java b/src/main/java/com/wms/entity/app/dto/StockDto.java
new file mode 100644
index 0000000..b7dfaf6
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/StockDto.java
@@ -0,0 +1,66 @@
+package com.wms.entity.app.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.wms.entity.app.dto.extend.StockDetailInfo;
+import com.wms.utils.excel.ExcelExport;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 库存
+ */
+@Data
+public class StockDto {
+ /**
+ * 库存编号
+ */
+ private String stockId;
+ /**
+ * 库位ID
+ */
+ private String locationId;
+ /**
+ * 托盘号
+ */
+ private String vehicleId;
+ /**
+ * 重量
+ */
+ private BigDecimal weight;
+ /**
+ * 库存状态
+ * 正常、出库中、锁定 等
+ */
+ private Integer stockStatus;
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+ /**
+ * 最后更新时间
+ */
+ private LocalDateTime lastUpdateTime;
+ /**
+ * 最后更新用户
+ */
+ private String lastUpdateUser;
+ /**
+ * 是否盘点
+ */
+ private Integer isInventory;
+ /**
+ * 盘点任务号 盘点出库和盘点入库同样
+ */
+ private String inventoryTaskId;
+ /**
+ * 呆滞天数
+ */
+ private Integer noUseDays;
+ /**
+ * 物料相关信息
+ */
+ private StockDetailInfo goodsRelated;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/TaskDto.java b/src/main/java/com/wms/entity/app/dto/TaskDto.java
new file mode 100644
index 0000000..c1bb74b
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/TaskDto.java
@@ -0,0 +1,70 @@
+package com.wms.entity.app.dto;
+
+import com.wms.entity.app.dto.extend.TaskDetailInfo;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 任务
+ */
+@Data
+public class TaskDto {
+ /**
+ * 任务号
+ */
+ private String taskId;
+ /**
+ * 任务类型
+ */
+ private Integer taskType;
+ /**
+ * 任务状态
+ */
+ private Integer taskStatus;
+ /**
+ * 起点
+ */
+ private String origin;
+ /**
+ * 终点
+ */
+ private String destination;
+ /**
+ * 任务优先级
+ */
+ private Integer taskPriority;
+ /**
+ * 任务组
+ */
+ private String taskGroup;
+ /**
+ * 载具号
+ */
+ private String vehicleId;
+ /**
+ * 重量
+ */
+ private BigDecimal weight;
+ /**
+ * 载具尺寸
+ */
+ private Integer vehicleSize;
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+ /**
+ * 完成时间
+ */
+ private LocalDateTime finishTime;
+ /**
+ * 用户名
+ */
+ private String userName;
+ /**
+ * 物料相关信息
+ */
+ private TaskDetailInfo goodsRelated;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/TaskRecordDto.java b/src/main/java/com/wms/entity/app/dto/TaskRecordDto.java
new file mode 100644
index 0000000..4365cbd
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/TaskRecordDto.java
@@ -0,0 +1,67 @@
+package com.wms.entity.app.dto;
+
+import com.wms.entity.app.dto.extend.TaskDetailInfo;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+public class TaskRecordDto {
+ /**
+ * 任务号
+ */
+ private String taskId;
+ /**
+ * 任务类型
+ */
+ private Integer taskType;
+ /**
+ * 任务状态
+ */
+ private Integer taskStatus;
+ /**
+ * 起点
+ */
+ private String origin;
+ /**
+ * 终点
+ */
+ private String destination;
+ /**
+ * 任务优先级
+ */
+ private Integer taskPriority;
+ /**
+ * 任务组
+ */
+ private String taskGroup;
+ /**
+ * 载具号
+ */
+ private String vehicleId;
+ /**
+ * 重量
+ */
+ private BigDecimal weight;
+ /**
+ * 载具尺寸
+ */
+ private Integer vehicleSize;
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+ /**
+ * 完成时间
+ */
+ private LocalDateTime finishTime;
+ /**
+ * 用户名
+ */
+ private String userName;
+ /**
+ * 物料相关
+ */
+ private TaskDetailInfo goodsRelated;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/UserDto.java b/src/main/java/com/wms/entity/app/dto/UserDto.java
new file mode 100644
index 0000000..2c43710
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/UserDto.java
@@ -0,0 +1,28 @@
+package com.wms.entity.app.dto;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 用户
+ */
+@Data
+public class UserDto {
+ /** 用户ID */
+ private Integer userId;
+ /** 用户名 */
+ private String userName;
+ /** 角色Id */
+ private Integer roleId = null;
+ /** 登录账户 */
+ private String loginAccount;
+ /** 登录密码 */
+ private String loginPassword;
+ /** 添加时间 */
+ private LocalDateTime addTime;
+ /** 更新时间 */
+ private LocalDateTime updateTime;
+ /** 添加用户名 */
+ private String addUser;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/VehicleDto.java b/src/main/java/com/wms/entity/app/dto/VehicleDto.java
new file mode 100644
index 0000000..e695223
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/VehicleDto.java
@@ -0,0 +1,35 @@
+package com.wms.entity.app.dto;
+
+import com.wms.entity.app.dto.extend.VehicleDetailInfo;
+import lombok.Data;
+
+/**
+ * 载具
+ */
+@Data
+public class VehicleDto {
+ /**
+ * 载具编号
+ */
+ private String vehicleId;
+ /**
+ * 当前所在位置
+ */
+ private String currentLocation;
+ /**
+ * 载具状态
+ */
+ private Integer vehicleStatus;
+ /**
+ * 是否是空箱
+ */
+ private Integer isEmpty;
+ /**
+ * 载具类型
+ */
+ private Integer vehicleType;
+ /**
+ * 额外信息
+ */
+ private VehicleDetailInfo details;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/WmsLogDto.java b/src/main/java/com/wms/entity/app/dto/WmsLogDto.java
new file mode 100644
index 0000000..664dacf
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/WmsLogDto.java
@@ -0,0 +1,46 @@
+package com.wms.entity.app.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.extension.handlers.Fastjson2TypeHandler;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 操作日志类
+ */
+@Data
+public class WmsLogDto {
+ /**
+ * id
+ */
+ private String logId;
+ /**
+ * 描述/标题
+ */
+ private String logTitle;
+ /**
+ * 方法
+ */
+ private String logMethod;
+ /**
+ * 请求参数
+ */
+ private Object logRequest;
+ /**
+ * 响应参数
+ */
+ private Object logResponse;
+ /**
+ * 请求的ip
+ */
+ private String logIp;
+ /**
+ * 请求时间
+ */
+ private LocalDateTime logTime;
+ /**
+ * 请求用户
+ */
+ private String logUser;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/extend/StockDetailInfo.java b/src/main/java/com/wms/entity/app/dto/extend/StockDetailInfo.java
new file mode 100644
index 0000000..49a583f
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/extend/StockDetailInfo.java
@@ -0,0 +1,19 @@
+package com.wms.entity.app.dto.extend;
+
+import lombok.Data;
+
+@Data
+public class StockDetailInfo {
+ /**
+ * 物料编号
+ */
+ private String goodsId;
+ /**
+ * 物料名称
+ */
+ private String goodsName;
+ /**
+ * 物料状态
+ */
+ private Integer goodsStatus;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/extend/TaskDetailInfo.java b/src/main/java/com/wms/entity/app/dto/extend/TaskDetailInfo.java
new file mode 100644
index 0000000..3519b93
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/extend/TaskDetailInfo.java
@@ -0,0 +1,15 @@
+package com.wms.entity.app.dto.extend;
+
+import lombok.Data;
+
+@Data
+public class TaskDetailInfo {
+ /**
+ * 物料编号
+ */
+ private String goodsId;
+ /**
+ * 物料名称
+ */
+ private String goodsName;
+}
diff --git a/src/main/java/com/wms/entity/app/dto/extend/VehicleDetailInfo.java b/src/main/java/com/wms/entity/app/dto/extend/VehicleDetailInfo.java
new file mode 100644
index 0000000..6869970
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/dto/extend/VehicleDetailInfo.java
@@ -0,0 +1,18 @@
+package com.wms.entity.app.dto.extend;
+
+import lombok.Data;
+
+/**
+ * 料箱详细信息
+ */
+@Data
+public class VehicleDetailInfo {
+ /// 上
+ private String up;
+ /// 下
+ private String down;
+ /// 左右
+ private String left;
+ /// 右
+ private String right;
+}
diff --git a/src/main/java/com/wms/entity/app/query/GoodsQuery.java b/src/main/java/com/wms/entity/app/query/GoodsQuery.java
new file mode 100644
index 0000000..edabbab
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/query/GoodsQuery.java
@@ -0,0 +1,33 @@
+package com.wms.entity.app.query;
+
+import com.wms.entity.app.dto.extend.StockDetailInfo;
+import com.wms.entity.table.Goods;
+import com.wms.entity.table.Stock;
+import com.wms.utils.StringUtils;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel(value = "物料查询")
+public class GoodsQuery extends PageQuery{
+ @ApiModelProperty(value ="物料编号")
+ private String goodsId;
+ @ApiModelProperty(value ="物料名称")
+ private String goodsName;
+
+
+ /**
+ * 将goodsQuery转化为GoodsPO
+ * @return goodsPO
+ */
+ public Goods toGoodsPO() {
+ Goods goodsPO = new Goods();
+ goodsPO.setGoodsId(goodsId);// 物料编号
+ goodsPO.setGoodsName(goodsName);// 物料描述
+
+ return goodsPO;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/query/PageQuery.java b/src/main/java/com/wms/entity/app/query/PageQuery.java
new file mode 100644
index 0000000..b2bd61e
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/query/PageQuery.java
@@ -0,0 +1,48 @@
+package com.wms.entity.app.query;
+
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.wms.utils.StringUtils;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "分页查询")
+public class PageQuery {
+ @ApiModelProperty(value ="页码")
+ private Long pageNo = 1L;
+ @ApiModelProperty(value ="每页行数")
+ private Long pageSize = 10L;
+ @ApiModelProperty(value ="排序字段")
+ private String sortBy;
+ @ApiModelProperty(value ="是否升序")
+ private Boolean isAsc = true;
+
+ /**
+ * 将前端查询转换为数据库查询可用的分页查询
+ * @param orderItems 排序字段
+ * @return 分页查询
+ * @param 实体类PO
+ */
+ public Page toMpPage(OrderItem ... orderItems){
+ Page page = Page.of(pageNo, pageSize);
+ if (StringUtils.isNotEmpty(sortBy)) {
+ page.addOrder(new OrderItem().setColumn(sortBy).setAsc(isAsc));
+ } else {
+ page.addOrder(orderItems);
+ }
+ return page;
+ }
+
+ /**
+ * 传入 默认排序字段的转换
+ * @param defaultSortValue 默认查询
+ * @param isAsc 排序方式
+ * @return 分页查询
+ * @param 实体类
+ */
+ public Page toMpPage(String defaultSortValue, Boolean isAsc){
+ return toMpPage(new OrderItem().setColumn(sortBy).setAsc(isAsc));
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/query/StockQuery.java b/src/main/java/com/wms/entity/app/query/StockQuery.java
new file mode 100644
index 0000000..e3b66c0
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/query/StockQuery.java
@@ -0,0 +1,47 @@
+package com.wms.entity.app.query;
+
+import com.wms.entity.app.dto.extend.StockDetailInfo;
+import com.wms.entity.table.Stock;
+import com.wms.utils.StringUtils;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "库存记录查询---客户端")
+public class StockQuery extends PageQuery {
+ @ApiModelProperty(value = "库存状态")
+ private Integer stockStatus;
+ @ApiModelProperty(value = "物料状态")
+ private Integer goodsStatus;
+ @ApiModelProperty(value = "库位编号")
+ private String locationId;
+ @ApiModelProperty(value = "载具号/料箱号")
+ private String vehicleId;
+ @ApiModelProperty(value = "物料编号")
+ private String goodsId;
+ @ApiModelProperty(value = "物料名称/描述")
+ private String goodsName;
+
+ /**
+ * 根据客户端查询生成数据库查询条件
+ * @return 数据库PO
+ */
+ public Stock toStockPO() {
+ Stock stockPO = new Stock();
+ stockPO.setLocationId(locationId);// 库位号
+ stockPO.setStockStatus(stockStatus);// 库存状态
+ stockPO.setVehicleId(vehicleId);// 载具号
+ if (StringUtils.isNotEmpty(goodsId) || StringUtils.isNotEmpty(goodsName) || goodsStatus != null) {// 包含物料详细信息
+ StockDetailInfo goodsRelatedPO = new StockDetailInfo();
+ goodsRelatedPO.setGoodsId(goodsId);
+ goodsRelatedPO.setGoodsName(goodsName);
+ goodsRelatedPO.setGoodsStatus(goodsStatus);
+ stockPO.setGoodsRelated(goodsRelatedPO);
+ }
+
+ return stockPO;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/query/TaskRecordQuery.java b/src/main/java/com/wms/entity/app/query/TaskRecordQuery.java
new file mode 100644
index 0000000..8e7d536
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/query/TaskRecordQuery.java
@@ -0,0 +1,41 @@
+package com.wms.entity.app.query;
+
+import com.wms.entity.app.dto.extend.TaskDetailInfo;
+import com.wms.entity.table.TaskRecord;
+import com.wms.utils.StringUtils;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "任务记录查询---客户端")
+public class TaskRecordQuery extends PageQuery {
+ @ApiModelProperty(value = "任务类型")
+ private Integer taskType;
+ @ApiModelProperty(value = "载具号/料箱号")
+ private String vehicleId;
+ @ApiModelProperty(value = "物料编号")
+ private String goodsId;
+ @ApiModelProperty(value = "物料名称/描述")
+ private String goodsName;
+
+ /**
+ * 根据客户端查询生成数据库查询条件
+ * @return 数据库PO
+ */
+ public TaskRecord toTaskRecordPO() {
+ TaskRecord recordPO = new TaskRecord();
+ recordPO.setTaskType(taskType);// 任务类型
+ recordPO.setVehicleId(vehicleId);// 载具号
+ if (StringUtils.isNotEmpty(goodsId) || StringUtils.isNotEmpty(goodsName)) {// 包含物料详细信息
+ TaskDetailInfo goodsRelatedPO = new TaskDetailInfo();
+ goodsRelatedPO.setGoodsId(goodsId);
+ goodsRelatedPO.setGoodsName(goodsName);
+ recordPO.setGoodsRelated(goodsRelatedPO);
+ }
+
+ return recordPO;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/vo/LayerLocation.java b/src/main/java/com/wms/entity/app/vo/LayerLocation.java
new file mode 100644
index 0000000..e37a602
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/vo/LayerLocation.java
@@ -0,0 +1,36 @@
+package com.wms.entity.app.vo;
+
+import com.wms.entity.table.LocationDto;
+
+import java.util.List;
+
+/**
+ * 按层划分的库位实体类
+ */
+public class LayerLocation {
+ /**
+ * 当前层
+ */
+ private Integer layer;
+
+ /**
+ * 当前层的所有库位
+ */
+ private List currentColLocations;
+
+ public Integer getLayer() {
+ return layer;
+ }
+
+ public void setLayer(Integer layer) {
+ this.layer = layer;
+ }
+
+ public List getCurrentColLocations() {
+ return currentColLocations;
+ }
+
+ public void setCurrentColLocations(List currentColLocations) {
+ this.currentColLocations = currentColLocations;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/vo/MenuEntity.java b/src/main/java/com/wms/entity/app/vo/MenuEntity.java
new file mode 100644
index 0000000..c79ceb6
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/vo/MenuEntity.java
@@ -0,0 +1,70 @@
+package com.wms.entity.app.vo;
+
+import java.util.List;
+
+public class MenuEntity {
+ /**
+ * 菜单Id
+ */
+ private String id;
+
+ /**
+ * 菜单名称
+ */
+ private String labelName;
+
+ /**
+ * 图标值
+ */
+ private String iconValue;
+
+ /**
+ * 地址
+ */
+ private String path;
+
+ /**
+ * 子菜单
+ */
+ private List children;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getLabelName() {
+ return labelName;
+ }
+
+ public void setLabelName(String labelName) {
+ this.labelName = labelName;
+ }
+
+ public String getIconValue() {
+ return iconValue;
+ }
+
+ public void setIconValue(String iconValue) {
+ this.iconValue = iconValue;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public List getChildren() {
+ return children;
+ }
+
+ public void setChildren(List children) {
+ this.children = children;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/vo/RowLocation.java b/src/main/java/com/wms/entity/app/vo/RowLocation.java
new file mode 100644
index 0000000..96af6b3
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/vo/RowLocation.java
@@ -0,0 +1,34 @@
+package com.wms.entity.app.vo;
+
+import java.util.List;
+
+/**
+ * 排
+ */
+public class RowLocation {
+ /**
+ * 当前排
+ */
+ private Integer row;
+
+ /**
+ * 当前排的所有库位
+ */
+ private List currentLayerLocations;
+
+ public Integer getRow() {
+ return row;
+ }
+
+ public void setRow(Integer row) {
+ this.row = row;
+ }
+
+ public List getCurrentLayerLocations() {
+ return currentLayerLocations;
+ }
+
+ public void setCurrentLayerLocations(List currentLayerLocations) {
+ this.currentLayerLocations = currentLayerLocations;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/vo/StockVo.java b/src/main/java/com/wms/entity/app/vo/StockVo.java
new file mode 100644
index 0000000..3789d88
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/vo/StockVo.java
@@ -0,0 +1,14 @@
+package com.wms.entity.app.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+@Data
+public class StockVo {
+ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ private LocalDateTime createTime;
+}
diff --git a/src/main/java/com/wms/entity/app/vo/UserConfigEntity.java b/src/main/java/com/wms/entity/app/vo/UserConfigEntity.java
new file mode 100644
index 0000000..9650bef
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/vo/UserConfigEntity.java
@@ -0,0 +1,35 @@
+package com.wms.entity.app.vo;
+
+import com.wms.entity.table.UserDto;
+import io.swagger.annotations.ApiModel;
+
+import java.util.List;
+
+@ApiModel(value = "用户信息")
+public class UserConfigEntity {
+ /**
+ * 用户认证信息
+ */
+ private UserDto user;
+
+ /**
+ * 菜单及各种按钮信息
+ */
+ private List menuList;
+
+ public UserDto getUser() {
+ return user;
+ }
+
+ public void setUser(UserDto user) {
+ this.user = user;
+ }
+
+ public List getMenuList() {
+ return menuList;
+ }
+
+ public void setMenuList(List menuList) {
+ this.menuList = menuList;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/wcs/ETaskData.java b/src/main/java/com/wms/entity/app/wcs/ETaskData.java
new file mode 100644
index 0000000..aeb4f56
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/wcs/ETaskData.java
@@ -0,0 +1,58 @@
+package com.wms.entity.app.wcs;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "电子标签详细任务数据")
+public class ETaskData {
+ @ApiModelProperty(value = "任务号")
+ private String taskId;
+ @ApiModelProperty(value = "点位")
+ private String location;
+ @ApiModelProperty(value = "物料编号")
+ private String goodsId;
+ @ApiModelProperty(value = "物料名称")
+ private String goodsName;
+ @ApiModelProperty(value = "需求数量")
+ private Integer needNum;
+
+ public String getTaskId() {
+ return taskId;
+ }
+
+ public void setTaskId(String taskId) {
+ this.taskId = taskId;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ public String getGoodsId() {
+ return goodsId;
+ }
+
+ public void setGoodsId(String goodsId) {
+ this.goodsId = goodsId;
+ }
+
+ public String getGoodsName() {
+ return goodsName;
+ }
+
+ public void setGoodsName(String goodsName) {
+ this.goodsName = goodsName;
+ }
+
+ public Integer getNeedNum() {
+ return needNum;
+ }
+
+ public void setNeedNum(Integer needNum) {
+ this.needNum = needNum;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/wcs/WcsBoxArriveRequest.java b/src/main/java/com/wms/entity/app/wcs/WcsBoxArriveRequest.java
new file mode 100644
index 0000000..d271c19
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/wcs/WcsBoxArriveRequest.java
@@ -0,0 +1,48 @@
+package com.wms.entity.app.wcs;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "WCS料箱到达请求")
+public class WcsBoxArriveRequest {
+ @ApiModelProperty(value = "任务组编号")
+ private String taskGroup;
+ @ApiModelProperty(value = "料箱号")
+ private String vehicleNo;
+ @ApiModelProperty(value = "点位---站台")
+ private String location;
+ @ApiModelProperty(value = "备注")
+ private String remark;
+
+ public String getTaskGroup() {
+ return taskGroup;
+ }
+
+ public void setTaskGroup(String taskGroup) {
+ this.taskGroup = taskGroup;
+ }
+
+ public String getVehicleNo() {
+ return vehicleNo;
+ }
+
+ public void setVehicleNo(String vehicleNo) {
+ this.vehicleNo = vehicleNo;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ public String getRemark() {
+ return remark;
+ }
+
+ public void setRemark(String remark) {
+ this.remark = remark;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/wcs/WcsChangeTaskRequest.java b/src/main/java/com/wms/entity/app/wcs/WcsChangeTaskRequest.java
new file mode 100644
index 0000000..f813ac4
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/wcs/WcsChangeTaskRequest.java
@@ -0,0 +1,28 @@
+package com.wms.entity.app.wcs;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(description = "向WCS发送任务请求")
+public class WcsChangeTaskRequest {
+ @ApiModelProperty(value = "任务ID", required = true)
+ private String taskId;
+ @ApiModelProperty(value = "任务状态---修改后", required = true)
+ private Integer taskStatus;
+
+ public String getTaskId() {
+ return taskId;
+ }
+
+ public void setTaskId(String taskId) {
+ this.taskId = taskId;
+ }
+
+ public Integer getTaskStatus() {
+ return taskStatus;
+ }
+
+ public void setTaskStatus(Integer taskStatus) {
+ this.taskStatus = taskStatus;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/wcs/WcsCommonResponse.java b/src/main/java/com/wms/entity/app/wcs/WcsCommonResponse.java
new file mode 100644
index 0000000..c4ce534
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/wcs/WcsCommonResponse.java
@@ -0,0 +1,38 @@
+package com.wms.entity.app.wcs;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(description = "WCS通用返回信息")
+public class WcsCommonResponse {
+ @ApiModelProperty(value = "返回码", required = true)
+ private Integer code;
+ @ApiModelProperty(value = "返回信息", required = true)
+ private String message;
+ @ApiModelProperty(value = "返回数据")
+ private T returnData;
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public T getReturnData() {
+ return returnData;
+ }
+
+ public void setReturnData(T returnData) {
+ this.returnData = returnData;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/wcs/WcsETaskFeedbackRequest.java b/src/main/java/com/wms/entity/app/wcs/WcsETaskFeedbackRequest.java
new file mode 100644
index 0000000..b08bd33
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/wcs/WcsETaskFeedbackRequest.java
@@ -0,0 +1,108 @@
+package com.wms.entity.app.wcs;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "WCS电子标签任务反馈请求")
+public class WcsETaskFeedbackRequest {
+ @ApiModelProperty(value = "任务组")
+ private String taskGroup;
+ @ApiModelProperty(value = "任务类型")
+ private Integer taskType;
+ @ApiModelProperty(value = "料箱号")
+ private String vehicleNo;
+ @ApiModelProperty(value = "订单号")
+ private String orderId;
+ @ApiModelProperty(value = "任务号")
+ private String taskId;
+ @ApiModelProperty(value = "点位")
+ private String location;
+ @ApiModelProperty(value = "物料编号")
+ private String goodsId;
+ @ApiModelProperty(value = "物料名称")
+ private String goodsName;
+ @ApiModelProperty(value = "需求数量")
+ private Integer needNum;
+ @ApiModelProperty(value = "确认数量")
+ private Integer confirmNum;
+
+ public String getTaskGroup() {
+ return taskGroup;
+ }
+
+ public void setTaskGroup(String taskGroup) {
+ this.taskGroup = taskGroup;
+ }
+
+ public Integer getTaskType() {
+ return taskType;
+ }
+
+ public void setTaskType(Integer taskType) {
+ this.taskType = taskType;
+ }
+
+ public String getVehicleNo() {
+ return vehicleNo;
+ }
+
+ public void setVehicleNo(String vehicleNo) {
+ this.vehicleNo = vehicleNo;
+ }
+
+ public String getOrderId() {
+ return orderId;
+ }
+
+ public void setOrderId(String orderId) {
+ this.orderId = orderId;
+ }
+
+ public String getTaskId() {
+ return taskId;
+ }
+
+ public void setTaskId(String taskId) {
+ this.taskId = taskId;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ public String getGoodsId() {
+ return goodsId;
+ }
+
+ public void setGoodsId(String goodsId) {
+ this.goodsId = goodsId;
+ }
+
+ public String getGoodsName() {
+ return goodsName;
+ }
+
+ public void setGoodsName(String goodsName) {
+ this.goodsName = goodsName;
+ }
+
+ public Integer getNeedNum() {
+ return needNum;
+ }
+
+ public void setNeedNum(Integer needNum) {
+ this.needNum = needNum;
+ }
+
+ public Integer getConfirmNum() {
+ return confirmNum;
+ }
+
+ public void setConfirmNum(Integer confirmNum) {
+ this.confirmNum = confirmNum;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/wcs/WcsETaskRequest.java b/src/main/java/com/wms/entity/app/wcs/WcsETaskRequest.java
new file mode 100644
index 0000000..58ba1a9
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/wcs/WcsETaskRequest.java
@@ -0,0 +1,60 @@
+package com.wms.entity.app.wcs;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.List;
+
+@ApiModel(value = "WCS电子标签任务发送请求")
+public class WcsETaskRequest {
+ @ApiModelProperty(value = "任务组")
+ private String taskGroup;
+ @ApiModelProperty(value = "任务类型")
+ private Integer taskType;
+ @ApiModelProperty(value = "料箱号")
+ private String vehicleNo;
+ @ApiModelProperty(value = "订单号")
+ private String orderId;
+ @ApiModelProperty(value = "任务数据")
+ private List taskData;
+
+ public String getTaskGroup() {
+ return taskGroup;
+ }
+
+ public void setTaskGroup(String taskGroup) {
+ this.taskGroup = taskGroup;
+ }
+
+ public Integer getTaskType() {
+ return taskType;
+ }
+
+ public void setTaskType(Integer taskType) {
+ this.taskType = taskType;
+ }
+
+ public String getVehicleNo() {
+ return vehicleNo;
+ }
+
+ public void setVehicleNo(String vehicleNo) {
+ this.vehicleNo = vehicleNo;
+ }
+
+ public String getOrderId() {
+ return orderId;
+ }
+
+ public void setOrderId(String orderId) {
+ this.orderId = orderId;
+ }
+
+ public List getTaskData() {
+ return taskData;
+ }
+
+ public void setTaskData(List taskData) {
+ this.taskData = taskData;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/wcs/WcsFeedbackTaskRequest.java b/src/main/java/com/wms/entity/app/wcs/WcsFeedbackTaskRequest.java
new file mode 100644
index 0000000..950d53c
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/wcs/WcsFeedbackTaskRequest.java
@@ -0,0 +1,48 @@
+package com.wms.entity.app.wcs;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(description = "WCS发送任务反馈")
+public class WcsFeedbackTaskRequest {
+ @ApiModelProperty(value = "任务Id")
+ private String taskId;
+ @ApiModelProperty(value = "任务状态")
+ private Integer taskStatus;
+ @ApiModelProperty(value = "任务终点")
+ private String destination;
+ @ApiModelProperty(value = "异常信息")
+ private String message;
+
+ public String getTaskId() {
+ return taskId;
+ }
+
+ public void setTaskId(String taskId) {
+ this.taskId = taskId;
+ }
+
+ public Integer getTaskStatus() {
+ return taskStatus;
+ }
+
+ public void setTaskStatus(Integer taskStatus) {
+ this.taskStatus = taskStatus;
+ }
+
+ public String getDestination() {
+ return destination;
+ }
+
+ public void setDestination(String destination) {
+ this.destination = destination;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/wcs/WcsStandTaskRequest.java b/src/main/java/com/wms/entity/app/wcs/WcsStandTaskRequest.java
new file mode 100644
index 0000000..0376114
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/wcs/WcsStandTaskRequest.java
@@ -0,0 +1,60 @@
+package com.wms.entity.app.wcs;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.List;
+
+@ApiModel(value = "WCS站台拣选任务请求")
+public class WcsStandTaskRequest {
+ @ApiModelProperty("任务组编号")
+ private String taskGroup;
+ @ApiModelProperty("料箱号")
+ private String vehicleNo;
+ @ApiModelProperty("任务类型---1:拣选任务")
+ private Integer taskType;
+ @ApiModelProperty("点位---站台号")
+ private List location;
+ @ApiModelProperty("备注")
+ private String remark;
+
+ public String getTaskGroup() {
+ return taskGroup;
+ }
+
+ public void setTaskGroup(String taskGroup) {
+ this.taskGroup = taskGroup;
+ }
+
+ public String getVehicleNo() {
+ return vehicleNo;
+ }
+
+ public void setVehicleNo(String vehicleNo) {
+ this.vehicleNo = vehicleNo;
+ }
+
+ public Integer getTaskType() {
+ return taskType;
+ }
+
+ public void setTaskType(Integer taskType) {
+ this.taskType = taskType;
+ }
+
+ public List getLocation() {
+ return location;
+ }
+
+ public void setLocation(List location) {
+ this.location = location;
+ }
+
+ public String getRemark() {
+ return remark;
+ }
+
+ public void setRemark(String remark) {
+ this.remark = remark;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/wcs/WcsTaskRequest.java b/src/main/java/com/wms/entity/app/wcs/WcsTaskRequest.java
new file mode 100644
index 0000000..bf82f3e
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/wcs/WcsTaskRequest.java
@@ -0,0 +1,93 @@
+package com.wms.entity.app.wcs;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.math.BigDecimal;
+
+/**
+ * 向Wcs发送任务的请求
+ */
+@ApiModel(description = "向WCS发送任务请求")
+public class WcsTaskRequest {
+ @ApiModelProperty(value = "任务ID", required = true)
+ private String taskId;
+ @ApiModelProperty(value = "任务类型", required = true)
+ private Integer taskType;
+ @ApiModelProperty(value = "任务优先级---同一任务类型中优先级")
+ private Integer priority;
+ @ApiModelProperty(value = "任务起点")
+ private String origin;
+ @ApiModelProperty(value = "任务终点")
+ private String destination;
+ @ApiModelProperty(value = "料箱号", required = true)
+ private String vehicleNo;
+ @ApiModelProperty(value = "料箱尺寸")
+ private Integer vehicleSize = 0;
+ @ApiModelProperty(value = "重量")
+ private BigDecimal weight = BigDecimal.ZERO;
+
+ public String getTaskId() {
+ return taskId;
+ }
+
+ public void setTaskId(String taskId) {
+ this.taskId = taskId;
+ }
+
+ public Integer getTaskType() {
+ return taskType;
+ }
+
+ public void setTaskType(Integer taskType) {
+ this.taskType = taskType;
+ }
+
+ public Integer getPriority() {
+ return priority;
+ }
+
+ public void setPriority(Integer priority) {
+ this.priority = priority;
+ }
+
+ public String getOrigin() {
+ return origin;
+ }
+
+ public void setOrigin(String origin) {
+ this.origin = origin;
+ }
+
+ public String getDestination() {
+ return destination;
+ }
+
+ public void setDestination(String destination) {
+ this.destination = destination;
+ }
+
+ public String getVehicleNo() {
+ return vehicleNo;
+ }
+
+ public void setVehicleNo(String vehicleNo) {
+ this.vehicleNo = vehicleNo;
+ }
+
+ public Integer getVehicleSize() {
+ return vehicleSize;
+ }
+
+ public void setVehicleSize(Integer vehicleSize) {
+ this.vehicleSize = vehicleSize;
+ }
+
+ public BigDecimal getWeight() {
+ return weight;
+ }
+
+ public void setWeight(BigDecimal weight) {
+ this.weight = weight;
+ }
+}
diff --git a/src/main/java/com/wms/entity/app/wcs/WcsVehicleInRequest.java b/src/main/java/com/wms/entity/app/wcs/WcsVehicleInRequest.java
new file mode 100644
index 0000000..7c8b909
--- /dev/null
+++ b/src/main/java/com/wms/entity/app/wcs/WcsVehicleInRequest.java
@@ -0,0 +1,48 @@
+package com.wms.entity.app.wcs;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel(value = "WCS请求料箱入库")
+public class WcsVehicleInRequest {
+ @ApiModelProperty(value = "点位")
+ private String point;
+ @ApiModelProperty(value = "料箱号")
+ private String vehicleNo;
+ @ApiModelProperty(value = "条码信息")
+ private String codeMessage;
+ @ApiModelProperty(value = "备注")
+ private String remark;
+
+ public String getPoint() {
+ return point;
+ }
+
+ public void setPoint(String point) {
+ this.point = point;
+ }
+
+ public String getVehicleNo() {
+ return vehicleNo;
+ }
+
+ public void setVehicleNo(String vehicleNo) {
+ this.vehicleNo = vehicleNo;
+ }
+
+ public String getCodeMessage() {
+ return codeMessage;
+ }
+
+ public void setCodeMessage(String codeMessage) {
+ this.codeMessage = codeMessage;
+ }
+
+ public String getRemark() {
+ return remark;
+ }
+
+ public void setRemark(String remark) {
+ this.remark = remark;
+ }
+}
diff --git a/src/main/java/com/wms/entity/page/PageDomain.java b/src/main/java/com/wms/entity/page/PageDomain.java
new file mode 100644
index 0000000..dc6e300
--- /dev/null
+++ b/src/main/java/com/wms/entity/page/PageDomain.java
@@ -0,0 +1,67 @@
+package com.wms.entity.page;
+
+import com.wms.utils.StringUtils;
+
+/**
+ * 分页请求
+ * 前端表格用
+ */
+public class PageDomain {
+ /**
+ * 当前记录起始索引
+ */
+ private Integer pageNum;
+ /**
+ * 每页显示记录数
+ */
+ private Integer pageSize;
+ /**
+ *排序列
+ */
+ private String orderByColumn;
+ /**
+ * 排序方向
+ */
+ private String isAsc = "asc";
+
+ public String getOrderBy()
+ {
+ if (StringUtils.isEmpty(orderByColumn))
+ {
+ return "";
+ }
+ return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc;
+ }
+
+ public Integer getPageNum() {
+ return pageNum;
+ }
+
+ public void setPageNum(Integer pageNum) {
+ this.pageNum = pageNum;
+ }
+
+ public Integer getPageSize() {
+ return pageSize;
+ }
+
+ public void setPageSize(Integer pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ public String getOrderByColumn() {
+ return orderByColumn;
+ }
+
+ public void setOrderByColumn(String orderByColumn) {
+ this.orderByColumn = orderByColumn;
+ }
+
+ public String getIsAsc() {
+ return isAsc;
+ }
+
+ public void setIsAsc(String isAsc) {
+ this.isAsc = isAsc;
+ }
+}
diff --git a/src/main/java/com/wms/entity/page/TableRequest.java b/src/main/java/com/wms/entity/page/TableRequest.java
new file mode 100644
index 0000000..a29b835
--- /dev/null
+++ b/src/main/java/com/wms/entity/page/TableRequest.java
@@ -0,0 +1,43 @@
+package com.wms.entity.page;
+
+/**
+ * 前端请求表格数据
+ */
+public class TableRequest {
+ /**
+ * 分页请求数据
+ */
+ private PageDomain page;
+ /**
+ * 参数
+ */
+ private T param;
+ /**
+ * 参数2
+ */
+ private T2 param2;
+
+ public PageDomain getPage() {
+ return page;
+ }
+
+ public void setPage(PageDomain page) {
+ this.page = page;
+ }
+
+ public T getParam() {
+ return param;
+ }
+
+ public void setParam(T param) {
+ this.param = param;
+ }
+
+ public T2 getParam2() {
+ return param2;
+ }
+
+ public void setParam2(T2 param2) {
+ this.param2 = param2;
+ }
+}
diff --git a/src/main/java/com/wms/entity/page/TableResponse.java b/src/main/java/com/wms/entity/page/TableResponse.java
new file mode 100644
index 0000000..4ea4218
--- /dev/null
+++ b/src/main/java/com/wms/entity/page/TableResponse.java
@@ -0,0 +1,57 @@
+package com.wms.entity.page;
+
+import java.util.List;
+
+/**
+ * 前端表格请求的返回值
+ */
+public class TableResponse {
+ /**
+ * 总记录数
+ */
+ private long total;
+ /**
+ * 列表数据
+ */
+ private List> rows;
+ /**
+ * 状态码
+ */
+ private int code;
+ /**
+ * 消息
+ */
+ private String message;
+
+ public long getTotal() {
+ return total;
+ }
+
+ public void setTotal(long total) {
+ this.total = total;
+ }
+
+ public List> getRows() {
+ return rows;
+ }
+
+ public void setRows(List> rows) {
+ this.rows = rows;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/src/main/java/com/wms/entity/table/Config.java b/src/main/java/com/wms/entity/table/Config.java
new file mode 100644
index 0000000..d5643b5
--- /dev/null
+++ b/src/main/java/com/wms/entity/table/Config.java
@@ -0,0 +1,44 @@
+package com.wms.entity.table;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 配置
+ */
+@Data
+@TableName(value = "tbl_sys_config", autoResultMap = true)
+public class Config {
+ /**
+ * 配置ID
+ */
+ @TableId(value = "config_id", type = IdType.AUTO)
+ private Integer configId;
+
+ /**
+ * 配置键
+ */
+ @TableField(value = "config_key")
+ private String configKey;
+
+ /**
+ * 配置值
+ */
+ @TableField(value = "config_value")
+ private String configValue;
+
+ /**
+ * 配置展示类型
+ */
+ @TableField(value = "config_type")
+ private String configType;
+
+ /**
+ * 配置名称
+ */
+ @TableField(value = "config_name")
+ private String configName;
+}
diff --git a/src/main/java/com/wms/entity/table/Goods.java b/src/main/java/com/wms/entity/table/Goods.java
new file mode 100644
index 0000000..28c80af
--- /dev/null
+++ b/src/main/java/com/wms/entity/table/Goods.java
@@ -0,0 +1,68 @@
+package com.wms.entity.table;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 物料
+ */
+@Data
+@TableName("tbl_app_goods")
+public class Goods {
+
+ /**
+ * 物料编号
+ */
+ @TableId(value = "goods_id")
+ private String goodsId;
+
+ /**
+ * 物料名称
+ */
+ @TableField(value = "goods_name")
+ private String goodsName;
+
+ /**
+ * 单位
+ */
+ private String goodsUnit;
+
+ /**
+ * 物料ID
+ */
+ private String itemId;
+ /**
+ * 用户物料类型
+ */
+ private String itemType;
+ /**
+ * 库存类别
+ */
+ private String invCategory;
+ /**
+ * 存储天数
+ */
+ private Integer lifeDays;
+ /**
+ * 库存组织Id
+ */
+ private String organizationId;
+ /**
+ * 库存组织代码
+ */
+ private String organizationCode;
+
+ /**
+ * 最后更新日期
+ */
+ private Date lastUpdateTime;
+
+ /**
+ * 最后更新用户
+ */
+ private String lastUpdateUser;
+}
diff --git a/src/main/java/com/wms/entity/table/Location.java b/src/main/java/com/wms/entity/table/Location.java
new file mode 100644
index 0000000..b15c1a5
--- /dev/null
+++ b/src/main/java/com/wms/entity/table/Location.java
@@ -0,0 +1,64 @@
+package com.wms.entity.table;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 库位
+ */
+@Data
+@TableName(value = "tbl_app_location", autoResultMap = true)
+public class Location {
+ /**
+ * 库位编号
+ */
+ @TableId(value = "location_id")
+ private String locationId;
+ /**
+ * 库区编号
+ */
+ @TableField(value = "area_id")
+ private Integer areaId;
+ /**
+ * 设备编号
+ */
+ @TableField(value = "equipment_id")
+ private Integer equipmentId;
+ /**
+ * 库位类型
+ */
+ @TableField(value = "location_type")
+ private Integer locationType;
+ /**
+ * 排
+ */
+ @TableField(value = "w_row")
+ private Integer wRow;
+ /**
+ * 列
+ */
+ @TableField(value = "w_col")
+ private Integer wCol;
+ /**
+ * 层
+ */
+ @TableField(value = "w_layer")
+ private Integer wLayer;
+ /**
+ * 深度
+ */
+ @TableField(value = "w_depth")
+ private Integer wDepth;
+ /**
+ * 是否锁定
+ */
+ @TableField(value = "is_lock")
+ private Integer isLock;
+ /**
+ * 库位状态
+ */
+ @TableField(value = "location_status")
+ private Integer locationStatus;
+}
diff --git a/src/main/java/com/wms/entity/table/Menu.java b/src/main/java/com/wms/entity/table/Menu.java
new file mode 100644
index 0000000..d13eed3
--- /dev/null
+++ b/src/main/java/com/wms/entity/table/Menu.java
@@ -0,0 +1,39 @@
+package com.wms.entity.table;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 菜单
+ */
+@Data
+@TableName(value = "tbl_app_menu", autoResultMap = true)
+public class Menu {
+ /**
+ * 菜单Id
+ */
+ @TableId(value = "menu_id")
+ private String menuId;
+ /**
+ * 菜单名称
+ */
+ @TableField(value = "label_name")
+ private String labelName;
+ /**
+ * 图标值
+ */
+ @TableField(value = "icon_value")
+ private String iconValue;
+ /**
+ * 地址
+ */
+ @TableField(value = "path")
+ private String path;
+ /**
+ * 父菜单Id
+ */
+ @TableField(value = "parent_id")
+ private String parentId;
+}
diff --git a/src/main/java/com/wms/entity/table/Stand.java b/src/main/java/com/wms/entity/table/Stand.java
new file mode 100644
index 0000000..d7ea532
--- /dev/null
+++ b/src/main/java/com/wms/entity/table/Stand.java
@@ -0,0 +1,74 @@
+package com.wms.entity.table;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 站台表
+ */
+@Data
+@TableName(value = "tbl_app_stand", autoResultMap = true)
+public class Stand {
+ /**
+ * 站台id
+ */
+ @TableId(value = "stand_id")
+ private String standId;
+ /**
+ * 是否允许入库
+ */
+ @TableField(value = "allow_in")
+ private Integer allowIn;
+ /**
+ * 是否允许出库
+ */
+ @TableField(value = "allow_out")
+ private Integer allowOut;
+ /**
+ * 站台是否锁定
+ */
+ @TableField(value = "is_lock")
+ private Integer isLock;
+ /**
+ * 站台状态
+ */
+ @TableField(value = "stand_status")
+ private Integer standStatus;
+
+ /**
+ * 设备编号
+ */
+ @TableField(value = "equipment_id")
+ private Integer equipmentId;
+
+ /**
+ * 库区编号
+ */
+ @TableField(value = "area_id")
+ private Integer areaId;
+ /**
+ * 站台类型
+ */
+ @TableField(value = "stand_type")
+ private Integer standType;
+ /**
+ * 站台ip
+ */
+ @TableField(value = "stand_ip")
+ private String standIp;
+ /**
+ * 外部id
+ * 如mes上的站台编号
+ */
+ @TableField(value = "outer_id")
+ private String outerId;
+ /**
+ * 最近一次的使用时间
+ */
+ @TableField(value = "last_use_time")
+ private LocalDateTime lastUseTime;
+}
diff --git a/src/main/java/com/wms/entity/table/Stock.java b/src/main/java/com/wms/entity/table/Stock.java
new file mode 100644
index 0000000..a9c39e5
--- /dev/null
+++ b/src/main/java/com/wms/entity/table/Stock.java
@@ -0,0 +1,80 @@
+package com.wms.entity.table;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.Fastjson2TypeHandler;
+import com.wms.entity.app.dto.extend.StockDetailInfo;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 库存
+ */
+@Data
+@TableName(value = "tbl_app_stock", autoResultMap = true)
+public class Stock {
+ /**
+ * 库存编号
+ */
+ @TableId(value = "stock_id")
+ private String stockId;
+ /**
+ * 库位ID
+ */
+ @TableField(value = "location_id")
+ private String locationId;
+ /**
+ * 托盘号
+ */
+ @TableField(value = "vehicle_id")
+ private String vehicleId;
+ /**
+ * 重量
+ */
+ @TableField(value = "weight")
+ private BigDecimal weight;
+ /**
+ * 库存状态
+ * 正常、出库中、锁定 等
+ */
+ @TableField(value = "stock_status")
+ private Integer stockStatus;
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time")
+ private LocalDateTime createTime;
+ /**
+ * 最后更新时间
+ */
+ @TableField(value = "last_update_time")
+ private LocalDateTime lastUpdateTime;
+ /**
+ * 最后更新用户
+ */
+ @TableField(value = "last_update_user")
+ private String lastUpdateUser;
+ /**
+ * 是否盘点
+ */
+ @TableField(value = "is_inventory")
+ private Integer isInventory;
+ /**
+ * 盘点任务号 盘点出库和盘点入库同样
+ */
+ @TableField(value = "inventory_task_id")
+ private String inventoryTaskId;
+ /**
+ * 呆滞天数
+ */
+ @TableField(value = "no_use_days")
+ private Integer noUseDays;
+ /**
+ * 物料相关信息
+ */
+ @TableField(value = "goods_related", typeHandler = Fastjson2TypeHandler.class)
+ private StockDetailInfo goodsRelated;
+}
diff --git a/src/main/java/com/wms/entity/table/Task.java b/src/main/java/com/wms/entity/table/Task.java
new file mode 100644
index 0000000..82e659a
--- /dev/null
+++ b/src/main/java/com/wms/entity/table/Task.java
@@ -0,0 +1,89 @@
+package com.wms.entity.table;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.Fastjson2TypeHandler;
+import com.wms.entity.app.dto.extend.TaskDetailInfo;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 任务
+ */
+@Data
+@TableName(value = "tbl_app_task", autoResultMap = true)
+public class Task {
+ /**
+ * 任务号
+ */
+ @TableId(value = "task_id")
+ private String taskId;
+ /**
+ * 任务类型
+ */
+ @TableField(value = "task_type")
+ private Integer taskType;
+ /**
+ * 任务状态
+ */
+ @TableField(value = "task_status")
+ private Integer taskStatus;
+ /**
+ * 起点
+ */
+ @TableField(value = "origin")
+ private String origin;
+ /**
+ * 终点
+ */
+ @TableField(value = "destination")
+ private String destination;
+ /**
+ * 任务优先级
+ */
+ @TableField(value = "task_priority")
+ private Integer taskPriority;
+ /**
+ * 任务组---多与载具绑定
+ */
+ @TableField(value = "task_group")
+ private String taskGroup;
+ /**
+ * 载具号/料箱号
+ */
+ @TableField(value = "vehicle_id")
+ private String vehicleId;
+ /**
+ * 重量
+ */
+ @TableField(value = "weight")
+ private BigDecimal weight;
+ /**
+ * 载具尺寸
+ */
+ @TableField(value = "vehicle_size")
+ private Integer vehicleSize;
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time")
+ private LocalDateTime createTime;
+ /**
+ * 完成时间
+ */
+ @TableField(value = "finish_time")
+ private LocalDateTime finishTime;
+ /**
+ * 用户名
+ */
+ @TableField(value = "user_name")
+ private String userName;
+ /**
+ * 物料相关的详细信息
+ */
+ @TableField(value = "goods_related", typeHandler = Fastjson2TypeHandler.class)
+ private TaskDetailInfo goodsRelated;
+}
diff --git a/src/main/java/com/wms/entity/table/TaskRecord.java b/src/main/java/com/wms/entity/table/TaskRecord.java
new file mode 100644
index 0000000..4163ac7
--- /dev/null
+++ b/src/main/java/com/wms/entity/table/TaskRecord.java
@@ -0,0 +1,86 @@
+package com.wms.entity.table;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.Fastjson2TypeHandler;
+import com.wms.entity.app.dto.extend.TaskDetailInfo;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Data
+@TableName(value = "tbl_app_task_bak", autoResultMap = true)
+public class TaskRecord {
+ /**
+ * 任务号
+ */
+ @TableId(value = "task_id")
+ private String taskId;
+ /**
+ * 任务类型
+ */
+ @TableField(value = "task_type")
+ private Integer taskType;
+ /**
+ * 任务状态
+ */
+ @TableField(value = "task_status")
+ private Integer taskStatus;
+ /**
+ * 起点
+ */
+ @TableField(value = "origin")
+ private String origin;
+ /**
+ * 终点
+ */
+ @TableField(value = "destination")
+ private String destination;
+ /**
+ * 任务优先级
+ */
+ @TableField(value = "task_priority")
+ private Integer taskPriority;
+ /**
+ * 任务组
+ */
+ @TableField(value = "task_group")
+ private String taskGroup;
+ /**
+ * 载具号
+ */
+ @TableField(value = "vehicle_id")
+ private String vehicleId;
+ /**
+ * 重量
+ */
+ @TableField(value = "weight")
+ private BigDecimal weight;
+ /**
+ * 载具尺寸
+ */
+ @TableField(value = "vehicle_size")
+ private Integer vehicleSize;
+ /**
+ * 创建时间
+ */
+ @TableField(value = "create_time")
+ private LocalDateTime createTime;
+ /**
+ * 完成时间
+ */
+ @TableField(value = "finish_time")
+ private LocalDateTime finishTime;
+ /**
+ * 用户名
+ */
+ @TableField(value = "user_name")
+ private String userName;
+ /**
+ * 物料相关的详细信息
+ */
+ @TableField(value = "goods_related", typeHandler = Fastjson2TypeHandler.class)
+ private TaskDetailInfo goodsRelated;
+}
diff --git a/src/main/java/com/wms/entity/table/User.java b/src/main/java/com/wms/entity/table/User.java
new file mode 100644
index 0000000..6e11732
--- /dev/null
+++ b/src/main/java/com/wms/entity/table/User.java
@@ -0,0 +1,49 @@
+package com.wms.entity.table;
+
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 用户
+ */
+@Data
+@TableName(value = "tbl_sys_user", autoResultMap = true)
+public class User {
+ /** 用户ID */
+ @TableId(value = "user_id", type = IdType.AUTO)
+ private Integer userId;
+
+ /** 用户名 */
+ @TableField(value = "user_name")
+ private String userName;
+
+ /** 角色Id */
+ @TableField(value = "role_id")
+ private Integer roleId = null;
+
+ /** 登录账户 */
+ @TableField(value = "login_account")
+ private String loginAccount;
+
+ /** 登录密码 */
+ @TableField(value = "login_password")
+ private String loginPassword;
+
+ /** 添加时间 */
+ @TableField(value = "add_time")
+ private LocalDateTime addTime;
+
+ /** 更新时间 */
+ @TableField(value = "update_time")
+ private LocalDateTime updateTime;
+
+ /** 添加用户名 */
+ @TableField(value = "add_user")
+ private String addUser;
+}
diff --git a/src/main/java/com/wms/entity/table/Vehicle.java b/src/main/java/com/wms/entity/table/Vehicle.java
new file mode 100644
index 0000000..345d8a2
--- /dev/null
+++ b/src/main/java/com/wms/entity/table/Vehicle.java
@@ -0,0 +1,46 @@
+package com.wms.entity.table;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.Fastjson2TypeHandler;
+import com.wms.entity.app.dto.extend.VehicleDetailInfo;
+import lombok.Data;
+
+/**
+ * 载具
+ */
+@Data
+@TableName(value = "tbl_app_vehicle", autoResultMap = true)
+public class Vehicle {
+ /**
+ * 载具编号
+ */
+ @TableId(value = "vehicle_id")
+ private String vehicleId;
+ /**
+ * 当前所在位置
+ */
+ @TableField(value = "current_location")
+ private String currentLocation;
+ /**
+ * 载具状态
+ */
+ @TableField(value = "vehicle_status")
+ private Integer vehicleStatus;
+ /**
+ * 是否是空箱
+ */
+ @TableField(value = "is_empty")
+ private Integer isEmpty;
+ /**
+ * 载具类型
+ */
+ @TableField(value = "vehicle_type")
+ private Integer vehicleType;
+ /**
+ * 额外信息
+ */
+ @TableField(value = "details", typeHandler = Fastjson2TypeHandler.class)
+ private VehicleDetailInfo details;
+}
diff --git a/src/main/java/com/wms/entity/table/WmsLog.java b/src/main/java/com/wms/entity/table/WmsLog.java
new file mode 100644
index 0000000..4640649
--- /dev/null
+++ b/src/main/java/com/wms/entity/table/WmsLog.java
@@ -0,0 +1,57 @@
+package com.wms.entity.table;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.Fastjson2TypeHandler;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 操作日志类
+ */
+@Data
+@TableName(value = "tbl_sys_log", autoResultMap = true)
+public class WmsLog {
+ /**
+ * id
+ */
+ @TableId(value = "log_id")
+ private String logId;
+ /**
+ * 描述/标题
+ */
+ @TableField(value = "log_title")
+ private String logTitle;
+ /**
+ * 方法
+ */
+ @TableField(value = "log_method")
+ private String logMethod;
+ /**
+ * 请求参数
+ */
+ @TableField(value = "log_request", typeHandler = Fastjson2TypeHandler.class)
+ private Object logRequest;
+ /**
+ * 响应参数
+ */
+ @TableField(value = "log_response", typeHandler = Fastjson2TypeHandler.class)
+ private Object logResponse;
+ /**
+ * 请求的ip
+ */
+ @TableField(value = "log_ip")
+ private String logIp;
+ /**
+ * 请求时间
+ */
+ @TableField(value = "log_time")
+ private LocalDateTime logTime;
+ /**
+ * 请求用户
+ */
+ @TableField(value = "log_user")
+ private String logUser;
+}
diff --git a/src/main/java/com/wms/entity/test/ExcelTest.java b/src/main/java/com/wms/entity/test/ExcelTest.java
new file mode 100644
index 0000000..03bead4
--- /dev/null
+++ b/src/main/java/com/wms/entity/test/ExcelTest.java
@@ -0,0 +1,36 @@
+package com.wms.entity.test;
+
+import com.wms.utils.excel.ExcelExport;
+import com.wms.utils.excel.ExcelImport;
+
+public class ExcelTest {
+ @ExcelImport("库位")
+ @ExcelExport("库位")
+ private String locationId;
+ @ExcelImport("箱号")
+ @ExcelExport("箱号")
+ private String vehicleId;
+
+ public ExcelTest(){};
+
+ public ExcelTest(String locationId, String vehicleId) {
+ this.locationId = locationId;
+ this.vehicleId = vehicleId;
+ }
+
+ public String getLocationId() {
+ return locationId;
+ }
+
+ public void setLocationId(String locationId) {
+ this.locationId = locationId;
+ }
+
+ public String getVehicleId() {
+ return vehicleId;
+ }
+
+ public void setVehicleId(String vehicleId) {
+ this.vehicleId = vehicleId;
+ }
+}
diff --git a/src/main/java/com/wms/mapper/ConfigMapper.java b/src/main/java/com/wms/mapper/ConfigMapper.java
new file mode 100644
index 0000000..a4446ad
--- /dev/null
+++ b/src/main/java/com/wms/mapper/ConfigMapper.java
@@ -0,0 +1,15 @@
+package com.wms.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.wms.entity.table.Config;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * 配置
+ */
+@Mapper
+public interface ConfigMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/wms/mapper/GoodsMapper.java b/src/main/java/com/wms/mapper/GoodsMapper.java
new file mode 100644
index 0000000..cef13d9
--- /dev/null
+++ b/src/main/java/com/wms/mapper/GoodsMapper.java
@@ -0,0 +1,10 @@
+package com.wms.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.wms.entity.table.GoodsDto;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface GoodsMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/wms/mapper/LocationMapper.java b/src/main/java/com/wms/mapper/LocationMapper.java
new file mode 100644
index 0000000..c8326a0
--- /dev/null
+++ b/src/main/java/com/wms/mapper/LocationMapper.java
@@ -0,0 +1,10 @@
+package com.wms.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.wms.entity.table.LocationDto;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface LocationMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/wms/mapper/LogMapper.java b/src/main/java/com/wms/mapper/LogMapper.java
new file mode 100644
index 0000000..7e0c5f1
--- /dev/null
+++ b/src/main/java/com/wms/mapper/LogMapper.java
@@ -0,0 +1,10 @@
+package com.wms.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.wms.entity.table.WmsLog;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface LogMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/wms/mapper/MenuMapper.java b/src/main/java/com/wms/mapper/MenuMapper.java
new file mode 100644
index 0000000..feb69c6
--- /dev/null
+++ b/src/main/java/com/wms/mapper/MenuMapper.java
@@ -0,0 +1,13 @@
+package com.wms.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.wms.entity.table.MenuDto;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 菜单Mapper
+ */
+@Mapper
+public interface MenuMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/mapper/StandMapper.java b/src/main/java/com/wms/mapper/StandMapper.java
new file mode 100644
index 0000000..098880e
--- /dev/null
+++ b/src/main/java/com/wms/mapper/StandMapper.java
@@ -0,0 +1,10 @@
+package com.wms.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.wms.entity.table.StandDto;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface StandMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/wms/mapper/StockMapper.java b/src/main/java/com/wms/mapper/StockMapper.java
new file mode 100644
index 0000000..faba906
--- /dev/null
+++ b/src/main/java/com/wms/mapper/StockMapper.java
@@ -0,0 +1,10 @@
+package com.wms.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.wms.entity.table.Stock;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface StockMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/mapper/TaskMapper.java b/src/main/java/com/wms/mapper/TaskMapper.java
new file mode 100644
index 0000000..341d2b3
--- /dev/null
+++ b/src/main/java/com/wms/mapper/TaskMapper.java
@@ -0,0 +1,10 @@
+package com.wms.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.wms.entity.table.Task;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface TaskMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/mapper/TaskRecordMapper.java b/src/main/java/com/wms/mapper/TaskRecordMapper.java
new file mode 100644
index 0000000..f9b0ee2
--- /dev/null
+++ b/src/main/java/com/wms/mapper/TaskRecordMapper.java
@@ -0,0 +1,10 @@
+package com.wms.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.wms.entity.table.TaskRecord;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface TaskRecordMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/mapper/UserMapper.java b/src/main/java/com/wms/mapper/UserMapper.java
new file mode 100644
index 0000000..7dfb6ea
--- /dev/null
+++ b/src/main/java/com/wms/mapper/UserMapper.java
@@ -0,0 +1,10 @@
+package com.wms.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.wms.entity.table.UserDto;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface UserMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/mapper/VehicleMapper.java b/src/main/java/com/wms/mapper/VehicleMapper.java
new file mode 100644
index 0000000..45fd9b0
--- /dev/null
+++ b/src/main/java/com/wms/mapper/VehicleMapper.java
@@ -0,0 +1,10 @@
+package com.wms.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.wms.entity.table.Vehicle;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface VehicleMapper extends BaseMapper {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/service/ConfigService.java b/src/main/java/com/wms/service/ConfigService.java
new file mode 100644
index 0000000..b47f9e9
--- /dev/null
+++ b/src/main/java/com/wms/service/ConfigService.java
@@ -0,0 +1,11 @@
+package com.wms.service;
+
+import com.wms.entity.table.Config;
+
+import java.util.List;
+
+public interface ConfigService {
+ List selectConfigs(String configKey);
+
+ int updateConfig(Config config);
+}
diff --git a/src/main/java/com/wms/service/GoodsService.java b/src/main/java/com/wms/service/GoodsService.java
new file mode 100644
index 0000000..36a8c95
--- /dev/null
+++ b/src/main/java/com/wms/service/GoodsService.java
@@ -0,0 +1,4 @@
+package com.wms.service;
+
+public interface GoodsService {
+}
diff --git a/src/main/java/com/wms/service/LocationService.java b/src/main/java/com/wms/service/LocationService.java
new file mode 100644
index 0000000..3ac0255
--- /dev/null
+++ b/src/main/java/com/wms/service/LocationService.java
@@ -0,0 +1,5 @@
+package com.wms.service;
+
+public interface LocationService {
+
+}
diff --git a/src/main/java/com/wms/service/LogService.java b/src/main/java/com/wms/service/LogService.java
new file mode 100644
index 0000000..8bbf436
--- /dev/null
+++ b/src/main/java/com/wms/service/LogService.java
@@ -0,0 +1,13 @@
+package com.wms.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.wms.entity.table.WmsLog;
+
+public interface LogService extends IService {
+ /**
+ * 定期删除日志记录(30天清一次)
+ *
+ * @return 结果
+ */
+ boolean deleteWmsLogsRegularly(int interval);
+}
diff --git a/src/main/java/com/wms/service/MenuService.java b/src/main/java/com/wms/service/MenuService.java
new file mode 100644
index 0000000..8060aba
--- /dev/null
+++ b/src/main/java/com/wms/service/MenuService.java
@@ -0,0 +1,5 @@
+package com.wms.service;
+
+public interface MenuService {
+
+}
diff --git a/src/main/java/com/wms/service/StandService.java b/src/main/java/com/wms/service/StandService.java
new file mode 100644
index 0000000..10fe691
--- /dev/null
+++ b/src/main/java/com/wms/service/StandService.java
@@ -0,0 +1,8 @@
+package com.wms.service;
+
+/**
+ *
+ */
+public interface StandService {
+
+}
diff --git a/src/main/java/com/wms/service/StockService.java b/src/main/java/com/wms/service/StockService.java
new file mode 100644
index 0000000..dff85f5
--- /dev/null
+++ b/src/main/java/com/wms/service/StockService.java
@@ -0,0 +1,11 @@
+package com.wms.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.wms.entity.app.dto.StockDto;
+import com.wms.entity.table.Stock;
+
+import java.util.List;
+
+public interface StockService extends IService {
+ List selectStocks(Stock stock);
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/service/TaskRecordService.java b/src/main/java/com/wms/service/TaskRecordService.java
new file mode 100644
index 0000000..a5e2188
--- /dev/null
+++ b/src/main/java/com/wms/service/TaskRecordService.java
@@ -0,0 +1,34 @@
+package com.wms.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.wms.entity.app.dto.TaskRecordDto;
+import com.wms.entity.table.TaskRecord;
+
+import java.util.List;
+
+public interface TaskRecordService extends IService {
+ /**
+ * 查找入库任务记录
+ * @param query 查询参数
+ * @return 查询结果
+ */
+ List selectInTaskRecord(TaskRecord query);
+ /**
+ * 查找出库任务记录
+ * @param query 查询参数
+ * @return 查询结果
+ */
+ List selectOutTaskRecord(TaskRecord query);
+ /**
+ * 查找盘点任务记录
+ * @param query 查询参数
+ * @return 查询结果
+ */
+ List selectInventoryTaskRecord(TaskRecord query);
+ /**
+ * 查找任务记录
+ * @param query 查询参数
+ * @return 查询结果
+ */
+ List selectTaskRecord(TaskRecord query);
+}
diff --git a/src/main/java/com/wms/service/TaskService.java b/src/main/java/com/wms/service/TaskService.java
new file mode 100644
index 0000000..ec2c8e0
--- /dev/null
+++ b/src/main/java/com/wms/service/TaskService.java
@@ -0,0 +1,5 @@
+package com.wms.service;
+
+public interface TaskService{
+
+}
diff --git a/src/main/java/com/wms/service/UserService.java b/src/main/java/com/wms/service/UserService.java
new file mode 100644
index 0000000..8d0ebd0
--- /dev/null
+++ b/src/main/java/com/wms/service/UserService.java
@@ -0,0 +1,5 @@
+package com.wms.service;
+
+public interface UserService {
+
+}
diff --git a/src/main/java/com/wms/service/VehicleService.java b/src/main/java/com/wms/service/VehicleService.java
new file mode 100644
index 0000000..37f48ad
--- /dev/null
+++ b/src/main/java/com/wms/service/VehicleService.java
@@ -0,0 +1,12 @@
+package com.wms.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.wms.entity.app.dto.VehicleDto;
+import com.wms.entity.table.Vehicle;
+
+import java.util.List;
+
+public interface VehicleService extends IService {
+
+ List selVehicles(Vehicle vehicle);
+}
diff --git a/src/main/java/com/wms/service/serviceImplements/ConfigServiceImplement.java b/src/main/java/com/wms/service/serviceImplements/ConfigServiceImplement.java
new file mode 100644
index 0000000..250a141
--- /dev/null
+++ b/src/main/java/com/wms/service/serviceImplements/ConfigServiceImplement.java
@@ -0,0 +1,39 @@
+package com.wms.service.serviceImplements;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.wms.entity.table.Config;
+import com.wms.mapper.ConfigMapper;
+import com.wms.service.ConfigService;
+import com.wms.utils.StringUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class ConfigServiceImplement implements ConfigService {
+ private final ConfigMapper configMapper;
+
+ @Override
+ public List selectConfigs(String configKey) {
+ // 查询条件
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ if (StringUtils.isNotEmpty(configKey)) {// 判断configKey是否为空
+ queryWrapper.eq(Config::getConfigKey, configKey);
+ }
+ return configMapper.selectList(queryWrapper);
+ }
+
+ @Override
+ public int updateConfig(Config config) {
+ if (StringUtils.isEmpty(config.getConfigKey())) {
+ return 0;
+ } else {
+ LambdaQueryWrapper queryWrapperForUpdate = new LambdaQueryWrapper()
+ .eq(Config::getConfigKey, config.getConfigKey());
+ return configMapper.update(config, queryWrapperForUpdate);
+ }
+ }
+}
diff --git a/src/main/java/com/wms/service/serviceImplements/GoodsServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/GoodsServiceImplements.java
new file mode 100644
index 0000000..cf59f93
--- /dev/null
+++ b/src/main/java/com/wms/service/serviceImplements/GoodsServiceImplements.java
@@ -0,0 +1,57 @@
+package com.wms.service.serviceImplements;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.wms.entity.table.GoodsDto;
+import com.wms.mapper.GoodsMapper;
+import com.wms.service.GoodsService;
+import com.wms.utils.StringUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class GoodsServiceImplements implements GoodsService {
+
+ private final GoodsMapper goodsMapper;
+
+ @Override
+ public List selGoods(GoodsDto goods){
+ return goodsMapper.selGoods(goods);
+ }
+
+ @Override
+ public GoodsDto selGoodsByGoodsId(String goodsId) {
+ if (StringUtils.isEmpty(goodsId)) {
+ return null;
+ } else {
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("goods_id", goodsId);
+ return goodsMapper.selectOne(queryWrapper);
+ }
+ }
+
+ @Override
+ public int addGoods(GoodsDto goods) {
+ return goodsMapper.insert(goods);
+ }
+
+ @Override
+ public int modifyGoods(GoodsDto goods) {
+ if (StringUtils.isEmpty(goods.getGoodsId())) {
+ return 0;
+ } else {
+ UpdateWrapper updateWrapper = new UpdateWrapper<>();
+ updateWrapper.eq("goods_id", goods.getGoodsId());
+ goodsMapper.update(goods, updateWrapper);
+ }
+ }
+
+ @Override
+ public int deleteGoods(String goodsId) {
+ return goodsMapper.deleteById(goodsId);
+ }
+}
diff --git a/src/main/java/com/wms/service/serviceImplements/LocationServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/LocationServiceImplements.java
new file mode 100644
index 0000000..44c7c7e
--- /dev/null
+++ b/src/main/java/com/wms/service/serviceImplements/LocationServiceImplements.java
@@ -0,0 +1,42 @@
+package com.wms.service.serviceImplements;
+
+import com.wms.entity.table.LocationDto;
+import com.wms.mapper.LocationMapper;
+import com.wms.service.LocationService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class LocationServiceImplements implements LocationService {
+
+ private final LocationMapper locationMapper;
+
+ @Override
+ public List selLocations(LocationDto location) {
+ return this.locationMapper.selLocations(location);
+ }
+
+ @Override
+ public List selNextLocation(LocationDto location) {
+ return locationMapper.selNextLocation(location);
+ }
+
+ @Override
+ public int addLocation(LocationDto location) {
+ return locationMapper.addLocation(location);
+ }
+
+ @Override
+ public int modifyLocation(LocationDto location) {
+ return this.locationMapper.modifyLocation(location);
+ }
+
+ @Override
+ public List selLocationsWithNum(int equipmentId, int needLocationNum) {
+ return locationMapper.selLocationsWithNum(equipmentId, needLocationNum);
+ }
+}
diff --git a/src/main/java/com/wms/service/serviceImplements/LogServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/LogServiceImplements.java
new file mode 100644
index 0000000..0a0d154
--- /dev/null
+++ b/src/main/java/com/wms/service/serviceImplements/LogServiceImplements.java
@@ -0,0 +1,23 @@
+package com.wms.service.serviceImplements;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.wms.entity.table.WmsLog;
+import com.wms.mapper.LogMapper;
+import com.wms.service.LogService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class LogServiceImplements extends ServiceImpl implements LogService {
+ private final LogMapper logMapper;
+
+ @Override
+ public boolean deleteWmsLogsRegularly(int interval) {
+ LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper()
+ .apply("log_time <= date_add(curdate(),INTERVAL -{0} DAY", interval);
+ return super.remove(lambdaQueryWrapper);
+ }
+}
diff --git a/src/main/java/com/wms/service/serviceImplements/MenuServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/MenuServiceImplements.java
new file mode 100644
index 0000000..b0eec70
--- /dev/null
+++ b/src/main/java/com/wms/service/serviceImplements/MenuServiceImplements.java
@@ -0,0 +1,23 @@
+package com.wms.service.serviceImplements;
+
+import com.wms.entity.table.MenuDto;
+import com.wms.mapper.MenuMapper;
+import com.wms.service.MenuService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class MenuServiceImplements implements MenuService {
+
+
+ private final MenuMapper menuMapper;
+
+ @Override
+ public List selMenuByRoleId(int roleId) {
+ return this.menuMapper.selMenuByRoleId(roleId);
+ }
+}
diff --git a/src/main/java/com/wms/service/serviceImplements/StandServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/StandServiceImplements.java
new file mode 100644
index 0000000..723b901
--- /dev/null
+++ b/src/main/java/com/wms/service/serviceImplements/StandServiceImplements.java
@@ -0,0 +1,45 @@
+package com.wms.service.serviceImplements;
+
+import com.wms.entity.table.StandDto;
+import com.wms.mapper.StandMapper;
+import com.wms.service.StandService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class StandServiceImplements implements StandService {
+
+ private final StandMapper standMapper;
+
+ @Autowired
+ public StandServiceImplements(StandMapper standMapper) {
+ this.standMapper = standMapper;
+ }
+
+ @Override
+ public List selStands(StandDto stand) {
+ return this.standMapper.selStands(stand);
+ }
+
+ @Override
+ public StandDto selStandById(String standId) {
+ return this.standMapper.selStandById(standId);
+ }
+
+ @Override
+ public int addStand(StandDto stand) {
+ return this.standMapper.addStand(stand);
+ }
+
+ @Override
+ public int modifyStand(StandDto stand) {
+ return this.standMapper.modifyStand(stand);
+ }
+
+ @Override
+ public int deleteStand(StandDto stand) {
+ return this.standMapper.deleteStand(stand);
+ }
+}
diff --git a/src/main/java/com/wms/service/serviceImplements/StockServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/StockServiceImplements.java
new file mode 100644
index 0000000..f7a289b
--- /dev/null
+++ b/src/main/java/com/wms/service/serviceImplements/StockServiceImplements.java
@@ -0,0 +1,32 @@
+package com.wms.service.serviceImplements;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.wms.entity.app.dto.StockDto;
+import com.wms.entity.table.Stock;
+import com.wms.entity.table.Vehicle;
+import com.wms.mapper.StockMapper;
+import com.wms.service.StockService;
+import com.wms.utils.StringUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class StockServiceImplements extends ServiceImpl implements StockService {
+ private final StockMapper stockMapper;
+
+ @Override
+ public List selectStocks(Stock stock) {
+ // TODO 具体查询条件待添加
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper()
+ .eq(StringUtils.isNotEmpty(stock.getVehicleId()), Stock::getVehicleId, stock.getVehicleId());
+ List results = super.list(queryWrapper);
+
+ return BeanUtil.copyToList(results, StockDto.class);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/wms/service/serviceImplements/TaskRecordServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/TaskRecordServiceImplements.java
new file mode 100644
index 0000000..35f429a
--- /dev/null
+++ b/src/main/java/com/wms/service/serviceImplements/TaskRecordServiceImplements.java
@@ -0,0 +1,57 @@
+package com.wms.service.serviceImplements;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.wms.constants.enums.TaskType;
+import com.wms.entity.app.dto.TaskRecordDto;
+import com.wms.entity.app.dto.extend.TaskDetailInfo;
+import com.wms.entity.table.TaskRecord;
+import com.wms.mapper.TaskRecordMapper;
+import com.wms.service.TaskRecordService;
+import com.wms.utils.StringUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+
+@Service
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class TaskRecordServiceImplements extends ServiceImpl implements TaskRecordService {
+ private final TaskRecordMapper taskRecordMapper;
+
+ @Override
+ public List selectInTaskRecord(TaskRecord query) {
+ query.setTaskType(TaskType.IN.getCode());// 设置为入库
+ return selectTaskRecord(query);
+ }
+
+ @Override
+ public List selectOutTaskRecord(TaskRecord query) {
+ query.setTaskType(TaskType.OUT.getCode());// 设置为出库
+ return selectTaskRecord(query);
+ }
+
+ @Override
+ public List selectInventoryTaskRecord(TaskRecord query) {
+ query.setTaskType(TaskType.INVENTORY.getCode());// 设置为盘点
+ return selectTaskRecord(query);
+ }
+
+ @Override
+ public List selectTaskRecord(TaskRecord query) {
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper()
+ .eq(TaskRecord::getTaskType, query.getTaskType())
+ .like(StringUtils.isNotEmpty(query.getVehicleId()), TaskRecord::getVehicleId, query.getVehicleId());
+ if (query.getGoodsRelated() != null) {
+ queryWrapper
+ // 物料编号
+ .apply(StringUtils.isNotEmpty(query.getGoodsRelated().getGoodsId()), "goods_related ->> '$.goodsId' like concat('%', {0}, '%')", query.getGoodsRelated().getGoodsId())
+ // 物料名称/描述
+ .apply(StringUtils.isNotEmpty(query.getGoodsRelated().getGoodsName()), "goods_related ->> '$.goodsName' like concat('%', {0}, '%')", query.getGoodsRelated().getGoodsName());
+ }
+ return BeanUtil.copyToList(super.list(queryWrapper), TaskRecordDto.class);
+ }
+}
diff --git a/src/main/java/com/wms/service/serviceImplements/TaskServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/TaskServiceImplements.java
new file mode 100644
index 0000000..278a49e
--- /dev/null
+++ b/src/main/java/com/wms/service/serviceImplements/TaskServiceImplements.java
@@ -0,0 +1,40 @@
+package com.wms.service.serviceImplements;
+
+import com.wms.entity.table.TaskDto;
+import com.wms.mapper.TaskMapper;
+import com.wms.service.TaskService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class TaskServiceImplements implements TaskService {
+
+ private final TaskMapper taskMapper;
+
+ @Autowired
+ public TaskServiceImplements(TaskMapper taskMapper) {
+ this.taskMapper = taskMapper;
+ }
+
+ @Override
+ public List selTasks(TaskDto task) {
+ return taskMapper.selTasks(task);
+ }
+
+ @Override
+ public int addTask(TaskDto task) {
+ return taskMapper.addTask(task);
+ }
+
+ @Override
+ public int executeTask(TaskDto task) {
+ return taskMapper.executeTask(task);
+ }
+
+ @Override
+ public int deleteTask(String taskId) {
+ return taskMapper.deleteTask(taskId);
+ }
+}
diff --git a/src/main/java/com/wms/service/serviceImplements/UserServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/UserServiceImplements.java
new file mode 100644
index 0000000..1610335
--- /dev/null
+++ b/src/main/java/com/wms/service/serviceImplements/UserServiceImplements.java
@@ -0,0 +1,24 @@
+package com.wms.service.serviceImplements;
+
+import com.wms.entity.table.UserDto;
+import com.wms.mapper.UserMapper;
+import com.wms.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class UserServiceImplements implements UserService {
+
+ private final UserMapper userMapper;
+ @Autowired
+ public UserServiceImplements(UserMapper userMapper) {
+ this.userMapper = userMapper;
+ }
+
+ @Override
+ public List selectUsers(UserDto user) {
+ return userMapper.selectUsers(user);
+ }
+}
diff --git a/src/main/java/com/wms/service/serviceImplements/VehicleServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/VehicleServiceImplements.java
new file mode 100644
index 0000000..111867c
--- /dev/null
+++ b/src/main/java/com/wms/service/serviceImplements/VehicleServiceImplements.java
@@ -0,0 +1,31 @@
+package com.wms.service.serviceImplements;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.wms.entity.app.dto.VehicleDto;
+import com.wms.entity.table.Vehicle;
+import com.wms.mapper.VehicleMapper;
+import com.wms.service.VehicleService;
+import com.wms.utils.StringUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class VehicleServiceImplements extends ServiceImpl implements VehicleService {
+ private final VehicleMapper vehicleMapper;
+
+ @Override
+ public List selVehicles(Vehicle vehicle) {
+ // TODO 具体查询条件待添加
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper()
+ .eq(StringUtils.isNotEmpty(vehicle.getVehicleId()), Vehicle::getVehicleId, vehicle.getVehicleId());
+ List results = super.list(queryWrapper);
+
+ return BeanUtil.copyToList(results, VehicleDto.class);
+ }
+}
diff --git a/src/main/java/com/wms/system_service/ISystemService.java b/src/main/java/com/wms/system_service/ISystemService.java
new file mode 100644
index 0000000..3d85592
--- /dev/null
+++ b/src/main/java/com/wms/system_service/ISystemService.java
@@ -0,0 +1,16 @@
+package com.wms.system_service;
+
+/**
+ * 系统相关的服务
+ */
+public interface ISystemService {
+ /**
+ * 重启系统
+ */
+ public boolean restartSystem();
+
+ /**
+ * 重新加载配置
+ */
+ public boolean reloadConfig();
+}
diff --git a/src/main/java/com/wms/system_service/serviceImplents/SystemServiceImplements.java b/src/main/java/com/wms/system_service/serviceImplents/SystemServiceImplements.java
new file mode 100644
index 0000000..11dbb6a
--- /dev/null
+++ b/src/main/java/com/wms/system_service/serviceImplents/SystemServiceImplements.java
@@ -0,0 +1,43 @@
+package com.wms.system_service.serviceImplents;
+
+import com.wms.WmsApplication;
+import com.wms.entity.table.Config;
+import com.wms.service.ConfigService;
+import com.wms.system_service.ISystemService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+import static com.wms.config.InitLocalConfig.configMap;
+
+@Service
+@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+public class SystemServiceImplements implements ISystemService {
+ private final ConfigService configService;
+ @Override
+ public boolean restartSystem() {
+ try {
+ WmsApplication.restart();
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean reloadConfig() {
+ try {
+ List configs = configService.selectConfigs("");
+ if (configs.size() > 0) {
+ for (Config config : configs) {
+ configMap.put(config.getConfigKey(), config.getConfigValue());
+ }
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/com/wms/utils/HttpUtils.java b/src/main/java/com/wms/utils/HttpUtils.java
new file mode 100644
index 0000000..99c1d3c
--- /dev/null
+++ b/src/main/java/com/wms/utils/HttpUtils.java
@@ -0,0 +1,227 @@
+package com.wms.utils;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.charset.Charset;
+import java.util.Base64;
+import java.util.Map;
+
+import jakarta.servlet.http.HttpServletRequest;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.ParseException;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+
+/**
+ * Http工具类
+ */
+public class HttpUtils {
+
+ /**
+ * 获取请求的ip地址
+ * @param request 请求
+ * @return ip地址
+ */
+ public static String getIpAddr(HttpServletRequest request) {
+ String ip = request.getHeader("x-forwarded-for");
+ if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("Proxy-Client-IP");
+ }
+ if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getRemoteAddr();
+ }
+ if (ip != null && ip.indexOf(",") > 0) {
+ String[] parts = ip.split(",");
+ for (String part : parts) {
+ if (!part.isEmpty() && !"unknown".equalsIgnoreCase(part)) {
+ ip = part.trim();
+ break;
+ }
+ }
+ }
+ if ("0:0:0:0:0:0:0:1".equals(ip)) {
+ ip = "127.0.0.1";
+ }
+ return ip;
+ }
+
+ /**
+ * 发送HttpGet请求(无参数)
+ * @param url 地址
+ * @return 响应结果
+ */
+ public static String sendHttpGet(String url) {
+ String result = "";
+ CloseableHttpClient httpClient = null;
+ CloseableHttpResponse response = null;
+ try {
+ httpClient = HttpClients.createDefault();
+ HttpGet httpget = new HttpGet(url);
+ response = httpClient.execute(httpget);
+ HttpEntity entity = null;
+ if (response != null) {
+ entity = response.getEntity();
+ }
+ if (entity != null) {
+ result = EntityUtils.toString(entity);
+ }
+ } catch (ParseException | IOException e) {
+ e.printStackTrace();
+ } finally {
+ if(response!=null){ try{response.close();}catch (IOException e){ e.printStackTrace();} }
+ if(httpClient!=null){ try{httpClient.close();}catch(IOException e){ e.printStackTrace();} }
+ }
+ return result;
+ }
+
+ /**
+ * 发送HttpGet请求(带参数)
+ * @param url 地址
+ * @param header 参数放在请求头里面
+ * @return 响应结果
+ */
+ public static String sendHttpGet(String url, Map header) {
+ if (header == null) {// 没有参数
+ return sendHttpGet(url);
+ }
+ String result = "";
+ CloseableHttpClient httpClient = null;
+ CloseableHttpResponse response = null;
+ try {
+ httpClient = HttpClients.createDefault();
+ HttpGet httpGet = new HttpGet(url);
+ // 设置超时时间
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setConnectTimeout(5000)
+ .setConnectionRequestTimeout(1000)
+ .setSocketTimeout(5000).build();
+ httpGet.setConfig(requestConfig);
+ for(Map.Entry entry : header.entrySet()){
+
+ httpGet.setHeader(entry.getKey(), entry.getValue());
+ }
+ response = httpClient.execute(httpGet);
+ HttpEntity entity = null;
+ if (response != null) {
+ entity = response.getEntity();
+ }
+ if (entity != null) {
+ result = EntityUtils.toString(entity);
+ }
+ } catch (ParseException | IOException e) {
+ e.printStackTrace();
+ } finally {
+ if(response!=null){ try{response.close();}catch (IOException e){ e.printStackTrace();} }
+ if(httpClient!=null){ try{httpClient.close();}catch(IOException e){ e.printStackTrace();} }
+ }
+ return result;
+ }
+
+ /**
+ * 发送httpPost请求(不需要认证信息)
+ * @param url 目的地址
+ * @param param 参数
+ * @return 请求结果
+ */
+ public static String sendHttpPostWithoutToken(String url,String param) {
+ return sendHttpPost(url, param, null, null, null);
+ }
+
+ /**
+ * 发送httpPost请求
+ * @param url 目的地址
+ * @param param 参数
+ * @param token 认证信息
+ * @param userName 登录账户
+ * @param password 登录密码
+ * @return 请求结果
+ */
+ public static String sendHttpPost(String url, String param, String token, String userName, String password) {
+ String data="";
+ CloseableHttpClient httpClient = null;
+ CloseableHttpResponse response = null;
+ try {
+ httpClient = HttpClients.createDefault();
+ HttpPost httppost = new HttpPost(url);
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setConnectTimeout(5000)
+ .setConnectionRequestTimeout(5000)
+ .setSocketTimeout(5000).build();
+ httppost.setConfig(requestConfig);
+ httppost.setHeader("Content-Type", "application/json;charset=UTF-8");
+ if (StringUtils.isEmpty(token) && StringUtils.isNotEmpty(userName) && StringUtils.isNotEmpty(password)) {
+ httppost.setHeader("Authorization", "Basic " + Base64.getUrlEncoder().encodeToString((userName + ":" + password).getBytes()));
+ } else {
+ httppost.setHeader("Authorization", "Bearer " + token);
+ }
+ StringEntity se = new StringEntity(param, Charset.forName("UTF-8"));
+ se.setContentType("text/json");
+ se.setContentEncoding("UTF-8");
+ httppost.setEntity(se);
+ response = httpClient.execute(httppost);
+ data = EntityUtils.toString(response.getEntity(), "utf-8");
+ EntityUtils.consume(response.getEntity());
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if(response!=null){ try{response.close();}catch (IOException e){ e.printStackTrace();} }
+ if(httpClient!=null){ try{httpClient.close();}catch(IOException e){ e.printStackTrace();} }
+ }
+ return data;
+ }
+
+ /**
+ * 发送httpPost请求
+ * @param url 目的地址
+ * @param param 参数
+ * @param token 认证信息
+ * @param userName 登录账户
+ * @param password 登录密码
+ * @return 请求结果
+ */
+ public static String sendHttpPostForm(String url, String param, String token, String userName, String password) {
+
+ String data="";
+ CloseableHttpClient httpClient = null;
+ CloseableHttpResponse response = null;
+ try {
+ httpClient = HttpClients.createDefault();
+ HttpPost httppost = new HttpPost(url);
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setConnectTimeout(5000)
+ .setConnectionRequestTimeout(1000)
+ .setSocketTimeout(5000).build();
+ httppost.setConfig(requestConfig);
+ httppost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
+ if (StringUtils.isEmpty(token) && StringUtils.isNotEmpty(userName) && StringUtils.isNotEmpty(password)) {
+ httppost.setHeader("Authorization", "Basic " + Base64.getUrlEncoder().encodeToString((userName + ":" + password).getBytes()));
+ } else {
+ httppost.setHeader("Authorization", "Bearer " + token);
+ }
+ StringEntity se = new StringEntity(param, Charset.forName("UTF-8"));
+ se.setContentType("application/x-www-form-urlencoded");
+ se.setContentEncoding("UTF-8");
+ httppost.setEntity(se);
+ response = httpClient.execute(httppost);
+ data = EntityUtils.toString(response.getEntity(), "utf-8");
+ EntityUtils.consume(response.getEntity());
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if(response!=null){ try{response.close();}catch (IOException e){ e.printStackTrace();} }
+ if(httpClient!=null){ try{httpClient.close();}catch(IOException e){ e.printStackTrace();} }
+ }
+ return data;
+ }
+}
diff --git a/src/main/java/com/wms/utils/JWTUtils.java b/src/main/java/com/wms/utils/JWTUtils.java
new file mode 100644
index 0000000..20363ad
--- /dev/null
+++ b/src/main/java/com/wms/utils/JWTUtils.java
@@ -0,0 +1,15 @@
+package com.wms.utils;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.interfaces.DecodedJWT;
+
+public class JWTUtils {
+ /**
+ * 解码token
+ * @param token token
+ * @return 结果
+ */
+ public static DecodedJWT decodeToken(String token) {
+ return JWT.decode(token);
+ }
+}
diff --git a/src/main/java/com/wms/utils/MyPassword.java b/src/main/java/com/wms/utils/MyPassword.java
new file mode 100644
index 0000000..ceb6ab3
--- /dev/null
+++ b/src/main/java/com/wms/utils/MyPassword.java
@@ -0,0 +1,113 @@
+package com.wms.utils;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.SecureRandom;
+
+/**
+ * Md5加密算法
+ */
+public class MyPassword {
+
+ // 密钥
+ private static final String myPwd = "fdbk";
+
+ /**
+ * 加密
+ * @param originalPassword
+ * @return
+ */
+ public static String encrypt(String originalPassword) {
+ byte[] targetPassword;
+ try {
+ // 声明加密算法
+ KeyGenerator kgen = KeyGenerator.getInstance("AES");
+ SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+ random.setSeed(myPwd.getBytes());
+ kgen.init(128, random);
+ SecretKey secretKey = kgen.generateKey();
+ byte[] enCodeFormat = secretKey.getEncoded();
+ SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
+
+ // 创建密码器
+ Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+ cipher.init(Cipher.ENCRYPT_MODE, key);
+ byte[] byteContent = originalPassword.getBytes();
+ targetPassword = cipher.doFinal(byteContent);
+
+ } catch (Exception e) {
+ return null;
+ }
+
+ return parseByte2HexStr(targetPassword);
+ }
+
+ /**
+ * 解密
+ * @param targetPassword
+ * @return
+ */
+ public static String decrypt(String targetPassword) {
+ byte[] originalPassword;
+ byte[] content = parseHexStr2Byte(targetPassword);
+ try {
+ KeyGenerator kgen = KeyGenerator.getInstance("AES");
+ SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
+ random.setSeed(myPwd.getBytes());
+ kgen.init(128, random);
+ SecretKey secretKey = kgen.generateKey();
+ byte[] enCodeFormat = secretKey.getEncoded();
+ SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
+
+ // 创建密码器
+ Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+ cipher.init(Cipher.DECRYPT_MODE, key);
+ originalPassword = cipher.doFinal(content);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ return new String(originalPassword);
+ }
+
+ /**
+ * 将二进制转换成十六进制
+ *
+ * @param buf
+ * @return
+ */
+ public static String parseByte2HexStr(byte buf[]) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < buf.length; i++) {
+ String hex = Integer.toHexString(buf[i] & 0xFF);
+ if (hex.length() == 1) {
+ hex = '0' + hex;
+ }
+ sb.append(hex.toUpperCase());
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 将十六进制转换为二进制
+ *
+ * @param hexStr
+ * @return
+ */
+ public static byte[] parseHexStr2Byte(String hexStr) {
+ if (hexStr.length() < 1) {
+ return null;
+ }
+ byte[] result = new byte[hexStr.length() / 2];
+ for (int i = 0; i < hexStr.length() / 2; i++) {
+ int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
+ int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
+ result[i] = (byte) (high * 16 + low);
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/wms/utils/StringUtils.java b/src/main/java/com/wms/utils/StringUtils.java
new file mode 100644
index 0000000..ca18756
--- /dev/null
+++ b/src/main/java/com/wms/utils/StringUtils.java
@@ -0,0 +1,121 @@
+package com.wms.utils;
+
+import com.alibaba.fastjson2.JSON;
+
+/**
+ * WMS字符串工具类
+ * @author 梁州
+ * @date 2023/2/13
+ */
+public class StringUtils {
+ /** 空字符串 */
+ private static final String NULLSTR = "";
+
+ /** 下划线 */
+ private static final char SEPARATOR = '_';
+
+ public static boolean isEmpty(String value) {
+ return value == null || value.equals(NULLSTR);
+ }
+
+ public static boolean isNotEmpty(String value) {
+ return !isEmpty(value);
+ }
+
+ /**
+ * 驼峰转下划线命名
+ */
+ public static String toUnderScoreCase(String str)
+ {
+ if (str == null)
+ {
+ return null;
+ }
+ StringBuilder sb = new StringBuilder();
+ // 前置字符是否大写
+ boolean preCharIsUpperCase = true;
+ // 当前字符是否大写
+ boolean curreCharIsUpperCase = true;
+ // 下一字符是否大写
+ boolean nexteCharIsUpperCase = true;
+ for (int i = 0; i < str.length(); i++)
+ {
+ char c = str.charAt(i);
+ if (i > 0)
+ {
+ preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
+ }
+ else
+ {
+ preCharIsUpperCase = false;
+ }
+
+ curreCharIsUpperCase = Character.isUpperCase(c);
+
+ if (i < (str.length() - 1))
+ {
+ nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
+ }
+
+ if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
+ {
+ sb.append(SEPARATOR);
+ }
+ else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
+ {
+ sb.append(SEPARATOR);
+ }
+ sb.append(Character.toLowerCase(c));
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * 驼峰式命名法
+ * 例如:user_name->userName
+ */
+ public static String toCamelCase(String s)
+ {
+ if (s == null)
+ {
+ return null;
+ }
+ if (s.indexOf(SEPARATOR) == -1)
+ {
+ s = s.toLowerCase();
+ return s;
+ }
+ s = s.toLowerCase();
+ StringBuilder sb = new StringBuilder(s.length());
+ boolean upperCase = false;
+ for (int i = 0; i < s.length(); i++)
+ {
+ char c = s.charAt(i);
+
+ if (c == SEPARATOR)
+ {
+ upperCase = true;
+ }
+ else if (upperCase)
+ {
+ sb.append(Character.toUpperCase(c));
+ upperCase = false;
+ }
+ else
+ {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 将对象转为json字符串
+ * @param o 实体类
+ * @return 字符串
+ */
+ public static String convertJsonString(Object o) {
+ return JSON.toJSONString(o);
+ }
+}
diff --git a/src/main/java/com/wms/utils/TokenUtils.java b/src/main/java/com/wms/utils/TokenUtils.java
new file mode 100644
index 0000000..f824f25
--- /dev/null
+++ b/src/main/java/com/wms/utils/TokenUtils.java
@@ -0,0 +1,6 @@
+package com.wms.utils;
+
+public class TokenUtils {
+ private static final long EXPIRE_TIME= 10*60*60*1000; //十小时
+ private static final String TOKEN_SECRET="123456"; //密钥盐
+}
diff --git a/src/main/java/com/wms/utils/WmsUtils.java b/src/main/java/com/wms/utils/WmsUtils.java
new file mode 100644
index 0000000..cc5a234
--- /dev/null
+++ b/src/main/java/com/wms/utils/WmsUtils.java
@@ -0,0 +1,181 @@
+package com.wms.utils;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * WMS工具类
+ * @author 梁州
+ * @date 2023/2/13
+ */
+public class WmsUtils {
+ // 日期格式
+ public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ // 时间格式
+ public static final SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ // id用的时间格式
+ public static final SimpleDateFormat idTimeFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ public static volatile Long lastTimestamp = -1L;
+ /**
+ * 生成唯一的编号
+ * @param code 插入字符串
+ * @return 唯一id
+ */
+ public static String generateId(String code) {
+ return code + generateUUIDString();
+ }
+
+ /**
+ * 生成UUID
+ */
+ public synchronized static String generateUUIDString() {
+ long timeStamp = System.currentTimeMillis();
+ if (timeStamp == lastTimestamp) {
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e){
+ timeStamp = System.currentTimeMillis();
+ lastTimestamp = timeStamp;
+ return idTimeFormat.format(new Date()).concat(String.valueOf(timeStamp));
+ }
+ timeStamp = System.currentTimeMillis();
+ lastTimestamp = timeStamp;
+ return idTimeFormat.format(new Date()).concat(String.valueOf(timeStamp));
+ } else {
+ lastTimestamp = timeStamp;
+ return idTimeFormat.format(new Date()).concat(String.valueOf(timeStamp));
+ }
+ }
+
+ // 方法接收一个字符参数,返回对应的1-26之间的数字
+ public static int letterToNumber(char letter) {
+ if ('a' <= letter && letter <= 'z') {
+ return letter - 'a' + 1;
+ } else if ('A' <= letter && letter <= 'Z') {
+ return letter - 'A' + 1;
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * 时间字符串转时间格式
+ * @param time 时间
+ */
+ public static Date timeStringToTime(String time) throws ParseException {
+ return timeFormat.parse(time);
+ }
+
+ /**
+ * 日期字符串
+ * @param date 日期
+ */
+ public static Date dateStringToDate(String date) throws ParseException {
+ return dateFormat.parse(date);
+ }
+
+ /**
+ * 生成时间戳,格式yyyy-MM-dd HH:mm:ss
+ * @return 时间戳
+ */
+ public static String createCurrentTimeString() {
+ return timeFormat.format(new Date());
+ }
+
+ /**
+ * 生成日期字符串,格式yyyy-MM-dd
+ * @return 时间戳
+ */
+ public static String createCurrentDateString() {
+ return dateFormat.format(new Date());
+ }
+
+ /**
+ * 格式化日期,格式yyyy-MM-dd
+ * @param date 日期
+ * @return 时间戳
+ */
+ public static String formatDateString(Date date) {
+ return dateFormat.format(date);
+ }
+
+ /**
+ * 格式化时间,格式yyyy-MM-dd HH:mm:ss
+ * @param date 日期
+ * @return 时间戳
+ */
+ public static String formatTimeString(Date date) {
+ return timeFormat.format(date);
+ }
+
+ /**
+ * 获得指定日期之后指定天数的日期
+ * @param beginDay 开始日期
+ * @param days 天数
+ * @return 日期
+ */
+ public static Date calculationDate(Date beginDay, int days){
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(beginDay);
+ calendar.add(Calendar.DATE, days);
+ return calendar.getTime();
+ }
+
+ /**
+ * 获得指定日期之后指定月数的日期
+ * @param beginDay 开始日期
+ * @param months 月数
+ * @return 日期
+ */
+ public static Date calculationMonth(Date beginDay, int months){
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(beginDay);
+ calendar.add(Calendar.MONTH, months);
+ return calendar.getTime();
+ }
+
+ /**
+ * 获得指定日期之后指定年数的日期
+ * @param beginDay 开始日期
+ * @param years 年数
+ * @return 日期
+ */
+ public static Date calculationYear(Date beginDay, int years){
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(beginDay);
+ calendar.add(Calendar.YEAR, years);
+ return calendar.getTime();
+ }
+
+ /**
+ * 获取指定天数后的日期
+ * @param day 天数
+ * @return 日期
+ */
+ public static Date getDay(int day){
+ return calculationDate(new Date(), day);
+ }
+
+ /**
+ * 获取任意月后的时间
+ * @Params: mon 1表示后一个月 -1表示前一个月
+ * @Return
+ */
+ public static Date getMon(int mon){
+ return calculationMonth(new Date(), mon);
+ }
+
+ /**
+ * 获取任意年之后的日期
+ * @param year 年
+ * @return 日期
+ */
+ public static Date getYear(int year){
+ return calculationYear(new Date(), year);
+ }
+}
diff --git a/src/main/java/com/wms/utils/excel/ExcelClassField.java b/src/main/java/com/wms/utils/excel/ExcelClassField.java
new file mode 100644
index 0000000..008be2b
--- /dev/null
+++ b/src/main/java/com/wms/utils/excel/ExcelClassField.java
@@ -0,0 +1,71 @@
+package com.wms.utils.excel;
+
+import java.util.LinkedHashMap;
+
+public class ExcelClassField {
+ /** 字段名称 */
+ private String fieldName;
+
+ /** 表头名称 */
+ private String name;
+
+ /** 映射关系 */
+ private LinkedHashMap kvMap;
+
+ /** 示例值 */
+ private Object example;
+
+ /** 排序 */
+ private int sort;
+
+ /** 是否为注解字段:0-否,1-是 */
+ private int hasAnnotation;
+
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ public void setFieldName(String fieldName) {
+ this.fieldName = fieldName;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public LinkedHashMap getKvMap() {
+ return kvMap;
+ }
+
+ public void setKvMap(LinkedHashMap kvMap) {
+ this.kvMap = kvMap;
+ }
+
+ public Object getExample() {
+ return example;
+ }
+
+ public void setExample(Object example) {
+ this.example = example;
+ }
+
+ public int getSort() {
+ return sort;
+ }
+
+ public void setSort(int sort) {
+ this.sort = sort;
+ }
+
+ public int getHasAnnotation() {
+ return hasAnnotation;
+ }
+
+ public void setHasAnnotation(int hasAnnotation) {
+ this.hasAnnotation = hasAnnotation;
+ }
+}
diff --git a/src/main/java/com/wms/utils/excel/ExcelExport.java b/src/main/java/com/wms/utils/excel/ExcelExport.java
new file mode 100644
index 0000000..431d99e
--- /dev/null
+++ b/src/main/java/com/wms/utils/excel/ExcelExport.java
@@ -0,0 +1,22 @@
+package com.wms.utils.excel;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExcelExport {
+ /** 字段名称 */
+ String value();
+
+ /** 导出排序先后: 数字越小越靠前(默认按Java类字段顺序导出) */
+ int sort() default 0;
+
+ /** 导出映射,格式如:0-未知;1-男;2-女 */
+ String kv() default "";
+
+ /** 导出模板示例值(有值的话,直接取该值,不做映射) */
+ String example() default "";
+}
diff --git a/src/main/java/com/wms/utils/excel/ExcelImport.java b/src/main/java/com/wms/utils/excel/ExcelImport.java
new file mode 100644
index 0000000..58c7b52
--- /dev/null
+++ b/src/main/java/com/wms/utils/excel/ExcelImport.java
@@ -0,0 +1,25 @@
+package com.wms.utils.excel;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExcelImport {
+ /** 字段名称 */
+ String value();
+
+ /** 导出映射,格式如:0-未知;1-男;2-女 */
+ String kv() default "";
+
+ /** 是否为必填字段(默认为非必填) */
+ boolean required() default false;
+
+ /** 最大长度(默认255) */
+ int maxLength() default 255;
+
+ /** 导入唯一性验证(多个字段则取联合验证) */
+ boolean unique() default false;
+}
diff --git a/src/main/java/com/wms/utils/excel/ExcelUtils.java b/src/main/java/com/wms/utils/excel/ExcelUtils.java
new file mode 100644
index 0000000..28c81d1
--- /dev/null
+++ b/src/main/java/com/wms/utils/excel/ExcelUtils.java
@@ -0,0 +1,1026 @@
+package com.wms.utils.excel;
+
+
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
+import org.apache.poi.hssf.usermodel.HSSFDataValidation;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.apache.poi.ss.usermodel.DateUtil;
+
+import java.io.*;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.net.URL;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * Excel工具类
+ */
+@SuppressWarnings("unused")
+public class ExcelUtils {
+ private static final String XLSX = ".xlsx";
+ private static final String XLS = ".xls";
+ public static final String ROW_MERGE = "row_merge";
+ public static final String COLUMN_MERGE = "column_merge";
+ private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
+ private static final String ROW_NUM = "rowNum";
+ private static final String ROW_DATA = "rowData";
+ private static final String ROW_TIPS = "rowTips";
+ private static final int CELL_OTHER = 0;
+ private static final int CELL_ROW_MERGE = 1;
+ private static final int CELL_COLUMN_MERGE = 2;
+ private static final int IMG_HEIGHT = 30;
+ private static final int IMG_WIDTH = 30;
+ private static final char LEAN_LINE = '/';
+ private static final int BYTES_DEFAULT_LENGTH = 10240;
+ private static final NumberFormat NUMBER_FORMAT = NumberFormat.getNumberInstance();
+
+ public static List readFile(File file, Class clazz) throws Exception {
+ JSONArray array = readFile(file);
+ return getBeanList(array, clazz);
+ }
+
+ public static List readMultipartFile(MultipartFile mFile, Class clazz) throws Exception {
+ JSONArray array = readMultipartFile(mFile);
+ return getBeanList(array, clazz);
+ }
+ public static JSONArray readFile(File file) throws Exception {
+ return readExcel(null, file);
+ }
+
+ public static JSONArray readMultipartFile(MultipartFile mFile) throws Exception {
+ return readExcel(mFile, null);
+ }
+
+ public static Map readFileManySheet(File file) throws Exception {
+ return readExcelManySheet(null, file);
+ }
+
+ public static Map readFileManySheet(MultipartFile file) throws Exception {
+ return readExcelManySheet(file, null);
+ }
+
+ private static List getBeanList(JSONArray array, Class clazz) throws Exception {
+ List list = new ArrayList<>();
+ Map uniqueMap = new HashMap<>(16);
+ for (int i = 0; i < array.size(); i++) {
+ list.add(getBean(clazz, array.getJSONObject(i), uniqueMap));
+ }
+ return list;
+ }
+
+
+ /**
+ * 获取每个对象的数据
+ */
+ private static T getBean(Class c, JSONObject obj, Map uniqueMap) throws Exception {
+ T t = c.getDeclaredConstructor().newInstance();
+ Field[] fields = c.getDeclaredFields();
+ List errMsgList = new ArrayList<>();
+ boolean hasRowTipsField = false;
+ StringBuilder uniqueBuilder = new StringBuilder();
+ int rowNum = 0;
+ for (Field field : fields) {
+ // 行号
+ if (field.getName().equals(ROW_NUM)) {
+ rowNum = obj.getInteger(ROW_NUM);
+ field.setAccessible(true);
+ field.set(t, rowNum);
+ continue;
+ }
+ // 是否需要设置异常信息
+ if (field.getName().equals(ROW_TIPS)) {
+ hasRowTipsField = true;
+ continue;
+ }
+ // 原始数据
+ if (field.getName().equals(ROW_DATA)) {
+ field.setAccessible(true);
+ field.set(t, obj.toString());
+ continue;
+ }
+ // 设置对应属性值
+ setFieldValue(t, field, obj, uniqueBuilder, errMsgList);
+ }
+ // 数据唯一性校验
+ if (uniqueBuilder.length() > 0) {
+ if (uniqueMap.containsValue(uniqueBuilder.toString())) {
+ Set rowNumKeys = uniqueMap.keySet();
+ for (Integer num : rowNumKeys) {
+ if (uniqueMap.get(num).equals(uniqueBuilder.toString())) {
+ errMsgList.add(String.format("数据唯一性校验失败,(%s)与第%s行重复)", uniqueBuilder, num));
+ }
+ }
+ } else {
+ uniqueMap.put(rowNum, uniqueBuilder.toString());
+ }
+ }
+ // 失败处理
+ if (errMsgList.isEmpty() && !hasRowTipsField) {
+ return t;
+ }
+ StringBuilder sb = new StringBuilder();
+ int size = errMsgList.size();
+ for (int i = 0; i < size; i++) {
+ if (i == size - 1) {
+ sb.append(errMsgList.get(i));
+ } else {
+ sb.append(errMsgList.get(i)).append(";");
+ }
+ }
+ // 设置错误信息
+ for (Field field : fields) {
+ if (field.getName().equals(ROW_TIPS)) {
+ field.setAccessible(true);
+ field.set(t, sb.toString());
+ }
+ }
+ return t;
+ }
+
+ private static void setFieldValue(T t, Field field, JSONObject obj, StringBuilder uniqueBuilder, List errMsgList) {
+ // 获取 ExcelImport 注解属性
+ ExcelImport annotation = field.getAnnotation(ExcelImport.class);
+ if (annotation == null) {
+ return;
+ }
+ String cname = annotation.value();
+ if (cname.trim().length() == 0) {
+ return;
+ }
+ // 获取具体值
+ String val = null;
+ if (obj.containsKey(cname)) {
+ val = getString(obj.getString(cname));
+ }
+ if (val == null) {
+ return;
+ }
+ field.setAccessible(true);
+ // 判断是否必填
+ boolean require = annotation.required();
+ if (require && val.isEmpty()) {
+ errMsgList.add(String.format("[%s]不能为空", cname));
+ return;
+ }
+ // 数据唯一性获取
+ boolean unique = annotation.unique();
+ if (unique) {
+ if (uniqueBuilder.length() > 0) {
+ uniqueBuilder.append("--").append(val);
+ } else {
+ uniqueBuilder.append(val);
+ }
+ }
+ // 判断是否超过最大长度
+ int maxLength = annotation.maxLength();
+ if (maxLength > 0 && val.length() > maxLength) {
+ errMsgList.add(String.format("[%s]长度不能超过%s个字符(当前%s个字符)", cname, maxLength, val.length()));
+ }
+ // 判断当前属性是否有映射关系
+ LinkedHashMap kvMap = getKvMap(annotation.kv());
+ if (!kvMap.isEmpty()) {
+ boolean isMatch = false;
+ for (String key : kvMap.keySet()) {
+ if (kvMap.get(key).equals(val)) {
+ val = key;
+ isMatch = true;
+ break;
+ }
+ }
+ if (!isMatch) {
+ errMsgList.add(String.format("[%s]的值不正确(当前值为%s)", cname, val));
+ return;
+ }
+ }
+ // 其余情况根据类型赋值
+ String fieldClassName = field.getType().getSimpleName();
+ try {
+ if ("String".equalsIgnoreCase(fieldClassName)) {
+ field.set(t, val);
+ } else if ("boolean".equalsIgnoreCase(fieldClassName)) {
+ field.set(t, Boolean.valueOf(val));
+ } else if ("int".equalsIgnoreCase(fieldClassName) || "Integer".equals(fieldClassName)) {
+ try {
+ field.set(t, Integer.valueOf(val));
+ } catch (NumberFormatException e) {
+ errMsgList.add(String.format("[%s]的值格式不正确(当前值为%s)", cname, val));
+ }
+ } else if ("double".equalsIgnoreCase(fieldClassName)) {
+ field.set(t, Double.valueOf(val));
+ } else if ("long".equalsIgnoreCase(fieldClassName)) {
+ field.set(t, Long.valueOf(val));
+ } else if ("BigDecimal".equalsIgnoreCase(fieldClassName)) {
+ field.set(t, new BigDecimal(val));
+ } else if ("Date".equalsIgnoreCase(fieldClassName)) {
+ try {
+ field.set(t, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(val));
+ } catch (Exception e) {
+ field.set(t, new SimpleDateFormat("yyyy-MM-dd").parse(val));
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static Map readExcelManySheet(MultipartFile mFile, File file) throws IOException {
+ Workbook book = getWorkbook(mFile, file);
+ if (book == null) {
+ return Collections.emptyMap();
+ }
+ Map map = new LinkedHashMap<>();
+ for (int i = 0; i < book.getNumberOfSheets(); i++) {
+ Sheet sheet = book.getSheetAt(i);
+ JSONArray arr = readSheet(sheet);
+ map.put(sheet.getSheetName(), arr);
+ }
+ book.close();
+ return map;
+ }
+
+ private static JSONArray readExcel(MultipartFile mFile, File file) throws IOException {
+ Workbook book = getWorkbook(mFile, file);
+ if (book == null) {
+ return new JSONArray();
+ }
+ JSONArray array = readSheet(book.getSheetAt(0));
+ book.close();
+ return array;
+ }
+
+ private static Workbook getWorkbook(MultipartFile mFile, File file) throws IOException {
+ boolean fileNotExist = (file == null || !file.exists());
+ if (mFile == null && fileNotExist) {
+ return null;
+ }
+ // 解析表格数据
+ InputStream in;
+ String fileName;
+ if (mFile != null) {
+ // 上传文件解析
+ in = mFile.getInputStream();
+ fileName = getString(mFile.getOriginalFilename()).toLowerCase();
+ } else {
+ // 本地文件解析
+ in = new FileInputStream(file);
+ fileName = file.getName().toLowerCase();
+ }
+ Workbook book;
+ if (fileName.endsWith(XLSX)) {
+ book = new XSSFWorkbook(in);
+ } else if (fileName.endsWith(XLS)) {
+ POIFSFileSystem poifsFileSystem = new POIFSFileSystem(in);
+ book = new HSSFWorkbook(poifsFileSystem);
+ } else {
+ return null;
+ }
+ in.close();
+ return book;
+ }
+
+ private static JSONArray readSheet(Sheet sheet) {
+ // 首行下标
+ int rowStart = sheet.getFirstRowNum();
+ // 尾行下标
+ int rowEnd = sheet.getLastRowNum();
+ // 获取表头行
+ Row headRow = sheet.getRow(rowStart);
+ if (headRow == null) {
+ return new JSONArray();
+ }
+ int cellStart = headRow.getFirstCellNum();
+ int cellEnd = headRow.getLastCellNum();
+ Map keyMap = new HashMap<>();
+ for (int j = cellStart; j < cellEnd; j++) {
+ // 获取表头数据
+ String val = getCellValue(headRow.getCell(j));
+ if (val != null && val.trim().length() != 0) {
+ keyMap.put(j, val);
+ }
+ }
+ // 如果表头没有数据则不进行解析
+ if (keyMap.isEmpty()) {
+ return (JSONArray) Collections.emptyList();
+ }
+ // 获取每行JSON对象的值
+ JSONArray array = new JSONArray();
+ // 如果首行与尾行相同,表明只有一行,返回表头数据
+ if (rowStart == rowEnd) {
+ JSONObject obj = new JSONObject();
+ // 添加行号
+ obj.put(ROW_NUM, 1);
+ for (int i : keyMap.keySet()) {
+ obj.put(keyMap.get(i), "");
+ }
+ array.add(obj);
+ return array;
+ }
+ for (int i = rowStart + 1; i <= rowEnd; i++) {
+ Row eachRow = sheet.getRow(i);
+ JSONObject obj = new JSONObject();
+ // 添加行号
+ obj.put(ROW_NUM, i + 1);
+ StringBuilder sb = new StringBuilder();
+ for (int k = cellStart; k < cellEnd; k++) {
+ if (eachRow != null) {
+ String val = getCellValue(eachRow.getCell(k));
+ // 所有数据添加到里面,用于判断该行是否为空
+ sb.append(val);
+ obj.put(keyMap.get(k), val);
+ }
+ }
+ if (sb.length() > 0) {
+ array.add(obj);
+ }
+ }
+ return array;
+ }
+
+ private static String getCellValue(Cell cell) {
+ // 空白或空
+ if (cell == null || cell.getCellType() == CellType.BLANK) {
+ return "";
+ }
+ // String类型
+ if (cell.getCellType() == CellType.STRING) {
+ String val = cell.getStringCellValue();
+ if (val == null || val.trim().length() == 0) {
+ return "";
+ }
+ return val.trim();
+ }
+ // 数字类型
+ if (cell.getCellType() == CellType.NUMERIC) {
+ if (DateUtil.isCellDateFormatted(cell)) {// 日期类型
+ // 短日期转化为字符串
+ Date date = cell.getDateCellValue();
+ if (date != null) {
+ // 标准0点 1970/01/01 08:00:00
+ if (date.getTime() % 86400000 == 16 * 3600 * 1000 && cell.getCellStyle().getDataFormat() == 14) {
+ return new SimpleDateFormat("yyyy-MM-dd").format(date);
+ } else {
+ return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
+ }
+ }
+ } else {// 数值
+ //System.out.println("Value:"+cell.getNumericCellValue());
+ String numberStr = new HSSFDataFormatter().formatCellValue(cell);
+ // 货币格式,如:1,200.00
+ if (numberStr.contains(",")) {
+ numberStr = numberStr.replace(",", "");
+ }
+ if (numberStr.contains("E")) { // 科学计算法
+ numberStr = new DecimalFormat("0").format(cell.getNumericCellValue()); //4.89481368464913E14还原为长整数
+ return numberStr;
+ } else {
+ if (numberStr.contains(".")) { // 小数
+ return numberStr;
+ } else { // 转换为整数
+ return numberStr;
+ }
+ }
+ }
+// String s = cell.getNumericCellValue() + "";
+// // 去掉尾巴上的小数点0
+// if (Pattern.matches(".*\\.0*", s)) {
+// return s.split("\\.")[0];
+// } else {
+// return s;
+// }
+ }
+ // 布尔值类型
+ if (cell.getCellType() == CellType.BOOLEAN) {
+ return String.valueOf(cell.getBooleanCellValue());
+ }
+ // 错误类型
+ return cell.getCellFormula();
+ }
+
+ public static void exportTemplate(HttpServletResponse response, String fileName, Class clazz) {
+ exportTemplate(response, fileName, fileName, clazz, false);
+ }
+
+ public static void exportTemplate(HttpServletResponse response, String fileName, String sheetName,
+ Class clazz) {
+ exportTemplate(response, fileName, sheetName, clazz, false);
+ }
+
+ public static void exportTemplate(HttpServletResponse response, String fileName, Class clazz,
+ boolean isContainExample) {
+ exportTemplate(response, fileName, fileName, clazz, isContainExample);
+ }
+
+ public static void exportTemplate(HttpServletResponse response, String fileName, String sheetName,
+ Class clazz, boolean isContainExample) {
+ // 获取表头字段
+ List headFieldList = getExcelClassFieldList(clazz);
+ // 获取表头数据和示例数据
+ List> sheetDataList = new ArrayList<>();
+ List