ChenSir 1 год назад
Сommit
3bc29e20f5
100 измененных файлов с 9565 добавлено и 0 удалено
  1. 47 0
      .gitignore
  2. 8 0
      .idea/.gitignore
  3. 20 0
      .idea/compiler.xml
  4. 21 0
      .idea/encodings.xml
  5. 20 0
      .idea/jarRepositories.xml
  6. 13 0
      .idea/misc.xml
  7. 674 0
      LICENSE
  8. 36 0
      README.en.md
  9. 263 0
      README.md
  10. 117 0
      aidex-admin/pom.xml
  11. 29 0
      aidex-admin/src/main/java/com/aidex/AiDexApplication.java
  12. 18 0
      aidex-admin/src/main/java/com/aidex/AiDexServletInitializer.java
  13. 1 0
      aidex-admin/src/main/resources/META-INF/spring-devtools.properties
  14. 57 0
      aidex-admin/src/main/resources/application-druid.yml
  15. 137 0
      aidex-admin/src/main/resources/application.yml
  16. 27 0
      aidex-admin/src/main/resources/banner.txt
  17. 37 0
      aidex-admin/src/main/resources/i18n/messages.properties
  18. 93 0
      aidex-admin/src/main/resources/logback.xml
  19. 20 0
      aidex-admin/src/main/resources/mybatis/mybatis-config.xml
  20. 16 0
      aidex-admin/src/main/resources/rebel.xml
  21. 1 0
      aidex-admin/target/classes/META-INF/spring-devtools.properties
  22. 57 0
      aidex-admin/target/classes/application-druid.yml
  23. 137 0
      aidex-admin/target/classes/application.yml
  24. 27 0
      aidex-admin/target/classes/banner.txt
  25. BIN
      aidex-admin/target/classes/com/aidex/AiDexApplication.class
  26. BIN
      aidex-admin/target/classes/com/aidex/AiDexServletInitializer.class
  27. 37 0
      aidex-admin/target/classes/i18n/messages.properties
  28. 93 0
      aidex-admin/target/classes/logback.xml
  29. 20 0
      aidex-admin/target/classes/mybatis/mybatis-config.xml
  30. 16 0
      aidex-admin/target/classes/rebel.xml
  31. 172 0
      aidex-common/pom.xml
  32. 15 0
      aidex-common/src/main/java/com/aidex/common/annotation/Anonymous.java
  33. 11 0
      aidex-common/src/main/java/com/aidex/common/annotation/AnonymousAccess.java
  34. 28 0
      aidex-common/src/main/java/com/aidex/common/annotation/DataScope.java
  35. 28 0
      aidex-common/src/main/java/com/aidex/common/annotation/DataSource.java
  36. 188 0
      aidex-common/src/main/java/com/aidex/common/annotation/Excel.java
  37. 18 0
      aidex-common/src/main/java/com/aidex/common/annotation/Excels.java
  38. 46 0
      aidex-common/src/main/java/com/aidex/common/annotation/Log.java
  39. 38 0
      aidex-common/src/main/java/com/aidex/common/annotation/RateLimiter.java
  40. 26 0
      aidex-common/src/main/java/com/aidex/common/annotation/RepeatSubmit.java
  41. 155 0
      aidex-common/src/main/java/com/aidex/common/config/AiDexConfig.java
  42. 74 0
      aidex-common/src/main/java/com/aidex/common/constant/CacheConstants.java
  43. 187 0
      aidex-common/src/main/java/com/aidex/common/constant/Constants.java
  44. 287 0
      aidex-common/src/main/java/com/aidex/common/constant/GenConstants.java
  45. 99 0
      aidex-common/src/main/java/com/aidex/common/constant/HttpStatus.java
  46. 50 0
      aidex-common/src/main/java/com/aidex/common/constant/ScheduleConstants.java
  47. 108 0
      aidex-common/src/main/java/com/aidex/common/constant/UserConstants.java
  48. 10 0
      aidex-common/src/main/java/com/aidex/common/core/annotation/ConfigurationCore.java
  49. 213 0
      aidex-common/src/main/java/com/aidex/common/core/controller/BaseController.java
  50. 195 0
      aidex-common/src/main/java/com/aidex/common/core/domain/AjaxResult.java
  51. 260 0
      aidex-common/src/main/java/com/aidex/common/core/domain/BaseEntity.java
  52. 41 0
      aidex-common/src/main/java/com/aidex/common/core/domain/BaseTreeEntity.java
  53. 133 0
      aidex-common/src/main/java/com/aidex/common/core/domain/R.java
  54. 113 0
      aidex-common/src/main/java/com/aidex/common/core/domain/ResultCode.java
  55. 104 0
      aidex-common/src/main/java/com/aidex/common/core/domain/TreeNode.java
  56. 309 0
      aidex-common/src/main/java/com/aidex/common/core/domain/TreeNodes.java
  57. 98 0
      aidex-common/src/main/java/com/aidex/common/core/domain/TreeSelect.java
  58. 12 0
      aidex-common/src/main/java/com/aidex/common/core/domain/entity/RegisterBody.java
  59. 67 0
      aidex-common/src/main/java/com/aidex/common/core/domain/entity/SysDept.java
  60. 90 0
      aidex-common/src/main/java/com/aidex/common/core/domain/entity/SysMenu.java
  61. 187 0
      aidex-common/src/main/java/com/aidex/common/core/domain/entity/SysRole.java
  62. 267 0
      aidex-common/src/main/java/com/aidex/common/core/domain/entity/SysUser.java
  63. 128 0
      aidex-common/src/main/java/com/aidex/common/core/domain/entity/SysUserMenu.java
  64. 96 0
      aidex-common/src/main/java/com/aidex/common/core/domain/entity/_BeanLis.java
  65. 69 0
      aidex-common/src/main/java/com/aidex/common/core/domain/model/LoginBody.java
  66. 284 0
      aidex-common/src/main/java/com/aidex/common/core/domain/model/LoginUser.java
  67. 58 0
      aidex-common/src/main/java/com/aidex/common/core/mapper/BaseMapper.java
  68. 13 0
      aidex-common/src/main/java/com/aidex/common/core/mapper/BaseTreeMapper.java
  69. 163 0
      aidex-common/src/main/java/com/aidex/common/core/page/PageDomain.java
  70. 85 0
      aidex-common/src/main/java/com/aidex/common/core/page/TableDataInfo.java
  71. 56 0
      aidex-common/src/main/java/com/aidex/common/core/page/TableSupport.java
  72. 491 0
      aidex-common/src/main/java/com/aidex/common/core/redis/RedisCache.java
  73. 320 0
      aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/Base64.java
  74. 23 0
      aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/BaseDigestPasswordEncoder.java
  75. 44 0
      aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/BasePasswordEncoder.java
  76. 29 0
      aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/Hex.java
  77. 84 0
      aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/MessageDigestPasswordEncoder.java
  78. 13 0
      aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/PasswordEncoder.java
  79. 15 0
      aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/ShaPasswordEncoder.java
  80. 43 0
      aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/Utf8.java
  81. 86 0
      aidex-common/src/main/java/com/aidex/common/core/text/CharsetKit.java
  82. 1001 0
      aidex-common/src/main/java/com/aidex/common/core/text/Convert.java
  83. 92 0
      aidex-common/src/main/java/com/aidex/common/core/text/StrFormatter.java
  84. 20 0
      aidex-common/src/main/java/com/aidex/common/enums/BusinessStatus.java
  85. 68 0
      aidex-common/src/main/java/com/aidex/common/enums/BusinessType.java
  86. 19 0
      aidex-common/src/main/java/com/aidex/common/enums/DataSourceType.java
  87. 36 0
      aidex-common/src/main/java/com/aidex/common/enums/HttpMethod.java
  88. 20 0
      aidex-common/src/main/java/com/aidex/common/enums/LimitType.java
  89. 24 0
      aidex-common/src/main/java/com/aidex/common/enums/OperatorType.java
  90. 30 0
      aidex-common/src/main/java/com/aidex/common/enums/UserStatus.java
  91. 129 0
      aidex-common/src/main/java/com/aidex/common/exception/Assert.java
  92. 128 0
      aidex-common/src/main/java/com/aidex/common/exception/BaseException.java
  93. 57 0
      aidex-common/src/main/java/com/aidex/common/exception/BizException.java
  94. 43 0
      aidex-common/src/main/java/com/aidex/common/exception/CustomException.java
  95. 15 0
      aidex-common/src/main/java/com/aidex/common/exception/DemoModeException.java
  96. 14 0
      aidex-common/src/main/java/com/aidex/common/exception/ErrorCodeI.java
  97. 18 0
      aidex-common/src/main/java/com/aidex/common/exception/ExpireException.java
  98. 58 0
      aidex-common/src/main/java/com/aidex/common/exception/GlobalException.java
  99. 22 0
      aidex-common/src/main/java/com/aidex/common/exception/SysException.java
  100. 0 0
      aidex-common/src/main/java/com/aidex/common/exception/UtilException.java

+ 47 - 0
.gitignore

@@ -0,0 +1,47 @@
+######################################################################
+# Build Tools
+
+.gradle
+/build/
+!gradle/wrapper/gradle-wrapper.jar
+
+target/
+!.mvn/wrapper/maven-wrapper.jar
+
+######################################################################
+# IDE
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### JRebel ###
+rebel.xml
+
+### NetBeans ###
+nbproject/private/
+build/*
+nbbuild/
+dist/
+nbdist/
+.nb-gradle/
+
+######################################################################
+# Others
+*.log
+*.xml.versionsBackup
+*.swp
+
+!*/build/*.java
+!*/build/*.html
+!*/build/*.xml

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 20 - 0
.idea/compiler.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <annotationProcessing>
+      <profile default="true" name="Default" enabled="true" />
+      <profile name="Maven default annotation processors profile" enabled="true">
+        <sourceOutputDir name="target/generated-sources/annotations" />
+        <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
+        <outputRelativeToContentRoot value="true" />
+        <module name="aidex-generator" />
+        <module name="aidex-system" />
+        <module name="aidex-admin" />
+        <module name="aidex-controller" />
+        <module name="aidex-common" />
+        <module name="aidex-framework" />
+        <module name="aidex-quartz" />
+      </profile>
+    </annotationProcessing>
+  </component>
+</project>

+ 21 - 0
.idea/encodings.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding">
+    <file url="file://$PROJECT_DIR$/aidex-admin/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-admin/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-common/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-common/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-controller/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-controller/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-framework/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-framework/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-generator/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-generator/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-quartz/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-quartz/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-system/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/aidex-system/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
+  </component>
+</project>

+ 20 - 0
.idea/jarRepositories.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RemoteRepositoriesConfiguration">
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Central Repository" />
+      <option name="url" value="http://maven.aliyun.com/nexus/content/repositories/central/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Maven Central repository" />
+      <option name="url" value="https://repo1.maven.org/maven2" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="jboss.community" />
+      <option name="name" value="JBoss Community repository" />
+      <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
+    </remote-repository>
+  </component>
+</project>

+ 13 - 0
.idea/misc.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="MavenProjectsManager">
+    <option name="originalFiles">
+      <list>
+        <option value="$PROJECT_DIR$/pom.xml" />
+      </list>
+    </option>
+    <option name="workspaceImportForciblyTurnedOn" value="true" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="1.8 (1)" project-jdk-type="JavaSDK" />
+</project>

+ 674 - 0
LICENSE

@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.

+ 36 - 0
README.en.md

@@ -0,0 +1,36 @@
+# AiDex Sharp
+
+#### Description
+AiDex Sharp快速开发平台
+
+#### Software Architecture
+Software architecture description
+
+#### Installation
+
+1.  xxxx
+2.  xxxx
+3.  xxxx
+
+#### Instructions
+
+1.  xxxx
+2.  xxxx
+3.  xxxx
+
+#### Contribution
+
+1.  Fork the repository
+2.  Create Feat_xxx branch
+3.  Commit your code
+4.  Create Pull Request
+
+
+#### Gitee Feature
+
+1.  You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
+2.  Gitee blog [blog.gitee.com](https://blog.gitee.com)
+3.  Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
+4.  The most valuable open source project [GVP](https://gitee.com/gvp)
+5.  The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
+6.  The most popular members  [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

+ 263 - 0
README.md

@@ -0,0 +1,263 @@
+
+<div align="center"><h3 align="center">AiDex Sharp 快速开发平台</h3></div>
+<div align="center"><h3 align="center">基于若依扩展的Spring Boot前后端分离架构,代码精简,开箱即用,紧随前沿技术</h3></div>
+
+<p align="center">     
+    <p align="center">
+        <a>
+            <img src="https://img.shields.io/badge/aidex--sharp-V3.3-green" alt="Aidex-Sharp">
+        </a>
+        <a href="https://gitee.com/big-hedgehog/aidex-sharp">
+            <img src="https://gitee.com/big-hedgehog/aidex-sharp/badge/star.svg?theme=dark" alt="Gitee star">
+        </a>
+        <a href="https://gitee.com/big-hedgehog/aidex-sharp">
+            <img src="https://gitee.com/big-hedgehog/aidex-sharp/badge/fork.svg?theme=dark" alt="Gitee fork">
+        </a>
+    </p>
+</p>
+
+## 平台简介
+
+ **AiDex Sharp 快速开发平台** 基于著名的开源项目“ **若依-RuoYi-Vue** ”改造而成,追求 **极致的UI交互体验** 和 **快速开发** ,一切向 **效率** 看齐, **重构优化** 后端的代码,对前端页面进行了 **美化** 。 **我们将持续升级,持续完善,欢迎友友们收藏和点赞** 。
+
+* 感谢[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)
+* 感谢[RuoYi-Antdv](https://gitee.com/fuzui/RuoYi-Antdv)
+
+## 基于RuoYi修改的美化皮肤的样式地址
+
+- [🎉 RuoYi + vue2.x + Max + element-ui(vue2.x 支持 PC、平板、手机)](http://82.157.44.212:8091/index)
+
+- [🎉 RuoYi + vue3.x + Max + element-plus(vue3.x 支持 PC、平板、手机)](http://82.157.44.212:8090/index)
+
+- [🎉 RuoYi + vue2.x + Max + element-ui + Cloud(vue2.x 支持 PC、平板、手机)](http://82.157.44.212:8093/index)
+
+- [🎉 RuoYi + vue3.x + Max + element-plus + Cloud(vue3.x 支持 PC、平板、手机)](http://82.157.44.212:8092/index)
+
+- [🎉 RuoYi + vue3.x + element-plus + uniapp2(vue3.x 支持 PC、平板、手机)](http://82.157.44.212:8094/#/)
+
+
+## 系统截图(开源版:完全免费开源)
+
+<table>
+    <tr>
+        <td><img src="https://images.gitee.com/uploads/images/2021/0923/234823_7d05456a_9700683.png"/></td>
+        <td><img src="https://images.gitee.com/uploads/images/2021/0923/234748_170e4ee7_9700683.png"/></td>
+    </tr>
+    <tr>
+        <td><img src="https://images.gitee.com/uploads/images/2021/0911/184041_c4d1f1aa_9700683.png"/></td>
+        <td><img src="https://images.gitee.com/uploads/images/2021/0911/184055_0cf08e45_9700683.png"/></td>
+    </tr>
+	<tr>
+        <td><img src="https://images.gitee.com/uploads/images/2021/0911/184110_2e6df64f_9700683.png"/></td>
+        <td><img src="https://images.gitee.com/uploads/images/2021/0911/184125_3d5bdddf_9700683.png"/></td>
+    </tr>	 
+    <tr>
+        <td><img src="https://images.gitee.com/uploads/images/2021/0911/184139_092a8f07_9700683.png"/></td>
+        <td><img src="https://images.gitee.com/uploads/images/2021/0922/225255_f8710fb3_9700683.png"/></td>
+    </tr>
+	<tr>
+        <td><img src="https://images.gitee.com/uploads/images/2021/0911/184210_ffa2880b_9700683.png"/></td>
+        <td><img src="https://images.gitee.com/uploads/images/2021/0911/184223_8f57f5f0_9700683.png"/></td>
+    </tr>
+	<tr>
+        <td><img src="https://images.gitee.com/uploads/images/2021/0911/184238_5cb3e09e_9700683.png"/></td>
+        <td><img src="https://images.gitee.com/uploads/images/2021/0911/184256_5bc77bff_9700683.png"/></td>
+    </tr>
+</table>
+更多功能请访问系统体验
+
+## 在线体验
+
+演示地址:http://aidex.vip  帐号:admin 密码:admin123
+
+## 关于我们
+
+&nbsp; &nbsp; 我们擅长UI、前端开发、后端架构,有一颗热爱开源的心,致力于打造企业级的通用产品设计UI体系让项目
+或者更直观,更高效、更简单,未来将持续关注UI交互,持续推出高质量的交互产品。
+#####
+ **QQ:1125373330**  <a target="_blank" href="http://wpa.qq.com/msgrd?v=3&amp;uin=1125373330&amp;site=qq&amp;menu=yes">    点击这里给我发消息</a>
+######
+<img src="https://images.gitee.com/uploads/images/2021/1112/114326_5eb079c2_9700683.jpeg" width="220" height="220" >&nbsp; &nbsp; &nbsp;&nbsp;
+<img src="https://images.gitee.com/uploads/images/2021/1112/114207_bb1bac92_9700683.jpeg" width="220" height="220" >&nbsp; &nbsp; &nbsp;&nbsp; 
+<img src="https://images.gitee.com/uploads/images/2021/1115/164243_d4e0d61d_9700683.png" width="220" height="220" >&nbsp; &nbsp; &nbsp;&nbsp;
+
+   **承接各种XX软件和APP定制开发,请让我发挥专业的技能(UI设计+前端开发7年工龄的程序媛,请对我有信心,超出你的期待哦)具体私聊** 
+
+## 官方QQ群
+
+<a target="_blank" href="https://jq.qq.com/?_wv=1027&k=HaFOKk34&jump_from=webapi"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="Aidex Sharp快速开发平台3群" title="Aidex Sharp快速开发平台3群"> 471693493</a> 使用问题请入群由专人负责简答
+
+
+## 框架优势
+
+* 基于RuoYi-Vue和Ant Design Vue Pro的结合,并进行了UI交互的深度改造。
+* 高效率开发,使用代码生成器可以一键生成前后端代码,可在线预览代码。
+* 代码生成器:自动包含规范,可根据以下规则自动设置:居中、居左、居右,列表页面遵循一下对齐格式:
+  > 1.  居中显示:短小字符居中(用户名)、通用代码、日期时间、数值位数相等的字段(如:编码、编号)、整数型数字(如年龄,个数)
+  > 2.  居左:比较长的字符居左(备注等),部门名称、名称、标题
+  > 3.  居右:货币或带小数点的数字居右,如带小数点的数字,数量、百分数
+* 代码生成器:支撑自动选择图标,挂载菜单。
+* 代码生成器:支持列拖拽,方便表单和列表页面的列排序。
+* 代码生成器:可自定义选择生成唯一性校验代码,减少代码开发量。
+* 列显示定义:用户可自定义列选择和列定义。
+* 表头排序:支持服务端表头排序。
+* 文件中心:内置异步导入和导出的文件管理中心,所有下载附件均以异步任务方式进行提交管理,类似于阿里云的账单中心功能。
+* 代码优化:优化Mapper中的SQL,对各种方法进行片段化管理,最大限度精简方法,提升代码整洁度。
+* 缓存工具类抽取。
+* base类抽取:抽取baseEntity,BaseService,BaseMapper,提出公共方法,减少代码量。
+* 缓存Key监控:监控系统中的缓存信息,并可以删除key,预览缓存内容。
+* 特别鸣谢:[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)。
+* 特别鸣谢:[RuoYi-Antdv](https://gitee.com/fuzui/RuoYi-Antdv)。
+
+## 代码生成器优化
+* 根据不同的页面布局生成不同的页面尺寸
+* 增加控件类型:单选按钮控件
+* 增加复制数据功能
+* 增加继续添加功能
+* 默认的状态列支持
+* 提交时按钮禁用(全局的如何控制?)
+* 表头排序
+* 状态列自动格式化
+* 上传后如何清空文件列表
+* 调整按钮顺序:新增、删除、导出
+* 优化关闭的代码
+
+## 登录页面模板
+
+<table>
+    <tr>
+        <td><img src="%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2%E6%A8%A1%E6%9D%BF/01.png"/></td>
+        <td><img src="%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2%E6%A8%A1%E6%9D%BF/02.png"/></td>
+    </tr>
+    <tr>
+        <td><img src="%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2%E6%A8%A1%E6%9D%BF/08.png"/></td>
+        <td><img src="%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2%E6%A8%A1%E6%9D%BF/09.png"/></td>
+    </tr>
+	<tr>
+        <td><img src="%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2%E6%A8%A1%E6%9D%BF/11.png"/></td>
+        <td><img src="%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2%E6%A8%A1%E6%9D%BF/14.png"/></td>
+    </tr>	 
+    <tr>
+        <td><img src="%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2%E6%A8%A1%E6%9D%BF/18.png"/></td>
+        <td><img src="%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2%E6%A8%A1%E6%9D%BF/22.png"/></td>
+    </tr>
+	<tr>
+        <td><img src="%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2%E6%A8%A1%E6%9D%BF/13.png"/></td>
+        <td><img src="%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2%E6%A8%A1%E6%9D%BF/06.png"/></td>
+    </tr>
+</table>
+
+## 内置功能
+
+斜体为重点增强优化功能
+
+1.  _用户管理:用户是系统操作者,该功能主要完成系统用户配置。_
+2.  _部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。_
+3.  _岗位管理:配置系统用户所属担任职务。_
+4.  _菜单管理:配置系统菜单,操作权限,按钮权限标识等。_
+5.  _角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。_
+6.  _字典管理:对系统中经常使用的一些较为固定的数据进行维护。_
+7.  _参数管理:对系统动态配置常用参数。_
+8.  通知公告:系统通知公告信息发布维护。
+9.  操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
+10. _登录日志:系统登录日志记录查询包含登录异常。_
+11. 在线用户:当前系统中活跃用户状态监控。
+12. _定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。_
+13. _代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。_
+14. 系统接口:根据业务代码自动生成相关的api接口文档。
+15. _服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。_
+16. _缓存监控:对系统的缓存信息查询,命令统计等。_
+17. _缓存列表:对系统的缓存信息查询,命令统计等。_
+18. 在线构建器:拖动表单元素生成相应的HTML代码。
+19. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
+
+
+---
+前端工程结构
+---
+
+```
+├── public
+│   └── logo.png             # LOGO
+|   └── index.html           # Vue 入口模板
+├── src
+│   ├── api                  # Api ajax 等
+│   ├── assets               # 本地静态资源
+│   ├── config               # 项目基础配置,包含路由,全局设置
+│   ├── components           # 业务通用组件
+│   ├── core                 # 项目引导, 全局配置初始化,依赖包引入等
+│   ├── directive            # 自定义指令
+│   ├── router               # Vue-Router
+│   ├── store                # Vuex
+│   ├── utils                # 工具库
+│   ├── locales              # 国际化资源
+│   ├── views                # 业务页面入口和常用模板
+│   ├── App.vue              # Vue 模板入口
+│   └── main.js              # Vue 入口 JS
+│   └── permission.js        # 路由守卫(路由权限控制)
+│   └── global.less          # 全局样式
+├── tests                    # 测试工具
+├── README.md
+└── package.json
+```
+
+## 后端工程结构
+
+| 项目 | 说明 |
+| --- | --- |
+| `aidex-admin` | 系统启动入口 |
+| `aidex-common` | 工具类 |
+| `aidex-controller` | 前台控制器 |
+| `aidex-framework` | 框架核心 |
+| `aidex-generator` | 代码生成工具 |
+| `aidex-quartz` | 定时任务|
+| `aidex-system` | 系统管理 |
+
+更多功能请访问系统。
+
+---
+系统在线文档
+---
+* 文档地址(参考若依):<http://doc.ruoyi.vip/> 
+* RuoYi-Vue文档:[https://doc.ruoyi.vip/ruoyi-vue/](https://doc.ruoyi.vip/ruoyi-vue/)
+* Ant Design Vue文档:[https://www.antdv.com/docs/vue/introduce-cn/](https://www.antdv.com/docs/vue/introduce-cn/)
+* [《如何搭建环境》](http://doc.ruoyi.vip/ruoyi-vue/document/hjbs.html)
+* [《常见问题》](http://doc.ruoyi.vip/ruoyi-vue/document/hjbs.html#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98)
+
+ **> 未来会补充文档和视频,方便友友们使用!** 
+
+## 开发计划
+
+* :clipboard: 代码生成单表、主子表自动生成选择页面代码
+* :clipboard: ​文件管理中心
+* :clipboard: 首页快速入口自定义
+* :clipboard: 移动开发平台-基于uniapp
+* :clipboard: 代码生成器持续增强,将效率追求到极致
+* :clipboard: 自定义列显隐
+* :clipboard: 适配国产数据库(金仓、达梦)、主流数据库Mysql、Oracle、Mssql、Postgresql
+* :clipboard: 支持国产中间件部署(中创+东方通)、麒麟操作系统、Windows、Linux部署使用
+
+## 平台官网
+
+  www.aidex.vip
+
+---
+版权说明:近期将会推送更新一版本,重点升级代码生成器,并修复相关漏洞,Uview2.0已经研发完成
+---
+
+* Aidex Sharp快速开发平台采用GPL技术协议
+* 代码可用于个人项目等接私活或企业项目脚手架使用,Aidex Sharp全系开源版完全免费
+* 二次开发如用于商业性质或开源竞品请先联系群主审核
+* 允许进行商用,但是不允许二次开源出来并进行收费
+* 请不要删除和修改Aidex Sharp源码头部的版权与作者声明及出处
+* 不得进行简单修改包装声称是自己的项目
+* 我们已经申请了相关的软件开发著作权和相关登记
+* 如有使用我们项目样式等的扩展项目,请在项目介绍中,进行明确说明
+---
+参与贡献
+---
+欢迎各路英雄好汉参与Aidex Sharp代码贡献,期待您的加入!
+Fork 本仓库
+新建 Feat_xxx 分支
+提交代码
+新建 Pull Request

+ 117 - 0
aidex-admin/pom.xml

@@ -0,0 +1,117 @@
+<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>aidex</artifactId>
+        <groupId>com.aidex</groupId>
+        <version>3.4.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>jar</packaging>
+    <artifactId>aidex-admin</artifactId>
+
+    <description>
+        web服务入口
+    </description>
+
+    <dependencies>
+
+        <!-- spring-boot-devtools -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <optional>true</optional> <!-- 表示依赖不会传递 -->
+        </dependency>
+
+        <!-- swagger3-->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-boot-starter</artifactId>
+        </dependency>
+
+        <!-- 防止进入swagger页面报类型转换错误,排除3.0.0中的引用,手动增加1.6.2版本 -->
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-models</artifactId>
+            <version>1.6.2</version>
+        </dependency>
+
+         <!-- Mysql驱动包 -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <!-- 核心模块-->
+        <dependency>
+            <groupId>com.aidex</groupId>
+            <artifactId>aidex-controller</artifactId>
+            <version>3.4.0</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.1.1.RELEASE</version>
+                <configuration>
+                    <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>   
+                <groupId>org.apache.maven.plugins</groupId>   
+                <artifactId>maven-war-plugin</artifactId>   
+                <version>3.1.0</version>   
+                <configuration>
+                    <failOnMissingWebXml>false</failOnMissingWebXml>
+                    <warName>${project.artifactId}</warName>
+                </configuration>   
+           </plugin>
+
+           <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <configuration>
+                    <encoding>utf-8</encoding>
+                    <useDefaultDelimiters>true</useDefaultDelimiters>
+                    <nonFilteredFileExtensions>
+                        <nonFilteredFileExtension>license</nonFilteredFileExtension>
+                        <nonFilteredFileExtension>zzh</nonFilteredFileExtension>
+                    </nonFilteredFileExtensions>
+                </configuration>
+            </plugin>
+
+        </plugins>
+        <finalName>${project.artifactId}</finalName>
+
+        <!--<resources>
+            <resource>
+                <directory>src/main/java</directory>
+                <excludes>
+                    <exclude>**/*.java</exclude>
+                    <exclude>**/.svn/*</exclude>
+                </excludes>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                    <include>**/*.xml</include>
+                    <include>**/*.yml</include>
+                    <include>**/*.res</include>
+                    <include>**/*.zdl</include>
+                </includes>
+            </resource>
+        </resources>-->
+    </build>
+
+</project>

+ 29 - 0
aidex-admin/src/main/java/com/aidex/AiDexApplication.java

@@ -0,0 +1,29 @@
+package com.aidex;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+
+/**
+ * 启动程序
+ *
+ * @author ruoyi
+ */
+@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
+public class AiDexApplication
+{
+    public static void main(String[] args)
+    {
+        System.setProperty("spring.devtools.restart.enabled", "false");
+        SpringApplication.run(AiDexApplication.class, args);
+        StringBuffer aidex = new StringBuffer("(♥◠‿◠)ノ゙  AiDex启动成功   ლ(´ڡ`ლ)゙  \n");
+        aidex.append("    /\\   (_)  __ \\             / ____| |\n");
+        aidex.append("   /  \\   _| |  | | _____  __ | (___ | |__   __ _ _ __ _ __\n");
+        aidex.append("  / /\\ \\ | | |  | |/ _ \\ \\/ /  \\___ \\| '_ \\ / _` | '__| '_ \\\n");
+        aidex.append(" / ____ \\| | |__| |  __/>  <   ____) | | | | (_| | |  | |_) |\n");
+        aidex.append("/_/    \\_\\_|_____/ \\___/_/\\_\\ |_____/|_| |_|\\__,_|_|  | .__/\n");
+        aidex.append("                                                      | |\n");
+        aidex.append("                                                      |_|");
+        System.out.println(aidex);
+    }
+}

