wangyongsheng пре 9 месеци
родитељ
комит
c78780ac00
38 измењених фајлова са 4624 додато и 0 уклоњено
  1. 31 0
      .gitignore
  2. 117 0
      .mvn/wrapper/MavenWrapperDownloader.java
  3. BIN
      .mvn/wrapper/maven-wrapper.jar
  4. 2 0
      .mvn/wrapper/maven-wrapper.properties
  5. 310 0
      mvnw
  6. 182 0
      mvnw.cmd
  7. 275 0
      pom.xml
  8. 13 0
      src/main/java/com/example/demo/DemoApplication.java
  9. 58 0
      src/main/java/com/example/demo/config/CorsConfig.java
  10. 34 0
      src/main/java/com/example/demo/config/FeignConfiguration.java
  11. 30 0
      src/main/java/com/example/demo/config/MybatisPlusConfig.java
  12. 56 0
      src/main/java/com/example/demo/config/MybatisPlusMetaObjectHandler.java
  13. 56 0
      src/main/java/com/example/demo/config/RedisProcessor.java
  14. 101 0
      src/main/java/com/example/demo/constants/NumberConstant.java
  15. 60 0
      src/main/java/com/example/demo/controller/DemoController.java
  16. 16 0
      src/main/java/com/example/demo/dao/mapper/TestMapper.java
  17. 77 0
      src/main/java/com/example/demo/dao/model/Test.java
  18. 40 0
      src/main/java/com/example/demo/dao/repository/TestRepository.java
  19. 50 0
      src/main/java/com/example/demo/endpoint/CenterEndPoint.java
  20. 28 0
      src/main/java/com/example/demo/nacosdiscovery/NacosDiscoveryConfiguration.java
  21. 21 0
      src/main/java/com/example/demo/service/DemoService.java
  22. 106 0
      src/main/java/com/example/demo/service/impl/DemoServiceImpl.java
  23. 106 0
      src/main/java/com/example/demo/util/AesUtil.java
  24. 150 0
      src/main/java/com/example/demo/util/BeanUtil.java
  25. 49 0
      src/main/java/com/example/demo/util/CommonUtil.java
  26. 1792 0
      src/main/java/com/example/demo/util/DateUtils.java
  27. 74 0
      src/main/java/com/example/demo/util/ErrorResult.java
  28. 192 0
      src/main/java/com/example/demo/util/JacksonUtil.java
  29. 140 0
      src/main/java/com/example/demo/util/PageUtils.java
  30. 63 0
      src/main/java/com/example/demo/util/RedisLock.java
  31. 107 0
      src/main/java/com/example/demo/util/Result.java
  32. 27 0
      src/main/java/com/example/demo/util/SnowflakeUtil.java
  33. 30 0
      src/main/java/com/example/demo/util/ThreadUtil.java
  34. 33 0
      src/main/java/com/example/demo/util/UserContext.java
  35. 42 0
      src/main/java/com/example/demo/vo/SessionUserVO.java
  36. 121 0
      src/main/resources/application.yml
  37. 22 0
      src/main/resources/mapper/TestMapper.xml
  38. 13 0
      src/test/java/com/example/demo/DemoApplicationTests.java

+ 31 - 0
.gitignore

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

+ 117 - 0
.mvn/wrapper/MavenWrapperDownloader.java

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

BIN
.mvn/wrapper/maven-wrapper.jar


+ 2 - 0
.mvn/wrapper/maven-wrapper.properties

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

+ 310 - 0
mvnw

@@ -0,0 +1,310 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   M2_HOME - location of maven2's installed home dir
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+  if [ -f /etc/mavenrc ] ; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ] ; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+  CYGWIN*) cygwin=true ;;
+  MINGW*) mingw=true;;
+  Darwin*) darwin=true
+    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+    if [ -z "$JAVA_HOME" ]; then
+      if [ -x "/usr/libexec/java_home" ]; then
+        export JAVA_HOME="`/usr/libexec/java_home`"
+      else
+        export JAVA_HOME="/Library/Java/Home"
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=`java-config --jre-home`
+  fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+  ## resolve links - $0 may be a link to maven's home
+  PRG="$0"
+
+  # need this for relative symlinks
+  while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+      PRG="$link"
+    else
+      PRG="`dirname "$PRG"`/$link"
+    fi
+  done
+
+  saveddir=`pwd`
+
+  M2_HOME=`dirname "$PRG"`/..
+
+  # make it fully qualified
+  M2_HOME=`cd "$M2_HOME" && pwd`
+
+  cd "$saveddir"
+  # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --unix "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME="`(cd "$M2_HOME"; pwd)`"
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="`which javac`"
+  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=`which readlink`
+    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+      if $darwin ; then
+        javaHome="`dirname \"$javaExecutable\"`"
+        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+      else
+        javaExecutable="`readlink -f \"$javaExecutable\"`"
+      fi
+      javaHome="`dirname \"$javaExecutable\"`"
+      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  if [ -n "$JAVA_HOME"  ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+    fi
+  else
+    JAVACMD="`which java`"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+
+  if [ -z "$1" ]
+  then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ] ; do
+    if [ -d "$wdir"/.mvn ] ; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=`cd "$wdir/.."; pwd`
+    fi
+    # end of workaround
+  done
+  echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    echo "$(tr -s '\n' ' ' < "$1")"
+  fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Found .mvn/wrapper/maven-wrapper.jar"
+    fi
+else
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
+    fi
+    if [ -n "$MVNW_REPOURL" ]; then
+      jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    else
+      jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    fi
+    while IFS="=" read key value; do
+      case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+      esac
+    done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+    if [ "$MVNW_VERBOSE" = true ]; then
+      echo "Downloading from: $jarUrl"
+    fi
+    wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+    if $cygwin; then
+      wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+    fi
+
+    if command -v wget > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found wget ... using wget"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget "$jarUrl" -O "$wrapperJarPath"
+        else
+            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Found curl ... using curl"
+        fi
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl -o "$wrapperJarPath" "$jarUrl" -f
+        else
+            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+        fi
+
+    else
+        if [ "$MVNW_VERBOSE" = true ]; then
+          echo "Falling back to using Java to download"
+        fi
+        javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaClass=`cygpath --path --windows "$javaClass"`
+        fi
+        if [ -e "$javaClass" ]; then
+            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Compiling MavenWrapperDownloader.java ..."
+                fi
+                # Compiling the Java class
+                ("$JAVA_HOME/bin/javac" "$javaClass")
+            fi
+            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+                # Running the downloader
+                if [ "$MVNW_VERBOSE" = true ]; then
+                  echo " - Running MavenWrapperDownloader.java ..."
+                fi
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+  echo $MAVEN_PROJECTBASEDIR
+fi
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$M2_HOME" ] &&
+    M2_HOME=`cygpath --path --windows "$M2_HOME"`
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

+ 182 - 0
mvnw.cmd

@@ -0,0 +1,182 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    https://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM     e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %DOWNLOAD_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%

+ 275 - 0
pom.xml

