fanfan il y a 4 ans
commit
9a2765d5b8
100 fichiers modifiés avec 5984 ajouts et 0 suppressions
  1. 32 0
      .gitignore
  2. 26 0
      README.md
  3. 310 0
      mvnw
  4. 182 0
      mvnw.cmd
  5. 248 0
      pom.xml
  6. 118 0
      pump-admin/.mvn/wrapper/MavenWrapperDownloader.java
  7. BIN
      pump-admin/.mvn/wrapper/maven-wrapper.jar
  8. 2 0
      pump-admin/.mvn/wrapper/maven-wrapper.properties
  9. 78 0
      pump-admin/pom.xml
  10. 26 0
      pump-admin/src/main/java/com/tuoren/TuorenApplication.java
  11. 49 0
      pump-admin/src/main/resources/application-dev.yml
  12. 58 0
      pump-admin/src/main/resources/application-prod.yml
  13. 50 0
      pump-admin/src/main/resources/application-test.yml
  14. 50 0
      pump-admin/src/main/resources/application.yml
  15. 25 0
      pump-admin/src/main/resources/banner.txt
  16. 27 0
      pump-admin/src/main/resources/converter/BusAnalgesicScoreEntity.properties
  17. 19 0
      pump-admin/src/main/resources/converter/BusHospitalEntity.properties
  18. 31 0
      pump-admin/src/main/resources/converter/BusPatientEntity.properties
  19. 48 0
      pump-admin/src/main/resources/converter/BusPumpEntity.properties
  20. 13 0
      pump-admin/src/main/resources/converter/ReadMe.txt
  21. 175 0
      pump-admin/src/main/resources/log/logback.xml
  22. 5 0
      pump-admin/src/main/resources/lua/del.lua
  23. 91 0
      pump-admin/src/main/resources/lua/getRedisMixed.lua
  24. 37 0
      pump-admin/src/main/resources/lua/redisBucket.lua
  25. 6 0
      pump-admin/src/main/resources/lua/setAndExpire.lua
  26. 23 0
      pump-common/pom.xml
  27. 27 0
      pump-common/src/main/java/com/tuoren/common/api/AopOrderEnum.java
  28. 113 0
      pump-common/src/main/java/com/tuoren/common/api/CommonResult.java
  29. 11 0
      pump-common/src/main/java/com/tuoren/common/api/IErrorCode.java
  30. 22 0
      pump-common/src/main/java/com/tuoren/common/api/ResultCode.java
  31. 35 0
      pump-common/src/main/java/com/tuoren/common/commponent/flowMonitor/FlowMonitorAutoConfiguration.java
  32. 16 0
      pump-common/src/main/java/com/tuoren/common/commponent/flowMonitor/FlowMonitorAutoConfigurationSelector.java
  33. 63 0
      pump-common/src/main/java/com/tuoren/common/commponent/flowMonitor/FlowMonitorMethodInterceptor.java
  34. 21 0
      pump-common/src/main/java/com/tuoren/common/commponent/flowMonitor/annotation/EnableFlowMonitor.java
  35. 40 0
      pump-common/src/main/java/com/tuoren/common/commponent/idempotent/IdempotentAutoConfiguration.java
  36. 20 0
      pump-common/src/main/java/com/tuoren/common/commponent/idempotent/IdempotentAutoConfigurationSelector.java
  37. 71 0
      pump-common/src/main/java/com/tuoren/common/commponent/idempotent/IdempotentMethodInterceptor.java
  38. 18 0
      pump-common/src/main/java/com/tuoren/common/commponent/idempotent/IdempotentProperties.java
  39. 21 0
      pump-common/src/main/java/com/tuoren/common/commponent/idempotent/annotation/EnableIdempotent.java
  40. 34 0
      pump-common/src/main/java/com/tuoren/common/commponent/idempotent/annotation/Idempotent.java
  41. 15 0
      pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/Interface/RateLimiter.java
  42. 20 0
      pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimitAutoConfigurationSelector.java
  43. 40 0
      pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimitMethodInterceptor.java
  44. 46 0
      pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimiterAutoConfigration.java
  45. 12 0
      pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimiterHandler/Interface/RateLimiterHandler.java
  46. 109 0
      pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimiterHandler/RedisBucketHandler.java
  47. 182 0
      pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimiterHandler/TokenBucketHandler.java
  48. 25 0
      pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimiterProperties.java
  49. 20 0
      pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/annotation/EnableRateLimit.java
  50. 21 0
      pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/annotation/RateLimit.java
  51. 37 0
      pump-common/src/main/java/com/tuoren/common/commponent/shiroLogin/ShiroLoginAutoConfiguration.java
  52. 20 0
      pump-common/src/main/java/com/tuoren/common/commponent/shiroLogin/ShiroLoginAutoConfigurationSelector.java
  53. 55 0
      pump-common/src/main/java/com/tuoren/common/commponent/shiroLogin/ShiroLoginMethodInterceptor.java
  54. 21 0
      pump-common/src/main/java/com/tuoren/common/commponent/shiroLogin/annotation/EnableWebShiro.java
  55. 24 0
      pump-common/src/main/java/com/tuoren/common/config/GlobalCorsConfig.java
  56. 60 0
      pump-common/src/main/java/com/tuoren/common/config/MvcConfig.java
  57. 23 0
      pump-common/src/main/java/com/tuoren/common/config/MybatisPlusConfig.java
  58. 82 0
      pump-common/src/main/java/com/tuoren/common/config/RedisConfig.java
  59. 59 0
      pump-common/src/main/java/com/tuoren/common/config/SSLConfig.java
  60. 61 0
      pump-common/src/main/java/com/tuoren/common/config/SwaggerConfig.java
  61. 29 0
      pump-common/src/main/java/com/tuoren/common/constant/CommonConstant.java
  62. 46 0
      pump-common/src/main/java/com/tuoren/common/entity/MvcEntity.java
  63. 31 0
      pump-common/src/main/java/com/tuoren/common/exception/ApiException.java
  64. 78 0
      pump-common/src/main/java/com/tuoren/common/exception/GlobalExceptionHandler.java
  65. 131 0
      pump-common/src/main/java/com/tuoren/common/mbg/CodeGenerator.java
  66. 21 0
      pump-common/src/main/java/com/tuoren/common/properties/MqttPushProperties.java
  67. 23 0
      pump-common/src/main/java/com/tuoren/common/push/BasePush.java
  68. 112 0
      pump-common/src/main/java/com/tuoren/common/push/Push.java
  69. 47 0
      pump-common/src/main/java/com/tuoren/common/push/PushJsonBean.java
  70. 41 0
      pump-common/src/main/java/com/tuoren/common/redis/RedisService.java
  71. 85 0
      pump-common/src/main/java/com/tuoren/common/redis/impl/RedisServiceImpl.java
  72. 57 0
      pump-common/src/main/java/com/tuoren/common/shiro/ShiroFilter.java
  73. 22 0
      pump-common/src/main/java/com/tuoren/common/shiro/ShiroSessionIdGenerator.java
  74. 42 0
      pump-common/src/main/java/com/tuoren/common/shiro/ShiroSessionManager.java
  75. 56 0
      pump-common/src/main/java/com/tuoren/common/utils/AESUtils.java
  76. 52 0
      pump-common/src/main/java/com/tuoren/common/utils/AsyncManager.java
  77. 120 0
      pump-common/src/main/java/com/tuoren/common/utils/ConstastUtils.java
  78. 49 0
      pump-common/src/main/java/com/tuoren/common/utils/DiffTimeUtils.java
  79. 18 0
      pump-common/src/main/java/com/tuoren/common/utils/LocalDateTimeUtil.java
  80. 35 0
      pump-common/src/main/java/com/tuoren/common/utils/RabbitUtil.java
  81. 29 0
      pump-common/src/main/java/com/tuoren/common/utils/SpringUtil.java
  82. 38 0
      pump-common/src/main/java/com/tuoren/common/utils/WebUtils.java
  83. 36 0
      pump-common/src/main/java/com/tuoren/common/utils/enums/LogType.java
  84. 137 0
      pump-common/src/main/resources/templates/controller2.java.btl
  85. 26 0
      pump-web/pom.xml
  86. 21 0
      pump-web/src/main/java/com/tuoren/web/commponent/config/CommponentConfig.java
  87. 39 0
      pump-web/src/main/java/com/tuoren/web/commponent/webLog/WebLogAutoConfigration.java
  88. 20 0
      pump-web/src/main/java/com/tuoren/web/commponent/webLog/WebLogAutoConfigurationSelector.java
  89. 94 0
      pump-web/src/main/java/com/tuoren/web/commponent/webLog/WebLogMethodInterceptor.java
  90. 20 0
      pump-web/src/main/java/com/tuoren/web/commponent/webLog/annotation/EnableWebLog.java
  91. 67 0
      pump-web/src/main/java/com/tuoren/web/commponent/webLog/javaBean/WebLog.java
  92. 59 0
      pump-web/src/main/java/com/tuoren/web/job/CommonJob.java
  93. 58 0
      pump-web/src/main/java/com/tuoren/web/job/InterfaceFlowStatisticsJob.java
  94. 94 0
      pump-web/src/main/java/com/tuoren/web/job/RemoveInvalidQueueJob.java
  95. 109 0
      pump-web/src/main/java/com/tuoren/web/job/SysConfigJob.java
  96. 266 0
      pump-web/src/main/java/com/tuoren/web/layer/controller/BusAnalgesicScoreController.java
  97. 151 0
      pump-web/src/main/java/com/tuoren/web/layer/controller/BusHospitalController.java
  98. 190 0
      pump-web/src/main/java/com/tuoren/web/layer/controller/BusLoginController.java
  99. 144 0
      pump-web/src/main/java/com/tuoren/web/layer/controller/BusPatientController.java
  100. 118 0
      pump-web/src/main/java/com/tuoren/web/layer/controller/BusProductController.java

+ 32 - 0
.gitignore

@@ -0,0 +1,32 @@
+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/
+/myLog

+ 26 - 0
README.md

@@ -0,0 +1,26 @@
+## 这里是 本项目的简单介绍
+
+
+### pump-admin 是存放项目的 启动类 使用的
+
+### pump-common 主要存放 公用配置 、组件 及 常量
+
+### pump-web 存放 mybatis CodeGenerator 生成关于数据库字段 实体、接口等
+
+
+
+### 目前情况是把 所有的 依赖放到了 根目录下,以后会根据使用情况进行分别整理
+
+### 另外开发分支如下
+
+- master
+    - dev
+        - lifang
+        - fanzihui
+        - wulianwei
+    - test
+    
+1. master 为 主   分支, 主要用于 生产环境,为最终版本
+2. dev    为 开发 分支, 主要用于 开发环境,最后合并到 master 分支上
+3. test   为 测试 分支, 主要用于 测试环境,此分支为 dev 分出,测试人员使用
+4. 姓名   为 各个 子分支, 平时分别再各自分支下进行开发使用,如有更新, 推送合并到 dev 分支

+ 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%

+ 248 - 0
pom.xml