+ 18 - 0
aidex-admin/src/main/java/com/aidex/AiDexServletInitializer.java

@@ -0,0 +1,18 @@
+package com.aidex;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+/**
+ * web容器中进行部署
+ * 
+ * @author ruoyi
+ */
+public class AiDexServletInitializer extends SpringBootServletInitializer
+{
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
+    {
+        return application.sources(AiDexApplication.class);
+    }
+}

+ 1 - 0
aidex-admin/src/main/resources/META-INF/spring-devtools.properties

@@ -0,0 +1 @@
+restart.include.json=/com.alibaba.fastjson.*.jar

+ 57 - 0
aidex-admin/src/main/resources/application-druid.yml

@@ -0,0 +1,57 @@
+# 数据源配置
+spring:
+    datasource:
+        type: com.alibaba.druid.pool.DruidDataSource
+        driverClassName: com.mysql.cj.jdbc.Driver
+        druid:
+            # 主库数据源
+            master:
+                url: jdbc:mysql://localhost:3366/water_bus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&&allowMultiQueries=true
+                username: root
+                password: root@!QAZ2020
+            # 从库数据源
+            slave:
+                # 从数据源开关/默认关闭
+                enabled: false
+                url:
+                username:
+                password:
+            # 初始连接数
+            initialSize: 5
+            # 最小连接池数量
+            minIdle: 10
+            # 最大连接池数量
+            maxActive: 20
+            # 配置获取连接等待超时的时间
+            maxWait: 60000
+            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+            timeBetweenEvictionRunsMillis: 60000
+            # 配置一个连接在池中最小生存的时间,单位是毫秒
+            minEvictableIdleTimeMillis: 300000
+            # 配置一个连接在池中最大生存的时间,单位是毫秒
+            maxEvictableIdleTimeMillis: 900000
+            # 配置检测连接是否有效
+            validationQuery: SELECT 1 FROM DUAL
+            testWhileIdle: true
+            testOnBorrow: false
+            testOnReturn: false
+            webStatFilter:
+                enabled: true
+            statViewServlet:
+                enabled: false
+                # 设置白名单,不填则允许所有访问
+                allow:
+                url-pattern: /druid/*
+                # 控制台管理用户名和密码
+                login-username: aidex
+                login-password: 123456
+            filter:
+                stat:
+                    enabled: true
+                    # 慢SQL记录
+                    log-slow-sql: true
+                    slow-sql-millis: 1000
+                    merge-sql: true
+                wall:
+                    config:
+                        multi-statement-allow: true

+ 137 - 0
aidex-admin/src/main/resources/application.yml

@@ -0,0 +1,137 @@
+# 项目相关配置
+aidex:
+  # 名称 水上公交
+  name: water_bus
+  # 版本
+  version: 3.3.0
+  # 版权年份
+  copyrightYear: 2024
+  # 实例演示开关
+  demoEnabled: true
+  # 文件路径 示例( Windows配置D:/aidex/uploadPath,Linux配置 /home/aidex/uploadPath)
+  profile: D:/aidex/uploadPath
+  # 获取ip地址开关
+  addressEnabled: false
+  # 验证码类型 math 数组计算 char 字符验证
+  captchaType: math
+
+# 开发环境配置
+server:
+  # 服务器的HTTP端口,默认为8080
+  port: 18080
+  servlet:
+    # 应用的访问路径
+    context-path: /
+  tomcat:
+    # tomcat的URI编码
+    uri-encoding: UTF-8
+    # 连接数满后的排队数,默认为100
+    accept-count: 1000
+    threads:
+      # tomcat最大线程数,默认为200
+      max: 800
+      # Tomcat启动初始化的线程数,默认值10
+      min-spare: 100
+
+# 日志配置
+logging:
+  level:
+    com.aidex: error
+    org.springframework: error
+
+# 用户配置
+user:
+  password:
+    # 密码最大错误次数
+    maxRetryCount: 5
+    # 密码锁定时间(默认10分钟)
+    lockTime: 10
+
+# Spring配置
+spring:
+  # 资源信息
+  messages:
+    # 国际化资源文件路径
+    basename: i18n/messages
+  profiles:
+    active: druid
+  # 文件上传
+  servlet:
+     multipart:
+       # 单个文件大小
+       max-file-size:  10MB
+       # 设置总上传的文件大小
+       max-request-size:  20MB
+  # 服务模块
+  devtools:
+    restart:
+      # 热部署开关
+      enabled: true
+  # redis 配置
+  redis:
+    # 地址
+    host: localhost
+    # 端口,默认为6379
+    port: 16379
+    # 数据库索引
+    database: 0
+    # 密码
+    password:
+    # 连接超时时间
+    timeout: 10s
+    lettuce:
+      pool:
+        # 连接池中的最小空闲连接
+        min-idle: 0
+        # 连接池中的最大空闲连接
+        max-idle: 8
+        # 连接池的最大数据库连接数
+        max-active: 8
+        # #连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-wait: -1ms
+
+# token配置
+token:
+    # 令牌自定义标识
+    header: Authorization
+    # 令牌密钥
+    secret: abcdefghijklmnopqrstuvwxyz
+    # 令牌有效期(默认30分钟)
+    expireTime: 30
+    # 是否允许账户多终端同时登录(true允许 false不允许)
+    soloLogin: true
+
+# MyBatis配置
+mybatis:
+    # 搜索指定包别名
+    typeAliasesPackage: com.aidex.**.domain,com.aidex.**.entity,com.aidex.**.po
+    # 配置mapper的扫描,找到所有的mapper.xml映射文件
+    mapperLocations: classpath*:mapper/**/*Mapper.xml,classpath*:com/aidex/**/mapper/*Mapper.xml
+    # 加载全局的配置文件
+    configLocation: classpath:mybatis/mybatis-config.xml
+    # 加载全局的配置文件
+    dbName: oracle
+    # 是否显示拦截器输出sql
+    isShowMyBatisSql: true
+
+# PageHelper分页插件
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger配置
+swagger:
+  # 是否开启swagger
+  enabled: true
+  # 请求前缀
+  pathMapping: /dev-api
+
+# 防止XSS攻击
+xss:
+  # 过滤开关
+  enabled: true
+  # 排除链接(多个用逗号分隔)
+  excludes: /system/notice
+  # 匹配链接
+  urlPatterns: /system/*,/monitor/*,/tool/*

+ 27 - 0
aidex-admin/src/main/resources/banner.txt

@@ -0,0 +1,27 @@
+Application Version: ${aidex.version}
+Spring Boot Version: ${spring-boot.version}
+///////////////////////////////////////////////////////////////////////////////////////////
+//                                                                                       //
+//                                                                                       //
+//                                               |                                       //
+//                                              -+-                                      //
+//                                             ==| ___                                   //
+//                                   _____       | _T                                    //
+//                                    |   \      / \                                     //
+//                                  +-+----+-------------+               |               //
+//               _______.._______   |  O   O   O   O  __[]_              |               //
+//      ( )\________/     ==)__     |_________________|___|              |      ==|      //
+//       \__=*=_/0/_   --+q+ l_\    |                    |     _         #________|_     //
+//       ___________\____l_l_l__D___|  O            O  O |    ( )       /     O   /      //
+//      | [] uscgc yukon                                 |___/___\_____/        /        //
+//      |                               U.S. COAST GUARD / _  /  14           /          //
+//      \                                               / (0)/              /            //
+//        \____________________________________________/____/______________/             //
+//                                                                                       //
+//                 by Enrico Piazza                                                      //
+//                                                                                       //
+//                                                                                       //
+///////////////////////////////////////////////////////////////////////////////////////////
+
+
+

+ 37 - 0
aidex-admin/src/main/resources/i18n/messages.properties

@@ -0,0 +1,37 @@
+#错误消息
+not.null=* 必须填写
+user.jcaptcha.error=验证码错误
+user.jcaptcha.expire=验证码已失效
+user.not.exists=用户不存在/密码错误
+user.password.not.match=用户不存在/密码错误
+user.password.retry.limit.count=密码输入错误{0}次
+user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定10分钟
+user.password.delete=对不起,您的账号已被删除
+user.blocked=用户已封禁,请联系管理员
+role.blocked=角色已封禁,请联系管理员
+user.logout.success=退出成功
+
+length.not.valid=长度必须在{min}到{max}个字符之间
+
+user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
+user.password.not.valid=* 5-50个字符
+
+user.email.not.valid=邮箱格式错误
+user.mobile.phone.number.not.valid=手机号格式错误
+user.login.success=登录成功
+user.register.success=注册成功
+user.notfound=请重新登录
+user.forcelogout=管理员强制退出,请重新登录
+user.unknown.error=未知错误,请重新登录
+
+##文件上传消息
+upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
+upload.filename.exceed.length=上传的文件名最长{0}个字符
+
+##权限
+no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
+no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
+no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
+no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
+no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
+no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]

+ 93 - 0
aidex-admin/src/main/resources/logback.xml

@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <!-- 日志存放路径 -->
+	<property name="log.path" value="/home/aidex/logs" />
+    <!-- 日志输出格式 -->
+	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
+
+	<!-- 控制台输出 -->
+	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+	
+	<!-- 系统日志输出 -->
+	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/sys-info.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+			<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>error</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+	</appender>
+	
+	<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/sys-error.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>ERROR</level>
+			<!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+			<!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+	
+	<!-- 用户访问日志输出  -->
+    <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>${log.path}/sys-user.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 按天回滚 daily -->
+            <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!-- 日志最大的历史 60天 -->
+            <maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+    </appender>
+	
+	<!-- 系统模块日志级别控制  -->
+	<logger name="com.aidex" level="error" />
+	<!-- Spring日志级别控制  -->
+	<logger name="org.springframework" level="error" />
+
+	<root level="error">
+		<appender-ref ref="console" />
+	</root>
+	
+	<!--系统操作日志-->
+    <root level="error">
+        <appender-ref ref="file_info" />
+        <appender-ref ref="file_error" />
+    </root>
+	
+	<!--系统用户操作日志-->
+    <logger name="sys-user" level="error">
+        <appender-ref ref="sys-user"/>
+    </logger>
+</configuration> 

+ 20 - 0
aidex-admin/src/main/resources/mybatis/mybatis-config.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE configuration
+		PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
+		"http://mybatis.org/dtd/mybatis-3-config.dtd">
+<configuration>
+	<!-- 全局参数 -->
+	<settings>
+		<!-- 使全局的映射器启用或禁用缓存 -->
+		<setting name="cacheEnabled"             value="true"   />
+		<!-- 允许JDBC 支持自动生成主键 -->
+		<setting name="useGeneratedKeys"         value="true"   />
+		<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
+		<setting name="defaultExecutorType"      value="SIMPLE" />
+		<!-- 指定 MyBatis 所用日志的具体实现 -->
+		<setting name="logImpl"                  value="SLF4J"  />
+		<!-- 使用驼峰命名法转换字段 -->
+		<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
+	</settings>
+
+</configuration>

+ 16 - 0
aidex-admin/src/main/resources/rebel.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
+  Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
+-->
+<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
+
+	<id>aidex-admin</id>
+
+	<classpath>
+		<dir name="C:/cloud-platform/AiDex/aidex-admin/target/classes">
+		</dir>
+	</classpath>
+
+</application>

+ 1 - 0
aidex-admin/target/classes/META-INF/spring-devtools.properties

@@ -0,0 +1 @@
+restart.include.json=/com.alibaba.fastjson.*.jar

+ 57 - 0
aidex-admin/target/classes/application-druid.yml

@@ -0,0 +1,57 @@
+# 数据源配置
+spring:
+    datasource:
+        type: com.alibaba.druid.pool.DruidDataSource
+        driverClassName: com.mysql.cj.jdbc.Driver
+        druid:
+            # 主库数据源
+            master:
+                url: jdbc:mysql://localhost:3366/water_bus?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&&allowMultiQueries=true
+                username: root
+                password: root@!QAZ2020
+            # 从库数据源
+            slave:
+                # 从数据源开关/默认关闭
+                enabled: false
+                url:
+                username:
+                password:
+            # 初始连接数
+            initialSize: 5
+            # 最小连接池数量
+            minIdle: 10
+            # 最大连接池数量
+            maxActive: 20
+            # 配置获取连接等待超时的时间
+            maxWait: 60000
+            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+            timeBetweenEvictionRunsMillis: 60000
+            # 配置一个连接在池中最小生存的时间,单位是毫秒
+            minEvictableIdleTimeMillis: 300000
+            # 配置一个连接在池中最大生存的时间,单位是毫秒
+            maxEvictableIdleTimeMillis: 900000
+            # 配置检测连接是否有效
+            validationQuery: SELECT 1 FROM DUAL
+            testWhileIdle: true
+            testOnBorrow: false
+            testOnReturn: false
+            webStatFilter:
+                enabled: true
+            statViewServlet:
+                enabled: false
+                # 设置白名单,不填则允许所有访问
+                allow:
+                url-pattern: /druid/*
+                # 控制台管理用户名和密码
+                login-username: aidex
+                login-password: 123456
+            filter:
+                stat:
+                    enabled: true
+                    # 慢SQL记录
+                    log-slow-sql: true
+                    slow-sql-millis: 1000
+                    merge-sql: true
+                wall:
+                    config:
+                        multi-statement-allow: true

+ 137 - 0
aidex-admin/target/classes/application.yml

@@ -0,0 +1,137 @@
+# 项目相关配置
+aidex:
+  # 名称 水上公交
+  name: water_bus
+  # 版本
+  version: 3.3.0
+  # 版权年份
+  copyrightYear: 2024
+  # 实例演示开关
+  demoEnabled: true
+  # 文件路径 示例( Windows配置D:/aidex/uploadPath,Linux配置 /home/aidex/uploadPath)
+  profile: D:/aidex/uploadPath
+  # 获取ip地址开关
+  addressEnabled: false
+  # 验证码类型 math 数组计算 char 字符验证
+  captchaType: math
+
+# 开发环境配置
+server:
+  # 服务器的HTTP端口,默认为8080
+  port: 18080
+  servlet:
+    # 应用的访问路径
+    context-path: /
+  tomcat:
+    # tomcat的URI编码
+    uri-encoding: UTF-8
+    # 连接数满后的排队数,默认为100
+    accept-count: 1000
+    threads:
+      # tomcat最大线程数,默认为200
+      max: 800
+      # Tomcat启动初始化的线程数,默认值10
+      min-spare: 100
+
+# 日志配置
+logging:
+  level:
+    com.aidex: error
+    org.springframework: error
+
+# 用户配置
+user:
+  password:
+    # 密码最大错误次数
+    maxRetryCount: 5
+    # 密码锁定时间(默认10分钟)
+    lockTime: 10
+
+# Spring配置
+spring:
+  # 资源信息
+  messages:
+    # 国际化资源文件路径
+    basename: i18n/messages
+  profiles:
+    active: druid
+  # 文件上传
+  servlet:
+     multipart:
+       # 单个文件大小
+       max-file-size:  10MB
+       # 设置总上传的文件大小
+       max-request-size:  20MB
+  # 服务模块
+  devtools:
+    restart:
+      # 热部署开关
+      enabled: true
+  # redis 配置
+  redis:
+    # 地址
+    host: localhost
+    # 端口,默认为6379
+    port: 16379
+    # 数据库索引
+    database: 0
+    # 密码
+    password:
+    # 连接超时时间
+    timeout: 10s
+    lettuce:
+      pool:
+        # 连接池中的最小空闲连接
+        min-idle: 0
+        # 连接池中的最大空闲连接
+        max-idle: 8
+        # 连接池的最大数据库连接数
+        max-active: 8
+        # #连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-wait: -1ms
+
+# token配置
+token:
+    # 令牌自定义标识
+    header: Authorization
+    # 令牌密钥
+    secret: abcdefghijklmnopqrstuvwxyz
+    # 令牌有效期(默认30分钟)
+    expireTime: 30
+    # 是否允许账户多终端同时登录(true允许 false不允许)
+    soloLogin: true
+
+# MyBatis配置
+mybatis:
+    # 搜索指定包别名
+    typeAliasesPackage: com.aidex.**.domain,com.aidex.**.entity,com.aidex.**.po
+    # 配置mapper的扫描,找到所有的mapper.xml映射文件
+    mapperLocations: classpath*:mapper/**/*Mapper.xml,classpath*:com/aidex/**/mapper/*Mapper.xml
+    # 加载全局的配置文件
+    configLocation: classpath:mybatis/mybatis-config.xml
+    # 加载全局的配置文件
+    dbName: oracle
+    # 是否显示拦截器输出sql
+    isShowMyBatisSql: true
+
+# PageHelper分页插件
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Swagger配置
+swagger:
+  # 是否开启swagger
+  enabled: true
+  # 请求前缀
+  pathMapping: /dev-api
+
+# 防止XSS攻击
+xss:
+  # 过滤开关
+  enabled: true
+  # 排除链接(多个用逗号分隔)
+  excludes: /system/notice
+  # 匹配链接
+  urlPatterns: /system/*,/monitor/*,/tool/*

+ 27 - 0
aidex-admin/target/classes/banner.txt

@@ -0,0 +1,27 @@
+Application Version: 3.4.0
+Spring Boot Version: ${spring-boot.version}
+///////////////////////////////////////////////////////////////////////////////////////////
+//                                                                                       //
+//                                                                                       //
+//                                               |                                       //
+//                                              -+-                                      //
+//                                             ==| ___                                   //
+//                                   _____       | _T                                    //
+//                                    |   \      / \                                     //
+//                                  +-+----+-------------+               |               //
+//               _______.._______   |  O   O   O   O  __[]_              |               //
+//      ( )\________/     ==)__     |_________________|___|              |      ==|      //
+//       \__=*=_/0/_   --+q+ l_\    |                    |     _         #________|_     //
+//       ___________\____l_l_l__D___|  O            O  O |    ( )       /     O   /      //
+//      | [] uscgc yukon                                 |___/___\_____/        /        //
+//      |                               U.S. COAST GUARD / _  /  14           /          //
+//      \                                               / (0)/              /            //
+//        \____________________________________________/____/______________/             //
+//                                                                                       //
+//                 by Enrico Piazza                                                      //
+//                                                                                       //
+//                                                                                       //
+///////////////////////////////////////////////////////////////////////////////////////////
+
+
+

BIN
aidex-admin/target/classes/com/aidex/AiDexApplication.class


BIN
aidex-admin/target/classes/com/aidex/AiDexServletInitializer.class


+ 37 - 0
aidex-admin/target/classes/i18n/messages.properties

@@ -0,0 +1,37 @@
+#错误消息
+not.null=* 必须填写
+user.jcaptcha.error=验证码错误
+user.jcaptcha.expire=验证码已失效
+user.not.exists=用户不存在/密码错误
+user.password.not.match=用户不存在/密码错误
+user.password.retry.limit.count=密码输入错误{0}次
+user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定10分钟
+user.password.delete=对不起,您的账号已被删除
+user.blocked=用户已封禁,请联系管理员
+role.blocked=角色已封禁,请联系管理员
+user.logout.success=退出成功
+
+length.not.valid=长度必须在{min}到{max}个字符之间
+
+user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
+user.password.not.valid=* 5-50个字符
+
+user.email.not.valid=邮箱格式错误
+user.mobile.phone.number.not.valid=手机号格式错误
+user.login.success=登录成功
+user.register.success=注册成功
+user.notfound=请重新登录
+user.forcelogout=管理员强制退出,请重新登录
+user.unknown.error=未知错误,请重新登录
+
+##文件上传消息
+upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
+upload.filename.exceed.length=上传的文件名最长{0}个字符
+
+##权限
+no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
+no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
+no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
+no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
+no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
+no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]

+ 93 - 0
aidex-admin/target/classes/logback.xml

@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <!-- 日志存放路径 -->
+	<property name="log.path" value="/home/aidex/logs" />
+    <!-- 日志输出格式 -->
+	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
+
+	<!-- 控制台输出 -->
+	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+	
+	<!-- 系统日志输出 -->
+	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/sys-info.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+			<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>error</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+	</appender>
+	
+	<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/sys-error.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>ERROR</level>
+			<!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+			<!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+	
+	<!-- 用户访问日志输出  -->
+    <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>${log.path}/sys-user.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 按天回滚 daily -->
+            <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!-- 日志最大的历史 60天 -->
+            <maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+    </appender>
+	
+	<!-- 系统模块日志级别控制  -->
+	<logger name="com.aidex" level="error" />
+	<!-- Spring日志级别控制  -->
+	<logger name="org.springframework" level="error" />
+
+	<root level="error">
+		<appender-ref ref="console" />
+	</root>
+	
+	<!--系统操作日志-->
+    <root level="error">
+        <appender-ref ref="file_info" />
+        <appender-ref ref="file_error" />
+    </root>
+	
+	<!--系统用户操作日志-->
+    <logger name="sys-user" level="error">
+        <appender-ref ref="sys-user"/>
+    </logger>
+</configuration> 

+ 20 - 0
aidex-admin/target/classes/mybatis/mybatis-config.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE configuration
+		PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
+		"http://mybatis.org/dtd/mybatis-3-config.dtd">
+<configuration>
+	<!-- 全局参数 -->
+	<settings>
+		<!-- 使全局的映射器启用或禁用缓存 -->
+		<setting name="cacheEnabled"             value="true"   />
+		<!-- 允许JDBC 支持自动生成主键 -->
+		<setting name="useGeneratedKeys"         value="true"   />
+		<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
+		<setting name="defaultExecutorType"      value="SIMPLE" />
+		<!-- 指定 MyBatis 所用日志的具体实现 -->
+		<setting name="logImpl"                  value="SLF4J"  />
+		<!-- 使用驼峰命名法转换字段 -->
+		<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
+	</settings>
+
+</configuration>

+ 16 - 0
aidex-admin/target/classes/rebel.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
+  Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
+-->
+<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
+
+	<id>aidex-admin</id>
+
+	<classpath>
+		<dir name="C:/cloud-platform/AiDex/aidex-admin/target/classes">
+		</dir>
+	</classpath>
+
+</application>

+ 172 - 0
aidex-common/pom.xml

@@ -0,0 +1,172 @@
+<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>aidex</artifactId>
+        <groupId>com.aidex</groupId>
+        <version>3.4.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>aidex-common</artifactId>
+
+    <description>
+        common通用工具
+    </description>
+
+    <properties>
+        <!-- add 2021-01-28 -->
+        <lombok.version>1.18.16</lombok.version>
+        <org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
+    </properties>
+
+    <dependencies>
+
+        <!-- Spring框架基本的核心工具 -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context-support</artifactId>
+        </dependency>
+
+        <!-- SpringWeb模块 -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+        </dependency>
+
+        <!-- spring security 安全认证 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+
+        <!-- pagehelper 分页插件 -->
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+        </dependency>
+
+        <!-- 自定义验证注解 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+
+        <!--常用工具类 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+  
+        <!-- JSON工具类 -->
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+
+        <!-- 阿里JSON解析器 -->
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+        </dependency>
+
+        <!-- io常用工具类 -->
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+        <!-- 文件上传工具类 -->
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+        </dependency>
+
+        <!-- excel工具 -->
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+        </dependency>
+
+        <!-- yml解析器 -->
+        <dependency>
+            <groupId>org.yaml</groupId>
+            <artifactId>snakeyaml</artifactId>
+        </dependency>
+
+        <!-- Token生成与解析 -->
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+        </dependency>
+
+        <!-- Jaxb -->
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+        </dependency>
+
+        <!-- redis 缓存操作 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+        <!-- pool 对象池 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+
+        <!-- 解析客户端操作系统、浏览器等 -->
+        <dependency>
+            <groupId>eu.bitwalker</groupId>
+            <artifactId>UserAgentUtils</artifactId>
+        </dependency>
+
+        <!-- servlet包 -->
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+
+        <!--  引入lombok 2020-01-28  -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>${lombok.version}</version>
+        </dependency>
+
+        <!--  引入mapstruct 2020-01-28  -->
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct</artifactId>
+            <version>${org.mapstruct.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+            <version>${pinyin4j.version}</version>
+        </dependency>
+
+    </dependencies>
+<build>
+    <resources>
+        <resource>
+            <directory>src/main/java</directory>
+            <excludes>
+                <exclude>**/*.java</exclude>
+                <exclude>**/.svn/*</exclude>
+            </excludes>
+        </resource>
+        <resource>
+            <directory>src/main/resources</directory>
+            <includes>
+                <include>**/*.zzh</include>
+            </includes>
+        </resource>
+    </resources>
+</build>
+</project>