@@ -0,0 +1,275 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.kcim</groupId>
+    <artifactId>kcim-medical</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>kcim-medical</name>
+    <description>医务代码</description>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <spring-boot.version>2.3.12.RELEASE</spring-boot.version>
+        <fastjson2.version>2.0.23</fastjson2.version>
+        <nacos.version>2.2.8.RELEASE</nacos.version>
+        <openfeign.version>2.2.9.RELEASE</openfeign.version>
+        <saToken.version>1.31.0</saToken.version>
+        <easypoi.version>4.3.0</easypoi.version>
+        <minio.version>7.0.2</minio.version>
+        <springfox.version>3.0.0</springfox.version>
+        <knife4j.version>3.0.3</knife4j.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <version>${spring-boot.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+            <version>${fastjson2.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.3.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter-test</artifactId>
+            <version>3.5.3.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-generator</artifactId>
+            <version>3.5.3.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <scope>runtime</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.junit.vintage</groupId>
+                    <artifactId>junit-vintage-engine</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.15</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-spring-boot-starter</artifactId>
+            <version>${saToken.version}</version>
+        </dependency>
+
+
+        <!-- Sa-Token插件:权限缓存与业务缓存分离 -->
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-alone-redis</artifactId>
+            <version>${saToken.version}</version>
+        </dependency>
+        <!-- Sa-Token 整合 jwt -->
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-jwt</artifactId>
+            <version>${saToken.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>cn.hutool</groupId>
+                    <artifactId>hutool-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <!-- Sa-Token 整合 Redis (使用jackson序列化方式) -->
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-dao-redis-jackson</artifactId>
+            <version>${saToken.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>1.9</version>
+        </dependency>
+        <!--redis-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <!-- 提供Redis连接池 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+        <!-- Swagger -->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-boot-starter</artifactId>
+            <version>${springfox.version}</version>
+        </dependency>
+        <!-- swagger ui美化依赖 -->
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-spring-boot-starter</artifactId>
+            <version>${knife4j.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+            <version>${nacos.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>archaius-core</artifactId>
+                    <groupId>com.netflix.archaius</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>hystrix-core</artifactId>
+                    <groupId>com.netflix.hystrix</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>com.alibaba.cloud</groupId>-->
+        <!--            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>-->
+        <!--            <version>${nacos.version}</version>-->
+        <!--        </dependency>-->
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+            <version>${openfeign.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!-- 文件上传 -->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+            <version>4.5.7</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
+            <version>${nacos.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.minio</groupId>
+            <artifactId>minio</artifactId>
+            <version>${minio.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>failureaccess</artifactId>
+                </exclusion>
+            </exclusions>
+
+        </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>com.squareup.okhttp3</groupId>-->
+        <!--            <artifactId>okhttp</artifactId>-->
+        <!--            <version>3.14.9</version>-->
+
+        <!--        </dependency>-->
+        <!--skywalking traceId 记录到logback日志,请与安装的服务器版本对应-->
+        <dependency>
+            <groupId>org.apache.skywalking</groupId>
+            <artifactId>apm-toolkit-trace</artifactId>
+            <version>8.7.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.skywalking</groupId>
+            <artifactId>apm-toolkit-logback-1.x</artifactId>
+            <version>8.7.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.skywalking</groupId>
+            <artifactId>apm-toolkit-opentracing</artifactId>
+            <version>8.7.0</version>
+        </dependency>
+    </dependencies>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.3.7.RELEASE</version>
+                <configuration>
+                    <mainClass>com.example.demo.DemoApplication</mainClass>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>repackage</id>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 13 - 0
src/main/java/com/example/demo/DemoApplication.java

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

+ 58 - 0
src/main/java/com/example/demo/config/CorsConfig.java

@@ -0,0 +1,58 @@
+package com.example.demo.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * @author huangrui
+ */
+@Configuration
+public class CorsConfig implements WebMvcConfigurer {
+
+
+
+//    @Value("${file.filelocal}")
+//    private String fileLocal;
+
+    @Bean
+    public CorsFilter corsFilter() {
+        // 初始化cors配置对象
+        CorsConfiguration configuration = new CorsConfiguration();
+        // 允许跨域的域名,如果要携带cookie,不能写*。*:代表所有域名都可以跨域访问
+        configuration.addAllowedOrigin("*");
+        // 允许携带cookie
+        configuration.setAllowCredentials(true);
+        // 代表所有的请求方法:GET POST PUT Delete。。。。
+        configuration.addAllowedMethod("*");
+        // 允许携带任何头信息
+        configuration.addAllowedHeader("*");
+
+        // 初始化cors配置源对象
+        UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource();
+        configurationSource.registerCorsConfiguration("/**", configuration);
+
+        // 返回corsFilter实例,参数:cors配置源对象
+        return new CorsFilter(configurationSource);
+    }
+
+    /**
+     * 实现静态资源访问,但是这里仅仅提供了classpath下static文件夹的转发
+     * 对于解决其他目录的需要重新修改
+     * @param registry
+     */
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        registry.addResourceHandler("/**")
+                .addResourceLocations("classpath:/static/**","/doc.html");
+//                .addResourceLocations(fileLocal);//映射本地静态资源
+    }
+
+
+
+
+}

+ 34 - 0
src/main/java/com/example/demo/config/FeignConfiguration.java

@@ -0,0 +1,34 @@
+package com.example.demo.config;
+
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2023-09-19 17:16
+ **/
+@Configuration
+public class FeignConfiguration implements RequestInterceptor {
+    /**
+     * Called for every request. Add data using methods on the supplied {@link RequestTemplate}.
+     *
+     * @param template
+     */
+    @Override
+    public void apply(RequestTemplate template) {
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+//        获取请求体
+        javax.servlet.http.HttpServletRequest request = attributes.getRequest();
+//        获取token
+        String token = request.getHeader("token");
+//        注入feign的请求头
+        template.header("token",token);
+
+    }
+
+}

+ 30 - 0
src/main/java/com/example/demo/config/MybatisPlusConfig.java

@@ -0,0 +1,30 @@
+package com.example.demo.config;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Collections;
+
+@Configuration
+public class MybatisPlusConfig {
+
+    @Bean
+    public PaginationInnerInterceptor paginationInnerInterceptor() {
+        PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor();
+        // 设置最大单页限制数量,默认 500 条,-1 不受限制
+        paginationInterceptor.setMaxLimit(-1L);
+        paginationInterceptor.setDbType(DbType.MYSQL);
+        // 开启 count 的 join 优化,只针对部分 left join
+        paginationInterceptor.setOptimizeJoin(true);
+        return paginationInterceptor;
+    }
+    @Bean
+    public MybatisPlusInterceptor mybatisPlusInterceptor(){
+        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
+        mybatisPlusInterceptor.setInterceptors(Collections.singletonList(paginationInnerInterceptor()));
+        return mybatisPlusInterceptor;
+    }
+}

+ 56 - 0
src/main/java/com/example/demo/config/MybatisPlusMetaObjectHandler.java

@@ -0,0 +1,56 @@
+package com.example.demo.config;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.ClassUtils;
+
+import java.util.Date;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2023-09-20 14:03
+ **/
+@Configuration
+public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
+    @Override
+    public void insertFill(MetaObject metaObject) {
+        fillValueByName("createTime", new Date(), metaObject, false);
+        fillValueByName("updateTime", new Date(), metaObject, false);
+    }
+
+    @Override
+    public void updateFill(MetaObject metaObject) {
+        fillValueByName("updateTime", new Date(), metaObject, false);
+
+    }
+    /**
+     * 填充数据具体实现
+     *
+     * @param filedName  字段名
+     * @param fieldVal   字段值
+     * @param metaObject 元对象
+     * @param isCover    是否覆盖原有内容
+     */
+    private static void fillValueByName(String filedName, Object fieldVal, MetaObject metaObject, Boolean isCover) {
+        // 如果该对象没有setter,直接返回
+        if (!metaObject.hasSetter(filedName)) {
+            return;
+        }
+        // 用户需要手动设置的值
+        Object value = metaObject.getValue(filedName);
+        String valueStr = StrUtil.str(value, "UTF-8");
+        // 如果不为空,并且不覆盖
+        if (StrUtil.isNotBlank(valueStr) && !isCover) {
+            return;
+        }
+        // 类型相同设置
+        Class<?> type = metaObject.getGetterType(filedName);
+        if (ClassUtils.isAssignableValue(type, fieldVal)) {
+            metaObject.setValue(filedName, fieldVal);
+        }
+    }
+}

+ 56 - 0
src/main/java/com/example/demo/config/RedisProcessor.java

@@ -0,0 +1,56 @@
+package com.example.demo.config;
+
+import cn.hutool.core.util.StrUtil;
+import org.springframework.data.redis.cache.RedisCache;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.cache.RedisCacheWriter;
+
+import java.time.Duration;
+
+/**
+ * @program: CostAccount
+ * @description: redis配置
+ * @author: Wang.YS
+ * @create: 2023-09-19 15:49
+ **/
+
+public class RedisProcessor extends RedisCacheManager {
+    /**
+     * 默认父类构造方法
+     *
+     * @param cacheWriter               must not be {@literal null}.
+     * @param defaultCacheConfiguration must not be {@literal null}. Maybe just use
+     *                                  {@link RedisCacheConfiguration#defaultCacheConfig()}.
+     */
+    public RedisProcessor(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
+        super(cacheWriter, defaultCacheConfiguration);
+    }
+
+    /**
+     * Configuration hook for creating {@link RedisCache} with given name and {@code cacheConfig}.
+     * 配置自定义的创建redisCache
+     *
+     * @param name        must not be {@literal null}.
+     *                    这里规定name格式必须为
+     *                    <p>
+     *                    user#60或者user,#后代表过期时间单位分钟,如果不存在默认一个小时的过期时间
+     *                    </p>
+     *                    // TODO 2021-9-14 14:19:15 暂未配置一个缓存多个名称的处理 所以暂定该项目缓存使用单命名方式,可以为每个缓存时间加上一个随机时间 防止同事失效造成缓存雪崩
+     * @param cacheConfig can be {@literal null}.
+     * @return never {@literal null}.
+     */
+    @Override
+    protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
+
+        String[] array = StrUtil.splitToArray(name, "#");
+        name = array[0];
+        cacheConfig = cacheConfig.entryTtl(Duration.ofMinutes(60));
+        if (array.length > 1) {
+            long ttl = Long.parseLong(array[1]);
+            cacheConfig = cacheConfig.entryTtl(Duration.ofMinutes(ttl));
+        }
+        return super.createRedisCache(name, cacheConfig);
+    }
+
+}

+ 101 - 0
src/main/java/com/example/demo/constants/NumberConstant.java

@@ -0,0 +1,101 @@
+package com.example.demo.constants;
+
+/**
+ * 数字设置
+ */
+public final class NumberConstant {
+    public NumberConstant() {
+    }
+
+    /**
+     * 零
+     */
+    public static final Long ZERO_L = 0L;
+    public static final Integer ZERO = 0;
+    public static final String ZERO_S = "0";
+    /**
+     * 一
+     */
+    public static final Integer ONE = 1;
+
+    /**
+     * 二
+     */
+    public static final Integer TWO = 2;
+
+    /**
+     * 三
+     */
+    public static final Integer THREE = 3;
+
+    /**
+     * 四
+     */
+    public static final Integer FOUR = 4;
+
+    /**
+     * 五
+     */
+    public static final Integer FIVE = 5;
+
+    /**
+     * 六
+     */
+    public static final Integer SIX = 6;
+
+    /**
+     * 七
+     */
+    public static final Integer SEVEN = 7;
+
+    /**
+     * 八
+     */
+    public static final Integer EIGHT = 8;
+
+    /**
+     * 九
+     */
+    public static final Integer NINE = 9;
+
+    /**
+     * 10
+     */
+    public static final Integer TEN = 10;
+
+    /**
+     * 二十四
+     */
+    public static final Integer TWENTY_FOUR = 24;
+
+    /**
+     * 三十
+     */
+    public static final Integer THIRTY = 30;
+
+    /**
+     * 五十八
+     */
+    public static final Integer FIFTY_EIGHT = 58;
+
+    /**
+     * 五十九
+     */
+    public static final Integer FIFTY_NINE = 59;
+
+    /**
+     * 一百
+     */
+    public static final Integer ONE_HUNDRED = 100;
+    /**
+     * 一千
+     */
+    public static final Integer ONE_THOUSAND = 1000;
+
+    /**
+     * 负一
+     */
+    public static final Integer NEGATIVE = -1;
+
+
+}

+ 60 - 0
src/main/java/com/example/demo/controller/DemoController.java

@@ -0,0 +1,60 @@
+package com.example.demo.controller;
+
+import com.example.demo.dao.model.Test;
+import com.example.demo.service.DemoService;
+import com.example.demo.util.Result;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @program: center-parent
+ * @description:
+ * @author: Wang.YS
+ * @create: 2023-11-30 20:13
+ **/
+
+@RestController
+@RequestMapping("/demo")
+@Api(tags = "测试相关接口")
+@AllArgsConstructor
+public class DemoController {
+
+    DemoService demoService;
+    @ApiOperation("测试-新增")
+    public Result testAdd(@RequestBody Test request){
+        demoService.testAdd(request);
+        return Result.ok();
+    }
+    @ApiOperation("测试-编辑")
+    public Result testEdit(@RequestBody Test request){
+        demoService.testEdit(request);
+        return Result.ok();
+    }
+
+    @ApiOperation("测试-删除")
+    public Result testDelete(@RequestParam Integer id){
+        demoService.testDelete(id);
+        return Result.ok();
+    }
+
+    @ApiOperation("测试-查询")
+    public Result testQuery(@RequestParam(required = false,value = "name") String name){
+        return Result.ok(demoService.testQuery(name));
+    }
+    @ApiOperation("测试-分页查询")
+    public Result testPage(@RequestParam(required = false,value = "current",defaultValue = "1")Integer current,
+                           @RequestParam(required = false,value = "pageSize",defaultValue = "10")Integer pageSize,
+                           @RequestParam(required = false,value = "name") String name){
+
+        return Result.ok(demoService.testPage(current,pageSize,name));
+    }
+
+
+
+
+}

+ 16 - 0
src/main/java/com/example/demo/dao/mapper/TestMapper.java

@@ -0,0 +1,16 @@
+package com.example.demo.dao.mapper;
+
+import com.example.demo.dao.model.Test;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 
+ * 
+ * @author Wang.YS
+ * @date 2023-12-11 11:25:38
+ */
+@Mapper
+public interface TestMapper extends BaseMapper<Test> {
+	
+}

+ 77 - 0
src/main/java/com/example/demo/dao/model/Test.java

@@ -0,0 +1,77 @@
+package com.example.demo.dao.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 
+ * 
+ * @author Wang.YS
+
+ * @date 2023-12-11 11:25:38
+ */
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@TableName("test")
+public class Test implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 主键
+	 */
+	@TableId
+	private Integer id;
+	/**
+	 * 代码
+	 */
+	private String code;
+	/**
+	 * 名称
+	 */
+	private String name;
+	/**
+	 * 值
+	 */
+	private String value;
+	/**
+	 * 创建人
+	 */
+	private String createUser;
+	/**
+	 * 创建时间
+	 */
+	private Date createTime;
+	/**
+	 * 修改人
+	 */
+	private String updateUser;
+	/**
+	 * 修改时间
+	 */
+	private Date updateTime;
+	/**
+	 * 删除人
+	 */
+	private String deleteUser;
+	/**
+	 * 删除时间
+	 */
+	private Date deleteTime;
+	/**
+	 * 作废标志 0正常 1作废
+	 */
+	@TableLogic(value = "0",delval = "1")
+	private Integer delFlag;
+
+}

+ 40 - 0
src/main/java/com/example/demo/dao/repository/TestRepository.java

@@ -0,0 +1,40 @@
+package com.example.demo.dao.repository;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.example.demo.dao.mapper.TestMapper;
+import com.example.demo.dao.model.Test;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.StringUtils;
+
+import java.util.List;
+
+/**
+ * @program: kcim-demo
+ * @description:
+ * @author: Wang.YS
+ * @create: 2023-12-11 11:27
+ **/
+@Repository
+public class TestRepository extends ServiceImpl<TestMapper, Test> {
+    public List<Test> getList(String name) {
+        LambdaQueryWrapper<Test> queryWrapper = new LambdaQueryWrapper<>();
+
+        if(StringUtils.isEmpty(name)){
+            queryWrapper.like(Test::getName,name);
+        }
+       return this.list(queryWrapper);
+    }
+
+    public Page<Test> getPage(Integer current, Integer pageSize, String name) {
+        Page<Test> page = new Page<>(current,pageSize);
+        LambdaQueryWrapper<Test> queryWrapper = new LambdaQueryWrapper<>();
+
+        if(StringUtils.isEmpty(name)){
+            queryWrapper.like(Test::getName,name);
+        }
+      return  this.page(page,queryWrapper);
+
+    }
+}

+ 50 - 0
src/main/java/com/example/demo/endpoint/CenterEndPoint.java

@@ -0,0 +1,50 @@
+package com.example.demo.endpoint;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * @program: pfm_manager
+ * @description: 中台方法调用
+ * @author: Wang.YS
+ * @create: 2023-10-11 14:38
+ **/
+@FeignClient(name = "center-provider")
+@RequestMapping("centerSys")
+public interface CenterEndPoint {
+
+    /**
+     * 中台获取用户信息
+     *
+     * @return 用户信息
+     */
+    @GetMapping("/api/getUser")
+    Object getUserInfo(@RequestParam(required = false,name = "filter") String filter);
+
+    @GetMapping("/api/getDict")
+    Object getDict(@RequestParam(required = false,name = "dictType")String dictType,
+                   @RequestParam(required = false,name="systemId") Long systemId);
+
+
+    @GetMapping("/api/getAllDict")
+    Object getAllDict();
+
+    @GetMapping("/api/getAllDictBySystemId")
+    Object getAllDictBySystemId(@RequestParam(required = false,name="systemId") Long systemId);
+
+    @GetMapping("/api/getDepartment")
+    Object getDepartment();
+
+    @GetMapping("/api/getDepartmentFilter")
+    Object getDepartmentFilter(@RequestParam(required = false,name = "departName") String departName);
+
+
+    @GetMapping("/api/getParameter")
+    Object getParameter(@RequestParam(required = false,name = "systemId")Long systemId,
+                 @RequestParam(required = false,name="parameterCode") Long parameterCode);
+
+    @GetMapping("/api/getKCClass")
+    Object getKCClass(@RequestParam(required = false,name = "className") String className);
+}

+ 28 - 0
src/main/java/com/example/demo/nacosdiscovery/NacosDiscoveryConfiguration.java

@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.example.demo.nacosdiscovery;
+
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author <a href="mailto:chenxilzx1@gmail.com">theonefx</a>
+ */
+@EnableDiscoveryClient
+@Configuration
+public class NacosDiscoveryConfiguration {
+}

+ 21 - 0
src/main/java/com/example/demo/service/DemoService.java

@@ -0,0 +1,21 @@
+package com.example.demo.service;
+
+import com.example.demo.dao.model.Test;
+
+/**
+ * @program: center-parent
+ * @description:
+ * @author: Wang.YS
+ * @create: 2023-11-30 20:15
+ **/
+public interface DemoService {
+    void testAdd(Test request);
+
+    void testEdit(Test request);
+
+    void testDelete(Integer request);
+
+    Object testQuery(String name);
+
+    Object testPage(Integer current, Integer pageSize, String name);
+}

+ 106 - 0
src/main/java/com/example/demo/service/impl/DemoServiceImpl.java

@@ -0,0 +1,106 @@
+package com.example.demo.service.impl;
+
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.example.demo.constants.NumberConstant;
+import com.example.demo.dao.model.Test;
+import com.example.demo.dao.repository.TestRepository;
+import com.example.demo.service.DemoService;
+import com.example.demo.util.BeanUtil;
+import com.example.demo.util.PageUtils;
+import com.example.demo.util.UserContext;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * @program: center-parent
+ * @description:
+ * @author: Wang.YS
+ * @create: 2023-11-30 20:15
+ **/
+@Service("DemoService")
+@Slf4j
+@AllArgsConstructor
+public class DemoServiceImpl implements DemoService {
+    TestRepository repository;
+
+    /**
+     * 测试-新增
+     * @param request 入参
+     */
+    @Override
+    public void testAdd(Test request) {
+        request.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
+        request.setCreateTime(new Date());
+        repository.save(request);
+    }
+
+    /**
+     * 测试-编辑
+     * @param request 入参
+     */
+    @Override
+    public void testEdit(Test request) {
+        Integer id = request.getId();
+        Test byId = repository.getById(id);
+        if(Objects.nonNull(byId)){
+            Test test = BeanUtil.convertObj(request, byId);
+            test.setUpdateTime(new Date());
+            test.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId()));
+            repository.updateById(test);
+        }
+    }
+
+    /**
+     * 测试删除
+     * @param id 主键
+     */
+    @Override
+    public void testDelete(Integer id) {
+        Test byId = repository.getById(id);
+        if(Objects.nonNull(byId)){
+            byId.setUpdateTime(new Date());
+            byId.setUpdateUser(String.valueOf(UserContext.getCurrentUser().getId()));
+            repository.updateById(byId);
+            //逻辑删除 需要给del_flag 添加 @TableLogic(value = "0",delval = "1") 进行标识
+
+            repository.removeById(id);
+        }
+
+    }
+
+    /**
+     * 测试-查询
+     * @param name 名称过滤
+     * @return 符合条件的数据
+     */
+    @Override
+    public Object testQuery(String name) {
+       return repository.getList(name);
+    }
+
+    /**
+     * 测试分页查询
+     * @param current 当前页
+     * @param pageSize 页容量
+     * @param name 过滤名称
+     * @return 分页列表
+     */
+    @Override
+    public Object testPage(Integer current, Integer pageSize, String name) {
+        Page<Test> page = repository.getPage(current, pageSize, name);
+        if(CollectionUtils.isEmpty(page.getRecords())){
+           return new PageUtils(new ArrayList<>(), NumberConstant.ZERO,pageSize,current);
+        }
+        return new PageUtils(page.getRecords(), Math.toIntExact(page.getTotal()),pageSize,current);
+
+    }
+}

+ 106 - 0
src/main/java/com/example/demo/util/AesUtil.java

@@ -0,0 +1,106 @@
+package com.example.demo.util;
+
+import org.apache.commons.codec.binary.Base64;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * @author :lilei
+ * @date :Created in 2020/1/9 14:35
+ * @description:AES
+ */
+public class AesUtil {
+    // 密钥
+    public static String key = "&qsh9li1KxZa9la@";
+
+    private static String charset = "utf-8";
+    // 偏移量
+    private static int offset = 16;
+    // 加密器类型:加密算法为AES,加密模式为CBC,补码方式为PKCS5Padding
+    private static String transformation = "AES/CBC/PKCS5Padding";
+    // 算法类型:用于指定生成AES的密钥
+    private static String algorithm = "AES";
+
+    /**
+     * 加密
+     *
+     * @param content
+     * @return
+     */
+    public static String encrypt(String content) {
+        return encrypt(content, key);
+    }
+
+    /**
+     * 解密
+     *
+     * @param content
+     * @return
+     */
+    public static String decrypt(String content) {
+        return decrypt(content, key);
+    }
+
+    /**
+     * 加密
+     *
+     * @param content 需要加密的内容
+     * @param key     加密密码
+     * @return
+     */
+    private static String encrypt(String content, String key) {
+        try {
+            //构造密钥
+            SecretKeySpec skey = new SecretKeySpec(key.getBytes(), algorithm);
+            //创建初始向量iv用于指定密钥偏移量(可自行指定但必须为128位),因为AES是分组加密,下一组的iv就用上一组加密的密文来充当
+            IvParameterSpec iv = new IvParameterSpec(key.getBytes(), 0, offset);
+            //创建AES加密器
+            Cipher cipher = Cipher.getInstance(transformation);
+            byte[] byteContent = content.getBytes(charset);
+            //使用加密器的加密模式
+            cipher.init(Cipher.ENCRYPT_MODE, skey, iv);
+            // 加密
+            byte[] result = cipher.doFinal(byteContent);
+            //使用BASE64对加密后的二进制数组进行编码
+            return new Base64().encodeToString(result);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * AES(256)解密
+     *
+     * @param content 待解密内容
+     * @param key     解密密钥
+     * @return 解密之后
+     * @throws Exception
+     */
+    private static String decrypt(String content, String key) {
+        try {
+            SecretKeySpec skey = new SecretKeySpec(key.getBytes(), algorithm);
+            IvParameterSpec iv = new IvParameterSpec(key.getBytes(), 0, offset);
+            Cipher cipher = Cipher.getInstance(transformation);
+            //解密时使用加密器的解密模式
+            cipher.init(Cipher.DECRYPT_MODE, skey, iv);// 初始化
+            byte[] result = cipher.doFinal(new Base64().decode(content));
+            return new String(result); // 解密
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static void main(String[] args) {
+        String s = "admin";
+        String encryptResultStr = encrypt(s);
+        // 加密
+        System.out.println("加密前:" + s);
+        System.out.println("加密后:" + encryptResultStr);
+        // 解密
+        System.out.println("解密后:" + decrypt(encryptResultStr));
+    }
+}

+ 150 - 0
src/main/java/com/example/demo/util/BeanUtil.java

@@ -0,0 +1,150 @@
+package com.example.demo.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.lang.reflect.Field;
+import java.util.*;
+
+@Slf4j
+public final class BeanUtil {
+
+    /**
+     * 将对象转为为指定的对象
+     *
+     * @param source
+     * @param <T>
+     * @return
+     */
+    public static <T> T convertObj(Object source, Class<T> clazz) {
+        Object model = null;
+        if (source == null || clazz == null) {
+            return null;
+        }
+
+        try {
+            model = clazz.newInstance();
+        } catch (Exception e) {
+            log.error("将对象转为为指定的对象异常", e);
+        }
+        BeanUtils.copyProperties(source, model);
+        return (T) model;
+    }
+
+    public static <T> T convertObj(Object source, T result) {
+        BeanUtils.copyProperties(source, result);
+        return result;
+    }
+
+    public static <F, T> List<T> convertList(List<F> fromList, Class<T> tClass) {
+        List<T> tList = new ArrayList<>();
+        if (CollectionUtils.isEmpty(fromList)) {
+            return tList;
+        }
+        fromList.forEach(f -> tList.add(convertObj(f, tClass)));
+        return tList;
+    }
+
+    public static <F, T> List<T> convertListIgnoreCase(List<F> fromList, Class<T> clazz) {
+        List<T> tList = new ArrayList<>();
+        if (CollectionUtils.isEmpty(fromList)) {
+            return tList;
+        }
+        fromList.forEach(f -> {
+            try {
+                tList.add(copyIgnoreCase(f, clazz.newInstance()));
+            } catch (Exception e) {
+                log.error("将对象转为为指定的对象异常", e);
+            }
+        });
+        return tList;
+    }
+
+    /**
+     * 模仿Spring中 BeanUtils.copyProperties(source,target)
+     * 类型不同不可以转换
+     * 但是
+     * 大小写可以忽略
+     * 下划线 _ 被忽略
+     *
+     * @param source
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public static <T> T copyIgnoreCase(Object source, Class<T> clazz) {
+        try {
+            return copyIgnoreCase(source, clazz.newInstance());
+        } catch (Exception e) {
+            log.error("将对象转为为指定的对象异常", e);
+        }
+        return null;
+    }
+
+    /**
+     * 模仿Spring中 BeanUtils.copyProperties(source,target)
+     * 类型不同不可以转换
+     * 但是
+     * 大小写可以忽略
+     * 下划线 _ 被忽略
+     *
+     * @param source
+     * @param target
+     * @param <T>
+     * @return
+     */
+    public static <T> T copyIgnoreCase(Object source, T target) {
+        Map<String, Field> sourceMap = CacheFieldMap.getFieldMap(source.getClass());
+        CacheFieldMap.getFieldMap(target.getClass()).forEach((k, it) -> {
+            Field field = sourceMap.get(k);
+            if (field != null && field.getType().equals(it.getType())) {
+                it.setAccessible(true);
+                field.setAccessible(true);
+                try {
+                    it.set(target, field.get(source));
+                } catch (Exception e) {
+                    log.error("对象复制错误", e);
+                }
+            }
+        });
+        return target;
+    }
+
+    private static class CacheFieldMap {
+        private static Map<String, Map<String, Field>> cacheMap = new HashMap<>();
+
+        private static final String SER_STR = "serialVersionUID";
+
+        private static Map<String, Field> getFieldMap(Class clazz) {
+            final String name = clazz.getName();
+            Map<String, Field> result = cacheMap.get(name);
+            if (result != null) {
+                return result;
+            }
+            synchronized (name) {
+                if (result != null) {
+                    return result;
+                }
+                Map<String, Field> fieldMap = new HashMap<>();
+                for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
+                    Arrays.stream(clazz.getDeclaredFields()).forEach(field -> {
+                                //忽略序列号字段
+                                if (SER_STR.equals(field.getName())) {
+                                    return;
+                                }
+                                fieldMap.put(field.getName().toLowerCase().replace("_", ""), field);
+                            }
+                    );
+                }
+                cacheMap.put(name, fieldMap);
+                return fieldMap;
+            }
+        }
+    }
+
+    public static <T> T copyProperties(Object source, T result) {
+        BeanUtils.copyProperties(source, result);
+        return result;
+    }
+}

+ 49 - 0
src/main/java/com/example/demo/util/CommonUtil.java

@@ -0,0 +1,49 @@
+package com.example.demo.util;
+
+/**
+ * 通用工具类
+ */
+public class CommonUtil {
+
+    /**
+     * 校验字符串中括号是否闭合'[']'('')''{''}'
+     *
+     * @param str
+     * @return
+     */
+    public static boolean whetherStringClose(String str) {
+        int parenthesesNums = 0;//小括号数量
+        int bracketsNums = 0;//中括号数量
+        int bracesNums = 0;//大括号数量
+        for (int i = 0; i < str.length(); i++) {
+            char c = str.charAt(i);
+            if (c == '{') {
+                bracesNums += 1;
+            }
+            if (c == '[') {
+                bracketsNums += 1;
+            }
+            if (c == '(') {
+                parenthesesNums += 1;
+            }
+            if (c == '}') {
+                bracesNums -= 1;
+            }
+            if (c == ']') {
+                bracketsNums -= 1;
+            }
+            if (c == ')') {
+                parenthesesNums -= 1;
+            }
+            if (parenthesesNums < 0 || bracesNums < 0 || bracketsNums < 0) {
+                break;
+            }
+        }
+        if (parenthesesNums != 0 || bracesNums != 0 || bracketsNums != 0) {
+            return false;
+        } else {
+            return true;
+        }
+
+    }
+}

+ 1792 - 0
src/main/java/com/example/demo/util/DateUtils.java

@@ -0,0 +1,1792 @@
+package com.example.demo.util;
+
+import com.kcim.common.enums.DateStyleEnum;
+import com.kcim.common.enums.WeekEnum;
+import lombok.extern.slf4j.Slf4j;
+
+import java.sql.Timestamp;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@Slf4j
+public class DateUtils {
+    public static final SimpleDateFormat DATE_FORMAT_YYYY_MM_DD_HH_MM_SS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    public static final SimpleDateFormat monthSdf = new SimpleDateFormat("yyyy-MM");
+    public static final SimpleDateFormat yearSdf = new SimpleDateFormat("yyyy");
+    public static final SimpleDateFormat DATE_FORMAT_YYYY_MM_DD = new SimpleDateFormat("yyyy-MM-dd");
+
+    /**
+     * 通用的一个DateFormat
+     */
+    public final static SimpleDateFormat commonDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
+    /**
+     * 处理时分秒的DateFormat
+     */
+    public final static SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    /**
+     * 不显示秒的DateFormat
+     */
+    public final static SimpleDateFormat noSecondFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+
+
+    /**
+     * 获取SimpleDateFormat
+     *
+     * @param parttern 日期格式
+     * @return SimpleDateFormat对象
+     * @throws RuntimeException 异常:非法日期格式
+     */
+    private static SimpleDateFormat getDateFormat(String parttern) throws RuntimeException {
+        return new SimpleDateFormat(parttern);
+    }
+
+    /**
+     * 获取日期中的某数值。如获取月份
+     *
+     * @param date     日期
+     * @param dateType 日期格式
+     * @return 数值
+     */
+    public static int getInteger(Date date, int dateType) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        return calendar.get(dateType);
+    }
+
+    /**
+     * 当前时间转换.
+     *
+     * @return 时间字符串
+     */
+    public static String getDateString() {
+        Date date = new Date();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+        String strDate = sdf.format(date);
+        return strDate;
+    }
+
+    /**
+     * 获取时间的字符串
+     *
+     * @param date
+     * @param simpleDateFormat
+     * @return 时间字符串
+     */
+    public static String getDateString(Date date, SimpleDateFormat simpleDateFormat) {
+        String strDate = simpleDateFormat.format(date);
+        return strDate;
+    }
+
+    /**
+     * 增加日期中某类型的某数值。如增加日期
+     *
+     * @param date     日期字符串
+     * @param dateType 类型
+     * @param amount   数值
+     * @return 计算后日期字符串
+     */
+    private static String addInteger(String date, int dateType, int amount) {
+        String dateString = null;
+        DateStyleEnum dateStyle = getDateStyle(date);
+        if (dateStyle != null) {
+            Date myDate = StringToDate(date, dateStyle);
+            myDate = addInteger(myDate, dateType, amount);
+            dateString = DateToString(myDate, dateStyle);
+        }
+        return dateString;
+    }
+
+    /**
+     * 增加日期中某类型的某数值。如增加日期
+     *
+     * @param date     日期字符串
+     * @param dateType 类型
+     * @param amount   数值
+     * @return 计算后日期字符串
+     */
+    private static String addInteger(String date, DateStyleEnum dateStyle, int dateType, int amount) {
+        String dateString = null;
+        if (dateStyle != null) {
+            Date myDate = StringToDate(date, dateStyle);
+            myDate = addInteger(myDate, dateType, amount);
+            dateString = DateToString(myDate, dateStyle);
+        }
+        return dateString;
+    }
+
+    /**
+     * 增加日期中某类型的某数值。如增加日期
+     *
+     * @param date     日期
+     * @param dateType 类型
+     * @param amount   数值
+     * @return 计算后日期
+     */
+    private static Date addInteger(Date date, int dateType, int amount) {
+        Date myDate = null;
+        if (date != null) {
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(date);
+            calendar.add(dateType, amount);
+            myDate = calendar.getTime();
+        }
+        return myDate;
+    }
+
+    /**
+     * 获取本周开始时间
+     *
+     * @param date
+     *
+     * @return
+     */
+    public static Date getBeginDayOfWeek(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
+        if (dayofweek == 1) {
+            dayofweek += 7;
+        }
+        cal.add(Calendar.DATE, 2 - dayofweek);
+        return getDayStartTime(cal.getTime());
+    }
+
+    /**
+     * 获取某个日期的开始时间
+     *
+     * @param date
+     *
+     * @return
+     */
+    public static Timestamp getDayStartTime(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        if (null != date) {
+            calendar.setTime(date);
+        }
+        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+        return new Timestamp(calendar.getTimeInMillis());
+    }
+
+    /**
+     * 获取本周结束时间
+     *
+     * @param date
+     *
+     * @return
+     */
+    public static Date getEndDayOfWeek(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(getBeginDayOfWeek(date));
+        cal.add(Calendar.DAY_OF_WEEK, 6);
+        Date weekEndSta = cal.getTime();
+        return getDayEndTime(weekEndSta);
+    }
+
+    /**
+     * 获取某个日期的结束时间
+     *
+     * @param date
+     *
+     * @return
+     */
+    private static Date getDayEndTime(Date date) {
+        Calendar calendar = Calendar.getInstance();
+         if(null != date){
+             calendar.setTime(date);
+         }
+         calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),    calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
+         calendar.set(Calendar.MILLISECOND, 999);
+         return new Timestamp(calendar.getTimeInMillis());
+    }
+
+    /**
+     * 获取精确的日期
+     *
+     * @param timestamps 时间long集合
+     * @return 日期
+     */
+    private static Date getAccurateDate(List<Long> timestamps) {
+        Date date = null;
+        long timestamp = 0;
+        Map<Long, long[]> map = new HashMap<Long, long[]>();
+        List<Long> absoluteValues = new ArrayList<Long>();
+        if (timestamps != null && timestamps.size() > 0) {
+            if (timestamps.size() > 1) {
+                for (int i = 0; i < timestamps.size(); i++) {
+                    for (int j = i + 1; j < timestamps.size(); j++) {
+                        long absoluteValue = Math.abs(timestamps.get(i) - timestamps.get(j));
+                        absoluteValues.add(absoluteValue);
+                        long[] timestampTmp = {timestamps.get(i), timestamps.get(j)};
+                        map.put(absoluteValue, timestampTmp);
+                    }
+                }
+                // 有可能有相等的情况。如2012-11和2012-11-01。时间戳是相等的
+                long minAbsoluteValue = -1;
+                if (!absoluteValues.isEmpty()) {
+                    // 如果timestamps的size为2,这是差值只有一个,因此要给默认值
+                    minAbsoluteValue = absoluteValues.get(0);
+                }
+                for (int i = 0; i < absoluteValues.size(); i++) {
+                    for (int j = i + 1; j < absoluteValues.size(); j++) {
+                        if (minAbsoluteValue > absoluteValues.get(j)) {
+                            minAbsoluteValue = absoluteValues.get(j);
+                        }
+                    }
+                }
+                if (minAbsoluteValue != -1) {
+                    long[] timestampsLastTmp = map.get(minAbsoluteValue);
+                    if (absoluteValues.size() > 1) {
+                        timestamp = Math.max(timestampsLastTmp[0], timestampsLastTmp[1]);
+                    } else if (absoluteValues.size() == 1) {
+                        // 当timestamps的size为2,需要与当前时间作为参照
+                        long dateOne = timestampsLastTmp[0];
+                        long dateTwo = timestampsLastTmp[1];
+                        if ((Math.abs(dateOne - dateTwo)) < 100000000000L) {
+                            timestamp = Math.max(timestampsLastTmp[0], timestampsLastTmp[1]);
+                        } else {
+                            long now = new Date().getTime();
+                            if (Math.abs(dateOne - now) <= Math.abs(dateTwo - now)) {
+                                timestamp = dateOne;
+                            } else {
+                                timestamp = dateTwo;
+                            }
+                        }
+                    }
+                }
+            } else {
+                timestamp = timestamps.get(0);
+            }
+        }
+        if (timestamp != 0) {
+            date = new Date(timestamp);
+        }
+        return date;
+    }
+
+    /**
+     * 判断字符串是否为日期字符串
+     *
+     * @param date 日期字符串
+     * @return true or false
+     */
+    public static boolean isDate(String date) {
+        boolean isDate = false;
+        if (date != null) {
+            if (StringToDate(date) != null) {
+                isDate = true;
+            }
+        }
+        return isDate;
+    }
+
+
+    /**
+     * 获取日期字符串的日期风格。失敗返回null。
+     *
+     * @param date 日期字符串
+     * @return 日期风格
+     */
+    public static DateStyleEnum getDateStyle(String date) {
+        DateStyleEnum dateStyle = null;
+        Map<Long, DateStyleEnum> map = new HashMap<Long, DateStyleEnum>();
+        List<Long> timestamps = new ArrayList<Long>();
+        for (DateStyleEnum style : DateStyleEnum.values()) {
+            Date dateTmp = StringToDate(date, style.getValue());
+            if (dateTmp != null) {
+                timestamps.add(dateTmp.getTime());
+                map.put(dateTmp.getTime(), style);
+            }
+        }
+        dateStyle = map.get(getAccurateDate(timestamps).getTime());
+        return dateStyle;
+    }
+
+    /**
+     * 将日期字符串转化为日期。失败返回null。
+     *
+     * @param date 日期字符串
+     * @return 日期
+     */
+    public static Date StringToDate(String date) {
+        DateStyleEnum dateStyle = null;
+        return StringToDate(date, dateStyle);
+    }
+
+    /**
+     * 将日期字符串转化为日期。失败返回null。
+     *
+     * @param date     日期字符串
+     * @param parttern 日期格式
+     * @return 日期
+     */
+    public static Date StringToDate(String date, String parttern) {
+        Date myDate = null;
+        if (date != null) {
+            try {
+                myDate = getDateFormat(parttern).parse(date);
+            } catch (Exception e) {
+            }
+        }
+        return myDate;
+    }
+
+
+    /**
+     * 将日期字符串转化为日期。失败返回null。
+     *
+     * @param date      日期字符串
+     * @param dateStyle 日期风格
+     * @return 日期
+     */
+    public static Date StringToDate(String date, DateStyleEnum dateStyle) {
+        Date myDate = null;
+        if (dateStyle == null) {
+            List<Long> timestamps = new ArrayList<Long>();
+            for (DateStyleEnum style : DateStyleEnum.values()) {
+                Date dateTmp = StringToDate(date, style.getValue());
+                if (dateTmp != null) {
+                    timestamps.add(dateTmp.getTime());
+                }
+            }
+            myDate = getAccurateDate(timestamps);
+        } else {
+            myDate = StringToDate(date, dateStyle.getValue());
+        }
+        return myDate;
+    }
+
+    /**
+     * 将日期转化为日期字符串。失败返回null。
+     *
+     * @param date     日期
+     * @param parttern 日期格式
+     * @return 日期字符串
+     */
+    public static String DateToString(Date date, String parttern) {
+        String dateString = null;
+        if (date != null) {
+            try {
+                dateString = getDateFormat(parttern).format(date);
+            } catch (Exception e) {
+            }
+        }
+        return dateString;
+    }
+
+    /**
+     * 将日期转化为日期字符串。失败返回null。
+     *
+     * @param date      日期
+     * @param dateStyle 日期风格
+     * @return 日期字符串
+     */
+    public static String DateToString(Date date, DateStyleEnum dateStyle) {
+        String dateString = null;
+        if (dateStyle != null) {
+            dateString = DateToString(date, dateStyle.getValue());
+        }
+        return dateString;
+    }
+
+    /**
+     * 将日期字符串转化为另一日期字符串。失败返回null。
+     *
+     * @param date     旧日期字符串
+     * @param parttern 新日期格式
+     * @return 新日期字符串
+     */
+    public static String StringToString(String date, String parttern) {
+        return StringToString(date, null, parttern);
+    }
+
+    /**
+     * 将日期字符串转化为另一日期字符串。失败返回null。
+     *
+     * @param date      旧日期字符串
+     * @param dateStyle 新日期风格
+     * @return 新日期字符串
+     */
+    public static String StringToString(String date, DateStyleEnum dateStyle) {
+        return StringToString(date, null, dateStyle);
+    }
+
+    /**
+     * 将日期字符串转化为另一日期字符串。失败返回null。
+     *
+     * @param date         旧日期字符串
+     * @param olddParttern 旧日期格式
+     * @param newParttern  新日期格式
+     * @return 新日期字符串
+     */
+    public static String StringToString(String date, String olddParttern, String newParttern) {
+        String dateString = null;
+        if (olddParttern == null) {
+            DateStyleEnum style = getDateStyle(date);
+            if (style != null) {
+                Date myDate = StringToDate(date, style.getValue());
+                dateString = DateToString(myDate, newParttern);
+            }
+        } else {
+            Date myDate = StringToDate(date, olddParttern);
+            dateString = DateToString(myDate, newParttern);
+        }
+        return dateString;
+    }
+
+    /**
+     * 将日期字符串转化为另一日期字符串。失败返回null。
+     *
+     * @param date         旧日期字符串
+     * @param olddDteStyle 旧日期风格
+     * @param newDateStyle 新日期风格
+     * @return 新日期字符串
+     */
+    public static String StringToString(String date, DateStyleEnum olddDteStyle, DateStyleEnum newDateStyle) {
+        String dateString = null;
+        if (olddDteStyle == null) {
+            DateStyleEnum style = getDateStyle(date);
+            dateString = StringToString(date, style.getValue(), newDateStyle.getValue());
+        } else {
+            dateString = StringToString(date, olddDteStyle.getValue(), newDateStyle.getValue());
+        }
+        return dateString;
+    }
+
+    /**
+     * 增加日期的年份。失败返回null。
+     *
+     * @param date       日期
+     * @param yearAmount 增加数量。可为负数
+     * @return 增加年份后的日期字符串
+     */
+    public static String addYear(String date, int yearAmount) {
+        return addInteger(date, Calendar.YEAR, yearAmount);
+    }
+
+    /**
+     * 增加日期的年份。失败返回null。
+     *
+     * @param date       日期
+     * @param yearAmount 增加数量。可为负数
+     * @return 增加年份后的日期
+     */
+    public static Date addYear(Date date, int yearAmount) {
+        return addInteger(date, Calendar.YEAR, yearAmount);
+    }
+
+    /**
+     * 增加日期的月份。失败返回null。
+     *
+     * @param date       日期
+     * @param yearAmount 增加数量。可为负数
+     * @return 增加月份后的日期字符串
+     */
+    public static String addMonth(String date, int yearAmount) {
+        return addInteger(date, Calendar.MONTH, yearAmount);
+    }
+
+    /**
+     * 增加日期的月份。失败返回null。
+     *
+     * @param date       日期
+     * @param yearAmount 增加数量。可为负数
+     * @return 增加月份后的日期
+     */
+    public static Date addMonth(Date date, int yearAmount) {
+        return addInteger(date, Calendar.MONTH, yearAmount);
+    }
+
+    /**
+     * 增加日期的天数。失败返回null。
+     *
+     * @param date      日期字符串
+     * @param dayAmount 增加数量。可为负数
+     * @return 增加天数后的日期字符串
+     * @deprecated use {@link #addDay(String, int, DateStyleEnum)}
+     */
+    @Deprecated
+    public static String addDay(String date, int dayAmount) {
+        return addInteger(date, Calendar.DATE, dayAmount);
+    }
+
+    /**
+     * 增加日期的天数。失败返回null。
+     *
+     * @param date      日期字符串
+     * @param dayAmount 增加数量。可为负数
+     * @param style     日期样式
+     * @return 增加天数后的日期字符串
+     */
+    public static String addDay(String date, int dayAmount, DateStyleEnum style) {
+        return addInteger(date, style, Calendar.DATE, dayAmount);
+    }
+
+    /**
+     * 增加日期的天数。失败返回null。
+     *
+     * @param date      日期
+     * @param dayAmount 增加数量。可为负数
+     * @return 增加天数后的日期
+     */
+    public static Date addDay(Date date, int dayAmount) {
+        return addInteger(date, Calendar.DATE, dayAmount);
+    }
+
+    /**
+     * 增加日期的小时。失败返回null。
+     *
+     * @param date       日期字符串
+     * @param hourAmount 增加数量。可为负数
+     * @return 增加小时后的日期字符串
+     */
+    public static String addHour(String date, int hourAmount) {
+        return addInteger(date, Calendar.HOUR_OF_DAY, hourAmount);
+    }
+
+    /**
+     * 增加日期的小时。失败返回null。
+     *
+     * @param date       日期
+     * @param hourAmount 增加数量。可为负数
+     * @return 增加小时后的日期
+     */
+    public static Date addHour(Date date, int hourAmount) {
+        return addInteger(date, Calendar.HOUR_OF_DAY, hourAmount);
+    }
+
+    /**
+     * 增加日期的分钟。失败返回null。
+     *
+     * @param date       日期字符串
+     * @param hourAmount 增加数量。可为负数
+     * @return 增加分钟后的日期字符串
+     */
+    public static String addMinute(String date, int hourAmount) {
+        return addInteger(date, Calendar.MINUTE, hourAmount);
+    }
+
+    /**
+     * 增加日期的分钟。失败返回null。
+     *
+     * @param date       日期
+     * @param hourAmount 增加数量。可为负数
+     * @return 增加分钟后的日期
+     */
+    public static Date addMinute(Date date, int hourAmount) {
+        return addInteger(date, Calendar.MINUTE, hourAmount);
+    }
+
+    /**
+     * 增加日期的秒钟。失败返回null。
+     *
+     * @param date       日期字符串
+     * @param hourAmount 增加数量。可为负数
+     * @return 增加秒钟后的日期字符串
+     */
+    public static String addSecond(String date, int hourAmount) {
+        return addInteger(date, Calendar.SECOND, hourAmount);
+    }
+
+    /**
+     * 增加日期的秒钟。失败返回null。
+     *
+     * @param date       日期
+     * @param hourAmount 增加数量。可为负数
+     * @return 增加秒钟后的日期
+     */
+    public static Date addSecond(Date date, int hourAmount) {
+        return addInteger(date, Calendar.SECOND, hourAmount);
+    }
+
+    /**
+     * 获取日期的年份。失败返回0。
+     *
+     * @param date 日期字符串
+     * @return 年份
+     */
+    public static int getYear(String date) {
+        return getYear(StringToDate(date));
+    }
+
+    /**
+     * 获取日期的年份。失败返回0。
+     *
+     * @param date 日期
+     * @return 年份
+     */
+    public static int getYear(Date date) {
+        return getInteger(date, Calendar.YEAR);
+    }
+
+    /**
+     * 获取日期的月份。失败返回0。
+     *
+     * @param date 日期字符串
+     * @return 月份
+     */
+    public static int getMonth(String date) {
+        return getMonth(StringToDate(date));
+    }
+
+    /**
+     * 获取日期的月份
+     *
+     * @param date 日期字符串
+     * @return 月份
+     */
+    public static String getMonthStr(Date date) {
+        return monthSdf.format(date);
+    }
+
+    /**
+     * 获取日期的月份。失败返回0。
+     *
+     * @param date 日期
+     * @return 月份
+     */
+    public static int getMonth(Date date) {
+        return getInteger(date, Calendar.MONTH);
+    }
+
+    /**
+     * 获取日期的天数。失败返回0。
+     *
+     * @param date 日期字符串
+     * @return 天
+     */
+    public static int getDay(String date) {
+        return getDay(StringToDate(date));
+    }
+
+    /**
+     * 获取日期的天数。失败返回0。
+     *
+     * @param date 日期
+     * @return 天
+     */
+    public static int getDay(Date date) {
+        return getInteger(date, Calendar.DATE);
+    }
+
+    /**
+     * 获取日期的小时。失败返回0。
+     *
+     * @param date 日期字符串
+     * @return 小时
+     */
+    public static int getHour(String date) {
+        return getHour(StringToDate(date));
+    }
+
+    /**
+     * 获取日期的小时。失败返回0。
+     *
+     * @param date 日期
+     * @return 小时
+     */
+    public static int getHour(Date date) {
+        return getInteger(date, Calendar.HOUR_OF_DAY);
+    }
+
+    /**
+     * 获取日期的分钟。失败返回0。
+     *
+     * @param date 日期字符串
+     * @return 分钟
+     */
+    public static int getMinute(String date) {
+        return getMinute(StringToDate(date));
+    }
+
+    /**
+     * 获取日期的分钟。失败返回0。
+     *
+     * @param date 日期
+     * @return 分钟
+     */
+    public static int getMinute(Date date) {
+        return getInteger(date, Calendar.MINUTE);
+    }
+
+    /**
+     * 获取日期的秒钟。失败返回0。
+     *
+     * @param date 日期字符串
+     * @return 秒钟
+     */
+    public static int getSecond(String date) {
+        return getSecond(StringToDate(date));
+    }
+
+    /**
+     * 获取日期的秒钟。失败返回0。
+     *
+     * @param date 日期
+     * @return 秒钟
+     */
+    public static int getSecond(Date date) {
+        return getInteger(date, Calendar.SECOND);
+    }
+
+    /**
+     * 获取日期 。默认yyyy-MM-dd格式。失败返回null。
+     *
+     * @param date 日期字符串
+     * @return 日期
+     */
+    public static String getDate(String date) {
+        return StringToString(date, DateStyleEnum.YYYY_MM_DD);
+    }
+
+    /**
+     * 获取日期。默认yyyy-MM-dd格式。失败返回null。
+     *
+     * @param date 日期
+     * @return 日期
+     */
+    public static String getDate(Date date) {
+        return DateToString(date, DateStyleEnum.YYYY_MM_DD);
+    }
+
+    /**
+     * 获取日期。默认yyyy-MM-dd HH:mm:ss格式。失败返回null。
+     *
+     * @param date 日期
+     * @return 日期
+     */
+    public static String getDateTime(Date date) {
+        return DateToString(date, DateStyleEnum.YYYY_MM_DD_HH_MM_SS);
+    }
+
+    /**
+     * 获取日期。默认yyyy-MM-dd HH:mm格式。失败返回null。
+     *
+     * @param date 日期
+     * @return 日期
+     */
+    public static String getDateTimeExcludeSec(Date date) {
+        return DateToString(date, DateStyleEnum.YYYY_MM_DD_HH_MM);
+    }
+
+    /**
+     * 获取日期。默认yyyy-MM-dd HH:mm格式。失败返回null。
+     *
+     * @param date 日期
+     * @return 日期
+     */
+    public static Date getDateTimeExcludeSec(String date) {
+        return StringToDate(date, DateStyleEnum.YYYY_MM_DD_HH_MM);
+    }
+
+    /**
+     * 获取日期的时间。默认HH:mm:ss格式。失败返回null。
+     *
+     * @param date 日期字符串
+     * @return 时间
+     */
+    public static String getTime(String date) {
+        return StringToString(date, DateStyleEnum.HH_MM_SS);
+    }
+
+    /**
+     * 获取日期的时间。默认HH:mm:ss格式。失败返回null。
+     *
+     * @param date 日期
+     * @return 时间
+     */
+    public static String getTime(Date date) {
+        return DateToString(date, DateStyleEnum.HH_MM_SS);
+    }
+
+    /**
+     * 获取日期的星期。失败返回null。
+     *
+     * @param date 日期字符串
+     * @return 星期
+     */
+    public static WeekEnum getWeek(String date) {
+        WeekEnum week = null;
+        DateStyleEnum dateStyle = getDateStyle(date);
+        if (dateStyle != null) {
+            Date myDate = StringToDate(date, dateStyle);
+            week = getWeek(myDate);
+        }
+        return week;
+    }
+
+    /**
+     * 获取日期的星期。失败返回null。
+     *
+     * @param date 日期
+     * @return 星期
+     */
+    public static WeekEnum getWeek(Date date) {
+        WeekEnum week = null;
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        int weekNumber = calendar.get(Calendar.DAY_OF_WEEK) - 1;
+        switch (weekNumber) {
+            case 0:
+                week = WeekEnum.SUNDAY;
+                break;
+            case 1:
+                week = WeekEnum.MONDAY;
+                break;
+            case 2:
+                week = WeekEnum.TUESDAY;
+                break;
+            case 3:
+                week = WeekEnum.WEDNESDAY;
+                break;
+            case 4:
+                week = WeekEnum.THURSDAY;
+                break;
+            case 5:
+                week = WeekEnum.FRIDAY;
+                break;
+            case 6:
+                week = WeekEnum.SATURDAY;
+                break;
+        }
+        return week;
+    }
+
+    /**
+     * 获取两个日期相差的天数
+     *
+     * @param date      日期字符串
+     * @param otherDate 另一个日期字符串
+     * @return 相差天数
+     */
+    public static int getIntervalDays(String date, String otherDate) {
+        return getIntervalDays(StringToDate(date), StringToDate(otherDate));
+    }
+
+    /**
+     * @param date      日期
+     * @param otherDate 另一个日期mingt
+     * @return 相差天数
+     */
+    public static int getIntervalDays(Date date, Date otherDate) {
+        //date = DateUtil.StringToDate(DateUtil.getDate(date));
+        long time = Math.abs(date.getTime() - otherDate.getTime());
+        long day = time / (24 * 60 * 60 * 1000);
+        return (int) day;
+    }
+
+
+    /**
+     * @param date
+     * @param otherDate
+     * @return 相差年数
+     */
+    public static long getIntervalYear(Date date, Date otherDate) {
+        Calendar cal = Calendar.getInstance();
+        int yearNow = cal.get(Calendar.YEAR);
+        cal.setTime(otherDate);
+        int yearOther = cal.get(Calendar.YEAR);
+        long year = yearNow - yearOther;
+        return year;
+    }
+
+    /**
+     * 获取月份差
+     *
+     * @param date
+     * @param otherDate
+     * @return
+     */
+    public static long getIntervalMonths(Date date, Date otherDate) {
+        long months;
+        Calendar cal = Calendar.getInstance();
+        int yearNow = cal.get(Calendar.YEAR);
+        int monthNow = cal.get(Calendar.MONTH);
+        cal.setTime(otherDate);
+        int yearOther = cal.get(Calendar.YEAR);
+        int monthOther = cal.get(Calendar.MONTH);
+        long year = yearNow - yearOther;
+        if (year >= 1) {
+            months = year * 12 + monthNow - monthOther;
+        } else {
+            months = monthNow - monthOther;
+        }
+
+
+        return months;
+    }
+
+    public static String getWeekFromDate(Date date) {
+        Calendar c = Calendar.getInstance();
+        c.setTime(date);
+        int week = c.get(Calendar.DAY_OF_WEEK);
+        switch (week) {
+            case 1:
+                return "星期日";
+            case 2:
+                return "星期一";
+            case 3:
+                return "星期二";
+            case 4:
+                return "星期三";
+            case 5:
+                return "星期四";
+            case 6:
+                return "星期五";
+            case 7:
+                return "星期六";
+            default:
+                return "";
+        }
+    }
+
+    /**
+     * 获取指定天数之前的时间(相对于当前天数)
+     *
+     * @param currentDate 当前时间
+     * @param dayNo       当前时间的几天之前
+     * @return
+     * @Title: getLastDays
+     * @date 2014-3-26 下午11:23:57
+     * @author Lawrence
+     */
+    public static Date getLastTimeForDays(Date currentDate, Integer dayNo) {
+        if (null == currentDate || null == dayNo) {
+            return null;
+        }
+        Calendar c = Calendar.getInstance();
+        c.setTime(currentDate);
+        c.add(Calendar.DATE, -dayNo);
+        return c.getTime();
+    }
+
+    /**
+     * 获取指定月数之前的时间(相对于当前天数)
+     *
+     * @param currentDate 当前时间
+     * @param monthNo     当前时间的几月之前
+     * @return
+     * @Title: getLastDays
+     * @date 2014-3-26 下午11:23:57
+     * @author Lawrence
+     */
+    public static Date getLastTimeForMonths(Date currentDate, Integer monthNo) {
+        if (null == currentDate || null == monthNo) {
+            return null;
+        }
+        Calendar c = Calendar.getInstance();
+        c.setTime(currentDate);
+        c.add(Calendar.MONTH, -monthNo);
+        return c.getTime();
+    }
+
+    /**
+     * 获取指定月数之前的时间(相对于当前天数)
+     *
+     * @param currentDate 当前时间
+     * @param yearNo      当前时间的几年之前
+     * @return
+     * @Title: getLastDays
+     * @date 2014-3-26 下午11:23:57
+     * @author Lawrence
+     */
+    public static Date getLastTimeForYears(Date currentDate, Integer yearNo) {
+        Calendar c = Calendar.getInstance();
+        c.setTime(currentDate);
+        c.add(Calendar.YEAR, -yearNo);
+        return c.getTime();
+    }
+
+
+    /**
+     * 获取当天00:00:00
+     *
+     * @param currentDate
+     * @return
+     * @Title: getZeroPoint
+     * @Description: (这里用一句话描述这个方法的作用)
+     * @date 2014年10月10日 上午11:09:35
+     * @author Administrator
+     */
+    public static Date getZeroPoint(Date currentDate) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(currentDate);
+        cal.set(Calendar.HOUR_OF_DAY, 0); // 把当前时间小时变成0
+        cal.set(Calendar.MINUTE, 0); // 把当前时间分钟变成0
+        cal.set(Calendar.SECOND, 0); // 把当前时间秒数变成0
+        cal.set(Calendar.MILLISECOND, 0); // 把当前时间毫秒变成0
+        return cal.getTime();
+    }
+
+    /**
+     * 获取当天00:00:00
+     *
+     * @param currentDate
+     * @return
+     * @Title: getZeroPoint
+     * @Description: (这里用一句话描述这个方法的作用)
+     * @date 2014年10月10日 上午11:09:35
+     * @author Administrator
+     */
+    public static Date getZeroPoint(String currentDate) {
+        return getZeroPoint(DateUtils.StringToDate(currentDate, DateStyleEnum.YYYY_MM_DD));
+    }
+
+    /**
+     * 获取日期的最后一秒时间
+     *
+     * @param currentDate
+     * @return
+     */
+    public static Date getLastPoint(String currentDate) {
+        return getLastPoint(DateUtils.StringToDate(currentDate, DateStyleEnum.YYYY_MM_DD));
+    }
+
+    /**
+     * 获取日期的最后一秒时间
+     *
+     * @param currentDate
+     * @return
+     */
+    public static Date getLastPoint(Date currentDate) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(currentDate);
+        cal.set(Calendar.HOUR_OF_DAY, 23); // 把当前时间小时变成
+        cal.set(Calendar.MINUTE, 59); // 把当前时间分钟变成
+        cal.set(Calendar.SECOND, 59); // 把当前时间秒数变成
+        return cal.getTime();
+    }
+
+
+    /**
+     * 获取指定分钟最后一秒时间
+     *
+     * @param currentDate
+     * @return
+     */
+    public static Date getDateEndTime(Date currentDate) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(currentDate);
+        cal.set(Calendar.SECOND, 59); // 把当前时间秒数变成
+        return cal.getTime();
+    }
+
+    /**
+     * 获取指定分钟最后一秒时间
+     *
+     * @param currentDate
+     * @return
+     */
+    public static Date getDateBegTime(Date currentDate) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(currentDate);
+        cal.set(Calendar.SECOND, 00); // 把当前时间秒数变成
+        return cal.getTime();
+    }
+
+    /**
+     * 时间比较大小工具类
+     *
+     * @param date1
+     * @param date2
+     * @return
+     */
+    public static Boolean compareDate(Date date1, Date date2) {
+        try {
+            if (date1.getTime() >= date2.getTime()) {
+                return true;
+            } else if (date1.getTime() < date2.getTime()) {
+                return false;
+            }
+        } catch (Exception e) {
+            log.error(e.toString(), e);
+        }
+        return false;
+    }
+
+    /**
+     * 把毫秒转化成日期
+     *
+     * @param millSec(毫秒数)
+     * @return
+     */
+    public static Date LongToDate(Long millSec) {
+        return LongToDate(millSec, "yyyy-MM-dd HH:mm:ss");
+    }
+
+    /**
+     * 把毫秒转化成日期
+     *
+     * @param parttern(日期格式,例如:MM/ dd/yyyy HH:mm:ss)
+     * @param millSec(毫秒数)
+     * @return
+     */
+    public static Date LongToDate(Long millSec, String parttern) {
+        return new Date(millSec);
+    }
+
+/*    public static void main(String[] args){
+//    	Long currentTime = System.currentTimeMillis();
+//    	System.out.println(LongToDate(currentTime));
+    	
+        // Date currentDate = new Date();
+        // currentDate = getZeroPoint(currentDate);
+        // //得到一天前
+        // Date dd = getLastTimeForDays(currentDate, 1);
+        // System.out.println(dd.toLocaleString());
+        // //得到前一周
+        // Date dw = getLastTimeForDays(currentDate, 7);
+        // System.out.println(dw.toLocaleString());
+        // //得到前一个月
+        // Date dm = getLastTimeForMonths(currentDate, 1);
+        // System.out.println(dm.toLocaleString());
+        // //得到前一年
+        // Date dy = getLastTimeForYears(currentDate, 1);
+        // System.out.println(dy.toLocaleString());
+        String date = DateToString(new Date(), "yyyyMMddHHmmss");
+        System.out.println(date);
+        System.out.println(getZeroPoint(new Date()));
+    }*/
+
+    /**
+     * 截取时间getTime的后N位
+     *
+     * @param time 时间
+     * @return
+     * @Title: getTimeToSix
+     * @date 2016年9月21日 下午5:14:00
+     * @author Chris_He
+     */
+    public static String getTimeToNumber(Date time, Integer n) {
+        String s = String.valueOf(time.getTime());
+        return s.substring(s.length() - n, s.length());
+    }
+
+    /**
+     * 获取当前时间上下午
+     *
+     * @return
+     * @Title: getNowDateAmPm
+     * @date 2017年8月29日 下午5:08:37
+     * @author Chris_He
+     */
+    public static DateStyleEnum getNowDateAmPm() {
+        GregorianCalendar ca = new GregorianCalendar();
+        int i = ca.get(GregorianCalendar.AM_PM);
+        if (i == 0) {
+            return DateStyleEnum.AM;
+        } else {
+            return DateStyleEnum.PM;
+        }
+    }
+
+    public static Date getAfterMinuteDate(Date date, int amount) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.add(Calendar.MINUTE, amount);
+        date = cal.getTime();
+//        String theDate = sdf.format(date);
+        return date;
+    }
+
+    public static Date getAfterSecondDate(Date date, int amount) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.add(Calendar.SECOND, amount);
+        date = cal.getTime();
+//        String theDate = sdf.format(date);
+        return date;
+    }
+
+    public static String formatFull(Date date) {
+        if (date != null) {
+            return DATE_FORMAT_YYYY_MM_DD_HH_MM_SS.format(date);
+        }
+        return null;
+    }
+
+    /**
+     * 获取下一天00:00:00
+     *
+     * @return
+     * @Title: getNextDay
+     * @date 2018年12月22日 下午5:08:37
+     * @author Chris_He
+     */
+    public static Date getNextDay(Date date) {
+        return addDay(StringToDate(DateToString(date, DateStyleEnum.YYYY_MM_DD), DateStyleEnum.YYYY_MM_DD), 1);
+    }
+
+    public static void main(String[] args) {
+//        System.out.println(DateUtil.getYear(new Date()));
+        System.out.println(getHour("7:00"));
+    }
+
+
+    /**
+     * 获取下一天指定时间
+     *
+     * @return
+     * @Title: getNextDay
+     * @date 2018年12月22日 下午5:08:37
+     * @author Chris_He
+     */
+    public static Date getNextDayHour(Date date, int hour, int amount) {
+        Date myDate = null;
+        if (date != null) {
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(date);
+            calendar.add(Calendar.DATE, amount);
+            calendar.set(Calendar.HOUR_OF_DAY, hour); // 把当前时间小时变成0
+            calendar.set(Calendar.MINUTE, 0); // 把当前时间分钟变成0
+            calendar.set(Calendar.SECOND, 0); // 把当前时间秒数变成0
+            calendar.set(Calendar.MILLISECOND, 0); // 把当前时间毫秒变成0
+            myDate = calendar.getTime();
+        }
+        return myDate;
+    }
+
+    /**
+     * 获取yyyy-MM
+     *
+     * @return
+     */
+    public static String getMonthStr() {
+        return monthSdf.format(new Date());
+    }
+
+    /**
+     * 获取时间范围内所有天数 yyyy-MM-dd
+     *
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    public static List<Date> getDayList(String startDate, String endDate) {
+        Date dBegin = getZeroPoint(startDate);
+        Date dEnd = getZeroPoint(endDate);
+        List<Date> dateList = new ArrayList<>();
+        Calendar calBegin = Calendar.getInstance();
+        // 使用给定的 Date 设置此 Calendar 的时间
+        calBegin.setTime(dBegin);
+        Calendar calEnd = Calendar.getInstance();
+        // 使用给定的 Date 设置此 Calendar 的时间
+        calEnd.setTime(dEnd);
+        // 此日期是否在指定日期之后
+        dateList.add(dBegin);
+        while (dEnd.after(calBegin.getTime())) {
+            // 根据日历的规则,为给定的日历字段添加或减去指定的时间量
+            calBegin.add(Calendar.DAY_OF_MONTH, 1);
+            dateList.add(calBegin.getTime());
+        }
+        return dateList;
+    }
+
+    /**
+     * 获取时间范围内所有天 yyyy-MM-dd
+     *
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    public static List<Date> getDayList(Date startDate, Date endDate) {
+        Date dBegin = getZeroPoint(startDate);
+        Date dEnd = getZeroPoint(endDate);
+        List<Date> dateList = new ArrayList<>();
+        Calendar calBegin = Calendar.getInstance();
+        // 使用给定的 Date 设置此 Calendar 的时间
+        calBegin.setTime(dBegin);
+        Calendar calEnd = Calendar.getInstance();
+        // 使用给定的 Date 设置此 Calendar 的时间
+        calEnd.setTime(dEnd);
+        // 此日期是否在指定日期之后
+        dateList.add(dBegin);
+        while (dEnd.after(calBegin.getTime())) {
+            // 根据日历的规则,为给定的日历字段添加或减去指定的时间量
+            calBegin.add(Calendar.DAY_OF_MONTH, 1);
+            dateList.add(calBegin.getTime());
+        }
+        return dateList;
+    }
+
+    /**
+     * 获取时间范围内所有天 yyyy-MM-dd
+     *
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    public static List<String> getDayStrList(Date startDate, Date endDate) {
+        Date dBegin = getZeroPoint(startDate);
+        Date dEnd = getZeroPoint(endDate);
+        List<String> dateList = new ArrayList<>();
+        Calendar calBegin = Calendar.getInstance();
+        // 使用给定的 Date 设置此 Calendar 的时间
+        calBegin.setTime(dBegin);
+        Calendar calEnd = Calendar.getInstance();
+        // 使用给定的 Date 设置此 Calendar 的时间
+        calEnd.setTime(dEnd);
+        // 此日期是否在指定日期之后
+        dateList.add(getDate(dBegin));
+        while (dEnd.after(calBegin.getTime())) {
+            // 根据日历的规则,为给定的日历字段添加或减去指定的时间量
+            calBegin.add(Calendar.DAY_OF_MONTH, 1);
+            dateList.add(getDate(calBegin.getTime()));
+        }
+        return dateList;
+    }
+
+    /**
+     * 获取某个时间段内所有月份
+     *
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    public static List<Date> getMonthList(String startDate, String endDate) {
+        List<Date> result = new ArrayList<>();
+        Calendar min = Calendar.getInstance();
+        Calendar max = Calendar.getInstance();
+        min.setTime(StringToDate(startDate, DateStyleEnum.YYYY_MM));
+        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
+        max.setTime(StringToDate(endDate, DateStyleEnum.YYYY_MM));
+        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
+        Calendar curr = min;
+        while (curr.before(max)) {
+            result.add(curr.getTime());
+            curr.add(Calendar.MONTH, 1);
+        }
+        return result;
+    }
+
+    /**
+     * 1 第一季度 2 第二季度 3 第三季度 4 第四季度
+     *
+     * @param date
+     * @return
+     */
+    public static int getSeason(Date date) {
+
+        int season = 0;
+
+        Calendar c = Calendar.getInstance();
+        c.setTime(date);
+        int month = c.get(Calendar.MONTH);
+        switch (month) {
+            case Calendar.JANUARY:
+            case Calendar.FEBRUARY:
+            case Calendar.MARCH:
+                season = 1;
+                break;
+            case Calendar.APRIL:
+            case Calendar.MAY:
+            case Calendar.JUNE:
+                season = 2;
+                break;
+            case Calendar.JULY:
+            case Calendar.AUGUST:
+            case Calendar.SEPTEMBER:
+                season = 3;
+                break;
+            case Calendar.OCTOBER:
+            case Calendar.NOVEMBER:
+            case Calendar.DECEMBER:
+                season = 4;
+                break;
+            default:
+                break;
+        }
+        return season;
+    }
+
+    /**
+     * 取得季度月
+     *
+     * @param date
+     * @return
+     */
+    public static Date[] getSeasonDate(Date date) {
+        Date[] season = new Date[3];
+
+        Calendar c = Calendar.getInstance();
+        c.setTime(date);
+
+        int nSeason = getSeason(date);
+        if (nSeason == 1) {// 第一季度
+            c.set(Calendar.MONTH, Calendar.JANUARY);
+            season[0] = c.getTime();
+            c.set(Calendar.MONTH, Calendar.FEBRUARY);
+            season[1] = c.getTime();
+            c.set(Calendar.MONTH, Calendar.MARCH);
+            season[2] = c.getTime();
+        } else if (nSeason == 2) {// 第二季度
+            c.set(Calendar.MONTH, Calendar.APRIL);
+            season[0] = c.getTime();
+            c.set(Calendar.MONTH, Calendar.MAY);
+            season[1] = c.getTime();
+            c.set(Calendar.MONTH, Calendar.JUNE);
+            season[2] = c.getTime();
+        } else if (nSeason == 3) {// 第三季度
+            c.set(Calendar.MONTH, Calendar.JULY);
+            season[0] = c.getTime();
+            c.set(Calendar.MONTH, Calendar.AUGUST);
+            season[1] = c.getTime();
+            c.set(Calendar.MONTH, Calendar.SEPTEMBER);
+            season[2] = c.getTime();
+        } else if (nSeason == 4) {// 第四季度
+            c.set(Calendar.MONTH, Calendar.OCTOBER);
+            season[0] = c.getTime();
+            c.set(Calendar.MONTH, Calendar.NOVEMBER);
+            season[1] = c.getTime();
+            c.set(Calendar.MONTH, Calendar.DECEMBER);
+            season[2] = c.getTime();
+        }
+        return season;
+    }
+
+    /**
+     * 取得季度第一天
+     *
+     * @param date
+     * @return
+     */
+    public static Date getFirstDateOfSeason(Date date) {
+        return getFirstDateOfMonth(getSeasonDate(date)[0]);
+    }
+
+    /**
+     * 取得季度最后一天
+     *
+     * @param date
+     * @return
+     */
+    public static Date getLastDateOfSeason(Date date) {
+        return getLastDateOfMonth(getSeasonDate(date)[2]);
+    }
+
+    /**
+     * 取得月第一天
+     *
+     * @param date
+     * @return
+     */
+    public static Date getFirstDateOfMonth(Date date) {
+        Calendar c = Calendar.getInstance();
+        c.setTime(date);
+        c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(Calendar.DAY_OF_MONTH));
+        return c.getTime();
+    }
+
+    /**
+     * 取得月最后一天
+     *
+     * @param date
+     * @return
+     */
+    public static Date getLastDateOfMonth(Date date) {
+        Calendar c = Calendar.getInstance();
+        c.setTime(date);
+        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
+        return c.getTime();
+    }
+
+    /**
+     * 时间范围内的每个季度开始时间
+     *
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    public static List<Date> getSeasonDateList(Date startDate, Date endDate) {
+        List<Date> list = new ArrayList<>();
+        Date firstDateOfSeason = getFirstDateOfSeason(startDate);
+        list.add(firstDateOfSeason);
+        Date lastDateOfSeason = getFirstDateOfSeason(endDate);
+        Calendar c = Calendar.getInstance();
+        c.setTime(firstDateOfSeason);
+        while (c.getTime().before(lastDateOfSeason)) {
+            c.add(Calendar.MONTH, 3);
+            list.add(c.getTime());
+        }
+        return list;
+    }
+
+    /**
+     * 获取所在年第一天
+     *
+     * @param date
+     * @return
+     */
+    public static Date getFirstDayOfYear(Date date) {
+        final Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.set(Calendar.DAY_OF_YEAR, cal.getActualMinimum(Calendar.DAY_OF_YEAR));
+        return cal.getTime();
+    }
+
+    /**
+     * 获取所在年第一天
+     *
+     * @param
+     * @return
+     */
+    public static Date getFirstDayOfYear(String year) {
+        final Calendar cal = Calendar.getInstance();
+        cal.setTime(StringToDate(year, DateStyleEnum.YYYY));
+        cal.set(Calendar.DAY_OF_YEAR, cal.getActualMinimum(Calendar.DAY_OF_YEAR));
+        return cal.getTime();
+    }
+
+    /**
+     * 获取所在年最后一天
+     *
+     * @param date
+     * @return
+     */
+    public static Date getLastDayOfYear(Date date) {
+        final Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.set(Calendar.DAY_OF_YEAR, cal.getActualMaximum(Calendar.DAY_OF_YEAR));
+        return cal.getTime();
+    }
+
+    /**
+     * 获取所在年最后一天
+     *
+     * @param year
+     * @return
+     */
+    public static Date getLastDayOfYear(String year) {
+        final Calendar cal = Calendar.getInstance();
+        cal.setTime(StringToDate(year, DateStyleEnum.YYYY));
+        cal.set(Calendar.DAY_OF_YEAR, cal.getActualMaximum(Calendar.DAY_OF_YEAR));
+        return cal.getTime();
+    }
+
+    /**
+     * 时间范围内的每个年开始时间列表
+     *
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    public static List<Date> getYearDateList(Date startDate, Date endDate) {
+        List<Date> list = new ArrayList<>();
+        Date firstDate = getFirstDayOfYear(startDate);
+        list.add(firstDate);
+        Date lastDate = getFirstDayOfYear(endDate);
+        Calendar c = Calendar.getInstance();
+        c.setTime(firstDate);
+        while (c.getTime().before(lastDate)) {
+            c.add(Calendar.YEAR, 1);
+            list.add(c.getTime());
+        }
+        return list;
+    }
+
+
+    public static String getChineseDate(Date date) {
+        String chineseDate = null;
+        SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD");
+
+
+        return chineseDate;
+    }
+
+    public static StringBuilder getChineseTime(Date date) {
+        String sign;
+        StringBuilder chineseTime = new StringBuilder();
+        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
+        String time = sdf.format(date);
+
+        String[] split = time.split(":");
+
+
+        if(split[0].equals("00")){
+            chineseTime.append("零时");
+        }else{
+            String s = formatDigit(split[0]);
+            String substring1 = s.substring(0, 1);
+            String substring2 = s.substring(1, 2);
+            if(substring1.equals("零")){
+
+            }else if(substring1.equals("一")){
+                chineseTime.append("十");
+            }else{
+                chineseTime.append(substring1).append("十");
+            }
+
+            if(!substring2.equals("零")){
+                chineseTime.append(substring2);
+            }
+
+
+            chineseTime.append("时");
+
+        }
+
+        if(split[1].equals("00")){
+            chineseTime.append("整");
+        }else {
+
+            String s = formatDigit(split[1]);
+
+            String substring1 = s.substring(0, 1);
+            String substring2 = s.substring(1, 2);
+
+            if(substring1.equals("零")){
+
+            }else if(substring1.equals("一")){
+                chineseTime.append("十");
+            }else{
+                chineseTime.append(substring1).append("十");
+            }
+
+            if(!substring2.equals("零")){
+                chineseTime.append(substring2);
+            }
+
+
+
+            chineseTime.append("分");
+        }
+//
+
+        return chineseTime;
+    }
+
+
+    private static String formatDigit(String sign) {
+        StringBuilder sb = new StringBuilder();
+        for(int i=0;i<sign.length();i++){
+            String substring = sign.substring(i, i + 1);
+            switch (substring){
+                case "0":
+                    sb.append("零");
+                    break;
+                case "1":
+                    sb.append("一");
+                    break;
+                case "2":
+                    sb.append("二");
+                    break;
+                case "3":
+                    sb.append("三");
+                    break;
+                case "4":
+                    sb.append("四");
+                    break;
+                case "5":
+                    sb.append("五");
+                    break;
+                case "6":
+                    sb.append("六");
+                    break;
+                case "7":
+                    sb.append("七");
+                    break;
+                case "8":
+                    sb.append("八");
+                    break;
+                case "9":
+                    sb.append("九");
+                    break;
+            }
+
+
+        }
+
+        sign = sb.toString();
+
+
+        return sign;
+    }
+
+    /**
+     * 取出当前日期到指定日期的周数据差值
+     *
+     * @param date      指日 定日期
+     * @param otherDate 当前日期
+     * @return 周数差
+     */
+    public static long intervalWeeks(Date date, Date otherDate) {
+        int intervalDays = getIntervalDays(date, otherDate) + 1;
+        int i = intervalDays % 7;
+        long weekNum = Math.abs((date.getTime() - otherDate.getTime()) / (7 * 60 * 60 * 24 * 1000));
+
+        weekNum += 1;
+
+        return weekNum;
+
+
+    }
+
+    public static long intervalWeeks(String date, String otherDate) {
+        Date date1 = DateUtils.StringToDate(date, DateStyleEnum.YYYY_MM_DD);
+        Date date2 = DateUtils.StringToDate(otherDate, DateStyleEnum.YYYY_MM_DD);
+
+
+        return intervalWeeks(date1, date2);
+
+
+    }
+
+    /**
+     * 获取两个时间相差多少小时多少分钟
+     *
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    public static String getDistanceHourMin(Date startTime, Date endTime) {
+        long hour = 0;
+        long min = 0;
+        try {
+            long time1 = startTime.getTime();
+            long time2 = endTime.getTime();
+            long diff;
+            if (time1 < time2) {
+                diff = time2 - time1;
+            } else {
+                diff = time1 - time2;
+            }
+            hour = (diff / (60 * 60 * 1000));
+            min = ((diff / (60 * 1000)) - hour * 60);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return hour + "小时" + min + "分";
+    }
+
+    public static Date getDateHourMin(Date date) {
+        if (date == null) {
+            return null;
+        }
+        return StringToDate(DateToString(date, DateStyleEnum.YYYY_MM_DD_HH_MM), DateStyleEnum.YYYY_MM_DD_HH_MM);
+    }
+
+    /**
+     * 判断一个日期是否是周六、周日
+     * @param date
+     * @return
+     * @throws ParseException
+     */
+    public static int isWeekend(String date) throws ParseException {
+        DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
+        Date bdate = format1.parse(date);
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(bdate);
+        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+}