@@ -0,0 +1,248 @@
+<?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>
+    <packaging>pom</packaging>
+
+    <groupId>com.tuoren</groupId>
+    <artifactId>netpump</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>netpump</name>
+    <description>Demo project for Spring Boot</description>
+
+
+    <modules>
+        <module>pump-common</module>
+        <module>pump-web</module>
+        <module>pump-admin</module>
+    </modules>
+
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.1.5.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+
+    <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.1.5.RELEASE</spring-boot.version>
+        <druid.version>1.1.21</druid.version>
+        <hutool.version>4.6.8</hutool.version>
+        <swagger2.version>2.6.1</swagger2.version>
+        <fastjson.version>1.2.62</fastjson.version>
+        <mybatisplus.version>3.2.0</mybatisplus.version>
+        <mybatisplusGenerator.version>3.2.0</mybatisplusGenerator.version>
+        <ibeetl.version>3.0.13.RELEASE</ibeetl.version>
+        <shiro.version>1.4.0</shiro.version>
+        <shiroRedis.version>3.1.0</shiroRedis.version>
+        <aliyunPush.version>3.13.0</aliyunPush.version>
+        <aliyunCore.version>4.3.2</aliyunCore.version>
+		<commonIo.version>2.6</commonIo.version>
+		<netty.version>4.1.36.Final</netty.version>
+        <rabbithttp.version>3.1.1.RELEASE</rabbithttp.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+            <version>${netty.version}</version>
+        </dependency>
+        <!-- 移动推送使用 Start -->
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-push</artifactId>
+            <version>${aliyunPush.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-core</artifactId>
+            <version>${aliyunCore.version}</version>
+        </dependency>
+        <!-- 移动推送使用 End -->
+        <!--面向切面 Start -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <!--面向切面 End -->
+        <!-- 模板引擎相关 Start -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ibeetl</groupId>
+            <artifactId>beetl</artifactId>
+            <version>${ibeetl.version}</version>
+        </dependency>
+        <!-- 模板引擎相关 End -->
+
+        <!--导入配置文件处理器 Start -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <!--导入配置文件处理器 End -->
+        <!--权限相关 Start -->
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-spring</artifactId>
+            <version>${shiro.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-core</artifactId>
+            <version>${shiro.version}</version>
+        </dependency>
+        <!-- Shiro-redis插件 -->
+        <dependency>
+            <groupId>org.crazycake</groupId>
+            <artifactId>shiro-redis</artifactId>
+            <version>${shiroRedis.version}</version>
+        </dependency>
+        <!--权限相关 End -->
+        <!-- Redis Start -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
+        </dependency>
+        <!-- Redis End -->
+        <!-- druid Start -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>${druid.version}</version>
+        </dependency>
+        <!-- druid End -->
+        <!-- hutool Start-->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>${hutool.version}</version>
+        </dependency>
+        <!-- hutool End -->
+        <!-- swagger2 生成接口文档 Start -->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>${swagger2.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>${swagger2.version}</version>
+        </dependency>
+        <!-- swagger2 生成接口文档 End -->
+        <!-- fastjson Start -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>${fastjson.version}</version>
+        </dependency>
+        <!-- fastjson End -->
+
+        <!--rabbit api远程调用-->
+        <dependency>
+            <groupId>com.rabbitmq</groupId>
+            <artifactId>http-client</artifactId>
+            <version>${rabbithttp.version}</version>
+        </dependency>
+
+        <!-- 文件监听 -->
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>${commonIo.version}</version>
+        </dependency>
+        <!-- 文件监听 -->
+        <!--mybatisplus 及批量生成 Start -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>${mybatisplus.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-generator</artifactId>
+            <version>${mybatisplusGenerator.version}</version>
+        </dependency>
+        <!--mybatisplus 及批量生成 End -->
+        <!-- 开发插件 Start -->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-devtools</artifactId>-->
+<!--            <scope>runtime</scope>-->
+<!--            <optional>true</optional>-->
+<!--        </dependency>-->
+        <!-- 开发插件 Start -->
+        <!-- mysql Start -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <!-- mysql End -->
+        <!-- rabbitmq 消息队列 Start -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-amqp</artifactId>
+        </dependency>
+        <!-- rabbitmq 消息队列 End -->
+        <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>
+    </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>-->
+<!--                <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>-->
+<!--            </plugin>-->
+<!--        </plugins>-->
+<!--    </build>-->
+
+</project>

+ 118 - 0
pump-admin/.mvn/wrapper/MavenWrapperDownloader.java

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

BIN
pump-admin/.mvn/wrapper/maven-wrapper.jar


+ 2 - 0
pump-admin/.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

+ 78 - 0
pump-admin/pom.xml

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>netpump</artifactId>
+        <groupId>com.tuoren</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+
+    <name>pump-admin</name>
+    <description>Demo project for Spring Boot</description>
+    <artifactId>pump-admin</artifactId>
+
+    <packaging>war</packaging>
+    <dependencies>
+        <!--&lt;!&ndash;        测试时把以下两个依赖注释&ndash;&gt;-->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-starter-web</artifactId>-->
+<!--            &lt;!&ndash; Maven整个生命周期内排除内置容器,排除内置容器导出成war包可以让外部容器运行spring-boot项目&ndash;&gt;-->
+<!--            <exclusions>-->
+<!--                <exclusion>-->
+<!--                    <groupId>org.springframework.boot</groupId>-->
+<!--                    <artifactId>spring-boot-starter-tomcat</artifactId>-->
+<!--                </exclusion>-->
+<!--            </exclusions>-->
+<!--        </dependency>-->
+
+<!--        <dependency>-->
+<!--            <groupId>javax.servlet</groupId>-->
+<!--            <artifactId>javax.servlet-api</artifactId>-->
+<!--            <version>3.1.0</version>-->
+<!--            <scope>provided</scope>-->
+<!--        </dependency>-->
+
+        <!--        测试时把以下两个依赖注释-->
+
+        <dependency>
+            <groupId>com.tuoren</groupId>
+            <artifactId>pump-common</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.tuoren</groupId>
+            <artifactId>pump-web</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration><!-- 指定该Main Class为全局的唯一入口 -->
+                    <mainClass>com.tuoren.TuorenApplication</mainClass>
+                    <layout>WAR</layout>
+                </configuration>
+                <!--<executions>-->
+                    <!--<execution>-->
+                        <!--<goals>-->
+                            <!--<goal>repackage</goal>&lt;!&ndash;可以把依赖的包都打包到生成的Jar包中&ndash;&gt;-->
+                        <!--</goals>-->
+                        <!--&lt;!&ndash;可以生成不含依赖包的不可执行Jar包&ndash;&gt;-->
+                        <!--&lt;!&ndash; configuration>-->
+                          <!--<classifier>exec</classifier>-->
+                        <!--</configuration> &ndash;&gt;-->
+                    <!--</execution>-->
+                <!--</executions>-->
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 26 - 0
pump-admin/src/main/java/com/tuoren/TuorenApplication.java

@@ -0,0 +1,26 @@
+package com.tuoren;
+
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+
+@SpringBootApplication
+@EnableScheduling
+public class TuorenApplication extends SpringBootServletInitializer {
+
+    public static void main(String[] args) {
+        SpringApplication.run(TuorenApplication.class,args);
+    }
+
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+        return application.sources(TuorenApplication.class);
+    }
+
+}

+ 49 - 0
pump-admin/src/main/resources/application-dev.yml

@@ -0,0 +1,49 @@
+# 开发环境
+spring:
+  profiles: dev
+  datasource:
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://192.168.1.137:3306/netpump?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
+    username: root
+    password: 123456
+    druid:
+      initial-size: 5 #连接池初始化大小
+      min-idle: 10 #最小空闲连接数
+      max-active: 20 #最大连接数
+      web-stat-filter:
+        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #不统计这些请求数据
+      stat-view-servlet: #访问监控网页的登录用户名和密码
+        login-username: druid
+        login-password: druid
+  redis:
+    host: 192.168.1.137 # Redis服务器地址
+    database: 0 # Redis数据库索引(默认为0)
+    port: 6379 # Redis服务器连接端口
+    password: root # Redis服务器连接密码(默认为空)
+    timeout: 6000 # 连接超时时间(毫秒
+    jedis:
+      pool:
+        max-active: 1000  # 连接池最大连接数(使用负值表示没有限制)
+        max-wait: -1      # 连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-idle: 10      # 连接池中的最大空闲连接
+        min-idle: 5       # 连接池中的最小空闲连接
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+    time-zone: GMT+8
+  rabbitmq:
+    host: 192.168.1.137
+    port: 5672
+    username: guest
+    password: guest
+    virtual-host: netpump
+    listener:
+      simple:
+        acknowledge-mode: none
+    #    publisher-confirms: true
+    publisher-returns: true
+  #日志
+logging:
+  config: classpath:log/logback.xml
+  path: D://logs/netpump-service
+server:
+  port: 8080

+ 58 - 0
pump-admin/src/main/resources/application-prod.yml

@@ -0,0 +1,58 @@
+#生产环境
+spring:
+  profiles: prod
+  datasource:
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://39.99.215.130:3306/netpump?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
+#    url: jdbc:mysql://127.0.0.1:3306/netpump?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
+    username: root
+    password: 123456
+    druid:
+      initial-size: 8 #连接池初始化大小
+      min-idle: 10 #最小空闲连接数
+      max-active: 20 #最大连接数
+      web-stat-filter:
+        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #不统计这些请求数据
+      stat-view-servlet: #访问监控网页的登录用户名和密码
+        login-username: druid
+        login-password: druid
+  redis:
+#    host: 172.18.0.1
+    host: 39.99.215.130
+#    host: 127.0.0.1
+    database: 0 # Redis数据库索引(默认为0)
+    port: 6379 # Redis服务器连接端口
+    password: 123456 # Redis服务器连接密码(默认为空)
+    timeout: 6000 # 连接超时时间(毫秒
+    jedis:
+      pool:
+        max-active: 1000  # 连接池最大连接数(使用负值表示没有限制)
+        max-wait: -1      # 连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-idle: 16      # 连接池中的最大空闲连接
+        min-idle: 8       # 连接池中的最小空闲连接
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+    time-zone: GMT+8
+  rabbitmq:
+    host:  39.99.215.130
+#    host: 118.190.103.83
+    port: 5672
+    username: guest
+    password: guest
+    virtual-host: netpump
+    listener:
+      simple:
+        acknowledge-mode: none
+    #    publisher-confirms: true
+    publisher-returns: true
+  #日志
+logging:
+  config: classpath:log/logback.xml
+  path: /usr/log/netpump-service
+  level:
+    root: info
+  file:
+    max-history: 10
+    max-size: 10
+server:
+  port: 8095

+ 50 - 0
pump-admin/src/main/resources/application-test.yml

@@ -0,0 +1,50 @@
+# 开发环境
+spring:
+  profiles: test
+  datasource:
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://39.99.215.130:3306/netpump?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
+    username: root
+    password: 123456
+    druid:
+      initial-size: 5 #连接池初始化大小
+      min-idle: 10 #最小空闲连接数
+      max-active: 20 #最大连接数
+      web-stat-filter:
+        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #不统计这些请求数据
+      stat-view-servlet: #访问监控网页的登录用户名和密码
+        login-username: druid
+        login-password: druid
+  redis:
+    host: 39.99.215.130 # Redis服务器地址
+    database: 0 # Redis数据库索引(默认为0)
+    port: 6379 # Redis服务器连接端口
+    password: root # Redis服务器连接密码(默认为空)
+    timeout: 6000 # 连接超时时间(毫秒
+    jedis:
+      pool:
+        max-active: 1000  # 连接池最大连接数(使用负值表示没有限制)
+        max-wait: -1      # 连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-idle: 10      # 连接池中的最大空闲连接
+        min-idle: 5       # 连接池中的最小空闲连接
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+    time-zone: GMT+8
+  rabbitmq:
+    #    host: 192.168.1.137
+    host: 118.190.103.83
+    port: 5672
+    username: root
+    password: root
+    virtual-host: netpump
+    listener:
+      simple:
+        acknowledge-mode: none
+    #    publisher-confirms: true
+    publisher-returns: true
+  #日志
+logging:
+  config: classpath:log/logback.xml
+  path: D://logs/netpump-service
+server:
+  port: 8080

+ 50 - 0
pump-admin/src/main/resources/application.yml

@@ -0,0 +1,50 @@
+spring:
+  profiles:
+    # 使用生产环境
+    active: prod
+  main:
+    allow-bean-definition-overriding: true
+mybatis-plus:
+  mapper-locations: classpath*:mapper/**/*Mapper.xml
+    #  global-config:
+    #字段策略 0:"忽略判断",1:"非 NULL 判断",2:"非空判断"
+    #    field-strategy: 0
+  #    db-config:
+  #主键类型 AUTO:"数据库ID自增" INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
+  #      id-type: auto
+  configuration:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+  type-handlers-package: com.tuoren.web.layer.mapper.handler
+#  global-config:
+#    db-config:
+#      update-strategy: ignored
+
+# shiro
+shiro:
+  hash-algorithm-name: md5
+  hash-iterations: 2
+  anon-urls:
+    - /index.html*
+    - /sys/toLogin*
+    - /login/**
+    - /login/getCode
+    - /resources/**
+    - /register/register*
+    - /swagger-ui.html
+    - /swagger-resources/**
+    - /v2/**
+    - /webjars/**
+    - /druid/**
+    - /css/**
+    - /js/**
+    - /user/login/**
+  login-url: /login.html
+  log-out-url: /logout*
+  authc-ulrs:
+    - /register
+file:
+  listener-time: 9000
+mqtt:
+  default-qos: 2
+  username: admin
+  password: public

+ 25 - 0
pump-admin/src/main/resources/banner.txt

@@ -0,0 +1,25 @@
+${AnsiColor.BRIGHT_YELLOW}
+////////////////////////////////////////////////////////////////////
+//                          _ooOoo_                               //
+//                         o8888888o                              //
+//                         88" . "88                              //
+//                         (| ^_^ |)                              //
+//                         O\  =  /O                              //
+//                      ____/`---'\____                           //
+//                    .'  \\|     |//  `.                         //
+//                   /  \\|||  :  |||//  \                        //
+//                  /  _||||| -:- |||||-  \                       //
+//                  |   | \\\  -  /// |   |                       //
+//                  | \_|  ''\---/''  |   |                       //
+//                  \  .-\__  `-`  ___/-. /                       //
+//                ___`. .'  /--.--\  `. . ___                     //
+//              ."" '<  `.___\_<|>_/___.'  >'"".                  //
+//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
+//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
+//      ========`-.____`-.___\_____/___.-`____.-'========         //
+//                           `=---='                              //
+//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
+//            佛祖保佑       永不宕机      永无BUG                //
+////////////////////////////////////////////////////////////////////
+ ${AnsiColor.BRIGHT_YELLOW}
+ ::: Spring-Boot ${spring-boot.version}     ::: Halo (version:${application.formatted-version})

+ 27 - 0
pump-admin/src/main/resources/converter/BusAnalgesicScoreEntity.properties

@@ -0,0 +1,27 @@
+pumpCode:PumpCode
+patientId:Patient_ID
+hospitalCode:SysHospital_ID
+productCode:SysProduct_ID
+statics:Static
+activity:Activity
+calm:Calm
+leftLeg:LeftLeg
+rightLeg:RightLeg
+leftArm:LeftArm
+rightArm:RightArm
+nauseaVomit:Nausea_Vomit
+itch:Itch
+vertigo:Vertigo
+soreThroat:SoreThroat
+uroschesis:Uroschesis
+breathDepression:BreathDepression
+hoarseness:Hoarseness
+cognitionObstacle:Cognition_Obstacle
+other:Other
+satisfaction:Satisfaction
+creator:FollowUp
+followDate:BillDate
+gmtModified:#
+analgesicScoreId:AnalgesicScore_ID
+gmtCreate:#
+id:#

+ 19 - 0
pump-admin/src/main/resources/converter/BusHospitalEntity.properties

@@ -0,0 +1,19 @@
+hospitalCode:HospitalNumber
+hospitalAddress:Hospital_Address
+hosptialName:Name
+provinceCode:ProvinceCode
+cityCode:CityCode
+areaCode:AreaCode
+bodyCode:BodyCode
+zipCode:ZipCode
+fax:Fax
+telephone:Telephone
+email:Email
+softwareVersion:SoftwareVersion
+softwareType:SoftType
+hardwareVersion:BaseStationVersion
+hardwareType:#
+ip:IPAddress
+gmtModified:#
+id:#
+gmtCreate:#

+ 31 - 0
pump-admin/src/main/resources/converter/BusPatientEntity.properties

@@ -0,0 +1,31 @@
+patientId:Patient_ID
+hospitalCode:SysHospital_ID
+productCode:SysProduct_ID
+patientCode:PatientCode
+pumpCode:PumpCode
+name:Name
+sex:Sex
+weight:Weight
+age:Age
+wardCode:Ward
+bedCode:BedNo
+operationName:Operation
+operationDoctor:Surgeon
+asa:ASA
+easyMode:EaseMode
+anesthesiaDoctor1:AnesthesiaMode
+anesthesiaDoctor2:DoctorTwo
+anesthesiaMode:AnesthesiaMode
+configPerson:ConfigPerson
+formula:Formula
+undoPerson:UndoPerson
+destoryPerson:DestroyPerson
+witnessPerson:WitnessPerson
+undoTime:UndoTime
+salt:Salt
+remain:Balance
+remark:Remark
+isDelete:IsDelete
+gmtModified:#
+id:#
+gmtCreate:#

+ 48 - 0
pump-admin/src/main/resources/converter/BusPumpEntity.properties

@@ -0,0 +1,48 @@
+pumpCode:PumpCode
+productCode:SysProduct_ID
+hospitalCode:SysHospital_ID
+patientCode:PatientCode
+remainQuantity:BalanceQuantity
+continueQuantity:ContinueQuantity
+selfControlQuantity:SelfQuantity
+lockTime:LockTime
+inputQuantity:InputQuantity
+validTime:TrueNum
+invalidTime:FalseNum
+maxQuantity:MaxQuantity
+firstQuantity:FirstQuantity
+singleQuantity:SingleQuantity
+totalQuantity:AllQuantity
+totalCount:AllCount
+pulseQuantity:PulseQuantity
+pulseLockTime:PulseLockTime
+upperLimit:UpperLimit
+lowerLimit:LowerLimit
+customScate:CustomScate
+firsLockTime:FirstLockTime
+addValidTime:AddTrueFrequency
+runState:RunState
+bufState1:BUFState1
+bufState2:BUFState2
+bufState3:BUFState3
+bufState4:BUFState4
+bufState5:BUFState5
+bufState6:BUFState6
+bufState7:BUFState7
+bufState8:BUFState8
+bufState9:BUFState9
+score:Score
+addCycle:FilingCycle
+reduceCycle:ReductionPeriod
+callFlag:CallFlag
+startTime:StartTime
+isRemove:Visible
+stateFlag:StateFlag
+noSignal:NoSignal
+viewState:ViewState
+remark:Remark
+lastUploadTime:LastUploadTime
+gmtModified:#
+id:#
+gmtCreate:#
+isFamily:#

+ 13 - 0
pump-admin/src/main/resources/converter/ReadMe.txt

@@ -0,0 +1,13 @@
+由于PC端和云端的数据库不一致,所以在传送过程中需要进行字段的转换
+在加载过程中会监控此文件所在的文件夹,并对此文件夹下的.properties文件进行加载
+.properties文件名称应与所对应的Entity所对应,文件名称不区分大小写
+文件中存放的字段格式为
+
+
+----------------------
+NewField:OldField
+云端字段:PC字段
+----------------------
+
+
+文件内容区分大小写

+ 175 - 0
pump-admin/src/main/resources/log/logback.xml

@@ -0,0 +1,175 @@
+<!-- Logback configuration. See http://logback.qos.ch/manual/index.html -->
+<configuration scan="true" scanPeriod="10 seconds">
+    <!--继承spring boot提供的logback配置-->
+    <!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->
+
+    <!--设置系统日志目录-->
+    <property name="APP_DIR" value="spring-boot-druid" />
+
+    <!-- 彩色日志 -->
+    <!-- 彩色日志依赖的渲染类 -->
+    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
+    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
+    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
+    <!-- 彩色日志格式 -->
+    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+
+    <!-- 控制台输出 -->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
+            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+        </encoder>
+        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>info</level>
+        </filter>
+    </appender>
+
+
+    <!-- 时间滚动输出 level为 DEBUG 日志 -->
+    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <file>${LOG_PATH}/log_debug.log</file>
+        <!--日志文件输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--
+                归档的日志文件的路径,例如今天是2017-04-26日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
+                而2017-04-26的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引
+            -->
+            <fileNamePattern>${LOG_PATH}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <!--
+                除按日志记录之外,还配置了日志文件不能超过500M,若超过500M,日志文件会以索引0开始,
+                命名日志文件,例如log-error-2017-04-26.0.log
+            -->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>500MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文件保留天数-->
+            <maxHistory>7</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文件只记录debug级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>debug</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+
+    <!-- 时间滚动输出 level为 INFO 日志 -->
+    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <file>${LOG_PATH}/log_info.log</file>
+        <!--日志文件输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--
+                归档的日志文件的路径,例如今天是2017-04-26日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
+                而2017-04-26的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引
+            -->
+            <fileNamePattern>${LOG_PATH}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <!--
+                除按日志记录之外,还配置了日志文件不能超过500M,若超过500M,日志文件会以索引0开始,
+                命名日志文件,例如log-error-2017-04-26.0.log
+            -->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>500MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文件保留天数-->
+            <maxHistory>7</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文件只记录info级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>info</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+
+    <!-- 时间滚动输出 level为 WARN 日志 -->
+    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <file>${LOG_PATH}/log_warn.log</file>
+        <!--日志文件输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--
+                归档的日志文件的路径,例如今天是2017-04-26日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
+                而2017-04-26的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引
+            -->
+            <fileNamePattern>${LOG_PATH}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <!--
+                除按日志记录之外,还配置了日志文件不能超过500M,若超过500M,日志文件会以索引0开始,
+                命名日志文件,例如log-error-2017-04-26.0.log
+            -->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>500MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文件保留天数-->
+            <maxHistory>7</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文件只记录warn级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>warn</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+
+    <!-- 时间滚动输出 level为 ERROR 日志 -->
+    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 正在记录的日志文件的路径及文件名 -->
+        <file>${LOG_PATH}/log_error.log</file>
+        <!--日志文件输出格式-->
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+        </encoder>
+        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--
+                归档的日志文件的路径,例如今天是2017-04-26日志,当前写的日志文件路径为file节点指定,可以将此文件与file指定文件路径设置为不同路径,从而将当前日志文件或归档日志文件置不同的目录。
+                而2017-04-26的日志文件在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引
+            -->
+            <fileNamePattern>${LOG_PATH}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <!--
+                除按日志记录之外,还配置了日志文件不能超过500M,若超过500M,日志文件会以索引0开始,
+                命名日志文件,例如log-error-2017-04-26.0.log
+            -->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>500MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+            <!--日志文件保留天数-->
+            <maxHistory>7</maxHistory>
+        </rollingPolicy>
+        <!-- 此日志文件只记录ERROR级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>error</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+    <root level="info">
+            <appender-ref ref="CONSOLE" />
+            <appender-ref ref="DEBUG_FILE" />
+            <appender-ref ref="INFO_FILE" />
+            <appender-ref ref="WARN_FILE" />
+            <appender-ref ref="ERROR_FILE" />
+      </root>
+</configuration>

+ 5 - 0
pump-admin/src/main/resources/lua/del.lua

@@ -0,0 +1,5 @@
+local key=KEYS[1]
+if redis.call('del',key)==1
+    then return 1
+    else return 0
+end

+ 91 - 0
pump-admin/src/main/resources/lua/getRedisMixed.lua

@@ -0,0 +1,91 @@
+---
+--- Generated by EmmyLua(https://github.com/EmmyLua)
+--- Created by fanfan.
+--- DateTime: 2020-05-27 9:22
+---
+
+local key=KEYS
+
+local portalKeys = {}
+
+local sessionKeys = {}
+
+local size = #key
+
+local result = {}
+
+if size == 0 then
+    return ''
+end
+
+for i = 1, size do
+    if string.find(key[i],"portal") then
+        table.insert(portalKeys,key[i])
+    elseif string.find(key[i],"shiro:session") then
+        table.insert(sessionKeys,key[i])
+    end
+end
+
+local portalKeysSize = #portalKeys
+
+local sessionKeysSize = #sessionKeys
+
+local regx = "(.+token%p)(.+)"
+
+--local pi = "portal:user:login_token_a8b0b971-77c2-4e00-b994-86e8529b6d22"
+--local name = string.gsub(pi,"(.+token%p)(.+)","%2")
+
+-- 遍历数组
+local function IsInTable(value, tbl)
+    for k,v in ipairs(tbl) do
+        if v == value then
+            return true;
+        end
+    end
+    return false;
+end
+
+local function square (List1,List2,bool)
+    local Len = #List1;
+    local pk = "portal:user:login_token_"
+    local sk = "shiro:session:login_token_"
+    for i = 1, Len do
+        local si = ""
+        local token = string.gsub(tostring(List1[i]),regx,"%2")
+        if bool then
+            si = sk..token
+        else
+            si = pk..token
+        end
+        print("si........."..si);
+        if IsInTable(si,List2) then
+            table.insert(result,pk..token)
+        end
+    end
+end
+
+if portalKeysSize <= sessionKeysSize then
+    square(portalKeys,sessionKeys,true)
+    else
+    square(sessionKeys,portalKeys,false)
+end
+
+local resultSize = #result
+
+--if resultSize then
+--    for i = 1, resultSize do
+--        print(result[i])
+--    end
+--end
+
+if (resultSize == 0) then
+    return ''
+else
+    return result;
+end
+
+
+
+
+
+

+ 37 - 0
pump-admin/src/main/resources/lua/redisBucket.lua

@@ -0,0 +1,37 @@
+--KEY值
+local key=KEYS[1]
+--桶容量
+local buketSize=tonumber(KEYS[2])
+--令牌产出时间
+local rate=ARGV[1]
+--此次更新时间
+local UpdateTime=ARGV[2]
+--var为集合,剩余令牌数量【1】,更新时间【2】
+local remain = tonumber(redis.call("hget",key,"remainToken"))
+local lastRefreshTime=redis.call("hget",key,"lastRefreshTime")
+--首次创建
+if type(remain)=="nil"
+then
+    remain=math.ceil(buketSize/2)
+    redis.call("hset",key,"lastRefreshTime",UpdateTime)
+    redis.call("hset",key,"remainToken",remain)
+    lastRefreshTime=UpdateTime
+end
+if(remain<=0)
+    then
+    local newTokens=math.ceil((UpdateTime-lastRefreshTime)/rate)
+    local refreshToken=newTokens
+    if(refreshToken<=0)
+    then
+        return 0
+    end
+    if(refreshToken>buketSize)
+        then
+        refreshToken=buketSize
+    end
+    redis.call("hset",key,"lastRefreshTime",UpdateTime)
+    redis.call("hset",key,"remainToken",refreshToken)
+    else
+    redis.call("hset",key,"remainToken",remain-1)
+end
+return 1

+ 6 - 0
pump-admin/src/main/resources/lua/setAndExpire.lua

@@ -0,0 +1,6 @@
+local key=KEYS[1]
+local value=KEYS[2]
+local expire=ARGV[1]
+redis.call("set",key,value)
+redis.call("expire",key,expire)
+return "1"

+ 23 - 0
pump-common/pom.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>netpump</artifactId>
+        <groupId>com.tuoren</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+
+    <name>pump-common</name>
+    <description>Demo project for Spring Boot</description>
+    <artifactId>pump-common</artifactId>
+
+    <dependencies>
+
+
+    </dependencies>
+
+
+
+</project>

+ 27 - 0
pump-common/src/main/java/com/tuoren/common/api/AopOrderEnum.java

@@ -0,0 +1,27 @@
+package com.tuoren.common.api;
+
+/**
+ * ClassName:
+ * date: 2020/5/21
+ *
+ * @author lifang
+ * @version 1.0
+ */
+public enum AopOrderEnum {
+    LOG(500,"日志切面"),
+    FLOWMONITOR(400,"流量监控切面"),
+    IDEMPOTENT(200,"幂等切面"),
+    SHIRO(100,"单点登录切面"),
+    RATELIMIT(10,"限流切面");
+
+    private int order;
+    private String name;
+    AopOrderEnum(int order,String name){
+        this.order = order;
+        this.name=name;
+    }
+
+    public int getOrder() {
+        return order;
+    }
+}

+ 113 - 0
pump-common/src/main/java/com/tuoren/common/api/CommonResult.java

@@ -0,0 +1,113 @@
+package com.tuoren.common.api;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * Create by fanfan
+ * Date: 2020-03-16 9:36
+ */
+@Data
+@AllArgsConstructor
+public class CommonResult<T> {
+    private long code;
+    private String message;
+    private T data;
+
+    /**
+     * 成功返回结果
+     *
+     * @param data 获取的数据
+     */
+    public static <T> CommonResult<T> success(T data) {
+        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
+    }
+
+    /**
+     * 成功返回结果
+     *
+     * @param data 获取的数据
+     * @param  message 提示信息
+     */
+    public static <T> CommonResult<T> success(T data, String message) {
+        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);
+    }
+
+    /**
+     * 失败返回结果
+     * @param errorCode 错误码
+     */
+    public static <T> CommonResult<T> failed(IErrorCode errorCode) {
+        return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);
+    }
+
+    /**
+     * 失败返回结果
+     * @param errorCode 错误码
+     * @param message 错误信息
+     */
+    public static <T> CommonResult<T> failed(IErrorCode errorCode,String message) {
+        return new CommonResult<T>(errorCode.getCode(), message, null);
+    }
+
+    /**
+     * 失败返回结果
+     * @param message 提示信息
+     */
+    public static <T> CommonResult<T> failed(String message) {
+        return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);
+    }
+
+    /**
+     * 失败返回结果
+     */
+    public static <T> CommonResult<T> failed() {
+        return failed(ResultCode.FAILED);
+    }
+
+    /**
+     * 参数验证失败返回结果
+     */
+    public static <T> CommonResult<T> validateFailed() {
+        return failed(ResultCode.VALIDATE_FAILED);
+    }
+
+    /**
+     * 参数验证失败返回结果
+     * @param message 提示信息
+     */
+    public static <T> CommonResult<T> validateFailed(String message) {
+        return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);
+    }
+
+    /**
+     * 未登录返回结果
+     */
+    public static <T> CommonResult<T> unauthorized() {
+        return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), null);
+    }
+
+    /**
+     * 未登录返回结果
+     */
+    public static <T> CommonResult<T> unauthorized(T data) {
+        return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
+    }
+
+    /**
+     * 未授权返回结果
+     */
+    public static <T> CommonResult<T> forbidden(T data) {
+        return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
+    }
+
+    /**
+     * 没有数据返回结果
+     */
+    public static <T> CommonResult<T> noData() {
+        return failed(ResultCode.NODATA);
+    }
+
+
+
+}

+ 11 - 0
pump-common/src/main/java/com/tuoren/common/api/IErrorCode.java

@@ -0,0 +1,11 @@
+package com.tuoren.common.api;
+
+/**
+ * 封装API的错误码
+ * Create by fanfan
+ * Date: 2020-03-16 9:42
+ */
+public interface IErrorCode {
+    long getCode();
+    String getMessage();
+}

+ 22 - 0
pump-common/src/main/java/com/tuoren/common/api/ResultCode.java

@@ -0,0 +1,22 @@
+package com.tuoren.common.api;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+@Getter
+public enum ResultCode implements IErrorCode{
+    SUCCESS(200, "操作成功"),
+    FAILED(500, "操作失败"),
+    VALIDATE_FAILED(404, "参数检验失败"),
+    UNAUTHORIZED(401, "暂未登录或token已经过期"),
+    FORBIDDEN(403, "没有相关权限"),
+    NODATA( 4000, "没有数据"),
+    DUPLICATE(4001,"重复操作或该页面已经过期"),
+    BUSY(4002,"系统繁忙,请稍后再试"),
+    OCCUPIED(4003, "用户在其他设备上登录"),
+	NOPATIENT(4005, "病人不存在"),
+	NOPUMP(4006, "泵不存在");
+    private long code;
+    private String message;
+}

+ 35 - 0
pump-common/src/main/java/com/tuoren/common/commponent/flowMonitor/FlowMonitorAutoConfiguration.java