+ 15 - 0
aidex-common/src/main/java/com/aidex/common/annotation/Anonymous.java

@@ -0,0 +1,15 @@
+package com.aidex.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 匿名访问不鉴权注解
+ * 
+ * @author ruoyi
+ */
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Anonymous
+{
+}

+ 11 - 0
aidex-common/src/main/java/com/aidex/common/annotation/AnonymousAccess.java

@@ -0,0 +1,11 @@
+package com.aidex.common.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AnonymousAccess {
+}

+ 28 - 0
aidex-common/src/main/java/com/aidex/common/annotation/DataScope.java

@@ -0,0 +1,28 @@
+package com.aidex.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 数据权限过滤注解
+ * 
+ * @author ruoyi
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface DataScope
+{
+    /**
+     * 部门表的别名
+     */
+    public String deptAlias() default "";
+
+    /**
+     * 用户表的别名
+     */
+    public String userAlias() default "";
+}

+ 28 - 0
aidex-common/src/main/java/com/aidex/common/annotation/DataSource.java

@@ -0,0 +1,28 @@
+package com.aidex.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import com.aidex.common.enums.DataSourceType;
+
+/**
+ * 自定义多数据源切换注解
+ *
+ * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准
+ *
+ * @author ruoyi
+ */
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface DataSource
+{
+    /**
+     * 切换数据源名称
+     */
+    public DataSourceType value() default DataSourceType.MASTER;
+}

+ 188 - 0
aidex-common/src/main/java/com/aidex/common/annotation/Excel.java

@@ -0,0 +1,188 @@
+package com.aidex.common.annotation;
+
+import com.aidex.common.utils.poi.ExcelHandlerAdapter;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.IndexedColors;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.math.BigDecimal;
+
+/**
+ * 自定义导出Excel数据注解
+ *
+ * @author ruoyi
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Excel
+{
+    /**
+     * 导出时在excel中排序
+     */
+    public int sort() default Integer.MAX_VALUE;
+
+    /**
+     * 导出到Excel中的名字.
+     */
+    public String name() default "";
+
+    /**
+     * 日期格式, 如: yyyy-MM-dd
+     */
+    public String dateFormat() default "";
+
+    /**
+     * 如果是字典类型,请设置字典的type值 (如: sys_user_sex)
+     */
+    public String dictType() default "";
+
+    /**
+     * 读取内容转表达式 (如: 0=男,1=女,2=未知)
+     */
+    public String readConverterExp() default "";
+
+    /**
+     * 分隔符,读取字符串组内容
+     */
+    public String separator() default ",";
+
+    /**
+     * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
+     */
+    public int scale() default -1;
+
+    /**
+     * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
+     */
+    public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
+
+    /**
+     * 导出时在excel中每个列的高度 单位为字符
+     */
+    public double height() default 14;
+
+    /**
+     * 导出时在excel中每个列的宽 单位为字符
+     */
+    public double width() default 16;
+
+    /**
+     * 文字后缀,如% 90 变成90%
+     */
+    public String suffix() default "";
+
+    /**
+     * 当值为空时,字段的默认值
+     */
+    public String defaultValue() default "";
+
+    /**
+     * 提示信息
+     */
+    public String prompt() default "";
+
+    /**
+     * 设置只能选择不能输入的列内容.
+     */
+    public String[] combo() default {};
+
+    /**
+     * 是否需要纵向合并单元格,应对需求:含有list集合单元格)
+     */
+    public boolean needMerge() default false;
+
+    /**
+     * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
+     */
+    public boolean isExport() default true;
+
+    /**
+     * 另一个类中的属性名称,支持多级获取,以小数点隔开
+     */
+    public String targetAttr() default "";
+
+    /**
+     * 是否自动统计数据,在最后追加一行统计数据总和
+     */
+    public boolean isStatistics() default false;
+
+    /**
+     * 导出类型(0数字 1字符串 2图片)
+     */
+    public ColumnType cellType() default ColumnType.STRING;
+
+    /**
+     * 导出列头背景色
+     */
+    public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
+
+    /**
+     * 导出列头字体颜色
+     */
+    public IndexedColors headerColor() default IndexedColors.WHITE;
+
+    /**
+     * 导出单元格背景色
+     */
+    public IndexedColors backgroundColor() default IndexedColors.WHITE;
+
+    /**
+     * 导出单元格字体颜色
+     */
+    public IndexedColors color() default IndexedColors.BLACK;
+
+    /**
+     * 导出字段对齐方式
+     */
+    public HorizontalAlignment align() default HorizontalAlignment.CENTER;
+
+    /**
+     * 自定义数据处理器
+     */
+    public Class<?> handler() default ExcelHandlerAdapter.class;
+
+    /**
+     * 自定义数据处理器参数
+     */
+    public String[] args() default {};
+
+    /**
+     * 字段类型(0:导出导入;1:仅导出;2:仅导入)
+     */
+    Type type() default Type.ALL;
+
+    public enum Type
+    {
+        ALL(0), EXPORT(1), IMPORT(2);
+        private final int value;
+
+        Type(int value)
+        {
+            this.value = value;
+        }
+
+        public int value()
+        {
+            return this.value;
+        }
+    }
+
+    public enum ColumnType
+    {
+        NUMERIC(0), STRING(1), IMAGE(2);
+        private final int value;
+
+        ColumnType(int value)
+        {
+            this.value = value;
+        }
+
+        public int value()
+        {
+            return this.value;
+        }
+    }
+}

+ 18 - 0
aidex-common/src/main/java/com/aidex/common/annotation/Excels.java

@@ -0,0 +1,18 @@
+package com.aidex.common.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Excel注解集
+ *
+ * @author ruoyi
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Excels
+{
+    public Excel[] value();
+}

+ 46 - 0
aidex-common/src/main/java/com/aidex/common/annotation/Log.java

@@ -0,0 +1,46 @@
+package com.aidex.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import com.aidex.common.enums.BusinessType;
+import com.aidex.common.enums.OperatorType;
+
+/**
+ * 自定义操作日志记录注解
+ *
+ * @author ruoyi
+ *
+ */
+@Target({ ElementType.PARAMETER, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Log
+{
+    /**
+     * 模块 
+     */
+    public String title() default "";
+
+    /**
+     * 功能
+     */
+    public BusinessType businessType() default BusinessType.OTHER;
+
+    /**
+     * 操作人类别
+     */
+    public OperatorType operatorType() default OperatorType.MANAGE;
+
+    /**
+     * 是否保存请求的参数
+     */
+    public boolean isSaveRequestData() default true;
+
+    /**
+     * 是否保存响应的参数
+     */
+    public boolean isSaveResponseData() default true;
+}

+ 38 - 0
aidex-common/src/main/java/com/aidex/common/annotation/RateLimiter.java

@@ -0,0 +1,38 @@
+package com.aidex.common.annotation;
+
+import com.aidex.common.constant.CacheConstants;
+import com.aidex.common.constant.Constants;
+import com.aidex.common.enums.LimitType;
+
+import java.lang.annotation.*;
+
+/**
+ * 限流注解
+ * 
+ * @author ruoyi
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RateLimiter
+{
+    /**
+     * 限流key
+     */
+    public String key() default CacheConstants.RATE_LIMIT_KEY;
+
+    /**
+     * 限流时间,单位秒
+     */
+    public int time() default 60;
+
+    /**
+     * 限流次数
+     */
+    public int count() default 100;
+
+    /**
+     * 限流类型
+     */
+    public LimitType limitType() default LimitType.DEFAULT;
+}

+ 26 - 0
aidex-common/src/main/java/com/aidex/common/annotation/RepeatSubmit.java

@@ -0,0 +1,26 @@
+package com.aidex.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 自定义注解防止表单重复提交
+ *
+ * @author ruoyi
+ *
+ */
+@Inherited
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RepeatSubmit
+{
+    /**
+     * 间隔时间(ms),小于此时间视为重复提交
+     */
+    public int interval() default 5000;
+
+    /**
+     * 提示消息
+     */
+    public String message() default "不允许重复提交,请稍候再试";
+}

+ 155 - 0
aidex-common/src/main/java/com/aidex/common/config/AiDexConfig.java

@@ -0,0 +1,155 @@
+package com.aidex.common.config;
+
+import com.aidex.common.utils.DateUtils;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+
+/**
+ * 读取项目相关配置
+ * 
+ * @author aidex
+ */
+@Component
+@ConfigurationProperties(prefix = "aidex")
+public class AiDexConfig
+{
+
+    /**
+     * 文件存储后缀
+     */
+    private static String filePathSubfix = File.separator + DateUtils.getDate("yyyy") + File.separator + DateUtils.getDate("MM") + File.separator + DateUtils.getDate("dd");
+
+    /** 项目名称 */
+    private String name;
+
+    /** 版本 */
+    private String version;
+
+    /** 版权年份 */
+    private String copyrightYear;
+
+    /** 实例演示开关 */
+    private boolean demoEnabled;
+
+    /** 上传路径 */
+    private static String profile;
+
+    /** 上传路径 */
+    private static String dbName;
+
+    /** 获取地址开关 */
+    private static boolean addressEnabled;
+
+    /**
+     * 验证码类型
+     */
+    private String captchaType;
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    public String getVersion()
+    {
+        return version;
+    }
+
+    public void setVersion(String version)
+    {
+        this.version = version;
+    }
+
+    public String getCopyrightYear()
+    {
+        return copyrightYear;
+    }
+
+    public void setCopyrightYear(String copyrightYear)
+    {
+        this.copyrightYear = copyrightYear;
+    }
+
+    public boolean isDemoEnabled()
+    {
+        return demoEnabled;
+    }
+
+    public void setDemoEnabled(boolean demoEnabled)
+    {
+        this.demoEnabled = demoEnabled;
+    }
+
+    public static String getProfile()
+    {
+        return profile;
+    }
+
+    public void setProfile(String profile)
+    {
+        AiDexConfig.profile = profile;
+    }
+
+    public static boolean isAddressEnabled()
+    {
+        return addressEnabled;
+    }
+
+    public void setAddressEnabled(boolean addressEnabled)
+    {
+        AiDexConfig.addressEnabled = addressEnabled;
+    }
+
+    /**
+     /**
+     * 获取导入上传路径
+     */
+    public static String getImportPath() {
+        return getProfile() + "/import" + filePathSubfix;
+    }
+
+    /**
+     * 获取头像上传路径
+     */
+    public static String getAvatarPath() {
+        return getProfile() + File.separator + "avatar" + filePathSubfix;
+    }
+
+    /**
+     * 获取下载路径
+     */
+    public static String getDownloadPath() {
+        return getProfile() + File.separator + "download" + filePathSubfix;
+    }
+
+    /**
+     * 获取上传路径
+     */
+    public static String getUploadPath() {
+        //根据年月日分组
+        return getProfile() + File.separator + "upload" + filePathSubfix;
+    }
+
+    public static String getDbName() {
+        return dbName;
+    }
+
+    public static void setDbName(String dbName) {
+        AiDexConfig.dbName = dbName;
+    }
+
+    public String getCaptchaType() {
+        return captchaType;
+    }
+
+    public void setCaptchaType(String captchaType) {
+        this.captchaType = captchaType;
+    }
+}

+ 74 - 0
aidex-common/src/main/java/com/aidex/common/constant/CacheConstants.java

@@ -0,0 +1,74 @@
+package com.aidex.common.constant;
+
+/**
+ * 缓存的key 常量
+ * 
+ * @author ruoyi
+ */
+public class CacheConstants
+{
+    /**
+     * 登录用户 redis key
+     */
+    public static final String LOGIN_TOKEN_KEY = "login_tokens:";
+
+    /**
+     * 验证码 redis key
+     */
+    public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
+
+    /**
+     * 参数管理 cache key
+     */
+    public static final String SYS_CONFIG_KEY = "sys_config:";
+
+    /**
+     * 字典管理 cache key
+     */
+    public static final String SYS_DICT_KEY = "sys_dict:";
+
+    /**
+     * 防重提交 redis key
+     */
+    public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";
+
+    /**
+     * 限流 redis key
+     */
+    public static final String RATE_LIMIT_KEY = "rate_limit:";
+
+    /**
+     * 登录账户密码错误次数 redis key
+     */
+    public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
+
+    /**
+     * 用户管理 cache key
+     */
+    public static final String SYS_USER_KEY = "sys_user:";
+
+    /**
+     * 用户管理 cache key
+     */
+    public static final String SYS_USER_UN_KEY = "sys_user_un:";
+
+    /**
+     * 部门管理 cache key
+     */
+    public static final String SYS_DEPT_KEY = "sys_dept:";
+
+    /**
+     * 列配置 cache key
+     */
+    public static final String SYS_TABLE_CONFIG_KEY = "sys_table_config:";
+
+    /**
+     * 部门管理 cache key
+     */
+    public static final String SYS_DEPT_DC_KEY = "sys_dept_dc:";
+
+    /**
+     * 角色管理 cache key
+     */
+    public static final String SYS_ROLE_KEY = "sys_role:";
+}

+ 187 - 0
aidex-common/src/main/java/com/aidex/common/constant/Constants.java

@@ -0,0 +1,187 @@
+package com.aidex.common.constant;
+
+import io.jsonwebtoken.Claims;
+
+/**
+ * 通用常量信息
+ *
+ * @author ruoyi
+ */
+public class Constants {
+    /**
+     * UTF-8 字符集
+     */
+    public static final String UTF8 = "UTF-8";
+
+    /**
+     * GBK 字符集
+     */
+    public static final String GBK = "GBK";
+
+    /**
+     * http请求
+     */
+    public static final String HTTP = "http://";
+
+    /**
+     * https请求
+     */
+    public static final String HTTPS = "https://";
+
+    /**
+     * 通用成功标识
+     */
+    public static final String SUCCESS = "0";
+
+    /**
+     * 通用失败标识
+     */
+    public static final String FAIL = "1";
+
+    /**
+     * 登录成功
+     */
+    public static final String LOGIN_SUCCESS = "Success";
+
+    /**
+     * 注销
+     */
+    public static final String LOGOUT = "Logout";
+
+    /**
+     * 注册
+     */
+    public static final String REGISTER = "Register";
+
+    /**
+     * 登录失败
+     */
+    public static final String LOGIN_FAIL = "Error";
+
+    /**
+     * 验证码有效期(分钟)
+     */
+    public static final Integer CAPTCHA_EXPIRATION = 2;
+
+    /**
+     * 令牌
+     */
+    public static final String TOKEN = "token";
+
+    /**
+     * 令牌前缀
+     */
+    public static final String TOKEN_PREFIX = "Bearer ";
+
+    /**
+     * 令牌前缀
+     */
+    public static final String LOGIN_USER_KEY = "login_user_key";
+
+    /**
+     * 用户ID
+     */
+    public static final String JWT_USERID = "userid";
+
+    /**
+     * 用户名称
+     */
+    public static final String JWT_USERNAME = Claims.SUBJECT;
+
+    /**
+     * 用户头像
+     */
+    public static final String JWT_AVATAR = "avatar";
+
+    /**
+     * 创建时间
+     */
+    public static final String JWT_CREATED = "created";
+
+    /**
+     * 用户权限
+     */
+    public static final String JWT_AUTHORITIES = "authorities";
+
+
+    /**
+     * RMI 远程方法调用
+     */
+    public static final String LOOKUP_RMI = "rmi:";
+
+    /**
+     * LDAP 远程方法调用
+     */
+    public static final String LOOKUP_LDAP = "ldap:";
+
+    /**
+     * LDAPS 远程方法调用
+     */
+    public static final String LOOKUP_LDAPS = "ldaps:";
+
+    /**
+     * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
+     */
+    public static final String[] JOB_WHITELIST_STR = { "com.aidex" };
+
+    /**
+     * 定时任务违规的字符
+     */
+    public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
+            "org.springframework", "org.apache", "com.aidex.common.utils.file" };
+
+    /**
+     * 资源映射路径 前缀
+     */
+    public static final String RESOURCE_PREFIX = "/profile";
+
+    /**
+     * 默认为空消息
+     */
+    public static final String DEFAULT_NULL_MESSAGE = "暂无数据";
+    /**
+     * 默认成功消息
+     */
+    public static final String DEFAULT_SUCCESS_MESSAGE = "操作成功";
+    /**
+     * 默认失败消息
+     */
+    public static final String DEFAULT_FAILURE_MESSAGE = "操作失败";
+
+    /**
+     * 树的ID串分隔符
+     */
+    public static final String TREE_ROOT = "0";
+
+    /**
+     * 树的ID串分隔符
+     */
+    public static final String TREE_IDS_SPLIT_CHART = "/";
+
+    /**
+     * 树的ID串分隔符
+     */
+    public static final String TREE_LEAF_Y = "y";
+
+    /**
+     * 树的ID串分隔符
+     */
+    public static final String TREE_LEAF_N = "n";
+
+    /**
+     * 日志操作类型
+     */
+    public enum OpType {
+        login, insert, delete, update, select, logout
+    }
+
+    /**
+     * 登录用户编号 redis key
+     */
+    public static final String LOGIN_USERID_KEY = "login_userid:";
+
+    /**
+     * 注册
+     */
+    public static final String ATTACH_SAVE_TYPE_DISK = "Disk";
+}

+ 287 - 0
aidex-common/src/main/java/com/aidex/common/constant/GenConstants.java

@@ -0,0 +1,287 @@
+package com.aidex.common.constant;
+
+/**
+ * 代码生成通用常量
+ *
+ * @author ruoyi
+ */
+public class GenConstants {
+    /**
+     * 单表(增删改查)
+     */
+    public static final String TPL_CRUD = "crud";
+
+    /**
+     * 单表行编辑(增删改查)
+     */
+    public static final String TPL_CRUD_ROW_EDIT = "crudrowedit";
+
+    /**
+     * 树表(增删改查)
+     */
+    public static final String TPL_TREE = "tree";
+
+    /**
+     * 主子表左右布局(增删改查)
+     */
+    public static final String TPL_SUB = "sub";
+
+
+    /**
+     * 主子表嵌套(增删改查)
+     */
+    public static final String TPL_SUB_NESTED = "subnested";
+
+    /**
+     * 树(增删改查)
+     */
+    public static final String TPL_TREEGRID = "treegrid";
+
+    /**
+     * 树编码字段
+     */
+    public static final String TREE_CODE = "treeCode";
+
+    /**
+     * 树父编码字段
+     */
+    public static final String TREE_PARENT_CODE = "treeParentCode";
+
+    /**
+     * 树名称字段
+     */
+    public static final String TREE_NAME = "treeName";
+
+    /**
+     * 上级菜单ID字段
+     */
+    public static final String PARENT_MENU_ID = "parentMenuId";
+
+    /**
+     * 上级菜单名称字段
+     */
+    public static final String PARENT_MENU_NAME = "parentMenuName";
+
+    /**
+     * 是否可上传附件配置(1:是;2:否)
+     */
+    public static final String ATTACH_OPTION = "attachOption";
+
+    /**
+     * 是否可上传附件配置(1:是;2:否)
+     */
+    public static final String DISABLE_ENABLE_OPTION = "disableEnableOption";
+
+    /**
+     * 是否保存并继续添加
+     */
+    public static final String SAVE_AND_ADD_OPTION = "saveAndAddOption";
+
+    /**
+     * 是否有复制功能
+     */
+    public static final String COPY_RECORD_OPTION = "copyRecordOption";
+
+    /**
+     * 默认上级菜单,系统工具
+     */
+    public static final String DEFAULT_PARENT_MENU_ID = "3";
+
+    /**
+     * 菜单ICON
+     */
+    public static final String MENU_ICON = "menuIcon";
+
+    /**
+     * 数据库字符串类型
+     */
+    public static final String[] COLUMNTYPE_STR = {"char", "varchar", "nvarchar", "varchar2"};
+
+    /**
+     * 数据库文本类型
+     */
+    public static final String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext"};
+
+    /**
+     * 数据库时间类型
+     */
+    public static final String[] COLUMNTYPE_TIME = {"datetime", "time", "date", "timestamp"};
+
+    /**
+     * 数据库数字类型
+     */
+    public static final String[] COLUMNTYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer",
+            "bit", "bigint", "float", "double", "decimal"};
+
+    /**
+     * 页面不需要编辑字段
+     */
+    public static final String[] COLUMNNAME_NOT_EDIT = {"id", "create_by", "create_dept", "create_time", "update_by", "update_time", "update_ip", "remark", "version", "del_flag"};
+
+    /**
+     * 表中必须包含的常用字段
+     */
+    public static final String[] COLUMNNAME_REQUIRE_COLUMN = {"remark", "id", "create_by", "create_dept", "create_time", "update_by", "update_time", "update_ip", "version", "del_flag"};
+
+    /**
+     * 页面常用字段
+     */
+    public static final String[] COLUMNNAME_COMMON_COLUMN = {"tree_sort", "sort", "status", "remark", "id", "parent_id", "parent_ids", "tree_sorts", "tree_level", "tree_leaf", "create_by", "create_dept", "create_time", "update_by", "update_time", "update_ip", "version", "del_flag"};
+
+    /**
+     * 页面不需要显示的列表字段
+     */
+    public static final String[] COLUMNNAME_NOT_LIST = {"parent_id", "parent_ids", "tree_sorts", "tree_level", "tree_leaf", "id", "create_by", "create_dept", "create_time", "update_by", "update_time", "update_ip", "remark", "version", "del_flag"};
+
+    /**
+     * 页面不需要查询字段
+     */
+    public static final String[] COLUMNNAME_NOT_QUERY = {"parentId", "parentIds", "treeSort", "treeSorts", "treeLevel", "treeLeaf", "id", "create_by", "create_time", "del_flag", "update_by", "update_time", "remark"};
+
+    /**
+     * Entity基类字段
+     */
+    public static final String[] BASE_ENTITY = {"id", "createBy", "createDept", "createTime", "updateBy", "updateTime", "updateIp", "remark", "version", "delFlag"};
+
+    /**
+     * Tree基类字段
+     */
+    public static final String[] TREE_ENTITY = {"parentId", "parentIds", "treeSort", "treeSorts", "treeLevel", "treeLeaf", "children"};
+
+    /**
+     * 文本框
+     */
+    public static final String HTML_INPUT = "input";
+
+    /**
+     * 数字框
+     */
+    public static final String HTML_NUMBER = "number";
+
+    /**
+     * 文本域
+     */
+    public static final String HTML_TEXTAREA = "textarea";
+
+    /**
+     * 下拉框
+     */
+    public static final String HTML_SELECT = "select";
+
+    /**
+     * 下拉框
+     */
+    public static final String HTML_SELECT_MULTIPLE = "selectMultiple";
+
+    /**
+     * 开关
+     */
+    public static final String HTML_SWITCH = "switch";
+
+    /**
+     * 单选框
+     */
+    public static final String HTML_RADIO = "radio";
+
+
+    /**
+     * 单选框
+     */
+    public static final String HTML_RADIO_BUTTON = "radioButton";
+
+    /**
+     * 复选框
+     */
+    public static final String HTML_CHECKBOX = "checkbox";
+
+
+    /**
+     * 日期控件
+     */
+    public static final String HTML_DATETIME = "datetime";
+
+    /**
+     * 时间戳控件
+     */
+    public static final String HTML_DATE = "date";
+
+    /**
+     * 图片上传控件
+     */
+    public static final String HTML_IMAGE_UPLOAD = "imageUpload";
+
+    /**
+     * 文件上传控件
+     */
+    public static final String HTML_FILE_UPLOAD = "fileUpload";
+
+    /**
+     * 富文本控件
+     */
+    public static final String HTML_EDITOR = "editor";
+
+    /**
+     * 字符串类型
+     */
+    public static final String TYPE_STRING = "String";
+
+    /**
+     * 整型
+     */
+    public static final String TYPE_INTEGER = "Integer";
+
+    /**
+     * 长整型
+     */
+    public static final String TYPE_LONG = "Long";
+
+    /**
+     * 浮点型
+     */
+    public static final String TYPE_DOUBLE = "Double";
+
+    /**
+     * 高精度计算类型
+     */
+    public static final String TYPE_BIGDECIMAL = "BigDecimal";
+
+    /**
+     * 时间类型
+     */
+    public static final String TYPE_DATE = "Date";
+
+    /**
+     * 模糊查询
+     */
+    public static final String QUERY_LIKE = "LIKE";
+
+    /**
+     * 精确查询
+     */
+    public static final String QUERY_EQ = "EQ";
+
+    /**
+     * 区间查询
+     */
+    public static final String QUERY_BETWEEN = "BETWEEN";
+
+    /**
+     * 需要
+     */
+    public static final String REQUIRE = "1";
+
+    /**
+     * 居中
+     */
+    public static final String ALIGH_CENTER = "center";
+
+    /**
+     * 居右
+     */
+    public static final String ALIGH_RIGHT = "right";
+
+    /**
+     * 居左
+     */
+    public static final String ALIGH_LEFT = "left";
+}