+ 74 - 0
src/main/java/com/example/demo/util/ErrorResult.java

@@ -0,0 +1,74 @@
+package com.example.demo.util;
+
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+public class ErrorResult {
+
+    private Boolean success;
+
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    private Object data;
+
+    private Integer errorCode;
+
+    private String errorMessage;
+
+    private Integer showType;
+
+    public ErrorResult(Integer errorCode, String errorMessage) {
+        this.success = false;
+        this.data = null;
+        this.errorCode = errorCode;
+        this.errorMessage = errorMessage;
+        this.showType = 4;
+    }
+
+    public static ErrorResult errorMsg(Integer errorCode, String errorMessage) {
+        return new ErrorResult(errorCode, errorMessage);
+    }
+
+    public Boolean getSuccess() {
+        return success;
+    }
+
+    public void setSuccess(Boolean success) {
+        this.success = success;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+    public Integer getErrorCode() {
+        return errorCode;
+    }
+
+    public void setErrorCode(Integer errorCode) {
+        this.errorCode = errorCode;
+    }
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage) {
+        this.errorMessage = errorMessage;
+    }
+
+    public Integer getShowType() {
+        return showType;
+    }
+
+    public void setShowType(Integer showType) {
+        this.showType = showType;
+    }
+}

+ 192 - 0
src/main/java/com/example/demo/util/JacksonUtil.java