@@ -0,0 +1,35 @@
+package com.tuoren.common.commponent.flowMonitor;
+
+import com.tuoren.common.api.AopOrderEnum;
+import com.tuoren.common.redis.RedisService;
+import org.springframework.aop.aspectj.AspectJExpressionPointcut;
+import org.springframework.aop.support.DefaultPointcutAdvisor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * @Author: lifang
+ * @Description:
+ * @Date: Created in 11:12 2020/9/7
+ */
+public class FlowMonitorAutoConfiguration {
+    private final String POINT_CUT= "execution(public * com.tuoren.web.layer.controller.*.*(..))";
+    @Bean
+    @ConditionalOnClass(RedisService.class)
+    public DefaultPointcutAdvisor repeatSubmitPointCutAdvice(RedisService redisService){
+        //声明一个AspectJ切点
+        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
+        //设置切点表达式
+        pointcut.setExpression(POINT_CUT);
+        // 配置增强类advisor, 切面=切点+增强
+        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
+        //设置切点
+        advisor.setPointcut(pointcut);
+        //设置增强(Advice)
+        advisor.setAdvice(new FlowMonitorMethodInterceptor());
+        //设置增强拦截器执行顺序
+        advisor.setOrder(AopOrderEnum.FLOWMONITOR.getOrder());
+
+        return advisor;
+    }
+}

+ 16 - 0
pump-common/src/main/java/com/tuoren/common/commponent/flowMonitor/FlowMonitorAutoConfigurationSelector.java

@@ -0,0 +1,16 @@
+package com.tuoren.common.commponent.flowMonitor;
+
+import org.springframework.context.annotation.DeferredImportSelector;
+import org.springframework.core.type.AnnotationMetadata;
+
+/**
+ * @Author: lifang
+ * @Description:
+ * @Date: Created in 11:15 2020/9/7
+ */
+public class FlowMonitorAutoConfigurationSelector implements DeferredImportSelector {
+    @Override
+    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
+        return new String[] { FlowMonitorAutoConfiguration.class.getName() };
+    }
+}

+ 63 - 0
pump-common/src/main/java/com/tuoren/common/commponent/flowMonitor/FlowMonitorMethodInterceptor.java

@@ -0,0 +1,63 @@
+package com.tuoren.common.commponent.flowMonitor;
+
+import com.tuoren.common.config.MvcConfig;
+import com.tuoren.common.entity.MvcEntity;
+import com.tuoren.common.utils.ConstastUtils;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @Author: lifang
+ * @Description: 流量监控切面
+ * @Date: Created in 11:13 2020/9/7
+ */
+public class FlowMonitorMethodInterceptor implements MethodInterceptor {
+    @Override
+    public Object invoke(MethodInvocation invocation) throws Throwable {
+        //若是拦截了Cglib代理对象,直接放行
+        if(invocation.getThis().getClass().getName().contains(ConstastUtils.CGLIBOBJ)){
+            return invocation.proceed();
+        }
+        //获取当前请求对象
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        //记录请求流量
+        logFlow(invocation,request);
+        return  invocation.proceed();
+    }
+
+    /**
+     * 记录访问流量
+     * @param request
+     * @param invocation
+     */
+    private void logFlow(MethodInvocation invocation, HttpServletRequest request) {
+        Map<MvcEntity, AtomicInteger> urlmap = MvcConfig.URLMAP;
+        MvcEntity mvcEntity = getMvcEntity(invocation,request);
+        MvcConfig.LOCK.readLock().lock();
+        try {
+            AtomicInteger atomicInteger = urlmap.get(mvcEntity);
+            atomicInteger.getAndIncrement();
+        }finally {
+            MvcConfig.LOCK.readLock().unlock();
+        }
+
+    }
+
+    private MvcEntity getMvcEntity(MethodInvocation invocation,HttpServletRequest request){
+        Method method = invocation.getMethod();
+        String className = invocation.getThis().getClass().getName();
+        MvcEntity mvcEntity = new MvcEntity();
+        mvcEntity.setMethodName(method.getName());
+        mvcEntity.setClassName(className);
+        mvcEntity.setOperation(request.getMethod());
+        return mvcEntity;
+    }
+}

+ 21 - 0
pump-common/src/main/java/com/tuoren/common/commponent/flowMonitor/annotation/EnableFlowMonitor.java

@@ -0,0 +1,21 @@
+package com.tuoren.common.commponent.flowMonitor.annotation;
+
+import com.tuoren.common.commponent.flowMonitor.FlowMonitorAutoConfigurationSelector;
+import com.tuoren.common.commponent.idempotent.IdempotentAutoConfigurationSelector;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+/**
+ * ClassName:
+ * date: 2020/6/5
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Documented
+@Import(FlowMonitorAutoConfigurationSelector.class)
+public @interface EnableFlowMonitor {
+}

+ 40 - 0
pump-common/src/main/java/com/tuoren/common/commponent/idempotent/IdempotentAutoConfiguration.java

@@ -0,0 +1,40 @@
+package com.tuoren.common.commponent.idempotent;
+
+import com.tuoren.common.api.AopOrderEnum;
+import com.tuoren.common.redis.RedisService;
+import org.springframework.aop.aspectj.AspectJExpressionPointcut;
+import org.springframework.aop.support.DefaultPointcutAdvisor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * ClassName:
+ * date: 2020/5/21
+ *
+ * @author lifang
+ * @version 1.0
+ */
+//@Configuration
+//@EnableConfigurationProperties(IdempotentProperties.class)
+//@ConditionalOnProperty(prefix = "idempontent",name ="enable",havingValue = "true")
+public class IdempotentAutoConfiguration {
+    private final String POINT_CUT= "@annotation(com.tuoren.common.commponent.idempotent.annotation.Idempotent)";
+    @Bean
+    @ConditionalOnClass(RedisService.class)
+    public DefaultPointcutAdvisor repeatSubmitPointCutAdvice(RedisService redisService){
+        //声明一个AspectJ切点
+        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
+        //设置切点表达式
+        pointcut.setExpression(POINT_CUT);
+        // 配置增强类advisor, 切面=切点+增强
+        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
+        //设置切点
+        advisor.setPointcut(pointcut);
+        //设置增强(Advice)
+        advisor.setAdvice(new IdempotentMethodInterceptor(redisService));
+        //设置增强拦截器执行顺序
+        advisor.setOrder(AopOrderEnum.IDEMPOTENT.getOrder());
+
+        return advisor;
+    }
+}

+ 20 - 0
pump-common/src/main/java/com/tuoren/common/commponent/idempotent/IdempotentAutoConfigurationSelector.java

@@ -0,0 +1,20 @@
+package com.tuoren.common.commponent.idempotent;
+
+import org.springframework.context.annotation.DeferredImportSelector;
+import org.springframework.core.annotation.Order;
+import org.springframework.core.type.AnnotationMetadata;
+
+/**
+ * ClassName:
+ * date: 2020/6/5
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Order
+public class IdempotentAutoConfigurationSelector implements DeferredImportSelector {
+    @Override
+    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
+        return new String[] { IdempotentAutoConfiguration.class.getName() };
+    }
+}

+ 71 - 0
pump-common/src/main/java/com/tuoren/common/commponent/idempotent/IdempotentMethodInterceptor.java

@@ -0,0 +1,71 @@
+package com.tuoren.common.commponent.idempotent;
+
+import com.aliyuncs.utils.StringUtils;
+import com.tuoren.common.api.CommonResult;
+import com.tuoren.common.api.ResultCode;
+import com.tuoren.common.commponent.idempotent.annotation.Idempotent;
+import com.tuoren.common.redis.RedisService;
+import com.tuoren.common.utils.ConstastUtils;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Collections;
+
+/**
+ * ClassName:
+ * date: 2020/5/21
+ *  幂等性拦截器
+ * @author lifang
+ * @version 1.0
+ */
+public class IdempotentMethodInterceptor implements MethodInterceptor {
+
+    private RedisService redisService;
+
+    private final String LUA="lua/del.lua";
+    public IdempotentMethodInterceptor(RedisService redisService) {
+        this.redisService = redisService;
+    }
+
+    @Override
+    public Object invoke(MethodInvocation invocation) throws Throwable {
+        /**
+         *    此切面会拦截目标对象和目标代理对象,共计拦截两次
+         *    默认Cglib代理,进行判断是否为代理对象,若是代理对象直接放行
+         */
+        if(invocation.getThis().getClass().getName().contains(ConstastUtils.CGLIBOBJ)) {
+            return invocation.proceed();
+        }
+        Method method = invocation.getMethod();
+        if(method.isAnnotationPresent(Idempotent.class)){
+            Idempotent idempotent = method.getAnnotation(Idempotent.class);
+            //幂等性开关未开启
+            if(!idempotent.enable()) {
+                return invocation.proceed();
+            };
+            //获取request对象
+            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+            HttpServletRequest request = attributes.getRequest();
+            //从请求头中获取token
+            String token = request.getHeader(ConstastUtils.IDEMPOTENTTOKEN);
+            if(StringUtils.isEmpty(token)){
+                return CommonResult.failed(ResultCode.DUPLICATE);
+            }
+            Idempotent.Type type = idempotent.type();
+            //采用Token+Url+Redis,一次访问后清除缓存,实现请求的幂等性
+            if(type== Idempotent.Type.TOKEN_AND_URL){
+                Long result = redisService.runLua(LUA, Long.class, Collections.singletonList(token));
+                //缓存中删除token成功
+                if(result==1){
+                    return invocation.proceed();
+                }
+                return CommonResult.failed(ResultCode.DUPLICATE);
+            }
+        }
+        return  invocation.proceed();
+    }
+}

+ 18 - 0
pump-common/src/main/java/com/tuoren/common/commponent/idempotent/IdempotentProperties.java

@@ -0,0 +1,18 @@
+package com.tuoren.common.commponent.idempotent;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * ClassName:
+ * date: 2020/5/21
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Data
+@ConfigurationProperties(prefix = "idempontent")
+public class IdempotentProperties {
+    //幂等操作过期时间,默认30分钟
+    private long expire=60*30*1000;
+}

+ 21 - 0
pump-common/src/main/java/com/tuoren/common/commponent/idempotent/annotation/EnableIdempotent.java

@@ -0,0 +1,21 @@
+package com.tuoren.common.commponent.idempotent.annotation;
+
+import com.tuoren.common.commponent.idempotent.IdempotentAutoConfigurationSelector;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+/**
+ * ClassName:
+ * date: 2020/6/5
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Documented
+@Import(IdempotentAutoConfigurationSelector.class)
+public @interface EnableIdempotent {
+    
+}

+ 34 - 0
pump-common/src/main/java/com/tuoren/common/commponent/idempotent/annotation/Idempotent.java

@@ -0,0 +1,34 @@
+package com.tuoren.common.commponent.idempotent.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * ClassName: Idempotent
+ * date: 2020/5/16 16:35
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Documented
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Idempotent {
+    /**
+     * 启动幂等性
+     * 默认开启
+     * @return
+     */
+    boolean enable() default true;
+
+    /**
+     * 定义幂等性组件校验规则
+     */
+    Type type() default Type.TOKEN_AND_URL;
+
+    /**
+     * TOKEN_AND_URL是通过令牌和URL组合的方式作为主键创建分布式锁的模式,这种模式适合用户已经登录,存在用户token令牌的模式,
+     */
+    enum Type{
+        TOKEN_AND_URL;
+    }
+}

+ 15 - 0
pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/Interface/RateLimiter.java

@@ -0,0 +1,15 @@
+package com.tuoren.common.commponent.rateLimit.Interface;
+
+/**
+ * ClassName:
+ * date: 2020/5/22
+ *
+ * @author lifang
+ * @version 1.0
+ */
+public interface RateLimiter {
+    enum Type{
+        //令牌桶可应对突发流量,漏桶速率恒定,Redis实现流量控制
+        TokenBucket,LeakyBucket,Redis
+    }
+}

+ 20 - 0
pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimitAutoConfigurationSelector.java

@@ -0,0 +1,20 @@
+package com.tuoren.common.commponent.rateLimit;
+
+import org.springframework.context.annotation.DeferredImportSelector;
+import org.springframework.core.annotation.Order;
+import org.springframework.core.type.AnnotationMetadata;
+
+/**
+ * ClassName:
+ * date: 2020/6/5
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Order
+public class RateLimitAutoConfigurationSelector implements DeferredImportSelector {
+    @Override
+    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
+        return new String[] { RateLimiterAutoConfigration.class.getName() };
+    }
+}

+ 40 - 0
pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimitMethodInterceptor.java

@@ -0,0 +1,40 @@
+package com.tuoren.common.commponent.rateLimit;
+
+import com.tuoren.common.api.CommonResult;
+import com.tuoren.common.api.ResultCode;
+import com.tuoren.common.commponent.rateLimit.RateLimiterHandler.Interface.RateLimiterHandler;
+import com.tuoren.common.utils.ConstastUtils;
+import lombok.Data;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+
+/**
+ * ClassName:
+ * date: 2020/5/25
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Data
+public class RateLimitMethodInterceptor implements MethodInterceptor {
+    RateLimiterProperties rateLimiterProperties;
+    RateLimiterHandler rateLimiterHandler;
+
+    public RateLimitMethodInterceptor(RateLimiterProperties rateLimiterProperties,RateLimiterHandler rateLimiterHandler ){
+        this.rateLimiterProperties = rateLimiterProperties;
+        this.rateLimiterHandler=rateLimiterHandler;
+    }
+
+    @Override
+    public Object invoke(MethodInvocation invocation) throws Throwable {
+        if(invocation.getThis().getClass().getName().contains(ConstastUtils.CGLIBOBJ)){
+            return invocation.proceed();
+        }
+        boolean res =rateLimiterHandler.acquire();
+        if(res){
+            return invocation.proceed();
+        }
+        return CommonResult.failed(ResultCode.BUSY);
+    }
+}

+ 46 - 0
pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimiterAutoConfigration.java

@@ -0,0 +1,46 @@
+package com.tuoren.common.commponent.rateLimit;
+
+import com.tuoren.common.api.AopOrderEnum;
+import com.tuoren.common.commponent.rateLimit.RateLimiterHandler.Interface.RateLimiterHandler;
+import org.springframework.aop.aspectj.AspectJExpressionPointcut;
+import org.springframework.aop.support.DefaultPointcutAdvisor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * ClassName:
+ * date: 2020/5/22
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Configuration
+@EnableConfigurationProperties({RateLimiterProperties.class})
+@ConditionalOnProperty(prefix = "ratelimit",name = "enable",havingValue = "true")
+public class RateLimiterAutoConfigration {
+    private final String POINT_CUT= "execution(public * com.tuoren.web.layer.controller.*.*(..))";
+    @Autowired
+    RateLimiterProperties rateLimiterProperties;
+    @Autowired
+    RateLimiterHandler rateLimiterHandler;
+    @Bean
+    public DefaultPointcutAdvisor rateLimitPointCutAdvice(){
+        //声明一个AspectJ切点
+        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
+        //设置切点表达式
+        pointcut.setExpression(POINT_CUT);
+        // 配置增强类advisor, 切面=切点+增强
+        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
+        //设置切点
+        advisor.setPointcut(pointcut);
+        //设置增强(Advice)
+        advisor.setAdvice(new RateLimitMethodInterceptor(rateLimiterProperties,rateLimiterHandler));
+        //设置增强拦截器执行顺序
+        advisor.setOrder(AopOrderEnum.RATELIMIT.getOrder());
+
+        return advisor;
+    }
+}

+ 12 - 0
pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimiterHandler/Interface/RateLimiterHandler.java

@@ -0,0 +1,12 @@
+package com.tuoren.common.commponent.rateLimit.RateLimiterHandler.Interface;
+
+/**
+ * ClassName:
+ * date: 2020/5/27
+ *
+ * @author lifang
+ * @version 1.0
+ */
+public interface RateLimiterHandler {
+    boolean acquire();
+}

+ 109 - 0
pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimiterHandler/RedisBucketHandler.java

@@ -0,0 +1,109 @@
+package com.tuoren.common.commponent.rateLimit.RateLimiterHandler;
+
+import com.tuoren.common.commponent.rateLimit.RateLimiterHandler.Interface.RateLimiterHandler;
+import com.tuoren.common.commponent.rateLimit.RateLimiterProperties;
+import com.tuoren.common.redis.RedisService;
+import com.tuoren.common.utils.ConstastUtils;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * ClassName:
+ * date: 2020/5/26
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Data
+@Slf4j
+@NoArgsConstructor
+@Configuration
+@EnableConfigurationProperties(RateLimiterProperties.class)
+@ConditionalOnProperty(prefix = "ratelimit",name = "type",havingValue = "redis")
+public class RedisBucketHandler implements RateLimiterHandler {
+    private int bucketSize;
+    private long rate;
+    private long millsWait;
+    @Autowired
+    private RedisService redisService;
+
+    @Autowired
+    RateLimiterProperties properties;
+    @PostConstruct
+    public void init(){
+        this.bucketSize=properties.getBucketSize();
+        this.rate=properties.getRate();
+        this.millsWait= TimeUnit.SECONDS.toMillis(properties.getWaitTime());
+        log.info("redis令牌桶参数设置成功,桶大小为--{},速率--{}ms/个,最大等待时间--{}ms",bucketSize,rate,millsWait);
+    }
+
+    @Override
+    public boolean acquire(){
+        return acquire(1,millsWait,System.currentTimeMillis());
+    }
+    private boolean acquire(long needPermits,long millsToWait,long now){
+        if(!checkPermits(needPermits)){
+            return  false;
+        }
+        long consumer = consumer(needPermits,now);
+        if(consumer==1){
+            return true;
+        }
+        if(millsToWait<=0) {
+            return false;
+        }
+        return waitToGetPermits(needPermits,millsToWait,now);
+    }
+
+    private boolean checkPermits(long needPermits){
+        //最大令牌数量小于0,令牌产出速率小于0,参数初始化失败,则令牌桶调用失败
+        if(bucketSize<=0||rate<=0L||needPermits>bucketSize) {
+            return false;
+        }
+        return true;
+    }
+
+    private long consumer(long needPermits,long now){
+        List<String> keys = getKeys();
+        Long result = redisService.runLua("/lua/redisBucket.lua", Long.class, keys, String.valueOf(rate),String.valueOf(System.currentTimeMillis()));
+        return result;
+    }
+
+    /**
+     * 等待时间内消费令牌
+     * @param now
+     * @param waitMillsTime
+     * @return
+     */
+    private boolean waitToGetPermits(long needPermits,long now,long waitMillsTime) {
+        if (waitMillsTime <= 0) {
+            return false;
+        }
+        long targetTime = now + waitMillsTime;
+        for (; ; ) {
+            //超过等待时间,按照waitTime时间计算令牌数
+            long timeMillis = System.currentTimeMillis();
+            if (timeMillis >= targetTime) {
+                return acquire(needPermits, 0, timeMillis);
+            }
+        }
+    }
+    private List<String> getKeys(){
+        ArrayList<String> keys = new ArrayList<>();
+        //key值
+        keys.add(ConstastUtils.REDISBUCKETT);
+        //桶容量
+        keys.add(String.valueOf(bucketSize));
+        return keys;
+    }
+}

+ 182 - 0
pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimiterHandler/TokenBucketHandler.java