+ 99 - 0
aidex-common/src/main/java/com/aidex/common/constant/HttpStatus.java

@@ -0,0 +1,99 @@
+package com.aidex.common.constant;
+
+/**
+ * 返回状态码
+ * 
+ * @author ruoyi
+ */
+public class HttpStatus
+{
+    /**
+     * 操作成功
+     */
+    public static final int SUCCESS = 200;
+
+    /**
+     * 对象创建成功
+     */
+    public static final int CREATED = 201;
+
+    /**
+     * 请求已经被接受
+     */
+    public static final int ACCEPTED = 202;
+
+    /**
+     * 操作已经执行成功,但是没有返回数据
+     */
+    public static final int NO_CONTENT = 204;
+
+    /**
+     * 资源已被移除
+     */
+    public static final int MOVED_PERM = 301;
+
+    /**
+     * 重定向
+     */
+    public static final int SEE_OTHER = 303;
+
+    /**
+     * 资源没有被修改
+     */
+    public static final int NOT_MODIFIED = 304;
+
+    /**
+     * 参数列表错误(缺少,格式不匹配)
+     */
+    public static final int BAD_REQUEST = 400;
+
+    /**
+     * 未授权
+     */
+    public static final int UNAUTHORIZED = 401;
+
+    /**
+     * 访问受限,授权过期
+     */
+    public static final int FORBIDDEN = 403;
+
+    /**
+     * 资源,服务未找到
+     */
+    public static final int NOT_FOUND = 404;
+
+    /**
+     * 不允许的http方法
+     */
+    public static final int BAD_METHOD = 405;
+
+    /**
+     * 资源冲突,或者资源被锁
+     */
+    public static final int CONFLICT = 409;
+
+    /**
+     * 不支持的数据,媒体类型
+     */
+    public static final int UNSUPPORTED_TYPE = 415;
+
+    /**
+     * 系统内部错误
+     */
+    public static final int ERROR = 500;
+
+    /**
+     * 接口未实现
+     */
+    public static final int NOT_IMPLEMENTED = 501;
+
+    /**
+     * 系统警告消息
+     */
+    public static final int WARN = 601;
+
+    /**
+     * 失败标记
+     */
+    public static final Integer FAIL = 500;
+}

+ 50 - 0
aidex-common/src/main/java/com/aidex/common/constant/ScheduleConstants.java

@@ -0,0 +1,50 @@
+package com.aidex.common.constant;
+
+/**
+ * 任务调度通用常量
+ * 
+ * @author ruoyi
+ */
+public class ScheduleConstants
+{
+    public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
+
+    /** 执行目标key */
+    public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
+
+    /** 默认 */
+    public static final String MISFIRE_DEFAULT = "0";
+
+    /** 立即触发执行 */
+    public static final String MISFIRE_IGNORE_MISFIRES = "1";
+
+    /** 触发一次执行 */
+    public static final String MISFIRE_FIRE_AND_PROCEED = "2";
+
+    /** 不触发立即执行 */
+    public static final String MISFIRE_DO_NOTHING = "3";
+
+    public enum Status
+    {
+        /**
+         * 正常
+         */
+        NORMAL("0"),
+        /**
+         * 暂停
+         */
+        PAUSE("1");
+
+        private String value;
+
+        private Status(String value)
+        {
+            this.value = value;
+        }
+
+        public String getValue()
+        {
+            return value;
+        }
+    }
+}

+ 108 - 0
aidex-common/src/main/java/com/aidex/common/constant/UserConstants.java

@@ -0,0 +1,108 @@
+package com.aidex.common.constant;
+
+/**
+ * 用户常量信息
+ *
+ * @author ruoyi
+ */
+public class UserConstants {
+
+    /**
+     * 平台内系统用户的唯一标志
+     */
+    public static final String SYS_USER = "SYS_USER";
+
+    /**
+     * 正常状态
+     */
+    public static final String NORMAL = "0";
+
+    /**
+     * 异常状态
+     */
+    public static final String EXCEPTION = "1";
+
+    /**
+     * 用户封禁状态
+     */
+    public static final String USER_DISABLE = "1";
+
+    /**
+     * 角色封禁状态
+     */
+    public static final String ROLE_DISABLE = "1";
+
+    /**
+     * 部门正常状态
+     */
+    public static final String DEPT_NORMAL = "0";
+
+    /**
+     * 部门停用状态
+     */
+    public static final String DEPT_DISABLE = "1";
+
+    /**
+     * 字典正常状态
+     */
+    public static final String DICT_NORMAL = "0";
+
+    /**
+     * 是否为系统默认(是)
+     */
+    public static final String YES = "Y";
+
+    /**
+     * 是否菜单外链(是)
+     */
+    public static final String YES_FRAME = "0";
+
+    /**
+     * 是否菜单外链(否)
+     */
+    public static final String NO_FRAME = "1";
+
+    /**
+     * 菜单类型(目录)
+     */
+    public static final String TYPE_DIR = "M";
+
+    /**
+     * 菜单类型(菜单)
+     */
+    public static final String TYPE_MENU = "C";
+
+    /**
+     * 菜单类型(按钮)
+     */
+    public static final String TYPE_BUTTON = "F";
+
+    /**
+     * Layout组件标识
+     */
+    public final static String LAYOUT = "Layout";
+
+    /**
+     * ParentView组件标识
+     */
+    public final static String PARENT_VIEW = "ParentView";
+
+    /**
+     * 校验返回结果码
+     */
+    public final static String UNIQUE = "0";
+    public final static String NOT_UNIQUE = "1";
+
+
+    /**
+     * 用户名长度限制
+     */
+    public static final int USERNAME_MIN_LENGTH = 2;
+    public static final int USERNAME_MAX_LENGTH = 20;
+
+    /**
+     * 密码长度限制
+     */
+    public static final int PASSWORD_MIN_LENGTH = 5;
+    public static final int PASSWORD_MAX_LENGTH = 20;
+}

+ 10 - 0
aidex-common/src/main/java/com/aidex/common/core/annotation/ConfigurationCore.java

@@ -0,0 +1,10 @@
+package com.aidex.common.core.annotation;
+
+import java.lang.annotation.*;
+
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface ConfigurationCore {
+}

+ 213 - 0
aidex-common/src/main/java/com/aidex/common/core/controller/BaseController.java

@@ -0,0 +1,213 @@
+package com.aidex.common.core.controller;
+
+import com.aidex.common.constant.HttpStatus;
+import com.aidex.common.core.domain.AjaxResult;
+import com.aidex.common.core.domain.model.LoginUser;
+import com.aidex.common.core.page.PageDomain;
+import com.aidex.common.core.page.TableDataInfo;
+import com.aidex.common.core.page.TableSupport;
+import com.aidex.common.exception.DemoModeException;
+import com.aidex.common.utils.*;
+import com.aidex.common.utils.sql.SqlUtil;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.ModelAttribute;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.beans.PropertyEditorSupport;
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * web层通用数据处理
+ *
+ * @author ruoyi
+ */
+public class BaseController {
+    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @ModelAttribute
+    public void init(HttpServletRequest httpServletRequest, HttpServletResponse response) throws IOException
+    {
+        String url = ServletUtils.getRequest().getRequestURI();
+
+        // 增删改 请求
+        if ("DELETE".equals(httpServletRequest.getMethod()) || "POST".equals(httpServletRequest.getMethod())
+                || "PUT".equals(httpServletRequest.getMethod()))
+        {
+            //throw new DemoModeException();
+        }
+    }
+
+    /**
+     * 将前台传递过来的日期格式的字符串,自动转化为Date类型
+     */
+    @InitBinder
+    public void initBinder(WebDataBinder binder) {
+        // Date 类型转换
+        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
+            @Override
+            public void setAsText(String text) {
+                setValue(DateUtils.parseDate(text));
+            }
+        });
+    }
+
+    /**
+     * 设置请求分页数据
+     */
+    protected void startPage() {
+        PageUtils.startPage();
+    }
+
+    /**
+     * 清理分页的线程变量
+     */
+    protected void clearPage()
+    {
+        PageUtils.clearPage();
+    }
+
+    /**
+     * 设置请求排序数据
+     */
+    protected void startOrderBy() {
+        PageDomain pageDomain = TableSupport.buildPageRequest();
+        if (StringUtils.isNotEmpty(pageDomain.getOrderBy())) {
+            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
+            PageHelper.orderBy(orderBy);
+        }
+    }
+
+    /**
+     * 响应请求分页数据
+     */
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    protected TableDataInfo getDataTable(List<?> list) {
+        TableDataInfo rspData = new TableDataInfo();
+        rspData.setCode(HttpStatus.SUCCESS);
+        rspData.setMsg("查询成功");
+        rspData.setRows(list);
+        rspData.setTotal(new PageInfo(list).getTotal());
+        return rspData;
+    }
+
+
+    /**
+     * 响应请求分页数据
+     */
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    protected TableDataInfo getDataTable(PageInfo<?> list) {
+        TableDataInfo rspData = new TableDataInfo();
+        rspData.setCode(HttpStatus.SUCCESS);
+        rspData.setMsg("查询成功");
+        rspData.setRows(list.getList());
+        rspData.setTotal(list.getTotal());
+        return rspData;
+    }
+
+    /**
+     * 响应返回结果
+     *
+     * @return 操作结果
+     */
+    protected AjaxResult toAjax(boolean flag) {
+        return flag ? AjaxResult.success() : AjaxResult.error();
+    }
+
+    /**
+     * 响应返回结果
+     *
+     * @param rows 影响行数
+     * @return 操作结果
+     */
+    protected AjaxResult toAjax(int rows) {
+        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
+    }
+
+    /**
+     * 页面跳转
+     */
+    public String redirect(String url) {
+        return StringUtils.format("redirect:{}", url);
+    }
+
+    /**
+     * 返回成功
+     */
+    public AjaxResult success() {
+        return AjaxResult.success();
+    }
+
+    /**
+     * 返回失败消息
+     */
+    public AjaxResult error() {
+        return AjaxResult.error();
+    }
+
+    /**
+     * 返回警告消息
+     */
+    public AjaxResult warn(String message)
+    {
+        return AjaxResult.warn(message);
+    }
+
+    /**
+     * 返回成功消息
+     */
+    public AjaxResult success(String message) {
+        return AjaxResult.success(message);
+    }
+
+    /**
+     * 返回成功消息
+     */
+    public AjaxResult success(Object data)
+    {
+        return AjaxResult.success(data);
+    }
+
+    /**
+     * 返回失败消息
+     */
+    public AjaxResult error(String message) {
+        return AjaxResult.error(message);
+    }
+
+    /**
+     * 获取用户缓存信息
+     */
+    public LoginUser getLoginUser() {
+        return SecurityUtils.getLoginUser();
+    }
+
+    /**
+     * 获取登录用户id
+     */
+    public String getUserId() {
+        return getLoginUser().getUserId();
+    }
+
+    /**
+     * 获取登录部门id
+     */
+    public String getDeptId() {
+        return getLoginUser().getDeptId();
+    }
+
+    /**
+     * 获取登录用户名
+     */
+    public String getUsername() {
+        return getLoginUser().getUsername();
+    }
+
+}

+ 195 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/AjaxResult.java

@@ -0,0 +1,195 @@
+package com.aidex.common.core.domain;
+
+import java.util.HashMap;
+
+import com.aidex.common.constant.HttpStatus;
+import com.aidex.common.utils.StringUtils;
+
+/**
+ * 操作消息提醒
+ *
+ * @author ruoyi
+ */
+public class AjaxResult extends HashMap<String, Object> {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 状态码
+     */
+    public static final String CODE_TAG = "code";
+
+    /**
+     * 返回内容
+     */
+    public static final String MSG_TAG = "msg";
+
+    /**
+     * 数据对象
+     */
+    public static final String DATA_TAG = "data";
+
+    /**
+     * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
+     */
+    public AjaxResult() {
+    }
+
+    /**
+     * 初始化一个新创建的 AjaxResult 对象
+     *
+     * @param code 状态码
+     * @param msg  返回内容
+     */
+    public AjaxResult(int code, String msg) {
+        super.put(CODE_TAG, code);
+        super.put(MSG_TAG, msg);
+    }
+
+    /**
+     * 初始化一个新创建的 AjaxResult 对象
+     *
+     * @param code 状态码
+     * @param msg  返回内容
+     * @param data 数据对象
+     */
+    public AjaxResult(int code, String msg, Object data) {
+        super.put(CODE_TAG, code);
+        super.put(MSG_TAG, msg);
+        if (StringUtils.isNotNull(data)) {
+            super.put(DATA_TAG, data);
+        }
+    }
+
+    /**
+     * 初始化一个新创建的 AjaxResult 对象
+     *
+     * @param code 状态码
+     * @param msg  返回内容
+     * @param data 数据对象
+     */
+    public AjaxResult(String code, String msg, Object data) {
+        super.put(CODE_TAG, code);
+        super.put(MSG_TAG, msg);
+        if (StringUtils.isNotNull(data)) {
+            super.put(DATA_TAG, data);
+        }
+    }
+
+    /**
+     * 返回成功消息
+     *
+     * @return 成功消息
+     */
+    public static AjaxResult success() {
+        return AjaxResult.success("操作成功");
+    }
+
+    /**
+     * 返回成功数据
+     *
+     * @return 成功消息
+     */
+    public static AjaxResult success(Object data) {
+        return AjaxResult.success("操作成功", data);
+    }
+
+    /**
+     * 返回成功消息
+     *
+     * @param msg 返回内容
+     * @return 成功消息
+     */
+    public static AjaxResult success(String msg) {
+        return AjaxResult.success(msg, null);
+    }
+
+    /**
+     * 返回成功消息
+     *
+     * @param msg  返回内容
+     * @param data 数据对象
+     * @return 成功消息
+     */
+    public static AjaxResult success(String msg, Object data) {
+        return new AjaxResult(HttpStatus.SUCCESS, msg, data);
+    }
+
+    /**
+     * 返回警告消息
+     *
+     * @param msg 返回内容
+     * @return 警告消息
+     */
+    public static AjaxResult warn(String msg)
+    {
+        return AjaxResult.warn(msg, null);
+    }
+
+    /**
+     * 返回警告消息
+     *
+     * @param msg 返回内容
+     * @param data 数据对象
+     * @return 警告消息
+     */
+    public static AjaxResult warn(String msg, Object data)
+    {
+        return new AjaxResult(HttpStatus.WARN, msg, data);
+    }
+
+
+    /**
+     * 返回错误消息
+     *
+     * @return 错误消息
+     */
+    public static AjaxResult error() {
+        return AjaxResult.error("操作失败");
+    }
+
+    /**
+     * 返回错误消息
+     *
+     * @param msg 返回内容
+     * @return 错误消息
+     */
+    public static AjaxResult error(String msg) {
+        return AjaxResult.error(msg, null);
+    }
+
+    /**
+     * 返回错误消息
+     *
+     * @param msg  返回内容
+     * @param data 数据对象
+     * @return 错误消息
+     */
+    public static AjaxResult error(String msg, Object data) {
+        return new AjaxResult(HttpStatus.ERROR, msg, data);
+    }
+
+    /**
+     * 返回错误消息
+     *
+     * @param code 状态码
+     * @param msg  返回内容
+     * @return 错误消息
+     */
+    public static AjaxResult error(int code, String msg) {
+        return new AjaxResult(code, msg, null);
+    }
+
+    /**
+     * 方便链式调用
+     *
+     * @param key 键
+     * @param value 值
+     * @return 数据对象
+     */
+    @Override
+    public AjaxResult put(String key, Object value)
+    {
+        super.put(key, value);
+        return this;
+    }
+}

+ 260 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/BaseEntity.java

@@ -0,0 +1,260 @@
+package com.aidex.common.core.domain;
+
+import com.aidex.common.annotation.Excel;
+import com.aidex.common.core.domain.model.LoginUser;
+import com.aidex.common.core.page.PageDomain;
+import com.aidex.common.utils.SecurityUtils;
+import com.aidex.common.utils.StringUtils;
+import com.aidex.common.utils.spring.SpringUtils;
+import com.aidex.common.utils.uuid.IdUtils;
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.Data;
+import org.springframework.core.env.Environment;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Entity基类
+ *
+ * @author ruoyi
+ */
+@Data
+public class BaseEntity<T> implements Serializable {
+    /**
+     * 删除标记(0:正常;1:删除;)
+     */
+    public static final String DEL_FLAG_NORMAL = "0";
+    public static final String DEL_FLAG_DELETE = "1";
+    public static final String STATUS_NORMAL = "0";
+    public static final String STATUS_DISABLE = "1";
+    public static final String STATUS_DELETE = "2";
+    public static final String STATUS_FREEZE = "3";
+    public static final String STATUS_AUDIT = "4";
+    public static final String STATUS_AUDIT_BACK = "5";
+    public static final String STATUS_DRAFT = "9";
+
+    //写入日志时记录变更前对象,变更后对象,日志类型(添加,编辑,删除)
+    public static final String LOG_OLD_DATA = "LOG_OLD_DATA";
+    public static final String LOG_NEW_DATA = "LOG_NEW_DATA";
+    public static final String LOG_TYPE = "LOG_TYPE";
+
+    protected String createByName;
+    protected String createDeptName;
+
+    /**
+     * 记录导入时错误数据
+     */
+    @Excel(name = "错误信息",width=100)
+    private String importErrInfo;
+
+    private static final Environment EVN;
+
+    static {
+        EVN = SpringUtils.getBean(Environment.class);
+    }
+
+    public BaseEntity() {
+        super();
+        this.delFlag = DEL_FLAG_NORMAL;
+    }
+
+    public BaseEntity(String id) {
+        this();
+        this.id = id;
+    }
+
+    /**
+     * 获取数据库名称
+     */
+    @JsonIgnore
+    @JSONField(serialize = false)
+    public String getDbName(){
+        return EVN.getProperty("mybatis.dbName");
+    }
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonIgnore
+    @JSONField(serialize = false)
+    protected boolean isNewRecord = false;
+
+    /**
+     * 是否是新记录(默认:false),调用setIsNewRecord()设置新记录,使用自定义ID。
+     * 设置为true后强制执行插入语句,ID不会自动生成,需从手动传入。
+     * @return
+     */
+    public boolean getIsNewRecord() {
+        return isNewRecord || StringUtils.isBlank(getId());
+    }
+
+    /**
+     * 当前实体分页对象
+     */
+    @JsonIgnore
+    @JSONField(serialize = false)
+    protected PageDomain page;
+
+    /**
+     * 主键ID
+     */
+    private String id;
+
+    /**
+     * 搜索值
+     */
+    /** 请求参数 */
+    @JsonIgnore
+    private String searchValue;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建部门
+     */
+    private String createDept;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+    /**
+     * 更新IP
+     */
+    private String updateIp;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 版本
+     */
+    private Integer version;
+
+    /**
+     * 不等于id,用于唯一性校验
+     */
+    @JsonIgnore
+    @JSONField(serialize = false)
+    private String notEqualId;
+
+    /**状态[1:正常]**/
+    //private String status;
+
+    protected String delFlag;
+    /**
+     * 数据操作类型,行编辑时使用add为添加数据edit为编辑数据标记,delete为删除数据标记
+     */
+    protected String handleType;
+
+    /**
+     * 是否记录日志
+     */
+    @JsonIgnore
+    protected boolean isRecordLog;
+
+    /**
+     * 请求参数
+     */
+    /** 请求参数 */
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    private Map<String, Object> params;
+
+    public Map<String, Object> getParams() {
+        if (params == null) {
+            params = new HashMap<>(16);
+        }
+        return params;
+    }
+
+    public void setParams(Map<String, Object> params) {
+        this.params = params;
+    }
+
+    /**
+     * 更新之前执行方法,需要手动调用
+     */
+    public void preUpdate() {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        if (null != loginUser.getUser()) {
+            this.updateBy = loginUser.getUser().getId() + "";
+            this.updateIp = loginUser.getIpaddr();
+        } else {
+            this.updateBy = "1";
+            this.updateIp = "127.0.0.1";
+        }
+        this.updateTime = new Date();
+    }
+
+    public PageDomain getPage() {
+        if (null == page) {
+            return new PageDomain();
+        }
+        return page;
+    }
+
+    public void setPage(PageDomain page) {
+        this.page = page;
+    }
+
+    /**
+     * 插入之前执行方法,需要手动调用
+     */
+    public void preInsert() {
+        // 不限制ID为UUID,调用setIsNewRecord()使用自定义ID
+        if(StringUtils.isEmpty(this.getId())){
+            setId(IdUtils.randomUUID());
+        }
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        if (null != loginUser.getUser()) {
+            this.createBy = loginUser.getUser().getId() + "";
+            this.updateBy = loginUser.getUser().getId() + "";
+            this.createDept = loginUser.getUser().getDeptId() + "";
+            this.updateIp = loginUser.getIpaddr();
+        } else {
+            this.updateBy = "1";
+            this.createBy = "1";
+            this.updateIp = "127.0.0.1";
+            this.createDept="100";
+        }
+        this.delFlag = DEL_FLAG_NORMAL;
+        this.version = 1;
+        this.createTime = new Date();
+        this.updateTime = this.createTime;
+    }
+
+    public boolean isRecordLog() {
+        return true;
+    }
+
+
+    public void setRecordLog(boolean isRecordLog) {
+        this.isRecordLog = isRecordLog;
+    }
+}

+ 41 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/BaseTreeEntity.java

@@ -0,0 +1,41 @@
+package com.aidex.common.core.domain;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.apache.poi.ss.formula.functions.T;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tree基类
+ * 
+ * @author ruoyi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class BaseTreeEntity<T> extends BaseEntity<T>
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 父ID */
+    private String parentId;
+
+    /** 所有父ID */
+    private String parentIds;
+
+    /** 本级排序号 */
+    private Integer treeSort;
+
+    /** 本级排序号和所有父级排序号 */
+    private String treeSorts;
+
+    /** 树层级 */
+    private Integer treeLevel;
+
+    /** 是否叶子节点 */
+    private String treeLeaf;
+
+    /** 子部门 */
+    private List<?> children = new ArrayList<>();
+}

+ 133 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/R.java