@@ -0,0 +1,192 @@
+package com.example.demo.util;
+
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * spring自带的jackson(json)工具类
+ */
+@Slf4j
+public class JacksonUtil {
+    private static ObjectMapper objectMapper = new ObjectMapper();
+    // 日起格式化
+    private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";
+
+    // 以下静态初始化可以根据需求去掉对应的
+    static {
+        //对象的所有字段全部列入
+        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
+        //取消默认转换timestamps形式
+        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+        //忽略空Bean转json的错误
+        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+        //所有的日期格式都统一为以下的样式,即yyyy-MM-dd HH:mm:ss
+        objectMapper.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT));
+        //忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误
+        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+    }
+
+    /**
+     * 对象转json 字符串
+     *
+     * @param obj 对象
+     * @return Json格式字符串
+     */
+    public static <T> String obj2Str(T obj) {
+        try {
+            return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
+        } catch (JsonProcessingException e) {
+            log.error("parse object to string error {}", e.getMessage());
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 对象转Json格式字符串(格式化的Json字符串)
+     *
+     * @param obj 对象
+     * @return 美化的Json格式字符串
+     */
+    public static <T> String obj2StrPretty(T obj) {
+        if (obj == null) {
+            return null;
+        }
+        try {
+            return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
+        } catch (JsonProcessingException e) {
+            log.warn("Parse Object to String error : {}", e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * json字符串转对象
+     *
+     * @param str   json字符串
+     * @param clazz clazz对象
+     * @param <T>   泛型
+     * @return T
+     */
+    public static <T> T str2Obj(String str, Class<T> clazz) {
+        if (StrUtil.isBlank(str) || Objects.isNull(clazz)) {
+            log.error("parse string to object error : Params is null");
+            return null;
+        }
+        T t = null;
+
+        try {
+            t = clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        return t;
+    }
+
+    /**
+     * 字符串转List等集合类型使用
+     * 样例:
+     * *  JacksonUtil.string2ObjList(str,new TypeReference<List<User>>{})
+     *
+     * @param str           字符串
+     * @param typeReference 泛型包装
+     * @param <T>           泛型
+     * @return T
+     */
+    public static <T> T str2ObjList(String str, TypeReference<T> typeReference) {
+        if (StrUtil.isBlank(str) || Objects.isNull(typeReference)) {
+            log.error("parse string to object error : Params is null");
+            return null;
+        }
+        try {
+            return (T) (typeReference.getType().equals(String.class) ? str : objectMapper.readValue(str, typeReference));
+        } catch (JsonProcessingException e) {
+            log.warn("Parse String to Object error", e);
+            return null;
+        }
+    }
+
+    /**
+     * 字符串转List等集合类型使用
+     * 样例:
+     * JacksonUtil.string2ObjList(str,List.class,User.class)
+     *
+     * @param str             json字符串
+     * @param collectionClazz 集合class对象
+     * @param elementClazzs   元素class对象
+     * @param <T>             返回的类型
+     * @return T
+     */
+    public static <T> T str2ObjList(String str, Class<?> collectionClazz, Class<?>... elementClazzs) {
+        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClazz, elementClazzs);
+        try {
+            return objectMapper.readValue(str, javaType);
+        } catch (IOException e) {
+            log.warn("Parse String to Object error : {}" + e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * json字符串转为泛型 Map<String,Object>
+     * 可根据类型自己创建不同的泛型Map
+     *
+     * @param str json字符串
+     * @return
+     */
+    public static Map str2Map(String str) {
+        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(Map.class, String.class, Object.class);
+        try {
+            return objectMapper.readValue(str, javaType);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 构建json字符串
+     *
+     * @return json Str
+     */
+    public static JsonBuilder builder() {
+        return new JsonBuilder();
+    }
+
+
+    public static class JsonBuilder {
+        private Map<String, Object> map = new HashMap<>();
+
+        JsonBuilder() {
+        }
+
+        public JsonBuilder put(String key, Object value) {
+            map.put(key, value);
+            return this;
+        }
+
+        public String build() {
+            ObjectMapper objectMapper = new ObjectMapper();
+
+            try {
+                objectMapper.writeValueAsString(this.map);
+            } catch (JsonProcessingException e) {
+                e.printStackTrace();
+            }
+            return "{}";
+        }
+    }
+}

+ 140 - 0
src/main/java/com/example/demo/util/PageUtils.java

@@ -0,0 +1,140 @@
+package com.example.demo.util;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 分页工具类
+ *
+ * @author Mark sunlightcs@gmail.com
+ */
+public class PageUtils implements Serializable {
+	private static final long serialVersionUID = 1L;
+	/**
+	 * 总记录数
+	 */
+	private int totalCount;
+	/**
+	 * 每页记录数
+	 */
+	private int pageSize;
+	/**
+	 * 总页数
+	 */
+	private int totalPage;
+	/**
+	 * 当前页数
+	 */
+	private int current;
+	/**
+	 * 列表数据
+	 */
+	private List<?> list;
+
+	/**
+	 * 归集后的数据总额
+	 */
+	@JsonInclude(JsonInclude.Include.NON_NULL)
+	private BigDecimal totalAmount;
+	
+	/**
+	 * 分页
+	 * @param list        列表数据
+	 * @param totalCount  总记录数
+	 * @param pageSize    每页记录数
+	 * @param current    当前页数
+	 */
+	public PageUtils(List<?> list, int totalCount, int pageSize, int current) {
+		this.list = list;
+		this.totalCount = totalCount;
+		this.pageSize = pageSize;
+		this.current = current ;
+		this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
+	}
+
+	/**
+	 * 分页
+	 * @param list        列表数据
+	 * @param totalCount  总记录数
+	 * @param pageSize    每页记录数
+	 * @param current    当前页数
+	 * @param totalAmount  总金额
+	 */
+	public PageUtils(List<?> list, int totalCount, int pageSize, int current,BigDecimal totalAmount) {
+		this.list = list;
+		this.totalCount = totalCount;
+		this.pageSize = pageSize;
+		this.current = current ;
+		this.totalPage = (int)Math.ceil((double)totalCount/pageSize);
+		this.totalAmount = totalAmount;
+	}
+
+	/**
+	 * 分页
+	 */
+	public PageUtils(IPage<?> page) {
+		this.list = page.getRecords();
+		this.totalCount = (int)page.getTotal();
+		this.pageSize = (int)page.getSize();
+		this.current = (int)page.getCurrent();
+		this.totalPage = (int)page.getPages();
+	}
+
+	public int getTotalCount() {
+		return totalCount;
+	}
+
+	public void setTotalCount(int totalCount) {
+		this.totalCount = totalCount;
+	}
+
+	public int getPageSize() {
+		return pageSize;
+	}
+
+	public void setPageSize(int pageSize) {
+		this.pageSize = pageSize;
+	}
+
+	public int getTotalPage() {
+		return totalPage;
+	}
+
+	public void setTotalPage(int totalPage) {
+		this.totalPage = totalPage;
+	}
+
+	public int getCurrent() {
+		return current;
+	}
+
+	public void setCurrent(int current) {
+		this.current = current;
+	}
+
+	public List<?> getList() {
+		return list;
+	}
+
+	public void setList(List<?> list) {
+		this.list = list;
+	}
+
+	public static long getSerialVersionUID() {
+		return serialVersionUID;
+	}
+
+	public BigDecimal getTotalAmount() {
+		return totalAmount;
+	}
+
+	public void setTotalAmount(BigDecimal totalAmount) {
+		this.totalAmount = totalAmount;
+	}
+
+
+}

+ 63 - 0
src/main/java/com/example/demo/util/RedisLock.java

@@ -0,0 +1,63 @@
+package com.example.demo.util;
+
+import cn.hutool.core.util.StrUtil;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RedisLock {
+    private final StringRedisTemplate stringRedisTemplate;
+
+    public RedisLock(StringRedisTemplate stringRedisTemplate) {
+        this.stringRedisTemplate = stringRedisTemplate;
+    }
+
+    /**
+     * 加锁
+     * @param lockKey 加锁的Key
+     * @param timeStamp 时间戳:当前时间+超时时间
+     * @return
+     */
+    public boolean lock(String lockKey,String timeStamp){
+        if(stringRedisTemplate.opsForValue().setIfAbsent(lockKey, timeStamp)){
+            // 对应setnx命令,可以成功设置,也就是key不存在,获得锁成功
+            return true;
+        }
+
+        //设置失败,获得锁失败
+        // 判断锁超时 - 防止原来的操作异常,没有运行解锁操作 ,防止死锁
+        String currentLock = stringRedisTemplate.opsForValue().get(lockKey);
+        // 如果锁过期 currentLock不为空且小于当前时间
+        if(StrUtil.isNotEmpty(currentLock) && Long.parseLong(currentLock) < System.currentTimeMillis()){
+            //如果lockKey对应的锁已经存在,获取上一次设置的时间戳之后并重置lockKey对应的锁的时间戳
+            String preLock = stringRedisTemplate.opsForValue().getAndSet(lockKey, timeStamp);
+
+            //假设两个线程同时进来这里,因为key被占用了,而且锁过期了。
+            //获取的值currentLock=A(get取的旧的值肯定是一样的),两个线程的timeStamp都是B,key都是K.锁时间已经过期了。
+            //而这里面的getAndSet一次只会一个执行,也就是一个执行之后,上一个的timeStamp已经变成了B。
+            //只有一个线程获取的上一个值会是A,另一个线程拿到的值是B。
+            if(StrUtil.isNotEmpty(preLock) && preLock.equals(currentLock)){
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * 释放锁
+     * @param lockKey
+     * @param timeStamp
+     */
+    public void release(String lockKey,String timeStamp){
+        try {
+            String currentValue = stringRedisTemplate.opsForValue().get(lockKey);
+            if(!StrUtil.isEmpty(currentValue) && currentValue.equals(timeStamp) ){
+                // 删除锁状态
+                stringRedisTemplate.opsForValue().getOperations().delete(lockKey);
+            }
+        } catch (Exception e) {
+            System.out.println("警报!警报!警报!解锁异常");
+        }
+    }
+}

+ 107 - 0
src/main/java/com/example/demo/util/Result.java

@@ -0,0 +1,107 @@
+package com.example.demo.util;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kcim.common.enums.ResultCodeEnum;
+
+/**
+ * 统一封装返回对象
+ */
+public class Result {
+
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+    // 响应业务状态
+     private Integer code;
+
+     private Integer status;
+
+    // 响应消息
+     private String msg;
+
+    // 响应中的数据
+    private Object data;
+
+
+    @JsonIgnore
+    private String ok;	// 不使用
+
+    public static Result build(Integer status, String msg, Object data) {
+        return new Result(status, msg, data);
+    }
+    public static Result build(ResultCodeEnum codeEnum, Object data) {
+        Integer code = codeEnum.getCode();
+        String msg=codeEnum.getMessage();
+        return new Result(code, msg, data);
+    }
+
+    public static Result build(Integer status, String msg, Object data, String ok) {
+        return new Result(status, msg, data, ok);
+    }
+
+
+    public static Result ok(Object data) {
+        return new Result(data);
+    }
+
+    public static Result ok () {
+        return new Result(null);
+    }
+    public Result() {
+
+    }
+
+    public Result(Integer status, String msg, Object data) {
+        this.status = status;
+        this.msg = msg;
+        this.data = data;
+    }
+
+    public Result(Integer status, String msg, Object data, String ok) {
+        this.status = status;
+        this.msg = msg;
+        this.data = data;
+        this.ok = ok;
+    }
+
+    public Result(Object data) {
+        this.status = 200;
+        this.msg = "success";
+        this.data = data;
+    }
+
+    public Boolean isOK() {
+        return this.status == 200;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+    public String getOk() {
+        return ok;
+    }
+
+    public void setOk(String ok) {
+        this.ok = ok;
+    }
+}

+ 27 - 0
src/main/java/com/example/demo/util/SnowflakeUtil.java

@@ -0,0 +1,27 @@
+package com.example.demo.util;
+
+import cn.hutool.core.lang.Snowflake;
+import cn.hutool.core.util.IdUtil;
+
+/**
+ * @desc 雪花生成主键id可以拓展
+ * @version 1.0
+ * @Author hhz
+ * @time 2020/6/23
+ */
+public class SnowflakeUtil {
+    //成本 workid 3
+    // workId 和 datacenterId 暂定1
+    public static Long getId(){
+        Snowflake snowflake = IdUtil.getSnowflake(3, 1);
+        return snowflake.nextId();
+    }
+
+    public static void main(String[] args) {
+        for (int i = 0; i < 10; i++) {
+            System.out.println(getId());
+        }
+    }
+
+
+}

+ 30 - 0
src/main/java/com/example/demo/util/ThreadUtil.java

@@ -0,0 +1,30 @@
+package com.example.demo.util;
+
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.*;
+
+/**
+ * 线程池通用
+ */
+@Slf4j
+public class ThreadUtil {
+
+    private static ExecutorService executorService;
+    public static final int CPU_NUM = Runtime.getRuntime().availableProcessors();
+
+    public static synchronized ExecutorService getInstance() {
+        if (executorService == null) {
+            executorService = new ThreadPoolExecutor(
+                    CPU_NUM + 1,
+                    CPU_NUM * 2,
+                    10000,
+                    TimeUnit.MILLISECONDS,
+                    new LinkedBlockingQueue<Runnable>(),
+                    Executors.defaultThreadFactory()
+            );
+        }
+        return executorService;
+    }
+}

+ 33 - 0
src/main/java/com/example/demo/util/UserContext.java

@@ -0,0 +1,33 @@
+package com.example.demo.util;
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.example.demo.vo.SessionUserVO;
+
+
+/**
+ * @author 李加喜
+ * @Package
+ * @date 2021-08-03 8:46
+ */
+public class UserContext {
+    static String USER_PREFIX = "centerSys:";
+    /**
+     * 获取当前用户
+     */
+    public static SessionUserVO getCurrentUser() {
+        return (SessionUserVO) StpUtil.getSession().get(USER_PREFIX + StpUtil.getLoginId());
+    }
+
+    /**
+     * 获取当前用户所登录的医院id
+     */
+    public static Long getCurrentLoginHospId() {
+        SessionUserVO user = (SessionUserVO) StpUtil.getSession().get(USER_PREFIX + StpUtil.getLoginId());
+        return user.getHospId();
+    }
+
+    public static Long getHospId() {
+        SessionUserVO user = (SessionUserVO) StpUtil.getSession().get(USER_PREFIX + StpUtil.getLoginId());
+        return user.getHospId();
+    }
+}

+ 42 - 0
src/main/java/com/example/demo/vo/SessionUserVO.java

@@ -0,0 +1,42 @@
+package com.example.demo.vo;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @program: CostAccount
+ * @description:
+ * @author: Wang.YS
+ * @create: 2023-09-20 10:16
+ **/
+@Data
+@Accessors(chain = true)
+public class SessionUserVO {
+
+    /**
+     * 主键自增
+     */
+    @TableId
+    private Long id;
+    /**
+     * 用户名称
+     */
+    private String name;
+    /**
+     * 账号
+     */
+    private String account;
+
+    /**
+     * 当前用户所属的医院id(医院表主键)
+     */
+    private Long hospId;
+
+    /**
+     * 当前用户登录的医院id
+     */
+    private Long currentLoginHospId;
+
+    // TODO: 2022/1/4 按业务需求新增
+}

+ 121 - 0
src/main/resources/application.yml

@@ -0,0 +1,121 @@
+server:
+  #端口号
+  port: 8701
+  servlet:
+    #网关配置的路由 按项目自行调整
+    context-path: /medical
+spring:
+  datasource:
+    type: com.zaxxer.hikari.HikariDataSource
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://120.27.235.181:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
+    username: root
+    password: xywl2021!
+    hikari:
+      maximum-pool-size: 15
+      minimum-idle: 5
+      idle-timeout: 300000
+      connection-timeout: 300000
+      max-lifetime: 180000
+      auto-commit: true
+      connection-test-query: SELECT 1
+  application:
+    name: kcim-medical
+  cloud:
+    nacos: #注册nacos
+      discovery:
+        service: ${spring.application.name}
+        server-addr: 120.27.235.181:8848
+        namespace: 38b4fbe9-4a20-48c3-a8bf-ebf069fb26e8
+        group: KCIM
+    sentinel:
+      enabled: true
+      transport:
+        port: 8719
+        dashboard: 120.27.235.181:8080
+  jackson:
+    date-format: yyyy-MM-dd hh:mm:ss
+    time-zone: GMT+8
+  #    default-property-inclusion: non_null
+  #redis
+  redis:
+    port: 6379
+    host: 120.27.235.181
+    password: xywl2021!
+    jedis:
+      pool:
+        max-active: 30
+        max-idle: 10
+        max-wait: -1
+        min-idle: 0
+    database: 1
+mybatis-plus:
+  mapper-locations: classpath*:/mapper/*.xml
+  type-aliases-package: com.kcim.model
+  configuration:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+  global-config:
+    db-config:
+      id-type: auto
+      logic-not-delete-value: 0
+      logic-delete-value: UNIX_TIMESTAMP(NOW()) * 1000
+    banner: false
+    enable-sql-runner: true
+
+#日志
+# log config
+logging:
+
+  #  config: classpath:log4j2.xml
+  level:
+    io.swagger.models.parameters.AbstractSerializableParameter: error
+    org.springframework.web: error
+    org.hibernate.SQL: debug
+    org.hibernate.engine.QueryParameters: debug
+    org.hibernate.engine.query.HQLQueryPlan: debug
+    org.hibernate.type.descriptor.sql.BasicBinder: trace
+####本地文件相关配置
+#file:
+#  filelocal: file:/image/
+#  #linux
+#  #  serverPath: /image
+#  #windows
+#  serverPath: /file
+#  #local
+#  #  serverUrl: http://112.124.59.133:8082//
+#  #linux
+#  serverUrl: http://47.96.149.190:8082/
+sa-token:
+  jwt-secret-key: kcim-oauth
+  #  kcim-oauth
+  ## 前后端分离不设置会有奇怪的问题
+  ## 默认采用的获取token 是从请求头默认名称为Sa-token的地方获取,如果没有会从Cookie中获取,会造成奇怪的问题!!
+  token-name: token
+  is-read-cookie: false
+  is-read-body: false
+  ##token 有效期 默认30天,到期强制登录
+  timeout: 2592000
+  ## 30分钟无操作就失效 不适用
+  activity-timeout: 1800
+  # 配置 Sa-Token 单独使用的 Redis 连接
+  alone-redis:
+    # Redis数据库索引(默认为0) 先固定2,后续有钱开另外的单独的db
+    database: 1
+    # Redis服务器地址
+    host: 120.27.235.181
+    # Redis服务器连接端口
+    port: 6379
+    # Redis服务器连接密码(默认为空)
+    password: xywl2021!
+    # 连接超时时间
+    timeout: 10s
+  #    host: 118.31.245.65
+  #    password: xywl2021#
+
+  is-log: false
+minio:
+  url: http://47.97.198.219:9000
+  port: 9000
+  access-key: UOxpxcO0loqZqKzH
+  secret-key: KfHhDLRWL0PtaWW0JTXqz6Gn685P2EWY
+  bucket-name: kcim-medical

+ 22 - 0
src/main/resources/mapper/TestMapper.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.kcim.dao.mapper.TestMapper">
+
+	<!-- 可根据自己的需求,是否要使用 -->
+    <resultMap type="com.kcim.dao.model.Test" id="testMap">
+        <result property="id" column="id"/>
+        <result property="code" column="code"/>
+        <result property="name" column="name"/>
+        <result property="value" column="value"/>
+        <result property="createUser" column="create_user"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateUser" column="update_user"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="deleteUser" column="delete_user"/>
+        <result property="deleteTime" column="delete_time"/>
+        <result property="delFlag" column="del_flag"/>
+    </resultMap>
+
+
+</mapper>

+ 13 - 0
src/test/java/com/example/demo/DemoApplicationTests.java

@@ -0,0 +1,13 @@
+package com.example.demo;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class DemoApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}