@@ -0,0 +1,182 @@
+package com.tuoren.common.commponent.rateLimit.RateLimiterHandler;
+import cn.hutool.core.date.DateUtil;
+import com.tuoren.common.commponent.rateLimit.RateLimiterHandler.Interface.RateLimiterHandler;
+import com.tuoren.common.commponent.rateLimit.RateLimiterProperties;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.PostConstruct;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * ClassName:
+ * date: 2020/5/22
+ * 令牌桶
+ *
+ * 假如用户配置的平均发送速率为   rate/1000,则每隔    rate  毫秒一个令牌被加入到桶中;
+ * 假设桶最多可以存发    bucketSize  个令牌。如果令牌到达时令牌桶已经满了,那么这个令牌会被丢弃;
+ * 当一个消耗N个令牌的数据包到达时,就从令牌桶中删除n个令牌,并且数据包被发送到网络;
+ * 如果令牌桶中少于n个令牌,那么不会删除令牌,用户进入轮询状态,等待    waitMillsTime  后再次调用令牌桶,如果失败则认为这个数据包在流量限制之外;
+ * 算法允许最长   bucketSize  个令牌请求的突发,但从长期运行结果看,数据包的速率被限制成常量   rate/1000。对于在流量限制外的数据包可以以不同的方式处理:
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Configuration
+@NoArgsConstructor
+@EnableConfigurationProperties(RateLimiterProperties.class)
+@ConditionalOnProperty(prefix = "ratelimit",name = "type",havingValue = "tokenbucket")
+@Data
+@Slf4j
+public class TokenBucketHandler implements RateLimiterHandler {
+    /**
+     * 最大令牌数量
+     */
+    private int bucketSize;
+    /**
+     * 当前存储的令牌数
+     */
+    private AtomicLong storedPermits=new AtomicLong(0);
+    /**
+     * 上次填充令牌时间
+     */
+    private AtomicLong lastRefillTime=new AtomicLong(0);
+    /**
+     * 每个令牌产生时间
+     */
+    private long rate;
+    /**
+     * 此处以微秒为单位
+     */
+    private long millsWait;
+    @Autowired
+    RateLimiterProperties tokenBucketProperties;
+    @PostConstruct
+    public void init(){
+        this.bucketSize=tokenBucketProperties.getBucketSize();
+        this.rate=tokenBucketProperties.getRate();
+        this.millsWait=TimeUnit.SECONDS.toMillis(tokenBucketProperties.getWaitTime());
+        this.storedPermits.set(bucketSize/2);
+        this.lastRefillTime.set(System.currentTimeMillis());
+        log.info("令牌桶参数设置成功,桶大小为--{},速率--{}ms/个,最大等待时间--{}ms,当前桶中存储令牌数量--{}",bucketSize,rate,millsWait,storedPermits.get());
+    }
+
+    @Override
+    public boolean acquire(){
+        return tryAcquire(1,millsWait,System.currentTimeMillis());
+    }
+    public boolean acquire(long needPermits){
+        return tryAcquire(needPermits,millsWait,System.currentTimeMillis());
+    }
+    public boolean acquire(long needPermits, TimeUnit unit){
+        return tryAcquire(unit.toMillis(needPermits),0,System.currentTimeMillis());
+    }
+
+
+    /**
+     * 获取令牌
+     * @param needPermits  消耗令牌数量,1个bit位消耗1个令牌
+     * @return
+     */
+    boolean tryAcquire(long needPermits,long millsToWait,long now){
+        if(!checkPermits(needPermits)){
+            return false;
+        }
+        //填充令牌
+        refillPermits(bucketSize,rate,System.currentTimeMillis());
+        //消费令牌
+        if(consumerToken((int) needPermits)) {
+            return true;
+        }
+        //若允许等待
+        return waitToGetPermits(needPermits,now,millsToWait);
+    }
+
+
+    boolean checkPermits(long needPermits){
+        //最大令牌数量小于0,令牌产出速率小于0,参数初始化失败,则令牌桶调用失败
+        if(bucketSize<=0||rate<=0L||needPermits>bucketSize) {
+            return false;
+        }
+        //将初始容量改为桶大小的一半
+        if(storedPermits.get()==-1) {
+            storedPermits.set(bucketSize/2);
+        }
+        return true;
+    }
+
+    /**
+     * 向令牌桶中添加令牌
+     * @param bucketSize
+     * @param rate
+     * @param nowMills
+     */
+    private void refillPermits(int bucketSize,long rate,long nowMills){
+        //上次填充时间
+        long lastTime = lastRefillTime.get();
+        //两次填充令牌桶的间隔时间
+        long interval = nowMills - lastTime;
+        //添加令牌数量
+        long newTokens = interval / rate;
+        if(newTokens>0){
+            long newFillTime=lastTime==0?nowMills:lastTime+newTokens*rate;
+            //CAS更新添加时间,若更新成功,则存放令牌
+            if(lastRefillTime.compareAndSet(lastTime,newFillTime)){
+                while (true){
+                    //获取当前存储令牌数量
+                    long l = storedPermits.get();
+                    //设置调整后的令牌数
+                    long adjust=Math.min(l+newTokens,bucketSize);
+                    if(storedPermits.compareAndSet(l,adjust)) {
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 消费令牌
+     * @param consumerTokens
+     * @return
+     */
+    private boolean consumerToken(int consumerTokens) {
+        while (true){
+            long storePermits = storedPermits.get();
+            if(storePermits<consumerTokens){
+                return false;
+            }
+            if(storedPermits.compareAndSet(storePermits,Math.max(0,storePermits-1))){
+                log.info("当前时间---{},消费令牌数量--{},剩余令牌数量--{}", DateUtil.now(),consumerTokens,storedPermits.get());
+                return true;
+            }
+        }
+    }
+
+    /**
+     * 等待时间内消费令牌
+     * @param now
+     * @param waitMillsTime
+     * @return
+     */
+    private boolean waitToGetPermits(long needPermits,long now,long waitMillsTime){
+        if(waitMillsTime<=0) {
+            return false;
+        }
+        long targetTime = now + waitMillsTime;
+        for (;;){
+            //超过等待时间,按照waitTime时间计算令牌数
+            long timeMillis = System.currentTimeMillis();
+            if(timeMillis>=targetTime) {
+                return tryAcquire(needPermits,0,timeMillis);
+            }
+        }
+    }
+}

+ 25 - 0
pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/RateLimiterProperties.java

@@ -0,0 +1,25 @@
+package com.tuoren.common.commponent.rateLimit;
+
+import com.tuoren.common.commponent.rateLimit.Interface.RateLimiter;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * ClassName:
+ * date: 2020/5/25
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Data
+@ConfigurationProperties(prefix = "ratelimit")
+public class RateLimiterProperties {
+    private boolean enable=true;
+    private RateLimiter.Type type=RateLimiter.Type.TokenBucket;
+    //限流最大值
+    private int bucketSize=100;
+    //令牌产出时间
+    private int rate=10;
+    //当流量被限时,线程最大等待时间,以秒s为单位
+    private long waitTime=0;
+}

+ 20 - 0
pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/annotation/EnableRateLimit.java

@@ -0,0 +1,20 @@
+package com.tuoren.common.commponent.rateLimit.annotation;
+
+import com.tuoren.common.commponent.rateLimit.RateLimitAutoConfigurationSelector;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+/**
+ * ClassName:
+ * date: 2020/6/5
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Documented
+@Import(RateLimitAutoConfigurationSelector.class)
+public @interface EnableRateLimit {
+}

+ 21 - 0
pump-common/src/main/java/com/tuoren/common/commponent/rateLimit/annotation/RateLimit.java

@@ -0,0 +1,21 @@
+package com.tuoren.common.commponent.rateLimit.annotation;
+
+import com.tuoren.common.commponent.idempotent.IdempotentAutoConfigurationSelector;
+import com.tuoren.common.commponent.rateLimit.RateLimitAutoConfigurationSelector;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+/**
+ * ClassName:
+ * date: 2020/6/5
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Documented
+@Import(RateLimitAutoConfigurationSelector.class)
+public @interface RateLimit {
+}

+ 37 - 0
pump-common/src/main/java/com/tuoren/common/commponent/shiroLogin/ShiroLoginAutoConfiguration.java

@@ -0,0 +1,37 @@
+package com.tuoren.common.commponent.shiroLogin;
+
+import com.tuoren.common.api.AopOrderEnum;
+import com.tuoren.common.redis.RedisService;
+import org.springframework.aop.aspectj.AspectJExpressionPointcut;
+import org.springframework.aop.support.DefaultPointcutAdvisor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * Create by fanfan
+ * Date: 2020-05-21 17:53
+ */
+//@Configuration
+//@EnableConfigurationProperties(WebProperties.class)
+//@ConditionalOnProperty(prefix = "shiroLogin",name = "enable",havingValue = "true")
+public class ShiroLoginAutoConfiguration {
+//    private final String POINT_CUT= "execution(public * com.tuoren.web.layer.controller.*.*(..)) && !execution(public * com.tuoren.web.layer.controller.BusLoginController.*(..))";
+//    @Bean
+//    @ConditionalOnClass(RedisService.class)
+//    public DefaultPointcutAdvisor  submitPointCutAdvice(RedisService redisService) {
+//        // 声明一个AspectJ切点
+//        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
+//        // 设置切点表达式
+//        pointcut.setExpression(POINT_CUT);
+//        // 配置增强类advisor, 切面=切点+增强
+//        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
+//        //设置切点
+//        advisor.setPointcut(pointcut);
+//        //设置增强(Advice)
+//        advisor.setAdvice(new ShiroLoginMethodInterceptor(redisService));
+//        //设置增强拦截器执行顺序
+//        advisor.setOrder(AopOrderEnum.SHIRO.getOrder());
+//        return advisor;
+//    }
+
+}

+ 20 - 0
pump-common/src/main/java/com/tuoren/common/commponent/shiroLogin/ShiroLoginAutoConfigurationSelector.java

@@ -0,0 +1,20 @@
+package com.tuoren.common.commponent.shiroLogin;
+
+import org.springframework.context.annotation.DeferredImportSelector;
+import org.springframework.core.annotation.Order;
+import org.springframework.core.type.AnnotationMetadata;
+
+/**
+ * ClassName:
+ * date: 2020/6/5
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Order
+public class ShiroLoginAutoConfigurationSelector implements DeferredImportSelector {
+    @Override
+    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
+        return new String[] { ShiroLoginAutoConfiguration.class.getName() };
+    }
+}

+ 55 - 0
pump-common/src/main/java/com/tuoren/common/commponent/shiroLogin/ShiroLoginMethodInterceptor.java

@@ -0,0 +1,55 @@
+package com.tuoren.common.commponent.shiroLogin;
+
+import com.tuoren.common.api.CommonResult;
+import com.tuoren.common.api.ResultCode;
+import com.tuoren.common.redis.RedisService;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Set;
+
+/**
+ * Create by fanfan
+ * Date: 2020-05-28 8:34
+ */
+public class ShiroLoginMethodInterceptor implements MethodInterceptor {
+    private RedisService redisService;
+    public ShiroLoginMethodInterceptor(RedisService redisService) {
+        this.redisService = redisService;
+    }
+    @Override
+    public Object invoke(MethodInvocation invocation) throws Throwable {
+        //若是拦截了Cglib代理对象,直接放行
+        if(invocation.getThis().getClass().getName().contains("$$Enhancer")){
+            return invocation.proceed();
+        }
+        //获取当前请求对象
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        String authorization = request.getHeader("Authorization");
+        String sessionRedisToken  = "shiro:session:" + authorization;
+        String portalRedisToken  = "portal:user:" + authorization;
+//        Set<String> sessionKeys = redisService.getKeys("shiro:session:login_token_*");
+        String loginToken = redisService.get(sessionRedisToken);
+
+        if(loginToken!=null){
+            return invocation.proceed();
+        }
+        // 验证 session
+//        for (String sk:  sessionKeys) {
+//            if(sk.equals(sessionRedisToken)){
+//                return invocation.proceed();
+//            }
+//        }
+        // 验证 portal
+        if(redisService.get(portalRedisToken) != null  && loginToken == null ) {
+            redisService.remove(portalRedisToken);
+            return CommonResult.failed(ResultCode.OCCUPIED);
+        } else {
+            return CommonResult.unauthorized();
+        }
+    }
+}

+ 21 - 0
pump-common/src/main/java/com/tuoren/common/commponent/shiroLogin/annotation/EnableWebShiro.java

@@ -0,0 +1,21 @@
+package com.tuoren.common.commponent.shiroLogin.annotation;
+
+
+import com.tuoren.common.commponent.shiroLogin.ShiroLoginAutoConfigurationSelector;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+/**
+ * ClassName:
+ * date: 2020/6/5
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Documented
+@Import(ShiroLoginAutoConfigurationSelector.class)
+public @interface EnableWebShiro {
+}

+ 24 - 0
pump-common/src/main/java/com/tuoren/common/config/GlobalCorsConfig.java

@@ -0,0 +1,24 @@
+package com.tuoren.common.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * Create by fanfan
+ * Date: 2020-04-22 16:20
+ */
+
+@Configuration
+public class GlobalCorsConfig implements WebMvcConfigurer {
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**")
+                .allowedOrigins("*")
+                .allowedMethods("*")
+                .allowCredentials(true)
+                .maxAge(3600)
+                .allowedHeaders("*");
+    }
+
+}

+ 60 - 0
pump-common/src/main/java/com/tuoren/common/config/MvcConfig.java

@@ -0,0 +1,60 @@
+package com.tuoren.common.config;
+
+import com.tuoren.common.entity.MvcEntity;
+import com.tuoren.common.utils.SpringUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+import javax.annotation.PostConstruct;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * @Author: lifang
+ * @Description:
+ * @Date: Created in 18:41 2020/9/3
+ */
+@Configuration
+public class MvcConfig {
+    /**
+     * 所有url集合
+     */
+    public static final Map<MvcEntity, AtomicInteger> URLMAP=new HashMap<>();
+
+    /**
+     * 读写锁,默认非公平锁
+     */
+    public static final ReentrantReadWriteLock LOCK=new ReentrantReadWriteLock();
+    @Autowired
+    WebApplicationContext webApplicationContext;
+    @PostConstruct
+    public void init(){
+        fillAllUrl();
+    }
+
+    public void fillAllUrl(){
+        RequestMappingHandlerMapping mapping = webApplicationContext.getBean(RequestMappingHandlerMapping.class);
+        Map<RequestMappingInfo, HandlerMethod> handlerMethods = mapping.getHandlerMethods();
+        handlerMethods.forEach((requestMappingInfo, handlerMethod) -> {
+            MvcEntity mvcEntity = new MvcEntity(handlerMethod.getMethod().getName(),
+                    handlerMethod.getBeanType().getName(),
+                    requestMappingInfo.getMethodsCondition().getMethods().toString().replaceAll("\\[","").replaceAll("\\]",""),
+                    requestMappingInfo.getPatternsCondition().toString());
+            Api api = handlerMethod.getBeanType().getAnnotation(Api.class);
+            ApiOperation apiOperation = handlerMethod.getMethod().getAnnotation(ApiOperation.class);
+            if(api!=null&&apiOperation!=null){
+                mvcEntity.setDescription(api.description()+":"+apiOperation.value());
+            }
+           URLMAP.put(mvcEntity,new AtomicInteger(0));
+        });
+    }
+}

+ 23 - 0
pump-common/src/main/java/com/tuoren/common/config/MybatisPlusConfig.java

@@ -0,0 +1,23 @@
+package com.tuoren.common.config;
+
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+/**
+ * Create by fanfan
+ * Date: 2020-03-16 14:44
+ */
+
+@Configuration
+@EnableTransactionManagement
+@MapperScan(basePackages =  {"com.tuoren.web.layer.mapper","com.tuoren.web.netty.blackList.mapper"})
+public class MybatisPlusConfig {
+    @Bean
+    public PaginationInterceptor paginationInterceptor(){
+        return new PaginationInterceptor().setCountSqlParser(new JsqlParserCountOptimize(true));
+    }
+}

+ 82 - 0
pump-common/src/main/java/com/tuoren/common/config/RedisConfig.java

@@ -0,0 +1,82 @@
+package com.tuoren.common.config;
+
+import lombok.NoArgsConstructor;
+import org.crazycake.shiro.RedisManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.StringRedisTemplate;
+
+import javax.annotation.PostConstruct;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * @Author: lifang
+ * @Description:
+ * @Date: Created in 17:38 2020/9/17
+ */
+@Configuration
+@EnableConfigurationProperties(RedisProperties.class)
+@NoArgsConstructor
+public class RedisConfig {
+    private static final String SALT ="netpump" ;
+
+    private RedisProperties redisProperties;
+
+    private RedisManager redisManager;
+    @Autowired
+    public RedisConfig(RedisProperties redisProperties,RedisManager redisManager) {
+        this.redisProperties=redisProperties;
+        this.redisManager=redisManager;
+    }
+
+    @Bean("redisTemplate")
+    public StringRedisTemplate stringRedisTemplate(
+            RedisConnectionFactory redisConnectionFactory)  {
+        StringRedisTemplate template = new StringRedisTemplate();
+        template.setConnectionFactory(redisConnectionFactory);
+        return template;
+    }
+    @PostConstruct
+    public void init(){
+        String originPassword = redisProperties.getPassword();
+        String newPassword = getEncryption(originPassword+SALT)+"\\.";
+        redisProperties.setPassword(newPassword);
+        redisManager.setPassword(newPassword);
+    }
+
+
+
+     private String getEncryption(String originString){
+        String result = null;
+        if (originString != null) {
+            try {
+                // 指定加密的方式为MD5
+                MessageDigest md = MessageDigest.getInstance("MD5");
+                // 进行加密运算
+                byte bytes[] = md.digest(originString.getBytes());
+                for (int i = 0; i < bytes.length; i++) {
+                    // 将整数转换成十六进制形式的字符串 这里与0xff进行与运算的原因是保证转换结果为32位
+                    String str = Integer.toHexString(bytes[i] & 0xFF);
+                    if (str.length() == 1) {
+                        str += "F";
+                    }
+                    result += str;
+                }
+            } catch (NoSuchAlgorithmException e) {
+                e.printStackTrace();
+            }
+        }
+        result = result.toUpperCase();
+        return result.substring(result.length()/2);
+    }
+
+    public static void main(String[] args) {
+        RedisConfig redisPostprocess = new RedisConfig();
+        System.out.println(redisPostprocess.getEncryption("123456"+SALT)+"\\.");
+    }
+}

+ 59 - 0
pump-common/src/main/java/com/tuoren/common/config/SSLConfig.java

@@ -0,0 +1,59 @@
+package com.tuoren.common.config;
+
+import org.apache.catalina.Context;
+import org.apache.tomcat.util.descriptor.web.SecurityCollection;
+import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+
+/**
+ * Create by fanfan
+ * Date: 2020-05-19 15:40
+ */
+@Configuration
+@Profile("cloud")
+public class SSLConfig {
+
+    @Value("${server.port}")
+    private int sslPort;//https的端口
+
+    /**
+      * @Description: 重定向请求到端口,需要端口转发时使用
+      * @Author: fanfan
+      * @Date: 2020-05-19  15:47
+      */
+//    @Bean
+//    public Connector connector(){
+//        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
+//        connector.setScheme("http");
+//        connector.setPort(80);
+//        connector.setSecure(false);
+//        connector.setRedirectPort(sslPort);
+//        return connector;
+//    }
+
+    /**
+      * @Description:  重定向到HTTPS
+      * @Author: fanfan
+      * @Date: 2020-05-19  15:47
+      */
+    @Bean
+    TomcatServletWebServerFactory tomcatServletWebServerFactory(){
+        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(){
+            @Override
+            protected void postProcessContext(Context context) {
+                SecurityConstraint constraint = new SecurityConstraint();
+                constraint.setUserConstraint("CONFIDENTIAL");
+                SecurityCollection collection = new SecurityCollection();
+                collection.addPattern("/*");
+                constraint.addCollection(collection);
+                context.addConstraint(constraint);
+            }
+        };
+//        factory.addAdditionalTomcatConnectors(connector());
+        return factory;
+    }
+}

+ 61 - 0
pump-common/src/main/java/com/tuoren/common/config/SwaggerConfig.java

@@ -0,0 +1,61 @@
+package com.tuoren.common.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ApiKey;
+import springfox.documentation.service.AuthorizationScope;
+import springfox.documentation.service.SecurityReference;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Create by fanfan
+ * Date: 2020-03-16 9:27
+ */
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+    @Bean
+    public Docket createRestApi(){
+        return new Docket(DocumentationType.SWAGGER_2)
+                .apiInfo(apiInfo())
+                .select()
+                .apis(RequestHandlerSelectors.basePackage("com.tuoren.web" ))
+                .paths(PathSelectors.any())
+                .build()
+                // 添加登录验证
+                .securitySchemes(securitySchemes());
+    }
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                .title("网络泵外网互联技术后台管理系统")
+                .description("网络泵外网互联技术后台管理系统API文档,下面是基本的接口,切勿随意修改,如有需求,请及时向本人微信说明,接口仅供参考。")
+                .version("2.0")
+                .build();
+    }
+
+    private List<ApiKey> securitySchemes() {
+        //设置请求头信息
+        List<ApiKey> result = new ArrayList<>();
+        ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
+        result.add(apiKey);
+        return result;
+    }
+
+    private List<SecurityReference> defaultAuth() {
+        List<SecurityReference> result = new ArrayList<>();
+        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
+        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
+        authorizationScopes[0] = authorizationScope;
+        result.add(new SecurityReference("Authorization", authorizationScopes));
+        return result;
+    }
+}

+ 29 - 0
pump-common/src/main/java/com/tuoren/common/constant/CommonConstant.java

@@ -0,0 +1,29 @@
+package com.tuoren.common.constant;
+
+public final class CommonConstant {
+
+	// 保持呼吸消息队列
+	public static final String QUEUE_BREATH = "cloud.breath";
+
+	// 医院信息消息队列
+	public static final String QUEUE_HOSPITAL = "cloud.hospital";
+
+	// 病员消息队列
+	public static final String QUEUE_PATIENT = "cloud.patient";
+
+	// 网络泵消息队列
+	public static final String QUEUE_PUMP = "cloud.pump";
+
+	// 医生评分消息队列
+	public static final String QUEUE_ANALGESICSCORE = "cloud.analgesicScore";
+
+	// 医院配置信息队列
+	public static final String QUEUE_CONFIG = "cloud.config";
+
+//	public static final Integer PUMP_HOSPITAL= 0;
+	public static final Boolean PUMP_FAMILY = false;
+
+	public static final String MQBREATH_ONLINE = "1"; // 消息队列监听在线
+
+	public static final String MQBREATH_OFFLINE = "0"; // 消息队列监听离线
+}

+ 46 - 0
pump-common/src/main/java/com/tuoren/common/entity/MvcEntity.java

@@ -0,0 +1,46 @@
+package com.tuoren.common.entity;
+
+import lombok.*;
+
+/**
+ * @Author: lifang
+ * @Description: 存放视图信息
+ * @Date: Created in 18:54 2020/9/3
+ */
+@Data
+@ToString
+@EqualsAndHashCode(exclude = {"url","description"})
+@NoArgsConstructor
+@AllArgsConstructor
+public class MvcEntity {
+    /**
+     * 方法名称
+     */
+    private String methodName;
+    /**
+     * 类名
+     */
+    private String className;
+
+    /**
+     * restful操作
+     */
+    private String operation;
+
+    /**
+     * 访问路径
+     */
+    private String url;
+
+    /**
+     * 接口描述
+     */
+    private String description;
+
+    public MvcEntity(String methodName, String className, String operation, String url) {
+        this.methodName = methodName;
+        this.className = className;
+        this.operation = operation;
+        this.url = url;
+    }
+}

+ 31 - 0
pump-common/src/main/java/com/tuoren/common/exception/ApiException.java

@@ -0,0 +1,31 @@
+package com.tuoren.common.exception;
+import com.tuoren.common.api.IErrorCode;
+
+/**
+ *  自定义API异常
+ * Create by fanfan
+ * Date: 2020-03-16 9:33
+ */
+public class ApiException extends RuntimeException {
+    private IErrorCode errorCode;
+    public ApiException(IErrorCode errorCode) {
+        super(errorCode.getMessage());
+        this.errorCode = errorCode;
+    }
+
+    public ApiException(String message) {
+        super(message);
+    }
+
+    public ApiException(Throwable cause) {
+        super(cause);
+    }
+
+    public ApiException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public IErrorCode getErrorCode() {
+        return errorCode;
+    }
+}

+ 78 - 0
pump-common/src/main/java/com/tuoren/common/exception/GlobalExceptionHandler.java

@@ -0,0 +1,78 @@
+package com.tuoren.common.exception;
+
+import com.tuoren.common.api.CommonResult;
+import com.tuoren.common.api.ResultCode;
+import com.tuoren.common.exception.ApiException;
+
+import org.apache.shiro.authc.AccountException;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.authz.UnauthenticatedException;
+import org.apache.shiro.authz.UnauthorizedException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Create by fanfan
+ * Date: 2020-03-16 9:50
+ */
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+    @ResponseBody
+    @ExceptionHandler(value = ApiException.class)
+    public CommonResult handle(ApiException e) {
+        if (e.getErrorCode() != null) {
+            return CommonResult.failed(e.getErrorCode());
+        }
+        return CommonResult.failed(e.getMessage());
+    }
+
+    /**
+     * 处理Shiro权限拦截异常
+     * 如果返回JSON数据格式请加上 @ResponseBody注解
+     *
+     */
+    @ResponseBody
+    @ExceptionHandler(value = AuthorizationException.class)
+    public CommonResult defaultErrorHandler() {
+        return CommonResult.failed(ResultCode.FORBIDDEN);
+    }
+
+    @ResponseBody
+    @ExceptionHandler(value = AuthenticationException.class)
+    public CommonResult shiroAuthHandler() {
+        return CommonResult.failed(ResultCode.FORBIDDEN);
+    }
+
+    @ResponseBody
+    @ExceptionHandler(value = AccountException.class)
+    public CommonResult shiroAccoundHandler() {
+        return CommonResult.failed(ResultCode.UNAUTHORIZED);
+    }
+
+    /**
+     * 授权异常
+     *
+     * @param request
+     * @param response
+     * @param e
+     * @return
+     */
+    @ExceptionHandler(UnauthorizedException.class)
+    @ResponseBody
+    public CommonResult defaultAuthorizedExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
+        return CommonResult.failed("未授权");
+    }
+
+    @ExceptionHandler(UnauthenticatedException.class)
+    @ResponseBody
+    public CommonResult defaultAuthenticatedExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
+        return CommonResult.failed("未认证");
+    }
+
+}