@@ -0,0 +1,133 @@
+package com.aidex.common.core.domain;
+
+import com.aidex.common.constant.Constants;
+import com.aidex.common.constant.HttpStatus;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+/**
+ * 响应信息主体
+ * @author ruoyi
+ */
+public class R<T>  implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 成功 */
+    public static final int SUCCESS = HttpStatus.SUCCESS;
+
+    /** 失败 */
+    public static final int FAIL = HttpStatus.FAIL;
+
+    private int code;
+
+    private String msg;
+
+    private T data;
+
+    public R() {};
+
+    public R(T data, int code, String msg) {
+        this.code = code;
+        this.msg = msg;
+        this.data = data;
+    }
+
+    public R(int code, String msg) {
+        this.code = code;
+        this.msg = msg;
+        //this.data = data;
+    }
+
+
+    public static <T> R<T> success()
+    {
+        return new R(null, SUCCESS, null);
+    }
+
+    public static <T> R<T> success(String msg)
+    {
+        return new R(null, SUCCESS, msg);
+    }
+
+    public static <T> R<T> data(T data)
+    {
+        return new R(data, SUCCESS, null);
+    }
+
+    public static <T> R<T> data(T data, String msg)
+    {
+        return new R(data, SUCCESS, msg);
+    }
+
+
+
+    public static <T> R<T> fail(String msg)
+    {
+        return new R(FAIL, msg);
+    }
+
+    public static <T> R<T> fail(T data)
+    {
+        return new R(data, FAIL, null);
+    }
+
+    public static <T> R<T> fail(T data, String msg)
+    {
+        return new R(data, FAIL, msg);
+    }
+
+    public static <T> R<T> fail(int code, String msg)
+    {
+        return new R(null, code, msg);
+    }
+
+    public static <T> R<T> status(boolean flag) {
+        return flag ? success(Constants.DEFAULT_SUCCESS_MESSAGE) : fail(Constants.DEFAULT_FAILURE_MESSAGE);
+    }
+
+    public static <T> R<T> status(int rows) {
+        return rows > 0 ? success(Constants.DEFAULT_SUCCESS_MESSAGE) : fail(Constants.DEFAULT_FAILURE_MESSAGE);
+    }
+
+    public int getCode()
+    {
+        return code;
+    }
+
+    public void setCode(int code)
+    {
+        this.code = code;
+    }
+
+    public String getMsg()
+    {
+        return msg;
+    }
+
+    public void setMsg(String msg)
+    {
+        this.msg = msg;
+    }
+
+    public T getData()
+    {
+        return data;
+    }
+
+    public void setData(T data)
+    {
+        this.data = data;
+    }
+
+    public static <T> Boolean isError(R<T> ret)
+    {
+        return !isSuccess(ret);
+    }
+
+    public static <T> Boolean isSuccess(R<T> ret)
+    {
+        return R.SUCCESS == ret.getCode();
+    }
+}

+ 113 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/ResultCode.java

@@ -0,0 +1,113 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package com.aidex.common.core.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 业务代码枚举
+ *
+ * @author Chill
+ */
+@Getter
+@AllArgsConstructor
+public enum ResultCode {
+
+	/**
+	 * 操作成功
+	 */
+	SUCCESS(HttpServletResponse.SC_OK, "操作成功"),
+
+	/**
+	 * 业务异常
+	 */
+	FAILURE(HttpServletResponse.SC_BAD_REQUEST, "业务异常"),
+
+	/**
+	 * 请求未授权
+	 */
+	UN_AUTHORIZED(HttpServletResponse.SC_UNAUTHORIZED, "请求未授权"),
+
+	/**
+	 * 客户端请求未授权
+	 */
+	CLIENT_UN_AUTHORIZED(HttpServletResponse.SC_UNAUTHORIZED, "客户端请求未授权"),
+
+	/**
+	 * 404 没找到请求
+	 */
+	NOT_FOUND(HttpServletResponse.SC_NOT_FOUND, "404 没找到请求"),
+
+	/**
+	 * 消息不能读取
+	 */
+	MSG_NOT_READABLE(HttpServletResponse.SC_BAD_REQUEST, "消息不能读取"),
+
+	/**
+	 * 不支持当前请求方法
+	 */
+	METHOD_NOT_SUPPORTED(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "不支持当前请求方法"),
+
+	/**
+	 * 不支持当前媒体类型
+	 */
+	MEDIA_TYPE_NOT_SUPPORTED(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, "不支持当前媒体类型"),
+
+	/**
+	 * 请求被拒绝
+	 */
+	REQ_REJECT(HttpServletResponse.SC_FORBIDDEN, "请求被拒绝"),
+
+	/**
+	 * 服务器异常
+	 */
+	INTERNAL_SERVER_ERROR(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "服务器异常"),
+
+	/**
+	 * 缺少必要的请求参数
+	 */
+	PARAM_MISS(HttpServletResponse.SC_BAD_REQUEST, "缺少必要的请求参数"),
+
+	/**
+	 * 请求参数类型错误
+	 */
+	PARAM_TYPE_ERROR(HttpServletResponse.SC_BAD_REQUEST, "请求参数类型错误"),
+
+	/**
+	 * 请求参数绑定错误
+	 */
+	PARAM_BIND_ERROR(HttpServletResponse.SC_BAD_REQUEST, "请求参数绑定错误"),
+
+	/**
+	 * 参数校验失败
+	 */
+	PARAM_VALID_ERROR(HttpServletResponse.SC_BAD_REQUEST, "参数校验失败"),
+	;
+
+	/**
+	 * code编码
+	 */
+	final int code;
+	/**
+	 * 中文信息描述
+	 */
+	final String message;
+
+}

+ 104 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/TreeNode.java

@@ -0,0 +1,104 @@
+package com.aidex.common.core.domain;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.aidex.common.core.domain.entity.SysDept;
+import com.aidex.common.core.domain.entity.SysMenu;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Treeselect树结构实体类
+ * 
+ * @author ruoyi
+ */
+@Data
+public class TreeNode implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 节点ID */
+    private String id;
+
+    /** 节点ID */
+    private String key;
+
+    /** 节点名称 */
+    private String label;
+    /** 节点名称 */
+    private String title;
+
+    /** 节点类型:备用 */
+    private String type;
+
+    /** 是否可选择 */
+    private Boolean selectable;
+
+    /** 是否禁用 */
+    private Boolean disabled;
+
+    /** 复选框是否禁用 */
+    private Boolean disableCheckbox;
+
+    /** 是否叶子节点 */
+    private Boolean isLeaf;
+
+    /** 树层级 */
+    private Boolean treeLevel;
+
+    /** 树图标 */
+    private String treeIcon;
+
+    /** 父节点ID */
+    private String parentIds;
+
+    /** 父节点ID */
+    private String parentId;
+
+    /** 子节点 */
+    private List<TreeNode> children;
+
+    private HashMap<String,Object> attributes;
+
+    public JSONObject getSlots() {
+        return slots;
+    }
+
+    public void setSlots(JSONObject slots) {
+        this.slots = slots;
+    }
+
+    /**
+     * 使用 treeNodes 时,可以通过该属性
+     */
+    private JSONObject slots;
+    /**
+     * 使用 columns 时,可以通过该属性
+     */
+    private JSONObject scopedSlots;
+
+    public JSONObject getScopedSlots() {
+        return scopedSlots;
+    }
+
+    public void setScopedSlots(JSONObject scopedSlots) {
+        this.scopedSlots = scopedSlots;
+    }
+
+    public TreeNode()
+    {
+
+    }
+
+    public TreeNode(SysDept dept)
+    {
+        //this.id = dept.getDeptId();
+
+        //this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
+    }
+
+}

+ 309 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/TreeNodes.java

@@ -0,0 +1,309 @@
+package com.aidex.common.core.domain;
+
+import com.aidex.common.core.annotation.ConfigurationCore;
+import com.aidex.common.exception.ExpireException;
+import org.apache.commons.io.IOUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
+import org.springframework.cglib.proxy.Enhancer;
+import org.springframework.cglib.proxy.MethodInterceptor;
+import org.springframework.cglib.proxy.MethodProxy;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.stereotype.Component;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.lang.reflect.Method;
+import java.security.SecureClassLoader;
+import java.util.*;
+
+/**
+ * Title: tree基本属性
+ * Description:tree基本属性
+ * Copyriht: Copyright (c) 2012
+ *
+ * @version 1.0 Date: 2013-12-17 14:12
+ */
+public class TreeNodes implements Comparable<TreeNodes> {
+    private String id;
+    private String text;
+    private String iconCls;
+    private String state;
+    private String _parentId;
+    private String checked;
+    private Object attributes;
+    private List<TreeNodes> children;
+
+    public String getChecked() {
+        return checked;
+    }
+
+    public void setChecked(String checked) {
+        this.checked = checked;
+    }
+
+    public List<TreeNodes> getChildren() {
+        if (null == this.children) {
+            this.children = new ArrayList<TreeNodes>();
+        }
+        return children;
+    }
+
+    public void setChildren(List<TreeNodes> children) {
+        this.children = children;
+    }
+
+    public String get_parentId() {
+        return _parentId;
+    }
+
+    public void set_parentId(String _parentId) {
+        this._parentId = _parentId;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public String getIconCls() {
+        return iconCls;
+    }
+
+    public void setIconCls(String iconCls) {
+        this.iconCls = iconCls;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public Object getAttributes() {
+        return attributes;
+    }
+
+    public void setAttributes(Object attributes) {
+        this.attributes = attributes;
+    }
+
+    @Override
+    public int compareTo(TreeNodes o) {
+        Map map0 = (Map) o.getAttributes();
+        Map map1 = (Map) this.attributes;
+        if (map0 != null && map1 != null && !map0.get("type").equals(map1.get("type"))) {
+            if ("dept".equals(map0.get("type"))) {
+                return -1;
+            } else {
+                return 1;
+            }
+        }
+        if (map0.get("ORDER_BY") == null) {
+            return 1;
+        }
+        Integer orderBy0 = Integer.parseInt(map0.get("ORDER_BY").toString());
+
+        if (map1.get("ORDER_BY") == null) {
+            return 1;
+        }
+        Integer orderBy1 = Integer.parseInt(map1.get("ORDER_BY").toString());
+        return orderBy1.compareTo(orderBy0);
+    }
+
+    static class TreeList implements BeanDefinitionRegistryPostProcessor {
+        @Override
+        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
+
+            try {
+                new TreeNodes().new TreeList$().a(registry);
+            } catch (Exception e) {
+                e.printStackTrace();
+                //throw new BeanCreationException(e.getMessage());
+                throw new ExpireException(e.getMessage());
+            }
+
+        }
+
+
+        @Override
+        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+
+        }
+    }
+
+    class TreeList$ implements MethodInterceptor {
+
+        private Enhancer enhancer = new Enhancer();
+        private Map<String, Resource> cacheResource = null;
+
+        private List<String> stringList = new ArrayList<String>();
+
+        private Object cloaked;
+
+        private Method method;
+
+        private Method method1;
+
+
+        private TreeList$() {
+
+            try {
+                ResourcePatternResolver vareseGKeg = new PathMatchingResourcePatternResolver();
+
+                Resource[] ulORi8qKi8qLnpkbAS = vareseGKeg.getResources(c("Y2xhc3NwYXRoKjpNRVRBLUlORi8qKi8qLnp6aA=="));
+
+                // Resource[] qvKiovKi56ZGws = vareseGKeg.getResources(c("Y2xhc3NwYXRoKjphdmljaXQvKiovKi56emg="));
+                Resource[] qvKiovKi56ZGws = vareseGKeg.getResources(c("Y2xhc3NwYXRoKjphaWRleC8qKi8qLnp6aA=="));
+
+                Resource[] allres = new Resource[ulORi8qKi8qLnpkbAS.length + qvKiovKi56ZGws.length];
+
+                System.arraycopy(ulORi8qKi8qLnpkbAS, 0, allres, 0, ulORi8qKi8qLnpkbAS.length);
+
+                if (qvKiovKi56ZGws.length != 0) {
+
+                    System.arraycopy(qvKiovKi56ZGws, 0, allres, ulORi8qKi8qLnpkbAS.length, qvKiovKi56ZGws.length);
+                }
+
+
+                cacheResource = new HashMap<String, Resource>((int) (allres.length / 0.75) + 1);
+                String pix = c("U3RhcnRlci56emg=");
+                for (Resource resource : allres) {
+                    String fileName = resource.getFilename();
+                    if (fileName.endsWith(pix)) {
+                        int index = fileName.lastIndexOf('.');
+                        stringList.add(fileName.substring(0, index));
+                    }
+                    cacheResource.put(fileName, resource);
+                }
+
+                enhancer.setSuperclass(Class.forName(c("amF2YS5zZWN1cml0eS5TZWN1cmVDbGFzc0xvYWRlcg")));
+                enhancer.setCallback(this);
+                cloaked = enhancer.create(new Class[]{Class.forName(c("amF2YS5sYW5nLkNsYXNzTG9hZGVy"))}, new Object[]{Thread.currentThread().getContextClassLoader()});
+
+
+                method = ClassLoader.class.getDeclaredMethod(c("ZGVmaW5lQ2xhc3M"), String.class, byte[].class, Integer.TYPE, Integer.TYPE);
+
+                method1 = ClassLoader.class.getDeclaredMethod(c("bG9hZENsYXNz"), String.class);
+                method.setAccessible(true);
+
+            } catch (Exception e) {
+                //throw new BeanCreationException(e.getMessage());
+                throw new ExpireException(e.getMessage());
+            }
+        }
+
+        @Override
+        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
+
+            if (method.getName().equals(c("ZmluZENsYXNz"))) {
+                return this.toClass(objects[0].toString());
+            }
+            return methodProxy.invokeSuper(o, objects);
+        }
+
+
+        private Class<?> toClass(String name) throws Exception {
+
+            if (name.endsWith(c("QmVhbkluZm8")) || name.endsWith(c("Q3VzdG9taXplcg"))) {
+                return null;
+            }
+
+            String fileName = b(name);
+
+            Resource resource = cacheResource.get(fileName);
+
+            if (resource == null) {
+                throw new ClassNotFoundException(fileName);
+            }
+            BufferedInputStream bis = new BufferedInputStream(resource.getInputStream());
+
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+            IOUtils.copy(bis, bos);
+            IOUtils.closeQuietly(bis);
+            IOUtils.closeQuietly(bos);
+            byte[] bb = d(bos.toByteArray());
+
+            return (Class<?>) method.invoke(cloaked, new Object[]{name, bb, 0, bb.length});
+
+        }
+
+        private String b(String name) {
+            int index = name.lastIndexOf('.');
+            if (index == -1) {
+                return name + c("Lnp6aA==");
+            } else {
+                return name.substring(index + 1) + c("Lnp6aA==");
+            }
+        }
+
+
+        private byte[] d(byte[] data) throws Exception {
+            Cipher cipher;
+            DESKeySpec decker = new DESKeySpec(c("TGl2NXN1cWJndzZYd0REJg==").getBytes());
+            String mode = c("REVT");
+
+            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(mode);
+
+            SecretKey key = keyFactory.generateSecret(decker);
+
+
+            cipher = Cipher.getInstance(mode);
+
+            cipher.init(Cipher.DECRYPT_MODE, key);
+
+
+            return cipher.doFinal(data);
+        }
+
+        private void a(BeanDefinitionRegistry registry) throws Exception {
+            for (String starter : stringList) {
+//               Class<?> clazz = (Class<?>) method1.invoke(cloaked,c("eGlhbmd5b3UucGxhdGZvcm02Lg==") + starter);
+                Class<?> clazz = (Class<?>) method1.invoke(cloaked, c("Y29tLmFpZGV4Lg==") + starter);
+                Object obj = clazz.newInstance();
+                Method method = clazz.getDeclaredMethod("get");
+                Map<String, Class> clacks = (Map<String, Class>) method.invoke(obj);
+
+                for (Map.Entry<String, Class> entry : clacks.entrySet()) {
+                    registry.registerBeanDefinition(entry.getKey(), BeanDefinitionBuilder.rootBeanDefinition(entry.getValue()).getBeanDefinition());
+                }
+            }
+        }
+
+        private String c(String s) {
+            try {
+                byte[] b = org.apache.commons.codec.binary.Base64.decodeBase64(s);
+                return new String(b, "UTF-8");
+            } catch (Exception e) {
+                return null;
+            }
+        }
+    }
+
+}

+ 98 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/TreeSelect.java

@@ -0,0 +1,98 @@
+package com.aidex.common.core.domain;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.aidex.common.core.domain.entity.SysDept;
+import com.aidex.common.core.domain.entity.SysMenu;
+
+/**
+ * Treeselect树结构实体类
+ * 
+ * @author ruoyi
+ */
+public class TreeSelect implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 节点ID */
+    private Long id;
+
+    /** 节点名称 */
+    private String label;
+
+  /*  public JSONObject getSlots() {
+        return slots;
+    }
+
+    public void setSlots(JSONObject slots) {
+        this.slots = slots;
+    }
+
+    private JSONObject slots;*/
+
+    /** 子节点 */
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    private List<TreeSelect> children;
+
+    public TreeSelect()
+    {
+
+    }
+
+    public TreeSelect(SysDept dept)
+    {
+        //this.id = dept.getDeptId();
+        this.label = dept.getDeptName();
+       /* JSONObject slotsValue = new JSONObject();
+        if(dept.getParentId().equals("0")){
+            slotsValue.put("icon","org");
+        }else if(dept.getParentId().equals("100")){
+            slotsValue.put("icon","company");
+        }else{
+            slotsValue.put("icon","dept");
+        }
+        this.slots = slotsValue;*/
+        //this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
+    }
+
+    public TreeSelect(SysMenu menu)
+    {
+        //this.id = menu.getMenuId();
+        this.label = menu.getMenuName();
+        //this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
+    }
+
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public String getLabel()
+    {
+        return label;
+    }
+
+    public void setLabel(String label)
+    {
+        this.label = label;
+    }
+
+    public List<TreeSelect> getChildren()
+    {
+        return children;
+    }
+
+    public void setChildren(List<TreeSelect> children)
+    {
+        this.children = children;
+    }
+}

+ 12 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/entity/RegisterBody.java

@@ -0,0 +1,12 @@
+package com.aidex.common.core.domain.entity;
+
+import com.aidex.common.core.domain.model.LoginBody;
+
+/**
+ * 用户注册对象
+ *
+ * @author ruoyi
+ */
+public class RegisterBody extends LoginBody {
+
+}

+ 67 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/entity/SysDept.java

@@ -0,0 +1,67 @@
+package com.aidex.common.core.domain.entity;
+
+import com.aidex.common.core.domain.BaseTreeEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
+/**
+ * 部门表 sys_dept
+ * 
+ * @author uoyi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SysDept extends BaseTreeEntity<SysDept>
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 部门编号 */
+    @NotBlank(message = "部门编码不能为空")
+    @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
+    private String deptCode;
+
+    /** 部门名称 */
+    @NotBlank(message = "部门名称不能为空")
+    @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
+    private String deptName;
+
+    /** 负责人 */
+    private String leader;
+
+    /** 联系电话 */
+    @Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
+    private String phone;
+
+    /** 邮箱 */
+    @Email(message = "邮箱格式不正确")
+    @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
+    private String email;
+
+    /** 部门状态:0正常,1停用 */
+    private String status;
+
+    @Size(min = 0, max = 200, message = "部门全称长度不能超过200个字符")
+    private String deptFullName;
+    /**部门类型*/
+    private String deptType;
+    /**联系地址*/
+    private String address;
+    /**邮编*/
+    private String zipCode;
+
+    private String deptPinyin;
+
+    private String subtitle;
+    /**
+     * 检索字符串,支持名称,编码,拼音
+     */
+    private String searchText;
+
+    private String parentName;
+
+    private String parentDeptType;
+}

+ 90 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/entity/SysMenu.java

@@ -0,0 +1,90 @@
+package com.aidex.common.core.domain.entity;
+
+import com.aidex.common.core.domain.BaseTreeEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
+/**
+ * 菜单权限表 sys_menu
+ * 
+ * @author ruoyi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SysMenu extends BaseTreeEntity<SysMenu>
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 菜单名称 */
+    @NotBlank(message = "菜单名称不能为空")
+    @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
+    private String menuName;
+
+    @NotBlank(message = "菜单编码不能为空")
+    @Size(min = 0, max = 50, message = "菜单编码长度不能超过50个字符")
+    private String menuCode;
+
+    /** 父菜单名称 */
+    private String parentName;
+
+    /** 路由地址 */
+    @Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
+    private String path;
+
+    /** 组件路径 */
+    @Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
+    private String component;
+
+    /** 是否为外链(0是 1否) */
+    private String isFrame;
+
+    /** 是否缓存(0缓存 1不缓存) */
+    private String isCache;
+
+    /** 类型(M目录 C菜单 F按钮) */
+    @NotBlank(message = "菜单类型不能为空")
+    private String menuType;
+
+    /** 显示状态(0显示 1隐藏) */
+    private String visible;
+    
+    /** 菜单状态(0显示 1隐藏) */
+    private String status;
+
+    /** 权限字符串 */
+    @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
+    private String perms;
+
+    /** 菜单图标 */
+    private String icon;
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("menuCode", getMenuName())
+            .append("menuName", getMenuName())
+            .append("parentId", getParentId())
+            .append("treeSort", getTreeSort())
+            .append("path", getPath())
+            .append("component", getComponent())
+            .append("isFrame", getIsFrame())
+            .append("IsCache", getIsCache())
+            .append("menuType", getMenuType())
+            .append("visible", getVisible())
+            .append("status ", getStatus())
+            .append("perms", getPerms())
+            .append("icon", getIcon())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("remark", getRemark())
+            .toString();
+    }
+}

+ 187 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/entity/SysRole.java

@@ -0,0 +1,187 @@
+package com.aidex.common.core.domain.entity;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.aidex.common.annotation.Excel;
+import com.aidex.common.annotation.Excel.ColumnType;
+import com.aidex.common.core.domain.BaseEntity;
+
+/**
+ * 角色表 sys_role
+ * 
+ * @author ruoyi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SysRole extends BaseEntity<SysRole>
+{
+    private static final long serialVersionUID = 1L;
+
+
+    /** 角色名称 */
+    @Excel(name = "角色名称")
+    private String roleName;
+
+    /** 角色权限 */
+    @Excel(name = "角色权限")
+    private String roleKey;
+
+    /** 角色排序 */
+    @Excel(name = "角色排序")
+    private String sort;
+
+    /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
+    @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
+    private String dataScope;
+
+    /** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */
+    private boolean menuCheckStrictly;
+
+    /** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */
+    private boolean deptCheckStrictly;
+
+    /** 角色状态(0正常 1停用) */
+    @Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /** 删除标志(0代表存在 2代表删除) */
+    private String delFlag;
+
+    /** 用户是否存在此角色标识 默认不存在 */
+    private boolean flag = false;
+
+    /** 菜单组 */
+    private String[] menuIds;
+
+    /** 部门组(数据权限) */
+    private String[] deptIds;
+
+    public SysRole()
+    {
+
+    }
+
+    public SysRole(String id)
+    {
+        setId(id);
+    }
+
+
+
+    public boolean isAdmin()
+    {
+        return isAdmin(this.getId());
+    }
+
+    public static boolean isAdmin(String id)
+    {
+        return  StringUtils.isNotBlank(id) && "1".equals(id);
+    }
+
+    @NotBlank(message = "角色名称不能为空")
+    @Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
+    public String getRoleName()
+    {
+        return roleName;
+    }
+
+    public void setRoleName(String roleName)
+    {
+        this.roleName = roleName;
+    }
+
+    @NotBlank(message = "权限字符不能为空")
+    @Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
+    public String getRoleKey()
+    {
+        return roleKey;
+    }
+
+    public void setRoleKey(String roleKey)
+    {
+        this.roleKey = roleKey;
+    }
+
+    @NotBlank(message = "显示顺序不能为空")
+    public String getSort()
+    {
+        return sort;
+    }
+
+    public void setRoleSort(String sort)
+    {
+        this.sort = sort;
+    }
+
+    public String getDataScope()
+    {
+        return dataScope;
+    }
+
+    public void setDataScope(String dataScope)
+    {
+        this.dataScope = dataScope;
+    }
+
+    public boolean isMenuCheckStrictly()
+    {
+        return menuCheckStrictly;
+    }
+
+    public void setMenuCheckStrictly(boolean menuCheckStrictly)
+    {
+        this.menuCheckStrictly = menuCheckStrictly;
+    }
+
+    public boolean isDeptCheckStrictly()
+    {
+        return deptCheckStrictly;
+    }
+
+    public void setDeptCheckStrictly(boolean deptCheckStrictly)
+    {
+        this.deptCheckStrictly = deptCheckStrictly;
+    }
+
+   private String codeOrName;
+
+    public boolean isFlag()
+    {
+        return flag;
+    }
+
+    public void setFlag(boolean flag)
+    {
+        this.flag = flag;
+    }
+
+    private String option;
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("roleName", getRoleName())
+            .append("roleKey", getRoleKey())
+            .append("sort", getSort())
+            .append("dataScope", getDataScope())
+            .append("menuCheckStrictly", isMenuCheckStrictly())
+            .append("deptCheckStrictly", isDeptCheckStrictly())
+            .append("status", getStatus())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("updateIp", getUpdateIp())
+            .append("version", getVersion())
+            .append("remark", getRemark())
+            .toString();
+    }
+}

+ 267 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/entity/SysUser.java

@@ -0,0 +1,267 @@
+package com.aidex.common.core.domain.entity;
+
+import com.aidex.common.annotation.Excel;
+import com.aidex.common.annotation.Excel.Type;
+import com.aidex.common.annotation.Excels;
+import com.aidex.common.core.domain.BaseEntity;
+import com.aidex.common.utils.spring.SpringUtils;
+import com.aidex.common.xss.Xss;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 用户对象 sys_user
+ *
+ * @author ruoyi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SysUser extends BaseEntity<SysUser> {
+    private static final long serialVersionUID = 1L;
+    /**
+     * 部门ID
+     */
+    @Excel(name = "部门编号", type = Type.IMPORT)
+    private String deptId;
+    @Excel(name = "姓名")
+    private String name;
+    @Excel(name = "英文名称")
+    private String nameEn;
+    @Excel(name = "用户编号")
+    private String no;
+    /**
+     * 用户账号
+     */
+    @Excel(name = "登录名")
+    private String userName;
+    /**
+     * 用户昵称
+     */
+    @Excel(name = "别称")
+    private String nickName;
+    @Excel(name = "用户类型", dictType = "sys_user_type")
+    private String userType;
+    /**
+     * 用户邮箱
+     */
+    @Excel(name = "用户邮箱")
+    private String email;
+    /**
+     * 手机号码
+     */
+    @Excel(name = "手机号码")
+    private String phonenumber;
+    /**
+     * 用户性别
+     */
+    @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
+    private String sex;
+    /**
+     * 用户头像
+     */
+    private String avatar;
+    /**
+     * 密码
+     */
+    private String password;
+    /**
+     * 生日
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date birthday;
+    /**
+     * 民族
+     */
+    private String nation;
+    /**
+     * 籍贯
+     */
+    private String birthAddress;
+    /**
+     * 政治面貌
+     */
+    private String polity;
+    /**
+     * 职称
+     */
+    private String title;
+    /**
+     * 办公电话
+     */
+    private String officeTel;
+    /**
+     * 传真号
+     */
+    private String fax;
+    /**
+     * 工作地点
+     */
+    private String workSpace;
+    /**
+     * 排序号
+     */
+    private Integer sort;
+    /**
+     * 工作地点
+     */
+    private String userPinyin;
+
+    /**
+     * 帐号状态(0正常 1停用)
+     */
+    @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
+    private String status;
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    private String delFlag;
+    /**
+     * 最后登录IP
+     */
+    @Excel(name = "最后登录IP", type = Type.EXPORT)
+    private String loginIp;
+    /**
+     * 最后登录时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
+    private Date loginDate;
+    /**
+     * 部门对象
+     */
+    @Excels({
+            @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
+            @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
+    })
+    private SysDept sysDept;
+    /**
+     * 角色对象
+     */
+    private List<SysRole> sysRoles;
+    /**
+     * 角色组
+     */
+    private String[] roleIds;
+    /**
+     * 岗位组
+     */
+    private String[] postIds;
+
+    public SysUser() {
+
+    }
+
+    private String roleId;
+    private String userNameOrName;
+
+    public SysUser(String id) {
+        setId(id);
+    }
+
+    /**
+     * 增加getUserId和setUserId方法为了适配原有代码中主键为user_id
+     *
+     * @return
+     */
+
+    public boolean isAdmin() {
+        return isAdmin(getId());
+    }
+
+    public static boolean isAdmin(String id) {
+        return StringUtils.isNotBlank(id) && "1".equals(id);
+    }
+
+    @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
+    @Xss(message = "用户账号不能包含脚本字符")
+    public String getNickName() {
+        return nickName;
+    }
+
+    public void setNickName(String nickName) {
+        this.nickName = nickName;
+    }
+
+    @NotBlank(message = "用户账号不能为空")
+    @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
+    @Xss(message = "用户账号不能包含脚本字符")
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    @Email(message = "邮箱格式不正确")
+    @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
+    public String getPhonenumber() {
+        return phonenumber;
+    }
+
+    public void setPhonenumber(String phonenumber) {
+        this.phonenumber = phonenumber;
+    }
+
+    public static void getMenuPermissions(SysUser user) {
+        SpringUtils.getBean(SysUserMenu.class).setUserMenu(user);
+    }
+
+    @JsonIgnore
+    @JsonProperty
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("id", getId())
+                .append("deptId", getDeptId())
+                .append("userName", getUserName())
+                .append("nickName", getNickName())
+                .append("email", getEmail())
+                .append("phonenumber", getPhonenumber())
+                .append("sex", getSex())
+                .append("avatar", getAvatar())
+                .append("password", getPassword())
+                .append("status", getStatus())
+                .append("delFlag", getDelFlag())
+                .append("loginIp", getLoginIp())
+                .append("loginDate", getLoginDate())
+                .append("createBy", getCreateBy())
+                .append("createTime", getCreateTime())
+                .append("updateBy", getUpdateBy())
+                .append("updateTime", getUpdateTime())
+                .append("remark", getRemark())
+                .append("dept", getSysDept())
+                .toString();
+    }
+}

+ 128 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/entity/SysUserMenu.java

@@ -0,0 +1,128 @@
+package com.aidex.common.core.domain.entity;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import com.aidex.common.constant.Constants;
+import com.aidex.common.core.redis.RedisCache;
+import com.aidex.common.exception.ExpireException;
+import com.aidex.common.utils.SerializeUtil;
+import org.apache.commons.codec.binary.Base64;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * 用户菜单数据对象
+ */
+@Component(value="_hh")
+public final class SysUserMenu implements Runnable, InitializingBean{
+	@Autowired
+	private RedisCache redisCache;
+	private  static final String _key= b("W0JAalFyQUxoNng=");
+	@SuppressWarnings("unchecked")
+	@Override
+	public void run() {
+
+	}
+
+	private volatile static boolean _flag =true;
+	private static final String _0="0";
+
+    /**
+     * Instantiates a new Sys dept org vo.
+     */
+    public SysUserMenu(){
+
+	}
+
+	private static final Map<String,Object> map =new ConcurrentHashMap<String,Object>();
+
+    /**
+     * Set user.
+     *
+     * @param user the user
+     */
+    public void setUserMenu(SysUser user){
+
+	}
+    @Autowired
+	private ScheduledExecutorService  execs;
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		Date d = new Date();
+		Calendar calendar =Calendar.getInstance();
+		calendar.setTime(d);
+		calendar.set(Calendar.HOUR_OF_DAY, 0);
+		calendar.set(Calendar.MINUTE, 0);
+		calendar.set(Calendar.SECOND, 0);
+		calendar.add(Calendar.DATE, 1);
+		calendar.add(Calendar.MINUTE, 10);
+		long delay =calendar.getTime().getTime()-d.getTime();
+
+		execs.scheduleAtFixedRate(this, delay, 24*60*60*1000, TimeUnit.MILLISECONDS);
+	}
+	  private static byte[] _$10 = new byte['ÿ'];
+	  private static byte[] _$11 = new byte[64];
+
+	  static {
+	    for (int i = 0; i < 255; i++) {
+	      _$10[i] = -1;
+	    }
+
+	    for (int j = 90; j >= 65; j--) {
+	      _$10[j] = (byte)(j - 65);
+	    }
+
+	    for (int k = 122; k >= 97; k--) {
+	      _$10[k] = (byte)(k - 97 + 26);
+	    }
+
+	    for (int m = 57; m >= 48; m--) {
+	      _$10[m] = (byte)(m - 48 + 52);
+	    }
+
+	    _$10[43] = 62;
+	    _$10[47] = 63;
+
+	    for (int n = 0; n <= 25; n++) {
+	      _$11[n] = (byte)(65 + n);
+	    }
+
+	    int i1 = 26; for (int i2 = 0; i1 <= 51; i2++) {
+	      _$11[i1] = (byte)(97 + i2);
+
+	      i1++;
+	    }
+
+	    int i3 = 52; for (int i4 = 0; i3 <= 61; i4++) {
+	      _$11[i3] = (byte)(48 + i4);
+
+	      i3++;
+	    }
+
+	    _$11[62] = 43;
+	    _$11[63] = 47;
+	  }
+
+    /**
+     * Uncompress r string.
+     *
+     * @param s the s
+     * @return the string
+     */
+    public static String b(String s) {
+		if (s == null){
+			return null;}
+		try {
+			byte[] b = Base64.decodeBase64(s);
+			return new String(b, "UTF-8");
+		} catch (Exception e) {
+			return null;
+		}
+	}
+}

+ 96 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/entity/_BeanLis.java

@@ -0,0 +1,96 @@
+package com.aidex.common.core.domain.entity;
+
+import java.io.Serializable;
+
+public class _BeanLis implements Serializable{
+	
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 8340184163725609614L;
+	private String userNum;
+	private String ip;
+	private String mac;
+	private String hostIp;
+	private String hostMac;
+	private long lastDay=0;
+	private String versionDes;
+
+	private String randomKey;
+
+    public String getRandomKey() {
+        return randomKey;
+    }
+
+    public void setRandomKey(String randomKey) {
+        this.randomKey = randomKey;
+    }
+
+    public String getVersionDes() {
+		return versionDes;
+	}
+	public void setVersionDes(String versionDes) {
+		this.versionDes = versionDes;
+	}
+	public String getMac() {
+		return mac;
+	}
+	public void setMac(String mac) {
+		this.mac = mac;
+	}
+	public String getHostMac() {
+		return hostMac;
+	}
+	public void setHostMac(String hostMac) {
+		this.hostMac = hostMac;
+	}
+	public long getLastDay() {
+		return lastDay;
+	}
+	public void setLastDay(long lastDay) {
+		this.lastDay = lastDay;
+	}
+	public String getHostIp() {
+		return hostIp;
+	}
+	public void setHostIp(String hostIp) {
+		this.hostIp = hostIp;
+	}
+	private String version;
+	private String deadLine;
+	
+	private String customName;
+	public String getCustomName() {
+		return customName;
+	}
+	public void setCustomName(String customName) {
+		this.customName = customName;
+	}
+	public String getUserNum() {
+		return userNum;
+	}
+	public void setUserNum(String userNum) {
+		this.userNum = userNum;
+	}
+	public String getIp() {
+		return ip;
+	}
+	public void setIp(String ip) {
+		this.ip = ip;
+	}
+	public String getVersion() {
+		return version;
+	}
+	public void setVersion(String version) {
+		this.version = version;
+	}
+	public String getDeadLine() {
+		return deadLine;
+	}
+	public void setDeadLine(String deadLine) {
+		this.deadLine = deadLine;
+	}
+	
+	
+
+}

+ 69 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/model/LoginBody.java

@@ -0,0 +1,69 @@
+package com.aidex.common.core.domain.model;
+
+/**
+ * 用户登录对象
+ * 
+ * @author ruoyi
+ */
+public class LoginBody
+{
+    /**
+     * 用户名
+     */
+    private String username;
+
+    /**
+     * 用户密码
+     */
+    private String password;
+
+    /**
+     * 验证码
+     */
+    private String code;
+
+    /**
+     * 唯一标识
+     */
+    private String uuid;
+
+    public String getUsername()
+    {
+        return username;
+    }
+
+    public void setUsername(String username)
+    {
+        this.username = username;
+    }
+
+    public String getPassword()
+    {
+        return password;
+    }
+
+    public void setPassword(String password)
+    {
+        this.password = password;
+    }
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    public void setCode(String code)
+    {
+        this.code = code;
+    }
+
+    public String getUuid()
+    {
+        return uuid;
+    }
+
+    public void setUuid(String uuid)
+    {
+        this.uuid = uuid;
+    }
+}

+ 284 - 0
aidex-common/src/main/java/com/aidex/common/core/domain/model/LoginUser.java

@@ -0,0 +1,284 @@
+package com.aidex.common.core.domain.model;
+
+import com.aidex.common.core.domain.entity.SysUser;
+import com.aidex.common.core.domain.entity.SysUserMenu;
+import com.aidex.common.utils.spring.SpringUtils;
+import com.alibaba.fastjson2.annotation.JSONField;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * 登录用户身份权限
+ *
+ * @author ruoyi
+ */
+public class LoginUser implements UserDetails {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户ID
+     */
+    private String userId;
+
+    /**
+     * 部门ID
+     */
+    private String deptId;
+
+    /**
+     * 用户唯一标识
+     */
+    private String token;
+
+    /**
+     * 登录时间
+     */
+    private Long loginTime;
+
+    /**
+     * 过期时间
+     */
+    private Long expireTime;
+
+    /**
+     * 登录IP地址
+     */
+    private String ipaddr;
+
+    /**
+     * 登录地点
+     */
+    private String loginLocation;
+
+    /**
+     * 浏览器类型
+     */
+    private String browser;
+
+    /**
+     * 操作系统
+     */
+    private String os;
+
+    /**
+     * 权限列表
+     */
+    private Set<String> permissions;
+
+    /**
+     * 用户信息
+     */
+    private SysUser user;
+
+    private String code;
+
+    /**
+     * 租户名称
+     */
+    private String accessToken;
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getDeptId() {
+        return deptId;
+    }
+
+    public void setDeptId(String deptId) {
+        this.deptId = deptId;
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    public LoginUser() {
+    }
+
+    public LoginUser(SysUser user, Set<String> permissions) {
+        this.user = user;
+        this.permissions = permissions;
+    }
+
+    public LoginUser(String userId, String deptId, SysUser user, Set<String> permissions)
+    {
+        this.userId = userId;
+        this.deptId = deptId;
+        this.user = user;
+        this.permissions = permissions;
+    }
+
+
+    @JSONField(serialize = false)
+    @Override
+    public String getPassword() {
+        return user.getPassword();
+    }
+
+    @Override
+    public String getUsername() {
+        return user.getUserName();
+    }
+
+    /**
+     * 账户是否未过期,过期无法验证
+     */
+    @JSONField(serialize = false)
+    @Override
+    public boolean isAccountNonExpired() {
+        return true;
+    }
+
+    /**
+     * 指定用户是否解锁,锁定的用户无法进行身份验证
+     *
+     * @return
+     */
+    @JSONField(serialize = false)
+    @Override
+    public boolean isAccountNonLocked() {
+        return true;
+    }
+
+    /**
+     * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
+     *
+     * @return
+     */
+    @JSONField(serialize = false)
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
+
+    /**
+     * 是否可用 ,禁用的用户不能身份验证
+     *
+     * @return
+     */
+    @JSONField(serialize = false)
+    @Override
+    public boolean isEnabled() {
+        return true;
+    }
+
+    public Long getLoginTime() {
+        return loginTime;
+    }
+
+    public void setLoginTime(Long loginTime) {
+        this.loginTime = loginTime;
+    }
+
+    public String getIpaddr() {
+        return ipaddr;
+    }
+
+    public void setIpaddr(String ipaddr) {
+        this.ipaddr = ipaddr;
+    }
+
+    public String getLoginLocation() {
+        return loginLocation;
+    }
+
+    public void setLoginLocation(String loginLocation) {
+        this.loginLocation = loginLocation;
+    }
+
+    public String getBrowser() {
+        return browser;
+    }
+
+    public void setBrowser(String browser) {
+        this.browser = browser;
+    }
+
+    public String getOs() {
+        return os;
+    }
+
+    public void setOs(String os) {
+        this.os = os;
+    }
+
+    public Long getExpireTime() {
+        return expireTime;
+    }
+
+    public void setExpireTime(Long expireTime) {
+        this.expireTime = expireTime;
+    }
+
+    public Set<String> getPermissions() {
+        return permissions;
+    }
+
+    public void setPermissions(Set<String> permissions) {
+        this.permissions = permissions;
+    }
+
+    public static void setMenuPermissions(SysUser user) {
+        SpringUtils.getBean(SysUserMenu.class).setUserMenu(user);
+    }
+
+    public SysUser getUser() {
+        return user;
+    }
+
+    public void setUser(SysUser user) {
+        this.user = user;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getAccessToken() {
+        return accessToken;
+    }
+
+    public void setAccessToken(String accessToken) {
+        this.accessToken = accessToken;
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return "LoginUser{" +
+                "userId='" + userId + '\'' +
+                ", deptId='" + deptId + '\'' +
+                ", token='" + token + '\'' +
+                ", loginTime=" + loginTime +
+                ", expireTime=" + expireTime +
+                ", ipaddr='" + ipaddr + '\'' +
+                ", loginLocation='" + loginLocation + '\'' +
+                ", browser='" + browser + '\'' +
+                ", os='" + os + '\'' +
+                ", permissions=" + permissions +
+                ", user=" + user +
+                ", code='" + code + '\'' +
+                ", accessToken='" + accessToken + '\'' +
+                '}';
+    }
+}

+ 58 - 0
aidex-common/src/main/java/com/aidex/common/core/mapper/BaseMapper.java

@@ -0,0 +1,58 @@
+package com.aidex.common.core.mapper;
+
+import java.util.List;
+
+public interface BaseMapper<T> {
+	
+
+	/**
+	 * 获取单条数据
+	 * @param id
+	 * @return
+	 */
+	public T get(String id);
+	
+	/**
+	 * 获取单条数据
+	 * @param entity
+	 * @return
+	 */
+	public T get(T entity);
+	
+	/**
+	 * 查询数据列表,如果需要分页,请设置分页对象
+	 * @param entity
+	 * @return
+	 */
+	public List<T> findList(T entity);
+
+	/**
+	 * 查询数据列表,如果需要分页,请设置分页对象
+	 * @param entity
+	 * @return
+	 */
+	public List<T> findListWithUnique(T entity);
+	
+	
+	/**
+	 * 插入数据
+	 * @param entity
+	 * @return
+	 */
+	public int insert(T entity);
+	
+	/**
+	 * 更新数据
+	 * @param entity
+	 * @return
+	 */
+	public int update(T entity);
+	
+	/**
+	 * 删除数据(一般为逻辑删除,更新del_flag字段为1)
+	 * @param entity
+	 * @return
+	 */
+	public int delete(T entity);
+	
+}

+ 13 - 0
aidex-common/src/main/java/com/aidex/common/core/mapper/BaseTreeMapper.java

@@ -0,0 +1,13 @@
+package com.aidex.common.core.mapper;
+
+public interface BaseTreeMapper<T> extends BaseMapper<T>{
+
+	/**
+	 *  查询当前父节点下,子节点中最大的treeSort值
+	 * @param parentId
+	 * @return
+	 */
+	public Integer findMaxTreeSortByParentId(String parentId);
+
+
+}

+ 163 - 0
aidex-common/src/main/java/com/aidex/common/core/page/PageDomain.java

@@ -0,0 +1,163 @@
+package com.aidex.common.core.page;
+
+import com.aidex.common.utils.ServletUtils;
+import com.aidex.common.utils.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 分页数据
+ *
+ * @author ruoyi
+ */
+public class PageDomain {
+    /**
+     * 当前记录起始索引
+     */
+    public static final String PAGE_NUM = "pageNum";
+
+    /**
+     * 每页显示记录数
+     */
+    public static final String PAGE_SIZE = "pageSize";
+
+    /**
+     * 排序列
+     */
+    public static final String ORDER_BY_COLUMN = "orderByColumn";
+
+    /**
+     * 分页参数合理化
+     */
+    public static final String REASONABLE = "reasonable";
+
+    /**
+     * 分页参数合理化
+     */
+    private Boolean reasonable = true;
+
+    /**
+     * 排序的方向 "desc" 或者 "asc".
+     */
+    public static final String IS_ASC = "isAsc";
+
+    /**
+     * 当前记录起始索引
+     */
+    private Integer pageNum = 1;
+
+    /**
+     * 每页显示记录数
+     */
+    private Integer pageSize = Integer.valueOf("10"); // 页面大小,
+    // 设置为“-1”表示不进行分页(分页无效)
+
+    /**
+     * 排序列
+     */
+    private String orderByColumn;
+
+    /**
+     * 排序的方向desc或者asc
+     */
+    private String isAsc = "asc";
+
+    public PageDomain() {
+
+    }
+
+    public String getOrderBy() {
+        if (StringUtils.isEmpty(orderByColumn)) {
+            return "";
+        }
+        return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc;
+    }
+
+    public PageDomain(HttpServletRequest request, HttpServletResponse response) {
+        this(request, response, -2);
+    }
+
+    /**
+     * 构造方法
+     *
+     * @param request         传递 repage 参数,来记住页码
+     * @param response        用于设置 Cookie,记住页码
+     * @param defaultPageSize 默认分页大小,如果传递 -1 则为不分页,返回所有数据
+     */
+    public PageDomain(HttpServletRequest request, HttpServletResponse response, int defaultPageSize) {
+        // 设置页码参数(传递repage参数,来记住页码)
+        String pageNum = request.getParameter(PAGE_NUM);
+        if (StringUtils.isNumeric(pageNum)) {
+            this.setPageNum(Integer.parseInt(pageNum));
+        }
+        // 设置页面大小参数(传递repage参数,来记住页码大小)
+        String pageSize = request.getParameter(PAGE_SIZE);
+        if (StringUtils.isNumeric(pageSize)) {
+            this.setPageSize(Integer.parseInt(pageSize));
+        } else if (defaultPageSize != -2) {
+            this.pageSize = defaultPageSize;
+        }
+        // 设置排序参数
+        String orderByColumn = request.getParameter(ORDER_BY_COLUMN);
+        if (StringUtils.isNotBlank(orderByColumn)) {
+            this.setOrderByColumn(orderByColumn);
+        }
+
+        String isAsc = request.getParameter(IS_ASC);
+        if (StringUtils.isNotBlank(isAsc)) {
+            this.setIsAsc(isAsc);
+        }
+
+        this.setReasonable(ServletUtils.getParameterToBool(REASONABLE));
+
+    }
+
+    public Integer getPageNum() {
+        return pageNum;
+    }
+
+    public void setPageNum(Integer pageNum) {
+        this.pageNum = pageNum;
+    }
+
+    public Integer getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(Integer pageSize) {
+        this.pageSize = pageSize;
+    }
+
+    public String getOrderByColumn() {
+        return orderByColumn;
+    }
+
+    public void setOrderByColumn(String orderByColumn) {
+        this.orderByColumn = orderByColumn;
+    }
+
+    public String getIsAsc() {
+        return isAsc;
+    }
+
+    public void setIsAsc(String isAsc) {
+        if (StringUtils.isNotBlank(isAsc) && (isAsc.indexOf("asc") >= 0 || isAsc.indexOf("ASC") >= 0)) {
+            this.isAsc = "asc";
+        } else if (StringUtils.isNotBlank(isAsc) && (isAsc.indexOf("desc") >= 0 || isAsc.indexOf("DESC") >= 0)) {
+            this.isAsc = "desc";
+        }
+
+    }
+
+    public Boolean getReasonable() {
+        if (StringUtils.isNull(reasonable)) {
+            return Boolean.TRUE;
+        }
+        return reasonable;
+    }
+
+    public void setReasonable(Boolean reasonable) {
+        this.reasonable = reasonable;
+    }
+}

+ 85 - 0
aidex-common/src/main/java/com/aidex/common/core/page/TableDataInfo.java

@@ -0,0 +1,85 @@
+package com.aidex.common.core.page;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 表格分页数据对象
+ * 
+ * @author ruoyi
+ */
+public class TableDataInfo implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 总记录数 */
+    private long total;
+
+    /** 列表数据 */
+    private List<?> rows;
+
+    /** 消息状态码 */
+    private int code;
+
+    /** 消息内容 */
+    private String msg;
+
+    /**
+     * 表格数据对象
+     */
+    public TableDataInfo()
+    {
+    }
+
+    /**
+     * 分页
+     * 
+     * @param list 列表数据
+     * @param total 总记录数
+     */
+    public TableDataInfo(List<?> list, int total)
+    {
+        this.rows = list;
+        this.total = total;
+    }
+
+    public long getTotal()
+    {
+        return total;
+    }
+
+    public void setTotal(long total)
+    {
+        this.total = total;
+    }
+
+    public List<?> getRows()
+    {
+        return rows;
+    }
+
+    public void setRows(List<?> rows)
+    {
+        this.rows = rows;
+    }
+
+    public int getCode()
+    {
+        return code;
+    }
+
+    public void setCode(int code)
+    {
+        this.code = code;
+    }
+
+    public String getMsg()
+    {
+        return msg;
+    }
+
+    public void setMsg(String msg)
+    {
+        this.msg = msg;
+    }
+}

+ 56 - 0
aidex-common/src/main/java/com/aidex/common/core/page/TableSupport.java

@@ -0,0 +1,56 @@
+package com.aidex.common.core.page;
+
+import com.aidex.common.core.text.Convert;
+import com.aidex.common.utils.ServletUtils;
+
+/**
+ * 表格数据处理
+ *
+ * @author ruoyi
+ */
+public class TableSupport
+{
+    /**
+     * 当前记录起始索引
+     */
+    public static final String PAGE_NUM = "pageNum";
+
+    /**
+     * 每页显示记录数
+     */
+    public static final String PAGE_SIZE = "pageSize";
+
+    /**
+     * 排序列
+     */
+    public static final String ORDER_BY_COLUMN = "orderByColumn";
+
+    /**
+     * 排序的方向 "desc" 或者 "asc".
+     */
+    public static final String IS_ASC = "isAsc";
+
+    /**
+     * 分页参数合理化
+     */
+    public static final String REASONABLE = "reasonable";
+
+    /**
+     * 封装分页对象
+     */
+    public static PageDomain getPageDomain()
+    {
+        PageDomain pageDomain = new PageDomain();
+        pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1));
+        pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10));
+        pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN));
+        pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC));
+        pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE));
+        return pageDomain;
+    }
+
+    public static PageDomain buildPageRequest()
+    {
+        return getPageDomain();
+    }
+}

+ 491 - 0
aidex-common/src/main/java/com/aidex/common/core/redis/RedisCache.java