+ 131 - 0
pump-common/src/main/java/com/tuoren/common/mbg/CodeGenerator.java

@@ -0,0 +1,131 @@
+package com.tuoren.common.mbg;
+
+import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.generator.AutoGenerator;
+import com.baomidou.mybatisplus.generator.InjectionConfig;
+import com.baomidou.mybatisplus.generator.config.*;
+import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
+import com.baomidou.mybatisplus.generator.engine.BeetlTemplateEngine;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+/**
+ * @author fanfan
+ * @date 2020-07-01 8:20
+ */
+public class CodeGenerator {
+    /**
+     * <p>
+     * 读取控制台内容
+     * </p>
+     */
+    public static String scanner(String tip) {
+        Scanner scanner = new Scanner(System.in);
+        StringBuilder help = new StringBuilder();
+        help.append("请输入" + tip + ":");
+        System.out.println(help.toString());
+        if (scanner.hasNext()) {
+            String ipt = scanner.next();
+            if (StringUtils.isNotEmpty(ipt)) {
+                return ipt;
+            }
+        }
+        throw new MybatisPlusException("请输入正确的" + tip + "!");
+    }
+
+    public static void main(String[] args) {
+        // 代码生成器
+        AutoGenerator mpg = new AutoGenerator();
+
+        // 全局配置
+        GlobalConfig gc = new GlobalConfig();
+        String projectPath = System.getProperty("user.dir");
+        gc.setOutputDir(projectPath + "/pump-web/src/main/java");
+        gc.setAuthor("fanfan");
+        gc.setOpen(false);
+        gc.setEntityName("%sEntity");
+        gc.setSwagger2(true);// 实体属性 Swagger2 注解
+//        生成 mapper resultmap
+        gc.setBaseResultMap(true);
+        // 生成 mapper 里面的列名
+//        gc.setBaseColumnList(true);
+        mpg.setGlobalConfig(gc);
+
+        // 数据源配置
+        DataSourceConfig dsc = new DataSourceConfig();
+        dsc.setUrl("jdbc:mysql://localhost:3306/netpump?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC");
+        // dsc.setSchemaName("public");
+        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
+        dsc.setUsername("root");
+        dsc.setPassword("root");
+        mpg.setDataSource(dsc);
+
+        // 包配置
+        PackageConfig pc = new PackageConfig();
+//        pc.setModuleName(scanner("模块名"));
+        pc.setParent("com.tuoren.web.layer");
+        mpg.setPackageInfo(pc);
+
+        // 自定义配置
+        InjectionConfig cfg = new InjectionConfig() {
+            @Override
+            public void initMap() {
+                // to do nothing
+            }
+        };
+
+        // 如果模板引擎是
+        String templatePath = "/templates/mapper.xml.btl";
+        // 自定义输出配置
+        List<FileOutConfig> focList = new ArrayList<>();
+        // 自定义配置会被优先输出
+        focList.add(new FileOutConfig(templatePath) {
+            @Override
+            public String outputFile(TableInfo tableInfo) {
+                // 自定义输出文件名 , 如果你 entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
+//                return projectPath + "/pump-web/src/main/resources/mapper/" + pc.getModuleName()
+//                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
+                return projectPath + "/pump-web/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
+            }
+        });
+
+        cfg.setFileOutConfigList(focList);
+        mpg.setCfg(cfg);
+
+        // 配置模板
+        TemplateConfig templateConfig = new TemplateConfig();
+        templateConfig.setXml(null);
+//        templateConfig.setController(projectPath+"/pump-web/src/main/resources/templates/controller2.java");
+        templateConfig.setController("/templates/controller2.java");
+        mpg.setTemplate(templateConfig);
+
+        // 策略配置
+        StrategyConfig strategy = new StrategyConfig();
+        strategy.setNaming(NamingStrategy.underline_to_camel);
+        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
+//        strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
+        strategy.setEntityLombokModel(true);
+        // 是否为构建者模型
+        strategy.setEntityBuilderModel(true);
+        strategy.setRestControllerStyle(true);
+        // 公共父类
+//        strategy.setSuperControllerClass("你自己的父类控制器,没有就不用设置!");
+        // 写于父类中的公共字段
+//        strategy.setSuperEntityColumns("id");
+        strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
+        strategy.setControllerMappingHyphenStyle(true);
+        strategy.setTablePrefix(pc.getModuleName() + "_");
+        mpg.setStrategy(strategy);
+        mpg.setTemplateEngine(new BeetlTemplateEngine());
+        mpg.execute();
+
+
+
+
+    }
+}

+ 21 - 0
pump-common/src/main/java/com/tuoren/common/properties/MqttPushProperties.java

@@ -0,0 +1,21 @@
+package com.tuoren.common.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author fanfan
+ * @date 2021-05-08 14:54
+ */
+@ConfigurationProperties("mqtt")
+@Data
+@Configuration
+public class MqttPushProperties {
+    private String username;
+    private String password;
+    private int defaultQos;
+    private String pushUrl="http://192.168.100.32:18083/api/v4/mqtt/publish";
+    private String defaultTopic="tuoren/netpump/alarm/%s";
+    private String clientId="TUOREN";
+}

+ 23 - 0
pump-common/src/main/java/com/tuoren/common/push/BasePush.java

@@ -0,0 +1,23 @@
+package com.tuoren.common.push;
+
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.profile.DefaultProfile;
+import com.aliyuncs.profile.IClientProfile;
+import com.tuoren.common.utils.ConstastUtils;
+
+/**
+  * @Description: 推送服务
+  * @Author: fanfan
+  * @Date: 2020-07-02  11:06
+  */
+public class BasePush {
+    protected static DefaultAcsClient client;
+
+    public static void base() throws Exception {
+        String region = ConstastUtils.REGIONID;
+        String accessKeyId = ConstastUtils.ACCESSKEYID;
+        String accessKeySecret = ConstastUtils.ACCESSKEYSECRET;
+        IClientProfile profile = DefaultProfile.getProfile(region, accessKeyId, accessKeySecret);
+        client = new DefaultAcsClient(profile);
+    }
+}

+ 112 - 0
pump-common/src/main/java/com/tuoren/common/push/Push.java

@@ -0,0 +1,112 @@
+package com.tuoren.common.push;
+
+import cn.hutool.core.lang.UUID;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.aliyuncs.http.MethodType;
+import com.aliyuncs.http.ProtocolType;
+import com.aliyuncs.push.model.v20160801.*;
+import com.aliyuncs.utils.ParameterHelper;
+import com.sun.org.apache.bcel.internal.generic.PUSH;
+import com.tuoren.common.properties.MqttPushProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.protocol.HTTP;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.Date;
+
+/**
+  * @Description: 推送
+  * @Author: fanfan
+  * @Date: 2020-07-02  11:07
+  */  
+@Component
+@Slf4j
+@EnableConfigurationProperties(MqttPushProperties.class)
+public class Push extends BasePush {
+
+    @Autowired
+    private MqttPushProperties pushProperties;
+    @PostConstruct
+    public void pushInit() throws Exception{
+        base();
+    }
+    /**
+     * 推送高级接口
+     * <p>
+     * 参见文档 https://help.aliyun.com/document_detail/48089.html
+     * //
+     */
+    @Async
+    public void AdvancedPush(String account,String title, String info, String appKey,String userCode) throws Exception {
+        try {
+//            PushRequest pushRequest = new PushRequest();
+//            //安全性比较高的内容建议使用HTTPS
+//            pushRequest.setProtocol(ProtocolType.HTTP);
+//            //内容较大的请求,使用POST请求
+//            pushRequest.setMethod(MethodType.POST);
+//            // 推送目标
+//            pushRequest.setAppKey(Long.valueOf(appKey));
+//            pushRequest.setTarget("ACCOUNT"); //推送目标: DEVICE:按设备推送 ALIAS : 按别名推送 ACCOUNT:按帐号推送  TAG:按标签推送; ALL: 广播推送
+//            pushRequest.setTargetValue(account); //根据Target来设定,如Target=DEVICE, 则对应的值为 设备id1,设备id2. 多个值使用逗号分隔.(帐号与设备有一次最多100个的限制)
+////        pushRequest.setTarget("ALL"); //推送目标: device:推送给设备; account:推送给指定帐号,tag:推送给自定义标签; all: 推送给全部
+////        pushRequest.setTargetValue("ALL"); //根据Target来设定,如Target=device, 则对应的值为 设备id1,设备id2. 多个值使用逗号分隔.(帐号与设备有一次最多100个的限制)
+//            pushRequest.setPushType("MESSAGE"); // 消息类型 MESSAGE NOTICE
+//            pushRequest.setDeviceType("ALL"); // 设备类型 ANDROID iOS ALL.
+//
+//            // 推送配置
+//            pushRequest.setTitle(title); // 消息的标题
+//            pushRequest.setBody(info); // 消息的内容
+//
+//            // 推送配置: Android
+//            pushRequest.setAndroidNotifyType("BOTH");//通知的提醒方式 "VIBRATE" : 震动 "SOUND" : 声音 "BOTH" : 声音和震动 NONE : 静音
+//            pushRequest.setAndroidNotificationBarType(1);//通知栏自定义样式0-100
+//            pushRequest.setAndroidNotificationBarPriority(1);//通知栏自定义样式0-100
+//            pushRequest.setAndroidOpenType("URL"); //点击通知后动作 "APPLICATION" : 打开应用 "ACTIVITY" : 打开AndroidActivity "URL" : 打开URL "NONE" : 无跳转
+//            pushRequest.setAndroidOpenUrl("http://www.aliyun.com"); //Android收到推送后打开对应的url,仅当AndroidOpenType="URL"有效
+//            pushRequest.setAndroidActivity("com.alibaba.push2.demo.XiaoMiPushActivity"); // 设定通知打开的activity,仅当AndroidOpenType="Activity"有效
+//            pushRequest.setAndroidMusic("default"); // Android通知音乐
+//            pushRequest.setAndroidXiaoMiActivity("com.ali.demo.MiActivity");//设置该参数后启动小米托管弹窗功能, 此处指定通知点击后跳转的Activity(托管弹窗的前提条件:1. 集成小米辅助通道;2. StoreOffline参数设为true)
+//            pushRequest.setAndroidXiaoMiNotifyTitle("Mi title");
+//            pushRequest.setAndroidXiaoMiNotifyBody("MiActivity Body");
+//            pushRequest.setAndroidExtParameters("{\"k1\":\"android\",\"k2\":\"v2\"}"); //设定通知的扩展属性。(注意 : 该参数要以 json map 的格式传入,否则会解析出错)
+//            pushRequest.setAndroidNotificationChannel("alicloud_android_push");
+//
+//            // 推送控制
+//            Date pushDate = new Date(System.currentTimeMillis()); // 30秒之间的时间点, 也可以设置成你指定固定时间
+//            String pushTime = ParameterHelper.getISO8601Time(pushDate);
+//            pushRequest.setPushTime(pushTime); // 延后推送。可选,如果不设置表示立即推送
+//            String expireTime = ParameterHelper.getISO8601Time(new Date(System.currentTimeMillis() + 12 * 3600 * 1000)); // 12小时后消息失效, 不会再发送
+//            pushRequest.setExpireTime(expireTime);
+//            pushRequest.setStoreOffline(true); // 离线消息是否保存,若保存, 在推送时候,用户即使不在线,下一次上线则会收到
+//
+//            PushResponse pushResponse = client.getAcsResponse(pushRequest);
+//            log.info("RequestId: "+pushResponse.getRequestId()+", MessageID: "+pushResponse.getMessageId()+"\n");
+            PushJsonBean pushJsonBean =  new PushJsonBean();
+            pushJsonBean.setTopic(String.format(pushProperties.getDefaultTopic(),userCode));
+            pushJsonBean.setQos(pushProperties.getDefaultQos());
+            pushJsonBean.setRetain(false);
+            pushJsonBean.setPayload(info);
+            pushJsonBean.setClient_id(pushProperties.getClientId());
+//             HttpUtil.post("http://api.xxx.com", JSONObject.toJSONString(pushJsonBean), 5000);
+            HttpRequest post = HttpUtil.createPost(pushProperties.getPushUrl());
+            post.body(JSONObject.toJSONString(pushJsonBean));
+            post.basicAuth(account,appKey);
+            post.execute();
+        } catch (Exception e) {
+            log.info("推送报警接口出现错误>>>>>>> " + e.getMessage());
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        Push push = new Push();
+        push.AdvancedPush("admin","","ceshi","public","123");
+    }
+}

+ 47 - 0
pump-common/src/main/java/com/tuoren/common/push/PushJsonBean.java

@@ -0,0 +1,47 @@
+package com.tuoren.common.push;
+
+/**
+ * @author fanfan
+ * @date 2021-04-28 17:26
+ */
+public class PushJsonBean {
+        private String topic;
+        private String payload;
+        private int qos;
+        private boolean retain;
+        private String client_id;
+        public void setTopic(String topic) {
+            this.topic = topic;
+        }
+        public String getTopic() {
+            return topic;
+        }
+
+        public void setPayload(String payload) {
+            this.payload = payload;
+        }
+        public String getPayload() {
+            return payload;
+        }
+
+        public void setQos(int qos) {
+            this.qos = qos;
+        }
+        public int getQos() {
+            return qos;
+        }
+
+        public void setRetain(boolean retain) {
+            this.retain = retain;
+        }
+        public boolean getRetain() {
+            return retain;
+        }
+
+        public void setClient_id(String client_id) {
+            this.client_id = client_id;
+        }
+        public String getClient_id() {
+            return client_id;
+        }
+}

+ 41 - 0
pump-common/src/main/java/com/tuoren/common/redis/RedisService.java

@@ -0,0 +1,41 @@
+package com.tuoren.common.redis;
+
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+  * @Description: redis  
+  * @Author: fanfan
+  * @Date: 2020-07-02  11:05
+  */  
+@Service
+public interface RedisService {
+    // 设置数据
+    void set(String key, String value);
+
+    // 获取数据
+    String get(String key);
+
+    // 设置过期时间
+    boolean expire(String key, long expire);
+
+    // 删除数据
+    void remove(String key);
+
+    long remove(Collection keys);
+
+    // 自增操作
+    Long increment(String key, long delta);
+
+    // 获取所有key
+   Set<String> getKeys(String key);
+
+   //设置过期键
+   void setAndExpire(String key, String value,long expireTime);
+
+   //运行lua脚本
+   <T> T runLua(String fileClasspath, Class<T> returnType, List<String> keys, Object...values);
+}

+ 85 - 0
pump-common/src/main/java/com/tuoren/common/redis/impl/RedisServiceImpl.java

@@ -0,0 +1,85 @@
+package com.tuoren.common.redis.impl;
+
+
+import com.tuoren.common.redis.RedisService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.scripting.support.ResourceScriptSource;
+import org.springframework.stereotype.Service;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Create by fanfan
+ * Date: 2020-04-06 8:20
+ */
+@Service
+@Slf4j
+public class RedisServiceImpl implements RedisService {
+
+    @Autowired
+    private StringRedisTemplate stringRedisTemplate;
+
+    @Override
+    public void set(String key, String value) {
+        stringRedisTemplate.opsForValue().set(key,value);
+    }
+
+    @Override
+    public String get(String key) {
+        return stringRedisTemplate.opsForValue().get(key);
+    }
+
+    @Override
+    public boolean expire(String key, long expire) {
+        return stringRedisTemplate.expire(key, expire, TimeUnit.SECONDS);
+    }
+
+    @Override
+    public void remove(String key) {
+        stringRedisTemplate.delete(key);
+    }
+
+    @Override
+    public long remove(Collection keys){
+       return stringRedisTemplate.delete(keys);
+    }
+
+    @Override
+    public Long increment(String key, long delta) {
+        return stringRedisTemplate.opsForValue().increment(key,delta);
+    }
+
+    @Override
+    public Set<String> getKeys(String key) {
+        return stringRedisTemplate.keys( key );
+    }
+
+    @Override
+    public void setAndExpire(String key, String value, long expireTime) {
+        List<String > keys = new ArrayList<>();
+        keys.add(key);
+        keys.add(value);
+        runLua("/lua/setAndExpire.lua", String.class,keys,String.valueOf(expireTime));
+    }
+
+    @Override
+    public <T> T runLua(String fileClasspath, Class<T> returnType, List<String> keys, Object... values) {
+        DefaultRedisScript<T> redisScript  = new DefaultRedisScript<>();
+        ResourceScriptSource resourceScriptSource = new ResourceScriptSource(new ClassPathResource(fileClasspath));
+        redisScript.setScriptSource(resourceScriptSource);
+        redisScript.setResultType(returnType);
+        T execute=null;
+        try {
+            execute = stringRedisTemplate.execute(redisScript, keys, values);
+        }catch (Exception e){
+            log.error("keys---{},values---{},luaScript running breakdown,{}",keys.toString(),Arrays.toString(values),e.getMessage());
+        }
+        return execute;
+    }
+
+}

+ 57 - 0
pump-common/src/main/java/com/tuoren/common/shiro/ShiroFilter.java

@@ -0,0 +1,57 @@
+package com.tuoren.common.shiro;
+
+import com.alibaba.fastjson.JSON;
+import com.tuoren.common.api.CommonResult;
+import com.tuoren.common.api.ResultCode;
+import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Create by fanfan
+ * Date: 2020-03-31 17:08
+ */
+public class ShiroFilter extends FormAuthenticationFilter {
+    /**
+     * 如果isAccessAllowed返回false 则执行onAccessDenied
+     * @param request
+     * @param response
+     * @param mappedValue
+     * @return
+     */
+    @Override
+    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
+        if (request instanceof HttpServletRequest) {
+            if (((HttpServletRequest) request).getMethod().toUpperCase().equals("OPTIONS")) {
+                return true;
+            }
+        }
+        return super.isAccessAllowed(request, response, mappedValue);
+    }
+
+    /**
+     * 在访问controller前判断是否登录,返回json,不进行重定向。
+     *
+     * @param request
+     * @param response
+     * @return true-继续往下执行,false-该filter过滤器已经处理,不继续执行其他过滤器
+     * @throws Exception
+     */
+    @Override
+    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
+        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
+        //这里是个坑,如果不设置的接受的访问源,那么前端都会报跨域错误,因为这里还没到corsConfig里面
+        httpServletResponse.setHeader("Access-Control-Allow-Origin", ((HttpServletRequest) request).getHeader("Origin"));
+        httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
+        httpServletResponse.setCharacterEncoding("UTF-8");
+        httpServletResponse.setContentType("application/json");
+        httpServletResponse.getWriter().write(JSON.toJSONString(CommonResult.failed(ResultCode.UNAUTHORIZED)));
+        return false;
+    }
+
+
+}

+ 22 - 0
pump-common/src/main/java/com/tuoren/common/shiro/ShiroSessionIdGenerator.java

@@ -0,0 +1,22 @@
+package com.tuoren.common.shiro;
+
+import com.tuoren.common.utils.ConstastUtils;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
+import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
+
+import java.io.Serializable;
+
+/**
+ * 自定义SessionId生成器
+ * Create by fanfan
+ * Date: 2020-04-06 8:45
+ */
+public class ShiroSessionIdGenerator implements SessionIdGenerator {
+    @Override
+    public Serializable generateId(Session session) {
+        Serializable sessionId = new JavaUuidSessionIdGenerator().generateId(session);
+        System.out.println(String.format(ConstastUtils.REDIS_PREFIX_LOGIN,sessionId));
+        return String.format(ConstastUtils.REDIS_PREFIX_LOGIN,sessionId);
+    }
+}

+ 42 - 0
pump-common/src/main/java/com/tuoren/common/shiro/ShiroSessionManager.java

@@ -0,0 +1,42 @@
+package com.tuoren.common.shiro;
+
+import cn.hutool.core.util.StrUtil;
+import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
+import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
+import org.apache.shiro.web.util.WebUtils;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import java.io.Serializable;
+
+/**
+ * Create by fanfan
+ * Date: 2020-04-01 9:49
+ */
+public class ShiroSessionManager extends DefaultWebSessionManager {
+    //定义常量
+    private static final String AUTHORIZATION = "Authorization";
+    private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
+
+    public ShiroSessionManager(){
+        super();
+        this.setDeleteInvalidSessions(true);
+    }
+    /**
+     * 重写方法实现从请求头获取Token便于接口统一
+     * 每次请求进来,Shiro会去从请求头找Authorization这个key对应的Value(Token)
+     */
+    @Override
+    public Serializable getSessionId(ServletRequest request, ServletResponse response) {
+        String token = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
+        if(!StrUtil.isEmpty(token)){
+            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID,token);
+            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID,Boolean.TRUE);
+            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,REFERENCED_SESSION_ID_SOURCE);
+            return token;
+        } else {
+//            System.out.println("getSessionId: 这里没有设置的 token: " + token);
+            return null;
+        }
+    }
+}