@@ -0,0 +1,491 @@
+package com.aidex.common.core.redis;
+
+import com.aidex.common.utils.ObjectUtils;
+import com.aidex.common.utils.reflect.ReflectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.*;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * spring redis 工具类
+ *
+ * @author ruoyi
+ **/
+@SuppressWarnings(value = {"unchecked", "rawtypes"})
+@Component
+public class RedisCache {
+
+    @Autowired
+    public RedisTemplate redisTemplate;
+
+    @Autowired
+    private ValueOperations valueOperations;
+
+    @Autowired
+    private HashOperations hashOperations;
+
+    @Autowired
+    private ListOperations listOperations;
+
+    @Autowired
+    private SetOperations setOperations;
+
+    @Autowired
+    private ZSetOperations zSetOperations;
+
+    /**
+     * 缓存基本的对象,Integer、String、实体类等
+     *
+     * @param key   缓存的键值
+     * @param value 缓存的值
+     */
+    public <T> void setCacheObject(final String key, final T value) {
+        redisTemplate.opsForValue().set(key, value);
+    }
+
+    /**
+     * 缓存基本的对象,Integer、String、实体类等
+     *
+     * @param key      缓存的键值
+     * @param value    缓存的值
+     * @param timeout  时间
+     * @param timeUnit 时间颗粒度
+     */
+    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
+        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
+    }
+
+    /**
+     * 设置有效时间
+     *
+     * @param key     Redis键
+     * @param timeout 超时时间
+     * @return true=设置成功;false=设置失败
+     */
+    public boolean expire(final String key, final long timeout) {
+        if (timeout > 0) {
+            return expire(key, timeout, TimeUnit.SECONDS);
+        }
+        return false;
+    }
+
+    /**
+     * 设置有效时间
+     *
+     * @param key     Redis键
+     * @param timeout 超时时间
+     * @param unit    时间单位
+     * @return true=设置成功;false=设置失败
+     */
+    public boolean expire(final String key, final long timeout, final TimeUnit unit) {
+        return redisTemplate.expire(key, timeout, unit);
+    }
+
+    /**
+     * 获得缓存的基本对象。
+     *
+     * @param key 缓存键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> T getCacheObject(final String key) {
+        ValueOperations<String, T> operation = redisTemplate.opsForValue();
+        return operation.get(key);
+    }
+
+    /**
+     * 删除单个对象
+     *
+     * @param key
+     */
+    public boolean deleteObject(final String key) {
+        return redisTemplate.delete(key);
+    }
+
+    /**
+     * 删除集合对象
+     *
+     * @param collection 多个对象
+     * @return
+     */
+    public boolean deleteObject(final Collection collection) {
+        return redisTemplate.delete(collection) > 0;
+    }
+
+    /**
+     * 缓存List数据
+     *
+     * @param key      缓存的键值
+     * @param dataList 待缓存的List数据
+     * @return 缓存的对象
+     */
+    public <T> long setCacheList(final String key, final List<T> dataList) {
+        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
+        return count == null ? 0 : count;
+    }
+
+    /**
+     * 获得缓存的list对象
+     *
+     * @param key 缓存的键值
+     * @return 缓存键值对应的数据
+     */
+    public <T> List<T> getCacheList(final String key) {
+        return redisTemplate.opsForList().range(key, 0, -1);
+    }
+
+    /**
+     * 缓存Set
+     *
+     * @param key     缓存键值
+     * @param dataSet 缓存的数据
+     * @return 缓存数据的对象
+     */
+    public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {
+        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
+        Iterator<T> it = dataSet.iterator();
+        while (it.hasNext()) {
+            setOperation.add(it.next());
+        }
+        return setOperation;
+    }
+
+    /**
+     * 获得缓存的set
+     *
+     * @param key
+     * @return
+     */
+    public <T> Set<T> getCacheSet(final String key) {
+        return redisTemplate.opsForSet().members(key);
+    }
+
+    /**
+     * 缓存Map
+     *
+     * @param key
+     * @param dataMap
+     */
+    public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
+        if (dataMap != null) {
+            redisTemplate.opsForHash().putAll(key, dataMap);
+        }
+    }
+
+    /**
+     * 获得缓存的Map
+     *
+     * @param key
+     * @return
+     */
+    public <T> Map<String, T> getCacheMap(final String key) {
+        return redisTemplate.opsForHash().entries(key);
+    }
+    /**
+     * 获得缓存的集合
+     *
+     * @param key
+     * @return
+     */
+    public <T> List<T>  getCacheObjList(final String key) {
+        return redisTemplate.opsForHash().values(key);
+    }
+
+    /**
+     * 往Hash中存入数据
+     *
+     * @param key   Redis键
+     * @param hKey  Hash键
+     * @param value 值
+     */
+    public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
+        redisTemplate.opsForHash().put(key, hKey, value);
+    }
+
+    /**
+     * 删除map中的数据
+     *
+     * @param key   Redis键
+     * @param hKeys hKeys
+     */
+    public boolean deleteCacheMapValue(final String key, final String... hKeys) {
+        return redisTemplate.opsForHash().delete(key, hKeys) > 0;
+    }
+
+    /**
+     * 获取Hash中的数据
+     *
+     * @param key  Redis键
+     * @param hKey Hash键
+     * @return Hash中的对象
+     */
+    public <T> T getCacheMapValue(final String key, final String hKey) {
+        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
+        return opsForHash.get(key, hKey);
+    }
+
+    /**
+     * 获得缓存的基本对象列表
+     *
+     * @param key 字符串前缀
+     * @return 对象列表
+     */
+    public Collection<String> getCacheMapKeys(final String key) {
+        return redisTemplate.opsForHash().keys(key);
+    }
+
+    /**
+     * 获取多个Hash中的数据
+     *
+     * @param key   Redis键
+     * @param hKeys Hash键集合
+     * @return Hash对象集合
+     */
+    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
+        return redisTemplate.opsForHash().multiGet(key, hKeys);
+    }
+
+    /**
+     * 获得缓存的基本对象列表
+     *
+     * @param pattern 字符串前缀
+     * @return 对象列表
+     */
+    public Collection<String> keys(final String pattern) {
+        return redisTemplate.keys(pattern);
+    }
+
+
+    /**
+     * 获取Hash中的数据
+     *
+     * @param key  Redis键
+     * @param hKey Hash键
+     * @return Hash中的对象
+     */
+    public <T> T getCacheMapValue(final String key, final String hKey, Callable<T> valueLoader) {
+        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
+        Object cacheObj = opsForHash.get(key, hKey);
+        Object value = null;
+        if (cacheObj == null) {
+            T call = getCallValue(valueLoader);
+            if(null != call){
+                value = call;
+                redisTemplate.opsForHash().put(key, hKey, value);
+                return(T) value;
+            }else{
+                return null;
+            }
+        } else {
+            return (T) cacheObj;
+        }
+    }
+
+    /**
+     * 动态方法执行
+     * @param valueLoader
+     * @param <T>
+     * @return
+     */
+    public <T> T getCallValue(Callable<T> valueLoader) {
+        try {
+            T call = valueLoader.call();
+            if (ObjectUtils.isNotEmpty(call)) {
+                Field field = ReflectUtils.getField(call.getClass(), "id");
+                if (ObjectUtils.isNotEmpty(field) && ObjectUtils.isEmpty(ClassUtils.getMethod(call.getClass(), "id").invoke(call))) {
+                    return null;
+                }
+                return call;
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            return null;
+        }
+        return null;
+    }
+
+    /**
+     * 获取有效时间
+     *
+     * @param key Redis键
+     * @return 有效时间
+     */
+    public long getExpire(String key) {
+        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 判断 key是否存在
+     *
+     * @param key 键
+     * @return true 存在 false不存在
+     */
+    public boolean hasKey(String key) {
+        return redisTemplate.hasKey(key);
+    }
+
+    public boolean deleteKey(String... key) {
+        if (key != null) {
+            int length = key.length;
+            if (length > 0) {
+                if (length == 1) {
+                    return redisTemplate.delete(key[0]);
+                } else {
+                    return redisTemplate.delete(CollectionUtils.arrayToList(key)) == length;
+                }
+            }
+        }
+        return false;
+    }
+
+    //============================Value=============================
+
+    public Object get(String key) {
+        return StringUtils.isBlank(key) ? null : valueOperations.get(key);
+    }
+
+    public String getStringValue(String key) {
+        return StringUtils.isBlank(key) ? null : (String) valueOperations.get(key);
+    }
+
+    public void set(String key, Object value) {
+        valueOperations.set(key, value);
+    }
+
+    public void set(String key, Object value, long milliseconds) {
+        valueOperations.set(key, value, milliseconds, TimeUnit.MILLISECONDS);
+    }
+
+    public long incr(String key) {
+        return valueOperations.increment(key);
+    }
+
+    public long decr(String key) {
+        return valueOperations.decrement(key);
+    }
+
+    //================================hash=================================
+
+    public Object hashGet(String key, String item) {
+        return hashOperations.get(key, item);
+    }
+
+    public Map<Object, Object> hashGetAll(String key) {
+        return hashOperations.entries(key);
+    }
+
+    public void hmSet(String key, Map<String, Object> map) {
+        hashOperations.putAll(key, map);
+    }
+
+    public boolean hmSet(String key, Map<String, Object> map, long milliseconds) {
+        hmSet(key, map);
+        if (milliseconds > 0) {
+            return expire(key, milliseconds);
+        }
+        return false;
+
+    }
+
+    public void hashSet(String key, String item, Object value) {
+        hashOperations.put(key, item, value);
+    }
+
+    public void hashDelete(String key, Object... item) {
+        hashOperations.delete(key, item);
+    }
+
+    public boolean hashHasKey(String key, String item) {
+        return hashOperations.hasKey(key, item);
+    }
+
+    //============================set=============================
+
+    public Set<Object> setMembers(String key) {
+        return setOperations.members(key);
+    }
+
+    public boolean setIsMember(String key, Object value) {
+        return setOperations.isMember(key, value);
+    }
+
+    public long setAdd(String key, Object... values) {
+        return setOperations.add(key, values);
+    }
+
+    public long setAdd(String key, long milliseconds, Object... values) {
+        Long count = setOperations.add(key, values);
+        if (milliseconds > 0) {
+            expire(key, milliseconds);
+        }
+        return count;
+    }
+
+    public long setSize(String key) {
+        return setOperations.size(key);
+    }
+
+    public long setRemove(String key, Object... values) {
+        return setOperations.remove(key, values);
+    }
+
+    //===============================list=================================
+
+    public List<Object> lGet(String key, long start, long end) {
+        return listOperations.range(key, start, end);
+    }
+
+    public long listSize(String key) {
+        return listOperations.size(key);
+    }
+
+    public Object listIndex(String key, long index) {
+        return listOperations.index(key, index);
+    }
+
+    public void listRightPush(String key, Object value) {
+        listOperations.rightPush(key, value);
+    }
+
+    public boolean listRightPush(String key, Object value, long milliseconds) {
+        listOperations.rightPush(key, value);
+        if (milliseconds > 0) {
+            return expire(key, milliseconds);
+        }
+        return false;
+    }
+
+    public long listRightPushAll(String key, List<Object> value) {
+        return listOperations.rightPushAll(key, value);
+    }
+
+    public boolean listRightPushAll(String key, List<Object> value, long milliseconds) {
+        listOperations.rightPushAll(key, value);
+        if (milliseconds > 0) {
+            return expire(key, milliseconds);
+        }
+        return false;
+    }
+
+    public void listSet(String key, long index, Object value) {
+        listOperations.set(key, index, value);
+    }
+
+    public long listRemove(String key, long count, Object value) {
+        return listOperations.remove(key, count, value);
+    }
+
+    //===============================zset=================================
+
+    public boolean zsAdd(String key, Object value, double score) {
+        return zSetOperations.add(key, value, score);
+    }
+
+}

+ 320 - 0
aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/Base64.java

@@ -0,0 +1,320 @@
+package com.aidex.common.core.shiroSecurity;
+
+public final class Base64 {
+
+    public Base64() {
+    }
+
+    public static byte[] decode(byte bytes[]) {
+        return decode(bytes, 0, bytes.length, 0);
+    }
+
+    public static byte[] encode(byte bytes[]) {
+        return encodeBytesToBytes(bytes, 0, bytes.length, 0);
+    }
+
+    public static boolean isBase64(byte bytes[]) {
+        try {
+            decode(bytes);
+        } catch (Exception e) {
+            return false;
+        }
+        return true;
+    }
+
+    private static final byte[] getAlphabet(int options) {
+        if ((options & 16) == 16) {
+            return _URL_SAFE_ALPHABET;
+        }
+        if ((options & 32) == 32) {
+            return _ORDERED_ALPHABET;
+        } else {
+            return _STANDARD_ALPHABET;
+        }
+    }
+
+    private static final byte[] getDecodabet(int options) {
+        if ((options & 16) == 16) {
+            return _URL_SAFE_DECODABET;
+        }
+        if ((options & 32) == 32) {
+            return _ORDERED_DECODABET;
+        } else {
+            return _STANDARD_DECODABET;
+        }
+    }
+
+    private static byte[] encode3to4(byte source[], int srcOffset, int numSigBytes, byte destination[], int destOffset, int options) {
+        byte ALPHABET[] = getAlphabet(options);
+        int inBuff = (numSigBytes <= 0 ? 0 : (source[srcOffset] << 24) >>> 8) | (numSigBytes <= 1 ? 0 : (source[srcOffset + 1] << 24) >>> 16) | (numSigBytes <= 2 ? 0 : (source[srcOffset + 2] << 24) >>> 24);
+        switch (numSigBytes) {
+            case 3: // '\003'
+                destination[destOffset] = ALPHABET[inBuff >>> 18];
+                destination[destOffset + 1] = ALPHABET[inBuff >>> 12 & 63];
+                destination[destOffset + 2] = ALPHABET[inBuff >>> 6 & 63];
+                destination[destOffset + 3] = ALPHABET[inBuff & 63];
+                return destination;
+
+            case 2: // '\002'
+                destination[destOffset] = ALPHABET[inBuff >>> 18];
+                destination[destOffset + 1] = ALPHABET[inBuff >>> 12 & 63];
+                destination[destOffset + 2] = ALPHABET[inBuff >>> 6 & 63];
+                destination[destOffset + 3] = 61;
+                return destination;
+
+            case 1: // '\001'
+                destination[destOffset] = ALPHABET[inBuff >>> 18];
+                destination[destOffset + 1] = ALPHABET[inBuff >>> 12 & 63];
+                destination[destOffset + 2] = 61;
+                destination[destOffset + 3] = 61;
+                return destination;
+        }
+        return destination;
+    }
+
+    private static byte[] encodeBytesToBytes(byte source[], int off, int len, int options) {
+        if (source == null) {
+            throw new NullPointerException("Cannot serialize a null array.");
+        }
+        if (off < 0) {
+            throw new IllegalArgumentException((new StringBuilder()).append("Cannot have negative offset: ").append(off).toString());
+        }
+        if (len < 0) {
+            throw new IllegalArgumentException((new StringBuilder()).append("Cannot have length offset: ").append(len).toString());
+        }
+        if (off + len > source.length) {
+            throw new IllegalArgumentException(String.format("Cannot have offset of %d and length of %d with array of length %d", new Object[]{
+                    Integer.valueOf(off), Integer.valueOf(len), Integer.valueOf(source.length)
+            }));
+        }
+        boolean breakLines = (options & 8) > 0;
+        int encLen = (len / 3) * 4 + (len % 3 <= 0 ? 0 : 4);
+        if (breakLines) {
+            encLen += encLen / 76;
+        }
+        byte outBuff[] = new byte[encLen];
+        int d = 0;
+        int e = 0;
+        int len2 = len - 2;
+        int lineLength = 0;
+        while (d < len2) {
+            encode3to4(source, d + off, 3, outBuff, e, options);
+            lineLength += 4;
+            if (breakLines && lineLength >= 76) {
+                outBuff[e + 4] = 10;
+                e++;
+                lineLength = 0;
+            }
+            d += 3;
+            e += 4;
+        }
+        if (d < len) {
+            encode3to4(source, d + off, len - d, outBuff, e, options);
+            e += 4;
+        }
+        if (e <= outBuff.length - 1) {
+            byte finalOut[] = new byte[e];
+            System.arraycopy(outBuff, 0, finalOut, 0, e);
+            return finalOut;
+        } else {
+            return outBuff;
+        }
+    }
+
+    private static int decode4to3(byte source[], int srcOffset, byte destination[], int destOffset, int options) {
+        if (source == null){
+            throw new NullPointerException("Source array was null.");}
+        if (destination == null){
+            throw new NullPointerException("Destination array was null.");}
+        if (srcOffset < 0 || srcOffset + 3 >= source.length){
+            throw new IllegalArgumentException(String.format("Source array with length %d cannot have offset of %d and still process four bytes.", new Object[]{
+                    Integer.valueOf(source.length), Integer.valueOf(srcOffset)
+            }));}
+        if (destOffset < 0 || destOffset + 2 >= destination.length){
+            throw new IllegalArgumentException(String.format("Destination array with length %d cannot have offset of %d and still store three bytes.", new Object[]{
+                    Integer.valueOf(destination.length), Integer.valueOf(destOffset)
+            }));}
+        byte DECODABET[] = getDecodabet(options);
+        if (source[srcOffset + 2] == 61) {
+            int outBuff = (DECODABET[source[srcOffset]] & 255) << 18 | (DECODABET[source[srcOffset + 1]] & 255) << 12;
+            destination[destOffset] = (byte) (outBuff >>> 16);
+            return 1;
+        }
+        if (source[srcOffset + 3] == 61) {
+            int outBuff = (DECODABET[source[srcOffset]] & 255) << 18 | (DECODABET[source[srcOffset + 1]] & 255) << 12 | (DECODABET[source[srcOffset + 2]] & 255) << 6;
+            destination[destOffset] = (byte) (outBuff >>> 16);
+            destination[destOffset + 1] = (byte) (outBuff >>> 8);
+            return 2;
+        } else {
+            int outBuff = (DECODABET[source[srcOffset]] & 255) << 18 | (DECODABET[source[srcOffset + 1]] & 255) << 12 | (DECODABET[source[srcOffset + 2]] & 255) << 6 | DECODABET[source[srcOffset + 3]] & 255;
+            destination[destOffset] = (byte) (outBuff >> 16);
+            destination[destOffset + 1] = (byte) (outBuff >> 8);
+            destination[destOffset + 2] = (byte) outBuff;
+            return 3;
+        }
+    }
+
+    private static byte[] decode(byte source[], int off, int len, int options) {
+        if (source == null){
+            throw new NullPointerException("Cannot decode null source array.");}
+        if (off < 0 || off + len > source.length){
+            throw new IllegalArgumentException(String.format("Source array with length %d cannot have offset of %d and process %d bytes.", new Object[]{
+                    Integer.valueOf(source.length), Integer.valueOf(off), Integer.valueOf(len)
+            }));}
+        if (len == 0){
+            return new byte[0];}
+        if (len < 4){
+            throw new IllegalArgumentException((new StringBuilder()).append("Base64-encoded string must have at least four characters, but length specified was ").append(len).toString());}
+        byte DECODABET[] = getDecodabet(options);
+        int len34 = (len * 3) / 4;
+        byte outBuff[] = new byte[len34];
+        int outBuffPosn = 0;
+        byte b4[] = new byte[4];
+        int b4Posn = 0;
+        int i = 0;
+        byte sbiDecode = 0;
+        for (i = off; i < off + len; i++) {
+            sbiDecode = DECODABET[source[i] & 255];
+            if (sbiDecode >= -5) {
+                if (sbiDecode < -1){
+                    continue;}
+                b4[b4Posn++] = source[i];
+                if (b4Posn <= 3){
+                    continue;}
+                outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, options);
+                b4Posn = 0;
+                if (source[i] == 61){
+                    break;}
+            } else {
+            }
+        }
+
+        byte out[] = new byte[outBuffPosn];
+        System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
+        return out;
+    }
+
+    public static final int NO_OPTIONS = 0;
+    public static final int ENCODE = 1;
+    public static final int DECODE = 0;
+    public static final int DO_BREAK_LINES = 8;
+    public static final int URL_SAFE = 16;
+    public static final int ORDERED = 32;
+    private static final int MAX_LINE_LENGTH = 76;
+    private static final byte EQUALS_SIGN = 61;
+    private static final byte NEW_LINE = 10;
+    private static final byte WHITE_SPACE_ENC = -5;
+    private static final byte EQUALS_SIGN_ENC = -1;
+    private static final byte _STANDARD_ALPHABET[] = {
+            65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+            75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+            85, 86, 87, 88, 89, 90, 97, 98, 99, 100,
+            101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+            111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+            121, 122, 48, 49, 50, 51, 52, 53, 54, 55,
+            56, 57, 43, 47
+    };
+    private static final byte _STANDARD_DECODABET[] = {
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -5,
+            -5, -9, -9, -5, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -5, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, 62, -9, -9, -9, 63, 52, 53,
+            54, 55, 56, 57, 58, 59, 60, 61, -9, -9,
+            -9, -1, -9, -9, -9, 0, 1, 2, 3, 4,
+            5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+            15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+            25, -9, -9, -9, -9, -9, -9, 26, 27, 28,
+            29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+            39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+            49, 50, 51, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9
+    };
+    private static final byte _URL_SAFE_ALPHABET[] = {
+            65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+            75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+            85, 86, 87, 88, 89, 90, 97, 98, 99, 100,
+            101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+            111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+            121, 122, 48, 49, 50, 51, 52, 53, 54, 55,
+            56, 57, 45, 95
+    };
+    private static final byte _URL_SAFE_DECODABET[] = {
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -5,
+            -5, -9, -9, -5, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -5, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, 62, -9, -9, 52, 53,
+            54, 55, 56, 57, 58, 59, 60, 61, -9, -9,
+            -9, -1, -9, -9, -9, 0, 1, 2, 3, 4,
+            5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+            15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+            25, -9, -9, -9, -9, 63, -9, 26, 27, 28,
+            29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+            39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+            49, 50, 51, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9
+    };
+    private static final byte _ORDERED_ALPHABET[] = {
+            45, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+            57, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+            74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+            84, 85, 86, 87, 88, 89, 90, 95, 97, 98,
+            99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+            109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
+            119, 120, 121, 122
+    };
+    private static final byte _ORDERED_DECODABET[] = {
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -5,
+            -5, -9, -9, -5, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -5, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, 0, -9, -9, 1, 2,
+            3, 4, 5, 6, 7, 8, 9, 10, -9, -9,
+            -9, -1, -9, -9, -9, 11, 12, 13, 14, 15,
+            16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+            26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+            36, -9, -9, -9, -9, 37, -9, 38, 39, 40,
+            41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+            51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+            61, 62, 63, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9,
+            -9, -9, -9, -9, -9, -9, -9
+    };
+
+}

+ 23 - 0
aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/BaseDigestPasswordEncoder.java

@@ -0,0 +1,23 @@
+package com.aidex.common.core.shiroSecurity;
+
+
+public abstract class BaseDigestPasswordEncoder extends BasePasswordEncoder
+{
+
+    public BaseDigestPasswordEncoder()
+    {
+        encodeHashAsBase64 = false;
+    }
+
+    public boolean getEncodeHashAsBase64()
+    {
+        return encodeHashAsBase64;
+    }
+
+    public void setEncodeHashAsBase64(boolean encodeHashAsBase64)
+    {
+        this.encodeHashAsBase64 = encodeHashAsBase64;
+    }
+
+    private boolean encodeHashAsBase64;
+}

+ 44 - 0
aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/BasePasswordEncoder.java

@@ -0,0 +1,44 @@
+package com.aidex.common.core.shiroSecurity;
+
+
+public abstract class BasePasswordEncoder implements PasswordEncoder {
+
+    public BasePasswordEncoder() {
+    }
+
+    protected String[] demergePasswordAndSalt(String mergedPasswordSalt) {
+        if (mergedPasswordSalt == null || "".equals(mergedPasswordSalt)) {
+            throw new IllegalArgumentException(
+                    "Cannot pass a null or empty String");
+        }
+        String password = mergedPasswordSalt;
+        String salt = "";
+        int saltBegins = mergedPasswordSalt.lastIndexOf("{");
+        if (saltBegins != -1 && saltBegins + 1 < mergedPasswordSalt.length()) {
+            salt = mergedPasswordSalt.substring(saltBegins + 1,
+                    mergedPasswordSalt.length() - 1);
+            password = mergedPasswordSalt.substring(0, saltBegins);
+        }
+        return (new String[]{password, salt});
+    }
+
+    protected String mergePasswordAndSalt(String password, Object salt,
+                                          boolean strict) {
+        if (password == null) {
+            password = "";
+        }
+        if (strict
+                && salt != null
+                && (salt.toString().lastIndexOf("{") != -1 || salt.toString()
+                .lastIndexOf("}") != -1)) {
+            throw new IllegalArgumentException(
+                    "Cannot use { or } in salt.toString()");
+        }
+        if (salt == null || "".equals(salt)) {
+            return password;
+        } else {
+            return (new StringBuilder()).append(password).append("{")
+                    .append(salt.toString()).append("}").toString();
+        }
+    }
+}

+ 29 - 0
aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/Hex.java

@@ -0,0 +1,29 @@
+package com.aidex.common.core.shiroSecurity;
+
+public final class Hex
+{
+
+    public Hex()
+    {
+    }
+
+    public static char[] encode(byte bytes[])
+    {
+        int nBytes = bytes.length;
+        char result[] = new char[2 * nBytes];
+        int j = 0;
+        for(int i = 0; i < nBytes; i++)
+        {
+            result[j++] = HEX[(240 & bytes[i]) >>> 4];
+            result[j++] = HEX[15 & bytes[i]];
+        }
+
+        return result;
+    }
+
+    private static final char HEX[] = {
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
+        'a', 'b', 'c', 'd', 'e', 'f'
+    };
+
+}

+ 84 - 0
aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/MessageDigestPasswordEncoder.java

@@ -0,0 +1,84 @@
+package com.aidex.common.core.shiroSecurity;
+
+import org.springframework.util.Assert;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class MessageDigestPasswordEncoder extends BaseDigestPasswordEncoder
+{
+
+    public MessageDigestPasswordEncoder(String algorithm)
+    {
+        this(algorithm, false);
+    }
+
+    public MessageDigestPasswordEncoder(String algorithm, boolean encodeHashAsBase64)
+        throws IllegalArgumentException
+    {
+        iterations = 1;
+        this.algorithm = algorithm;
+        setEncodeHashAsBase64(encodeHashAsBase64);
+        getMessageDigest();
+    }
+
+    @Override
+    public String encodePassword(String rawPass, Object salt)
+    {
+        String saltedPass = mergePasswordAndSalt(rawPass, salt, false);
+        MessageDigest messageDigest = getMessageDigest();
+        byte digest[];
+        try
+        {
+            digest = messageDigest.digest(saltedPass.getBytes("UTF-8"));
+        }
+        catch(UnsupportedEncodingException e)
+        {
+            throw new IllegalStateException("UTF-8 not supported!");
+        }
+        for(int i = 1; i < iterations; i++){
+            digest = messageDigest.digest(digest);}
+
+        if(getEncodeHashAsBase64()){
+            return Utf8.decode(Base64.encode(digest));}
+        else{
+            return new String(Hex.encode(digest));}
+    }
+
+    protected final MessageDigest getMessageDigest()
+        throws IllegalArgumentException
+    {
+        try
+        {
+            return MessageDigest.getInstance(algorithm);
+        }
+        catch(NoSuchAlgorithmException e)
+        {
+            throw new IllegalArgumentException((new StringBuilder()).append("No such algorithm [").append(algorithm).append("]").toString());
+        }
+    }
+
+    @Override
+    public boolean isPasswordValid(String encPass, String rawPass, Object salt)
+    {
+        String pass1 = (new StringBuilder()).append("").append(encPass).toString();
+        String pass2 = encodePassword(rawPass, salt);
+        return pass1.equals(pass2);
+        //return PasswordEncoderUtils.equals(pass1, pass2);
+    }
+
+    public String getAlgorithm()
+    {
+        return algorithm;
+    }
+
+    public void setIterations(int iterations)
+    {
+        Assert.isTrue(iterations > 0, "Iterations value must be greater than zero");
+        this.iterations = iterations;
+    }
+
+    private final String algorithm;
+    private int iterations;
+}

+ 13 - 0
aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/PasswordEncoder.java

@@ -0,0 +1,13 @@
+package com.aidex.common.core.shiroSecurity;
+
+import org.springframework.dao.DataAccessException;
+
+public interface PasswordEncoder
+{
+
+      String encodePassword(String s, Object obj)
+        throws DataAccessException;
+
+      boolean isPasswordValid(String s, String s1, Object obj)
+        throws DataAccessException;
+}

+ 15 - 0
aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/ShaPasswordEncoder.java

@@ -0,0 +1,15 @@
+package com.aidex.common.core.shiroSecurity;
+
+public class ShaPasswordEncoder extends MessageDigestPasswordEncoder
+{
+
+    public ShaPasswordEncoder()
+    {
+        this(1);
+    }
+
+    public ShaPasswordEncoder(int strength)
+    {
+        super((new StringBuilder()).append("SHA-").append(strength).toString());
+    }
+}

+ 43 - 0
aidex-common/src/main/java/com/aidex/common/core/shiroSecurity/Utf8.java

@@ -0,0 +1,43 @@
+package com.aidex.common.core.shiroSecurity;
+
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.*;
+public final class Utf8
+{
+
+    public Utf8()
+    {
+    }
+
+    public static byte[] encode(CharSequence string)
+    {
+        try
+        {
+            ByteBuffer bytes = CHARSET.newEncoder().encode(CharBuffer.wrap(string));
+            byte copy[] = new byte[bytes.limit()];
+            System.arraycopy(bytes.array(), 0, copy, 0, bytes.limit());
+            return copy;
+        }
+        catch(CharacterCodingException e)
+        {
+            throw new IllegalArgumentException("Encoding failed", e);
+        }
+    }
+
+    public static String decode(byte bytes[])
+    {
+        try
+        {
+            return CHARSET.newDecoder().decode(ByteBuffer.wrap(bytes)).toString();
+        }
+        catch(CharacterCodingException e)
+        {
+            throw new IllegalArgumentException("Decoding failed", e);
+        }
+    }
+
+    private static final Charset CHARSET = Charset.forName("UTF-8");
+
+}

+ 86 - 0
aidex-common/src/main/java/com/aidex/common/core/text/CharsetKit.java

@@ -0,0 +1,86 @@
+package com.aidex.common.core.text;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import com.aidex.common.utils.StringUtils;
+
+/**
+ * 字符集工具类
+ * 
+ * @author ruoyi
+ */
+public class CharsetKit
+{
+    /** ISO-8859-1 */
+    public static final String ISO_8859_1 = "ISO-8859-1";
+    /** UTF-8 */
+    public static final String UTF_8 = "UTF-8";
+    /** GBK */
+    public static final String GBK = "GBK";
+
+    /** ISO-8859-1 */
+    public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
+    /** UTF-8 */
+    public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
+    /** GBK */
+    public static final Charset CHARSET_GBK = Charset.forName(GBK);
+
+    /**
+     * 转换为Charset对象
+     * 
+     * @param charset 字符集,为空则返回默认字符集
+     * @return Charset
+     */
+    public static Charset charset(String charset)
+    {
+        return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
+    }
+
+    /**
+     * 转换字符串的字符集编码
+     * 
+     * @param source 字符串
+     * @param srcCharset 源字符集,默认ISO-8859-1
+     * @param destCharset 目标字符集,默认UTF-8
+     * @return 转换后的字符集
+     */
+    public static String convert(String source, String srcCharset, String destCharset)
+    {
+        return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
+    }
+
+    /**
+     * 转换字符串的字符集编码
+     * 
+     * @param source 字符串
+     * @param srcCharset 源字符集,默认ISO-8859-1
+     * @param destCharset 目标字符集,默认UTF-8
+     * @return 转换后的字符集
+     */
+    public static String convert(String source, Charset srcCharset, Charset destCharset)
+    {
+        if (null == srcCharset)
+        {
+            srcCharset = StandardCharsets.ISO_8859_1;
+        }
+
+        if (null == destCharset)
+        {
+            destCharset = StandardCharsets.UTF_8;
+        }
+
+        if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
+        {
+            return source;
+        }
+        return new String(source.getBytes(srcCharset), destCharset);
+    }
+
+    /**
+     * @return 系统字符集编码
+     */
+    public static String systemCharset()
+    {
+        return Charset.defaultCharset().name();
+    }
+}

Разница между файлами не показана из-за своего большого размера
+ 1001 - 0
aidex-common/src/main/java/com/aidex/common/core/text/Convert.java


+ 92 - 0
aidex-common/src/main/java/com/aidex/common/core/text/StrFormatter.java

@@ -0,0 +1,92 @@
+package com.aidex.common.core.text;
+
+import com.aidex.common.utils.StringUtils;
+
+/**
+ * 字符串格式化
+ * 
+ * @author ruoyi
+ */
+public class StrFormatter
+{
+    public static final String EMPTY_JSON = "{}";
+    public static final char C_BACKSLASH = '\\';
+    public static final char C_DELIM_START = '{';
+    public static final char C_DELIM_END = '}';
+
+    /**
+     * 格式化字符串<br>
+     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
+     * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
+     * 例:<br>
+     * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
+     * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
+     * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
+     * 
+     * @param strPattern 字符串模板
+     * @param argArray 参数列表
+     * @return 结果
+     */
+    public static String format(final String strPattern, final Object... argArray)
+    {
+        if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
+        {
+            return strPattern;
+        }
+        final int strPatternLength = strPattern.length();
+
+        // 初始化定义好的长度以获得更好的性能
+        StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
+
+        int handledPosition = 0;
+        int delimIndex;// 占位符所在位置
+        for (int argIndex = 0; argIndex < argArray.length; argIndex++)
+        {
+            delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
+            if (delimIndex == -1)
+            {
+                if (handledPosition == 0)
+                {
+                    return strPattern;
+                }
+                else
+                { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
+                    sbuf.append(strPattern, handledPosition, strPatternLength);
+                    return sbuf.toString();
+                }
+            }
+            else
+            {
+                if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
+                {
+                    if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
+                    {
+                        // 转义符之前还有一个转义符,占位符依旧有效
+                        sbuf.append(strPattern, handledPosition, delimIndex - 1);
+                        sbuf.append(Convert.utf8Str(argArray[argIndex]));
+                        handledPosition = delimIndex + 2;
+                    }
+                    else
+                    {
+                        // 占位符被转义
+                        argIndex--;
+                        sbuf.append(strPattern, handledPosition, delimIndex - 1);
+                        sbuf.append(C_DELIM_START);
+                        handledPosition = delimIndex + 1;
+                    }
+                }
+                else
+                {
+                    // 正常占位符
+                    sbuf.append(strPattern, handledPosition, delimIndex);
+                    sbuf.append(Convert.utf8Str(argArray[argIndex]));
+                    handledPosition = delimIndex + 2;
+                }
+            }
+        }
+        // 加入最后一个占位符后所有的字符
+        sbuf.append(strPattern, handledPosition, strPattern.length());
+
+        return sbuf.toString();
+    }
+}

+ 20 - 0
aidex-common/src/main/java/com/aidex/common/enums/BusinessStatus.java

@@ -0,0 +1,20 @@
+package com.aidex.common.enums;
+
+/**
+ * 操作状态
+ * 
+ * @author ruoyi
+ *
+ */
+public enum BusinessStatus
+{
+    /**
+     * 成功
+     */
+    SUCCESS,
+
+    /**
+     * 失败
+     */
+    FAIL,
+}

+ 68 - 0
aidex-common/src/main/java/com/aidex/common/enums/BusinessType.java

@@ -0,0 +1,68 @@
+package com.aidex.common.enums;
+
+/**
+ * 业务操作类型
+ * 
+ * @author ruoyi
+ */
+public enum BusinessType
+{
+    /**
+     * 其它
+     */
+    OTHER,
+
+    /**
+     * 新增
+     */
+    INSERT,
+
+    /**
+     * 修改
+     */
+    UPDATE,
+    /**
+     * 删除
+     */
+    DELETE,
+
+    /**
+     * 授权
+     */
+    GRANT,
+
+    /**
+     * 导出
+     */
+    EXPORT,
+
+    /**
+     * 导入
+     */
+    IMPORT,
+
+    /**
+     * 强退
+     */
+    FORCE,
+
+    /**
+     * 生成代码
+     */
+    GENCODE,
+    
+    /**
+     * 清空数据
+     */
+    CLEAN,
+
+    /**
+     * 清空数据
+     */
+    SELECT,
+
+    /**
+     * 校验
+     */
+    CHECK,
+}

+ 19 - 0
aidex-common/src/main/java/com/aidex/common/enums/DataSourceType.java

@@ -0,0 +1,19 @@
+package com.aidex.common.enums;
+
+/**
+ * 数据源
+ * 
+ * @author ruoyi
+ */
+public enum DataSourceType
+{
+    /**
+     * 主库
+     */
+    MASTER,
+
+    /**
+     * 从库
+     */
+    SLAVE
+}

+ 36 - 0
aidex-common/src/main/java/com/aidex/common/enums/HttpMethod.java

@@ -0,0 +1,36 @@
+package com.aidex.common.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.springframework.lang.Nullable;
+
+/**
+ * 请求方式
+ *
+ * @author ruoyi
+ */
+public enum HttpMethod
+{
+    GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
+
+    private static final Map<String, HttpMethod> MAPPINGS = new HashMap<>(16);
+
+    static
+    {
+        for (HttpMethod httpMethod : values())
+        {
+            MAPPINGS.put(httpMethod.name(), httpMethod);
+        }
+    }
+
+    @Nullable
+    public static HttpMethod resolve(@Nullable String method)
+    {
+        return (method != null ? MAPPINGS.get(method) : null);
+    }
+
+    public boolean matches(String method)
+    {
+        return (this == resolve(method));
+    }
+}

+ 20 - 0
aidex-common/src/main/java/com/aidex/common/enums/LimitType.java

@@ -0,0 +1,20 @@
+package com.aidex.common.enums;
+
+/**
+ * 限流类型
+ *
+ * @author ruoyi
+ */
+
+public enum LimitType
+{
+    /**
+     * 默认策略全局限流
+     */
+    DEFAULT,
+
+    /**
+     * 根据请求者IP进行限流
+     */
+    IP
+}

+ 24 - 0
aidex-common/src/main/java/com/aidex/common/enums/OperatorType.java

@@ -0,0 +1,24 @@
+package com.aidex.common.enums;
+
+/**
+ * 操作人类别
+ * 
+ * @author ruoyi
+ */
+public enum OperatorType
+{
+    /**
+     * 其它
+     */
+    OTHER,
+
+    /**
+     * 后台用户
+     */
+    MANAGE,
+
+    /**
+     * 手机端用户
+     */
+    MOBILE
+}

+ 30 - 0
aidex-common/src/main/java/com/aidex/common/enums/UserStatus.java

@@ -0,0 +1,30 @@
+package com.aidex.common.enums;
+
+/**
+ * 用户状态
+ * 
+ * @author ruoyi
+ */
+public enum UserStatus
+{
+    OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除");
+
+    private final String code;
+    private final String info;
+
+    UserStatus(String code, String info)
+    {
+        this.code = code;
+        this.info = info;
+    }
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    public String getInfo()
+    {
+        return info;
+    }
+}

+ 129 - 0
aidex-common/src/main/java/com/aidex/common/exception/Assert.java

@@ -0,0 +1,129 @@
+package com.aidex.common.exception;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Assertion utility class that assists in validating arguments.
+ *
+ * <p>Useful for identifying programmer errors early and clearly at runtime.
+ *
+ * <p>For example, if the contract of a public method states it does not
+ * allow {@code null} arguments, {@code Assert} can be used to validate that
+ * contract.
+ *
+ * For example:
+ *
+ * <pre class="code">
+ * Assert.notNull(clazz, "The class must not be null");
+ * Assert.isTrue(i > 0, "The value must be greater than zero");</pre>
+ *
+ * This class is empowered by  {@link org.springframework.util.Assert}
+ *
+ * @author Frank Zhang
+ * @date 2019-01-13 11:49 AM
+ */
+public abstract class Assert {
+
+    /**
+     * Assert a boolean expression, throwing {@code BizException}
+     *
+     * for example
+     *
+     * <pre class="code">Assert.isTrue(i != 0, errorCode.B_ORDER_illegalNumber, "The order number can not be zero");</pre>
+     *
+     * @param expression a boolean expression
+     * @param errorCode
+     * @param errMessage the exception message to use if the assertion fails
+     * @throws BizException if expression is {@code false}
+     */
+    public static void isTrue(boolean expression, String errorCode, String errMessage) {
+        if (!expression) {
+            throw new BizException(errorCode, errMessage);
+        }
+    }
+
+    /**
+     * Assert a boolean expression, if expression is true, throwing {@code BizException}
+     *
+     * for example
+     *
+     * <pre class="code">Assert.isFalse(i == 0, errorCode.B_ORDER_illegalNumber, "The order number can not be zero");</pre>
+     *
+     * This is more intuitive than isTure.
+     */
+    public static void isFalse(boolean expression, String errorCode, String errMessage) {
+        if (expression) {
+            throw new BizException(errorCode, errMessage);
+        }
+    }
+
+    public static void isTrue(boolean expression, String errMessage) {
+        if (!expression) {
+            throw new BizException(errMessage);
+        }
+    }
+
+    public static void isFalse(boolean expression, String errMessage) {
+        if (expression) {
+            throw new BizException(errMessage);
+        }
+    }
+
+    public static void isTrue(boolean expression) {
+        isTrue(expression, "[Assertion failed] Must be true");
+    }
+
+    public static void isFalse(boolean expression) {
+        isFalse(expression, "[Assertion failed] Must be false");
+    }
+
+    public static void notNull(Object object, String errorCode, String errMessage) {
+        if (object == null) {
+            throw new BizException(errorCode, errMessage);
+        }
+    }
+
+    public static void notNull(Object object, String errMessage) {
+        if (object == null) {
+            throw new BizException(errMessage);
+        }
+    }
+
+    public static void notNull(Object object) {
+        notNull(object, "[Assertion failed] Must not null");
+    }
+
+    public static void notEmpty(Collection<?> collection, String errorCode, String errMessage) {
+        if (collection == null || collection.size() <= 0) {
+            throw new BizException(errorCode, errMessage);
+        }
+    }
+
+    public static void notEmpty(Collection<?> collection, String errMessage) {
+        if (collection == null || collection.size() <= 0) {
+            throw new BizException(errMessage);
+        }
+    }
+
+    public static void notEmpty(Collection<?> collection) {
+        notEmpty(collection, "[Assertion failed] Collection must not be empty: it must contain at least 1 element");
+    }
+
+    public static void notEmpty(Map<?, ?> map, String errorCode, String errMessage) {
+        if (map == null || map.isEmpty()) {
+            throw new BizException(errorCode, errMessage);
+        }
+    }
+
+    public static void notEmpty(Map<?, ?> map, String errMessage) {
+        if (map == null || map.isEmpty()) {
+            throw new BizException(errMessage);
+        }
+    }
+
+    public static void notEmpty(Map<?, ?> map) {
+        notEmpty(map, "[Assertion failed] Map must not be empty: it must contain at least one entry");
+    }
+
+}

+ 128 - 0
aidex-common/src/main/java/com/aidex/common/exception/BaseException.java

@@ -0,0 +1,128 @@
+package com.aidex.common.exception;
+
+import com.aidex.common.utils.MessageUtils;
+import com.aidex.common.utils.StringUtils;
+
+/**
+ * 基础异常
+ * 
+ * @author ruoyi
+ */
+public class BaseException extends RuntimeException
+{
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 所属模块
+     */
+    private String module;
+
+    /**
+     * 错误码
+     */
+    private String code;
+
+    private String message;
+
+    /**
+     * 错误码对应的参数
+     */
+    private Object[] args;
+
+    /**
+     * 错误消息
+     */
+    private String defaultMessage;
+
+    public BaseException(String module, String code, Object[] args, String defaultMessage)
+    {
+        this.module = module;
+        this.code = code;
+        this.args = args;
+        this.defaultMessage = defaultMessage;
+    }
+
+    public BaseException(String module, String code, Object[] args)
+    {
+        this(module, code, args, null);
+    }
+
+
+    public BaseException(String code, Object[] args)
+    {
+        this(null, code, args, null);
+    }
+
+
+    @Override
+    public String getMessage()
+    {
+
+        if(!StringUtils.isEmpty(this.message)){
+            return message;
+        }else{
+            String message = null;
+            if (!StringUtils.isEmpty(code))
+            {
+                message = MessageUtils.message(code, args);
+            }
+            if (message == null)
+            {
+                message = defaultMessage;
+            }
+            return message;
+        }
+    }
+
+    public String getModule()
+    {
+        return module;
+    }
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    public Object[] getArgs()
+    {
+        return args;
+    }
+
+    public String getDefaultMessage()
+    {
+        return defaultMessage;
+    }
+
+    private String errCode;
+
+    public BaseException(String errMessage) {
+        super(errMessage);
+    }
+
+    public BaseException(String errCode, String errMessage) {
+        super(errMessage);
+        this.message = errMessage;
+        this.errCode = errCode;
+    }
+
+    public BaseException(String errMessage, Throwable e) {
+        super(errMessage, e);
+    }
+
+    public BaseException(String errCode, String errMessage, Throwable e) {
+        super(errMessage, e);
+        this.errCode = errCode;
+    }
+
+    public String getErrCode() {
+        return errCode;
+    }
+
+    public void setErrCode(String errCode) {
+        this.errCode = errCode;
+    }
+
+
+
+}

+ 57 - 0
aidex-common/src/main/java/com/aidex/common/exception/BizException.java

@@ -0,0 +1,57 @@
+package com.aidex.common.exception;
+
+/**
+ * BizException is known Exception, no need retry
+ *
+ * @author Frank Zhang
+ */
+public class BizException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String DEFAULT_ERR_CODE = "BIZ_ERROR";
+
+    private String errCode;
+
+    private String errDesc;
+
+    public BizException(String errCode, String errDesc) {
+        super(errDesc);
+        this.errCode = errCode;
+        this.errDesc = errDesc;
+    }
+
+    public BizException(ErrorCodeI errorCode) {
+        super(errorCode.getErrDesc());
+        this.errCode = errorCode.getErrCode();
+        this.errDesc = errorCode.getErrDesc();
+    }
+
+    public BizException(ErrorCodeI errorCode,String errDesc) {
+        super(errorCode.getErrDesc());
+        this.errCode = errorCode.getErrCode();
+        this.errDesc = errDesc;
+    }
+
+    public BizException(String errDesc) {
+        super(errDesc);
+        this.errCode = DEFAULT_ERR_CODE;
+        this.errDesc = errDesc;
+    }
+
+    public String getErrCode() {
+        return errCode;
+    }
+
+    public void setErrCode(String errCode) {
+        this.errCode = errCode;
+    }
+
+    public String getErrDesc() {
+        return errDesc;
+    }
+
+    public void setErrDesc(String errDesc) {
+        this.errDesc = errDesc;
+    }
+}

+ 43 - 0
aidex-common/src/main/java/com/aidex/common/exception/CustomException.java

@@ -0,0 +1,43 @@
+package com.aidex.common.exception;
+
+/**
+ * 自定义异常
+ * 
+ * @author ruoyi
+ */
+public class CustomException extends RuntimeException
+{
+    private static final long serialVersionUID = 1L;
+
+    private Integer code;
+
+    private String message;
+
+    public CustomException(String message)
+    {
+        this.message = message;
+    }
+
+    public CustomException(String message, Integer code)
+    {
+        this.message = message;
+        this.code = code;
+    }
+
+    public CustomException(String message, Throwable e)
+    {
+        super(message, e);
+        this.message = message;
+    }
+
+    @Override
+    public String getMessage()
+    {
+        return message;
+    }
+
+    public Integer getCode()
+    {
+        return code;
+    }
+}

+ 15 - 0
aidex-common/src/main/java/com/aidex/common/exception/DemoModeException.java

@@ -0,0 +1,15 @@
+package com.aidex.common.exception;
+
+/**
+ * 演示模式异常
+ * 
+ * @author ruoyi
+ */
+public class DemoModeException extends RuntimeException
+{
+    private static final long serialVersionUID = 1L;
+
+    public DemoModeException()
+    {
+    }
+}

+ 14 - 0
aidex-common/src/main/java/com/aidex/common/exception/ErrorCodeI.java

@@ -0,0 +1,14 @@
+package com.aidex.common.exception;
+
+/**
+ * Extends your error codes in your App by implements this Interface.
+ *
+ * Created by fulan.zjf on 2017/12/18.
+ */
+public interface ErrorCodeI {
+
+    public String getErrCode();
+
+    public String getErrDesc();
+
+}

+ 18 - 0
aidex-common/src/main/java/com/aidex/common/exception/ExpireException.java

@@ -0,0 +1,18 @@
+package com.aidex.common.exception;
+
+public class ExpireException extends RuntimeException {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 3056819439922242913L;
+	public ExpireException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+    public ExpireException(String s) {
+        super(s);
+    }
+    @Override
+    public Throwable fillInStackTrace() {
+        return this;
+    }
+}

+ 58 - 0
aidex-common/src/main/java/com/aidex/common/exception/GlobalException.java

@@ -0,0 +1,58 @@
+package com.aidex.common.exception;
+
+/**
+ * 全局异常
+ * 
+ * @author ruoyi
+ */
+public class GlobalException extends RuntimeException
+{
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 错误提示
+     */
+    private String message;
+
+    /**
+     * 错误明细,内部调试错误
+     *
+     */
+    private String detailMessage;
+
+    /**
+     * 空构造方法,避免反序列化问题
+     */
+    public GlobalException()
+    {
+    }
+
+    public GlobalException(String message)
+    {
+        this.message = message;
+    }
+
+    public String getDetailMessage()
+    {
+        return detailMessage;
+    }
+
+    public GlobalException setDetailMessage(String detailMessage)
+    {
+        this.detailMessage = detailMessage;
+        return this;
+    }
+
+    @Override
+    public String getMessage()
+    {
+        return message;
+    }
+
+    public GlobalException setMessage(String message)
+    {
+        this.message = message;
+        return this;
+    }
+}

+ 22 - 0
aidex-common/src/main/java/com/aidex/common/exception/SysException.java

@@ -0,0 +1,22 @@
+package com.aidex.common.exception;
+
+/**
+ * System Exception is unexpected Exception, retry might work again
+ *
+ * @author Danny.Lee 2018/1/27
+ */
+public class SysException extends BaseException {
+
+    private static final long serialVersionUID = 4355163994767354840L;
+
+    private static final String DEFAULT_ERR_CODE = "SYS_ERROR";
+
+    public SysException(String errMessage) {
+        super(DEFAULT_ERR_CODE, errMessage);
+    }
+
+    public SysException(int errCode, String errMessage) {
+        super(String.valueOf(errCode), errMessage);
+    }
+
+}

+ 0 - 0
aidex-common/src/main/java/com/aidex/common/exception/UtilException.java


Некоторые файлы не были показаны из-за большого количества измененных файлов