+ 56 - 0
pump-common/src/main/java/com/tuoren/common/utils/AESUtils.java

@@ -0,0 +1,56 @@
+package com.tuoren.common.utils;
+
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
+import lombok.Data;
+import sun.misc.BASE64Decoder;
+import sun.misc.BASE64Encoder;
+
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Create by fanfan
+ * Date: 2020-04-06 10:39
+ */
+@Data
+public class AESUtils {
+
+    private static final long serialVersionUID = 1L;
+
+    // 密钥
+    private String key;
+
+    // 生成密匙
+    public static byte[] keys(){
+        // 生成 keys,使用时需要 toString() 转换成 String 类型
+        return SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
+//      return "2550e1be21ba49a1".getBytes();
+    }
+
+    // 加密
+    public static String aesEncrypt(String str, String key) throws Exception {
+        if (str == null || key == null) return null;
+        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "AES"));
+        byte[] bytes = cipher.doFinal(str.getBytes("utf-8"));
+        return new BASE64Encoder().encode(bytes);
+    }
+
+    // 解密
+    public static String aesDecrypt(String str, String key) throws Exception {
+        try{
+            if (str == null || key == null) return null;
+            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "AES"));
+            byte[] bytes = new BASE64Decoder().decodeBuffer(str);
+            bytes = cipher.doFinal(bytes);
+            return new String(bytes, "utf-8");
+        } catch (IllegalBlockSizeException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}

+ 52 - 0
pump-common/src/main/java/com/tuoren/common/utils/AsyncManager.java

@@ -0,0 +1,52 @@
+package com.tuoren.common.utils;
+
+import java.util.TimerTask;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class AsyncManager {
+    /**
+     * 异步操作任务调度线程池
+     */
+    private ThreadLocal<ScheduledThreadPoolExecutor> threadLocal=new ThreadLocal<>();
+    private AsyncManager(){
+
+    }
+    private static class AsyncManagerFactory{
+        static AsyncManager asyncManager=new AsyncManager();
+        static AsyncManager getAsyncManager(){
+            return asyncManager;
+        }
+    }
+
+    private ScheduledThreadPoolExecutor getExecutor(){
+        ScheduledThreadPoolExecutor executor = threadLocal.get();
+        if(executor==null){
+            executor = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),new ThreadPoolExecutor.CallerRunsPolicy());
+        }
+        threadLocal.set(executor);
+        return executor;
+    }
+    public static AsyncManager getAsyncManager(){
+        return AsyncManagerFactory.getAsyncManager();
+    }
+
+    public void execute(TimerTask task){
+        ScheduledThreadPoolExecutor executor=getExecutor();
+        executor.execute(task);
+    }
+
+    public void execute(TimerTask task,long delay){
+        ScheduledThreadPoolExecutor executor=getExecutor();
+        executor.schedule(task,delay, MILLISECONDS);
+    }
+
+    public void execute(TimerTask task,long delay,TimeUnit timeUnit){
+        ScheduledThreadPoolExecutor executor=getExecutor();
+        executor.schedule(task,delay,timeUnit);
+    }
+
+}

+ 120 - 0
pump-common/src/main/java/com/tuoren/common/utils/ConstastUtils.java

@@ -0,0 +1,120 @@
+package com.tuoren.common.utils;
+
+/**
+ * Create by fanfan
+ * Date: 2020-03-16 16:05
+ */
+public class ConstastUtils {
+
+    /**
+     * 用户默认密码
+     */
+    public static final String USER_DEFAULT_PWD="123456";
+
+    /**
+     * 菜单可用状态  0不可用   1可用
+     */
+    public static final Object AVAILABLE_TRUE = 1;
+    public static final Object AVAILABLE_FALSE = 0;
+
+    /**
+     * 菜单和权限类型   menu  菜单   permission  权限
+     */
+    public static final String TYPE_MENU = "menu";
+    public static final String TYPE_PERMISSION = "permission";
+
+    /**
+     * 用户类型   [ 0 超级管理员 ,1 管理员,2 普通用户 ]
+     */
+    public static final Integer USER_TYPE_SUPER = 0;
+    public static final Integer USER_TYPE_NORMAL = 1;
+    public static final Integer HASHITERATIONS = 2;
+
+
+    /**
+     * 日志最大内存量
+     */
+    public final static long LOG_MAX_MEMEORY=10*1024*1024;
+    /**
+     * 日志保存路径
+     */
+    public final static String LOG_PATH=System.getProperty("user.dir") +"/mylog/log.";
+    /**
+     * 日志填充符
+     */
+    public static final String LINE= String.format("%70s", "").replace("","-");
+
+    /**
+     * AES 加密密匙
+     */
+    public static final String KEYS = "2550e1be21ba49a1";
+
+    /**
+     * 幂等性token key值
+     */
+    public static final String IDEMPOTENTTOKEN = "IdempotentToken";
+    /**
+     * 限流 redisBucket key值
+     */
+    public static final String REDISBUCKETT = "redisBucket";
+
+    /**
+     * netty 日志保存路径
+     */
+    public static final String NETTY_LOG_PATH=System.getProperty("user.dir") +"/mylog/nettylog.";
+
+    /**
+     *  推送 手机端 appKey
+     */
+//    public static final String PHONE_APP_KEY  = "30549452";
+    public static final String PHONE_APP_KEY  = "public";
+    /**
+     *  推送 Pad端 appKey
+     */
+//    public static final String PAD_APP_KEY  = "30537902";
+    public static final String PAD_APP_KEY  = "public";
+    /**
+     * 推送KeyId 和 密匙
+     */
+    public static final String ACCESSKEYID  = "LTAI4G7FA9ytMc76oNkJ45YJ";
+    public static final String ACCESSKEYSECRET = "R7hOvMfiHb0PYroDqUDXAYgB9htQss";
+    /**
+     * region
+     */
+    public static final String REGIONID  = "cn-hangzhou";
+    /**
+     * CGlig动态代理对象名所包含字段
+     */
+    public static final String CGLIBOBJ="$$Enhancer";
+
+    /**
+     *
+     */
+    public static final String PUSH_PATH=System.getProperty("user.dir") +"/myLog/pushlog.";
+
+    /**
+     * TOKEN前缀
+     */
+    public static final String REDIS_PREFIX_LOGIN = "login_token_%s";
+    /**
+     * 设置redis 前缀和过期时间
+     */
+    public static final  String REDIS_AUTH_CODE = "portal:authCode:";
+    public static final  String REDIS_USER_CODE  = "portal:user:";
+    public static final  String REDIS_SESSION_CODE  = "shiro:session:";
+    public static final  long REDIS_EXPIRE = 60 * 60 * 10;
+    // 获取所有的 shiro:session
+    public static final  String REDIS_SESSION_CODE_ALL  = "shiro:session:login_token_*";
+    public static final  String REDIS_USER_CODE_ALL  = "portal:user:login_token_*";
+    // 设置队列路由键
+    public static final String ROUTING_KEY = "hospital.";
+    // 设置直连交换机
+    public static final String EXCHANGE_NAME= "amq.direct";
+
+    // 获取所有的 reidsKeys
+    public static final  String REDIS_CODE_ALL  = "*";
+
+    // netty 接口
+    public static final Integer NETTY_PORT = 7001;
+
+}

+ 49 - 0
pump-common/src/main/java/com/tuoren/common/utils/DiffTimeUtils.java

@@ -0,0 +1,49 @@
+package com.tuoren.common.utils;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * @author fanfan
+ * @date 2020-07-06 11:09
+ */
+public class DiffTimeUtils {
+    /**
+     * @Description:  TCP 接收数据时时差比较
+     * @Author: fanfan
+     * @CreateTime: 2020-05-11  10:44
+     * @Param:   t1 数据库最后插入时间
+     * @Param:   t2 最新数据时间
+     * @Return:
+     */
+    public Boolean pumpTimeDiff(LocalDateTime t1, LocalDateTime t2){
+//        System.out.println("t1: "+ t1);
+//        System.out.println("t1: "+ t2);
+        Date dateT1 = DateUtil.parse(t1.toString().replaceAll("T"," "));
+        Date dateT2 = DateUtil.parse(t2.toString().replaceAll("T"," "));
+        if(dateT1.getTime() <= dateT2.getTime()){
+            System.out.println("True,可插入数据库");
+            return true;
+        } else {
+            System.out.println("False,不可插入数据库");
+            return false;
+        }
+    }
+
+    /**
+     * @Description:  泵发送数据时间对比
+     * @Author: fanfan
+     * @CreateTime: 2020-05-18  21:44
+     * @Param:   t1 数据库最后插入时间
+     * @Return:
+     */
+    public Boolean pushTimeDiff(LocalDateTime t1, int range){
+        Date dateT1 = DateUtil.parse(t1.toString().replaceAll("T"," "));
+        long betweenMin = DateUtil.between(dateT1, DateTime.now(), DateUnit.MINUTE);
+        return betweenMin <= range;
+    }
+}

+ 18 - 0
pump-common/src/main/java/com/tuoren/common/utils/LocalDateTimeUtil.java

@@ -0,0 +1,18 @@
+package com.tuoren.common.utils;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+
+public class LocalDateTimeUtil {
+
+	public static LocalDateTime longToLocalTime(Long time) {
+		LocalDateTime dateTime = null;
+		if(13 == time.toString().length()) {
+			dateTime = Instant.ofEpochMilli(time).atZone(ZoneId.systemDefault()).toLocalDateTime();
+		}else if(10 == time.toString().length()) {
+			dateTime = Instant.ofEpochSecond(time).atZone(ZoneId.systemDefault()).toLocalDateTime();
+		}
+		return dateTime;
+	}
+}

+ 35 - 0
pump-common/src/main/java/com/tuoren/common/utils/RabbitUtil.java

@@ -0,0 +1,35 @@
+package com.tuoren.common.utils;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * @Description  rabbit工具类 
+ * @Author wulianwei  
+ * @Date 2020-07-08 10:54
+ */
+public class RabbitUtil {
+	
+	/**
+	 * @Description 处理字节信息
+	 * @Author wulianwei
+	 * @Date 2020-07-08 10:54
+	 * @Return  String
+	 */
+	public static String covertHandleStringMessage(String message) {
+		if(message.matches("(\\d+,\\d+)+")) {//字节码
+			String [] strs = message.split(",");
+			byte[] bytes = new byte[strs.length];
+			for(int i=0; i<strs.length; i++) {
+				bytes[i] = Byte.parseByte(strs[i]);
+			}
+			try {
+				message = new String(bytes, "UTF-8");
+			} catch (UnsupportedEncodingException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		return message;
+	}
+
+}

+ 29 - 0
pump-common/src/main/java/com/tuoren/common/utils/SpringUtil.java

@@ -0,0 +1,29 @@
+package com.tuoren.common.utils;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * Create by fanfan
+ * Date: 2020-03-18 11:41
+ */
+@Component
+public class SpringUtil implements ApplicationContextAware {
+    private static  ApplicationContext context;
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        context  = applicationContext;
+    }
+
+    /**
+     * 通过Name返回指定的Bean
+     *
+     * @Author Sans
+     * @CreateTime 2019/6/17 16:03
+     */
+    public static <T> T getBean(Class<T> beanClass) {
+        return context.getBean(beanClass);
+    }
+}

+ 38 - 0
pump-common/src/main/java/com/tuoren/common/utils/WebUtils.java

@@ -0,0 +1,38 @@
+package com.tuoren.common.utils;
+
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author fanfan
+ * @date 2020-07-03 14:45
+ */
+public class WebUtils {
+    public static ServletRequestAttributes getServletRequestAttributes() {
+        return (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+    }
+    /**
+     * 得到request
+     * @return
+     */
+    public static HttpServletRequest getRequest(){
+        HttpServletRequest request = getServletRequestAttributes().getRequest();
+        return request;
+    }
+
+    /**
+     * 判断设备
+     * @return
+     */
+    public static String getUserAgent(){
+        String agent = getRequest().getHeader("user-agent");
+        if(agent.contains("TuoRenPhone")){
+            return "Phone";
+        } else if( agent.contains("TuoRenPad")){
+            return "Pad";
+        };
+        return null;
+    }
+}

+ 36 - 0
pump-common/src/main/java/com/tuoren/common/utils/enums/LogType.java

@@ -0,0 +1,36 @@
+package com.tuoren.common.utils.enums;
+
+public enum LogType{
+    
+        Sucess("运行成功",1),
+        Fail("运行失败",2),
+        Exception("运行结果发生异常",3),
+        Login("登录信息",4),
+        Netty("Netty通信日志",5),
+        MqFail("RabbitMQ 消息发送失败",6),
+        PushInfo("报警信息推送",7),
+        MqInfo("RabbitMQ 发送到医院消息",8);
+        private int code;
+        private String message;
+
+        LogType(String message,int code) {
+            this.code = code;
+            this.message=message;
+        }
+
+        public int getCode() {
+            return code;
+        }
+
+        public void setCode(int code) {
+            this.code = code;
+        }
+
+        public String getMessage() {
+            return message;
+        }
+
+        public void setMessage(String message) {
+            this.message = message;
+        }
+    }

+ 137 - 0
pump-common/src/main/resources/templates/controller2.java.btl

@@ -0,0 +1,137 @@
+package ${package.Controller};
+
+import com.tuoren.common.api.CommonResult;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import ${package.Service}.${table.serviceName};
+import ${package.Entity}.${entity};
+
+import java.io.Serializable;
+import java.util.List;
+
+<% if(restControllerStyle){ %>
+import org.springframework.web.bind.annotation.RestController;
+<% }else{ %>
+import org.springframework.stereotype.Controller;
+<% } %>
+<% if(isNotEmpty(superControllerClassPackage)){ %>
+import ${superControllerClassPackage};
+<% } %>
+
+/**
+ * <p>
+ * ${table.comment!} 前端控制器
+ * </p>
+ *
+ * @author ${author}
+ * @since ${date}
+ */
+@Api(tags = "${table.controllerName}", description = "${table.controllerName}")
+@Slf4j
+<% if(restControllerStyle){ %>
+@RestController
+<% }else{ %>
+@Controller
+<% } %>
+@RequestMapping("<% if(isNotEmpty(package.ModuleName)){ %>/${package.ModuleName}<% } %>/<% if(isNotEmpty(controllerMappingHyphenStyle)){ %>${controllerMappingHyphen}<% }else{ %>${table.entityPath}<% } %>")
+<% if(kotlin){ %>
+class ${table.controllerName}<% if(isNotEmpty(superControllerClass)){ %> : ${superControllerClass}()<% } %>
+<% }else{ %>
+    <% if(isNotEmpty(superControllerClass)){ %>
+public class ${table.controllerName} extends ${superControllerClass} {
+    <% }else{ %>
+public class ${table.controllerName}{
+    @Autowired
+    public ${table.serviceName} i${entity}Service;
+
+    /**
+         * 分页查询所有数据
+         *
+         * @param pageNo 页码
+         * @param pageSize 条数
+         * @param ${table.entityPath} 查询实体
+         * @return 所有数据
+         */
+        @ApiOperation("分页查询所有数据")
+        @GetMapping
+        public CommonResult selectAll(Integer pageNo, Integer pageSize,${entity} ${table.entityPath}) {
+            IPage<${entity}> page = new Page<>(pageNo,pageSize);
+            return CommonResult.success(this.i${entity}Service.page(page, new QueryWrapper<>(${table.entityPath})));
+        }
+
+    /**
+         * 通过主键查询单条数据
+         *
+         * @param id 主键
+         * @return 单条数据
+         */
+        @ApiOperation("通过主键查询单条数据")
+        @GetMapping("{id}")
+        public CommonResult selectOne(@PathVariable Serializable id) {
+            return CommonResult.success(this.i${entity}Service.getById(id));
+        }
+
+    /**
+         * 新增数据
+         *
+         * @param ${table.entityPath}  实体对象
+         * @return 新增结果
+         */
+        @ApiOperation("新增数据")
+        @PostMapping
+        public CommonResult insert(@RequestBody ${entity} ${table.entityPath}) {
+            try{
+                return CommonResult.success(this.i${entity}Service.save( ${table.entityPath}),"添加成功");
+            } catch (Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("添加失败");
+            }
+        }
+
+    /**
+         * 修改数据
+         *
+         * @param  ${table.entityPath} 实体对象
+         * @return 修改结果
+         */
+        @ApiOperation("修改数据")
+        @PutMapping
+        public CommonResult update(@RequestBody ${entity} ${table.entityPath}) {
+            try {
+                return CommonResult.success(this.i${entity}Service.updateById(${table.entityPath}),"修改成功");
+            } catch (Exception e) {
+                 log.error("出现错误, {}",e.getMessage());
+                 return CommonResult.failed("修改失败");
+            }
+        }
+
+    /**
+         * 删除数据
+         *
+         * @param idList 主键结合
+         * @return 删除结果
+         */
+        @ApiOperation("删除数据")
+        @DeleteMapping
+        public CommonResult delete(@RequestParam("idList") List<Long> idList) {
+            try{
+                return CommonResult.success(this.i${entity}Service.removeByIds(idList),"删除成功");
+            } catch ( Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("删除失败");
+            }
+        }
+
+
+    <% } %>
+
+}
+<% } %>

+ 26 - 0
pump-web/pom.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>netpump</artifactId>
+        <groupId>com.tuoren</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+
+    <name>pump-web</name>
+    <description>Demo project for Spring Boot</description>
+    <artifactId>pump-web</artifactId>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>com.tuoren</groupId>
+            <artifactId>pump-common</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+
+    </dependencies>
+
+</project>

+ 21 - 0
pump-web/src/main/java/com/tuoren/web/commponent/config/CommponentConfig.java

@@ -0,0 +1,21 @@
+package com.tuoren.web.commponent.config;
+import com.tuoren.common.commponent.flowMonitor.annotation.EnableFlowMonitor;
+import com.tuoren.common.commponent.idempotent.annotation.EnableIdempotent;
+import com.tuoren.common.commponent.shiroLogin.annotation.EnableWebShiro;
+import com.tuoren.web.commponent.webLog.annotation.EnableWebLog;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * ClassName:
+ * date: 2020/6/8
+ *
+ * @author lifang
+ * @version 1.0
+ */
+//@EnableIdempotent
+@EnableWebLog
+@EnableWebShiro
+@Configuration
+@EnableFlowMonitor
+public class CommponentConfig {
+}

+ 39 - 0
pump-web/src/main/java/com/tuoren/web/commponent/webLog/WebLogAutoConfigration.java

@@ -0,0 +1,39 @@
+package com.tuoren.web.commponent.webLog;
+
+
+import com.tuoren.common.api.AopOrderEnum;
+import com.tuoren.common.redis.RedisService;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.aop.aspectj.AspectJExpressionPointcut;
+import org.springframework.aop.support.DefaultPointcutAdvisor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * ClassName:
+ * date: 2020/5/21
+ *
+ * @author lifang
+ * @version 1.0
+ */
+public class WebLogAutoConfigration {
+    private final String POINT_CUT= "execution(public * com.tuoren.web.layer.controller.*.*(..))";
+    @Bean
+    @ConditionalOnClass(RedisService.class)
+    public DefaultPointcutAdvisor webLogPointCutAdvice(RedisService redisService){
+        //声明一个AspectJ切点
+        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
+        //设置切点表达式
+        pointcut.setExpression(POINT_CUT);
+        // 配置增强类advisor, 切面=切点+增强
+        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
+        //设置切点
+        advisor.setPointcut(pointcut);
+        //设置增强(Advice)
+        advisor.setAdvice(new WebLogMethodInterceptor());
+        //设置增强拦截器执行顺序
+        advisor.setOrder(AopOrderEnum.LOG.getOrder());
+
+        return advisor;
+    }
+}

+ 20 - 0
pump-web/src/main/java/com/tuoren/web/commponent/webLog/WebLogAutoConfigurationSelector.java

@@ -0,0 +1,20 @@
+package com.tuoren.web.commponent.webLog;
+
+import org.springframework.context.annotation.DeferredImportSelector;
+import org.springframework.core.annotation.Order;
+import org.springframework.core.type.AnnotationMetadata;
+
+/**
+ * ClassName: 访问日志配置
+ * date: 2020/6/8
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Order
+public class WebLogAutoConfigurationSelector implements DeferredImportSelector {
+    @Override
+    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
+        return new String[] { WebLogAutoConfigration.class.getName() };
+    }
+}

+ 94 - 0
pump-web/src/main/java/com/tuoren/web/commponent/webLog/WebLogMethodInterceptor.java

@@ -0,0 +1,94 @@
+package com.tuoren.web.commponent.webLog;
+
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.URLUtil;
+import cn.hutool.json.JSONUtil;
+import com.tuoren.common.utils.ConstastUtils;
+import com.tuoren.web.utils.LogUtils;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.*;
+import com.tuoren.web.commponent.webLog.javaBean.WebLog;
+@Slf4j
+public class WebLogMethodInterceptor implements MethodInterceptor {
+    @Override
+    public Object invoke(MethodInvocation invocation) throws Throwable {
+        //若是拦截了Cglib代理对象,直接放行
+        if(invocation.getThis().getClass().getName().contains(ConstastUtils.CGLIBOBJ)){
+            return invocation.proceed();
+        }
+        long startTime = System.currentTimeMillis();
+        //获取当前请求对象
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+        //记录请求信息
+        WebLog webLog = new WebLog();
+        Object result = invocation.proceed();
+        Method method = invocation.getMethod();
+        if (method.isAnnotationPresent(ApiOperation.class)) {
+            ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
+            webLog.setDescription(apiOperation.value());
+        }
+        long endTime = System.currentTimeMillis();
+        String urlStr = request.getRequestURL().toString();
+        webLog.setBasePath(StrUtil.removeSuffix(urlStr, URLUtil.url(urlStr).getPath()));
+        webLog.setIp(request.getRemoteUser());
+        webLog.setMethod(request.getMethod());
+        webLog.setParameter(getParameter(method, invocation.getArguments()));
+        webLog.setResult(result);
+        webLog.setSpendTime((int) (endTime - startTime));
+        webLog.setStartTime(startTime);
+        webLog.setUri(request.getRequestURI());
+        webLog.setUrl(request.getRequestURL().toString());
+        webLog.setLogTime(DateUtil.now());
+        // 在 JSON 中加入当前时间,可以使用 hutool 这个工具类库,保存日志文件到 MyLog 文件夹, 当文件大于 10MB 时分割文件
+        LogUtils.success(webLog);
+        // 保存到文件End
+        return result;
+    }
+
+    /**
+     * 根据方法和传入的参数获取请求参数
+     */
+    private Object getParameter(Method method, Object[] args) {
+        List<Object> argList = new ArrayList<>();
+        Parameter[] parameters = method.getParameters();
+        for (int i = 0; i < parameters.length; i++) {
+            //将RequestBody注解修饰的参数作为请求参数
+            RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
+            if (requestBody != null) {
+                argList.add(args[i]);
+            }
+            //将RequestParam注解修饰的参数作为请求参数
+            RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
+            if (requestParam != null) {
+                Map<String, Object> map = new HashMap<>();
+                String key = parameters[i].getName();
+                if (!StringUtils.isEmpty(requestParam.value())) {
+                    key = requestParam.value();
+                }
+                map.put(key, args[i]);
+                argList.add(map);
+            }
+        }
+        if (argList.size() == 0) {
+            return null;
+        } else if (argList.size() == 1) {
+            return argList.get(0);
+        } else {
+            return argList;
+        }
+    }
+}

+ 20 - 0
pump-web/src/main/java/com/tuoren/web/commponent/webLog/annotation/EnableWebLog.java

@@ -0,0 +1,20 @@
+package com.tuoren.web.commponent.webLog.annotation;
+
+import com.tuoren.web.commponent.webLog.WebLogAutoConfigurationSelector;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+/**
+ * ClassName:
+ * date: 2020/6/8
+ *
+ * @author lifang
+ * @version 1.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Documented
+@Import(WebLogAutoConfigurationSelector.class)
+public @interface EnableWebLog {
+}

+ 67 - 0
pump-web/src/main/java/com/tuoren/web/commponent/webLog/javaBean/WebLog.java

@@ -0,0 +1,67 @@
+package com.tuoren.web.commponent.webLog.javaBean;
+
+import lombok.Data;
+
+/**
+ * Create by fanfan
+ * Date: 2020-05-15 9:09
+ */
+@Data
+public class WebLog {
+    /**
+     * 操作描述
+     */
+    private String description;
+
+    /**
+     * 操作用户
+     */
+    private String username;
+
+    /**
+     * 操作时间
+     */
+    private Long startTime;
+
+    /**
+     * 消耗时间
+     */
+    private Integer spendTime;
+
+    /**
+     * 根路径
+     */
+    private String basePath;
+
+    /**
+     * URI
+     */
+    private String uri;
+
+    /**
+     * URL
+     */
+    private String url;
+
+    /**
+     * 请求类型
+     */
+    private String method;
+
+    /**
+     * IP地址
+     */
+    private String ip;
+
+    /**
+     * 请求参数
+     */
+    private Object parameter;
+
+    /**
+     * 请求返回的结果
+     */
+    private Object result;
+
+    private String logTime;
+}

+ 59 - 0
pump-web/src/main/java/com/tuoren/web/job/CommonJob.java

@@ -0,0 +1,59 @@
+package com.tuoren.web.job;
+
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.tuoren.common.constant.CommonConstant;
+import com.tuoren.web.layer.entity.SysBreathEntity;
+import com.tuoren.web.layer.service.ISysBreathService;
+
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @Description  定时任务
+ * @Author wulianwei  
+ * @Date 2020-07-03 15:19
+ */
+//@Component
+@Slf4j
+public class CommonJob {
+		
+	@Autowired
+	private ISysBreathService iSysBreathService;
+	
+	/**
+	 * @Description 10分钟未呼吸的队列置为离线
+	 * @Author wulianwei
+	 * @Date 2020-07-03 15:33
+	 * @Return  void
+	 */
+	@Scheduled(cron = "0 0/2 * * * *")
+	public void queueBreahJob() {
+		log.info("==========queueBreahJob start=========");
+		QueryWrapper<SysBreathEntity> wrapper = new QueryWrapper<SysBreathEntity>();
+		wrapper.eq("flag_online", CommonConstant.MQBREATH_ONLINE);
+		List<SysBreathEntity> entitys = iSysBreathService.list(wrapper);
+		Date currentDate = new Date();
+		if(entitys != null && entitys.size() > 0) {
+			for(SysBreathEntity item : entitys) {
+				Date breathTime = Date.from(item.getBreathTime().atZone(ZoneId.systemDefault()).toInstant());
+				if(DateUtil.between(breathTime, currentDate, DateUnit.MINUTE)>15) {
+					item.setFlagOnline(CommonConstant.MQBREATH_OFFLINE);
+					iSysBreathService.updateById(item);
+				}
+			}
+		}
+		log.info("==========queueBreahJob end=========");
+		
+	}
+
+}

+ 58 - 0
pump-web/src/main/java/com/tuoren/web/job/InterfaceFlowStatisticsJob.java

@@ -0,0 +1,58 @@
+package com.tuoren.web.job;
+
+import cn.hutool.core.date.DateUtil;
+import com.tuoren.common.config.MvcConfig;
+import com.tuoren.common.entity.MvcEntity;
+import com.tuoren.web.layer.entity.SysInterfaceFlowStatisticsEntity;
+import com.tuoren.web.layer.service.ISysInterfaceFlowStatisticsService;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @Author: lifang
+ * @Description: 记录各个接口流量情况
+ * @Date: Created in 9:39 2020/9/4
+ */
+//@Component
+@Slf4j
+@Data
+public class InterfaceFlowStatisticsJob {
+    ISysInterfaceFlowStatisticsService statisticsService;
+    @Autowired
+    public InterfaceFlowStatisticsJob(ISysInterfaceFlowStatisticsService statisticsService) {
+        this.statisticsService=statisticsService;
+    }
+
+    @Scheduled(cron = "0 58 23 * * ? ")
+    public void logStatics(){
+        MvcConfig.LOCK.writeLock().lock();
+        try {
+            Map<MvcEntity, AtomicInteger> urlmap = MvcConfig.URLMAP;
+            LinkedList<SysInterfaceFlowStatisticsEntity> list = new LinkedList<>();
+            String statisticsTime = DateUtil.today();
+            urlmap.forEach((K,V)->{
+                SysInterfaceFlowStatisticsEntity statisticsEntity = new SysInterfaceFlowStatisticsEntity(K);
+                int count = V.getAndSet(0);
+                if(count==0){
+                    return;
+                }
+                statisticsEntity.setCount(count);
+                statisticsEntity.setStatisticsTime(statisticsTime);
+                list.add(statisticsEntity);
+            });
+            statisticsService.saveBatch(list);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        finally {
+            MvcConfig.LOCK.writeLock().unlock();
+        }
+    }
+}

+ 94 - 0
pump-web/src/main/java/com/tuoren/web/job/RemoveInvalidQueueJob.java

@@ -0,0 +1,94 @@
+package com.tuoren.web.job;
+
+import com.rabbitmq.http.client.Client;
+import com.rabbitmq.http.client.domain.QueueInfo;
+import com.tuoren.common.constant.CommonConstant;
+import com.tuoren.web.layer.service.IBusHospitalService;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.util.List;
+
+
+/**
+ * @Author: lifang
+ * @Description:
+ * @Date: Created in 16:02 2020/9/2
+ */
+//@Component
+@Slf4j
+@Data
+public class RemoveInvalidQueueJob {
+    final int port =15672;
+    @Autowired
+    RabbitProperties rabbitProperties;
+    @Autowired
+    IBusHospitalService busHospitalService;
+
+    Client client = null;
+    public boolean init(){
+        try {
+            client = new Client("http://"+rabbitProperties.getHost()+":"+port+"/api",rabbitProperties.getUsername(),rabbitProperties.getPassword());
+            return true;
+        } catch (MalformedURLException e) {
+            log.error("RemoveInvalidQueueJob.getRemoteQueues come with a MalformedURLException,{}",e.getMessage());
+        } catch (URISyntaxException e) {
+            log.error("RemoveInvalidQueueJob.getRemoteQueues come with a URISyntaxException,{}",e.getMessage());
+        }
+        return false;
+    }
+    @Scheduled(cron = "0 0 2 * * ? ")
+    public void removeInvalidQueue(){
+        //初始化参数
+        if(!init()){
+            return;
+        }
+        List<String> localQueues = busHospitalService.queryHospitalCodes();
+        List<QueueInfo> remoteQueues = getRemoteQueues();
+        if(remoteQueues==null){
+            return;
+        }
+        remoteQueues.forEach(queueInfo -> {
+            String name = queueInfo.getName();
+            if(!isValid(name)){
+                deleteRemoteQueue(queueInfo.getVhost(),queueInfo.getName());
+                return;
+            }
+            String hospitalCode=name.split("\\.")[1];
+            if(!localQueues.contains(hospitalCode)){
+                deleteRemoteQueue(queueInfo.getVhost(),queueInfo.getName());
+            }
+        });
+    }
+
+
+    public boolean isValid(String queueName){
+        if(queueName.startsWith("hospital")){
+            String[] split = queueName.split("\\.");
+            return split.length==2;
+        }
+        if(CommonConstant.QUEUE_BREATH.equals(queueName)||CommonConstant.QUEUE_ANALGESICSCORE.equals(queueName)
+        ||CommonConstant.QUEUE_CONFIG.equals(queueName)||CommonConstant.QUEUE_HOSPITAL.equals(queueName)
+        ||CommonConstant.QUEUE_PATIENT.equals(queueName)||CommonConstant.QUEUE_PUMP.equals(queueName)){
+            return true;
+        }
+        return false;
+    }
+
+    public List<QueueInfo> getRemoteQueues(){
+        return client.getQueues();
+    }
+
+
+    public void deleteRemoteQueue(String hostName,String queueName){
+        client.deleteQueue(hostName,queueName);
+    }
+}

+ 109 - 0
pump-web/src/main/java/com/tuoren/web/job/SysConfigJob.java

@@ -0,0 +1,109 @@
+package com.tuoren.web.job;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.tuoren.web.layer.entity.BusPumpEntity;
+import com.tuoren.web.layer.service.IBusPumpService;
+import com.tuoren.web.layer.service.ISysConfigService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author fanfan
+ * @date 2020-07-06 16:28
+ */
+
+//@Component
+@Slf4j
+public class SysConfigJob {
+
+        private static  final int pageSize = 500;
+        private static SysConfigJob sysConfigJob ;
+
+        @Autowired
+        public ISysConfigService iSystemConfigEntityService;
+
+        @Autowired
+        public IBusPumpService iBusPumpService;
+
+        @PostConstruct //通过@PostConstruct实现初始化bean之前进行的操作
+        public void init() {
+            sysConfigJob = this;
+            sysConfigJob.iSystemConfigEntityService = this.iSystemConfigEntityService;
+        }
+
+        @Scheduled(cron = "0 0/2 * * * *")
+        public void updatePumpList(){
+            int count = iBusPumpService.count();
+            int page = (int) Math.ceil(count / pageSize) ;
+            Page<BusPumpEntity> pumpEntityPage = new Page<>();
+            for (int i = 0; i <= page; i++) {
+                pumpEntityPage.setSize(pageSize);
+                pumpEntityPage.setPages(page);
+                List<BusPumpEntity> records = iBusPumpService.page(pumpEntityPage).getRecords();
+                System.out.println("更新前的值:" + records);
+                getFilterList(records);
+                System.out.println("更新后的值:" + records);
+                iBusPumpService.saveOrUpdateBatch(records);
+            }
+        }
+
+        // 设置是否在服务区 和 自动撤泵 问题
+        public void getFilterList(List<BusPumpEntity> list){
+            for(BusPumpEntity v : list) {
+                try {
+                   String dateStr = v.getLastUploadTime().toString().replaceAll("T"," ");
+                   // 泵时间
+                   Date date = DateUtil.parse(dateStr);
+                   // 现在时间
+                   DateTime now = DateTime.now();
+                   // 比较时间
+                   long betweenMin = DateUtil.between(date,now, DateUnit.MINUTE);
+                   // 获取相关设置
+                   Map<String,String> map = sysConfigJob.iSystemConfigEntityService.querySysConfigByHospitalMap(v.getHospitalCode());
+
+                   // 是否自动撤泵
+                   boolean IsAutoUndo = Boolean.parseBoolean(map.get("IsAutoUndo"));
+
+                   // 不在服务区时间
+                   String OutServiceSpan = StrUtil.isNotEmpty(map.get("OutServiceSpan")) ? map.get("OutServiceSpan") : "60";
+
+                   //不在服务区到自动撤泵几分钟后的参数
+                   String AutoOutSpan = StrUtil.isNotEmpty(map.get("AutoOutSpan")) ? map.get("AutoOutSpan") : "3";
+
+                   // 关机几分钟后的参数
+                   String OffSpan = StrUtil.isNotEmpty(map.get("OffSpan")) ? map.get("OffSpan") : "5";
+
+                   long OutSpanAndOutServiceSpan = Long.parseLong(OutServiceSpan) + Long.parseLong(AutoOutSpan);
+
+                   if( v.getRunState() != null) {
+                       if(IsAutoUndo){
+                           if( (v.getRunState() == 0 && betweenMin >= Long.parseLong(OffSpan)) || ( v.getRunState() != 0 &&  betweenMin >= OutSpanAndOutServiceSpan)){
+                               v.setIsRemove(false);
+                           } else {
+                               v.setIsRemove(true);
+                           }
+                       }
+                       // 没有关机 并且 时差 >= 不在服务区时间
+                       if( (v.getRunState() != 0 && betweenMin >= Long.parseLong(OutServiceSpan)) ){
+                           v.setNoSignal(1);
+                       }  else {
+                           v.setNoSignal(0);
+                       }
+                   }
+               } catch (NullPointerException e) {
+                    log.error("出现错误: >>>>>> {}", e.getMessage());
+               }
+            }
+        }
+    }

+ 266 - 0
pump-web/src/main/java/com/tuoren/web/layer/controller/BusAnalgesicScoreController.java

@@ -0,0 +1,266 @@
+package com.tuoren.web.layer.controller;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.tuoren.common.api.CommonResult;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import com.tuoren.common.redis.RedisService;
+import com.tuoren.common.utils.ConstastUtils;
+import com.tuoren.common.utils.enums.LogType;
+import com.tuoren.web.layer.vo.AnalgesicScoreParam;
+import com.tuoren.web.layer.entity.SysBreathEntity;
+import com.tuoren.web.layer.service.ISysBreathService;
+import com.tuoren.web.utils.ConverterUtils;
+import com.tuoren.web.utils.DataUtils;
+import com.tuoren.web.utils.DateFormatUtils;
+import com.tuoren.web.utils.LogUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.connection.CorrelationData;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import com.tuoren.web.layer.service.IBusAnalgesicScoreService;
+import com.tuoren.web.layer.entity.BusAnalgesicScoreEntity;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author fanfan
+ * @since 2020-07-03
+ */
+@Api(tags = "BusAnalgesicScoreController", description = "评分和随访人员")
+@Slf4j
+@RestController
+@RequestMapping("/bus/analgesic-score")
+public class BusAnalgesicScoreController{
+    @Autowired
+    public IBusAnalgesicScoreService iBusAnalgesicScoreEntityService;
+
+    @Autowired
+    public RedisService redisService;
+
+    @Autowired
+    public ISysBreathService iSysBreathService;
+
+    @Autowired
+//    @Resource(name = "simpleRabbitTemplate")
+//    @Qualifier("simpleRabbitTemplate")
+    public RabbitTemplate rabbitTemplate;
+
+    /**
+         * 分页查询所有数据
+         *
+         * @param pageNo 页码
+         * @param pageSize 条数
+         * @param busAnalgesicScoreEntity 查询实体
+         * @return 所有数据
+         */
+        @ApiOperation("分页查询所有数据")
+        @GetMapping
+        public CommonResult selectAll(Integer pageNo, Integer pageSize,BusAnalgesicScoreEntity busAnalgesicScoreEntity) {
+            IPage<BusAnalgesicScoreEntity> page = new Page<>(pageNo,pageSize);
+            QueryWrapper<BusAnalgesicScoreEntity> wrapper = new QueryWrapper<>(busAnalgesicScoreEntity);
+            wrapper.orderByDesc("follow_date");
+            return CommonResult.success(this.iBusAnalgesicScoreEntityService.page(page, wrapper));
+        }
+
+    /**
+         * 通过主键查询单条数据
+         *
+         * @param id 主键
+         * @return 单条数据
+         */
+        @ApiOperation("通过主键查询单条数据")
+        @GetMapping("{id}")
+        public CommonResult selectOne(@PathVariable Serializable id) {
+            return CommonResult.success(this.iBusAnalgesicScoreEntityService.getById(id));
+        }
+
+    /**
+         * 新增数据
+         *
+         * @param busAnalgesicScoreEntity  实体对象
+         * @return 新增结果
+         */
+        @ApiOperation("新增数据")
+        @PostMapping
+        @RabbitHandler
+        public CommonResult insert(@RequestBody BusAnalgesicScoreEntity busAnalgesicScoreEntity) {
+            String hospital = busAnalgesicScoreEntity.getHospitalCode();
+            try{
+                busAnalgesicScoreEntity.setFollowDate(DateFormatUtils.format(DateUtil.now()));
+                iBusAnalgesicScoreEntityService.insertAcqId(busAnalgesicScoreEntity);
+                busAnalgesicScoreEntity.setAnalgesicScoreId(busAnalgesicScoreEntity.getId().toString());
+              return CommonResult.success( "添加成功");
+//                return CommonResult.success("添加成功");
+            } catch (Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("添加失败");
+            } finally {
+                JSONObject jsonObject =  new JSONObject();
+                jsonObject.put("operation", 1);
+                jsonObject.put("tableName", "AnalgesicScore");
+                jsonObject.put("data",JSON.toJSON(busAnalgesicScoreEntity));
+                pushRabbit(jsonObject,hospital,busAnalgesicScoreEntity);
+            }
+        }
+
+
+    /**
+         * 修改数据
+         *
+         * @param  busAnalgesicScoreEntity 实体对象
+         * @return 修改结果
+         */
+        @ApiOperation("修改数据")
+        @PutMapping
+        public CommonResult update(@RequestBody BusAnalgesicScoreEntity busAnalgesicScoreEntity) {
+            try {
+                return CommonResult.success(this.iBusAnalgesicScoreEntityService.updateById(busAnalgesicScoreEntity),"修改成功");
+            } catch (Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("修改失败");
+            }
+        }
+
+    /**
+         * 删除数据
+         *
+         * @param idList 主键结合
+         * @return 删除结果
+         */
+        @ApiOperation("删除数据")
+        @DeleteMapping
+        public CommonResult delete(@RequestParam("idList") List<Long> idList) {
+            try{
+                return CommonResult.success(this.iBusAnalgesicScoreEntityService.removeByIds(idList),"删除成功");
+            } catch ( Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("删除失败");
+            }
+        }
+    /**
+         * 获取不重复的随访人员
+         *
+         * @param analgesicScoreParam 参数
+         * @return 单条数据
+         */
+        @ApiOperation("获取不重复的随访人员")
+        @PostMapping("/getFollowUp")
+        public CommonResult getFollowUp(
+                @RequestBody AnalgesicScoreParam analgesicScoreParam
+        ) {
+            QueryWrapper<BusAnalgesicScoreEntity> wrapper = new QueryWrapper<BusAnalgesicScoreEntity>();
+            wrapper.eq(StrUtil.isNotBlank(analgesicScoreParam.getProductCode()),"product_code",analgesicScoreParam.getProductCode());
+            wrapper.eq(StrUtil.isNotBlank(analgesicScoreParam.getHospitalCode()),"hospital_code",analgesicScoreParam.getHospitalCode());
+            // 去重
+            wrapper.select(" creator ");
+            wrapper.last("limit " + analgesicScoreParam.getPageSize());
+            wrapper.groupBy("creator");
+            wrapper.orderByDesc("max(gmt_modified)");
+            return CommonResult.success(this.iBusAnalgesicScoreEntityService.listObjs(wrapper));
+        }
+
+    /**
+         * 根据病人ID获取评分信息
+         *
+         * @param analgesicScoreParam 参数
+         * @return 单条数据
+         */
+        @ApiOperation("根据住院号和病人ID和所在医院获取最新评分信息")
+        @PostMapping("/getNewScore")
+        public CommonResult getNewScore(
+                @RequestBody AnalgesicScoreParam analgesicScoreParam
+        ) {
+            QueryWrapper<BusAnalgesicScoreEntity> wrapper = new QueryWrapper<BusAnalgesicScoreEntity>();
+            wrapper.eq(StrUtil.isNotBlank(analgesicScoreParam.getProductCode()),"product_code",analgesicScoreParam.getProductCode());
+            wrapper.eq(StrUtil.isNotBlank(analgesicScoreParam.getHospitalCode()),"hospital_code",analgesicScoreParam.getHospitalCode());
+            wrapper.eq(StrUtil.isNotBlank(analgesicScoreParam.getPatientCode()),"patient_code",analgesicScoreParam.getPatientCode());
+            wrapper.select("*");
+            wrapper.last("limit 1");
+            wrapper.orderByDesc("gmt_modified");
+            return CommonResult.success(this.iBusAnalgesicScoreEntityService.getOne(wrapper));
+        }
+    /**
+         * 模糊查询评分
+         *
+         * @param analgesicScoreParam 参数
+         * @return 数据
+         */
+        @ApiOperation("模糊查询评分 住院号 patientCode | 泵号 pumpCode | 产品编码类型 productCode | 医院 hospitalCode | 创建人 creator ")
+        @GetMapping("/getFuzzyScore")
+        public CommonResult getFuzzyScore(
+                @RequestBody AnalgesicScoreParam analgesicScoreParam
+        ) {
+           try{
+               IPage<BusAnalgesicScoreEntity> iPage = iBusAnalgesicScoreEntityService.queryFuzzyScore(analgesicScoreParam);
+               if( iPage.getRecords().size() > 0 ){
+                   return CommonResult.success(iPage);
+               }
+               return CommonResult.noData();
+           } catch (Exception e) {
+               log.error("出现错误, {}",e.getMessage());
+               return CommonResult.failed("查询失败");
+           }
+        }
+
+
+    private void pushRabbit(JSONObject jsonObject, String hospital,BusAnalgesicScoreEntity busAnalgesicScoreEntity){
+        try {
+            QueryWrapper<SysBreathEntity> wrapper = new QueryWrapper<>();
+            wrapper.eq("code",busAnalgesicScoreEntity.getHospitalCode());
+            SysBreathEntity sysBreathEntity = iSysBreathService.getOne(wrapper);
+            if(sysBreathEntity.getFlagOnline().equals("1")) {
+                JSON convert = ConverterUtils.convert(jsonObject, BusAnalgesicScoreEntity.class, ConverterUtils.ConverterType.Cloud2PC);
+//                    System.out.println(convert);
+//                    System.out.println(DataUtils.byteArrToHexString(DataUtils.stringToByte(convert)));
+                // 发送到队列
+                rabbitTemplate.convertAndSend(ConstastUtils.ROUTING_KEY+hospital,DataUtils.stringToByte(convert),new CorrelationData(convert.toJSONString()));
+                LogUtils.save(LogType.MqInfo,convert);
+            }
+        } catch (Exception e) {
+            log.info("推送评分到Rabbit 出现错误>>>>>>>"  + e.getMessage());
+        }
+    }
+
+
+    /**
+     * 智慧大屏接口: 地图呼吸接口
+     * @return 所有数据
+     */
+    @ApiOperation("智慧大屏接口: 满意度接口")
+    @PostMapping("/queryViewAnalgesicScore")
+    public CommonResult queryViewAnalgesicScore() {
+        QueryWrapper<BusAnalgesicScoreEntity> wrapper = new QueryWrapper<>();
+        wrapper.select("satisfaction"," count(satisfaction)");
+        wrapper.groupBy("satisfaction");
+        List<Map<String, Object>> maps = iBusAnalgesicScoreEntityService.listMaps(wrapper);
+        List<Map<String, Object>> mapResult = new ArrayList<>();
+        for (Map<String, Object> mapEach : maps) {
+            Map<String,Object> map = new HashMap<>();
+            map.put("satisfaction",mapEach.get("satisfaction"));
+            map.put("count", mapEach.get("count(satisfaction)"));
+            mapResult.add(map);
+        }
+        return CommonResult.success(mapResult);
+    }
+}

+ 151 - 0
pump-web/src/main/java/com/tuoren/web/layer/controller/BusHospitalController.java

@@ -0,0 +1,151 @@
+package com.tuoren.web.layer.controller;
+
+import cn.hutool.core.util.IdUtil;
+import com.tuoren.common.api.CommonResult;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import com.tuoren.web.layer.vo.HospitalParam;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import com.tuoren.web.layer.service.IBusHospitalService;
+import com.tuoren.web.layer.entity.BusHospitalEntity;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author fanfan
+ * @since 2020-07-03
+ */
+@Api(tags = "BusHospitalController", description = "医院管理")
+@Slf4j
+@RestController
+@RequestMapping("/bus/hospital")
+public class BusHospitalController{
+    @Autowired
+    public IBusHospitalService iBusHospitalEntityService;
+
+    /**
+         * 分页查询所有数据
+         *
+         * @param pageNo 页码
+         * @param pageSize 条数
+         * @param busHospitalEntity 查询实体
+         * @return 所有数据
+         */
+        @ApiOperation("分页查询所有数据")
+        @GetMapping
+        public CommonResult selectAll(Integer pageNo, Integer pageSize,BusHospitalEntity busHospitalEntity) {
+            IPage<BusHospitalEntity> page = new Page<>(pageNo,pageSize);
+            QueryWrapper<BusHospitalEntity> wrapper = new QueryWrapper<>(busHospitalEntity);
+            wrapper.orderByDesc("gmt_modified");
+            return CommonResult.success(this.iBusHospitalEntityService.page(page, wrapper));
+        }
+
+    /**
+         * 通过主键查询单条数据
+         *
+         * @param id 主键
+         * @return 单条数据
+         */
+        @ApiOperation("通过主键查询单条数据")
+        @GetMapping("{id}")
+        public CommonResult selectOne(@PathVariable Serializable id) {
+            return CommonResult.success(this.iBusHospitalEntityService.getById(id));
+        }
+
+    /**
+         * 新增数据
+         *
+         * @param busHospitalEntity  实体对象
+         * @return 新增结果
+         */
+        @ApiOperation("新增数据")
+        @PostMapping
+        public CommonResult insert(@RequestBody BusHospitalEntity busHospitalEntity) {
+            try{
+                busHospitalEntity.setHospitalCode(IdUtil.simpleUUID());
+                QueryWrapper<BusHospitalEntity> wrapper = new QueryWrapper<>();
+                wrapper.eq("hosptial_name",busHospitalEntity.getHosptialName());
+                List<BusHospitalEntity> list = iBusHospitalEntityService.list(wrapper);
+                if(list.size() > 0) {
+                    return CommonResult.failed("医院名称重复");
+                }
+                return CommonResult.success(this.iBusHospitalEntityService.save( busHospitalEntity),"添加成功");
+            } catch (Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("添加失败");
+            }
+        }
+
+    /**
+         * 修改数据
+         *
+         * @param  busHospitalEntity 实体对象
+         * @return 修改结果
+         */
+        @ApiOperation("修改数据")
+        @PutMapping
+        public CommonResult update(@RequestBody BusHospitalEntity busHospitalEntity) {
+            try {
+                return CommonResult.success(this.iBusHospitalEntityService.updateById(busHospitalEntity),"修改成功");
+            } catch (Exception e) {
+                 log.error("出现错误, {}",e.getMessage());
+                 return CommonResult.failed("修改失败");
+            }
+        }
+
+    /**
+         * 删除数据
+         *
+         * @param idList 主键结合
+         * @return 删除结果
+         */
+        @ApiOperation("删除数据")
+        @DeleteMapping
+        public CommonResult delete(@RequestParam("idList") List<Long> idList) {
+            try{
+//                return CommonResult.success(this.iBusHospitalEntityService.removeByIds(idList),"删除成功");
+                return CommonResult.failed("医院无法删除");
+            } catch ( Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("删除失败");
+            }
+        }
+    /**
+         * 模糊查询评分
+         *
+         * @param hospitalParam 参数
+         * @return 数据
+         */
+        @ApiOperation("模糊查询医院 医院名字 hosptialName | 医院编号 hospitalCode | 省编码 provinceCode | 市编码 cityCode | 区编码 areaCode")
+        @PostMapping("/getFuzzyHospital")
+        public CommonResult getFuzzyHospital(
+                @RequestBody HospitalParam hospitalParam
+        ) {
+            try{
+                IPage<BusHospitalEntity> iPage = iBusHospitalEntityService.queryFuzzyHospital(hospitalParam);
+                if( iPage.getRecords().size() > 0 ){
+                    return CommonResult.success(iPage);
+                }
+                return CommonResult.noData();
+            } catch (Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("查询失败");
+            }
+        }
+
+
+}

+ 190 - 0
pump-web/src/main/java/com/tuoren/web/layer/controller/BusLoginController.java

@@ -0,0 +1,190 @@
+package com.tuoren.web.layer.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.tuoren.common.api.CommonResult;
+import com.tuoren.common.redis.RedisService;
+import com.tuoren.common.utils.AESUtils;
+import com.tuoren.common.utils.ConstastUtils;
+import com.tuoren.common.utils.WebUtils;
+import com.tuoren.common.utils.enums.LogType;
+import com.tuoren.web.layer.vo.UserLoginParam;
+import com.tuoren.web.layer.entity.SysUserEntity;
+import com.tuoren.web.layer.service.IBusPumpService;
+import com.tuoren.web.layer.service.ISysConfigService;
+import com.tuoren.web.layer.service.ISysRoleService;
+import com.tuoren.web.push.PushInfo;
+import com.tuoren.web.shiro.utils.ActiverUserUtils;
+import com.tuoren.web.shiro.utils.ShiroUtils;
+import com.tuoren.web.utils.LogUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.subject.Subject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * @author fanfan
+ * @date 2020-07-03 14:41
+ */
+@Api(tags = "LoginController", description = "登录")
+@Slf4j
+@RestController
+public class BusLoginController {
+    @Autowired
+    private RedisService redisService;
+
+    @Autowired
+    public IBusPumpService iBusPumpService;
+
+    @Autowired
+    public ISysRoleService iSysRoleService;
+
+    @Autowired
+    public ISysConfigService iSysConfigService;
+
+
+    @ApiOperation("登录")
+    @PostMapping("/login")
+    public CommonResult login(@RequestBody UserLoginParam userLoginParam) throws Exception{
+        Subject subject = SecurityUtils.getSubject();
+        String device = WebUtils.getUserAgent();
+        String pwd  = AESUtils.aesDecrypt(userLoginParam.getPassword(), ConstastUtils.KEYS);
+        AuthenticationToken token = new UsernamePasswordToken(userLoginParam.getUsername(),pwd);
+        Serializable tokenId = subject.getSession().getId();
+        try {
+            //对用户进行认证登陆
+            subject.login(token);
+            //通过subject获取以认证活动的user
+            ActiverUserUtils activerUser = (ActiverUserUtils) subject.getPrincipal();
+            // 设置 token
+            activerUser.setToken(ShiroUtils.getSession().getId().toString());
+            // 设置 设备
+            activerUser.setDevice(device);
+            String jsonString = JSON.toJSONString(activerUser);
+            List<String> role = activerUser.getRoles();
+            SysUserEntity acUser = activerUser.getUsers();
+            String hospital = acUser.getHospitalCode();
+            // 获取相关设置
+            Map<String,String> map = iSysConfigService.querySysConfigByHospitalMap(hospital);
+            if(activerUser.getUsers().getType() != 1 &&  map.isEmpty()){
+                redisService.remove(ConstastUtils.REDIS_SESSION_CODE +(String) tokenId);
+                return CommonResult.failed("该用户医院没有进行相关配置设置,无法登录");
+            }
+            // 存储到redis
+            redisService.set(ConstastUtils.REDIS_USER_CODE + activerUser.getToken(), jsonString);
+            redisService.expire(ConstastUtils.REDIS_USER_CODE + activerUser.getToken(), ConstastUtils.REDIS_EXPIRE);
+            // 重置 shiro redis 时间
+            redisService.expire(ConstastUtils.REDIS_SESSION_CODE + activerUser.getToken(), ConstastUtils.REDIS_EXPIRE);
+            // 登录日志简要
+            SysUserEntity user = new SysUserEntity();
+            user.setUserCode(acUser.getUserCode());
+            user.setUserCode(acUser.getName());
+            user.setLoginTime(acUser.getLoginTime());
+            user.setHospitalCode(acUser.getHospitalCode());
+            LogUtils.save(LogType.Login,user);
+            return CommonResult.success(activerUser);
+        } catch (AuthenticationException e) {
+            log.error("出现错误, {}",e.getMessage());
+            redisService.remove(ConstastUtils.REDIS_SESSION_CODE + (String) tokenId);
+            return CommonResult.failed("用户名或者密码错误");
+        }
+    }
+
+    @ApiOperation("退出登录")
+    @GetMapping("/logout")
+    public CommonResult logout(){
+        ShiroUtils.logout();
+        return CommonResult.success("已退出");
+    }
+
+
+    @ApiOperation("判断 token 是否有效")
+    @GetMapping("/isToken")
+    public CommonResult isToken(@RequestParam String token){
+        String sessionRedisToken  = ConstastUtils.REDIS_SESSION_CODE + token;
+        Set<String> sessionKeys = redisService.getKeys(ConstastUtils.REDIS_SESSION_CODE_ALL);
+        for (String sk:  sessionKeys) {
+            if(sk.equals(sessionRedisToken)){
+                return CommonResult.success(true);
+            }
+        }
+        return CommonResult.validateFailed();
+    }
+
+    @ApiOperation("简单推送测试")
+    @GetMapping("/push")
+    public CommonResult push(@RequestParam String pumpCode,String productCode, Integer stateFlag, Integer bufState9 )throws Exception{
+        try {
+            String LUA= "lua/getRedisMixed.lua";
+            Set<String> reidsKeys = redisService.getKeys("*");
+            List<String > list = new ArrayList<>(reidsKeys);
+            List result =  redisService.runLua(LUA,List.class,list);
+            List<Map<String,Object>> nameList = new ArrayList<>();
+            if(result.size() < 1)  {
+                return CommonResult.failed("没有用户在登录中");
+            }
+            for (Object i : result) {
+                ActiverUserUtils activerUserUtils = JSON.parseObject(redisService.get(i.toString()),ActiverUserUtils.class);
+                SysUserEntity usersEntity = activerUserUtils.getUsers();
+                Map<String,Object> map = new HashMap<>();
+                if(activerUserUtils.getDevice() == null) continue;
+                map.put("Device",activerUserUtils.getDevice());
+                map.put("PumpCode",pumpCode);
+                map.put("Token",activerUserUtils.getToken());
+                map.put("UserCode", usersEntity.getUserCode());
+                map.put("Hospital", usersEntity.getHospitalCode());
+                map.put("LastProduct",usersEntity.getLastProduct());
+                map.put("LoginTime", usersEntity.getLoginTime());
+                nameList.add(map);
+            }
+            new PushInfo().pushErrorInfo(stateFlag, bufState9, pumpCode, productCode);
+            return CommonResult.success(nameList,"发送成功");
+        } catch (Exception e){
+            log.error("出现错误, {}",e.getMessage());
+            return CommonResult.failed("没有用户在登录中");
+        }
+    }
+
+    @ApiOperation("删除所有的redis key, 1 所有 | 2 用户")
+    @GetMapping("/delSession")
+    public CommonResult delSession(@RequestParam Integer key){
+        Set<String> portalKeys = redisService.getKeys(ConstastUtils.REDIS_USER_CODE_ALL);
+        Set<String> sessionKeys = redisService.getKeys(ConstastUtils.REDIS_SESSION_CODE_ALL);
+        Set<String> redisKeysAll = redisService.getKeys(ConstastUtils.REDIS_CODE_ALL);
+        switch (key){
+            case 1:
+                for(String all: redisKeysAll) {
+                    redisService.remove(all);
+                }
+                break;
+            case 2:
+                for(String pk: portalKeys) {
+                    redisService.remove(pk);
+                }
+                for(String sk: sessionKeys) {
+                    redisService.remove(sk);
+                }
+                break;
+            default:
+                break;
+        }
+        return CommonResult.success("删除成功");
+    }
+
+    @ApiOperation("api地址类型")
+    @GetMapping("/pump")
+    public CommonResult pumpApiType(){
+        HashMap<Object,Number> hashMap =  new HashMap<>();
+        hashMap.put("apiType", 1);
+        return CommonResult.success(hashMap);
+    }
+
+}

+ 144 - 0
pump-web/src/main/java/com/tuoren/web/layer/controller/BusPatientController.java

@@ -0,0 +1,144 @@
+package com.tuoren.web.layer.controller;
+
+import com.tuoren.common.api.CommonResult;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import com.tuoren.web.layer.vo.PatientParam;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import com.tuoren.web.layer.service.IBusPatientService;
+import com.tuoren.web.layer.entity.BusPatientEntity;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author fanfan
+ * @since 2020-07-03
+ */
+@Api(tags = "BusPatientController", description = "病人信息管理")
+@Slf4j
+@RestController
+@RequestMapping("/bus/patient")
+public class BusPatientController{
+    @Autowired
+    public IBusPatientService iBusPatientEntityService;
+
+    /**
+         * 分页查询所有数据
+         *
+         * @param pageNo 页码
+         * @param pageSize 条数
+         * @param busPatientEntity 查询实体
+         * @return 所有数据
+         */
+        @ApiOperation("分页查询所有数据")
+        @GetMapping
+        public CommonResult selectAll(Integer pageNo, Integer pageSize,BusPatientEntity busPatientEntity) {
+            IPage<BusPatientEntity> page = new Page<>(pageNo,pageSize);
+            QueryWrapper<BusPatientEntity> wrapper = new QueryWrapper<>(busPatientEntity);
+            wrapper.orderByDesc("gmt_modified");
+            return CommonResult.success(this.iBusPatientEntityService.page(page, wrapper));
+        }
+
+    /**
+         * 通过主键查询单条数据
+         *
+         * @param id 主键
+         * @return 单条数据
+         */
+        @ApiOperation("通过主键查询单条数据")
+        @GetMapping("{id}")
+        public CommonResult selectOne(@PathVariable Serializable id) {
+            return CommonResult.success(this.iBusPatientEntityService.getById(id));
+        }
+
+    /**
+         * 新增数据
+         *
+         * @param busPatientEntity  实体对象
+         * @return 新增结果
+         */
+        @ApiOperation("新增数据")
+        @PostMapping
+        public CommonResult insert(@RequestBody BusPatientEntity busPatientEntity) {
+            try{
+                return CommonResult.success(this.iBusPatientEntityService.save( busPatientEntity),"添加成功");
+            } catch (Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("添加失败");
+            }
+        }
+
+    /**
+         * 修改数据
+         *
+         * @param  busPatientEntity 实体对象
+         * @return 修改结果
+         */
+        @ApiOperation("修改数据")
+        @PutMapping
+        public CommonResult update(@RequestBody BusPatientEntity busPatientEntity) {
+            try {
+                return CommonResult.success(this.iBusPatientEntityService.updateById(busPatientEntity),"修改成功");
+            } catch (Exception e) {
+                 log.error("出现错误, {}",e.getMessage());
+                 return CommonResult.failed("修改失败");
+            }
+        }
+
+    /**
+         * 删除数据
+         *
+         * @param idList 主键结合
+         * @return 删除结果
+         */
+        @ApiOperation("删除数据")
+        @DeleteMapping
+        public CommonResult delete(@RequestParam("idList") List<Long> idList) {
+            try{
+                return CommonResult.success(this.iBusPatientEntityService.removeByIds(idList),"删除成功");
+            } catch ( Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("删除失败");
+            }
+        }
+
+    /**
+         * 模糊查询
+         *
+         * @param patientParam 参数
+         * @return 数据
+         */
+        @ApiOperation("模糊查询病人 住院号 patientCode | 泵号 pumpCode | 产品编码类型 productCode | 医院 hospitalCode | 人名 name  | 病区号 wardCode | 床号 bedCode ")
+        @PostMapping("/getFuzzyPatient")
+        public CommonResult getFuzzyPatient(
+                @RequestBody PatientParam patientParam
+        ) {
+            try{
+                IPage<BusPatientEntity> iPage = iBusPatientEntityService.queryFuzzyPatient(patientParam);
+                if( iPage.getRecords().size() > 0 ){
+                    return CommonResult.success(iPage);
+                }
+                return CommonResult.noData();
+            } catch (Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("查询失败");
+            }
+        }
+
+
+
+}

+ 118 - 0
pump-web/src/main/java/com/tuoren/web/layer/controller/BusProductController.java

@@ -0,0 +1,118 @@
+package com.tuoren.web.layer.controller;
+
+import com.tuoren.common.api.CommonResult;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import com.tuoren.web.layer.service.IBusProductService;
+import com.tuoren.web.layer.entity.BusProductEntity;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author fanfan
+ * @since 2020-07-03
+ */
+@Api(tags = "BusProductController", description = "产品管理")
+@Slf4j
+@RestController
+@RequestMapping("/bus/product")
+public class BusProductController{
+    @Autowired
+    public IBusProductService iBusProductEntityService;
+
+    /**
+         * 分页查询所有数据
+         *
+         * @param pageNo 页码
+         * @param pageSize 条数
+         * @param busProductEntity 查询实体
+         * @return 所有数据
+         */
+        @ApiOperation("分页查询所有数据")
+        @GetMapping
+        public CommonResult selectAll(Integer pageNo, Integer pageSize,BusProductEntity busProductEntity) {
+            IPage<BusProductEntity> page = new Page<>(pageNo,pageSize);
+            return CommonResult.success(this.iBusProductEntityService.page(page, new QueryWrapper<>(busProductEntity)));
+        }
+
+    /**
+         * 通过主键查询单条数据
+         *
+         * @param id 主键
+         * @return 单条数据
+         */
+        @ApiOperation("通过主键查询单条数据")
+        @GetMapping("{id}")
+        public CommonResult selectOne(@PathVariable Serializable id) {
+            return CommonResult.success(this.iBusProductEntityService.getById(id));
+        }
+
+    /**
+         * 新增数据
+         *
+         * @param busProductEntity  实体对象
+         * @return 新增结果
+         */
+        @ApiOperation("新增数据")
+        @PostMapping
+        public CommonResult insert(@RequestBody BusProductEntity busProductEntity) {
+            try{
+                return CommonResult.success(this.iBusProductEntityService.save( busProductEntity),"添加成功");
+            } catch (Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("添加失败");
+            }
+        }
+
+    /**
+         * 修改数据
+         *
+         * @param  busProductEntity 实体对象
+         * @return 修改结果
+         */
+        @ApiOperation("修改数据")
+        @PutMapping
+        public CommonResult update(@RequestBody BusProductEntity busProductEntity) {
+            try {
+                return CommonResult.success(this.iBusProductEntityService.updateById(busProductEntity),"修改成功");
+            } catch (Exception e) {
+                 log.error("出现错误, {}",e.getMessage());
+                 return CommonResult.failed("修改失败");
+            }
+        }
+
+    /**
+         * 删除数据
+         *
+         * @param idList 主键结合
+         * @return 删除结果
+         */
+        @ApiOperation("删除数据")
+        @DeleteMapping
+        public CommonResult delete(@RequestParam("idList") List<Long> idList) {
+            try{
+                return CommonResult.success(this.iBusProductEntityService.removeByIds(idList),"删除成功");
+            } catch ( Exception e) {
+                log.error("出现错误, {}",e.getMessage());
+                return CommonResult.failed("删除失败");
+            }
+        }
+
+
+
+}

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff