lucky 4 mēneši atpakaļ
revīzija
7043794527
100 mainītis faili ar 12555 papildinājumiem un 0 dzēšanām
  1. BIN
      .git.zip
  2. 47 0
      .gitignore
  3. 277 0
      LICENSE
  4. 97 0
      README.md
  5. 18 0
      kdwebapi.properties
  6. 8 0
      kdwebapi1111.properties
  7. 253 0
      pom.xml
  8. 67 0
      ry.bat
  9. 86 0
      ry.sh
  10. 160 0
      zkqy-admin/pom.xml
  11. 55 0
      zkqy-admin/src/main/java/com/zkqy/ZkqyApplication.java
  12. 25 0
      zkqy-admin/src/main/java/com/zkqy/ZkqyServletInitializer.java
  13. 40 0
      zkqy-admin/src/main/java/com/zkqy/web/asd.json
  14. 24 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/TetsContro.java
  15. 23 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/Yx.java
  16. 88 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/chemicalFiber/QualityInspectionCertificateController.java
  17. 94 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/common/CaptchaController.java
  18. 395 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/common/CommonFileController.java
  19. 32 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/dragForm/DynamicController.java
  20. 4 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/dragForm/TestController.java
  21. 12 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/dragForm/TestMain.java
  22. 213 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/homepagestatistics/StatisticsController.java
  23. 120 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/monitor/CacheController.java
  24. 27 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/monitor/ServerController.java
  25. 65 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/monitor/SysActivationLogController.java
  26. 82 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/monitor/SysLogininforController.java
  27. 81 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/monitor/SysOperlogController.java
  28. 83 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/monitor/SysUserOnlineController.java
  29. 169 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/projcetzip/DownloadController.java
  30. 130 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/projcetzip/ExportController.java
  31. 80 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/DataSourceController.java
  32. 110 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/LoginPageConfigurationController.java
  33. 112 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysBpmNodeScriptController.java
  34. 133 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysConfigController.java
  35. 135 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysDeptController.java
  36. 126 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysDictDataController.java
  37. 131 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysDictTypeController.java
  38. 338 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysEngineeringController.java
  39. 29 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysIndexController.java
  40. 393 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysLoginController.java
  41. 174 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysMenuController.java
  42. 91 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysNoticeController.java
  43. 134 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysPostController.java
  44. 141 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysProfileController.java
  45. 38 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysRegisterController.java
  46. 268 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysRoleController.java
  47. 147 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysTenantController.java
  48. 353 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysUserController.java
  49. 73 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/tool/DynamicBeanRegistrar.java
  50. 32 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/tool/DynamicCompiler.java
  51. 184 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/tool/TestController.java
  52. 175 0
      zkqy-admin/src/main/java/com/zkqy/web/controller/tool/daochuController.java
  53. 125 0
      zkqy-admin/src/main/java/com/zkqy/web/core/config/SwaggerConfig.java
  54. 192 0
      zkqy-admin/src/main/java/com/zkqy/web/ljj.java
  55. 18 0
      zkqy-admin/src/main/java/com/zkqy/web/yb.java
  56. 1 0
      zkqy-admin/src/main/resources/META-INF/spring-devtools.properties
  57. 11 0
      zkqy-admin/src/main/resources/abc/TestController.java
  58. 68 0
      zkqy-admin/src/main/resources/application-druid.yml
  59. 212 0
      zkqy-admin/src/main/resources/application.yml
  60. 61 0
      zkqy-admin/src/main/resources/bak1/application-druid.yml
  61. 176 0
      zkqy-admin/src/main/resources/bak1/application.yml
  62. 24 0
      zkqy-admin/src/main/resources/banner.txt
  63. 66 0
      zkqy-admin/src/main/resources/bf1/application-druid.yml
  64. 203 0
      zkqy-admin/src/main/resources/bf1/application.yml
  65. 66 0
      zkqy-admin/src/main/resources/bf2/application-druid.yml
  66. 208 0
      zkqy-admin/src/main/resources/bf2/application.yml
  67. 66 0
      zkqy-admin/src/main/resources/bf3/application-druid.yml
  68. 203 0
      zkqy-admin/src/main/resources/bf3/application.yml
  69. 38 0
      zkqy-admin/src/main/resources/i18n/messages.properties
  70. 96 0
      zkqy-admin/src/main/resources/logback-spring.xml
  71. 43 0
      zkqy-admin/src/main/resources/mybatis/mybatis-config.xml
  72. 233 0
      zkqy-admin/src/test/java/com/zkqy/Test01.java
  73. 67 0
      zkqy-business/pom.xml
  74. 459 0
      zkqy-business/src/main/java/com/zkqy/business/controller/CommonBtnController.java
  75. 220 0
      zkqy-business/src/main/java/com/zkqy/business/controller/CommonController.java
  76. 55 0
      zkqy-business/src/main/java/com/zkqy/business/controller/DragFormController.java
  77. 49 0
      zkqy-business/src/main/java/com/zkqy/business/controller/DragTableBtnController.java
  78. 71 0
      zkqy-business/src/main/java/com/zkqy/business/controller/DragTableConditionController.java
  79. 64 0
      zkqy-business/src/main/java/com/zkqy/business/controller/DragTableController.java
  80. 72 0
      zkqy-business/src/main/java/com/zkqy/business/controller/DragTableGroupController.java
  81. 87 0
      zkqy-business/src/main/java/com/zkqy/business/controller/DragTableStatisticController.java
  82. 100 0
      zkqy-business/src/main/java/com/zkqy/business/controller/DragTableStyleController.java
  83. 219 0
      zkqy-business/src/main/java/com/zkqy/business/controller/FileManagementController.java
  84. 136 0
      zkqy-business/src/main/java/com/zkqy/business/controller/MobilePageDataController.java
  85. 118 0
      zkqy-business/src/main/java/com/zkqy/business/controller/MobilePageTableListController.java
  86. 50 0
      zkqy-business/src/main/java/com/zkqy/business/controller/TableSqlController.java
  87. 32 0
      zkqy-business/src/main/java/com/zkqy/business/entity/BlobTypeHandler.java
  88. 293 0
      zkqy-business/src/main/java/com/zkqy/business/entity/DragForm.java
  89. 267 0
      zkqy-business/src/main/java/com/zkqy/business/entity/DragTable.java
  90. 320 0
      zkqy-business/src/main/java/com/zkqy/business/entity/DragTableBtn.java
  91. 52 0
      zkqy-business/src/main/java/com/zkqy/business/entity/DragTableBtnRelevance.java
  92. 332 0
      zkqy-business/src/main/java/com/zkqy/business/entity/DragTableCondition.java
  93. 53 0
      zkqy-business/src/main/java/com/zkqy/business/entity/DragTableForm.java
  94. 123 0
      zkqy-business/src/main/java/com/zkqy/business/entity/DragTableGroup.java
  95. 153 0
      zkqy-business/src/main/java/com/zkqy/business/entity/DragTableStatistic.java
  96. 189 0
      zkqy-business/src/main/java/com/zkqy/business/entity/DragTableStyle.java
  97. 238 0
      zkqy-business/src/main/java/com/zkqy/business/entity/FileManagement.java
  98. 127 0
      zkqy-business/src/main/java/com/zkqy/business/entity/MobilePageData.java
  99. 214 0
      zkqy-business/src/main/java/com/zkqy/business/entity/MobilePageTableList.java
  100. 113 0
      zkqy-business/src/main/java/com/zkqy/business/entity/TableInfo.java

BIN
.git.zip


+ 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

+ 277 - 0
LICENSE

@@ -0,0 +1,277 @@
+Eclipse Public License - v 2.0
+
+    THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+    PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION
+    OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+  a) in the case of the initial Contributor, the initial content
+     Distributed under this Agreement, and
+
+  b) in the case of each subsequent Contributor:
+     i) changes to the Program, and
+     ii) additions to the Program;
+  where such changes and/or additions to the Program originate from
+  and are Distributed by that particular Contributor. A Contribution
+  "originates" from a Contributor if it was added to the Program by
+  such Contributor itself or anyone acting on such Contributor's behalf.
+  Contributions do not include changes or additions to the Program that
+  are not Modified Works.
+
+"Contributor" means any person or entity that Distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which
+are necessarily infringed by the use or sale of its Contribution alone
+or when combined with the Program.
+
+"Program" means the Contributions Distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement
+or any Secondary License (as applicable), including Contributors.
+
+"Derivative Works" shall mean any work, whether in Source Code or other
+form, that is based on (or derived from) the Program and for which the
+editorial revisions, annotations, elaborations, or other modifications
+represent, as a whole, an original work of authorship.
+
+"Modified Works" shall mean any work in Source Code or other form that
+results from an addition to, deletion from, or modification of the
+contents of the Program, including, for purposes of clarity any new file
+in Source Code form that contains any contents of the Program. Modified
+Works shall not include works that contain only declarations,
+interfaces, types, classes, structures, or files of the Program solely
+in each case in order to link to, bind by name, or subclass the Program
+or Modified Works thereof.
+
+"Distribute" means the acts of a) distributing or b) making available
+in any manner that enables the transfer of a copy.
+
+"Source Code" means the form of a Program preferred for making
+modifications, including but not limited to software source code,
+documentation source, and configuration files.
+
+"Secondary License" means either the GNU General Public License,
+Version 2.0, or any later versions of that license, including any
+exceptions or additional permissions as identified by the initial
+Contributor.
+
+2. GRANT OF RIGHTS
+
+  a) Subject to the terms of this Agreement, each Contributor hereby
+  grants Recipient a non-exclusive, worldwide, royalty-free copyright
+  license to reproduce, prepare Derivative Works of, publicly display,
+  publicly perform, Distribute and sublicense the Contribution of such
+  Contributor, if any, and such Derivative Works.
+
+  b) Subject to the terms of this Agreement, each Contributor hereby
+  grants Recipient a non-exclusive, worldwide, royalty-free patent
+  license under Licensed Patents to make, use, sell, offer to sell,
+  import and otherwise transfer the Contribution of such Contributor,
+  if any, in Source Code or other form. This patent license shall
+  apply to the combination of the Contribution and the Program if, at
+  the time the Contribution is added by the Contributor, such addition
+  of the Contribution causes such combination to be covered by the
+  Licensed Patents. The patent license shall not apply to any other
+  combinations which include the Contribution. No hardware per se is
+  licensed hereunder.
+
+  c) Recipient understands that although each Contributor grants the
+  licenses to its Contributions set forth herein, no assurances are
+  provided by any Contributor that the Program does not infringe the
+  patent or other intellectual property rights of any other entity.
+  Each Contributor disclaims any liability to Recipient for claims
+  brought by any other entity based on infringement of intellectual
+  property rights or otherwise. As a condition to exercising the
+  rights and licenses granted hereunder, each Recipient hereby
+  assumes sole responsibility to secure any other intellectual
+  property rights needed, if any. For example, if a third party
+  patent license is required to allow Recipient to Distribute the
+  Program, it is Recipient's responsibility to acquire that license
+  before distributing the Program.
+
+  d) Each Contributor represents that to its knowledge it has
+  sufficient copyright rights in its Contribution, if any, to grant
+  the copyright license set forth in this Agreement.
+
+  e) Notwithstanding the terms of any Secondary License, no
+  Contributor makes additional grants to any Recipient (other than
+  those set forth in this Agreement) as a result of such Recipient's
+  receipt of the Program under the terms of a Secondary License
+  (if permitted under the terms of Section 3).
+
+3. REQUIREMENTS
+
+3.1 If a Contributor Distributes the Program in any form, then:
+
+  a) the Program must also be made available as Source Code, in
+  accordance with section 3.2, and the Contributor must accompany
+  the Program with a statement that the Source Code for the Program
+  is available under this Agreement, and informs Recipients how to
+  obtain it in a reasonable manner on or through a medium customarily
+  used for software exchange; and
+
+  b) the Contributor may Distribute the Program under a license
+  different than this Agreement, provided that such license:
+     i) effectively disclaims on behalf of all other Contributors all
+     warranties and conditions, express and implied, including
+     warranties or conditions of title and non-infringement, and
+     implied warranties or conditions of merchantability and fitness
+     for a particular purpose;
+
+     ii) effectively excludes on behalf of all other Contributors all
+     liability for damages, including direct, indirect, special,
+     incidental and consequential damages, such as lost profits;
+
+     iii) does not attempt to limit or alter the recipients' rights
+     in the Source Code under section 3.2; and
+
+     iv) requires any subsequent distribution of the Program by any
+     party to be under a license that satisfies the requirements
+     of this section 3.
+
+3.2 When the Program is Distributed as Source Code:
+
+  a) it must be made available under this Agreement, or if the
+  Program (i) is combined with other material in a separate file or
+  files made available under a Secondary License, and (ii) the initial
+  Contributor attached to the Source Code the notice described in
+  Exhibit A of this Agreement, then the Program may be made available
+  under the terms of such Secondary Licenses, and
+
+  b) a copy of this Agreement must be included with each copy of
+  the Program.
+
+3.3 Contributors may not remove or alter any copyright, patent,
+trademark, attribution notices, disclaimers of warranty, or limitations
+of liability ("notices") contained within the Program from any copy of
+the Program which they Distribute, provided that Contributors may add
+their own appropriate notices.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities
+with respect to end users, business partners and the like. While this
+license is intended to facilitate the commercial use of the Program,
+the Contributor who includes the Program in a commercial product
+offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes
+the Program in a commercial product offering, such Contributor
+("Commercial Contributor") hereby agrees to defend and indemnify every
+other Contributor ("Indemnified Contributor") against any losses,
+damages and costs (collectively "Losses") arising from claims, lawsuits
+and other legal actions brought by a third party against the Indemnified
+Contributor to the extent caused by the acts or omissions of such
+Commercial Contributor in connection with its distribution of the Program
+in a commercial product offering. The obligations in this section do not
+apply to any claims or Losses relating to any actual or alleged
+intellectual property infringement. In order to qualify, an Indemnified
+Contributor must: a) promptly notify the Commercial Contributor in
+writing of such claim, and b) allow the Commercial Contributor to control,
+and cooperate with the Commercial Contributor in, the defense and any
+related settlement negotiations. The Indemnified Contributor may
+participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those performance
+claims and warranties, and if a court requires any other Contributor to
+pay any damages as a result, the Commercial Contributor must pay
+those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS"
+BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF
+TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+PURPOSE. Each Recipient is solely responsible for determining the
+appropriateness of using and distributing the Program and assumes all
+risks associated with its exercise of rights under this Agreement,
+including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs
+or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS
+SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
+EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further
+action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other software
+or hardware) infringes such Recipient's patent(s), then such Recipient's
+rights granted under Section 2(b) shall terminate as of the date such
+litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of
+time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use
+and distribution of the Program as soon as reasonably practicable.
+However, Recipient's obligations under this Agreement and any licenses
+granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement,
+but in order to avoid inconsistency the Agreement is copyrighted and
+may only be modified in the following manner. The Agreement Steward
+reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement
+Steward has the right to modify this Agreement. The Eclipse Foundation
+is the initial Agreement Steward. The Eclipse Foundation may assign the
+responsibility to serve as the Agreement Steward to a suitable separate
+entity. Each new version of the Agreement will be given a distinguishing
+version number. The Program (including Contributions) may always be
+Distributed subject to the version of the Agreement under which it was
+received. In addition, after a new version of the Agreement is published,
+Contributor may elect to Distribute the Program (including its
+Contributions) under the new version.
+
+Except as expressly stated in Sections 2(a) and 2(b) above, Recipient
+receives no rights or licenses to the intellectual property of any
+Contributor under this Agreement, whether expressly, by implication,
+estoppel or otherwise. All rights in the Program not expressly granted
+under this Agreement are reserved. Nothing in this Agreement is intended
+to be enforceable by any entity that is not a Contributor or Recipient.
+No third-party beneficiary rights are created under this Agreement.
+
+Exhibit A - Form of Secondary Licenses Notice
+
+"This Source Code may also be made available under the following
+Secondary Licenses when the conditions for such availability set forth
+in the Eclipse Public License, v. 2.0 are satisfied: {name license(s),
+version(s), and exceptions or additional permissions here}."
+
+  Simply including a copy of this Agreement, including this Exhibit A
+  is not sufficient to license the Source Code under Secondary Licenses.
+
+  If it is not possible or desirable to put the notice in a particular
+  file, then You may include the notice in a location (such as a LICENSE
+  file in a relevant directory) where a recipient would be likely to
+  look for such a notice.
+
+  You may add additional accurate notices of copyright ownership.

+ 97 - 0
README.md

@@ -0,0 +1,97 @@
+<p align="center">
+	<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
+</p>
+<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.5</h1>
+<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
+<p align="center">
+	<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
+	<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.5-brightgreen.svg"></a>
+	<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
+</p>
+
+## 平台简介
+
+若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
+
+* 前端采用Vue、Element UI。
+* 后端采用Spring Boot、Spring Security、Redis & Jwt。
+* 权限认证使用Jwt,支持多终端认证系统。
+* 支持加载动态权限菜单,多方式轻松权限控制。
+* 高效率开发,使用代码生成器可以一键生成前后端代码。
+* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。
+* 提供了单应用版本[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast),Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
+* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
+* 特别鸣谢:[element](https://github.com/ElemeFE/element),[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin),[eladmin-web](https://github.com/elunez/eladmin-web)。
+* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
+* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)&nbsp;&nbsp;
+
+## 内置功能
+
+1.  用户管理:用户是系统操作者,该功能主要完成系统用户配置。
+2.  部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
+3.  岗位管理:配置系统用户所属担任职务。
+4.  菜单管理:配置系统菜单,操作权限,按钮权限标识等。
+5.  角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
+6.  字典管理:对系统中经常使用的一些较为固定的数据进行维护。
+7.  参数管理:对系统动态配置常用参数。
+8.  通知公告:系统通知公告信息发布维护。
+9.  操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
+10. 登录日志:系统登录日志记录查询包含登录异常。
+11. 在线用户:当前系统中活跃用户状态监控。
+12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
+13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。
+14. 系统接口:根据业务代码自动生成相关的api接口文档。
+15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
+16. 缓存监控:对系统的缓存信息查询,命令统计等。
+17. 在线构建器:拖动表单元素生成相应的HTML代码。
+18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
+
+## 在线体验
+
+- admin/admin123  
+- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
+
+演示地址:http://vue.ruoyi.vip  
+文档地址:http://doc.ruoyi.vip
+
+## 演示图
+
+<table>
+    <tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
+    </tr>
+    <tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-8074972883b5ba0622e13246738ebba237a.png"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-9f88719cdfca9af2e58b352a20e23d43b12.png"/></td>
+    </tr>
+    <tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-39bf2584ec3a529b0d5a3b70d15c9b37646.png"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-936ec82d1f4872e1bc980927654b6007307.png"/></td>
+    </tr>
+	<tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-b2d62ceb95d2dd9b3fbe157bb70d26001e9.png"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-d67451d308b7a79ad6819723396f7c3d77a.png"/></td>
+    </tr>	 
+    <tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
+    </tr>
+	<tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-8370a0d02977eebf6dbf854c8450293c937.png"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-49003ed83f60f633e7153609a53a2b644f7.png"/></td>
+    </tr>
+	<tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-d4fe726319ece268d4746602c39cffc0621.png"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td>
+    </tr>
+    <tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
+    </tr>
+</table>
+
+
+## 若依前后端分离交流群
+
+QQ群: [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/已满-170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [![加入QQ群](https://img.shields.io/badge/已满-108482800-blue.svg)](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [![加入QQ群](https://img.shields.io/badge/已满-101046199-blue.svg)](https://jq.qq.com/?_wv=1027&k=SpyH2875) [![加入QQ群](https://img.shields.io/badge/136919097-blue.svg)](https://jq.qq.com/?_wv=1027&k=tKEt51dz) 点击按钮入群。

+ 18 - 0
kdwebapi.properties

@@ -0,0 +1,18 @@
+# 第三方系统登录授权的账套ID
+X-KDApi-AcctID = 66b0f368397bae
+# 第三方系统登录授权的用户
+X-KDApi-UserName= 王金明
+# 第三方系统登录授权的应用ID
+X-KDApi-AppID = 297800_541D3ztu3Oq50ewJ3ZwMTb/FVsQX6OMG
+# 第三方系统登录授权的应用密钥
+X-KDApi-AppSec = fae1bbc9a75643fdba58af17289f6edb
+# 服务Url地址(公有云统一走网关sdk底层已处理,无需传X-KDApi-ServerUrl,下面这行需要注释)X-KDApi-ServerUrl =http://192.168.2.134/K3Cloud/
+X-KDApi-ServerUrl =http://192.168.2.134/K3Cloud/
+# 账套语系,默认2052
+X-KDApi-LCID = 2052
+# 组织编码,启用多组织时配置对应的组织编码才有效
+# X-KDApi-OrgNum = 100
+# 允许的最大连接延时,单位为秒
+X-KDApi-ConnectTimeout=10000000
+# 允许的最大读取延时,单位为秒
+X-KDApi-RequestTimeout=10000000

+ 8 - 0
kdwebapi1111.properties

@@ -0,0 +1,8 @@
+X-KDApi-AcctID = 61c7dd2d0ff564
+X-KDApi-UserName = 王金明
+X-KDApi-AppID = 291472_5Z6q2/Ho6roeQaXv0d5PS61FQrTa0PNs
+X-KDApi-AppSec = 18d80a2709c7446ea44aa14b7d94e86e
+X-KDApi-ServerUrl =http://192.168.2.134/K3Cloud/
+X-KDApi-LCID = 2052
+X-KDApi-ConnectTimeout=10000000
+X-KDApi-RequestTimeout=10000000

+ 253 - 0
pom.xml

@@ -0,0 +1,253 @@
+<?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">
+	<modelVersion>4.0.0</modelVersion>
+	
+    <groupId>com.zkqy</groupId>
+    <artifactId>zkqy</artifactId>
+    <version>3.8.5</version>
+    <name>zkqy</name>
+    <description>智能制造平台</description>
+    
+    <properties>
+        <ruoyi.version>3.8.5</ruoyi.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+        <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
+        <druid.version>1.2.16</druid.version>
+        <bitwalker.version>1.21</bitwalker.version>
+        <swagger.version>3.0.0</swagger.version>
+        <kaptcha.version>2.3.3</kaptcha.version>
+        <pagehelper.boot.version>1.4.6</pagehelper.boot.version>
+        <fastjson.version>2.0.25</fastjson.version>
+        <oshi.version>6.4.0</oshi.version>
+        <commons.io.version>2.11.0</commons.io.version>
+        <commons.collections.version>3.2.2</commons.collections.version>
+        <poi.version>4.1.2</poi.version>
+        <velocity.version>2.3</velocity.version>
+        <jwt.version>0.9.1</jwt.version>
+    </properties>
+	
+    <!-- 依赖声明 -->
+    <dependencyManagement>
+        <dependencies>
+            <!-- SpringBoot的依赖配置-->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>2.5.14</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+            <!-- 阿里数据库连接池 -->
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>druid-spring-boot-starter</artifactId>
+                <version>${druid.version}</version>
+            </dependency>
+
+            <!-- 解析客户端操作系统、浏览器等 -->
+            <dependency>
+                <groupId>eu.bitwalker</groupId>
+                <artifactId>UserAgentUtils</artifactId>
+                <version>${bitwalker.version}</version>
+            </dependency>
+
+            <!-- pagehelper 分页插件 -->
+            <dependency>
+                <groupId>com.github.pagehelper</groupId>
+                <artifactId>pagehelper-spring-boot-starter</artifactId>
+                <version>${pagehelper.boot.version}</version>
+            </dependency>
+
+            <!-- 获取系统信息 -->
+            <dependency>
+                <groupId>com.github.oshi</groupId>
+                <artifactId>oshi-core</artifactId>
+                <version>${oshi.version}</version>
+            </dependency>
+
+            <!-- Swagger3依赖 -->
+            <dependency>
+                <groupId>io.springfox</groupId>
+                <artifactId>springfox-boot-starter</artifactId>
+                <version>${swagger.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>io.swagger</groupId>
+                        <artifactId>swagger-models</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+
+            <!-- io常用工具类 -->
+            <dependency>
+                <groupId>commons-io</groupId>
+                <artifactId>commons-io</artifactId>
+                <version>${commons.io.version}</version>
+            </dependency>
+
+            <!-- excel工具 -->
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi-ooxml</artifactId>
+                <version>${poi.version}</version>
+            </dependency>
+
+            <!-- velocity代码生成使用模板 -->
+            <dependency>
+                <groupId>org.apache.velocity</groupId>
+                <artifactId>velocity-engine-core</artifactId>
+                <version>${velocity.version}</version>
+            </dependency>
+
+            <!-- collections工具类 -->
+            <dependency>
+                <groupId>commons-collections</groupId>
+                <artifactId>commons-collections</artifactId>
+                <version>${commons.collections.version}</version>
+            </dependency>
+
+            <!-- 阿里JSON解析器 -->
+            <dependency>
+                <groupId>com.alibaba.fastjson2</groupId>
+                <artifactId>fastjson2</artifactId>
+                <version>${fastjson.version}</version>
+            </dependency>
+
+            <!-- Token生成与解析-->
+            <dependency>
+                <groupId>io.jsonwebtoken</groupId>
+                <artifactId>jjwt</artifactId>
+                <version>${jwt.version}</version>
+            </dependency>
+
+            <!-- 验证码 -->
+            <dependency>
+                <groupId>pro.fessional</groupId>
+                <artifactId>kaptcha</artifactId>
+                <version>${kaptcha.version}</version>
+            </dependency>
+
+
+            <!-- 核心模块-->
+            <dependency>
+                <groupId>com.zkqy</groupId>
+                <artifactId>zkqy-framework</artifactId>
+                <version>${ruoyi.version}</version>
+            </dependency>
+            <!-- 核心模块-->
+            <dependency>
+                <groupId>com.zkqy</groupId>
+                <artifactId>zkqy-business</artifactId>
+                <version>${ruoyi.version}</version>
+            </dependency>
+            <!-- 系统模块-->
+            <dependency>
+                <groupId>com.zkqy</groupId>
+                <artifactId>zkqy-system</artifactId>
+                <version>${ruoyi.version}</version>
+            </dependency>
+            <!-- 通用工具-->
+            <dependency>
+                <groupId>com.zkqy</groupId>
+                <artifactId>zkqy-common</artifactId>
+                <version>${ruoyi.version}</version>
+            </dependency>
+            <!-- mybatis-plus -->
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>mybatis-plus-boot-starter</artifactId>
+                <version>3.5.2</version>
+            </dependency>
+            <dependency>
+                <groupId>com.zkqy</groupId>
+                <artifactId>zkqy-custom-business</artifactId>
+                <version>3.8.5</version>
+            </dependency>
+            <dependency>
+                <groupId>com.zkqy</groupId>
+                <artifactId>zkqy-laboratory-information</artifactId>
+                <version>3.8.5</version>
+            </dependency>
+            <dependency>
+                <groupId>org.projectlombok</groupId>
+                <artifactId>lombok</artifactId>
+                <version>1.18.24</version>
+            </dependency>
+
+<!--            &lt;!&ndash; sqlserver 驱动 &ndash;&gt;-->
+<!--            <dependency>-->
+<!--                <groupId>com.microsoft.sqlserver</groupId>-->
+<!--                <artifactId>mssql-jdbc</artifactId>-->
+<!--                <version>10.2.3.jre8</version>-->
+<!--            </dependency>-->
+
+<!--            &lt;!&ndash; oracle 驱动 &ndash;&gt;-->
+<!--            <dependency>-->
+<!--                <groupId>com.oracle</groupId>-->
+<!--                <artifactId>ojdbc6</artifactId>-->
+<!--                <version>11.2.0.3</version>-->
+<!--            </dependency>-->
+        </dependencies>
+    </dependencyManagement>
+
+    <modules>
+        <module>zkqy-admin</module>
+        <module>zkqy-framework</module>
+        <module>zkqy-system</module>
+        <module>zkqy-common</module>
+        <module>zkqy-business</module>
+        <module>zkqy-process-execution</module>
+        <module>zkqy-custom-business</module>
+        <module>zkqy-laboratory-information</module>
+        <module>zkqy-fujian-amichi</module>
+    </modules>
+    <packaging>pom</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>3.3.2</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <!-- 达梦驱动包 -->
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.10.1</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+
+    <repositories>
+        <repository>
+            <id>public</id>
+            <name>aliyun nexus</name>
+            <url>https://maven.aliyun.com/repository/public</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>public</id>
+            <name>aliyun nexus</name>
+            <url>https://maven.aliyun.com/repository/public</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </pluginRepository>
+    </pluginRepositories>
+
+</project>

+ 67 - 0
ry.bat

@@ -0,0 +1,67 @@
+@echo off
+
+rem jar平级目录
+set AppName=ruoyi-admin.jar
+
+rem JVM参数
+set JVM_OPTS="-Dname=%AppName%  -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps  -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
+
+
+ECHO.
+	ECHO.  [1] 启动%AppName%
+	ECHO.  [2] 关闭%AppName%
+	ECHO.  [3] 重启%AppName%
+	ECHO.  [4] 启动状态 %AppName%
+	ECHO.  [5] 退 出
+ECHO.
+
+ECHO.请输入选择项目的序号:
+set /p ID=
+	IF "%id%"=="1" GOTO start
+	IF "%id%"=="2" GOTO stop
+	IF "%id%"=="3" GOTO restart
+	IF "%id%"=="4" GOTO status
+	IF "%id%"=="5" EXIT
+PAUSE
+:start
+    for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do (
+		set pid=%%a
+		set image_name=%%b
+	)
+	if  defined pid (
+		echo %%is running
+		PAUSE
+	)
+
+start javaw %JVM_OPTS% -jar %AppName%
+
+echo  starting……
+echo  Start %AppName% success...
+goto:eof
+
+rem 函数stop通过jps命令查找pid并结束进程
+:stop
+	for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do (
+		set pid=%%a
+		set image_name=%%b
+	)
+	if not defined pid (echo process %AppName% does not exists) else (
+		echo prepare to kill %image_name%
+		echo start kill %pid% ...
+		rem 根据进程ID,kill进程
+		taskkill /f /pid %pid%
+	)
+goto:eof
+:restart
+	call :stop
+    call :start
+goto:eof
+:status
+	for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do (
+		set pid=%%a
+		set image_name=%%b
+	)
+	if not defined pid (echo process %AppName% is dead ) else (
+		echo %image_name% is running
+	)
+goto:eof

+ 86 - 0
ry.sh

@@ -0,0 +1,86 @@
+#!/bin/sh
+# ./ry.sh start 启动 stop 停止 restart 重启 status 状态
+AppName=ruoyi-admin.jar
+
+# JVM参数
+JVM_OPTS="-Dname=$AppName  -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps  -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
+APP_HOME=`pwd`
+LOG_PATH=$APP_HOME/logs/$AppName.log
+
+if [ "$1" = "" ];
+then
+    echo -e "\033[0;31m 未输入操作名 \033[0m  \033[0;34m {start|stop|restart|status} \033[0m"
+    exit 1
+fi
+
+if [ "$AppName" = "" ];
+then
+    echo -e "\033[0;31m 未输入应用名 \033[0m"
+    exit 1
+fi
+
+function start()
+{
+    PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
+
+	if [ x"$PID" != x"" ]; then
+	    echo "$AppName is running..."
+	else
+		nohup java $JVM_OPTS -jar $AppName > /dev/null 2>&1 &
+		echo "Start $AppName success..."
+	fi
+}
+
+function stop()
+{
+    echo "Stop $AppName"
+
+	PID=""
+	query(){
+		PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
+	}
+
+	query
+	if [ x"$PID" != x"" ]; then
+		kill -TERM $PID
+		echo "$AppName (pid:$PID) exiting..."
+		while [ x"$PID" != x"" ]
+		do
+			sleep 1
+			query
+		done
+		echo "$AppName exited."
+	else
+		echo "$AppName already stopped."
+	fi
+}
+
+function restart()
+{
+    stop
+    sleep 2
+    start
+}
+
+function status()
+{
+    PID=`ps -ef |grep java|grep $AppName|grep -v grep|wc -l`
+    if [ $PID != 0 ];then
+        echo "$AppName is running..."
+    else
+        echo "$AppName is not running..."
+    fi
+}
+
+case $1 in
+    start)
+    start;;
+    stop)
+    stop;;
+    restart)
+    restart;;
+    status)
+    status;;
+    *)
+
+esac

+ 160 - 0
zkqy-admin/pom.xml

@@ -0,0 +1,160 @@
+<?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>zkqy</artifactId>
+        <groupId>com.zkqy</groupId>
+        <version>3.8.5</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>jar</packaging>
+    <artifactId>zkqy-admin</artifactId>
+    <name>zkqy-admin</name>
+    <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.dm</groupId>-->
+<!--            <artifactId>DmJdbcDriver18</artifactId>-->
+<!--            <version>1.8</version>-->
+<!--            <scope>system</scope>-->
+<!--            <systemPath>${project.basedir}/src/main/resources/lib/DmJdbcDriver18.jar</systemPath>-->
+<!--        </dependency>-->
+
+        <!-- 核心模块-->
+        <dependency>
+            <groupId>com.zkqy</groupId>
+            <artifactId>zkqy-framework</artifactId>
+            <version>3.8.5</version>
+        </dependency>
+        <!--业务模块-->
+        <dependency>
+            <groupId>com.zkqy</groupId>
+            <artifactId>zkqy-business</artifactId>
+            <version>3.8.5</version>
+        </dependency>
+        <!--业务模块-->
+        <dependency>
+            <groupId>com.zkqy</groupId>
+            <artifactId>zkqy-custom-business</artifactId>
+            <version>3.8.5</version>
+        </dependency>
+        <dependency>
+            <groupId>com.zkqy</groupId>
+            <artifactId>zkqy-common</artifactId>
+            <version>3.8.5</version>
+        </dependency>
+        <dependency>
+            <groupId>com.zkqy</groupId>
+            <artifactId>zkqy-laboratory-information</artifactId>
+            <version>3.8.5</version>
+        </dependency>
+        <dependency>
+            <groupId>com.zkqy</groupId>
+            <artifactId>zkqy-fujian-amichi</artifactId>
+            <version>3.8.5</version>
+        </dependency>
+        <!--谷歌的JSON转换工具GSON-->
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.10.1</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </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-compiler-plugin</artifactId>
+                <version>3.1</version>
+                <configuration>
+                    <fork>true</fork>
+                    <meminitial>512m</meminitial>
+                    <!-- 设置最大内存 -->
+                    <maxmem>4096m</maxmem>
+                </configuration>
+            </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>
+        </plugins>
+        <finalName>${project.artifactId}</finalName>
+    </build>
+
+</project>

+ 55 - 0
zkqy-admin/src/main/java/com/zkqy/ZkqyApplication.java

@@ -0,0 +1,55 @@
+package com.zkqy;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+import java.util.Arrays;
+
+/**
+ * 启动程序
+ * 
+ * @author ruoyi
+ */
+@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
+@EnableAspectJAutoProxy(exposeProxy = true)
+@EnableScheduling
+public class ZkqyApplication
+{
+    public static void main(String[] args)
+    {
+        SpringApplication.run(ZkqyApplication.class, args);
+        System.out.println("(♥◠‿◠)ノ゙  中科擎云智能制造平台客户端后台启动成功   ლ(´ڡ`ლ)゙  \n"+
+                "        CCCCCCCCCCCCCLLLLLLLLLLL             IIIIIIIIIIEEEEEEEEEEEEEEEEEEEEEENNNNNNNN        NNNNNNNNTTTTTTTTTTTTTTTTTTTTTTT\n" +
+                "     CCC::::::::::::CL:::::::::L             I::::::::IE::::::::::::::::::::EN:::::::N       N::::::NT:::::::::::::::::::::T\n" +
+                "   CC:::::::::::::::CL:::::::::L             I::::::::IE::::::::::::::::::::EN::::::::N      N::::::NT:::::::::::::::::::::T\n" +
+                "  C:::::CCCCCCCC::::CLL:::::::LL             II::::::IIEE::::::EEEEEEEEE::::EN:::::::::N     N::::::NT:::::TT:::::::TT:::::T\n" +
+                " C:::::C       CCCCCC  L:::::L                 I::::I    E:::::E       EEEEEEN::::::::::N    N::::::NTTTTTT  T:::::T  TTTTTT\n" +
+                "C:::::C                L:::::L                 I::::I    E:::::E             N:::::::::::N   N::::::N        T:::::T        \n" +
+                "C:::::C                L:::::L                 I::::I    E::::::EEEEEEEEEE   N:::::::N::::N  N::::::N        T:::::T        \n" +
+                "C:::::C                L:::::L                 I::::I    E:::::::::::::::E   N::::::N N::::N N::::::N        T:::::T        \n" +
+                "C:::::C                L:::::L                 I::::I    E:::::::::::::::E   N::::::N  N::::N:::::::N        T:::::T        \n" +
+                "C:::::C                L:::::L                 I::::I    E::::::EEEEEEEEEE   N::::::N   N:::::::::::N        T:::::T        \n" +
+                "C:::::C                L:::::L                 I::::I    E:::::E             N::::::N    N::::::::::N        T:::::T        \n" +
+                " C:::::C       CCCCCC  L:::::L         LLLLLL  I::::I    E:::::E       EEEEEEN::::::N     N:::::::::N        T:::::T        \n" +
+                "  C:::::CCCCCCCC::::CLL:::::::LLLLLLLLL:::::LII::::::IIEE::::::EEEEEEEE:::::EN::::::N      N::::::::N      TT:::::::TT      \n" +
+                "   CC:::::::::::::::CL::::::::::::::::::::::LI::::::::IE::::::::::::::::::::EN::::::N       N:::::::N      T:::::::::T      \n" +
+                "     CCC::::::::::::CL::::::::::::::::::::::LI::::::::IE::::::::::::::::::::EN::::::N        N::::::N      T:::::::::T      \n" +
+                "        CCCCCCCCCCCCCLLLLLLLLLLLLLLLLLLLLLLLLIIIIIIIIIIEEEEEEEEEEEEEEEEEEEEEENNNNNNNN         NNNNNNN      TTTTTTTTTTT      "
+        );
+//        Long id=new Long(1);
+//        id.toString();
+//        System.out.println(id);
+//        System.out.println();
+        //base........................................
+        //base........................................
+        //base........................................
+        //输出容器中所有bean
+//        ApplicationContext context = SpringApplication.run(ZkqyApplication.class, args);
+//        Arrays.stream(context.getBeanDefinitionNames()).forEach(System.out::println);
+    }
+}

+ 25 - 0
zkqy-admin/src/main/java/com/zkqy/ZkqyServletInitializer.java

@@ -0,0 +1,25 @@
+package com.zkqy;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+/**
+ * web容器中进行部署
+ * 
+ * @author ruoyi
+ */
+public class ZkqyServletInitializer extends SpringBootServletInitializer
+{
+    @Override
+    protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
+    {
+        System.out.println("新仓库第一次提交");
+        return application.sources(ZkqyApplication.class);
+    }
+
+
+    public static void main(String[] args) {
+
+    }
+
+}

+ 40 - 0
zkqy-admin/src/main/java/com/zkqy/web/asd.json

@@ -0,0 +1,40 @@
+com.zkqy.business.domain.SaleAccountsReceivableDetail@682535c6[
+  id=<null>
+  accountingType=1
+  customerId=1
+  accountsReceivableDate=Thu Aug 01 00:00:00 CST 2024
+  saleNo=2024073180778
+  saleProductNo=<null>
+  productId=5590
+  productName=150D仿锦纶高弹
+  productSpecifications=150D
+  productLevel=AA
+  productColour=003雪花白
+  lotNumber=24-7-31
+  boxNum=3
+  weight=<null>
+  productPrice=<null>
+  amountReceivable=68.2
+  receivedAmount=0.0
+  amounts=<null>
+  paymentMethod=<null>
+  billingType=1
+  accountsReceivableRemark=<null>
+  settlementUnit=<null>
+  returnReceipt=0
+  returnReceiptDate=<null>
+  returnReceiptRemark=<null>
+  noticeNumber=20240731175442
+  status=1
+  spare1=<null>
+  spare2=<null>
+  spare3=<null>
+  remark=<null>
+  createBy=<null>
+  createById=<null>
+  createTime=<null>
+  updateBy=<null>
+  updateById=<null>
+  updateTime=<null>
+  delFlag=<null>
+]

+ 24 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/TetsContro.java

@@ -0,0 +1,24 @@
+package com.zkqy.web.controller;
+
+import com.zkqy.common.annotation.Anonymous;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/admin")
+public class TetsContro {
+
+    @PostMapping("/test")
+    @Anonymous
+    public String test(@RequestBody Yx yx) {
+        System.out.println(yx);
+        return "hello";
+    }
+
+    @GetMapping("/test2")
+    @Anonymous
+    public String test2(Yx yx) {
+        System.out.println(yx);
+        return "hello";
+    }
+
+}

+ 23 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/Yx.java

@@ -0,0 +1,23 @@
+package com.zkqy.web.controller;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+public class Yx {
+
+    private String name;
+
+    private  String age;
+
+    private  String desc;
+
+    private List<Yx> rows;
+}

+ 88 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/chemicalFiber/QualityInspectionCertificateController.java

@@ -0,0 +1,88 @@
+package com.zkqy.web.controller.chemicalFiber;
+
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.execution.produce.dispersed.entity.CommonEntity;
+import com.zkqy.execution.produce.dispersed.service.ICommonService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/QualityInspectionCertificate")
+public class QualityInspectionCertificateController {
+
+    @Autowired
+    private ICommonService commonService;
+
+    /**
+     * 新增质检单
+     */
+    @PostMapping("/addQualityInspectionCertificate")
+    public AjaxResult addQualityInspectionCertificate(@RequestBody Map<String,Object> map){
+        //新增检验单表
+        Map<String,String> inspectionList = (Map<String,String>) map.get("inspectionList");
+        // 封装检验单表新增数据
+        CommonEntity commonEntity = new CommonEntity();
+        commonEntity.getBasicMap().put("tableName","inspection_list");
+//        List<Map<String,String>> addList = new ArrayList<>();
+//        addList.add(inspectionList);
+        commonEntity.getAddListMap().add(inspectionList);
+        commonService.batchInsert(commonEntity);
+        //新增检验单详情表
+        List<Map<String, String>> inspectionListInfo = (List<Map<String, String>>) map.get("inspectionListInfo");
+        // 封装检验单表新增数据
+        CommonEntity commonEntity1 = new CommonEntity();
+        commonEntity1.getBasicMap().put("tableName","inspection_list_info");
+        commonEntity1.getAddListMap().addAll(inspectionListInfo);
+        commonService.batchInsert(commonEntity1);
+        return AjaxResult.success();
+    }
+
+    @PostMapping("/editQualityInspectionCertificate")
+    public AjaxResult editQualityInspectionCertificate(@RequestBody Map<String,Object> map){
+        // 删除检验单表
+        Map<String,String> inspectionList = (Map<String,String>) map.get("inspectionList");
+        CommonEntity commonEntity = new CommonEntity();
+        commonEntity.getBasicMap().put("tableName","inspection_list");
+        Map<String,Object> conditions = new HashMap<>();
+        List<String> list = new ArrayList<>();
+        list.add(inspectionList.get("inspectionListNo"));
+        conditions.put("inspection_list_no",list);
+        commonEntity.getConditionMap().putAll(conditions);
+        commonService.batchDelete(commonEntity);
+        // 删除检验单详情表
+        CommonEntity commonEntity3 = new CommonEntity();
+        commonEntity3.getBasicMap().put("tableName","inspection_list_info");
+        commonEntity3.getConditionMap().putAll(conditions);
+        commonService.batchDelete(commonEntity3);
+
+
+        //新增检验单表
+        Map<String,String> inspectionList1 = (Map<String,String>) map.get("inspectionList");
+        // 封装检验单表新增数据
+        CommonEntity commonEntity1 = new CommonEntity();
+        commonEntity1.getBasicMap().put("tableName","inspection_list");
+//        List<Map<String,String>> addList = new ArrayList<>();
+//        addList.add(inspectionList);
+        commonEntity1.getAddListMap().add(inspectionList1);
+        commonService.batchInsert(commonEntity1);
+        //新增检验单详情表
+        List<Map<String, String>> inspectionListInfo = (List<Map<String, String>>) map.get("inspectionListInfo");
+        // 封装检验单表新增数据
+        CommonEntity commonEntity2 = new CommonEntity();
+        commonEntity2.getBasicMap().put("tableName","inspection_list_info");
+        commonEntity2.getAddListMap().addAll(inspectionListInfo);
+        commonService.batchInsert(commonEntity2);
+        return AjaxResult.success();
+
+
+    }
+
+}

+ 94 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/common/CaptchaController.java

@@ -0,0 +1,94 @@
+package com.zkqy.web.controller.common;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Resource;
+import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.FastByteArrayOutputStream;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.google.code.kaptcha.Producer;
+import com.zkqy.common.config.ZkqyConfig;
+import com.zkqy.common.constant.CacheConstants;
+import com.zkqy.common.constant.Constants;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.redis.RedisCache;
+import com.zkqy.common.utils.sign.Base64;
+import com.zkqy.common.utils.uuid.IdUtils;
+import com.zkqy.system.service.ISysConfigService;
+
+/**
+ * 验证码操作处理
+ * 
+ * @author ruoyi
+ */
+@RestController
+public class CaptchaController
+{
+    @Resource(name = "captchaProducer")
+    private Producer captchaProducer;
+
+    @Resource(name = "captchaProducerMath")
+    private Producer captchaProducerMath;
+
+    @Autowired
+    private RedisCache redisCache;
+    
+    @Autowired
+    private ISysConfigService configService;
+    /**
+     * 生成验证码
+     */
+    @GetMapping("/captchaImage")
+    public AjaxResult getCode(HttpServletResponse response) throws IOException
+    {
+        AjaxResult ajax = AjaxResult.success();
+        boolean captchaEnabled = configService.selectCaptchaEnabled();
+        ajax.put("captchaEnabled", captchaEnabled);
+        if (!captchaEnabled)
+        {
+            return ajax;
+        }
+
+        // 保存验证码信息
+        String uuid = IdUtils.simpleUUID();
+        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
+
+        String capStr = null, code = null;
+        BufferedImage image = null;
+
+        // 生成验证码
+        String captchaType = ZkqyConfig.getCaptchaType();
+        if ("math".equals(captchaType))
+        {
+            String capText = captchaProducerMath.createText();
+            capStr = capText.substring(0, capText.lastIndexOf("@"));
+            code = capText.substring(capText.lastIndexOf("@") + 1);
+            image = captchaProducerMath.createImage(capStr);
+        }
+        else if ("char".equals(captchaType))
+        {
+            capStr = code = captchaProducer.createText();
+            image = captchaProducer.createImage(capStr);
+        }
+
+        redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
+        // 转换流信息写出
+        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
+        try
+        {
+            ImageIO.write(image, "jpg", os);
+        }
+        catch (IOException e)
+        {
+            return AjaxResult.error(e.getMessage());
+        }
+
+        ajax.put("uuid", uuid);
+        ajax.put("img", Base64.encode(os.toByteArray()));
+        return ajax;
+    }
+}

+ 395 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/common/CommonFileController.java

@@ -0,0 +1,395 @@
+package com.zkqy.web.controller.common;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.TypeReference;
+import com.zkqy.business.entity.DragTable;
+import com.zkqy.business.service.IDragTableService;
+import com.zkqy.common.annotation.Anonymous;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.config.ZkqyConfig;
+import com.zkqy.common.constant.Constants;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.redis.RedisCache;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.common.utils.file.FileUploadUtils;
+import com.zkqy.common.utils.file.FileUtils;
+import com.zkqy.execution.produce.dispersed.entity.CommonEntity;
+import com.zkqy.execution.produce.dispersed.entity.TableSql;
+import com.zkqy.execution.produce.dispersed.service.ICommonService;
+import com.zkqy.execution.produce.dispersed.service.ITableSqlService;
+import com.zkqy.framework.config.ServerConfig;
+import com.zkqy.business.controller.CommonController;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
+
+import static com.zkqy.common.core.domain.AjaxResult.success;
+
+/**
+ * 通用请求处理
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/common")
+public class CommonFileController {
+    private static final Logger log = LoggerFactory.getLogger(CommonController.class);
+
+    @Autowired
+    private ServerConfig serverConfig;
+
+    //@Resource
+    //private IDataSourceService dataSourceService;
+
+    @Resource
+    private ICommonService commonService;
+
+    @Resource
+    private ITableSqlService iTableSqlService;
+
+    @Resource
+    private IDragTableService dragTableService;
+
+    @Resource
+    private RedisCache redisCache;
+
+    private static final String FILE_DELIMETER = ",";
+
+    /**
+     * 共通导出
+     * 通用导出excel
+     */
+    @Log(title = "动态表格", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, CommonEntity commonEntity) throws Exception {
+        commonService.export(response, commonEntity);
+    }
+
+    /**
+     * 通用导出excel模版
+     *
+     * @param response
+     * @param tableName
+     * @throws Exception
+     */
+    @Log(title = "动态表格", businessType = BusinessType.EXPORT)
+    @PostMapping("/exportTemplate")
+    public void exportTemplate(HttpServletResponse response, String tableName, String sqlkey) throws Exception {
+        commonService.exportTemplate(response, tableName, sqlkey);
+    }
+
+    /**
+     * 通用下载请求
+     *
+     * @param fileName 文件名称
+     * @param delete   是否删除
+     */
+    @Log(title = "动态表格", businessType = BusinessType.EXPORT)
+    @GetMapping("/download")
+    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) {
+        try {
+            if (!FileUtils.checkAllowDownload(fileName)) {
+                throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
+            }
+            String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
+            String filePath = ZkqyConfig.getDownloadPath() + fileName;
+
+            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
+            FileUtils.setAttachmentResponseHeader(response, realFileName);
+            FileUtils.writeBytes(filePath, response.getOutputStream());
+            if (delete) {
+                FileUtils.deleteFile(filePath);
+            }
+        } catch (Exception e) {
+            log.error("下载文件失败", e);
+        }
+    }
+
+    /**
+     * 通用上传请求(单个)
+     * /common/upload
+     */
+    @PostMapping("/upload")
+    public AjaxResult uploadFile(MultipartFile file) throws Exception {
+        try {
+            // 上传文件路径
+            String filePath = ZkqyConfig.getUploadPath();
+            // 上传并返回新文件名称
+            String fileName = FileUploadUtils.upload(filePath, file);
+            String url = serverConfig.getUrl() + fileName;
+            AjaxResult ajax = success();
+            ajax.put("url", url);
+            ajax.put("fileName", fileName);
+            ajax.put("newFileName", FileUtils.getName(fileName));
+            ajax.put("originalFilename", file.getOriginalFilename());
+            return ajax;
+        } catch (Exception e) {
+            return AjaxResult.error(e.getMessage());
+        }
+    }
+
+//    /**
+//     * 租户通用上传文件接口(需携带租户标识)
+//     *
+//     * @param file
+//     * @param base64
+//     * @return
+//     */
+//    @PostMapping("/tenantUploadFile")
+//    public AjaxResult tenantUploadFile(MultipartFile file, boolean base64) {
+//        try {
+//            // 每个租户都有属于自己的文件夹
+//            String tenantCode = SecurityUtils.getLoginUser().getUser().getTenant().getTenantCode();
+//            // 上传文件路径
+//            String filePath = ZkqyConfig.getUploadPath() + "/" + tenantCode;
+//            AjaxResult ajax = success();
+//            // 当前文件是否使用base64来进行存储
+//            if (base64) {
+//                // 从MultipartFile获取字节数组
+//                byte[] bytes = file.getBytes();
+//                // 将字节数组转换为Base64编码的字符串
+//                String base64Encoded = Base64.getEncoder().encodeToString(bytes);
+//                String key = UUID.randomUUID().toString();
+//                // 存储字节流  redis暂存30分钟
+//                redisCache.setCacheObject(key, base64Encoded, Constants.BYTESTREAM_EXPIRATION, TimeUnit.MINUTES);
+//                ajax.put("base64", key);
+//            } else {
+//                // 上传并返回新文件名称
+//                String fileName = FileUploadUtils.upload(filePath, file);
+//                // 存储文件
+//                String url = serverConfig.getUrl() + fileName;
+//                ajax.put("url", url);
+//                ajax.put("fileName", fileName);
+//                ajax.put("newFileName", FileUtils.getName(fileName));
+//                ajax.put("originalFilename", file.getOriginalFilename());
+//            }
+//            return ajax;
+//        } catch (Exception e) {
+//            return AjaxResult.error(e.getMessage());
+//        }
+//    }
+//
+//
+//    /**
+//     * * 租户通用批量上传文件接口(需携带租户标识)
+//     * * * 批量上传无法使用流文件逻辑
+//     *
+//     * @param request
+//     * @param files
+//     * @return
+//     */
+//    @PostMapping("/tenantUploadFiles")
+//    @RequestBody
+//    public AjaxResult tenantUploadFiles(HttpServletRequest request, List<MultipartFile> files) {
+//        try {
+//            // 每个租户都有属于自己的文件夹
+//            String tenantCode = SecurityUtils.getLoginUser().getUser().getTenant().getTenantCode();
+//            // 上传文件路径
+//            String filePath = ZkqyConfig.getUploadPath() + "/" + tenantCode;
+//            List<String> urls = new ArrayList<String>();
+//            List<String> fileNames = new ArrayList<String>();
+//            List<String> newFileNames = new ArrayList<String>();
+//            List<String> originalFilenames = new ArrayList<String>();
+//            List<String> base64Keys = new ArrayList<String>();
+//            AjaxResult ajax = success();
+//            for (MultipartFile file : files) {
+//                boolean is = Boolean.parseBoolean(request.getParameter(file.getOriginalFilename().split("\\.")[0]));
+//                if (is) {
+//                    // 从MultipartFile获取字节数组
+//                    byte[] bytes = file.getBytes();
+//                    // 将字节数组转换为Base64编码的字符串
+//                    String base64Encoded = Base64.getEncoder().encodeToString(bytes);
+//                    String key = UUID.randomUUID().toString();
+//                    // 存储字节流  redis暂存30分钟
+//                    redisCache.setCacheObject(key, base64Encoded, Constants.BYTESTREAM_EXPIRATION, TimeUnit.MINUTES);
+//                    base64Keys.add("file:base64:" + key);
+//                    ajax.put("base64", StringUtils.join(base64Keys, FILE_DELIMETER));
+//                } else {
+//                    // 上传并返回新文件名称
+//                    String fileName = FileUploadUtils.upload(filePath, file);
+//                    String url = serverConfig.getUrl() + fileName;
+//                    urls.add(url);
+//                    fileNames.add(fileName);
+//                    newFileNames.add(FileUtils.getName(fileName));
+//                    originalFilenames.add(file.getOriginalFilename());
+//
+//                    ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
+//                    ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
+//                    ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
+//                    ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
+//                }
+//            }
+//            return ajax;
+//        } catch (Exception e) {
+//            return AjaxResult.error(e.getMessage());
+//        }
+//    }
+
+    /**
+     * 通用上传请求(多个)
+     */
+    @Log(title = "动态表格", businessType = BusinessType.IMPORT)
+    @PostMapping("/uploads")
+    public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception {
+        try {
+            // 上传文件路径
+            String filePath = ZkqyConfig.getUploadPath();
+            List<String> urls = new ArrayList<String>();
+            List<String> fileNames = new ArrayList<String>();
+            List<String> newFileNames = new ArrayList<String>();
+            List<String> originalFilenames = new ArrayList<String>();
+            for (MultipartFile file : files) {
+                // 上传并返回新文件名称
+                String fileName = FileUploadUtils.upload(filePath, file);
+                String url = serverConfig.getUrl() + fileName;
+                urls.add(url);
+                fileNames.add(fileName);
+                newFileNames.add(FileUtils.getName(fileName));
+                originalFilenames.add(file.getOriginalFilename());
+            }
+            AjaxResult ajax = success();
+            ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
+            ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
+            ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
+            ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
+            return ajax;
+        } catch (Exception e) {
+            return AjaxResult.error(e.getMessage());
+        }
+    }
+
+    /**
+     * 本地资源通用下载
+     */
+    @Log(title = "动态表格", businessType = BusinessType.EXPORT)
+    @GetMapping("/download/resource")
+    public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
+            throws Exception {
+        try {
+            if (!FileUtils.checkAllowDownload(resource)) {
+                throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
+            }
+            // 本地资源路径
+            String localPath = ZkqyConfig.getProfile();
+            // 数据库资源地址
+            String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
+            // 下载名称
+            String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
+            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
+            FileUtils.setAttachmentResponseHeader(response, downloadName);
+            FileUtils.writeBytes(downloadPath, response.getOutputStream());
+        } catch (Exception e) {
+            log.error("下载文件失败", e);
+        }
+    }
+
+    /**
+     * 导入execl数据(单个文件)文件名即表名
+     * common/uploadData
+     */
+
+    @Log(title = "动态表格", businessType = BusinessType.IMPORT)
+    @Anonymous
+    @ApiOperation("上传文件")
+    @PostMapping(value = "/uploadData", headers = "content-type=multipart/form-data")
+    public AjaxResult uploadDataFile(String tableName, String sqlKey, @RequestPart("file") MultipartFile file) throws Exception {
+        try {
+            // 创建一个工作簿对象 解析上传的excel表数据
+            List<Map<String, String>> listMap = convertList(EasyExcel.read(file.getInputStream()).sheet().headRowNumber(0).doReadSync());
+            // 校验表格数据是否为空
+            if (listMap.size() <= 1) {
+                return AjaxResult.warn("请检查表格中的数据!");
+            }
+            // 得到当前导出入数据的格式k/v
+            DragTable dragTable = dragTableService.selectSqlKeyByTableKey(sqlKey);
+            if (dragTable.getSqlKey().isEmpty()) {
+                return AjaxResult.error("网络出现问题,请等待网络恢复!");
+            }
+            // 根据tableKey查询sqlKey(虽然是getSqlKey但是拿到的是tableKey)
+            TableSql tableSql = iTableSqlService.selectTableSqlByTSqlKey(dragTable.getSqlKey());
+            // 存储 字段描述:字段列名
+            Map<String, Object> fieldMap = (Map<String, Object>) JSON.parse(tableSql.getTableExportField());
+            Map<String, Object> endFieldMap = new HashMap<>();
+            // 处理导入title对应问题,双重校验
+            fieldMap.forEach((mKey, mVal) -> {
+                if (!mKey.contains("@")) {
+                    // 表示列名 删除掉表名称
+                    endFieldMap.put(mVal.toString(), mKey.replaceFirst(tableName + "_", ""));
+                } else {
+                    // 定义新的title map集合
+                    Map<String, String> map = listMap.get(0);
+                    // 根据val值删除当前map中的k/v(此处是title,理论上不会有重复的val存在)
+                    map.values().removeIf(value -> value.contains(mVal.toString()));
+                    // 删除旧title
+                    listMap.remove(0);
+                    // 替换新title
+                    listMap.add(0, map);
+                }
+            });
+            listMap.get(0).forEach((mKey, mVal) -> {
+                if (mVal != null) {
+                    if (endFieldMap.get(mVal) != null) {
+                        listMap.get(0).put(mKey, endFieldMap.get(mVal).toString());
+                    }
+                }
+            });
+            // 挣个excel文件数据
+            listMap.forEach(item -> {
+                if (listMap.indexOf(item) == 0) {
+                    return;
+                }
+                Map<String, String> handleMap = new HashMap<>(item);
+                handleMap.forEach((mKey, mVal) -> {
+                    // 新增       // 删除当前map中的k/v
+                    item.put(listMap.get(0).get(mKey), item.remove(mKey));
+                });
+                // 如果value为空就清空
+//                item.entrySet().removeIf(entry -> entry.getValue() == null);
+            });
+            listMap.remove(0);
+            CommonEntity commonEntity = new CommonEntity();
+            commonEntity.setBasicMap(
+                    JSONObject.parseObject("{ \"tableName\":\"" + tableName + "\"}", new TypeReference<Map<String, Object>>() {
+                    })
+            );
+            int state = 0;  // 返回状态值
+            int batchSize = 1000; // 设置批量新增每次执行添加sql上线为1000条
+            for (int i = 0; i < listMap.size(); i += batchSize) {
+                int end = Math.min(listMap.size(), i + batchSize);
+                commonEntity.setAddListMap(listMap.subList(i, end));
+                state = commonService.batchInsert(commonEntity);
+            }
+            return success(state);
+        } catch (Exception e) {
+            return AjaxResult.error(e.getMessage());
+        }
+    }
+
+    // map类型转换
+    public static List<Map<String, String>> convertList(List<Map<Integer, String>> inputList) {
+        List<Map<String, String>> resultList = new ArrayList<>();
+        for (Map<Integer, String> inputMap : inputList) {
+            Map<String, String> resultMap = new HashMap<>();
+            for (Map.Entry<Integer, String> entry : inputMap.entrySet()) {
+                Integer key = entry.getKey();
+                String value = entry.getValue();
+                // 将 Integer 类型的 key 转换为 String 类型
+                String convertedKey = key.toString();
+                resultMap.put(convertedKey, value);
+            }
+            resultList.add(resultMap);
+        }
+        return resultList;
+    }
+}

+ 32 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/dragForm/DynamicController.java

@@ -0,0 +1,32 @@
+package com.zkqy.web.controller.dragForm;
+
+import com.zkqy.common.annotation.Anonymous;
+import com.zkqy.web.controller.tool.DynamicBeanRegistrar;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+//@RestController
+public class DynamicController {
+
+//    @Autowired
+//    @Lazy
+//    private DynamicBeanRegistrar dynamicBeanRegistrar;
+//
+//    @GetMapping("/load-controller")
+//    @Anonymous
+//    public String loadController(@RequestParam String sourceFilePath, @RequestParam String beanName) {
+//        try {
+//            dynamicBeanRegistrar.registerController(sourceFilePath, beanName);
+//            return "Controller loaded successfully!";
+//        } catch (Exception e) {
+//            return "Failed to load controller: " + e.getMessage();
+//        }
+//    }
+}

+ 4 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/dragForm/TestController.java

@@ -0,0 +1,4 @@
+package com.zkqy.web.controller.dragForm;
+
+public class TestController {
+}

+ 12 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/dragForm/TestMain.java

@@ -0,0 +1,12 @@
+package com.zkqy.web.controller.dragForm;
+
+
+import java.util.HashMap;
+
+public class TestMain {
+    public static void main(String[] args) {
+        HashMap<String, Integer> e=new HashMap<>();
+        e.remove("a");
+    }
+
+}

+ 213 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/homepagestatistics/StatisticsController.java

@@ -0,0 +1,213 @@
+package com.zkqy.web.controller.homepagestatistics;
+
+import com.zkqy.business.domain.DetailsOfTheRefuelingPlan;
+import com.zkqy.business.entity.DragForm;
+import com.zkqy.business.entity.DragTable;
+import com.zkqy.business.entity.DragTableGroup;
+import com.zkqy.business.entity.vo.CommonTableOperationVO;
+import com.zkqy.business.service.impl.*;
+import com.zkqy.common.constant.DataSourceType;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.utils.SecurityUtils;
+import com.zkqy.execution.produce.dispersed.entity.BpmExecuteProcess;
+import com.zkqy.execution.produce.dispersed.service.impl.BpmExecuteProcessServiceImpl;
+import com.zkqy.execution.produce.dispersed.service.impl.BpmProcessServiceImpl;
+import com.zkqy.system.domain.SysLogininfor;
+import com.zkqy.system.service.ISysOperLogService;
+import com.zkqy.system.service.impl.SysLogininforServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 化纤数据统计
+ */
+@RestController
+@RequestMapping("/statistics/info")
+public class StatisticsController {
+
+    @Autowired
+    BpmExecuteProcessServiceImpl bpmExecuteProcessService;
+
+    @Autowired
+    private ISysOperLogService operLogService;
+
+    @Autowired
+    private SysLogininforServiceImpl logininforService;
+
+    @Autowired
+    DetailsOfTheRefuelingPlanServiceImpl detailsOfTheRefuelingPlanService;
+
+    @Autowired
+    DetailsOfTheRefuelingPlanSpinningServiceImpl detailsOfTheRefuelingPlanSpinningService;
+
+    @Autowired
+    MaterialInventoryServiceImpl   materialInventoryService;
+
+    @Autowired
+    InboundRecordsServiceImpl inboundRecordsService;
+
+    @Autowired
+    OutboundRecordsServiceImpl outboundRecordsService;
+
+    /**
+     * 任务数量统计 √
+     * @return
+     */
+    @GetMapping("/getProcessInformation")
+     public AjaxResult getProcessInformation(){
+        if(SecurityUtils.getTenantId().equals(166L)){
+            //查询加弹计划
+            int i1 = detailsOfTheRefuelingPlanService.selectDetailsOfTheRefuelingPlanListCount();
+            int i2 = detailsOfTheRefuelingPlanSpinningService.selectDetailsOfTheRefuelingPlanSpinningListCount();
+            HashMap<String, String> map1 = new HashMap<>();
+            map1.put("name", "计划任务");
+            map1.put("value",String.valueOf((i1+i2)));
+            int i = bpmExecuteProcessService.selectBpmExecuteProcessListCount();
+            HashMap<String, String> map2 = new HashMap<>();
+            map2.put("审批任务",String.valueOf(i));
+            map2.put("name", "审批任务");
+            map2.put("value",String.valueOf(i));
+            List<Map> listMap=new ArrayList<>();
+            listMap.add(map1);
+            listMap.add(map2);
+            return AjaxResult.success(listMap);
+            //纺丝+翻框+络筒
+        }else {
+            HashMap<String, String> map1 = new HashMap<>();
+            map1.put("name", "计划任务");
+            map1.put("value","0");
+            HashMap<String, String> map2 = new HashMap<>();
+            map2.put("审批任务","0");
+            map2.put("name", "审批任务");
+            map2.put("value","0");
+            List<Map> listMap=new ArrayList<>();
+            listMap.add(map1);
+            listMap.add(map2);
+            return AjaxResult.success(listMap);
+        }
+     }
+
+    /**
+     * 操作日志信息统计 (这个没办法做成共同的,因为,操作记录在主表当中)
+     * Operation information statistics
+     */
+    @GetMapping("/getOperationInformationStatistics")
+    public AjaxResult getOperationInformationStatistics(){
+        Long tenantId = SecurityUtils.getLoginUser().getTenantId();
+        List<Map> list = operLogService.selectOperationInformationStatistics(tenantId);
+        return AjaxResult.success(list);
+    }
+
+    /**
+     * 生产任务、 完成任务数量
+     * Operation information statistics
+     */
+    @GetMapping("/getProductionTaskCompletionQuantity")
+    public AjaxResult getProductionTaskCompletionQuantity(){
+        BpmExecuteProcess bpmExecuteProcess=new BpmExecuteProcess();
+        bpmExecuteProcess.setTaskProcessType("0");
+        //所有生产的,生产流程
+        List<Map> mapList1= bpmExecuteProcessService.selectBpmExecuteProcessListProductionCount(bpmExecuteProcess);
+        List<Map> list = new ArrayList<>();
+        HashMap hashMap1=new HashMap();
+        hashMap1.put("name","在产任务");
+        hashMap1.put("type","line");
+        hashMap1.put("smooth","true");
+        hashMap1.put("data",mapList1.stream().map((item->item.get("count"))).collect(Collectors.toList()));
+        hashMap1.put("date",mapList1.stream().map((item->item.get("month"))).collect(Collectors.toList()));
+        list.add(hashMap1);
+        BpmExecuteProcess bpmExecuteProcess2=new BpmExecuteProcess();
+        bpmExecuteProcess2.setTaskProcessType("0");
+        bpmExecuteProcess2.setTaskProcessState(3L);
+        //所有生产的,生产流程
+        List<Map> mapList2 = bpmExecuteProcessService.selectBpmExecuteProcessListProductionCount(bpmExecuteProcess2);
+        HashMap hashMap2=new HashMap();
+        hashMap2.put("name","完成任务");
+        hashMap2.put("type","line");
+        hashMap2.put("smooth","true");
+        hashMap2.put("data",mapList2.stream().map((item->item.get("count"))).collect(Collectors.toList()));
+        hashMap2.put("date",mapList2.stream().map((item->item.get("month"))).collect(Collectors.toList()));
+        list.add(hashMap2);
+        return  AjaxResult.success(list);
+    }
+
+    /**
+     * 原材料
+     * DataModelingStatistics
+     */
+    @GetMapping("/getRawMaterial")
+    public AjaxResult getRawMaterial(){
+        if(SecurityUtils.getTenantId().equals("166")){
+            //总库存数量
+            int i1 = materialInventoryService.selectMaterialInventoryListSum();
+            //出库数量
+            int i2 = inboundRecordsService.selectInboundRecordsByQtCodeNumberCount();
+            //入库数量
+            int i3 = outboundRecordsService.selectOutboundRecordsCount();
+            List<Map> list=new ArrayList<>();
+            HashMap dragFormsMap=new HashMap();
+            dragFormsMap.put("name","总库存数量");
+            dragFormsMap.put("value",i1);
+            list.add(dragFormsMap);
+
+            HashMap dragTableSMap=new HashMap();
+            dragTableSMap.put("name","出库数量");
+            dragTableSMap.put("value",i2);
+            list.add(dragTableSMap);
+
+            HashMap dragTableGroupsSMap=new HashMap();
+            dragTableGroupsSMap.put("name","入库数量");
+            dragTableGroupsSMap.put("value",i3);
+            list.add(dragTableGroupsSMap);
+            return AjaxResult.success(list);
+        }else {
+            List<Map> list=new ArrayList<>();
+            HashMap dragFormsMap=new HashMap();
+            dragFormsMap.put("name","总库存数量");
+            dragFormsMap.put("value",0);
+            list.add(dragFormsMap);
+
+            HashMap dragTableSMap=new HashMap();
+            dragTableSMap.put("name","出库数量");
+            dragTableSMap.put("value",0);
+            list.add(dragTableSMap);
+
+            HashMap dragTableGroupsSMap=new HashMap();
+            dragTableGroupsSMap.put("name","入库数量");
+            dragTableGroupsSMap.put("value",0);
+            list.add(dragTableGroupsSMap);
+            return AjaxResult.success(list);
+        }
+
+    }
+
+
+    /**
+     * 最近12个月的客户端的登录情况
+     */
+    @GetMapping("/getLoginInformationStatistics")
+    public AjaxResult getLoginInfo(){
+        SysLogininfor logininfor=new SysLogininfor();
+        logininfor.setTenantId(SecurityUtils.getTenantId());
+        logininfor.setWhichApplication("1");
+        List<Map> loginInformationStatistics = logininforService.getLoginInformationStatistics(logininfor);
+        List<String> dates1=new ArrayList<>();
+        List<String> dates2=new ArrayList<>();
+        loginInformationStatistics.stream().forEach(item->{
+            dates1.add(item.get("month").toString());
+            dates2.add(item.get("loginCount").toString());
+        });
+        HashMap<String,Object> data=new HashMap<>();
+        data.put("name",dates1);
+        data.put("value",dates2);
+        return AjaxResult.success(data);
+    }
+}

+ 120 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/monitor/CacheController.java

@@ -0,0 +1,120 @@
+package com.zkqy.web.controller.monitor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.constant.CacheConstants;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.system.domain.SysCache;
+
+/**
+ * 缓存监控
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/cache")
+public class CacheController
+{
+    @Autowired
+    private RedisTemplate<String, String> redisTemplate;
+
+    private final static List<SysCache> caches = new ArrayList<SysCache>();
+    {
+        caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息"));
+        caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息"));
+        caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典"));
+        caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码"));
+        caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交"));
+        caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理"));
+        caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数"));
+    }
+
+    //@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+    @GetMapping()
+    public AjaxResult getInfo() throws Exception
+    {
+        Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info());
+        Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
+        Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize());
+
+        Map<String, Object> result = new HashMap<>(3);
+        result.put("info", info);
+        result.put("dbSize", dbSize);
+
+        List<Map<String, String>> pieList = new ArrayList<>();
+        commandStats.stringPropertyNames().forEach(key -> {
+            Map<String, String> data = new HashMap<>(2);
+            String property = commandStats.getProperty(key);
+            data.put("name", StringUtils.removeStart(key, "cmdstat_"));
+            data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
+            pieList.add(data);
+        });
+        result.put("commandStats", pieList);
+        return AjaxResult.success(result);
+    }
+
+    //@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+    @GetMapping("/getNames")
+    public AjaxResult cache()
+    {
+        return AjaxResult.success(caches);
+    }
+
+    //@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+    @GetMapping("/getKeys/{cacheName}")
+    public AjaxResult getCacheKeys(@PathVariable String cacheName)
+    {
+        Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
+        return AjaxResult.success(cacheKeys);
+    }
+
+    //@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+    @GetMapping("/getValue/{cacheName}/{cacheKey}")
+    public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey)
+    {
+        String cacheValue = redisTemplate.opsForValue().get(cacheKey);
+        SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue);
+        return AjaxResult.success(sysCache);
+    }
+
+    //@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+    @DeleteMapping("/clearCacheName/{cacheName}")
+    public AjaxResult clearCacheName(@PathVariable String cacheName)
+    {
+        Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*");
+        redisTemplate.delete(cacheKeys);
+        return AjaxResult.success();
+    }
+
+    @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+    @DeleteMapping("/clearCacheKey/{cacheKey}")
+    public AjaxResult clearCacheKey(@PathVariable String cacheKey)
+    {
+        redisTemplate.delete(cacheKey);
+        return AjaxResult.success();
+    }
+
+    @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
+    @DeleteMapping("/clearCacheAll")
+    public AjaxResult clearCacheAll()
+    {
+        Collection<String> cacheKeys = redisTemplate.keys("*");
+        redisTemplate.delete(cacheKeys);
+        return AjaxResult.success();
+    }
+}

+ 27 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/monitor/ServerController.java

@@ -0,0 +1,27 @@
+package com.zkqy.web.controller.monitor;
+
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.framework.web.domain.Server;
+
+/**
+ * 服务器监控
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/server")
+public class ServerController
+{
+    //@PreAuthorize("@ss.hasPermi('monitor:server:list')")
+    @GetMapping()
+    public AjaxResult getInfo() throws Exception
+    {
+        Server server = new Server();
+        server.copyTo();
+        return AjaxResult.success(server);
+    }
+}

+ 65 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/monitor/SysActivationLogController.java

@@ -0,0 +1,65 @@
+package com.zkqy.web.controller.monitor;
+
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.system.domain.SysActivationCodeLog;
+import com.zkqy.system.service.ISysActivationCodeLogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 操作日志记录
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/activationlog")
+public class SysActivationLogController extends BaseController
+{
+    @Autowired
+    private ISysActivationCodeLogService iSysActivationCodeLogService;
+
+    @PreAuthorize("@ss.hasPermi('monitor:activationcodelog:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysActivationCodeLog activationCodeLog)
+    {
+        startPage();
+        List<SysActivationCodeLog> list = iSysActivationCodeLogService.selectActivationCodeLogList(activationCodeLog);
+        return getDataTable(list);
+    }
+
+    @Log(title = "操作日志", businessType = BusinessType.EXPORT)
+    @PreAuthorize("@ss.hasPermi('monitor:activationcodelog:export')")
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SysActivationCodeLog activationCodeLog)
+    {
+        List<SysActivationCodeLog> list = iSysActivationCodeLogService.selectActivationCodeLogList(activationCodeLog);
+        ExcelUtil<SysActivationCodeLog> util = new ExcelUtil<>(SysActivationCodeLog.class);
+        util.exportExcel(response, list, "操作日志");
+    }
+
+    @Log(title = "操作日志", businessType = BusinessType.DELETE)
+    @PreAuthorize("@ss.hasPermi('monitor:activationcodelog:remove')")
+    @DeleteMapping("/{logIds}")
+    public AjaxResult remove(@PathVariable Long[] logIds)
+    {
+        return toAjax(iSysActivationCodeLogService.deleteActivationCodeLogById(logIds));
+    }
+
+    @Log(title = "操作日志", businessType = BusinessType.CLEAN)
+    @PreAuthorize("@ss.hasPermi('monitor:activationcodelog:remove')")
+    @DeleteMapping("/clean")
+    public AjaxResult clean()
+    {
+        iSysActivationCodeLogService.cleanActivationCodeLog();
+        return success();
+    }
+}

+ 82 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/monitor/SysLogininforController.java

@@ -0,0 +1,82 @@
+package com.zkqy.web.controller.monitor;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.framework.web.service.SysPasswordService;
+import com.zkqy.system.domain.SysLogininfor;
+import com.zkqy.system.service.ISysLogininforService;
+
+/**
+ * 系统访问记录
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/logininfor")
+public class SysLogininforController extends BaseController
+{
+    @Autowired
+    private ISysLogininforService logininforService;
+
+    @Autowired
+    private SysPasswordService passwordService;
+
+    //@PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysLogininfor logininfor)
+    {
+        startPage();
+        List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
+        return getDataTable(list);
+    }
+
+    @Log(title = "登录日志", businessType = BusinessType.EXPORT)
+    //@PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SysLogininfor logininfor)
+    {
+        List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
+        ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
+        util.exportExcel(response, list, "登录日志");
+    }
+
+    //@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
+    @Log(title = "登录日志", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{infoIds}")
+    public AjaxResult remove(@PathVariable Long[] infoIds)
+    {
+        return toAjax(logininforService.deleteLogininforByIds(infoIds));
+    }
+
+    //@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
+    @Log(title = "登录日志", businessType = BusinessType.CLEAN)
+    @DeleteMapping("/clean")
+    public AjaxResult clean()
+    {
+        logininforService.cleanLogininfor();
+        return success();
+    }
+
+    //@PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')")
+    @Log(title = "账户解锁", businessType = BusinessType.OTHER)
+    @GetMapping("/unlock/{userName}")
+    public AjaxResult unlock(@PathVariable("userName") String userName)
+    {
+        passwordService.clearLoginRecordCache(userName);
+        return success();
+    }
+}

+ 81 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/monitor/SysOperlogController.java

@@ -0,0 +1,81 @@
+package com.zkqy.web.controller.monitor;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import com.zkqy.common.core.domain.entity.SysUser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.system.domain.SysOperLog;
+import com.zkqy.system.service.ISysOperLogService;
+
+/**
+ * 操作日志记录
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/operlog")
+public class SysOperlogController extends BaseController
+{
+    @Autowired
+    private ISysOperLogService operLogService;
+
+    //@PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysOperLog operLog)
+    {
+        if(SysUser.isAdmin(getUserId())){
+            operLog.setTenantId(0L);
+        }else {
+            operLog.setTenantId(getTenantId());
+        }
+        startPage();
+        List<SysOperLog> list = operLogService.selectOperLogList(operLog);
+        return getDataTable(list);
+    }
+
+    @Log(title = "操作日志", businessType = BusinessType.EXPORT)
+    //@PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SysOperLog operLog)
+    {
+        if(SysUser.isAdmin(getUserId())){
+            operLog.setTenantId(0L);
+        }else {
+            operLog.setTenantId(getTenantId());
+        }
+        List<SysOperLog> list = operLogService.selectOperLogList(operLog);
+        ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
+        util.exportExcel(response, list, "操作日志");
+    }
+
+    @Log(title = "操作日志", businessType = BusinessType.DELETE)
+    //@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
+    @DeleteMapping("/{operIds}")
+    public AjaxResult remove(@PathVariable Long[] operIds)
+    {
+        return toAjax(operLogService.deleteOperLogByIds(operIds));
+    }
+
+    @Log(title = "操作日志", businessType = BusinessType.CLEAN)
+    //@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
+    @DeleteMapping("/clean")
+    public AjaxResult clean()
+    {
+        operLogService.cleanOperLog();
+        return success();
+    }
+}

+ 83 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/monitor/SysUserOnlineController.java

@@ -0,0 +1,83 @@
+package com.zkqy.web.controller.monitor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.constant.CacheConstants;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.model.LoginUser;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.core.redis.RedisCache;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.system.domain.SysUserOnline;
+import com.zkqy.system.service.ISysUserOnlineService;
+
+/**
+ * 在线用户监控
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/online")
+public class SysUserOnlineController extends BaseController
+{
+    @Autowired
+    private ISysUserOnlineService userOnlineService;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    //@PreAuthorize("@ss.hasPermi('monitor:online:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(String ipaddr, String userName)
+    {
+        Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
+        List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
+        for (String key : keys)
+        {
+            LoginUser user = redisCache.getCacheObject(key);
+            if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
+            {
+                userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
+            }
+            else if (StringUtils.isNotEmpty(ipaddr))
+            {
+                userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
+            }
+            else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
+            {
+                userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
+            }
+            else
+            {
+                userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
+            }
+        }
+        Collections.reverse(userOnlineList);
+        userOnlineList.removeAll(Collections.singleton(null));
+        return getDataTable(userOnlineList);
+    }
+
+    /**
+     * 强退用户
+     */
+    @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')")
+    @Log(title = "在线用户", businessType = BusinessType.FORCE)
+    @DeleteMapping("/{tokenId}")
+    public AjaxResult forceLogout(@PathVariable String tokenId)
+    {
+        redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
+        return success();
+    }
+}

+ 169 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/projcetzip/DownloadController.java

@@ -0,0 +1,169 @@
+package com.zkqy.web.controller.projcetzip;
+
+import com.zkqy.common.config.ZkqyConfig;
+import com.zkqy.common.core.redis.RedisCache;
+import com.zkqy.common.utils.DateUtils;
+import com.zkqy.common.utils.SecurityUtils;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.system.domain.SysEngineering;
+import com.zkqy.system.service.ISysEngineeringService;
+import org.apache.tools.zip.ZipEntry;
+import org.apache.tools.zip.ZipOutputStream;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
+@RestController
+@RequestMapping("/download/project-db")
+public class DownloadController {
+
+    @Autowired
+    private ISysEngineeringService sysEngineeringService;
+
+    @Autowired
+    private ZkqyConfig zkqyConfig;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    private static final ReentrantLock lock = new ReentrantLock();
+    private volatile boolean exportCompleted = false;
+
+
+    @GetMapping("/status")
+    public ResponseEntity<String> checkExportStatus() {
+        String state = redisCache.getCacheObject("isExportState:" + SecurityUtils.getTenantId()).toString();
+        if (StringUtils.isNotNull(state) && !state.isEmpty() && state.equals("true")) {
+            return ResponseEntity.ok("导出已完成。您现在可以触发下载");
+        } else {
+            return ResponseEntity.status(HttpStatus.GATEWAY_TIMEOUT).body("文件还在生成中。请稍候。。。");
+        }
+
+    }
+
+    @GetMapping("/download")
+    public void downloadZip(HttpServletResponse response) {
+        String state = redisCache.getCacheObject("isExportState:" + SecurityUtils.getTenantId()).toString();
+        String sqlDirectoryPath = zkqyConfig.getUploadPath() + "/engineeringdownload/sql/" + SecurityUtils.getTenantId();
+        String jarDirectoryPath = zkqyConfig.getUploadPath() + "/engineeringdownload/jar/";
+        try {
+            if (StringUtils.isNotNull(state) && !state.isEmpty() && state.equals("true")) {
+                try {
+                    List<Map<String, String>> fileList = listFiles(sqlDirectoryPath, jarDirectoryPath);
+                    try {
+                        response.setContentType("application/x-octet-stream");
+                        response.setHeader("Content-Disposition", "attachment; filename=\"download.zip\"");
+                        response.setCharacterEncoding("utf-8");
+                        ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
+                        byte[] buffer = new byte[1024];
+                        for (Map<String, String> fileMap : fileList) {
+                            String fileName = fileMap.get("fileName");
+                            String filePath = fileMap.get("filePath");
+                            // 使用 File.separator 来实现跨平台兼容性
+                            String relativePath = fileName;
+                            // 在 Zip 中创建带有相对路径的 ZipEntry
+                            zos.putNextEntry(new ZipEntry(relativePath));
+                            try (InputStream is = new FileInputStream(filePath)) {
+                                int length;
+                                while ((length = is.read(buffer)) > 0) {
+                                    zos.write(buffer, 0, length);
+                                }
+                            } catch (IOException e) {
+                                e.printStackTrace();
+                            }
+                            zos.closeEntry();
+                        }
+                        zos.close();
+                        zos.flush();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                    // 下载完成后删除sqlDirectoryPath路径下的所有文件
+                    deleteFilesInDirectory(sqlDirectoryPath);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+                }
+            } else {
+                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+            }
+        } finally {
+            SysEngineering sysEngineering = new SysEngineering();
+            sysEngineering.setCreateTime(DateUtils.getNowDate());
+            sysEngineering.setDownloadTime(DateUtils.getNowDate());
+            sysEngineering.setEngineeringName(SecurityUtils.getLoginUser().getUser().getTenantName() + "-MES");
+            sysEngineering.setTenantId(SecurityUtils.getTenantId());
+            sysEngineeringService.insertSysEngineering(sysEngineering);
+
+            // 删除
+            redisCache.deleteObject("isExportState:" + SecurityUtils.getTenantId());
+        }
+    }
+
+
+    private List<Map<String, String>> listFiles(String sqlDirectoryPath, String jarDirectoryPath) {
+        List<Map<String, String>> fileList = new ArrayList<>();
+        processDirectory(sqlDirectoryPath, fileList);
+        processDirectory(jarDirectoryPath, fileList);
+        return fileList;
+    }
+
+    private void processDirectory(String directoryPath, List<Map<String, String>> fileList) {
+        File directory = new File(directoryPath);
+        if (directory.exists() && directory.isDirectory()) {
+            listFilesRecursively(directory, fileList);
+        }
+    }
+
+    private void listFilesRecursively(File directory, List<Map<String, String>> fileList) {
+        File[] files = directory.listFiles();
+        if (files != null) {
+            for (File file : files) {
+                if (file.isDirectory()) {
+                    listFilesRecursively(file, fileList);
+                } else {
+                    Map<String, String> fileInfo = new HashMap<>();
+                    fileInfo.put("fileName", file.getName());
+                    fileInfo.put("filePath", file.getAbsolutePath());
+                    fileList.add(fileInfo);
+                }
+            }
+        }
+    }
+
+    public void setExportCompleted(boolean value, String tenantKey) {
+        try {
+            exportCompleted = value;
+        } finally {
+            //  设置导出验证有效时间5分钟
+            redisCache.setCacheObject("isExportState:" + tenantKey, "true", 5, TimeUnit.MINUTES);
+        }
+    }
+
+    private void deleteFilesInDirectory(String directoryPath) {
+        File directory = new File(directoryPath);
+        if (directory.exists() && directory.isDirectory()) {
+            File[] files = directory.listFiles();
+            if (files != null) {
+                for (File file : files) {
+                    file.delete();
+                }
+            }
+        }
+    }
+}

+ 130 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/projcetzip/ExportController.java

@@ -0,0 +1,130 @@
+package com.zkqy.web.controller.projcetzip;
+
+import com.zkqy.common.config.ZkqyConfig;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.entity.SysUser;
+import com.zkqy.common.utils.SecurityUtils;
+import com.zkqy.web.controller.tool.TestController;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import com.zkqy.common.core.domain.entity.DataSource;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+
+@RestController
+@RequestMapping("/export/project-db")
+public class ExportController {
+
+    @Autowired
+    private ThreadPoolTaskExecutor taskExecutor;
+
+    @Autowired
+    private DownloadController downloadController;
+
+    // 执行当前环境下的mysql
+    @Value("${projectDownloadZip.mysql}")
+    private String MYSQLDUMP_PATH;
+
+    // sql 生成路径
+    private static final String SQL_OUTPUT_PATH = "sql";
+
+    private static final Logger log = LoggerFactory.getLogger(ExportController.class);
+
+    @PostMapping("/start")
+    public AjaxResult startExport(@RequestBody List<String> databaseNames) {
+        String sourceFilePath = ZkqyConfig.getUploadPath() + "/engineeringdownload/";
+        DataSource datasourceInfo = SecurityUtils.getDatasourceInfo();
+        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
+        String tenantid = sysUser.getTenant().getTenantId().toString();
+//        if (databaseNames == null || databaseNames.isEmpty()) {
+//        databaseNames = Arrays.asList("ry-vue-call", datasourceInfo.getDatabaseName());
+        databaseNames = Arrays.asList(datasourceInfo.getDatabaseName());
+//        }
+        try {
+            // 获取数据库信息等
+            exportDatabases(databaseNames, sourceFilePath, datasourceInfo, tenantid);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("数据生成失败:" + sysUser);
+            return AjaxResult.error("数据生成失败!请联系管理员操作!");
+        }
+        // 导出完成后,设置导出状态为 true
+        downloadController.setExportCompleted(true, sysUser.getTenantId().toString());
+        log.info("导出数据文件成功!" + sysUser.getUserName());
+        return AjaxResult.success("数据生成成功!");
+    }
+
+    private void exportDatabases(List<String> databaseNames, String sourceFilePath, DataSource dataSource, String tenantId) {
+        try {
+            // 并行导出多个数据库
+            CompletableFuture.allOf(
+                    databaseNames.stream()
+                            .map(databaseName ->
+                                    CompletableFuture.runAsync(() ->
+                                            exportDatabase(databaseName, sourceFilePath, dataSource, tenantId), taskExecutor)
+                            )
+                            .toArray(CompletableFuture[]::new)
+            ).get(); // 等待所有导出完成
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void exportDatabase(String databaseName, String sourceFilePath, DataSource dataSource, String tenantId) {
+        String outputPath = sourceFilePath + SQL_OUTPUT_PATH + File.separator + tenantId;
+        try {
+            Files.createDirectories(Paths.get(outputPath));
+            String dumpFileName = outputPath + File.separator + databaseName + ".sql";
+            List<String> cmd = buildMysqldumpCommand(databaseName, dataSource);
+            ProcessBuilder pb = new ProcessBuilder(cmd);
+            pb.redirectOutput(new File(dumpFileName));
+            Process process = pb.start();
+            // 设置导出超时时间为10分钟
+            if (!process.waitFor(10, TimeUnit.MINUTES)) {
+                process.destroyForcibly(); // 超时则强制销毁进程
+                throw new TimeoutException("导出数据库超时");
+            }
+            int exitCode = process.exitValue();
+
+            if (exitCode == 0) {
+                System.out.println("数据库备份成功。导出文件:" + dumpFileName);
+            } else {
+                System.err.println("执行mysqldump命令时发生错误。退出代码:" + exitCode);
+            }
+        } catch (IOException | InterruptedException | TimeoutException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private List<String> buildMysqldumpCommand(String databaseName, DataSource dataSource) {
+        // 使用 Arrays.asList 创建不可变 List
+        //  windwos: mysqldump --column-statistics=0
+        // Linux: 需要指明mysql脚本地址-》/usr/local/mysql/bin/mysqldump
+        return new ArrayList<>(Arrays.asList(
+                MYSQLDUMP_PATH,
+                "-h", dataSource.getDatabaseIp(),
+                "-u", dataSource.getUsername(),
+                "-p" + dataSource.getPassword(),
+                databaseName
+        ));
+    }
+}

+ 80 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/DataSourceController.java

@@ -0,0 +1,80 @@
+package com.zkqy.web.controller.system;
+
+import com.alibaba.fastjson2.JSON;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.entity.DataSource;
+import com.zkqy.common.utils.SecurityUtils;
+import com.zkqy.system.service.IDataSourceService;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.Resource;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/dataSource")
+public class DataSourceController extends BaseController {
+
+    //@Resource
+    //private IDataSourceService dataSourceService;
+//
+//    RestTemplate restTemplate = new RestTemplate();
+//
+//    /**
+//     * 数据引擎切换数据源接口地址
+//     */
+//    @Value("${parameter.ip.DATA_ENGINE_IP}")
+//    public String DATA_ENGINE_IP;
+//
+//    /**
+//     * 动态表单切换数据源接口地址
+//     */
+//    @Value("${parameter.ip.DRAG_FORM_IP}")
+//    public String DRAG_FORM_IP;
+//
+//    @Value("${parameter.ip.PROCESS_ENGINE_IP}")
+//    public String PROCESS_ENGINE_IP;
+//
+//
+//    /**
+//     * 数据源信息列表
+//     */
+////    @GetMapping("/list")
+////    public AjaxResult dataSourceList(){
+////        return AjaxResult.success(dataSourceService.list());
+////    }
+//
+//    /**
+//     * 新增数据源
+//     */
+//    @PostMapping("/save")
+//    public AjaxResult addDataSource(@RequestBody Map<String, Object> map) {
+//
+//        DataSource dataSource = JSON.parseObject(JSON.toJSONString(map.get("dataSource")), DataSource.class);
+//        Integer tenantId = (Integer) map.get("tenantId");
+//        if (dataSourceService.selectDatabaseExist(dataSource) > 0) {
+//            return AjaxResult.error("数据库已存在");
+//        }
+//        //return toAjax(dataSourceService.insertDataSource(dataSource,tenantId.longValue()));
+//        return dataSourceService.insertDataSource(dataSource, tenantId.longValue());
+//    }
+//
+//    /**
+//     * 调用(数据引擎、流程引擎、表单引擎)切换数据源接口
+//     */
+    @PostMapping("/changeDatasource")
+    public AjaxResult changeDatasource() {
+        // admin 没有数据源
+//        if (SecurityUtils.isAdmin(getUserId())) return AjaxResult.success();
+//        DataSource dataSource = SecurityUtils.getDatasourceInfo();
+//        //调用数据引擎服务切换数据源接口
+//        restTemplate.postForEntity(DATA_ENGINE_IP, dataSource, DataSource.class);
+//        //调用表单引擎服务切换数据源接口
+//        restTemplate.postForEntity(DRAG_FORM_IP, dataSource, DataSource.class);
+//        //调用流程引擎服务切换数据源接口
+//        restTemplate.postForEntity(PROCESS_ENGINE_IP, dataSource, DataSource.class);
+        return AjaxResult.success();
+    }
+}

+ 110 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/LoginPageConfigurationController.java

@@ -0,0 +1,110 @@
+package com.zkqy.web.controller.system;
+
+import com.zkqy.common.annotation.Anonymous;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.system.domain.LoginPageConfiguration;
+import com.zkqy.system.service.ILoginPageConfigurationService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 登录页面配置信息Controller
+ *
+ * @author zkqy
+ * @date 2024-01-22
+ */
+@RestController
+@RequestMapping("/system/configuration")
+@Api(value = "/system/configuration", description = "登录页面配置信息-接口")
+public class LoginPageConfigurationController extends BaseController {
+    @Autowired
+    private ILoginPageConfigurationService loginPageConfigurationService;
+
+    /**
+     * 查询登录页面配置信息列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:configuration:list')")
+    @GetMapping("/list")
+    @ApiOperation(value = "查询登录页面配置信息列表")
+    public TableDataInfo list(LoginPageConfiguration loginPageConfiguration) {
+        startPage();
+        List<LoginPageConfiguration> list = loginPageConfigurationService.selectLoginPageConfigurationList(loginPageConfiguration);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出登录页面配置信息列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:configuration:export')")
+    @Log(title = "登录页面配置信息", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    @ApiOperation(value = "导出登录页面配置信息列表")
+    public void export(HttpServletResponse response, LoginPageConfiguration loginPageConfiguration) {
+        List<LoginPageConfiguration> list = loginPageConfigurationService.selectLoginPageConfigurationList(loginPageConfiguration);
+        ExcelUtil<LoginPageConfiguration> util = new ExcelUtil<LoginPageConfiguration>(LoginPageConfiguration.class);
+        util.exportExcel(response, list, "登录页面配置信息数据");
+    }
+
+    /**
+     * 获取登录页面配置信息详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:configuration:query')")
+    @GetMapping(value = "/{tenantId}")
+    @ApiOperation(value = "获取登录页面配置信息详细信息")
+    public AjaxResult getInfo(@PathVariable("tenantId") Long tenantId) {
+        return success(loginPageConfigurationService.selectLoginPageConfigurationByTenantId(tenantId));
+    }
+
+    /**
+     * 根据登录编号查询详细信息
+     */
+    @Anonymous
+    @GetMapping("/queryLoginPageConfigurationInfo/{loginPageNumber}")
+    public AjaxResult queryLoginPageConfigurationInfo(@PathVariable("loginPageNumber") String loginPageNumber) {
+        return success(loginPageConfigurationService.selectLoginPageConfigurationByLoginPageNumber(loginPageNumber,"client"));
+    }
+
+    /**
+     * 新增登录页面配置信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:configuration:add')")
+    @Log(title = "登录页面配置信息", businessType = BusinessType.INSERT)
+    @PostMapping
+    @ApiOperation(value = "新增登录页面配置信息")
+    public AjaxResult add(@RequestBody LoginPageConfiguration loginPageConfiguration) {
+        return toAjax(loginPageConfigurationService.insertLoginPageConfiguration(loginPageConfiguration));
+    }
+
+    /**
+     * 修改登录页面配置信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:configuration:edit')")
+    @Log(title = "登录页面配置信息", businessType = BusinessType.UPDATE)
+    @PutMapping
+    @ApiOperation(value = "修改登录页面配置信息")
+    public AjaxResult edit(@RequestBody LoginPageConfiguration loginPageConfiguration) {
+        return toAjax(loginPageConfigurationService.updateLoginPageConfiguration(loginPageConfiguration));
+    }
+
+    /**
+     * 删除登录页面配置信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:configuration:remove')")
+    @Log(title = "登录页面配置信息", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    @ApiOperation(value = "删除登录页面配置信息")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(loginPageConfigurationService.deleteLoginPageConfigurationByIds(ids));
+    }
+}

+ 112 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysBpmNodeScriptController.java

@@ -0,0 +1,112 @@
+package com.zkqy.web.controller.system;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.system.domain.SysBpmNodeScript;
+import com.zkqy.system.service.ISysBpmNodeScriptService;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.common.core.page.TableDataInfo;
+
+/**
+ * 流程节点脚本Controller
+ *
+ * @author ruoyi
+ * @date 2023-10-26
+ */
+@RestController
+@RequestMapping("/system/script")
+@Api(value = "/system/script")
+public class SysBpmNodeScriptController extends BaseController
+{
+    @Autowired
+    private ISysBpmNodeScriptService sysBpmNodeScriptService;
+
+    /**
+     * 查询流程节点脚本列表
+     */
+//    //@PreAuthorize("@ss.hasPermi('system:script:list')")
+    @GetMapping("/list")
+    @ApiOperation(value = "查询流程节点脚本列表")
+    public TableDataInfo list(SysBpmNodeScript sysBpmNodeScript)
+    {
+        startPage();
+        List<SysBpmNodeScript> list = sysBpmNodeScriptService.selectSysBpmNodeScriptList(sysBpmNodeScript);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出流程节点脚本列表
+     */
+//    //@PreAuthorize("@ss.hasPermi('system:script:export')")
+    @Log(title = "流程节点脚本", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    @ApiOperation(value = "导出流程节点脚本列表")
+    public void export(HttpServletResponse response, SysBpmNodeScript sysBpmNodeScript)
+    {
+        List<SysBpmNodeScript> list = sysBpmNodeScriptService.selectSysBpmNodeScriptList(sysBpmNodeScript);
+        ExcelUtil<SysBpmNodeScript> util = new ExcelUtil<SysBpmNodeScript>(SysBpmNodeScript.class);
+        util.exportExcel(response, list, "流程节点脚本数据");
+    }
+
+    /**
+     * 获取流程节点脚本详细信息
+     */
+//    //@PreAuthorize("@ss.hasPermi('system:script:query')")
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "获取流程节点脚本详细信息")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(sysBpmNodeScriptService.selectSysBpmNodeScriptById(id));
+    }
+
+    /**
+     * 新增流程节点脚本
+     */
+//    //@PreAuthorize("@ss.hasPermi('system:script:add')")
+    @Log(title = "流程节点脚本", businessType = BusinessType.INSERT)
+    @PostMapping
+    @ApiOperation(value = "新增流程节点脚本")
+    public AjaxResult add(@RequestBody SysBpmNodeScript sysBpmNodeScript)
+    {
+        return toAjax(sysBpmNodeScriptService.insertSysBpmNodeScript(sysBpmNodeScript));
+    }
+
+    /**
+     * 修改流程节点脚本
+     */
+//    //@PreAuthorize("@ss.hasPermi('system:script:edit')")
+    @Log(title = "流程节点脚本", businessType = BusinessType.UPDATE)
+    @PutMapping
+    @ApiOperation(value = "修改流程节点脚本")
+    public AjaxResult edit(@RequestBody SysBpmNodeScript sysBpmNodeScript)
+    {
+        return toAjax(sysBpmNodeScriptService.updateSysBpmNodeScript(sysBpmNodeScript));
+    }
+
+    /**
+     * 删除流程节点脚本
+     */
+//    //@PreAuthorize("@ss.hasPermi('system:script:remove')")
+    @Log(title = "流程节点脚本", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    @ApiOperation(value = "删除流程节点脚本")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(sysBpmNodeScriptService.deleteSysBpmNodeScriptByIds(ids));
+    }
+}

+ 133 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysConfigController.java

@@ -0,0 +1,133 @@
+package com.zkqy.web.controller.system;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.system.domain.SysConfig;
+import com.zkqy.system.service.ISysConfigService;
+
+/**
+ * 参数配置 信息操作处理
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/system/config")
+public class SysConfigController extends BaseController
+{
+    @Autowired
+    private ISysConfigService configService;
+
+    /**
+     * 获取参数配置列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:config:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysConfig config)
+    {
+        startPage();
+        List<SysConfig> list = configService.selectConfigList(config);
+        return getDataTable(list);
+    }
+
+    @Log(title = "参数管理", businessType = BusinessType.EXPORT)
+    //@PreAuthorize("@ss.hasPermi('system:config:export')")
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SysConfig config)
+    {
+        List<SysConfig> list = configService.selectConfigList(config);
+        ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
+        util.exportExcel(response, list, "参数数据");
+    }
+
+    /**
+     * 根据参数编号获取详细信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:config:query')")
+    @GetMapping(value = "/{configId}")
+    public AjaxResult getInfo(@PathVariable Long configId)
+    {
+        return success(configService.selectConfigById(configId));
+    }
+
+    /**
+     * 根据参数键名查询参数值
+     */
+    @GetMapping(value = "/configKey/{configKey}")
+    public AjaxResult getConfigKey(@PathVariable String configKey)
+    {
+        return success(configService.selectConfigByKey(configKey));
+    }
+
+    /**
+     * 新增参数配置
+     */
+    //@PreAuthorize("@ss.hasPermi('system:config:add')")
+    @Log(title = "参数管理", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@Validated @RequestBody SysConfig config)
+    {
+        if (!configService.checkConfigKeyUnique(config))
+        {
+            return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
+        }
+        config.setCreateBy(getUsername());
+        return toAjax(configService.insertConfig(config));
+    }
+
+    /**
+     * 修改参数配置
+     */
+    //@PreAuthorize("@ss.hasPermi('system:config:edit')")
+    @Log(title = "参数管理", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@Validated @RequestBody SysConfig config)
+    {
+        if (!configService.checkConfigKeyUnique(config))
+        {
+            return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
+        }
+        config.setUpdateBy(getUsername());
+        return toAjax(configService.updateConfig(config));
+    }
+
+    /**
+     * 删除参数配置
+     */
+    //@PreAuthorize("@ss.hasPermi('system:config:remove')")
+    @Log(title = "参数管理", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{configIds}")
+    public AjaxResult remove(@PathVariable Long[] configIds)
+    {
+        configService.deleteConfigByIds(configIds);
+        return success();
+    }
+
+    /**
+     * 刷新参数缓存
+     */
+    //@PreAuthorize("@ss.hasPermi('system:config:remove')")
+    @Log(title = "参数管理", businessType = BusinessType.CLEAN)
+    @DeleteMapping("/refreshCache")
+    public AjaxResult refreshCache()
+    {
+        configService.resetConfigCache();
+        return success();
+    }
+}

+ 135 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysDeptController.java

@@ -0,0 +1,135 @@
+package com.zkqy.web.controller.system;
+
+import java.util.List;
+import org.apache.commons.lang3.ArrayUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.constant.UserConstants;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.entity.SysDept;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.system.service.ISysDeptService;
+
+/**
+ * 部门信息
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/system/dept")
+public class SysDeptController extends BaseController
+{
+    @Autowired
+    private ISysDeptService deptService;
+
+    /**
+     * 获取部门列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dept:list')")
+    @GetMapping("/list")
+    public AjaxResult list(SysDept dept)
+    {
+        if (getLoginUser().isTenantAdmin()) {
+            dept.setTenantId(getTenantId());
+        }
+        List<SysDept> depts = deptService.selectDeptList(dept);
+        return success(depts);
+    }
+
+    /**
+     * 查询部门列表(排除节点)
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dept:list')")
+    @GetMapping("/list/exclude/{deptId}")
+    public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId)
+    {
+        List<SysDept> depts = deptService.selectDeptList(new SysDept());
+        depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""));
+        return success(depts);
+    }
+
+    /**
+     * 根据部门编号获取详细信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dept:query')")
+    @GetMapping(value = "/{deptId}")
+    public AjaxResult getInfo(@PathVariable Long deptId)
+    {
+        deptService.checkDeptDataScope(deptId);
+        return success(deptService.selectDeptById(deptId));
+    }
+
+    /**
+     * 新增部门
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dept:add')")
+    @Log(title = "部门管理", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@Validated @RequestBody SysDept dept)
+    {
+        if (!deptService.checkDeptNameUnique(dept))
+        {
+            return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
+        }
+        dept.setCreateBy(getUsername());
+        return toAjax(deptService.insertDept(dept));
+    }
+
+    /**
+     * 修改部门
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dept:edit')")
+    @Log(title = "部门管理", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@Validated @RequestBody SysDept dept)
+    {
+        Long deptId = dept.getDeptId();
+        deptService.checkDeptDataScope(deptId);
+        if (!deptService.checkDeptNameUnique(dept))
+        {
+            return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
+        }
+        else if (dept.getParentId().equals(deptId))
+        {
+            return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
+        }
+        else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
+        {
+            return error("该部门包含未停用的子部门!");
+        }
+        dept.setUpdateBy(getUsername());
+        return toAjax(deptService.updateDept(dept));
+    }
+
+    /**
+     * 删除部门
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dept:remove')")
+    @Log(title = "部门管理", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{deptId}")
+    public AjaxResult remove(@PathVariable Long deptId)
+    {
+        if (deptService.hasChildByDeptId(deptId))
+        {
+            return warn("存在下级部门,不允许删除");
+        }
+        if (deptService.checkDeptExistUser(deptId))
+        {
+            return warn("部门存在用户,不允许删除");
+        }
+        deptService.checkDeptDataScope(deptId);
+        return toAjax(deptService.deleteDeptById(deptId));
+    }
+}

+ 126 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysDictDataController.java

@@ -0,0 +1,126 @@
+package com.zkqy.web.controller.system;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import com.zkqy.common.annotation.Anonymous;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.entity.SysDictData;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.system.service.ISysDictDataService;
+import com.zkqy.system.service.ISysDictTypeService;
+
+/**
+ * 数据字典信息
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/system/dict/data")
+public class SysDictDataController extends BaseController {
+    @Autowired
+    private ISysDictDataService dictDataService;
+
+    @Autowired
+    private ISysDictTypeService dictTypeService;
+
+    //    //@PreAuthorize("@ss.hasPermi('system:dict:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysDictData dictData) {
+        startPage();
+        List<SysDictData> list = dictDataService.selectDictDataList(dictData);
+        return getDataTable(list);
+    }
+
+    @Log(title = "字典数据", businessType = BusinessType.EXPORT)
+    //@PreAuthorize("@ss.hasPermi('system:dict:export')")
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SysDictData dictData) {
+        List<SysDictData> list = dictDataService.selectDictDataList(dictData);
+        ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class);
+        util.exportExcel(response, list, "字典数据");
+    }
+
+    /**
+     * 查询字典数据详细
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dict:query')")
+    @GetMapping(value = "/{dictCode}")
+    public AjaxResult getInfo(@PathVariable Long dictCode) {
+        return success(dictDataService.selectDictDataById(dictCode));
+    }
+
+
+    /**
+     * 根据dict_label查询字典数据详细
+     * 根据编码查询--对应后的转码信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dict:query')")
+    @GetMapping(value = "/getDictLabel/{dictLabel}")
+    public AjaxResult getInfoByDictLabel(@PathVariable String dictLabel) {
+        return success(dictDataService.selectDictDataByDictLabel(dictLabel));
+    }
+
+
+    /**
+     * 根据字典类型查询字典数据信息
+     */
+    @GetMapping(value = "/type/{dictType}")
+    public AjaxResult dictType(@PathVariable String dictType) {
+        List<SysDictData> data = dictTypeService.selectDictDataByTypeAllTenant(dictType);
+        if (StringUtils.isNull(data)) {
+            data = new ArrayList<>();
+        }
+        return success(data);
+    }
+
+    /**
+     * 新增字典类型
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dict:add')")
+    @Log(title = "字典数据", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@Validated @RequestBody SysDictData dict) {
+        dict.setCreateBy(getUsername());
+        return toAjax(dictDataService.insertDictData(dict));
+    }
+
+    /**
+     * 修改保存字典类型
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dict:edit')")
+    @Log(title = "字典数据", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@Validated @RequestBody SysDictData dict) {
+        dict.setUpdateBy(getUsername());
+        return toAjax(dictDataService.updateDictData(dict));
+    }
+
+    /**
+     * 删除字典类型
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dict:remove')")
+    @Log(title = "字典类型", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{dictCodes}")
+    public AjaxResult remove(@PathVariable Long[] dictCodes) {
+        dictDataService.deleteDictDataByIds(dictCodes);
+        return success();
+    }
+}

+ 131 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysDictTypeController.java

@@ -0,0 +1,131 @@
+package com.zkqy.web.controller.system;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.entity.SysDictType;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.system.service.ISysDictTypeService;
+
+/**
+ * 数据字典信息
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/system/dict/type")
+public class SysDictTypeController extends BaseController
+{
+    @Autowired
+    private ISysDictTypeService dictTypeService;
+
+    //@PreAuthorize("@ss.hasPermi('system:dict:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysDictType dictType)
+    {
+        startPage();
+        List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
+        return getDataTable(list);
+    }
+
+    @Log(title = "字典类型", businessType = BusinessType.EXPORT)
+    //@PreAuthorize("@ss.hasPermi('system:dict:export')")
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SysDictType dictType)
+    {
+        List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
+        ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class);
+        util.exportExcel(response, list, "字典类型");
+    }
+
+    /**
+     * 查询字典类型详细
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dict:query')")
+    @GetMapping(value = "/{dictId}")
+    public AjaxResult getInfo(@PathVariable Long dictId)
+    {
+        return success(dictTypeService.selectDictTypeById(dictId));
+    }
+
+    /**
+     * 新增字典类型
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dict:add')")
+    @Log(title = "字典类型", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@Validated @RequestBody SysDictType dict)
+    {
+        if (!dictTypeService.checkDictTypeUnique(dict))
+        {
+            return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
+        }
+        dict.setCreateBy(getUsername());
+        return toAjax(dictTypeService.insertDictType(dict));
+    }
+
+    /**
+     * 修改字典类型
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dict:edit')")
+    @Log(title = "字典类型", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@Validated @RequestBody SysDictType dict)
+    {
+        if (!dictTypeService.checkDictTypeUnique(dict))
+        {
+            return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
+        }
+        dict.setUpdateBy(getUsername());
+        return toAjax(dictTypeService.updateDictType(dict));
+    }
+
+    /**
+     * 删除字典类型
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dict:remove')")
+    @Log(title = "字典类型", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{dictIds}")
+    public AjaxResult remove(@PathVariable Long[] dictIds)
+    {
+        dictTypeService.deleteDictTypeByIds(dictIds);
+        return success();
+    }
+
+    /**
+     * 刷新字典缓存
+     */
+    //@PreAuthorize("@ss.hasPermi('system:dict:remove')")
+    @Log(title = "字典类型", businessType = BusinessType.CLEAN)
+    @DeleteMapping("/refreshCache")
+    public AjaxResult refreshCache()
+    {
+        dictTypeService.resetDictCache();
+        return success();
+    }
+
+    /**
+     * 获取字典选择框列表
+     */
+    @GetMapping("/optionselect")
+    public AjaxResult optionselect()
+    {
+        List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll();
+        return success(dictTypes);
+    }
+}

+ 338 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysEngineeringController.java

@@ -0,0 +1,338 @@
+package com.zkqy.web.controller.system;
+
+import java.io.*;
+import java.net.URLEncoder;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+
+import cn.hutool.core.io.FileUtil;
+import com.zkqy.common.annotation.Anonymous;
+import com.zkqy.common.config.ZkqyConfig;
+import com.zkqy.common.core.domain.entity.DataSource;
+import com.zkqy.common.core.domain.entity.SysUser;
+import com.zkqy.common.utils.DateUtils;
+import com.zkqy.common.utils.SecurityUtils;
+import com.zkqy.common.utils.ZipUtils;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.system.domain.SysEngineering;
+import com.zkqy.system.service.ISysEngineeringService;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.common.core.page.TableDataInfo;
+import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
+
+/**
+ * 工程部署Controller
+ *
+ * @author zkqy
+ * @date 2024-01-03
+ */
+@RestController
+@RequestMapping("/system/engineering")
+public class SysEngineeringController extends BaseController {
+    @Autowired
+    private ISysEngineeringService sysEngineeringService;
+
+    /**
+     * 查询工程部署列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:engineering:list')")
+    @GetMapping("/list")
+    @ApiOperation(value = "查询工程部署列表")
+    public TableDataInfo list(SysEngineering sysEngineering) {
+        startPage();
+        List<SysEngineering> list = sysEngineeringService.selectSysEngineeringList(sysEngineering);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出工程部署列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:engineering:export')")
+    @Log(title = "工程部署", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    @ApiOperation(value = "导出工程部署列表")
+    public void export(HttpServletResponse response, SysEngineering sysEngineering) {
+        List<SysEngineering> list = sysEngineeringService.selectSysEngineeringList(sysEngineering);
+        ExcelUtil<SysEngineering> util = new ExcelUtil<SysEngineering>(SysEngineering.class);
+        util.exportExcel(response, list, "工程部署数据");
+    }
+
+    /**
+     * 获取工程部署详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:engineering:query')")
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "获取工程部署详细信息")
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
+        return success(sysEngineeringService.selectSysEngineeringById(id));
+    }
+
+    /**
+     * 新增工程部署
+     */
+    @PreAuthorize("@ss.hasPermi('system:engineering:add')")
+    @Log(title = "工程部署", businessType = BusinessType.INSERT)
+    @PostMapping
+    @ApiOperation(value = "新增工程部署")
+    public AjaxResult add(@RequestBody SysEngineering sysEngineering) {
+        return toAjax(sysEngineeringService.insertSysEngineering(sysEngineering));
+    }
+
+    /**
+     * 修改工程部署
+     */
+    @PreAuthorize("@ss.hasPermi('system:engineering:edit')")
+    @Log(title = "工程部署", businessType = BusinessType.UPDATE)
+    @PutMapping
+    @ApiOperation(value = "修改工程部署")
+    public AjaxResult edit(@RequestBody SysEngineering sysEngineering) {
+        return toAjax(sysEngineeringService.updateSysEngineering(sysEngineering));
+    }
+
+    /**
+     * 删除工程部署
+     */
+    @PreAuthorize("@ss.hasPermi('system:engineering:remove')")
+    @Log(title = "工程部署", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    @ApiOperation(value = "删除工程部署")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(sysEngineeringService.deleteSysEngineeringByIds(ids));
+    }
+
+
+    @GetMapping("/largeFile")
+    public ResponseEntity<Resource> downloadLargeFile() {
+        // 调用Service层获取文件
+        File name = new File("/Users/zrwj/Downloads/123.zip");
+        // 调用 FileDownloadService 中的方法获取文件
+        if (Objects.isNull(name)) {
+            throw new RuntimeException("文件名称不能为空");
+        }
+        // directoryPath为服务器文件路径
+        String path = "" + name;
+        File file = new File(path);
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
+        headers.add("Content-Disposition", "attachment; filename=" + file.getName());
+        headers.add("Pragma", "no-cache");
+        headers.add("Expires", "0");
+        headers.add("Last-Modified", new Date().toString());
+        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
+        return ResponseEntity
+                .ok()
+                .headers(headers)
+                .contentLength(file.length())
+                .contentType(MediaType.parseMediaType("application/octet-stream"))
+                .body(new FileSystemResource(file));
+
+    }
+
+    /**
+     * 下载压缩包
+     */
+    @GetMapping("/download")
+    public ResponseEntity<StreamingResponseBody> downloadZip() {
+        // 指定要打包的文件或目录路径
+        String sourceFilePath = ZkqyConfig.getUploadPath() + "/engineeringdownload/";
+
+        File dir = new File(sourceFilePath);
+        // 判断文件夹路径是否存在,不存在创建
+        if (!dir.exists()) {
+            boolean isCreated = dir.mkdirs();
+            if (!isCreated) {
+                System.out.println("目录 '" + sourceFilePath + "' 创建失败.");
+            }
+        }
+        //当前用户数据源信息
+        DataSource datasourceInfo = SecurityUtils.getDatasourceInfo();
+        //导出数据库集合
+        Set<String> databaseList = new LinkedHashSet<>();
+        databaseList.add("ry-vue-call");
+        //        databaseList.add("zkqy-template");
+//        databaseList.add("zkqy-call");
+        databaseList.add(datasourceInfo.getDatabaseName());
+        //将sql文件导出到指定目录下
+        exportMultipleDatabasesToLocal(databaseList, sourceFilePath, datasourceInfo);
+        //下载成功插入数据
+        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
+        SysEngineering sysEngineering = new SysEngineering();
+        sysEngineering.setCreateTime(DateUtils.getNowDate());
+        sysEngineering.setDownloadTime(DateUtils.getNowDate());
+        sysEngineering.setEngineeringName(sysUser.getTenantName() + "-mes");
+        sysEngineeringService.insertSysEngineering(sysEngineering);
+
+        String zipFileName = new Date().getTime() + ".zip";
+        HttpHeaders headers = new HttpHeaders();
+        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + zipFileName + "\"");
+        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
+
+        return ResponseEntity.ok()
+                .headers(headers)
+                .contentType(MediaType.APPLICATION_OCTET_STREAM)
+                .body(outputStream -> {
+                    try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(sourceFilePath));
+                         ZipOutputStream zipOut = new ZipOutputStream(outputStream)) {
+                        addFilesToZipRecursively(zipOut, Paths.get(sourceFilePath), directoryStream);
+                    } catch (IOException e) {
+                        throw new RuntimeException("Failed to create the ZIP stream.", e);
+                    }
+                });
+    }
+
+
+    /**
+     * 下载压缩包
+     */
+
+    @Anonymous
+    @GetMapping("/download1")
+    public void downloadZip1(HttpServletResponse response) {
+        // 指定要打包的文件或目录路径
+        String sourceFilePath = ZkqyConfig.getUploadPath() + "/engineeringdownload/";
+        //当前用户数据源信息
+        DataSource datasourceInfo = SecurityUtils.getDatasourceInfo();
+        //导出数据库集合
+        Set<String> databaseList = new LinkedHashSet<>();
+        databaseList.add("ry-vue-call");
+        databaseList.add(datasourceInfo.getDatabaseName());
+        //将sql文件导出到指定目录下
+        exportMultipleDatabasesToLocal(databaseList, sourceFilePath, datasourceInfo);
+        //下载成功插入数据
+        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
+        SysEngineering sysEngineering = new SysEngineering();
+        sysEngineering.setCreateTime(DateUtils.getNowDate());
+        sysEngineering.setDownloadTime(DateUtils.getNowDate());
+        sysEngineering.setEngineeringName(sysUser.getTenantName() + "-mes");
+        sysEngineeringService.insertSysEngineering(sysEngineering);
+        List<Map<String, String>> fileList = listFiles(sourceFilePath);
+        ZipUtils.createZip(response, fileList);
+    }
+
+
+    private void addFilesToZipRecursively(ZipOutputStream zipOut, Path rootPath, DirectoryStream<Path> dirStream) throws
+            IOException {
+        for (Path filePath : dirStream) {
+            if (Files.isDirectory(filePath)) {
+                // 添加目录条目到ZIP
+                String entryName = filePath.toString().substring(rootPath.toString().length() + 1) + "/";
+                zipOut.putNextEntry(new ZipEntry(entryName));
+                zipOut.closeEntry();
+
+                // 递归处理子目录中的文件
+                try (DirectoryStream<Path> subDirStream = Files.newDirectoryStream(filePath)) {
+                    addFilesToZipRecursively(zipOut, rootPath, subDirStream);
+                }
+            } else if (Files.isRegularFile(filePath)) {
+                // 添加文件到ZIP
+                String entryName = filePath.toString().substring(rootPath.toString().length() + 1);
+                zipOut.putNextEntry(new ZipEntry(entryName));
+
+                try (InputStream fileIn = Files.newInputStream(filePath)) {
+                    byte[] buffer = new byte[4096];
+                    int read;
+                    while ((read = fileIn.read(buffer)) != -1) {
+                        zipOut.write(buffer, 0, read);
+                    }
+                }
+
+                zipOut.closeEntry();
+            }
+        }
+    }
+
+    /**
+     * 导出数据库文件
+     */
+    private static final String MYSQLDUMP_PATH = "/usr/local/mysql/bin/mysqldump";
+//    private static final String OUTPUT_PATH = "sql/";
+
+    public void exportMultipleDatabasesToLocal(Set<String> databaseNames, String sourceFilePath, DataSource dataSource) {
+
+        String outputPath = sourceFilePath + "sql/" + SecurityUtils.getTenantId();
+
+        try {
+            Files.createDirectories(Paths.get(outputPath));
+
+            for (String databaseName : databaseNames) {
+                String dumpFileName = outputPath + "/" + databaseName + ".sql";
+                List<String> cmd = buildMysqldumpCommand(databaseName, dataSource);
+
+                ProcessBuilder pb = new ProcessBuilder(cmd);
+                pb.redirectOutput(new File(dumpFileName));
+
+                Process process = pb.start();
+                int exitCode = process.waitFor();
+
+                if (exitCode == 0) {
+                    System.out.println("数据库备份成功,导出文件: " + dumpFileName);
+                } else {
+                    System.err.println("mysqldump命令执行失败,退出代码: " + exitCode);
+                }
+            }
+        } catch (IOException | InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private List<String> buildMysqldumpCommand(String databaseName, DataSource dataSource) {
+        List<String> cmd = new ArrayList<>();
+        cmd.add(MYSQLDUMP_PATH);
+        cmd.add("-h");
+        cmd.add(dataSource.getDatabaseIp());
+        cmd.add("-u");
+        cmd.add(dataSource.getUsername());
+        cmd.add("-p" + dataSource.getPassword());
+        cmd.add(databaseName);
+        return cmd;
+    }
+
+    public static List<Map<String, String>> listFiles(String directoryPath) {
+        List<Map<String, String>> fileList = new ArrayList<>();
+        File directory = new File(directoryPath);
+
+        if (directory.exists() && directory.isDirectory()) {
+            listFilesRecursively(directory, fileList);
+        }
+
+        return fileList;
+    }
+
+    private static void listFilesRecursively(File directory, List<Map<String, String>> fileList) {
+        File[] files = directory.listFiles();
+
+        if (files != null) {
+            for (File file : files) {
+                if (file.isFile()) {
+                    Map<String, String> fileMap = new HashMap<>();
+                    fileMap.put("fileName", file.getName());
+                    fileMap.put("filePath", file.getAbsolutePath());
+                    fileList.add(fileMap);
+                } else if (file.isDirectory()) {
+                    listFilesRecursively(file, fileList);
+                }
+            }
+        }
+    }
+
+
+}

+ 29 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysIndexController.java

@@ -0,0 +1,29 @@
+package com.zkqy.web.controller.system;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.config.ZkqyConfig;
+import com.zkqy.common.utils.StringUtils;
+
+/**
+ * 首页
+ *
+ * @author ruoyi
+ */
+@RestController
+public class SysIndexController
+{
+    /** 系统基础配置 */
+    @Autowired
+    private ZkqyConfig ruoyiConfig;
+
+    /**
+     * 访问首页,提示语
+     */
+    @RequestMapping("/")
+    public String index()
+    {
+        return StringUtils.format("生产协同{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion());
+    }
+}

+ 393 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysLoginController.java

@@ -0,0 +1,393 @@
+package com.zkqy.web.controller.system;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import com.zkqy.business.entity.MobilePageData;
+import com.zkqy.business.service.IMobilePageDataService;
+import com.zkqy.common.core.domain.entity.DataSource;
+import com.zkqy.common.core.domain.entity.SysTenant;
+import com.zkqy.common.core.domain.model.LoginUser;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.framework.web.service.TokenService;
+import com.zkqy.system.domain.LoginPageConfiguration;
+import com.zkqy.system.service.*;
+import com.zkqy.system.service.impl.LoginPageConfigurationServiceImpl;
+import com.zkqy.system.service.impl.SysTenantServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.*;
+import com.zkqy.common.constant.Constants;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.entity.SysMenu;
+import com.zkqy.common.core.domain.entity.SysUser;
+import com.zkqy.common.core.domain.model.LoginBody;
+import com.zkqy.common.utils.SecurityUtils;
+import com.zkqy.framework.web.service.SysLoginService;
+import com.zkqy.framework.web.service.SysPermissionService;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+/**
+ * 登录验证
+ *
+ * @author ruoyi
+ */
+@RestController
+public class SysLoginController {
+
+
+    @Autowired
+    private SysLoginService loginService;
+
+    @Autowired
+    private ISysUserService userService;
+
+    @Autowired
+    private ISysMenuService menuService;
+
+    @Autowired
+    private SysPermissionService permissionService;
+
+    @Resource
+    private SysTenantServiceImpl sysTenantService;
+
+    @Resource
+    private TokenService tokenService;
+
+    @Resource
+    private ISysTenantService iSysTenantService;
+
+    @Resource
+    private IMobilePageDataService iMobilePageDataService;
+
+
+    @Autowired //登录页面配置信息
+    private ILoginPageConfigurationService loginPageConfigurationService;
+
+    //@Resource
+    //private IDataSourceService dataSourceService;
+
+    /**
+     * 数据引擎切换数据源接口地址
+     */
+    //@Value("${parameter.ip.DATA_ENGINE_IP}")
+    //public String DATA_ENGINE_IP;
+
+    /**
+     * 动态表单切换数据源接口地址
+     */
+    //@Value("${parameter.ip.DRAG_FORM_IP}")
+    //public String DRAG_FORM_IP;
+
+    /**
+     * 流程引擎切换数据源地址接口
+     */
+    //@Value("${parameter.ip.PROCESS_ENGINE_IP}")
+    //public String PROCESS_ENGINE_IP;
+
+    RestTemplate restTemplate = new RestTemplate();
+
+
+    /**
+     * 登录方法
+     *
+     * @param loginBody 登录信息
+     * @return 结果
+     */
+    @PostMapping("/login")
+    public AjaxResult login(@Valid @RequestBody LoginBody loginBody, BindingResult bindingResult) {
+        // 验证当前登录用的账号是否有效
+//        if (loginService.checkLogin(loginBody)) return AjaxResult.error("请合法登录!");
+        if (bindingResult.hasErrors()) {
+            return AjaxResult.error(bindingResult.getFieldError().getDefaultMessage());
+        }
+        //校验租户状态?生成token
+        AjaxResult ajax = AjaxResult.success();
+        //校验不能是admin
+        if (loginBody.getUsername().equals("admin")) {
+            return AjaxResult.error("未有此用户信息");
+        }
+        // 生成令牌
+        String token = loginService.login(loginBody.getTenantID() + "¥¥¥" + loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
+                loginBody.getUuid(), true);
+        if (tokenService.getLoginUserIsAdminByToken(token)) {
+            return AjaxResult.error("用户不存在!");
+        }
+        //检查租户过期时间
+        String checkTenantExpirationTimeMsg = loginService.checkTenantExpirationTime(loginBody.getTenantID() + "¥¥¥" + loginBody.getUsername());
+        if (!checkTenantExpirationTimeMsg.isEmpty()) {
+            return AjaxResult.error(checkTenantExpirationTimeMsg);
+        }
+        ajax.put(Constants.TOKEN, token);
+        return ajax;
+    }
+
+    /**
+     * 登录方法
+     *
+     * @param loginBody 登录信息
+     * @return 结果
+     */
+    @PostMapping("/tenantLogin")
+    public AjaxResult tenantLogin(@Valid @RequestBody LoginBody loginBody, BindingResult bindingResult) {
+        // 验证当前登录用的账号是否有效
+//        if (loginService.checkLogin(loginBody)) return AjaxResult.error("请合法登录!");
+        if (bindingResult.hasErrors()) {
+            return AjaxResult.error(bindingResult.getFieldError().getDefaultMessage());
+        }
+        //校验租户状态?生成token
+        AjaxResult ajax = AjaxResult.success();
+        //校验不能是admin
+        if (loginBody.getUsername().equals("admin")) {
+            return AjaxResult.error("未有此用户信息");
+        }
+        // 生成令牌
+        String token = loginService.tenantLogin(loginBody.getTenantID(), loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
+                loginBody.getUuid(), true);
+        if (tokenService.getLoginUserIsAdminByToken(token)) {
+            return AjaxResult.error("用户不存在!");
+        }
+        //检查租户过期时间
+        String checkTenantExpirationTimeMsg = loginService.checkTenantExpirationTime(loginBody.getUsername());
+        if (!checkTenantExpirationTimeMsg.isEmpty()) {
+            return AjaxResult.error(checkTenantExpirationTimeMsg);
+        }
+        ajax.put(Constants.TOKEN, token);
+        return ajax;
+    }
+
+    /**
+     * 单点登录调用模拟登录方法
+     *
+     * @param loginInfo 登录信息
+     * @return 结果
+     */
+    @GetMapping("/Oauth2Login/{loginInfo}")
+    public AjaxResult Oauth2Login(@PathVariable String loginInfo) {
+        if (StringUtils.isEmpty(loginInfo)) {
+            return AjaxResult.error("用户不存在!");
+        }
+        // 恢复(解码)数据
+        byte[] decodedBytes = Base64.getDecoder().decode(loginInfo);
+        String decodedCredentials = new String(decodedBytes, StandardCharsets.UTF_8);
+        String[] code = decodedCredentials.split("\\^\\_\\^");
+        if (code.length != 3) {
+            return AjaxResult.error("用户不存在!");
+        }
+        LoginBody loginBody = new LoginBody();
+        loginBody.setTenantID(code[2]);
+        loginBody.setUsername(code[1]);
+        AjaxResult ajax = AjaxResult.success();
+        // 生成令牌
+        String token = loginService.loginOauth(code[0], code[1]);
+        if (tokenService.getLoginUserIsAdminByToken(token)) {
+            return AjaxResult.error("用户不存在!");
+        }
+        // 校验租户是否过期
+        String checkTenantExpirationTimeMsg = loginService.checkTenantExpirationTime(loginBody.getTenantID() + "¥¥¥" + loginBody.getUsername());
+        if (!checkTenantExpirationTimeMsg.isEmpty()) {
+            return AjaxResult.error(checkTenantExpirationTimeMsg);
+        }
+        ajax.put(Constants.TOKEN, token);
+        return ajax;
+    }
+
+
+    @GetMapping("/lims/Login/")
+    public AjaxResult LimsOauth2Login(@RequestParam("userName") String userName,
+                                      @RequestParam(value = "tenantId", required = false, defaultValue = "213") String tenantId) {
+        //本身参数就为空
+        if (StringUtils.isEmpty(userName)) {
+            return AjaxResult.error("用户名不能为空");
+        }
+        //处理租户拼接问题(buffer线程安全)
+        StringBuffer tenantIdStringBuffer=new StringBuffer(tenantId);
+        tenantIdStringBuffer.append("¥¥¥");
+        tenantIdStringBuffer.append(userName);
+        //根据用户名查询,lims租户下的用户信息
+        SysUser sysUser = userService.selectUserByUserName(tenantIdStringBuffer.toString());
+        //当前系统中不存在此用户名
+        if (!Optional.ofNullable(sysUser).isPresent()) {
+            return AjaxResult.error("用户名不能为空");
+        }
+        LoginBody loginBody = new LoginBody();
+        loginBody.setTenantID(sysUser.getTenant().getTenantId().toString());
+        loginBody.setUsername(userName);
+        AjaxResult ajax = AjaxResult.success();
+        // 生成令牌(参数1:租户code 参数二:租户用户名称)
+        String token = loginService.loginOauth(sysUser.getTenant().getTenantCode(), sysUser.getUserName());
+        // 校验你当前登录是否是admin,这是不被允许的
+        if (tokenService.getLoginUserIsAdminByToken(token)) {
+            return AjaxResult.error("用户不存在!");
+        }
+        //这种租户永不过期
+        ajax.put(Constants.TOKEN, token);
+        return ajax;
+    }
+
+
+
+
+
+    /**
+     * 验证租户i是否存在有效
+     *
+     * @param tenantCode 租户编号
+     * @return
+     */
+    @GetMapping("/isTenantExist")
+    public AjaxResult isTenantExist(String tenantCode) {
+        SysTenant sysTenantInfo = iSysTenantService.selectSysTenantByTenantCode(tenantCode);
+        if (sysTenantInfo != null) {
+            sysTenantInfo.setLoginPageConfiguration(loginPageConfigurationService.selectLoginPageConfigurationByLoginPageNumber(tenantCode, "client"));            return AjaxResult.success(sysTenantInfo);
+        }
+        return AjaxResult.error("租户不存在");
+    }
+
+
+    /**
+     * 登录方法(化纤用的)
+     *
+     * @param loginBody 登录信息
+     * @return 结果
+     */
+    @PostMapping("/uniappLogin")
+    public AjaxResult uniappLogin(@RequestBody LoginBody loginBody) {
+
+        //校验不能是admin
+        if (loginBody.getUsername().equals("admin")) {
+            return AjaxResult.error("未有此用户信息");
+        }
+        // 生成令牌
+        String token = loginService.login(loginBody.getTenantID() + "¥¥¥" + loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
+                loginBody.getUuid(), false);
+        if (tokenService.getLoginUserIsAdminByToken(token)) {
+            return AjaxResult.error("用户不存在!");
+        }
+        //检查租户过期时间
+        String checkTenantExpirationTimeMsg = loginService.checkTenantExpirationTime(loginBody.getTenantID() + "¥¥¥" + loginBody.getUsername());
+        if (!checkTenantExpirationTimeMsg.isEmpty()) {
+            return AjaxResult.error(checkTenantExpirationTimeMsg);
+        }
+        //校验租户状态?生成token
+        AjaxResult ajax = AjaxResult.success();
+        ajax.put(Constants.TOKEN, token);
+        return ajax;
+    }
+
+
+    /**
+     * 平台移动端通用登录方法
+     */
+    @PostMapping("/commonUniappLogin")
+    public AjaxResult commonUniappLogin(@RequestBody LoginBody loginBody) {
+        //校验租户状态?生成token
+        AjaxResult ajax = AjaxResult.success();
+        //校验不能是admin
+        if (loginBody.getUsername().equals("admin")) {
+            return AjaxResult.error("未有此用户信息");
+        }
+        if (loginBody.getUsername().indexOf("@") == -1) {
+            return AjaxResult.error("请输入正确的用户名");
+        }
+        // 获取登录用户名
+        String username = loginBody.getUsername();
+        String[] split = username.split("@");
+        // 根据租户code查询租户信息
+        SysTenant sysTenant = iSysTenantService.selectSysTenantByTenantCode(split[0]);
+        loginBody.setTenantID(sysTenant.getTenantId().toString());
+        loginBody.setUsername(split[1]);
+        //生成令牌
+        String token = loginService.login(loginBody.getTenantID() + "¥¥¥" + loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
+                loginBody.getUuid(), false);
+        if (tokenService.getLoginUserIsAdminByToken(token)) {
+            return AjaxResult.error("用户不存在!");
+        }
+        //检查租户过期时间
+        String checkTenantExpirationTimeMsg = loginService.checkTenantExpirationTime(loginBody.getTenantID() + "¥¥¥" + loginBody.getUsername());
+        if (!checkTenantExpirationTimeMsg.isEmpty()) {
+            return AjaxResult.error(checkTenantExpirationTimeMsg);
+        }
+        ajax.put(Constants.TOKEN, token);
+//        MobilePageData mobilePageData = iMobilePageDataService.selectMobilePageDataIndexTrue();
+//        ajax.put("indexId",mobilePageData);
+        return ajax;
+    }
+
+
+    /**
+     * 登录方法
+     *
+     * @param loginBody 登录信息
+     * @return 结果
+     */
+    @PostMapping("/loginAdmin")
+    public AjaxResult loginAdmin(@Valid @RequestBody LoginBody loginBody, BindingResult bindingResult) {
+        if (bindingResult.hasErrors()) {
+            return AjaxResult.error(bindingResult.getFieldError().getDefaultMessage());
+        }
+        //校验租户状态?生成token
+        AjaxResult ajax = AjaxResult.success();
+        //校验不能是admin
+        if (loginBody.getUsername().equals("admin")) {
+            return AjaxResult.error("未有此用户信息");
+        }
+        // 生成令牌
+        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
+                loginBody.getUuid(), true);
+        //检查租户过期时间
+        String checkTenantExpirationTimeMsg = loginService.checkTenantExpirationTime(loginBody.getUsername());
+        if (!checkTenantExpirationTimeMsg.isEmpty()) {
+            return AjaxResult.error(checkTenantExpirationTimeMsg);
+        }
+        ajax.put(Constants.TOKEN, token);
+        return ajax;
+    }
+
+    /**
+     * 获取用户信息
+     *
+     * @return 用户信息
+     */
+    @GetMapping("getInfo")
+    public AjaxResult getInfo() {
+        SysUser user = SecurityUtils.getLoginUser().getUser();
+        // 角色集合
+        Set<String> roles = permissionService.getRolePermission(user);
+        // 权限集合
+        Set<String> permissions = permissionService.getMenuPermission(user);
+        AjaxResult ajax = AjaxResult.success();
+        ajax.put("user", user);
+        ajax.put("roles", roles);
+        ajax.put("permissions", permissions);
+        //租户信息
+        if (user.getTenantId() != null) {
+            //租户信息
+            SysTenant sysTenant = sysTenantService.selectSysTenantByTenantId(user.getTenantId());
+            ajax.put("tenant", sysTenant);
+            //数据源信息
+            // DataSource dataSource = dataSourceService.selectById(sysTenant.getDatasourceId());
+            ajax.put("dataSource", null);
+        }
+        return ajax;
+    }
+
+    /**
+     * 获取路由信息
+     *
+     * @return 路由信息
+     */
+    @GetMapping("getRouters")
+    public AjaxResult getRouters() {
+        Long userId = SecurityUtils.getUserId() == null ? SecurityUtils.getLoginUser().getUser().getUserId() : SecurityUtils.getUserId();
+        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
+        return AjaxResult.success(menuService.buildMenus(menus));
+    }
+}

+ 174 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysMenuController.java

@@ -0,0 +1,174 @@
+package com.zkqy.web.controller.system;
+
+import java.util.List;
+
+import com.zkqy.common.core.domain.entity.SysUser;
+import com.zkqy.common.core.domain.model.LoginUser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.constant.UserConstants;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.entity.SysMenu;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.system.service.ISysMenuService;
+
+/**
+ * 菜单信息
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/system/menu")
+public class SysMenuController extends BaseController {
+    @Autowired
+    private ISysMenuService menuService;
+
+    /**
+     * 获取菜单列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:menu:list')")
+    @GetMapping("/list")
+    public AjaxResult list(SysMenu menu) {
+        List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
+        return success(menus);
+    }
+
+    /**
+     * 根据菜单编号获取详细信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:menu:query')")
+    @GetMapping(value = "/{menuId}")
+    public AjaxResult getInfo(@PathVariable Long menuId) {
+        return success(menuService.selectMenuById(menuId));
+    }
+
+    /**
+     * 获取菜单下拉树列表
+     */
+    @GetMapping("/treeselect")
+    public AjaxResult treeselect(SysMenu menu) {
+        List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
+        return success(menuService.buildMenuTreeSelect(menus));
+    }
+
+    /**
+     * 加载对应角色菜单列表树
+     */
+    @GetMapping(value = "/roleMenuTreeselect/{roleId}")
+    public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) {
+        List<SysMenu> menus = menuService.selectMenuList(getUserId());
+        AjaxResult ajax = AjaxResult.success();
+        ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
+        ajax.put("menus", menuService.buildMenuTreeSelect(menus));
+        return ajax;
+    }
+
+    /**
+     * 新增菜单
+     */
+    //@PreAuthorize("@ss.hasPermi('system:menu:add')")
+    @Log(title = "菜单管理", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@Validated @RequestBody SysMenu menu) {
+        if (!menuService.checkMenuNameUnique(menu)) {
+            return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
+        } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
+            return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
+        }
+        menu.setCreateBy(getUsername());
+        // 如果租户id为null 表示admin新增菜单操作
+        if (menu.getTenantId() == null) {
+            return toAjax(menuService.insertMenu(menu));
+        } else {
+            return AjaxResult.success(menuService.insertMenus(menu, getUserId()));
+        }
+    }
+
+    /**
+     * 修改菜单
+     */
+    //@PreAuthorize("@ss.hasPermi('system:menu:edit')")
+    @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@Validated @RequestBody SysMenu menu) {
+        if (!menuService.checkMenuNameUnique(menu)) {
+            return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
+        } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
+            return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
+        } else if (menu.getMenuId().equals(menu.getParentId())) {
+            return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
+        }
+        menu.setUpdateBy(getUsername());
+        return toAjax(menuService.updateMenu(menu));
+    }
+
+    /**
+     * 删除菜单
+     */
+    //@PreAuthorize("@ss.hasPermi('system:menu:remove')")
+    @Log(title = "菜单管理", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{menuId}")
+    public AjaxResult remove(@PathVariable("menuId") Long menuId) {
+        if (menuService.hasChildByMenuId(menuId)) {
+            return warn("存在子菜单,不允许删除");
+        }
+        if (menuService.checkMenuExistRole(menuId)) {
+            return warn("菜单已分配,不允许删除");
+        }
+        return toAjax(menuService.deleteMenuById(menuId));
+    }
+
+    /**
+     * 批量删除菜单
+     */
+    //@PreAuthorize("@ss.hasPermi('system:menu:remove')")
+    @Log(title = "菜单管理", businessType = BusinessType.DELETE)
+    @DeleteMapping("/removeBatch/{menuIds}")
+    public AjaxResult removeBatch(@PathVariable List<Long> menuIds) {
+        if(menuService.hasChildByMenuIdBatchRemove(menuIds)){
+            return warn("当前选择的菜单中、存在子菜单,不允许删除");
+        }
+        if(menuService.checkMenuExistRoleBatchRemove(menuIds)){
+            return warn("当前选择的菜单中、菜单已分配,不允许删除");
+        }
+        return toAjax(menuService.batchDeleteMenuByIds(menuIds));
+    }
+
+
+    /**
+     * 动态表格获取菜单
+     */
+    //@PreAuthorize("@ss.hasPermi('system:menu:list')")
+    @GetMapping("/getMenuList")
+    public AjaxResult getMenuList() {
+        List<SysMenu> menus = menuService.getMenuList(getTenantId());
+        return success(menus);
+    }
+
+    /**
+     * 根据路由地址获取详细信息
+     */
+    @GetMapping("/particular/{path}")
+    public AjaxResult particular(@PathVariable String path) {
+        return success(menuService.selectMenuByPath(path));
+    }
+
+    /**
+     * 新增菜单添加租户逻辑
+     */
+    @PostMapping("/addMenu")
+    public AjaxResult addMenu(@Validated @RequestBody SysMenu menu) {
+        if (!menuService.checkMenuNameUnique(menu)) {
+            return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
+        } else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
+            return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
+        }
+        menu.setCreateBy(getUsername());
+        return AjaxResult.success(menuService.insertMenus(menu, getUserId()));
+    }
+}

+ 91 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysNoticeController.java

@@ -0,0 +1,91 @@
+package com.zkqy.web.controller.system;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.system.domain.SysNotice;
+import com.zkqy.system.service.ISysNoticeService;
+
+/**
+ * 公告 信息操作处理
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/system/notice")
+public class SysNoticeController extends BaseController
+{
+    @Autowired
+    private ISysNoticeService noticeService;
+
+    /**
+     * 获取通知公告列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:notice:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysNotice notice)
+    {
+        startPage();
+        List<SysNotice> list = noticeService.selectNoticeList(notice);
+        return getDataTable(list);
+    }
+
+    /**
+     * 根据通知公告编号获取详细信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:notice:query')")
+    @GetMapping(value = "/{noticeId}")
+    public AjaxResult getInfo(@PathVariable Long noticeId)
+    {
+        return success(noticeService.selectNoticeById(noticeId));
+    }
+
+    /**
+     * 新增通知公告
+     */
+    //@PreAuthorize("@ss.hasPermi('system:notice:add')")
+    @Log(title = "通知公告", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@Validated @RequestBody SysNotice notice)
+    {
+        notice.setCreateBy(getUsername());
+        return toAjax(noticeService.insertNotice(notice));
+    }
+
+    /**
+     * 修改通知公告
+     */
+    //@PreAuthorize("@ss.hasPermi('system:notice:edit')")
+    @Log(title = "通知公告", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@Validated @RequestBody SysNotice notice)
+    {
+        notice.setUpdateBy(getUsername());
+        return toAjax(noticeService.updateNotice(notice));
+    }
+
+    /**
+     * 删除通知公告
+     */
+    //@PreAuthorize("@ss.hasPermi('system:notice:remove')")
+    @Log(title = "通知公告", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{noticeIds}")
+    public AjaxResult remove(@PathVariable Long[] noticeIds)
+    {
+        return toAjax(noticeService.deleteNoticeByIds(noticeIds));
+    }
+}

+ 134 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysPostController.java

@@ -0,0 +1,134 @@
+package com.zkqy.web.controller.system;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.system.domain.SysPost;
+import com.zkqy.system.service.ISysPostService;
+
+/**
+ * 岗位信息操作处理
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/system/post")
+public class SysPostController extends BaseController
+{
+    @Autowired
+    private ISysPostService postService;
+
+    /**
+     * 获取岗位列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:post:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysPost post)
+    {
+        startPage();
+        if(getLoginUser().isTenantAdmin()){
+            post.setTenantId(getTenantId());
+        }
+        List<SysPost> list = postService.selectPostList(post);
+        return getDataTable(list);
+    }
+    
+    @Log(title = "岗位管理", businessType = BusinessType.EXPORT)
+    @PreAuthorize("@ss.hasPermi('system:post:export')")
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SysPost post)
+    {
+        post.setTenantId(getTenantId());
+        List<SysPost> list = postService.selectPostList(post);
+        ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class);
+        util.exportExcel(response, list, "岗位数据");
+    }
+
+    /**
+     * 根据岗位编号获取详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:post:query')")
+    @GetMapping(value = "/{postId}")
+    public AjaxResult getInfo(@PathVariable Long postId)
+    {
+        return success(postService.selectPostById(postId));
+    }
+
+    /**
+     * 新增岗位
+     */
+    @PreAuthorize("@ss.hasPermi('system:post:add')")
+    @Log(title = "岗位管理", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@Validated @RequestBody SysPost post)
+    {
+        post.setTenantId(getTenantId());
+        if (!postService.checkPostNameUnique(post))
+        {
+            return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
+        }
+        else if (!postService.checkPostCodeUnique(post))
+        {
+            return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
+        }
+        post.setCreateBy(getUsername());
+        return toAjax(postService.insertPost(post));
+    }
+
+    /**
+     * 修改岗位
+     */
+    @PreAuthorize("@ss.hasPermi('system:post:edit')")
+    @Log(title = "岗位管理", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@Validated @RequestBody SysPost post)
+    {
+        if (!postService.checkPostNameUnique(post))
+        {
+            return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
+        }
+        else if (!postService.checkPostCodeUnique(post))
+        {
+            return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
+        }
+        post.setUpdateBy(getUsername());
+        return toAjax(postService.updatePost(post));
+    }
+
+    /**
+     * 删除岗位
+     */
+    @PreAuthorize("@ss.hasPermi('system:post:remove')")
+    @Log(title = "岗位管理", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{postIds}")
+    public AjaxResult remove(@PathVariable Long[] postIds)
+    {
+        return toAjax(postService.deletePostByIds(postIds));
+    }
+
+    /**
+     * 获取岗位选择框列表
+     */
+    @GetMapping("/optionselect")
+    public AjaxResult optionselect()
+    {
+        List<SysPost> posts = postService.selectPostAll();
+        return success(posts);
+    }
+}

+ 141 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysProfileController.java

@@ -0,0 +1,141 @@
+package com.zkqy.web.controller.system;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.config.ZkqyConfig;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.entity.SysUser;
+import com.zkqy.common.core.domain.model.LoginUser;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.SecurityUtils;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.common.utils.file.FileUploadUtils;
+import com.zkqy.common.utils.file.MimeTypeUtils;
+import com.zkqy.framework.web.service.TokenService;
+import com.zkqy.system.service.ISysUserService;
+
+/**
+ * 个人信息 业务处理
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/system/user/profile")
+public class SysProfileController extends BaseController
+{
+    @Autowired
+    private ISysUserService userService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    /**
+     * 个人信息
+     */
+    @GetMapping
+    public AjaxResult profile()
+    {
+        LoginUser loginUser = getLoginUser();
+        SysUser user = loginUser.getUser();
+        AjaxResult ajax = AjaxResult.success(user);
+        ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
+        ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
+        return ajax;
+    }
+
+    /**
+     * 修改用户
+     */
+    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult updateProfile(@RequestBody SysUser user)
+    {
+        LoginUser loginUser = getLoginUser();
+        SysUser sysUser = loginUser.getUser();
+        user.setUserName(sysUser.getUserName());
+        if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
+        {
+            return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
+        }
+        if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
+        {
+            return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
+        }
+        user.setUserId(sysUser.getUserId());
+        user.setPassword(null);
+        user.setAvatar(null);
+        user.setDeptId(null);
+        if (userService.updateUserProfile(user) > 0)
+        {
+            // 更新缓存用户信息
+            sysUser.setNickName(user.getNickName());
+            sysUser.setPhonenumber(user.getPhonenumber());
+            sysUser.setEmail(user.getEmail());
+            sysUser.setSex(user.getSex());
+            tokenService.setLoginUser(loginUser);
+            return success();
+        }
+        return error("修改个人信息异常,请联系管理员");
+    }
+
+    /**
+     * 重置密码
+     */
+    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
+    @PutMapping("/updatePwd")
+    public AjaxResult updatePwd(String oldPassword, String newPassword)
+    {
+        LoginUser loginUser = getLoginUser();
+        String userName = loginUser.getUsername();
+        String password = loginUser.getPassword();
+        if (!SecurityUtils.matchesPassword(oldPassword, password))
+        {
+            return error("修改密码失败,旧密码错误");
+        }
+        if (SecurityUtils.matchesPassword(newPassword, password))
+        {
+            return error("新密码不能与旧密码相同");
+        }
+        if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0)
+        {
+            // 更新缓存用户密码
+            loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));
+            tokenService.setLoginUser(loginUser);
+            return success();
+        }
+        return error("修改密码异常,请联系管理员");
+    }
+
+    /**
+     * 头像上传
+     */
+    @Log(title = "用户头像", businessType = BusinessType.UPDATE)
+    @PostMapping("/avatar")
+    public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception
+    {
+        if (!file.isEmpty())
+        {
+            LoginUser loginUser = getLoginUser();
+            String avatar = FileUploadUtils.upload(ZkqyConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
+            if (userService.updateUserAvatar(loginUser.getUsername(), avatar))
+            {
+                AjaxResult ajax = AjaxResult.success();
+                ajax.put("imgUrl", avatar);
+                // 更新缓存用户头像
+                loginUser.getUser().setAvatar(avatar);
+                tokenService.setLoginUser(loginUser);
+                return ajax;
+            }
+        }
+        return error("上传图片异常,请联系管理员");
+    }
+}

+ 38 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysRegisterController.java

@@ -0,0 +1,38 @@
+package com.zkqy.web.controller.system;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.model.RegisterBody;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.framework.web.service.SysRegisterService;
+import com.zkqy.system.service.ISysConfigService;
+
+/**
+ * 注册验证
+ * 
+ * @author ruoyi
+ */
+@RestController
+public class SysRegisterController extends BaseController
+{
+    @Autowired
+    private SysRegisterService registerService;
+
+    @Autowired
+    private ISysConfigService configService;
+
+    @PostMapping("/register")
+    public AjaxResult register(@RequestBody RegisterBody user)
+    {
+        if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
+        {
+            return error("当前系统没有开启注册功能!");
+        }
+        String msg = registerService.register(user);
+        return StringUtils.isEmpty(msg) ? success() : error(msg);
+    }
+}

+ 268 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysRoleController.java

@@ -0,0 +1,268 @@
+package com.zkqy.web.controller.system;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.entity.SysDept;
+import com.zkqy.common.core.domain.entity.SysRole;
+import com.zkqy.common.core.domain.entity.SysUser;
+import com.zkqy.common.core.domain.model.LoginUser;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.framework.web.service.SysPermissionService;
+import com.zkqy.framework.web.service.TokenService;
+import com.zkqy.system.domain.SysUserRole;
+import com.zkqy.system.service.ISysDeptService;
+import com.zkqy.system.service.ISysRoleService;
+import com.zkqy.system.service.ISysUserService;
+
+/**
+ * 角色信息
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/system/role")
+public class SysRoleController extends BaseController
+{
+    @Autowired
+    private ISysRoleService roleService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private SysPermissionService permissionService;
+
+    @Autowired
+    private ISysUserService userService;
+
+    @Autowired
+    private ISysDeptService deptService;
+
+    //@PreAuthorize("@ss.hasPermi('system:role:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysRole role)
+    {
+        startPage();
+        if (getLoginUser().isTenantAdmin()) {
+            role.setTenantId(getTenantId());
+        }
+        List<SysRole> list = roleService.selectRoleList(role);
+        return getDataTable(list);
+    }
+
+    @Log(title = "角色管理", businessType = BusinessType.EXPORT)
+    //@PreAuthorize("@ss.hasPermi('system:role:export')")
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SysRole role)
+    {
+        role.setTenantId(getTenantId());
+        List<SysRole> list = roleService.selectRoleList(role);
+        ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
+        util.exportExcel(response, list, "角色数据");
+    }
+
+    /**
+     * 根据角色编号获取详细信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:query')")
+    @GetMapping(value = "/{roleId}")
+    public AjaxResult getInfo(@PathVariable Long roleId)
+    {
+        roleService.checkRoleDataScope(roleId);
+        return success(roleService.selectRoleById(roleId));
+    }
+
+    /**
+     * 新增角色
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:add')")
+    @Log(title = "角色管理", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@Validated @RequestBody SysRole role)
+    {
+        if (!roleService.checkRoleNameUnique(role))
+        {
+            return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
+        }
+        else if (!roleService.checkRoleKeyUnique(role))
+        {
+            return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
+        }
+        role.setCreateBy(getUsername());
+        role.setTenantId(getTenantId());
+        return toAjax(roleService.insertRole(role));
+
+    }
+
+    /**
+     * 修改保存角色
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:edit')")
+    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@Validated @RequestBody SysRole role)
+    {
+        roleService.checkRoleAllowed(role);
+        roleService.checkRoleDataScope(role.getRoleId());
+        if (!roleService.checkRoleNameUnique(role))
+        {
+            return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
+        }
+        else if (!roleService.checkRoleKeyUnique(role))
+        {
+            return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
+        }
+        role.setUpdateBy(getUsername());
+        
+        if (roleService.updateRole(role) > 0)
+        {
+            // 更新缓存用户权限
+            LoginUser loginUser = getLoginUser();
+            if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin())
+            {
+                loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser()));
+                loginUser.getUser().setUserName(loginUser.getTenantId()+"¥¥¥"+loginUser.getUsername());
+                loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
+                tokenService.setLoginUser(loginUser);
+            }
+            return success();
+        }
+        return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
+    }
+
+    /**
+     * 修改保存数据权限
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:edit')")
+    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
+    @PutMapping("/dataScope")
+    public AjaxResult dataScope(@RequestBody SysRole role)
+    {
+        roleService.checkRoleAllowed(role);
+        roleService.checkRoleDataScope(role.getRoleId());
+        return toAjax(roleService.authDataScope(role));
+    }
+
+    /**
+     * 状态修改
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:edit')")
+    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public AjaxResult changeStatus(@RequestBody SysRole role)
+    {
+        roleService.checkRoleAllowed(role);
+        roleService.checkRoleDataScope(role.getRoleId());
+        role.setUpdateBy(getUsername());
+        return toAjax(roleService.updateRoleStatus(role));
+    }
+
+    /**
+     * 删除角色
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:remove')")
+    @Log(title = "角色管理", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{roleIds}")
+    public AjaxResult remove(@PathVariable Long[] roleIds)
+    {
+        return toAjax(roleService.deleteRoleByIds(roleIds));
+    }
+
+    /**
+     * 获取角色选择框列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:query')")
+    @GetMapping("/optionselect")
+    public AjaxResult optionselect()
+    {
+        return success(roleService.selectRoleAll());
+    }
+
+    /**
+     * 查询已分配用户角色列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:list')")
+    @GetMapping("/authUser/allocatedList")
+    public TableDataInfo allocatedList(SysUser user)
+    {
+        startPage();
+        List<SysUser> list = userService.selectAllocatedList(user);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询未分配用户角色列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:list')")
+    @GetMapping("/authUser/unallocatedList")
+    public TableDataInfo unallocatedList(SysUser user)
+    {
+        startPage();
+        List<SysUser> list = userService.selectUnallocatedList(user);
+        return getDataTable(list);
+    }
+
+    /**
+     * 取消授权用户
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:edit')")
+    @Log(title = "角色管理", businessType = BusinessType.GRANT)
+    @PutMapping("/authUser/cancel")
+    public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole)
+    {
+        return toAjax(roleService.deleteAuthUser(userRole));
+    }
+
+    /**
+     * 批量取消授权用户
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:edit')")
+    @Log(title = "角色管理", businessType = BusinessType.GRANT)
+    @PutMapping("/authUser/cancelAll")
+    public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds)
+    {
+        return toAjax(roleService.deleteAuthUsers(roleId, userIds));
+    }
+
+    /**
+     * 批量选择用户授权
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:edit')")
+    @Log(title = "角色管理", businessType = BusinessType.GRANT)
+    @PutMapping("/authUser/selectAll")
+    public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds)
+    {
+        roleService.checkRoleDataScope(roleId);
+        return toAjax(roleService.insertAuthUsers(roleId, userIds));
+    }
+
+    /**
+     * 获取对应角色部门树列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:role:query')")
+    @GetMapping(value = "/deptTree/{roleId}")
+    public AjaxResult deptTree(@PathVariable("roleId") Long roleId)
+    {
+        AjaxResult ajax = AjaxResult.success();
+        ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
+        ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
+        return ajax;
+    }
+}

+ 147 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysTenantController.java

@@ -0,0 +1,147 @@
+package com.zkqy.web.controller.system;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import com.zkqy.common.annotation.Anonymous;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.core.domain.entity.SysTenant;
+import com.zkqy.system.service.ISysTenantService;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.common.core.page.TableDataInfo;
+
+/**
+ * 租户信息Controller
+ *
+ * @author zkqy
+ * @date 2023-06-03
+ */
+@RestController
+@RequestMapping("/system/tenant")
+public class SysTenantController extends BaseController {
+    @Autowired
+    private ISysTenantService sysTenantService;
+
+    /**
+     * 查询租户信息列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:tenant:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysTenant sysTenant) {
+        startPage();
+        List<SysTenant> list = sysTenantService.selectSysTenantList(sysTenant);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询所有租户信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:tenant:list')")
+    @GetMapping("/getTenantAllList")
+    public TableDataInfo getTenantAllList(SysTenant sysTenant) {
+        List<SysTenant> list = sysTenantService.selectSysTenantAllList(sysTenant);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出租户信息列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:tenant:export')")
+    @Log(title = "租户信息", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SysTenant sysTenant) {
+        List<SysTenant> list = sysTenantService.selectSysTenantList(sysTenant);
+        ExcelUtil<SysTenant> util = new ExcelUtil<SysTenant>(SysTenant.class);
+        util.exportExcel(response, list, "租户信息数据");
+    }
+
+    /**
+     * 获取租户信息详细信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:tenant:query')")
+    @GetMapping(value = "/{tenantId}")
+    public AjaxResult getInfo(@PathVariable("tenantId") Long tenantId) {
+        return success(sysTenantService.selectSysTenantByTenantId(tenantId));
+    }
+
+    /**
+     * 获取当前租户下的子租户
+     *
+     * @param tenantId
+     * @return
+     */
+    //@PreAuthorize("@ss.hasPermi('system:tenant:query')")
+    @GetMapping(value = "/getTenantChildrenInfo/{tenantId}")
+    public AjaxResult getTenantChildrenInfo(@PathVariable("tenantId") Long tenantId) {
+        return success(sysTenantService.selectSysTenantChildrenInfoByTenantId(tenantId));
+    }
+
+    /**
+     * 新增租户信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:tenant:add')")
+    @Log(title = "租户信息", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody SysTenant sysTenant) {
+        return toAjax(sysTenantService.insertSysTenant(sysTenant));
+    }
+
+    /**
+     * 修改租户信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:tenant:edit')")
+    @Log(title = "租户信息", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody SysTenant sysTenant) {
+        return toAjax(sysTenantService.updateSysTenant(sysTenant));
+    }
+
+    /**
+     * 删除租户信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:tenant:remove')")
+    @Log(title = "租户信息", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{tenantIds}")
+    public AjaxResult remove(@PathVariable Long[] tenantIds) {
+        return toAjax(sysTenantService.deleteSysTenantByTenantIds(tenantIds));
+    }
+
+    /**
+     * 初始化租户管理员菜单(租户管理员显示菜单)
+     */
+    @Anonymous
+    @GetMapping("/initTenantMenuData/{tenantId}")
+    public AjaxResult initTenantMenuData(@PathVariable Long tenantId) {
+        return sysTenantService.initTenantMenuData(tenantId);
+    }
+
+    /**
+     * 生成激活码方法
+     */
+    @GetMapping("/crateTenantCode/{tenantId}/{tenantExpirationTime}")
+    public AjaxResult crateTenantCode(@PathVariable String tenantId, @PathVariable String tenantExpirationTime) throws Exception {
+        return sysTenantService.crateTenantCode(tenantId, tenantExpirationTime);
+    }
+
+    /**
+     * 激活租户
+     */
+    @GetMapping("/activationOperation/{tenantId}/{activationCode}")
+    public AjaxResult activationOperation(@PathVariable String tenantId, @PathVariable String activationCode) throws Exception {
+        return sysTenantService.activationOperation(tenantId, activationCode);
+    }
+
+}

+ 353 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysUserController.java

@@ -0,0 +1,353 @@
+package com.zkqy.web.controller.system;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.servlet.http.HttpServletResponse;
+
+import com.alibaba.fastjson2.JSON;
+import com.google.zxing.WriterException;
+import com.zkqy.amichi.utils.MaUtils;
+import com.zkqy.common.annotation.Anonymous;
+import com.zkqy.system.domain.SysPost;
+import org.apache.commons.lang3.ArrayUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.entity.SysDept;
+import com.zkqy.common.core.domain.entity.SysRole;
+import com.zkqy.common.core.domain.entity.SysUser;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.SecurityUtils;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.system.service.ISysDeptService;
+import com.zkqy.system.service.ISysPostService;
+import com.zkqy.system.service.ISysRoleService;
+import com.zkqy.system.service.ISysUserService;
+
+/**
+ * 用户信息
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/system/user")
+public class SysUserController extends BaseController {
+    @Autowired
+    private ISysUserService userService;
+
+    @Autowired
+    private ISysRoleService roleService;
+
+    @Autowired
+    private ISysDeptService deptService;
+
+    @Autowired
+    private ISysPostService postService;
+
+    /**
+     * 获取用户列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:user:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysUser user) {
+        startPage();
+        if (getLoginUser().isTenantAdmin()) {
+            user.setTenantId(getTenantId());
+        }
+        List<SysUser> list = userService.selectUserList(user);
+        return getDataTable(list);
+    }
+
+    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
+    //@PreAuthorize("@ss.hasPermi('system:user:export')")
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SysUser user, List<String> uIds) {
+        if (uIds != null && uIds.size() != 0) {// 导出指定用户集合
+
+        }
+        List<SysUser> list = userService.selectUserList(user);
+        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
+        util.exportExcel(response, list, "用户数据");
+    }
+
+    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
+    //@PreAuthorize("@ss.hasPermi('system:user:export')")
+    @GetMapping("/abc")
+    public AjaxResult export() {
+        SysUser sysUser = new SysUser();
+        List<SysUser> list = userService.selectUserList(sysUser);
+
+        // 定义基础目录
+        String baseDir = "C:\\Users\\86180\\Desktop\\lims\\yhsj";
+
+        //循环
+        list.forEach(item->{
+            String userFolder = baseDir + "\\" + item.getUserName();
+            //创建用户文件夹
+            File folder = new File(userFolder);
+            if(folder.exists()){
+                folder.delete();//刪除
+            }else {
+                folder.mkdirs();//創建
+            }
+            //码存放的路径
+            String qrFilePath = userFolder + "\\qrcode_" + item.getUserName() + ".png";
+            //
+            StringBuilder builder=new StringBuilder();
+            builder.append(item.getUserId()).append("#").append(item.getUserName()).append("scan@");
+            try {
+                MaUtils.generateQRCode(builder.toString(),qrFilePath);
+            } catch (WriterException e) {
+                throw new RuntimeException(e);
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        });
+        return AjaxResult.success("导出成功");
+    }
+
+
+    @Log(title = "用户管理", businessType = BusinessType.IMPORT)
+    //@PreAuthorize("@ss.hasPermi('system:user:import')")
+    @PostMapping("/importData")
+    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
+        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
+        List<SysUser> userList = util.importExcel(file.getInputStream());
+        String operName = getUsername();
+        String message = userService.importUser(userList, updateSupport, operName);
+        return success(message);
+    }
+
+    @PostMapping("/importTemplate")
+    public void importTemplate(HttpServletResponse response) {
+        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
+        util.importTemplateExcel(response, "用户数据");
+    }
+
+    /**
+     * 根据用户编号获取详细信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:user:query')")
+    @GetMapping(value = {"/", "/{userId}"})
+    public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) {
+        userService.checkUserDataScope(userId);
+        AjaxResult ajax = AjaxResult.success();
+        List<SysRole> roles = roleService.selectRoleAll();
+        roles.forEach(r -> {
+            if (r.getTenantId() == null) {
+                r.setTenantId(0L);
+            }
+        });
+        List<SysPost> sysPosts = postService.selectPostAll();
+        sysPosts.forEach(s -> {
+            if (s.getTenantId() == null) {
+                s.setTenantId(0L);
+            }
+        });
+
+        ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin() && r.getTenantId().equals(getTenantId())).collect(Collectors.toList()));
+        ajax.put("posts", sysPosts.stream().filter(p -> p.getTenantId().equals(getTenantId())).collect(Collectors.toList()));
+        if (StringUtils.isNotNull(userId)) {
+            SysUser sysUser = userService.selectUserById(userId);
+            ajax.put(AjaxResult.DATA_TAG, sysUser);
+            ajax.put("postIds", postService.selectPostListByUserId(userId));
+            ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
+        }
+        return ajax;
+    }
+
+    /**
+     * 根据用户编号获取详细信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:user:query')")
+    @GetMapping(value = { "/userInfoAndSection/{userId}"})
+    public AjaxResult getUserInfo(@PathVariable(value = "userId", required = false) Long userId) {
+        userService.checkUserDataScope(userId);
+        AjaxResult ajax = AjaxResult.success();
+        SysUser sysUser = userService.selectUserById(userId);
+        Long deptId = sysUser.getDeptId();
+        SysDept sysDept = deptService.selectDeptById(deptId);
+        ajax.put("deptInfo",sysDept);
+        return ajax;
+    }
+    /**
+     * 新增用户
+     */
+    //@PreAuthorize("@ss.hasPermi('system:user:add')")
+    @Log(title = "用户管理", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@Validated @RequestBody SysUser user) {
+        if (!userService.checkUserNameUnique(user)) {
+            return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
+        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
+            return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
+        } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
+            return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
+        }
+        user.setCreateBy(getUsername());
+        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
+        if (getTenantId() != null) {
+            user.setTenantId(getTenantId());
+        }
+        return toAjax(userService.insertUser(user));
+    }
+
+    /**
+     * 修改用户
+     */
+    //@PreAuthorize("@ss.hasPermi('system:user:edit')")
+    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@Validated @RequestBody SysUser user) {
+        userService.checkUserAllowed(user);
+        userService.checkUserDataScope(user.getUserId());
+        if (!userService.checkUserNameUnique(user)) {
+            return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
+        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
+            return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
+        } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
+            return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
+        }
+        user.setUpdateBy(getUsername());
+        return toAjax(userService.updateUser(user));
+    }
+
+    /**
+     * 删除用户
+     */
+    //@PreAuthorize("@ss.hasPermi('system:user:remove')")
+    @Log(title = "用户管理", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{userIds}")
+    public AjaxResult remove(@PathVariable Long[] userIds) {
+        if (ArrayUtils.contains(userIds, getUserId())) {
+            return error("当前用户不能删除");
+        }
+        return toAjax(userService.deleteUserByIds(userIds));
+    }
+
+    /**
+     * 重置密码
+     */
+    //@PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
+    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
+    @PutMapping("/resetPwd")
+    public AjaxResult resetPwd(@RequestBody SysUser user) {
+        userService.checkUserAllowed(user);
+        userService.checkUserDataScope(user.getUserId());
+        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
+        user.setUpdateBy(getUsername());
+        return toAjax(userService.resetPwd(user));
+    }
+
+    /**
+     * 状态修改
+     */
+    //@PreAuthorize("@ss.hasPermi('system:user:edit')")
+    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public AjaxResult changeStatus(@RequestBody SysUser user) {
+        userService.checkUserAllowed(user);
+        userService.checkUserDataScope(user.getUserId());
+        user.setUpdateBy(getUsername());
+        return toAjax(userService.updateUserStatus(user));
+    }
+
+    /**
+     * 根据用户编号获取授权角色
+     */
+    //@PreAuthorize("@ss.hasPermi('system:user:query')")
+    @GetMapping("/authRole/{userId}")
+    public AjaxResult authRole(@PathVariable("userId") Long userId) {
+        AjaxResult ajax = AjaxResult.success();
+        SysUser user = userService.selectUserById(userId);
+        List<SysRole> roles = roleService.selectRolesByUserId(userId);
+        roles.forEach(r -> {
+            if (r.getTenantId() == null) {
+                r.setTenantId(0L);
+            }
+        });
+        ajax.put("user", user);
+        ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin() && r.getTenantId().equals(getTenantId())).collect(Collectors.toList()));
+        return ajax;
+    }
+
+    /**
+     * BPM流程 根据用户编号获取授权角色
+     */
+    @Anonymous
+    @GetMapping("/roleKeyByUserId/{userId}")
+    public AjaxResult roleKeyByUserId(@PathVariable("userId") Long userId) {
+        AjaxResult ajax = AjaxResult.success();
+        String[] strings = roleService.selectRolesKeyByUserId(userId);
+        ajax.put("rolesKey", JSON.toJSONString(strings));
+        return ajax;
+    }
+
+    /**
+     * 用户授权角色
+     */
+    //@PreAuthorize("@ss.hasPermi('system:user:edit')")
+    @Log(title = "用户管理", businessType = BusinessType.GRANT)
+    @PutMapping("/authRole")
+    public AjaxResult insertAuthRole(Long userId, Long[] roleIds) {
+        userService.checkUserDataScope(userId);
+        userService.insertUserAuth(userId, roleIds);
+        return success();
+    }
+
+    /**
+     * 获取部门树列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:user:list')")
+    @GetMapping("/deptTree")
+    public AjaxResult deptTree(SysDept dept) {
+        if (getLoginUser().isTenantAdmin()) {
+            dept.setTenantId(getTenantId());
+        }
+        return success(deptService.selectDeptTreeList(dept));
+    }
+
+    /**
+     * 查询所有用户
+     */
+    @GetMapping("/selectAllUser")
+    public AjaxResult selectAllUser() {
+        return AjaxResult.success(userService.selectAllUser());
+    }
+
+    /**
+     * 校验用户账号
+     */
+    @GetMapping("/isExistUser")
+    public AjaxResult isExistUser(String userName) {
+        return AjaxResult.success(userService.isExistUser(userName));
+    }
+
+
+    /**
+     * 根据角色获取用户信息
+     */
+    @GetMapping("/getRoleUser/{roleKey}")
+    public AjaxResult getRoleUser(@PathVariable("roleKey") String roleKey) {
+        return AjaxResult.success(userService.selectUserListByRoleKey(roleKey,getTenantId()));
+    }
+
+
+
+}

+ 73 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/tool/DynamicBeanRegistrar.java

@@ -0,0 +1,73 @@
+package com.zkqy.web.controller.tool;
+
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+public class DynamicBeanRegistrar {
+    private final ApplicationContext applicationContext;
+    private final DynamicCompiler dynamicCompiler;
+
+    public DynamicBeanRegistrar(ApplicationContext applicationContext) {
+        this.applicationContext = applicationContext;
+        this.dynamicCompiler = new DynamicCompiler();
+    }
+
+    /**
+     * 动态加载并注册控制器
+     */
+    public void registerController(String sourceFilePath, String beanName) throws Exception {
+        // 1. 动态编译 .java 文件
+        File classDirectory = dynamicCompiler.compileJavaFile("C:\\Users\\86180\\IdeaProjects\\gsxm\\mec-cloud_-intelligent-manufacturing_client\\zkqy-admin\\src\\main\\resources\\abc\\TestController.java");
+
+        // 2. 加载编译后的类
+        Class<?> controllerClass = loadClassFromFile(classDirectory, sourceFilePath);
+
+        // 3. 获取 ConfigurableListableBeanFactory
+        ConfigurableListableBeanFactory beanFactory = ((org.springframework.context.support.AbstractApplicationContext) applicationContext).getBeanFactory();
+
+        // 4. 注册 Bean 到容器
+        beanFactory.registerSingleton(beanName, controllerClass.getDeclaredConstructor().newInstance());
+
+        // 5. 刷新请求映射(确保新控制器生效)
+        refreshRequestMappings();
+    }
+
+    /**
+     * 加载编译后的类文件
+     */
+    private Class<?> loadClassFromFile(File classDirectory, String sourceFilePath) throws Exception {
+        // 获取类名
+        String className = extractClassNameFromSourcePath(sourceFilePath);
+
+        // 创建自定义 ClassLoader 加载类
+        URLClassLoader classLoader = new URLClassLoader(new URL[]{classDirectory.toURI().toURL()}, getClass().getClassLoader());
+        return Class.forName(className, true, classLoader);
+    }
+
+    /**
+     * 提取类名
+     */
+    private String extractClassNameFromSourcePath(String sourceFilePath) {
+        File sourceFile = new File(sourceFilePath);
+        String fileName = sourceFile.getName();
+        String className = fileName.substring(0, fileName.lastIndexOf('.'));
+        return className;
+    }
+
+    /**
+     * 刷新请求映射
+     */
+    private void refreshRequestMappings() {
+        RequestMappingHandlerMapping requestMappingHandlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
+        try {
+            requestMappingHandlerMapping.afterPropertiesSet();
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to refresh request mappings", e);
+        }
+    }
+}

+ 32 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/tool/DynamicCompiler.java

@@ -0,0 +1,32 @@
+package com.zkqy.web.controller.tool;
+
+import javax.tools.JavaCompiler;
+import javax.tools.ToolProvider;
+import java.io.File;
+
+public class DynamicCompiler {
+    /**
+     * 动态编译 .java 文件
+     */
+    public File compileJavaFile(String sourceFilePath) throws Exception {
+        // 获取 Java 编译器
+        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+
+        if (compiler == null) {
+            throw new IllegalStateException("Java compiler is not available. Ensure you are running with JDK, not JRE.");
+        }
+
+        // 获取源文件对象
+        File sourceFile = new File(sourceFilePath);
+
+        // 编译源文件
+        int compilationResult = compiler.run(null, null, null, sourceFile.getPath());
+
+        if (compilationResult != 0) {
+            throw new Exception("Compilation failed for file: " + sourceFilePath);
+        }
+
+        // 返回生成的 .class 文件所在目录
+        return sourceFile.getParentFile();
+    }
+}

+ 184 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/tool/TestController.java

@@ -0,0 +1,184 @@
+package com.zkqy.web.controller.tool;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.R;
+import com.zkqy.common.utils.StringUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * swagger 用户测试方法
+ * 
+ * @author ruoyi
+ */
+@Api("用户信息管理")
+@RestController
+@RequestMapping("/test/user")
+public class TestController extends BaseController
+{
+    private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
+    {
+        users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
+        users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
+        users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
+    }
+
+    @ApiOperation("获取用户列表")
+    @GetMapping("/list")
+    public R<List<UserEntity>> userList()
+    {
+        List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
+        return R.ok(userList);
+    }
+
+    @ApiOperation("获取用户详细")
+    @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
+    @GetMapping("/{userId}")
+    public R<UserEntity> getUser(@PathVariable Integer userId)
+    {
+        if (!users.isEmpty() && users.containsKey(userId))
+        {
+            return R.ok(users.get(userId));
+        }
+        else
+        {
+            return R.fail("用户不存在");
+        }
+    }
+
+    @ApiOperation("新增用户")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class),
+        @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class),
+        @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class)
+    })
+    @PostMapping("/save")
+    public R<String> save(UserEntity user)
+    {
+        if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
+        {
+            return R.fail("用户ID不能为空");
+        }
+        users.put(user.getUserId(), user);
+        return R.ok();
+    }
+
+    @ApiOperation("更新用户")
+    @PutMapping("/update")
+    public R<String> update(@RequestBody UserEntity user)
+    {
+        if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
+        {
+            return R.fail("用户ID不能为空");
+        }
+        if (users.isEmpty() || !users.containsKey(user.getUserId()))
+        {
+            return R.fail("用户不存在");
+        }
+        users.remove(user.getUserId());
+        users.put(user.getUserId(), user);
+        return R.ok();
+    }
+
+    @ApiOperation("删除用户信息")
+    @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
+    @DeleteMapping("/{userId}")
+    public R<String> delete(@PathVariable Integer userId)
+    {
+        if (!users.isEmpty() && users.containsKey(userId))
+        {
+            users.remove(userId);
+            return R.ok();
+        }
+        else
+        {
+            return R.fail("用户不存在");
+        }
+    }
+}
+
+@ApiModel(value = "UserEntity", description = "用户实体")
+class UserEntity
+{
+    @ApiModelProperty("用户ID")
+    private Integer userId;
+
+    @ApiModelProperty("用户名称")
+    private String username;
+
+    @ApiModelProperty("用户密码")
+    private String password;
+
+    @ApiModelProperty("用户手机")
+    private String mobile;
+
+    public UserEntity()
+    {
+
+    }
+
+    public UserEntity(Integer userId, String username, String password, String mobile)
+    {
+        this.userId = userId;
+        this.username = username;
+        this.password = password;
+        this.mobile = mobile;
+    }
+
+    public Integer getUserId()
+    {
+        return userId;
+    }
+
+    public void setUserId(Integer userId)
+    {
+        this.userId = userId;
+    }
+
+    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 getMobile()
+    {
+        return mobile;
+    }
+
+    public void setMobile(String mobile)
+    {
+        this.mobile = mobile;
+    }
+}

+ 175 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/tool/daochuController.java

@@ -0,0 +1,175 @@
+package com.zkqy.web.controller.tool;
+
+import com.zkqy.common.config.ZkqyConfig;
+import com.zkqy.common.core.domain.entity.DataSource;
+import com.zkqy.common.core.domain.entity.SysUser;
+import com.zkqy.common.utils.DateUtils;
+import com.zkqy.common.utils.SecurityUtils;
+import com.zkqy.common.utils.ZipUtils;
+import com.zkqy.system.domain.SysEngineering;
+import com.zkqy.system.service.ISysEngineeringService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+@RestController
+@RequestMapping("/download/project-db")
+public class daochuController {
+
+    @Autowired
+    private ISysEngineeringService sysEngineeringService;
+    @Autowired
+    private ThreadPoolTaskExecutor taskExecutor;
+    private static final String MYSQLDUMP_PATH = "/usr/local/mysql/bin/mysqldump";
+    private static final String SQL_OUTPUT_PATH = "sql";
+
+
+    @GetMapping("/zip")
+    public void downloadZip1(HttpServletResponse response) {
+        String sourceFilePath = ZkqyConfig.getUploadPath() + "/engineeringdownload/";
+        DataSource datasourceInfo = SecurityUtils.getDatasourceInfo();
+        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
+        String tenantid = sysUser.getTenant().getTenantId().toString();
+        // 使用 Arrays.asList 转换数组为集合
+        List<String> databaseList = Arrays.asList("ry-vue-call", datasourceInfo.getDatabaseName());
+        List<CompletableFuture<Void>> exportFutures = databaseList.stream()
+                .map(databaseName -> CompletableFuture.runAsync(
+                                () -> exportDatabase(databaseName, sourceFilePath, datasourceInfo, tenantid), taskExecutor)
+                        .exceptionally(throwable -> {
+                            throwable.printStackTrace();
+                            return null;
+                        })
+                )
+                .collect(Collectors.toList());
+        CompletableFuture<Void> allOf = CompletableFuture.allOf(
+                exportFutures.toArray(new CompletableFuture[0])
+        );
+        try {
+            allOf.get(10, TimeUnit.MINUTES);
+        } catch (InterruptedException | ExecutionException | TimeoutException e) {
+            e.printStackTrace();
+        }
+        SysEngineering sysEngineering = new SysEngineering();
+        sysEngineering.setCreateTime(DateUtils.getNowDate());
+        sysEngineering.setDownloadTime(DateUtils.getNowDate());
+        sysEngineering.setEngineeringName(sysUser.getTenantName() + "-MES");
+        sysEngineering.setTenantId(sysUser.getTenantId());
+        sysEngineeringService.insertSysEngineering(sysEngineering);
+        List<Map<String, String>> fileList = listFiles(sourceFilePath);
+        ZipUtils.createZip(response, fileList);
+    }
+
+
+    private void addFilesToZipRecursively(ZipOutputStream zipOut, Path rootPath, DirectoryStream<Path> dirStream) throws
+            IOException {
+        for (Path filePath : dirStream) {
+            if (Files.isDirectory(filePath)) {
+                // 添加目录条目到ZIP
+                String entryName = filePath.toString().substring(rootPath.toString().length() + 1) + "/";
+                zipOut.putNextEntry(new ZipEntry(entryName));
+                zipOut.closeEntry();
+                // 递归处理子目录中的文件
+                try (DirectoryStream<Path> subDirStream = Files.newDirectoryStream(filePath)) {
+                    addFilesToZipRecursively(zipOut, rootPath, subDirStream);
+                }
+            } else if (Files.isRegularFile(filePath)) {
+                // 添加文件到ZIP
+                String entryName = filePath.toString().substring(rootPath.toString().length() + 1);
+                zipOut.putNextEntry(new ZipEntry(entryName));
+                try (InputStream fileIn = Files.newInputStream(filePath)) {
+                    byte[] buffer = new byte[4096];
+                    int read;
+                    while ((read = fileIn.read(buffer)) != -1) {
+                        zipOut.write(buffer, 0, read);
+                    }
+                }
+                zipOut.closeEntry();
+            }
+        }
+    }
+
+    private List<String> buildMysqldumpCommand(String databaseName, DataSource dataSource) {
+        // 使用 Arrays.asList 创建不可变 List
+        return new ArrayList<>(Arrays.asList(
+                MYSQLDUMP_PATH,
+                "-h", dataSource.getDatabaseIp(),
+                "-u", dataSource.getUsername(),
+                "-p" + dataSource.getPassword(),
+                databaseName
+        ));
+    }
+
+    public static List<Map<String, String>> listFiles(String directoryPath) {
+        List<Map<String, String>> fileList = new ArrayList<>();
+        File directory = new File(directoryPath);
+        if (directory.exists() && directory.isDirectory()) {
+            listFilesRecursively(directory, fileList);
+        }
+        return fileList;
+    }
+
+    private static void listFilesRecursively(File directory, List<Map<String, String>> fileList) {
+        File[] files = directory.listFiles();
+        if (files != null) {
+            for (File file : files) {
+                if (file.isFile()) {
+                    Map<String, String> fileMap = new HashMap<>();
+                    fileMap.put("fileName", file.getName());
+                    fileMap.put("filePath", file.getAbsolutePath());
+                    fileList.add(fileMap);
+                } else if (file.isDirectory()) {
+                    listFilesRecursively(file, fileList);
+                }
+            }
+        }
+    }
+
+    private void exportDatabase(String databaseName, String sourceFilePath, DataSource dataSource, String tenantId) {
+        String outputPath = sourceFilePath + SQL_OUTPUT_PATH + File.separator + tenantId;
+        try {
+            Files.createDirectories(Paths.get(outputPath));
+            String dumpFileName = outputPath + File.separator + databaseName + ".sql";
+            List<String> cmd = buildMysqldumpCommand(databaseName, dataSource);
+            ProcessBuilder pb = new ProcessBuilder(cmd);
+            pb.redirectOutput(new File(dumpFileName));
+            Process process = pb.start();
+            // 设置导出超时时间为10分钟
+            if (!process.waitFor(10, TimeUnit.MINUTES)) {
+                process.destroyForcibly(); // 超时则强制销毁进程
+                throw new TimeoutException("导出数据库超时");
+            }
+            int exitCode = process.exitValue();
+
+            if (exitCode == 0) {
+                System.out.println("数据库备份成功。导出文件:" + dumpFileName);
+            } else {
+                System.err.println("执行mysqldump命令时发生错误。退出代码:" + exitCode);
+            }
+        } catch (IOException | InterruptedException | TimeoutException e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 125 - 0
zkqy-admin/src/main/java/com/zkqy/web/core/config/SwaggerConfig.java

@@ -0,0 +1,125 @@
+package com.zkqy.web.core.config;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import com.zkqy.common.config.ZkqyConfig;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.models.auth.In;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ApiKey;
+import springfox.documentation.service.AuthorizationScope;
+import springfox.documentation.service.Contact;
+import springfox.documentation.service.SecurityReference;
+import springfox.documentation.service.SecurityScheme;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.Docket;
+
+/**
+ * Swagger2的接口配置
+ * 
+ * @author ruoyi
+ */
+@Configuration
+public class SwaggerConfig
+{
+    /** 系统基础配置 */
+    @Autowired
+    private ZkqyConfig ruoyiConfig;
+
+    /** 是否开启swagger */
+    @Value("${swagger.enabled}")
+    private boolean enabled;
+
+    /** 设置请求的统一前缀 */
+    @Value("${swagger.pathMapping}")
+    private String pathMapping;
+
+    /**
+     * 创建API
+     */
+    @Bean
+    public Docket createRestApi()
+    {
+        return new Docket(DocumentationType.OAS_30)
+                // 是否启用Swagger
+                .enable(enabled)
+                // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
+                .apiInfo(apiInfo())
+                // 设置哪些接口暴露给Swagger展示
+                .select()
+                // 扫描所有有注解的api,用这种方式更灵活
+                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
+                // 扫描指定包中的swagger注解
+                // .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
+                // 扫描所有 .apis(RequestHandlerSelectors.any())
+                .paths(PathSelectors.any())
+                .build()
+                /* 设置安全模式,swagger可以设置访问token */
+                .securitySchemes(securitySchemes())
+                .securityContexts(securityContexts())
+                .pathMapping(pathMapping);
+    }
+
+    /**
+     * 安全模式,这里指定token通过Authorization头请求头传递
+     */
+    private List<SecurityScheme> securitySchemes()
+    {
+        List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
+        apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
+        return apiKeyList;
+    }
+
+    /**
+     * 安全上下文
+     */
+    private List<SecurityContext> securityContexts()
+    {
+        List<SecurityContext> securityContexts = new ArrayList<>();
+        securityContexts.add(
+                SecurityContext.builder()
+                        .securityReferences(defaultAuth())
+                        .operationSelector(o -> o.requestMappingPattern().matches("/.*"))
+                        .build());
+        return securityContexts;
+    }
+
+    /**
+     * 默认的安全上引用
+     */
+    private List<SecurityReference> defaultAuth()
+    {
+        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
+        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
+        authorizationScopes[0] = authorizationScope;
+        List<SecurityReference> securityReferences = new ArrayList<>();
+        securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
+        return securityReferences;
+    }
+
+    /**
+     * 添加摘要信息
+     */
+    private ApiInfo apiInfo()
+    {
+        // 用ApiInfoBuilder进行定制
+        return new ApiInfoBuilder()
+                // 设置标题
+                .title("标题:若依管理系统_接口文档")
+                // 描述
+                .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
+                // 作者信息
+                .contact(new Contact(ruoyiConfig.getName(), null, null))
+                // 版本
+                .version("版本号:" + ruoyiConfig.getVersion())
+                .build();
+    }
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 192 - 0
zkqy-admin/src/main/java/com/zkqy/web/ljj.java


+ 18 - 0
zkqy-admin/src/main/java/com/zkqy/web/yb.java

@@ -0,0 +1,18 @@
+package com.zkqy.web;
+
+import org.junit.Test;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+public class yb {
+
+    public static void main(String[] args) {
+        int count = 0;
+        for(int i = 0;i < 100;i++)
+        {
+            count = ++count;
+        }
+        System.out.println("count = "+count);
+    }
+}

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

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

+ 11 - 0
zkqy-admin/src/main/resources/abc/TestController.java

@@ -0,0 +1,11 @@
+package com.zkqy.web.controller.dragForm;
+
+
+
+@RestController
+public class TestController {
+    @GetMapping("/dynamic")
+    public String dynamicEndpoint() {
+        return "This is a dynamically loaded controller!";
+    }
+}

+ 68 - 0
zkqy-admin/src/main/resources/application-druid.yml

@@ -0,0 +1,68 @@
+# 数据源配置
+spring:
+    datasource:
+        type: com.alibaba.druid.pool.DruidDataSource
+        driverClassName: com.mysql.cj.jdbc.Driver
+        druid:
+            # 主库数据源 http:///
+            master:
+                #url: jdbc:mysql://localhost:3306/ry-vue-call?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                url: jdbc:mysql://localhost:3306/hqzk?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                #url: jdbc:mysql://192.168.110.15:3306/ry-vue-call?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                #url: jdbc:mysql://121.37.234.37:3306/zkqyzk?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                username: root
+                #password: zkqy8888
+                password: root
+                #password: quanyi666
+#                password: zkqy123456,
+                #password: zkqy@8888888
+            # 从库数据源
+            slave:
+                # 从数据源开关/默认关闭
+                enabled: false
+                url: 
+                username: 
+                password: 
+            # 初始连接数
+            initialSize: 5
+            # 最小连接池数量
+            minIdle: 10
+            # 最大连接池数量
+            maxActive: 60
+            # 配置获取连接等待超时的时间
+            maxWait: 60000
+            # 配置连接超时时间
+            connectTimeout: 30000
+            # 配置网络超时时间
+            socketTimeout: 60000
+            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+            timeBetweenEvictionRunsMillis: 60000
+            # 配置一个连接在池中最小生存的时间,单位是毫秒
+            minEvictableIdleTimeMillis: 300000
+            # 配置一个连接在池中最大生存的时间,单位是毫秒
+            maxEvictableIdleTimeMillis: 900000
+            # 配置检测连接是否有效
+            validationQuery: SELECT 1 FROM DUAL
+            testWhileIdle: true
+            testOnBorrow: false
+            testOnReturn: false
+            webStatFilter: 
+                enabled: true
+            statViewServlet:
+                enabled: true
+                # 设置白名单,不填则允许所有访问
+                allow:
+                url-pattern: /druid/*
+                # 控制台管理用户名和密码
+                login-username: ruoyi
+                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

+ 212 - 0
zkqy-admin/src/main/resources/application.yml

@@ -0,0 +1,212 @@
+# 项目相关配置
+zkqy:
+  # 名称
+  name: zkqy
+  # 版本
+  version: 3.8.5
+  # 版权年份
+  copyrightYear: 2023
+  # 实例演示开关
+  demoEnabled: true
+  # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
+  profile: D:/zkqy/uploadPath
+  # 获取ip地址开关
+  addressEnabled: false
+  # 验证码类型 math 数组计算 char 字符验证
+  captchaType: math
+
+# 开发环境配置
+server:
+  # 服务器的HTTP端口,默认为8080
+  port: 8066
+  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.zkqy包及其子包下的日志级别为debug
+    com.zkqy: debug
+    # 设置org.springframework包及其子包下的日志级别为warn
+    org.springframework: warn
+  # 文件日志相关配置
+  file:
+    # 指定日志文件的输出目录
+    # 此处将所有生成的日志文件存储在D:/rz/logs路径下(日志文件必须名为)
+    # logback-spring.xml中可以读取这个配置项(注意:日志配置文件必须叫logback-spring.xml)
+    path: C:/logs
+
+# 用户配置
+user:
+  password:
+    # 密码最大错误次数
+    maxRetryCount: 5
+    # 密码锁定时间(默认10分钟)
+    lockTime: 10
+
+# Spring配置
+spring:
+  # 资源信息
+  messages:
+    # 国际化资源文件路径
+    basename: i18n/messages
+  profiles:
+    active: druid
+  # 文件上传
+  servlet:
+    multipart:
+      # 单个文件大小
+      max-file-size: 100MB
+      # 设置总上传的文件大小
+      max-request-size: 1000MB
+  # 服务模块
+  devtools:
+    restart:
+      # 热部署开关
+      enabled: true
+  # redis 配置
+  redis:
+    # 地址
+    host: localhost
+    # 端口,默认为6379
+    port: 6379
+    # 数据库索引
+    database: 14
+    # 密码
+    password:
+    # 连接超时时间
+    timeout: 10s
+    lettuce:
+      pool:
+        # 连接池中的最小空闲连接
+        min-idle: 0
+        # 连接池中的最大空闲连接
+        max-idle: 8
+        # 连接池的最大数据库连接数
+        max-active: 8
+        # #连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-wait: -1ms
+
+# token配置
+token:
+  # 令牌自定义标识
+  header: Authorization
+  # 令牌密钥
+  secret: abcdefghijklmnopqrstuvwxyz
+  # 令牌有效期(默认30分钟)3000000
+  expireTime: 3000000
+
+# MyBatis配置
+mybatis:
+  # 搜索指定包别名
+  typeAliasesPackage: com.zkqy.**.domain
+  # 配置mapper的扫描,找到所有的mapper.xml映射文件
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 加载全局的配置文件
+  configLocation: classpath:mybatis/mybatis-config.xml
+
+# PageHelper分页插件
+pagehelper:
+  #sql方言
+  helperDialect: mysql
+  #是否支持通过方法参数来传递分页参数(如 pageNum 和 pageSize)
+  #supportMethodsArguments 设置为 true,PageHelper 会自动识别 pageNum 和 pageSize 参数,并进行分页处理。
+  #如果设置为 false,则需要在调用 Mapper 方法之前手动调用 PageHelper.startPage() 来设置分页参数。
+  supportMethodsArguments: false
+  #count=countSql:这是一个常用的配置项,表示在分页查询时是否执行 count 查询以获取总记录数。
+  #count=countSql:表示在分页查询时,会执行一个 count 查询语句来获取总记录数。
+  params: count=countSql
+  #关闭合理化分页
+  reasonable: false
+
+
+# Shiro
+shiro:
+  user:
+    # 登录地址
+    loginUrl: /login
+    # 权限认证失败地址
+    unauthorizedUrl: /unauth
+    # 首页地址
+    indexUrl: /index
+    # 验证码开关
+    captchaEnabled: true
+    # 验证码类型 math 数组计算 char 字符
+    captchaType: math
+  cookie:
+    # 设置Cookie的域名 默认空,即当前访问的域名
+    domain:
+    # 设置cookie的有效访问路径
+    path: /
+    # 设置HttpOnly属性
+    httpOnly: true
+    # 设置Cookie的过期时间,天为单位
+    maxAge: 30
+    # 设置密钥,务必保持唯一性(生成方式,直接拷贝到main运行即可)Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) (默认启动生成随机秘钥,随机秘钥会导致之前客户端RememberMe Cookie无效,如设置固定秘钥RememberMe Cookie则有效)
+    cipherKey:
+  session:
+    # Session超时时间,-1代表永不过期(默认30分钟)
+    expireTime: 30
+    # 同步session到数据库的周期(默认1分钟)
+    dbSyncPeriod: 1
+    # 相隔多久检查一次session的有效性,默认就是10分钟
+    validationInterval: 10
+    # 同一个用户最大会话数,比如2的意思是同一个账号允许最多同时两个人登录(默认-1不限制)
+    maxSession: -1
+    # 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
+    kickoutAfter: false
+  rememberMe:
+    # 是否开启记住我
+    enabled: true
+
+# Swagger配置
+swagger:
+  # 是否开启swagger
+  enabled: true
+  # 请求前缀
+  pathMapping: /dev-api
+
+# 防止XSS攻击
+xss:
+  # 过滤开关
+  enabled: true
+  # 排除链接(多个用逗号分隔)
+  excludes: /system/notice
+  # 匹配链接
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# cas配置
+cas:
+  client-name: CasClient
+  server:
+    url: http://localhost:8080/cas
+  project:
+    url: http://localhost:80
+
+projectDownloadZip:
+  mysql: /usr/local/mysql/bin/mysqldump
+
+OpenAuthorization2:
+  MES:
+    # 单点获取code、token、userinfo主机地址
+    URL: http://192.168.110.83:8066/oauth2
+    # 系统标识
+    BASIC: mes
+    # 重定向本系统主机地址
+    REDIRECT_URL: http://192.168.110.83:1025
+    # 回调地址
+    CALLBACK: http://192.168.110.83:8066/oauth/callback
+    #
+    NAME: hmc

+ 61 - 0
zkqy-admin/src/main/resources/bak1/application-druid.yml

@@ -0,0 +1,61 @@
+# 数据源配置
+spring:
+    datasource:
+        type: com.alibaba.druid.pool.DruidDataSource
+        driverClassName: com.mysql.cj.jdbc.Driver
+        druid:
+            # 主库数据源
+            master:
+                url: jdbc:mysql://62.234.61.92:3306/ry-vue-call?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                username: root
+                password: zkqy123456,
+            # 从库数据源
+            slave:
+                # 从数据源开关/默认关闭
+                enabled: false
+                url: 
+                username: 
+                password: 
+            # 初始连接数
+            initialSize: 5
+            # 最小连接池数量
+            minIdle: 10
+            # 最大连接池数量
+            maxActive: 20
+            # 配置获取连接等待超时的时间
+            maxWait: 60000
+            # 配置连接超时时间
+            connectTimeout: 30000
+            # 配置网络超时时间
+            socketTimeout: 60000
+            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+            timeBetweenEvictionRunsMillis: 60000
+            # 配置一个连接在池中最小生存的时间,单位是毫秒
+            minEvictableIdleTimeMillis: 300000
+            # 配置一个连接在池中最大生存的时间,单位是毫秒
+            maxEvictableIdleTimeMillis: 900000
+            # 配置检测连接是否有效
+            validationQuery: SELECT 1 FROM DUAL
+            testWhileIdle: true
+            testOnBorrow: false
+            testOnReturn: false
+            webStatFilter: 
+                enabled: true
+            statViewServlet:
+                enabled: true
+                # 设置白名单,不填则允许所有访问
+                allow:
+                url-pattern: /druid/*
+                # 控制台管理用户名和密码
+                login-username: ruoyi
+                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

+ 176 - 0
zkqy-admin/src/main/resources/bak1/application.yml

@@ -0,0 +1,176 @@
+# 项目相关配置
+zkqy:
+  # 名称
+  name: zkqy
+  # 版本
+  version: 3.8.5
+  # 版权年份
+  copyrightYear: 2023
+  # 实例演示开关
+  demoEnabled: true
+  # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
+  profile: C:/log
+  # 获取ip地址开关
+  addressEnabled: false
+  # 验证码类型 math 数组计算 char 字符验证
+  captchaType: math
+
+# 开发环境配置
+server:
+  # 服务器的HTTP端口,默认为8080
+  port: 8066
+  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.zkqy: debug
+    org.springframework: warn
+
+# 用户配置
+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: 62.234.61.92
+    # 端口,默认为6379
+    port: 6379
+    # 数据库索引
+    database: 11
+    # 密码
+    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: 3000000
+
+# MyBatis配置
+mybatis:
+  # 搜索指定包别名
+  typeAliasesPackage: com.zkqy.**.domain
+  # 配置mapper的扫描,找到所有的mapper.xml映射文件
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 加载全局的配置文件
+  configLocation: classpath:mybatis/mybatis-config.xml
+
+# 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/*
+
+# 参数配置项
+parameter:
+  ip:
+    # 数据引擎切换数据源接口地址
+    DATA_ENGINE_IP: http://localhost:8099/dataSource/changeDataSource
+    # 动态表单切换数据源接口地址
+    DRAG_FORM_IP: http://localhost:8088/dataSource/changeDataSource
+    # 流程引擎切换数据源接口地址
+    PROCESS_ENGINE_IP: http://localhost:8055/dataSource/changeDataSource
+    #数据引擎初始化数据库表接口地址
+    DATA_ENGINE_INITDATABASE_IP: http://localhost:8099/tableInfo/initDatabase
+
+    # 用户下对应的所有角色key
+    MAIN_ROLESKEY_IP: http://localhost:8080/system/user/roleKeyByUserId
+    # CRM项目根据scriptKey获取节点脚本详情地址
+    GET_NODESCRIPT_IP: http://localhost:8080/system/script/selectSysBpmNodeScriptByScriptKey/{scriptKey}
+    # crm项目查看角色下是否存在真实用户
+    QUERY_USER_EXISTS_BY_ROLEKEY_IP: http://localhost:8080/system/role/selectUserByRoleKey/{roleKeys}
+    # crm项目查看一组用户是否存在真实用户
+    QUERY_USER_EXISTS_BY_USERIDS_IP: http://localhost:8080/system/user/selectUserByUserIds/{userIds}
+    # form项目共通修改接口
+    FORM_COMMON_UPDATE_IP: http://localhost:8088/dragform/common/batchEdit
+    #from项目共通获取详情接口
+    FORM_COMMON_GETINFO_IP: http://localhost:8088/dragform/common/getInfo
+    # form项目共通新增接口
+    FORM_COMMON_BATCHINSERT_IP: http://localhost:8088/dragform/common/batchInsert
+    # CRM项目根据scriptKeys获取节点脚本详情地址
+    GET_NODESCRIPTS_IP: http://localhost:8080/system/script/selectSysBpmNodeScriptByScriptKeys
+    # 租户字典:根据字典类型得到当前字典下的所有的数据
+    GET_TENANT_DICT_IP: http://localhost:8088/system/dict/data/list
+    # form项目共通新增接口
+    FORM_COMMON_INSERT_IP: http://localhost:8088/dragform/common/batchInsert
+    # form项目根据表单Fid查询详情接口
+    FORM_GET_FORM_INFO_IP: http://localhost:8088/dragform/form/{fId}
+    # from项目根据groupKey查询表格组信息
+    FORM_GET_GROUP_INFO_IP: http://localhost:8088/system/group/getInfoBySqlKey/{groupKey}
+    # CRM项目获取所有模板库数据表
+    CRM_QUERY_TEMPLATEBASE_TABLE: http://localhost:8080/system/templateBase/queryTemplateBaseTable
+
+bpm:
+  runbpmurl: http://localhost:8055/system/runbpm/process/productionScheduling
+
+script:
+  runscripturl: http://localhost:8055/system/script/execute

+ 24 - 0
zkqy-admin/src/main/resources/banner.txt

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

+ 66 - 0
zkqy-admin/src/main/resources/bf1/application-druid.yml

@@ -0,0 +1,66 @@
+# 数据源配置
+spring:
+    datasource:
+        type: com.alibaba.druid.pool.DruidDataSource
+        driverClassName: com.mysql.cj.jdbc.Driver
+        druid:
+            # 主库数据源 http:///
+            master:
+                url: jdbc:mysql://localhost:3306/ry-vue-call?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                #url: jdbc:mysql://192.168.110.15:3306/ry-vue-call?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                #url: jdbc:mysql://121.37.234.37:3306/zkqyzk?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                username: root
+                #password: zkqy8888
+#                password: quanyi666
+                password: root
+                #password: zkqy@8888888
+            # 从库数据源
+            slave:
+                # 从数据源开关/默认关闭
+                enabled: false
+                url: 
+                username: 
+                password: 
+            # 初始连接数
+            initialSize: 5
+            # 最小连接池数量
+            minIdle: 10
+            # 最大连接池数量
+            maxActive: 60
+            # 配置获取连接等待超时的时间
+            maxWait: 60000
+            # 配置连接超时时间
+            connectTimeout: 30000
+            # 配置网络超时时间
+            socketTimeout: 60000
+            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+            timeBetweenEvictionRunsMillis: 60000
+            # 配置一个连接在池中最小生存的时间,单位是毫秒
+            minEvictableIdleTimeMillis: 300000
+            # 配置一个连接在池中最大生存的时间,单位是毫秒
+            maxEvictableIdleTimeMillis: 900000
+            # 配置检测连接是否有效
+            validationQuery: SELECT 1 FROM DUAL
+            testWhileIdle: true
+            testOnBorrow: false
+            testOnReturn: false
+            webStatFilter: 
+                enabled: true
+            statViewServlet:
+                enabled: true
+                # 设置白名单,不填则允许所有访问
+                allow:
+                url-pattern: /druid/*
+                # 控制台管理用户名和密码
+                login-username: ruoyi
+                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

+ 203 - 0
zkqy-admin/src/main/resources/bf1/application.yml

@@ -0,0 +1,203 @@
+# 项目相关配置
+zkqy:
+  # 名称
+  name: zkqy
+  # 版本
+  version: 3.8.5
+  # 版权年份
+  copyrightYear: 2023
+  # 实例演示开关
+  demoEnabled: true
+  # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
+  profile: D:/zkqy/uploadPath
+  # 获取ip地址开关
+  addressEnabled: false
+  # 验证码类型 math 数组计算 char 字符验证
+  captchaType: math
+
+# 开发环境配置
+server:
+  # 服务器的HTTP端口,默认为8080
+  port: 8066
+  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.zkqy包及其子包下的日志级别为debug
+    com.zkqy: debug
+    # 设置org.springframework包及其子包下的日志级别为warn
+    org.springframework: warn
+  # 文件日志相关配置
+  file:
+    # 指定日志文件的输出目录
+    # 此处将所有生成的日志文件存储在D:/rz/logs路径下(日志文件必须名为)
+    # logback-spring.xml中可以读取这个配置项(注意:日志配置文件必须叫logback-spring.xml)
+    path: C:/logs
+
+# 用户配置
+user:
+  password:
+    # 密码最大错误次数
+    maxRetryCount: 5
+    # 密码锁定时间(默认10分钟)
+    lockTime: 10
+
+# Spring配置
+spring:
+  # 资源信息
+  messages:
+    # 国际化资源文件路径
+    basename: i18n/messages
+  profiles:
+    active: druid
+  # 文件上传
+  servlet:
+    multipart:
+      # 单个文件大小
+      max-file-size: 100MB
+      # 设置总上传的文件大小
+      max-request-size: 1000MB
+  # 服务模块
+  devtools:
+    restart:
+      # 热部署开关
+      enabled: true
+  # redis 配置
+  redis:
+    # 地址
+    host: 121.37.234.37
+    # 端口,默认为6379
+    port: 6379
+    # 数据库索引
+    database: 10
+    # 密码
+    password: zkqy@8888888
+    # 连接超时时间
+    timeout: 10s
+    lettuce:
+      pool:
+        # 连接池中的最小空闲连接
+        min-idle: 0
+        # 连接池中的最大空闲连接
+        max-idle: 8
+        # 连接池的最大数据库连接数
+        max-active: 8
+        # #连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-wait: -1ms
+
+# token配置
+token:
+  # 令牌自定义标识
+  header: Authorization
+  # 令牌密钥
+  secret: abcdefghijklmnopqrstuvwxyz
+  # 令牌有效期(默认30分钟)3000000
+  expireTime: 144000000
+
+# MyBatis配置
+mybatis:
+  # 搜索指定包别名
+  typeAliasesPackage: com.zkqy.**.domain
+  # 配置mapper的扫描,找到所有的mapper.xml映射文件
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 加载全局的配置文件
+  configLocation: classpath:mybatis/mybatis-config.xml
+
+# PageHelper分页插件
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Shiro
+shiro:
+  user:
+    # 登录地址
+    loginUrl: /login
+    # 权限认证失败地址
+    unauthorizedUrl: /unauth
+    # 首页地址
+    indexUrl: /index
+    # 验证码开关
+    captchaEnabled: true
+    # 验证码类型 math 数组计算 char 字符
+    captchaType: math
+  cookie:
+    # 设置Cookie的域名 默认空,即当前访问的域名
+    domain:
+    # 设置cookie的有效访问路径
+    path: /
+    # 设置HttpOnly属性
+    httpOnly: true
+    # 设置Cookie的过期时间,天为单位
+    maxAge: 30
+    # 设置密钥,务必保持唯一性(生成方式,直接拷贝到main运行即可)Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) (默认启动生成随机秘钥,随机秘钥会导致之前客户端RememberMe Cookie无效,如设置固定秘钥RememberMe Cookie则有效)
+    cipherKey:
+  session:
+    # Session超时时间,-1代表永不过期(默认30分钟)
+    expireTime: 30
+    # 同步session到数据库的周期(默认1分钟)
+    dbSyncPeriod: 1
+    # 相隔多久检查一次session的有效性,默认就是10分钟
+    validationInterval: 10
+    # 同一个用户最大会话数,比如2的意思是同一个账号允许最多同时两个人登录(默认-1不限制)
+    maxSession: -1
+    # 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
+    kickoutAfter: false
+  rememberMe:
+    # 是否开启记住我
+    enabled: true
+
+# Swagger配置
+swagger:
+  # 是否开启swagger
+  enabled: true
+  # 请求前缀
+  pathMapping: /dev-api
+
+# 防止XSS攻击
+xss:
+  # 过滤开关
+  enabled: true
+  # 排除链接(多个用逗号分隔)
+  excludes: /system/notice
+  # 匹配链接
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# cas配置
+cas:
+  client-name: CasClient
+  server:
+    url: http://localhost:8080/cas
+  project:
+    url: http://localhost:80
+
+projectDownloadZip:
+  mysql: /usr/local/mysql/bin/mysqldump
+
+OpenAuthorization2:
+  MES:
+    # 单点获取code、token、userinfo主机地址
+    URL: http://192.168.2.127:8066/oauth2
+    # 系统标识
+    BASIC: mes
+    # 重定向本系统主机地址
+    REDIRECT_URL: http://192.168.2.127:1025
+    # 回调地址
+    CALLBACK: http://192.168.2.127:8066/oauth/callback
+    #
+    NAME: hmc

+ 66 - 0
zkqy-admin/src/main/resources/bf2/application-druid.yml

@@ -0,0 +1,66 @@
+# 数据源配置
+spring:
+    datasource:
+        type: com.alibaba.druid.pool.DruidDataSource
+        driverClassName: com.mysql.cj.jdbc.Driver
+        druid:
+            # 主库数据源 http:///
+            master:
+                url: jdbc:mysql://localhost:3307/ry-vue-call?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                #url: jdbc:mysql://192.168.110.15:3306/ry-vue-call?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                #url: jdbc:mysql://121.37.234.37:3306/zkqyzk?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                username: root
+                #password: zkqy8888
+                password: quanyi666
+                #password: root
+                #password: zkqy@8888888
+            # 从库数据源
+            slave:
+                # 从数据源开关/默认关闭
+                enabled: false
+                url: 
+                username: 
+                password: 
+            # 初始连接数
+            initialSize: 5
+            # 最小连接池数量
+            minIdle: 10
+            # 最大连接池数量
+            maxActive: 60
+            # 配置获取连接等待超时的时间
+            maxWait: 60000
+            # 配置连接超时时间
+            connectTimeout: 30000
+            # 配置网络超时时间
+            socketTimeout: 60000
+            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+            timeBetweenEvictionRunsMillis: 60000
+            # 配置一个连接在池中最小生存的时间,单位是毫秒
+            minEvictableIdleTimeMillis: 300000
+            # 配置一个连接在池中最大生存的时间,单位是毫秒
+            maxEvictableIdleTimeMillis: 900000
+            # 配置检测连接是否有效
+            validationQuery: SELECT 1 FROM DUAL
+            testWhileIdle: true
+            testOnBorrow: false
+            testOnReturn: false
+            webStatFilter: 
+                enabled: true
+            statViewServlet:
+                enabled: true
+                # 设置白名单,不填则允许所有访问
+                allow:
+                url-pattern: /druid/*
+                # 控制台管理用户名和密码
+                login-username: ruoyi
+                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

+ 208 - 0
zkqy-admin/src/main/resources/bf2/application.yml

@@ -0,0 +1,208 @@
+# 项目相关配置
+zkqy:
+  # 名称
+  name: zkqy
+  # 版本
+  version: 3.8.5
+  # 版权年份
+  copyrightYear: 2023
+  # 实例演示开关
+  demoEnabled: true
+  # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
+  profile: D:/zkqy/uploadPath
+  # 获取ip地址开关
+  addressEnabled: false
+  # 验证码类型 math 数组计算 char 字符验证
+  captchaType: math
+
+# 开发环境配置
+server:
+  # 服务器的HTTP端口,默认为8080
+  port: 8066
+  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.zkqy包及其子包下的日志级别为debug
+    com.zkqy: debug
+    # 设置org.springframework包及其子包下的日志级别为warn
+    org.springframework: warn
+  # 文件日志相关配置
+  file:
+    # 指定日志文件的输出目录
+    # 此处将所有生成的日志文件存储在D:/rz/logs路径下(日志文件必须名为)
+    # logback-spring.xml中可以读取这个配置项(注意:日志配置文件必须叫logback-spring.xml)
+    path: C:/logs
+
+# 用户配置
+user:
+  password:
+    # 密码最大错误次数
+    maxRetryCount: 5
+    # 密码锁定时间(默认10分钟)
+    lockTime: 10
+
+# Spring配置
+spring:
+  # 资源信息
+  messages:
+    # 国际化资源文件路径
+    basename: i18n/messages
+  profiles:
+    active: druid
+  # 文件上传
+  servlet:
+    multipart:
+      # 单个文件大小
+      max-file-size: 100MB
+      # 设置总上传的文件大小
+      max-request-size: 1000MB
+  # 服务模块
+  devtools:
+    restart:
+      # 热部署开关
+      enabled: true
+  # redis 配置
+  redis:
+    # 地址
+#    host: 192.168.110.15
+    #host: 121.37.234.37
+    #
+    host: 127.0.0.1
+    # 端口,默认为6379
+    port: 6479
+    # 数据库索引
+    database: 10
+    # 密码
+    password:
+    #password: zkqy@8888888
+#    password: 123456
+    # 连接超时时间
+    timeout: 10s
+    lettuce:
+      pool:
+        # 连接池中的最小空闲连接
+        min-idle: 0
+        # 连接池中的最大空闲连接
+        max-idle: 8
+        # 连接池的最大数据库连接数
+        max-active: 8
+        # #连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-wait: -1ms
+
+# token配置
+token:
+  # 令牌自定义标识
+  header: Authorization
+  # 令牌密钥
+  secret: abcdefghijklmnopqrstuvwxyz
+  # 令牌有效期(默认30分钟)3000000
+  expireTime: 144000000
+
+# MyBatis配置
+mybatis:
+  # 搜索指定包别名
+  typeAliasesPackage: com.zkqy.**.domain
+  # 配置mapper的扫描,找到所有的mapper.xml映射文件
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 加载全局的配置文件
+  configLocation: classpath:mybatis/mybatis-config.xml
+
+# PageHelper分页插件
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Shiro
+shiro:
+  user:
+    # 登录地址
+    loginUrl: /login
+    # 权限认证失败地址
+    unauthorizedUrl: /unauth
+    # 首页地址
+    indexUrl: /index
+    # 验证码开关
+    captchaEnabled: true
+    # 验证码类型 math 数组计算 char 字符
+    captchaType: math
+  cookie:
+    # 设置Cookie的域名 默认空,即当前访问的域名
+    domain:
+    # 设置cookie的有效访问路径
+    path: /
+    # 设置HttpOnly属性
+    httpOnly: true
+    # 设置Cookie的过期时间,天为单位
+    maxAge: 30
+    # 设置密钥,务必保持唯一性(生成方式,直接拷贝到main运行即可)Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) (默认启动生成随机秘钥,随机秘钥会导致之前客户端RememberMe Cookie无效,如设置固定秘钥RememberMe Cookie则有效)
+    cipherKey:
+  session:
+    # Session超时时间,-1代表永不过期(默认30分钟)
+    expireTime: 30
+    # 同步session到数据库的周期(默认1分钟)
+    dbSyncPeriod: 1
+    # 相隔多久检查一次session的有效性,默认就是10分钟
+    validationInterval: 10
+    # 同一个用户最大会话数,比如2的意思是同一个账号允许最多同时两个人登录(默认-1不限制)
+    maxSession: -1
+    # 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
+    kickoutAfter: false
+  rememberMe:
+    # 是否开启记住我
+    enabled: true
+
+# Swagger配置
+swagger:
+  # 是否开启swagger
+  enabled: true
+  # 请求前缀
+  pathMapping: /dev-api
+
+# 防止XSS攻击
+xss:
+  # 过滤开关
+  enabled: true
+  # 排除链接(多个用逗号分隔)
+  excludes: /system/notice
+  # 匹配链接
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# cas配置
+cas:
+  client-name: CasClient
+  server:
+    url: http://localhost:8080/cas
+  project:
+    url: http://localhost:80
+
+projectDownloadZip:
+  mysql: /usr/local/mysql/bin/mysqldump
+
+OpenAuthorization2:
+  MES:
+    # 单点获取code、token、userinfo主机地址
+    URL: http://192.168.2.135:8066/oauth2
+    # 系统标识
+    BASIC: mes
+    # 重定向本系统主机地址
+    REDIRECT_URL: http://192.168.2.135:1025
+    # 回调地址
+    CALLBACK: http://192.168.2.135:8066/oauth/callback
+    #
+    NAME: mestools

+ 66 - 0
zkqy-admin/src/main/resources/bf3/application-druid.yml

@@ -0,0 +1,66 @@
+# 数据源配置
+spring:
+    datasource:
+        type: com.alibaba.druid.pool.DruidDataSource
+        driverClassName: com.mysql.cj.jdbc.Driver
+        druid:
+            # 主库数据源 http:///
+            master:
+                url: jdbc:mysql://localhost:3306/ry-vue-call?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                #url: jdbc:mysql://192.168.110.15:3306/ry-vue-call?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                #url: jdbc:mysql://121.37.234.37:3306/zkqyzk?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true
+                username: root
+                #password: zkqy8888
+#                password: quanyi666
+                password: root
+                #password: zkqy@8888888
+            # 从库数据源
+            slave:
+                # 从数据源开关/默认关闭
+                enabled: false
+                url: 
+                username: 
+                password: 
+            # 初始连接数
+            initialSize: 5
+            # 最小连接池数量
+            minIdle: 10
+            # 最大连接池数量
+            maxActive: 60
+            # 配置获取连接等待超时的时间
+            maxWait: 60000
+            # 配置连接超时时间
+            connectTimeout: 30000
+            # 配置网络超时时间
+            socketTimeout: 60000
+            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+            timeBetweenEvictionRunsMillis: 60000
+            # 配置一个连接在池中最小生存的时间,单位是毫秒
+            minEvictableIdleTimeMillis: 300000
+            # 配置一个连接在池中最大生存的时间,单位是毫秒
+            maxEvictableIdleTimeMillis: 900000
+            # 配置检测连接是否有效
+            validationQuery: SELECT 1 FROM DUAL
+            testWhileIdle: true
+            testOnBorrow: false
+            testOnReturn: false
+            webStatFilter: 
+                enabled: true
+            statViewServlet:
+                enabled: true
+                # 设置白名单,不填则允许所有访问
+                allow:
+                url-pattern: /druid/*
+                # 控制台管理用户名和密码
+                login-username: ruoyi
+                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

+ 203 - 0
zkqy-admin/src/main/resources/bf3/application.yml

@@ -0,0 +1,203 @@
+# 项目相关配置
+zkqy:
+  # 名称
+  name: zkqy
+  # 版本
+  version: 3.8.5
+  # 版权年份
+  copyrightYear: 2023
+  # 实例演示开关
+  demoEnabled: true
+  # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
+  profile: D:/zkqy/uploadPath
+  # 获取ip地址开关
+  addressEnabled: false
+  # 验证码类型 math 数组计算 char 字符验证
+  captchaType: math
+
+# 开发环境配置
+server:
+  # 服务器的HTTP端口,默认为8080
+  port: 8066
+  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.zkqy包及其子包下的日志级别为debug
+    com.zkqy: debug
+    # 设置org.springframework包及其子包下的日志级别为warn
+    org.springframework: warn
+  # 文件日志相关配置
+  file:
+    # 指定日志文件的输出目录
+    # 此处将所有生成的日志文件存储在D:/rz/logs路径下(日志文件必须名为)
+    # logback-spring.xml中可以读取这个配置项(注意:日志配置文件必须叫logback-spring.xml)
+    path: C:/logs
+
+# 用户配置
+user:
+  password:
+    # 密码最大错误次数
+    maxRetryCount: 5
+    # 密码锁定时间(默认10分钟)
+    lockTime: 10
+
+# Spring配置
+spring:
+  # 资源信息
+  messages:
+    # 国际化资源文件路径
+    basename: i18n/messages
+  profiles:
+    active: druid
+  # 文件上传
+  servlet:
+    multipart:
+      # 单个文件大小
+      max-file-size: 100MB
+      # 设置总上传的文件大小
+      max-request-size: 1000MB
+  # 服务模块
+  devtools:
+    restart:
+      # 热部署开关
+      enabled: true
+  # redis 配置
+  redis:
+    # 地址
+    host: 121.37.234.37
+    # 端口,默认为6379
+    port: 6379
+    # 数据库索引
+    database: 3
+    # 密码
+    password: zkqy@8888888
+    # 连接超时时间
+    timeout: 10s
+    lettuce:
+      pool:
+        # 连接池中的最小空闲连接
+        min-idle: 0
+        # 连接池中的最大空闲连接
+        max-idle: 8
+        # 连接池的最大数据库连接数
+        max-active: 8
+        # #连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-wait: -1ms
+
+# token配置
+token:
+  # 令牌自定义标识
+  header: Authorization
+  # 令牌密钥
+  secret: abcdefghijklmnopqrstuvwxyz
+  # 令牌有效期(默认30分钟)3000000
+  expireTime: 144000000
+
+# MyBatis配置
+mybatis:
+  # 搜索指定包别名
+  typeAliasesPackage: com.zkqy.**.domain
+  # 配置mapper的扫描,找到所有的mapper.xml映射文件
+  mapperLocations: classpath*:mapper/**/*Mapper.xml
+  # 加载全局的配置文件
+  configLocation: classpath:mybatis/mybatis-config.xml
+
+# PageHelper分页插件
+pagehelper:
+  helperDialect: mysql
+  supportMethodsArguments: true
+  params: count=countSql
+
+# Shiro
+shiro:
+  user:
+    # 登录地址
+    loginUrl: /login
+    # 权限认证失败地址
+    unauthorizedUrl: /unauth
+    # 首页地址
+    indexUrl: /index
+    # 验证码开关
+    captchaEnabled: true
+    # 验证码类型 math 数组计算 char 字符
+    captchaType: math
+  cookie:
+    # 设置Cookie的域名 默认空,即当前访问的域名
+    domain:
+    # 设置cookie的有效访问路径
+    path: /
+    # 设置HttpOnly属性
+    httpOnly: true
+    # 设置Cookie的过期时间,天为单位
+    maxAge: 30
+    # 设置密钥,务必保持唯一性(生成方式,直接拷贝到main运行即可)Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) (默认启动生成随机秘钥,随机秘钥会导致之前客户端RememberMe Cookie无效,如设置固定秘钥RememberMe Cookie则有效)
+    cipherKey:
+  session:
+    # Session超时时间,-1代表永不过期(默认30分钟)
+    expireTime: 30
+    # 同步session到数据库的周期(默认1分钟)
+    dbSyncPeriod: 1
+    # 相隔多久检查一次session的有效性,默认就是10分钟
+    validationInterval: 10
+    # 同一个用户最大会话数,比如2的意思是同一个账号允许最多同时两个人登录(默认-1不限制)
+    maxSession: -1
+    # 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
+    kickoutAfter: false
+  rememberMe:
+    # 是否开启记住我
+    enabled: true
+
+# Swagger配置
+swagger:
+  # 是否开启swagger
+  enabled: true
+  # 请求前缀
+  pathMapping: /dev-api
+
+# 防止XSS攻击
+xss:
+  # 过滤开关
+  enabled: true
+  # 排除链接(多个用逗号分隔)
+  excludes: /system/notice
+  # 匹配链接
+  urlPatterns: /system/*,/monitor/*,/tool/*
+
+# cas配置
+cas:
+  client-name: CasClient
+  server:
+    url: http://localhost:8080/cas
+  project:
+    url: http://localhost:80
+
+projectDownloadZip:
+  mysql: /usr/local/mysql/bin/mysqldump
+
+OpenAuthorization2:
+  MES:
+    # 单点获取code、token、userinfo主机地址
+    URL: http://192.168.2.127:8066/oauth2
+    # 系统标识
+    BASIC: mes
+    # 重定向本系统主机地址
+    REDIRECT_URL: http://192.168.2.127:1025
+    # 回调地址
+    CALLBACK: http://192.168.2.127:8066/oauth/callback
+    #
+    NAME: hmc

+ 38 - 0
zkqy-admin/src/main/resources/i18n/messages.properties

@@ -0,0 +1,38 @@
+#错误消息
+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}次,帐户锁定{1}分钟
+user.password.delete=对不起,您的账号已被删除
+user.blocked=用户已封禁,请联系管理员
+role.blocked=角色已封禁,请联系管理员
+login.blocked=很遗憾,访问IP已被列入系统黑名单
+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}]

+ 96 - 0
zkqy-admin/src/main/resources/logback-spring.xml

@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <!-- 日志存放路径 -->
+    <!--<property name="log.path" value="./logs" />-->
+    <!-- 日志存放路径 -->
+    <!-- 引入Spring Boot的环境变量 文件名必须叫 logback-spring 否则不能引用logging.file.path -->
+    <springProperty scope="context" name="log.path" source="logging.file.path"/>
+    <!-- 日志输出格式 -->
+	<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>INFO</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.zkqy" level="info" />
+	<!-- Spring日志级别控制  -->
+	<logger name="org.springframework" level="warn" />
+
+	<root level="info">
+		<appender-ref ref="console" />
+	</root>
+	
+	<!--系统操作日志-->
+    <root level="info">
+        <appender-ref ref="file_info" />
+        <appender-ref ref="file_error" />
+    </root>
+	
+	<!--系统用户操作日志-->
+    <logger name="sys-user" level="info">
+        <appender-ref ref="sys-user"/>
+    </logger>
+</configuration> 

+ 43 - 0
zkqy-admin/src/main/resources/mybatis/mybatis-config.xml

@@ -0,0 +1,43 @@
+<?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="logImpl" value="STDOUT_LOGGING"/>-->
+        <!--        <setting name="lazyLoadingEnabled" value="false"/>-->
+        <!--        <setting name="aggressiveLazyLoading" value="true"/>-->
+        <!-- 使用驼峰命名法转换字段 -->
+        <setting name="mapUnderscoreToCamelCase" value="true"/>
+        <!-- value为空时显示key -->
+        <setting name="callSettersOnNulls" value="true"/>
+        <!--驼峰转换-->
+        <setting name="mapUnderscoreToCamelCase" value="true"/>
+
+    </settings>
+
+    <!-- 类型处理器-->
+    <typeHandlers>
+        <typeHandler handler="com.zkqy.system.domain.BlobTypeHandler"/>
+    </typeHandlers>
+
+    <!-- 重写驼峰转换工具类  -->
+    <objectWrapperFactory type="com.zkqy.common.utils.MapWrapperFactory"/>
+
+    <!-- sql拦截器 -->
+    <plugins>
+        <plugin interceptor="com.zkqy.framework.aspectj.SqlInterceptor"/>
+    </plugins>
+
+</configuration>

+ 233 - 0
zkqy-admin/src/test/java/com/zkqy/Test01.java

@@ -0,0 +1,233 @@
+package com.zkqy;
+
+
+
+import com.alibaba.fastjson2.JSON;
+import com.google.gson.Gson;
+import com.kingdee.bos.webapi.entity.IdentifyInfo;
+import com.kingdee.bos.webapi.entity.QueryParam;
+import com.kingdee.bos.webapi.sdk.K3CloudApi;
+import com.zkqy.amichi.domain.ProcedureList;
+import com.zkqy.amichi.domain.RingScanInformation;
+import com.zkqy.amichi.mapper.ProcedureListMapper;
+import com.zkqy.amichi.service.ISharedFileService;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.R;
+import com.zkqy.system.domain.sso.User;
+import org.apache.http.client.HttpClient;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.redis.support.collections.RedisList;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import javax.annotation.Resource;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+
+@SpringBootTest(classes = ZkqyApplication.class)
+
+public class Test01 {
+
+    @Test
+    public void testA() throws Exception {
+//        K3CloudApi api = new K3CloudApi();
+//        List datacenter = api.getDataCenters();
+//        Gson gson = new Gson();
+//        System.out.printf("或则环境账套信息:%s%n",gson.toJson(datacenter));
+//        System.out.println("ddddd");
+//
+//        //注意 1:此处不再使用参数形式传入用户名及密码等敏感信息,改为在登录配置文件中设置。
+//        //注意 2:必须先配置第三方系统登录授权信息后,再进行业务操作,详情参考各语言版本SDK介绍中的登录配置文件说明。
+//        //读取配置,初始化SDK
+//        //请求参数,要求为json字符串
+////        String jsonData = "{\"FormId\":\"PLN_PLANORDER\",\"FieldKeys\":\"FMaterialName,FMaterialId\",\"FilterString\":[],\"OrderString\":\"\",\"TopRowCount\":0,\"StartRow\":0,\"Limit\":2000,\"SubSystemId\":\"\"}";
+////        try {
+////            //调用接口
+////            String resultJson = String.valueOf(api.executeBillQuery(jsonData));
+////            System.out.println("接口返回结果: " + resultJson);
+////        } catch (Exception e) {
+////            System.out.println(e.getMessage());
+////        }
+//        String jsonDdata="{\"FormId\":\"PLN_PLANORDER\"}";
+//        String s = api.queryBusinessInfo(jsonDdata);
+//        System.out.println(s);
+        List<RingScanInformation> ringScanInformations=new ArrayList<>();
+
+        RingScanInformation scanInformation=new RingScanInformation();
+        scanInformation.setContentInformation("dddd");
+        scanInformation.setDeviceName("ddddd");
+        scanInformation.setId(1L);
+        scanInformation.setDeviceNumber("0001");
+        ringScanInformations.add(scanInformation);
+        AjaxResult success = AjaxResult.success(ringScanInformations);
+        String jsonString = JSON.toJSONString(success);
+        Map map = JSON.parseObject(jsonString, Map.class);
+        List<RingScanInformation> lists = JSON
+                .parseArray(map.get("data").toString(), RingScanInformation.class);
+        for (RingScanInformation list : lists) {
+            System.out.println(list);
+        }
+
+    }
+
+
+    @Test
+    public  void  test02() throws Exception {
+        String s="MO051961";
+        //2、大于这个编号的所有订单全部拉取回来
+        //2.1、new金蝶jdk工具类
+        K3CloudApi api = new K3CloudApi();
+        //2.2、
+        HashMap<String,Object > stringHashMap=new HashMap();
+        stringHashMap.put("FormId","PRD_MO");
+        List<String> stringList=new ArrayList<>();
+        stringList.add("FBillNo");
+        stringList.add("FBillType");
+        stringList.add("FDate");
+        stringList.add("FDocumentStatus");
+        stringList.add("FProductType");
+        stringList.add("FMaterialId");
+        stringList.add("FWorkShopID0");
+        stringList.add("FQty");
+        stringList.add("FStatus");
+        stringList.add("FSaleOrderNo");
+        stringList.add("FPickMtrlStatus");
+        stringHashMap.put("FieldKeys",stringList.stream().collect(Collectors.joining(",")));
+        HashMap gl=new HashMap();
+        gl.put("FieldName","FBillNo");
+        gl.put("Compare","72");
+        gl.put("Value",s);
+        gl.put("Left","");
+        gl.put("Right","");
+        gl.put("Logic","0");
+        List<Map> mapList=new ArrayList<>();
+        mapList.add(gl);
+        stringHashMap.put("FilterString",mapList);
+        stringHashMap.put("OrderString","");
+        stringHashMap.put("TopRowCount",0);
+        stringHashMap.put("StartRow",0);
+        stringHashMap.put("Limit",2000);
+        stringHashMap.put("SubSystemId","");
+        String jsonString = JSON.toJSONString(stringHashMap);
+        System.out.println(jsonString);
+        try {
+            String resultJson = String.valueOf(api.executeBillQuery(jsonString));
+            System.out.println(resultJson);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+
+    @Resource
+    private ISharedFileService sharedFileService;
+
+    @Test
+    public void test01(){
+        // 配置共享文件夹路径
+//        String sharedPath = "smb://username:password@192.168.1.100/share/";
+
+        // Windows共享文件夹路径
+        // 注意:中文需要使用 URLEncoder 进行编码
+
+
+            sharedFileService.syncSharedFiles();
+
+    }
+
+    @Autowired
+    public ThreadPoolTaskExecutor threadPoolTaskExecutor;
+
+    @Test
+    public void test03(){
+        // 模拟大数据集
+        List<String> largeDataSet = new ArrayList<>();
+        for (int i = 0; i < 50000; i++) {
+            largeDataSet.add("Data " + i);
+        }
+        // 分割数据集
+        int batchSize = 500;
+        int totalBatches = (int) Math.ceil((double) largeDataSet.size() / batchSize);
+
+        // 创建固定大小的线程池
+//        int threadPoolSize = 40; // 根据实际情况调整线程池大小
+//        ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
+
+        List<CompletableFuture<Void>> futures = new ArrayList<>();
+
+        long  l= System.currentTimeMillis();
+        System.out.println("开始时间"+l+"ms");
+        for (int i = 0; i < totalBatches; i++) {
+            int start = i * batchSize;
+            int end = Math.min(start + batchSize, largeDataSet.size());
+
+            // 创建一个子列表
+            List<String> subList = largeDataSet.subList(start, end);
+// 异步处理每个子列表
+            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
+                processData(subList); // 调用处理方法
+            }, threadPoolTaskExecutor);
+
+            futures.add(future);
+        }
+        // 等待所有异步任务完成
+        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
+        // 关闭线程池
+        long  l1= System.currentTimeMillis();
+        System.out.println("结束时间"+l1);
+        System.out.println("总计耗时:"+(l1-l));
+        threadPoolTaskExecutor.shutdown();
+    }
+
+
+    private static void processData(List<String> data) {
+        // 这里是处理数据的地方,例如插入数据库
+        System.out.println("Processing " + data.size() + " items.");
+        // 模拟耗时操作
+        try {
+            Thread.sleep(30); // 假设每个批次处理需要1秒
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void abc(){
+        Map<String, User> abc=new HashMap<>();
+        abc.put("1",new User());
+        abc.put("2",new User());
+        System.out.println(abc.get("3"));
+        if(abc.get("3")==null){
+            System.out.println("为null");
+        }
+        if(abc.get("1")!=null){
+            System.out.println("不为null");
+        }
+        double a=3.4;
+        System.out.println(a);
+    }
+
+    @Autowired
+    ProcedureListMapper procedureListMapper;
+    @Test
+    public  void setSharedFileService(){
+        List<ProcedureList> procedureLists = procedureListMapper.selectProcedureListMap();
+
+        Map<String, String> collect = procedureLists.stream()
+                .filter(procedureList ->
+                        procedureList.getElpname() != null && !procedureList.getElpname().isEmpty()) // 过滤条件
+                .collect(Collectors.toMap(ProcedureList::getElpname, ProcedureList::getProcedurName));
+
+
+
+    }
+}
+
+
+

+ 67 - 0
zkqy-business/pom.xml

@@ -0,0 +1,67 @@
+<?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>zkqy</artifactId>
+        <groupId>com.zkqy</groupId>
+        <version>3.8.5</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>zkqy-business</artifactId>
+    <name>zkqy-business</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.zkqy</groupId>
+            <artifactId>zkqy-framework</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>3.3.2</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.10.1</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.zkqy</groupId>
+            <artifactId>zkqy-process-execution</artifactId>
+            <version>3.8.5</version>
+        </dependency>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+            <version>1.6.2</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>net.bytebuddy</groupId>
+            <artifactId>byte-buddy</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.zkqy</groupId>
+            <artifactId>zkqy-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.zkqy</groupId>
+            <artifactId>zkqy-custom-business</artifactId>
+        </dependency>
+
+
+    </dependencies>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
+</project>

+ 459 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/CommonBtnController.java

@@ -0,0 +1,459 @@
+package com.zkqy.business.controller;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.TypeReference;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.zkqy.business.entity.DragForm;
+import com.zkqy.business.entity.DragTableBtn;
+import com.zkqy.business.service.IDragFormService;
+import com.zkqy.business.service.IDragTableBtnService;
+import com.zkqy.business.service.IDragTableGroupService;
+import com.zkqy.business.service.impl.DragTableBtnServiceImpl;
+
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.StringUtils;
+import com.zkqy.common.utils.form.FromUtils;
+import com.zkqy.execution.produce.dispersed.entity.CommonEntity;
+import com.zkqy.execution.produce.dispersed.entity.DragFormGroup;
+import com.zkqy.execution.produce.dispersed.entity.runbpm.BpmRunNodeFormDateVo;
+import com.zkqy.execution.produce.dispersed.mapper.BpmExecuteNodeFormMapper;
+import com.zkqy.execution.produce.dispersed.runbpm.PreExecutionToolClass;
+import com.zkqy.execution.produce.dispersed.runbpm.RunImplementationClass;
+import com.zkqy.execution.produce.dispersed.service.IBpmExecuteProcessService;
+import com.zkqy.execution.produce.dispersed.service.ICommonService;
+import com.zkqy.execution.produce.dispersed.service.IDragFormGroupService;
+import com.zkqy.execution.produce.utils.EchoNodeFormData;
+import org.apache.tools.ant.taskdefs.Sleep;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+/**
+ * @author hanzihang
+ * @date 2023/11/16 5:49 PM
+ */
+@RestController
+@RequestMapping("/dragform/commonbtn")
+public class CommonBtnController extends BaseController {
+
+    @Resource   // 共通crud
+    private ICommonService commonService;
+
+    @Resource  // 动态表单
+    private IDragFormService dragFormService;
+
+    @Resource  // 表格按钮
+    private IDragTableBtnService iDragTableBtnService;
+
+    @Resource
+    private FromUtils fromUtils;
+
+
+    @Resource
+    private IDragTableGroupService dragTableGroupService;
+
+    @Autowired
+    private PreExecutionToolClass ipreExecutionToolClass;
+
+    @Resource
+    private RunImplementationClass irunImplementationClass;
+
+    @Resource // 表单组
+    private IDragFormGroupService iDragFormGroupService;
+
+    @Autowired // 执行流程service
+    private IBpmExecuteProcessService iBpmExecuteProcessService;
+
+    @Autowired
+    private EchoNodeFormData echoNodeFormData;
+
+    @Autowired  // 节点
+    private BpmExecuteNodeFormMapper executeNodeFormMapper;
+
+    @Autowired
+    private DragTableBtnServiceImpl dragTableBtnService;
+
+    /**
+     * 处理按钮通用接口(新增、修改、删除...)
+     * 判断什么类型走什么接口: visible  false代表弹窗未开启时走回显表单模板及数据信息接口;true代表弹窗开启时走保存数据接口
+     * 是否提交表单操作 true是 false回显表单数据  commonEntity.getBasicMap().get("visible").toString()
+     */
+
+    @PostMapping("/commonBtnHandle")
+    @Log(title = "动态按钮操作", businessType = BusinessType.OTHER)
+    public AjaxResult commonBtnHandle(@RequestBody CommonEntity commonEntity) throws JsonProcessingException {
+        // 获取到按钮类型
+        String btnType = commonEntity.getBasicMap().get("btnType").toString();
+        //查询当前按钮详情
+        DragTableBtn dragTableBtn = new DragTableBtn();
+        if (commonEntity.getBasicMap().get("btnKey") != null && !commonEntity.getBasicMap().get("btnKey").toString().isEmpty()) {
+            dragTableBtn = iDragTableBtnService.selectDragTableBtnByBtnKey(commonEntity.getBasicMap().get("btnKey").toString());
+        }
+        /**
+         * 发起流程类型(需要特定参数),
+         * 启动脚本类型(执行特定脚本无需传递参数)
+         */
+        switch (btnType) {
+            case "INSERT":
+                return insertBtn(commonEntity, dragTableBtn);
+            case "UPDATE":
+                return updateBtn(commonEntity, dragTableBtn);
+            case "DELETE":
+                return deleteBtn(commonEntity);
+            case "EXECUTE":  // 执行脚本
+                return executeBtn(commonEntity, dragTableBtn);
+            case "INITIATED":  // 发起流程
+                return initiatedBtn(commonEntity, dragTableBtn);
+            default:
+                return warn("暂不支持该操作!");
+        }
+    }
+
+    /**
+     * 新增类型按钮
+     *
+     * @param commonEntity
+     * @return
+     */
+    public AjaxResult insertBtn(CommonEntity commonEntity, DragTableBtn dragTableBtn) throws JsonProcessingException {
+        if (commonEntity.getBasicMap().get("visible").toString().equals("true")) {
+            if (dragTableBtn.getBtnFormType() != null && dragTableBtn.getBtnFormType().equals("dragFormGroup")) {
+                // 表格组添加逻辑
+                BpmRunNodeFormDateVo bpmRunNodeFormDateVo = JSON.parseObject(JSON.toJSONString(commonEntity.getBasicMap().get("BpmRunNodeFormDateVo")), BpmRunNodeFormDateVo.class);
+                return AjaxResult.btnMessage(echoNodeFormData.handleSubmitForm(bpmRunNodeFormDateVo));
+            } else {
+                // 单个表单添加逻辑
+                return AjaxResult.btnMessage(commonService.batchInsert(commonEntity));
+            }
+        } else if (commonEntity.getBasicMap().get("visible").toString().equals("false")) {
+            if (dragTableBtn.getBtnFormType() != null && dragTableBtn.getBtnFormType().equals("dragFormGroup")) {
+                return success(getFormGroupInfo(commonEntity, dragTableBtn));
+            } else {
+                String sqlKey = commonEntity.getBasicMap().get("sqlKey").toString();
+                DragForm dragForm = dragFormService.selectDragFormBySqlKey(sqlKey);
+                if (dragForm != null) {
+                    return success(dragFormService.selectDragFormBySqlKey(sqlKey));
+                } else {
+                    String btnKey = commonEntity.getBasicMap().get("btnKey").toString();
+                    DragTableBtn dragTableBtnPojo = dragTableBtnService.selectDragTableBtnByBtnKey(btnKey);
+//                    dragTableBtnPojo.getBtnFormKey();
+                    return success(dragFormService.selectDragFormByformKey(dragTableBtnPojo.getBtnFormKey()));
+                }
+            }
+        } else {
+            return warn("暂不支持该操作!");
+        }
+    }
+
+
+    /**
+     * 修改类型按钮
+     *
+     * @param commonEntity
+     * @return
+     */
+    public AjaxResult updateBtn(CommonEntity commonEntity, DragTableBtn dragTableBtn) throws JsonProcessingException {
+        //是否开启弹窗
+        if (commonEntity.getBasicMap().get("visible").toString().equals("true")) {
+
+//            if (commonEntity.getBasicMap().containsKey("btnKey")) {  // 按钮提交时会触发别的操作
+//                // 根据流程的key判断当前按钮是否执行触发流程
+//                if (!dragTableBtn.getBtnProcessKey().isEmpty()) {
+//                    // 调用发起流程接口
+//                    //fromUtils.runBpmProductionScheduling(commonEntity);
+//                    ipreExecutionToolClass.ReadyToExecute(commonEntity);
+////                    if (dragTableBtn.getBtnFormKey().isEmpty()) {  // 校验当前按钮是否是直接触发流程 或者脚本 (新增按钮类型)
+////                        fromUtils.runBpmProductionScheduling(commonEntity);
+////                    }
+//                } else if (!dragTableBtn.getBtnScriptKey().isEmpty()) {
+//                    // 调用执行脚本接口
+//                    logger.info("执行脚本接口");
+//                    fromUtils.triggerScript(commonEntity);
+//                    //IScriptEntity iScriptEntity = new IScriptEntity();
+//                    //iScriptEntity.setScriptFlowKey(commonEntity.toString()); // 脚本别名
+//                    //irunImplementationClass.RunScriptImplementationClassLogicCode(iScriptEntity,commonEntity.toString());
+//                }
+//            }
+            if (dragTableBtn.getBtnFormType() != null && dragTableBtn.getBtnFormType().equals("dragFormGroup")) {
+                // 表格组添加逻辑
+                BpmRunNodeFormDateVo bpmRunNodeFormDateVo = JSON.parseObject(JSON.toJSONString(commonEntity.getBasicMap().get("BpmRunNodeFormDateVo")), BpmRunNodeFormDateVo.class);
+                return AjaxResult.btnMessage(echoNodeFormData.handleSubmitForm(bpmRunNodeFormDateVo));
+            } else {
+                commonEntity.getCommMap().putAll(commonEntity.getBtnParametersMap());
+                return toAjax(commonService.edit(commonEntity));
+            }
+        } else if (commonEntity.getBasicMap().get("visible").toString().equals("false")) {
+            if (dragTableBtn.getBtnFormType().equals("dragForm")) {
+                Map<String, Object> map = new HashMap<>();
+                DragForm dragForm = dragFormService.selectDragFormByformKey(dragTableBtn.getBtnFormKey());
+                map.put("template", dragForm);
+                // 单个表单
+                map.put("result", commonService.getInfoById(commonEntity));
+                return success(map);
+            } else if (dragTableBtn.getBtnFormType() != null && dragTableBtn.getBtnFormType().equals("dragFormGroup")) {
+                // 当前按钮绑定的是表单组
+                return success(getFormGroupInfo(commonEntity, dragTableBtn));
+            }
+            return null;
+        } else {
+            return warn("暂不支持该操作!");
+        }
+    }
+
+    // 解析表单组逻辑
+    public Map<String, Object> getFormGroupInfo(CommonEntity commonEntity, DragTableBtn dragTableBtn) {
+        // 得到当前表格组的信息
+        DragFormGroup dragFormGroup = iDragFormGroupService.selectDragFormGroupByKey(dragTableBtn.getBtnFormKey());
+        // 根据表单组中的keys信息 获取对应动态表单的信息
+
+        String[] formKeys = JSON.parseArray(dragFormGroup.getFormKeys()).toArray(String.class);
+        List<CommonEntity> commonEntityList = iBpmExecuteProcessService.getFromInfoByFormKeys(formKeys);
+
+        // 当前表单组关系
+        Map<String, Object> relationJsonMap = (Map<String, Object>) JSON.parse(dragFormGroup.getRelationJson());
+        // 得到当前主表单key
+        ((Map) relationJsonMap.get("mainForm")).get("formKey");
+
+        // 表单组布局样式
+        relationJsonMap.put("layoutJson", dragFormGroup.getLayoutJson());
+
+        // 主表单增加模版信息
+        commonEntityList.forEach(ctem -> {
+            if (ctem.getResultMap().get("formKey").equals(((Map) relationJsonMap.get("mainForm")).get("formKey"))) {
+                ((Map) relationJsonMap.get("mainForm")).put("showTemplate", ctem.getResultMap());
+            }
+        });
+        // 从表单增加模版信息
+        ((ArrayList) relationJsonMap.get("subFormList")).forEach(rtem -> {
+            ((Map) rtem).put("showTemplate", commonEntityList.stream().filter(ctem -> ctem.getResultMap().get("formKey").equals(((Map) rtem).get("formKey"))).findFirst().get().getResultMap());
+        });
+        if (!dragTableBtn.getBtnType().equals("INSERT")) {
+            // 表单组回显数据
+            String zhuTableName = commonEntity.getBasicMap().get("tableName").toString();
+            // 通用查询方法
+            CommonEntity common = new CommonEntity();
+            common.getBasicMap().put("tableName", zhuTableName);
+            commonEntity.getConditionMap().entrySet().forEach(item -> {
+                common.getQueryMap().put(item.getKey(), item.getValue());
+            });
+            //  主
+            List<CommonEntity> retCommonEntityList = commonService.selectList(common);
+            ((Map) relationJsonMap.get("mainForm")).put("showValue", retCommonEntityList);
+
+            // 从
+            ArrayList subFormList = ((ArrayList) relationJsonMap.get("subFormList"));
+
+            subFormList.forEach(item -> {
+                String[] congTableOInfo = ((Map) item).get("formItem").toString().split("\\.");
+                String[] zhuTableOWhere = ((Map) item).get("relateMainItem").toString().split("\\.");
+//                List<Map<String, Object>> updateListMap = (List<Map<String, Object>>) ((Map) item).get("updateMap");
+
+                CommonEntity congCommon = new CommonEntity();
+                congCommon.getBasicMap().put("tableName", congTableOInfo[0]);
+                Object val = retCommonEntityList.get(0).getResultMap().get(StringUtils.toCamelCase(zhuTableOWhere[1]));
+                congCommon.getQueryMap().put(congTableOInfo[1], val);
+
+                List<Map<String, Object>> queryListMap = (List<Map<String, Object>>) ((Map) item).get("queryMap");
+                queryListMap.forEach(qtem -> {
+                    if (qtem.get("type").equals("defaultValue")) {  // 当前查询条件是默认的
+                        congCommon.getQueryMap().put(qtem.get("fieldName").toString(), qtem.get("refValue"));
+                    }
+                    if (qtem.get("type").equals("relateValue")) {
+                        if (qtem.get("tableName").equals(zhuTableName)) {  // 当前关联条件是主表单
+                            Object queryVal = retCommonEntityList.get(0).getResultMap().get(qtem.get("relaField").toString().split("\\.")[1]);
+                            congCommon.getQueryMap().put(qtem.get("fieldName").toString(), queryVal);
+                        } else {  // 关联从表单
+                            String tableWhere[] = qtem.get("relaField").toString().split("\\.");
+                            Map<String, Object> getCurrentMap = (Map<String, Object>) subFormList.stream().filter(stem -> ((Map) stem).get("dfTableName").equals(
+                                    tableWhere[0]
+                            )).findFirst().get();
+//                                ((Map) getCurrentMap.get("showValue")).get(tableWhere[1]);
+                            CommonEntity common1 = (CommonEntity) ((ArrayList) getCurrentMap.get("showValue")).get(0);
+                            Object queryVal = common1.getResultMap().get(tableWhere[1]);
+
+                            congCommon.getQueryMap().put(qtem.get("fieldName").toString(), queryVal);
+                        }
+
+                        // retCommonEntityList.get(0).getResultMap().get(StringUtils.toCamelCase(zhuTableOWhere[1]));
+
+                        // ((Map<?, ?>) item).get("dfTableName").equals(qtem.get("tableName"));
+
+                        // zhuTableName
+
+                        // qtem.get("refValue") 某张表的某个字段值
+
+                    }
+                });
+
+                ((Map) item).put("showValue", commonService.selectList(congCommon));
+            });
+        }
+        //得到【df_form_sql】
+        String dfFormSql = ((Map) ((Map) relationJsonMap.get("mainForm")).get("showTemplate")).get("dfFormSql").toString();
+        ObjectMapper objectMapper = new ObjectMapper();
+        Map<String, Object> sqlMap = null;
+        try {
+            sqlMap = objectMapper.readValue(dfFormSql, Map.class);
+            //循环得到每一个sql语句返回结果
+            for (Map.Entry<String, Object> entry : sqlMap.entrySet()) {
+                List<Map<String, Object>> resultMap = executeNodeFormMapper.executeSql(entry.getValue().toString());
+                sqlMap.put(entry.getKey(), resultMap);
+            }
+            //把原来的sql语句替换成下拉框数据
+            ((Map) ((Map) relationJsonMap.get("mainForm")).get("showTemplate")).put("dfFormSql", JSONObject.toJSONString(sqlMap));
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        ((ArrayList) relationJsonMap.get("subFormList")).forEach(rtem -> {
+            String dfFormSql1 = ((Map) ((Map) rtem).get("showTemplate")).get("dfFormSql").toString();
+            ObjectMapper objectMapper1 = new ObjectMapper();
+            Map<String, Object> sqlMap1 = null;
+            try {
+                sqlMap1 = objectMapper1.readValue(dfFormSql1, Map.class);
+                //循环得到每一个sql语句返回结果
+                for (Map.Entry<String, Object> entry : sqlMap1.entrySet()) {
+                    List<Map<String, Object>> resultMap = executeNodeFormMapper.executeSql(entry.getValue().toString());
+                    sqlMap1.put(entry.getKey(), resultMap);
+                }
+                //把原来的sql语句替换成下拉框数据
+                ((Map) ((Map) rtem).get("showTemplate")).put("dfFormSql", JSONObject.toJSONString(sqlMap1));
+            } catch (JsonProcessingException e) {
+                e.printStackTrace();
+            }
+        });
+//        //处理字段默认值显示
+//        relationJsonMap.forEach((k,v)->{
+//            String jsonString = JSONObject.toJSONString(v);
+//            JSONObject jsonObject = JSONObject.parseObject(jsonString);
+//            jsonObject.get("")
+//        });
+        return relationJsonMap;
+    }
+
+    /**
+     * 删除类型按钮
+     * @param commonEntity
+     * @return
+     */
+    public AjaxResult deleteBtn(CommonEntity commonEntity) {
+        return toAjax(commonService.batchDelete(commonEntity));
+    }
+
+    /**
+     * 按钮执行脚本
+     *
+     * @param commonEntity
+     * @return
+     */
+    public AjaxResult executeBtn(CommonEntity commonEntity, DragTableBtn dragTableBtn) throws JsonProcessingException {
+        if (commonEntity.getBasicMap().get("visible").toString().equals("true")) {
+            if (!dragTableBtn.getBtnScriptKey().isEmpty()) {
+                // 调用执行脚本接口
+                fromUtils.triggerScript(commonEntity);
+            }
+            commonEntity.getCommMap().putAll(commonEntity.getBtnParametersMap());
+            commonService.edit(commonEntity);
+            return AjaxResult.success("执行脚本成功!");
+        } else if (commonEntity.getBasicMap().get("visible").toString().equals("false")) {
+            Map<String, Object> map = new HashMap<>();
+            String sqlKey = commonEntity.getBasicMap().get("sqlKey").toString();
+            DragForm dragForm = dragFormService.selectDragFormBySqlKey(sqlKey);
+            map.put("template", dragForm);
+            map.put("result", commonService.getInfoById(commonEntity));
+            return success(map);
+        } else {
+            return AjaxResult.error("执行脚本失败!");
+        }
+    }
+
+    /**
+     * 发起流程按钮
+     *
+     * @param commonEntity
+     * @return
+     */
+    public AjaxResult initiatedBtn(CommonEntity commonEntity, DragTableBtn dragTableBtn) {
+        //是否开启弹窗
+        if (commonEntity.getBasicMap().get("visible").toString().equals("true")) {
+
+            // 判断当前按钮是否绑定流程
+            if (!dragTableBtn.getBtnProcessKey().equals("unknown")) {
+                commonEntity.getCommMap().put("process_key", dragTableBtn.getBtnProcessKey());
+            }
+            CommonEntity common1 = JSON.parseObject(JSON.toJSONString(commonEntity), CommonEntity.class);
+            // 调用发起流程接口
+            ipreExecutionToolClass.ReadyToExecute(common1);
+
+            // 如果当前发起流程表单使用的是表单组
+            if (dragTableBtn.getBtnFormType() != null && dragTableBtn.getBtnFormType().equals("dragFormGroup")) {
+                BpmRunNodeFormDateVo bpmRunNodeFormDateVo = JSON.parseObject(JSON.toJSONString(commonEntity.getBasicMap().get("BpmRunNodeFormDateVo")), BpmRunNodeFormDateVo.class);
+                //表单组执行流程
+                echoNodeFormData.handleSubmitForm(bpmRunNodeFormDateVo);
+                return AjaxResult.success("启动流程成功!");
+            } else {
+                commonEntity.getCommMap().putAll(commonEntity.getBtnParametersMap());
+                toAjax(commonService.edit(commonEntity));
+                return AjaxResult.success("启动流程成功!");
+            }
+        } else if (commonEntity.getBasicMap().get("visible").toString().equals("false")) {
+            Map<String, Object> map = new HashMap<>();
+            DragForm dragForm;
+            // 如果当前按钮绑定了表单则
+            // 判断当前表单的类型
+            if (dragTableBtn.getBtnFormType().equals("dragForm")) {  // 单个表单
+                // 目前只是单个表单的模版
+                dragForm = dragFormService.selectDragFormByformKey(dragTableBtn.getBtnFormKey());
+                // 查询当前表的条件
+                CommonEntity commonEntity1 = new CommonEntity();
+                commonEntity1.getBasicMap().put("tableName", dragForm.getDfTableName());
+                commonEntity1.getConditionMap().putAll(commonEntity.getConditionMap());
+                // 返回结果
+                map.put("result", commonService.getInfoById(commonEntity1));
+                map.put("template", dragForm);
+                // 展示当前按钮绑定的表单
+                return success(map);
+            } else if (dragTableBtn.getBtnFormType() != null && dragTableBtn.getBtnFormType().equals("dragFormGroup")) {  // 多个表单
+                return success(getFormGroupInfo(commonEntity, dragTableBtn));
+            } else if (dragTableBtn.getBtnFormType().equals("other")) {// 其他表单
+
+            } else {
+                // 单纯是表格还是弹窗里有表格
+                String sqlKey = commonEntity.getBasicMap().get("sqlKey").toString();
+                dragForm = dragFormService.selectDragFormBySqlKey(sqlKey);
+                map.put("template", dragForm);
+                // 返回结果
+                map.put("result", commonService.getInfoById(commonEntity));
+                return success(map);
+            }
+        } else {
+            return AjaxResult.error("发起流程失败!");
+        }
+        return AjaxResult.error("发起流程失败!");
+    }
+
+
+    /**
+     * 动态表格绑定的弹窗表格结构信息
+     */
+    @GetMapping(value = "/getProcessPopupTableInfo")
+    public AjaxResult getProcessPopupTableInfo(CommonEntity commonEntity) {
+        return AjaxResult.success(dragTableGroupService.getProcessPopupTableInfo(commonEntity));
+    }
+
+    /**
+     * 动态表格弹窗表格信息
+     */
+    @GetMapping(value = "/getProcessPopupTableList")
+    public AjaxResult getProcessPopupTableList(CommonEntity commonEntity) {
+        return AjaxResult.success(dragTableGroupService.getProcessPopupTableList(commonEntity));
+    }
+
+
+}

+ 220 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/CommonController.java

@@ -0,0 +1,220 @@
+package com.zkqy.business.controller;
+
+import com.zkqy.business.entity.DragForm;
+import com.zkqy.business.service.*;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.constant.ButtonTypeConstants;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.exception.tenantdatassource.TenantDataSource;
+import com.zkqy.execution.produce.dispersed.entity.CommonEntity;
+import com.zkqy.execution.produce.dispersed.entity.TableSql;
+import com.zkqy.execution.produce.dispersed.service.ICommonService;
+import com.zkqy.execution.produce.dispersed.service.ITableSqlService;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.zkqy.business.domain.SaleProducts;
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/dragform/common")
+public class CommonController extends BaseController {
+
+    @Resource
+    private ICommonService commonService;
+
+    @Resource  // 动态sql
+    private ITableSqlService iTableSqlService;
+
+    @Resource // 动态表格
+    private IDragTableService dragTableService;
+
+    @Resource
+    private IDragTableGroupService dragTableGroupService;
+
+    @Resource
+    private IDragFormService dragFormService;
+
+    @Autowired
+    private ISaleProductsService saleProductsService;
+
+    /**
+     * 共通查询
+     */
+    @GetMapping("/selectList")
+    public TableDataInfo selectList(CommonEntity commonEntity) {
+        startPage();
+        return getDataTable(commonService.selectList(commonEntity));
+    }
+
+    /**
+     * 共通批量新增
+     */
+    @Log(title = "动态表单", businessType = BusinessType.INSERT)
+    @PostMapping("/batchInsert")
+    public AjaxResult batchInsert(@RequestBody CommonEntity commonEntity) {
+        return toAjax(commonService.batchInsert(commonEntity));
+    }
+
+    /**
+     * 共通修改sql
+     */
+    @PutMapping("/batchEdit")
+    @Log(title = "动态表单", businessType = BusinessType.UPDATE)
+    public AjaxResult edit(@RequestBody CommonEntity commonEntity) {
+        return toAjax(commonService.edit(commonEntity));
+    }
+
+    /**
+     * 修改销售产品
+     */
+//    @PreAuthorize("@ss.hasPermi('system:products:edit')")
+    @Log(title = "销售产品", businessType = BusinessType.UPDATE)
+    @PutMapping("/saleProductsBatchEdit")
+    @ApiOperation(value = "修改销售产品")
+    public AjaxResult edit(@RequestBody SaleProducts saleProducts) {
+        return toAjax(saleProductsService.updateSaleProducts(saleProducts));
+    }
+
+
+    /**
+     * 批量删除
+     */
+    @DeleteMapping("/batchDelete")
+    @Log(title = "动态表单", businessType = BusinessType.DELETE)
+    public AjaxResult batchDelete(@RequestBody CommonEntity commonEntity) {
+        return toAjax(commonService.batchDelete(commonEntity));
+    }
+
+    /**
+     * 共通获取详情
+     */
+    @GetMapping("/getInfo")
+    public AjaxResult getInfo(CommonEntity commonEntity) {
+        return success(commonService.getInfoById(commonEntity));
+    }
+
+
+    /**
+     * 联合查询通用sql
+     *
+     * @param commonEntity
+     * @return
+     */
+    @GetMapping("/getTableList")
+//    @ProcessCommonEntity
+    public TableDataInfo queryTableList(CommonEntity commonEntity) throws TenantDataSource {
+//        if (true) {
+//            System.err.println(commonEntity.getQueryMap());
+//            System.err.println(commonEntity.getQueryMap().get("timehorizon") instanceof  String);
+//            return null;
+//        }
+        TableSql tableSql = iTableSqlService.selectTableSqlByTSqlKey(commonEntity.getQueryMap().get("sqlkey").toString());
+        String tableFormat = dragTableService.getTableFormatBySqlKey(tableSql.getSqlKey());
+        startPage();  // 校验是否sqlserver 否执行 是执行另一种方式的分页
+        return getDataTable(commonService.queryGroupTableList(commonEntity, tableSql, tableFormat));
+    }
+
+    /**
+     * 化纤厂联合查询销售单订单类型sql
+     *
+     * @param commonEntity
+     * @return
+     */
+    @GetMapping("/getTableList1")
+    public TableDataInfo queryTableList1(CommonEntity commonEntity) throws TenantDataSource {
+        TableSql tableSql = iTableSqlService.selectTableSqlByTSqlKey(commonEntity.getQueryMap().get("sqlkey").toString());
+        String tableFormat = dragTableService.getTableFormatBySqlKey(tableSql.getSqlKey());
+        startPage();  // 校验是否sqlserver 否执行 是执行另一种方式的分页
+        return getDataTable(commonService.queryGroupTableList1(commonEntity, tableSql, tableFormat));
+    }
+
+    /**
+     * 通用动态表单详情
+     */
+    @GetMapping("/dragTableInfo")
+    public AjaxResult dragTableInfo(CommonEntity commonEntity) {
+        return AjaxResult.success(dragTableService.dragTableInfo(commonEntity.getQueryMap().get("tableKey").toString()));
+    }
+
+    /**
+     * 动态表单预览接口
+     */
+    @GetMapping("/dragTablePreview")
+    public TableDataInfo DragTablePreview(CommonEntity commonEntity) {
+        startPage();
+        return getDataTable(commonService.dragTablePreview(commonEntity));
+    }
+
+    /**
+     * 通用批量查询下拉框数据接口
+     */
+    @PostMapping("/queryDropDownBoxData")
+    public AjaxResult queryDropDownBoxData(@RequestBody List<CommonEntity> commonEntityList) {
+        return AjaxResult.success(commonService.queryDropDownBoxData(commonEntityList));
+    }
+
+    /**
+     * 处理按钮通用接口(新增、修改、删除)
+     */
+    @PostMapping("/commonBtnHandle")
+    public AjaxResult commonBtnHandle(@RequestBody CommonEntity commonEntity) {
+        //按钮类型
+        Long btnType = Long.valueOf(commonEntity.getBasicMap().get("btnType").toString());
+        //是否开启弹窗
+        String visible = commonEntity.getBasicMap().get("visible").toString();
+        /*
+         * 判断什么类型走什么接口:
+         * btnType  10:新增、8:修改、9:删除、5:脚本
+         * visible  false代表弹窗未开启时走回显表单模板及数据信息接口;true代表弹窗开启时走保存数据接口
+         * */
+        if (btnType == ButtonTypeConstants.INSERT && visible.equals("true")) {
+            return toAjax(commonService.batchInsert(commonEntity));
+        } else if (btnType == ButtonTypeConstants.INSERT && visible.equals("false")) {
+            String sqlKey = commonEntity.getBasicMap().get("sqlKey").toString();
+            return success(dragFormService.selectDragFormBySqlKey(sqlKey));
+        } else if (btnType == ButtonTypeConstants.UPDATE && visible.equals("true")) {
+            return toAjax(commonService.edit(commonEntity));
+        } else if (btnType == ButtonTypeConstants.UPDATE && visible.equals("false")) {
+            Map<String, Object> map = new HashMap<>();
+            //获取模板信息
+            String sqlKey = commonEntity.getBasicMap().get("sqlKey").toString();
+            DragForm dragForm = dragFormService.selectDragFormBySqlKey(sqlKey);
+            map.put("template", dragForm);
+            //返回结果
+            map.put("result", commonService.getInfoById(commonEntity));
+            return success(map);
+        } else if (btnType == ButtonTypeConstants.DELETE) {
+            return toAjax(commonService.batchDelete(commonEntity));
+        } else if (btnType == ButtonTypeConstants.SCRIPT) {
+        }
+        return warn("暂不支持该操作!");
+    }
+
+
+    /**
+     * 查询表格组信息
+     *
+     * @param commonEntity
+     * @return
+     */
+    @GetMapping("/dragGroupTableInfo")
+    public AjaxResult dragGroupTableInfo(CommonEntity commonEntity) {
+        return AjaxResult.success(dragTableGroupService.selectDragTableGroup(commonEntity.getQueryMap().get("groupKey").toString()));
+    }
+
+    /**
+     * 刷新token
+     */
+    @GetMapping("/refreshToken")
+    public AjaxResult refreshToken() {
+        return success();
+    }
+
+}

+ 55 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/DragFormController.java

@@ -0,0 +1,55 @@
+package com.zkqy.business.controller;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.zkqy.business.entity.DragForm;
+import com.zkqy.business.service.IDragFormService;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import java.util.List;
+
+
+/**
+ * 动态表单
+ * Controller
+ */
+@RestController
+@RequestMapping("/dragform/form")
+public class DragFormController extends BaseController {
+
+    @Resource
+    private IDragFormService dragFormService;
+
+    /**
+     * 查询动态表单列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:form:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(DragForm dragForm) {
+        startPage();
+        List<DragForm> list = dragFormService.selectDragFormList(dragForm);
+        return getDataTable(list);
+    }
+
+    /**
+     * 获取动态表单
+     * 详细信息
+     */
+    //@PreAuthorize("@ss.hasPermi('system:form:query')")
+    @GetMapping(value = "/{fId}")
+    public AjaxResult getInfo(@PathVariable("fId") Long fId) {
+        return success(dragFormService.selectDragFormByFId(fId));
+    }
+
+    /**
+     * 获取动态表单
+     * 详细信息
+     */
+    @GetMapping("/getInfoBySqlKey/{sqlKey}")
+    public AjaxResult getInfoBySqlKey(@PathVariable("sqlKey") String sqlKey) throws JsonProcessingException {
+        return success(dragFormService.selectDragFormBySqlKey(sqlKey));
+    }
+
+}

+ 49 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/DragTableBtnController.java

@@ -0,0 +1,49 @@
+package com.zkqy.business.controller;
+
+import com.zkqy.business.entity.DragTableBtn;
+import com.zkqy.business.service.IDragTableBtnService;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+
+/**
+ * 格绑定的自定义按钮Controller
+ * @author ruoyi
+ * @date 2023-11-07
+ */
+@RestController
+@RequestMapping("/system/btn")
+public class DragTableBtnController extends BaseController
+{
+    @Autowired
+    private IDragTableBtnService dragTableBtnService;
+
+    /**
+     * 查询格绑定的自定义按钮列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:btn:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(DragTableBtn dragTableBtn)
+    {
+        startPage();
+        List<DragTableBtn> list = dragTableBtnService.selectDragTableBtnList(dragTableBtn);
+        return getDataTable(list);
+    }
+
+    /**
+     * 获取格绑定的自定义按钮详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:btn:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(dragTableBtnService.selectDragTableBtnById(id));
+    }
+
+}

+ 71 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/DragTableConditionController.java

@@ -0,0 +1,71 @@
+package com.zkqy.business.controller;
+
+import com.zkqy.business.service.IDragTableConditionService;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.execution.produce.dispersed.entity.CommonEntity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 动态表格条件Controller
+ * 
+ * @author ruoyi
+ * @date 2023-07-31
+ */
+@RestController
+@RequestMapping("/system/condition")
+public class DragTableConditionController extends BaseController
+{
+    @Autowired
+    private IDragTableConditionService dragTableConditionService;
+
+    /**
+     * 查询动态表格条件列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:condition:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(CommonEntity commonEntity)
+    {
+        startPage();
+        return getDataTable(dragTableConditionService.selectDragTableConditionList(commonEntity));
+    }
+
+    /**
+     * 新增动态表格条件
+     */
+    @PreAuthorize("@ss.hasPermi('system:condition:add')")
+    @Log(title = "动态表格条件", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody CommonEntity commonEntity)
+    {
+        return toAjax(dragTableConditionService.insertDragTableCondition(commonEntity));
+    }
+
+    /**
+     * 修改动态表格条件
+     */
+    @PreAuthorize("@ss.hasPermi('system:condition:edit')")
+    @Log(title = "动态表格条件", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody CommonEntity commonEntity)
+    {
+        return toAjax(dragTableConditionService.updateDragTableCondition(commonEntity));
+    }
+
+    /**
+     * 删除动态表格条件
+     */
+    @PreAuthorize("@ss.hasPermi('system:condition:remove')")
+    @Log(title = "动态表格条件", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{tcIds}")
+    public AjaxResult remove(@RequestBody CommonEntity commonEntity)
+    {
+        return toAjax(dragTableConditionService.deleteDragTableConditionByTcIds(commonEntity));
+    }
+
+}

+ 64 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/DragTableController.java

@@ -0,0 +1,64 @@
+package com.zkqy.business.controller;
+
+import com.zkqy.business.entity.DragTable;
+import com.zkqy.business.service.IDragTableBtnRelevanceService;
+import com.zkqy.business.service.IDragTableService;
+import com.zkqy.business.service.IDragTableStatisticService;
+import com.zkqy.business.service.IDragTableStyleService;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 动态表格Controller
+ *
+ * @author xzz
+ * @date 2023-07-31
+ */
+@RestController
+@RequestMapping("/system/table")
+public class DragTableController extends BaseController {
+
+    @Autowired
+    private IDragTableService dragTableService;
+
+    @Autowired
+    private IDragTableStatisticService dragTableStatisticService;
+
+    @Autowired
+    private IDragTableStyleService dragTableStyleService;
+
+    @Autowired
+    private IDragTableBtnRelevanceService dragTableBtnRelevanceService;
+    
+    /**
+     * 查询动态表格列表
+     */
+    @GetMapping("/list")
+    public TableDataInfo list(DragTable dragTable) {
+        startPage();
+        List<DragTable> list = dragTableService.selectDragTableList(dragTable);
+        return getDataTable(list);
+    }
+
+    /**
+     * 获取动态表格详细信息
+     */
+    @GetMapping("/getInfo/{tId}")
+    public AjaxResult getInfo(@PathVariable("tId") Long tId) {
+        return success(dragTableService.selectDragTableVoByTId(tId));
+    }
+
+    /**
+     * 查询动态表格列表
+     */
+    @GetMapping("/dragTableList")
+    public AjaxResult dragTableList() {
+        return AjaxResult.success(dragTableService.selectDragTableList(new DragTable()));
+    }
+
+}

+ 72 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/DragTableGroupController.java

@@ -0,0 +1,72 @@
+package com.zkqy.business.controller;
+
+import com.zkqy.business.entity.DragTableGroup;
+import com.zkqy.business.entity.vo.DragTableGroupVo;
+import com.zkqy.business.service.IDragTableGroupService;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.execution.produce.dispersed.entity.CommonEntity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author hmc
+ * @date 2023-11-01 14:29
+ * @Description:
+ */
+@RestController
+@RequestMapping("/system/group")
+public class DragTableGroupController extends BaseController {
+
+    @Autowired
+    private IDragTableGroupService dragTableGroupService;
+
+    /**
+     * 传groupKey获取当前组下的所有动态表格
+     * @param commonEntity
+     * @return
+     */
+    @GetMapping("/dragGroupTableInfo")
+    public AjaxResult dragGroupTableInfo(CommonEntity commonEntity) {
+        return   AjaxResult.success(dragTableGroupService.selectDragTableGroup(commonEntity.getQueryMap().get("groupKey").toString()));
+    }
+
+    /**
+     * 查询拖拽格组列表
+     * @PreAuthorize("@ss.hasPermi('system:group:list')")
+     */
+    @GetMapping("/list")
+    public TableDataInfo list(DragTableGroup dragTableGroup)
+    {
+        startPage();
+        List<DragTableGroup> list = dragTableGroupService.selectDragTableGroupList(dragTableGroup);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询拖拽表格组详细信息
+     * @param dragTableGroup
+     * @return
+     */
+    @GetMapping("/listDetail")
+    public AjaxResult listDetail(DragTableGroup dragTableGroup)
+    {
+        DragTableGroupVo list = dragTableGroupService.selectDragTableGroupListDetail(dragTableGroup);
+        return AjaxResult.success(list);
+    }
+
+    /**
+     * 获取拖拽格组详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:group:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(dragTableGroupService.selectDragTableGroupById(id));
+    }
+
+}

+ 87 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/DragTableStatisticController.java

@@ -0,0 +1,87 @@
+package com.zkqy.business.controller;
+
+import com.zkqy.business.entity.DragTableStatistic;
+import com.zkqy.business.service.IDragTableStatisticService;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.execution.produce.dispersed.entity.CommonEntity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+
+/**
+ * 动态表格统计Controller
+ * @author ruoyi
+ * @date 2023-10-27
+ */
+@RestController
+@RequestMapping("/system/statistic")
+public class DragTableStatisticController extends BaseController
+{
+    @Autowired
+    private IDragTableStatisticService dragTableStatisticService;
+
+    /**
+     * 查询动态表格统计列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:statistic:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(DragTableStatistic dragTableStatistic)
+    {
+        startPage();
+        List<DragTableStatistic> list = dragTableStatisticService.selectDragTableStatisticList(dragTableStatistic);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出动态表格统计列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:statistic:export')")
+    @Log(title = "动态表格统计", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, DragTableStatistic dragTableStatistic)
+    {
+        List<DragTableStatistic> list = dragTableStatisticService.selectDragTableStatisticList(dragTableStatistic);
+        ExcelUtil<DragTableStatistic> util = new ExcelUtil<DragTableStatistic>(DragTableStatistic.class);
+        util.exportExcel(response, list, "动态表格统计数据");
+    }
+
+    /**
+     * 获取动态表格统计详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:statistic:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(dragTableStatisticService.selectDragTableStatisticById(id));
+    }
+
+
+
+    /**
+     * 获取动态表格统计详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:statistic:query')")
+    @GetMapping("/getInfoBySqlKey")
+    public AjaxResult getInfoBySqlKey(@RequestParam("sqlKey") String sqlKey)
+    {
+        return success(dragTableStatisticService.getInfoBySqlKey(sqlKey));
+    }
+
+    /**
+     * 获取列表统计信息
+     */
+    @GetMapping("/getStatisticList")
+    public AjaxResult getStatisticList(CommonEntity commonEntity){
+        return AjaxResult.success(dragTableStatisticService.getStatisticList(commonEntity));
+    }
+
+
+}

+ 100 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/DragTableStyleController.java

@@ -0,0 +1,100 @@
+package com.zkqy.business.controller;
+
+import com.zkqy.business.entity.DragTableStyle;
+import com.zkqy.business.entity.vo.DragTableVo;
+import com.zkqy.business.service.IDragTableStyleService;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 动态格样式Controller
+ * 
+ * @author ruoyi
+ * @date 2023-11-03
+ */
+@RestController
+@RequestMapping("/system/style")
+public class DragTableStyleController extends BaseController
+{
+
+    @Autowired
+    private IDragTableStyleService dragTableStyleService;
+
+    /**
+     * 查询动态格样式列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:style:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(DragTableStyle dragTableStyle)
+    {
+        startPage();
+        List<DragTableStyle> list = dragTableStyleService.selectDragTableStyleList(dragTableStyle);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出动态格样式列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:style:export')")
+    @Log(title = "动态格样式", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, DragTableStyle dragTableStyle)
+    {
+        List<DragTableStyle> list = dragTableStyleService.selectDragTableStyleList(dragTableStyle);
+        ExcelUtil<DragTableStyle> util = new ExcelUtil<DragTableStyle>(DragTableStyle.class);
+        util.exportExcel(response, list, "动态格样式数据");
+    }
+
+    /**
+     * 获取动态格样式详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:style:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(dragTableStyleService.selectDragTableStyleById(id));
+    }
+
+    /**
+     * 新增动态格样式
+     */
+    @PreAuthorize("@ss.hasPermi('system:style:add')")
+    @Log(title = "动态格样式", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody DragTableVo vo)
+    {
+        return toAjax(dragTableStyleService.batchInsertDragTableStyle(vo));
+    }
+
+    /**
+     * 修改动态格样式
+     */
+    @PreAuthorize("@ss.hasPermi('system:style:edit')")
+    @Log(title = "动态格样式", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody DragTableVo vo)
+    {
+        dragTableStyleService.updateDragTableStyle(vo);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 删除动态格样式
+     */
+    @PreAuthorize("@ss.hasPermi('system:style:remove')")
+    @Log(title = "动态格样式", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable List<Long> ids)
+    {
+        return toAjax(dragTableStyleService.deleteDragTableStyleByIds(ids));
+    }
+}

+ 219 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/FileManagementController.java

@@ -0,0 +1,219 @@
+package com.zkqy.business.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.zkqy.business.entity.FileManagement;
+import com.zkqy.business.service.IFileManagementService;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.config.ZkqyConfig;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.core.redis.RedisCache;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.common.utils.SecurityUtils;
+import com.zkqy.common.utils.file.FileUploadUtils;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.framework.config.ServerConfig;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Base64;
+import java.util.List;
+import java.util.UUID;
+
+
+/**
+ * 文件管理(业务数据关联)Controller
+ *
+ * @author hzh
+ * @date 2024-07-04
+ */
+@RestController
+@RequestMapping("/system/fileManagement")
+@Api(value = "/system/fileManagement", description = "文件管理(业务数据关联)-接口")
+public class FileManagementController extends BaseController {
+    @Autowired
+    private IFileManagementService fileManagementService;
+
+    @Resource
+    private RedisCache redisCache;
+
+    @Autowired
+    private ServerConfig serverConfig;
+
+
+    @Autowired
+    private ObjectMapper objectMapper;  // 用于JSON转换
+
+    private static final String FILE_DELIMETER = ",";
+
+
+    /**
+     * 租户通用上传文件接口(需携带租户标识)
+     *
+     * @param file
+     * @param fileManagementJson
+     * @return
+     */
+    @Transactional
+    @PostMapping("/tenantUploadFile")
+    public AjaxResult tenantUploadFile(@RequestParam("file") MultipartFile file,
+                                       @RequestParam("fileManagement") String fileManagementJson) {
+        try {
+            FileManagement fileManagement = objectMapper.readValue(fileManagementJson, FileManagement.class);
+            // 每个租户都有属于自己的文件夹
+            String tenantCode = SecurityUtils.getLoginUser().getUser().getTenant().getTenantCode();
+            // 上传文件路径
+            String filePath = ZkqyConfig.getUploadPath() + "/" + tenantCode;
+            AjaxResult ajax = success();
+            String fileGroupKey = UUID.randomUUID().toString();
+            // 处理文件、封装数据
+            switch (fileManagement.getFileType()) {
+                case "filePattern":
+                    String fileName = FileUploadUtils.upload(filePath, file);
+                    String url = serverConfig.getUrl() + fileName;
+                    fileManagement.setFileDownloadUrl(url);
+                    fileManagement.setFilePath(fileName);
+                    break;
+                case "base64":
+                    byte[] bytes = file.getBytes();
+                    String base64Encoded = Base64.getEncoder().encodeToString(bytes);
+                    fileManagement.setFileContent(base64Encoded);
+                    break;
+                case "bytes":
+                    fileManagement.setFileData(file.getBytes());
+                    break;
+            }
+            fileManagement.setOriginalFileName(file.getOriginalFilename());
+            fileManagement.setFileGroupKey(fileGroupKey);
+            fileManagement.setFileSize(fileManagement.getFileSize());
+            // 插入文件信息
+            fileManagementService.insertFileManagement(fileManagement);
+            ajax.put("fileGroupKey", fileGroupKey);
+            return ajax;
+        } catch (Exception e) {
+            return AjaxResult.error(e.getMessage());
+        }
+    }
+
+    /**
+     * * 租户通用批量上传文件接口(需携带租户标识)
+     * * * 批量上传无法使用流文件逻辑
+     *
+     * @param files
+     * @param fileManagementJson
+     * @return
+     */
+    @PostMapping("/tenantUploadFiles")
+    public AjaxResult tenantUploadFiles(@RequestParam("files") MultipartFile[] files, @RequestParam("fileManagement") String fileManagementJson) {
+        try {
+            FileManagement fileManagement = objectMapper.readValue(fileManagementJson, FileManagement.class);
+            // 每个租户都有属于自己的文件夹
+            String tenantCode = SecurityUtils.getLoginUser().getUser().getTenant().getTenantCode();
+            // 上传文件路径
+            String filePath = ZkqyConfig.getUploadPath() + "/" + tenantCode;
+            AjaxResult ajax = success();
+            String fileGroupKey = UUID.randomUUID().toString();
+            for (MultipartFile file : files) {
+                if (file.isEmpty()) {
+                    continue;
+                }
+                // 处理文件、封装数据
+                switch (fileManagement.getFileType()) {
+                    case "filePattern":
+                        String fileName = FileUploadUtils.upload(filePath, file);
+                        String url = serverConfig.getUrl() + fileName;
+                        fileManagement.setFileDownloadUrl(url);
+                        fileManagement.setFilePath(fileName);
+                        break;
+                    case "base64":
+                        byte[] bytes = file.getBytes();
+                        String base64Encoded = Base64.getEncoder().encodeToString(bytes);
+                        fileManagement.setFileContent(base64Encoded);
+                        break;
+                    case "bytes":
+                        fileManagement.setFileData(file.getBytes());
+                        break;
+                }
+                fileManagement.setOriginalFileName(file.getOriginalFilename());
+                fileManagement.setFileGroupKey(fileGroupKey);
+                fileManagement.setFileSize(fileManagement.getFileSize());
+                // 插入文件信息
+                fileManagementService.insertFileManagement(fileManagement);
+            }
+            ajax.put("fileGroupKey", fileGroupKey);
+            return ajax;
+        } catch (Exception e) {
+            return AjaxResult.error(e.getMessage());
+        }
+    }
+
+
+    /**
+     * 查询文件管理(业务数据关联)列表
+     */
+    @GetMapping("/list")
+    @ApiOperation(value = "查询文件管理(业务数据关联)列表")
+    public TableDataInfo list(FileManagement fileManagement) {
+        startPage();
+        List<FileManagement> list = fileManagementService.selectFileManagementList(fileManagement);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出文件管理(业务数据关联)列表
+     */
+    @Log(title = "文件管理(业务数据关联)", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    @ApiOperation(value = "导出文件管理(业务数据关联)列表")
+    public void export(HttpServletResponse response, FileManagement fileManagement) {
+        List<FileManagement> list = fileManagementService.selectFileManagementList(fileManagement);
+        ExcelUtil<FileManagement> util = new ExcelUtil<FileManagement>(FileManagement.class);
+        util.exportExcel(response, list, "文件管理(业务数据关联)数据");
+    }
+
+    /**
+     * 获取文件管理(业务数据关联)详细信息
+     */
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "获取文件管理(业务数据关联)详细信息")
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
+        return success(fileManagementService.selectFileManagementById(id));
+    }
+
+    /**
+     * 新增文件管理(业务数据关联)
+     */
+    @Log(title = "文件管理(业务数据关联)", businessType = BusinessType.INSERT)
+    @PostMapping
+    @ApiOperation(value = "新增文件管理(业务数据关联)")
+    public AjaxResult add(@RequestBody FileManagement fileManagement) {
+        return toAjax(fileManagementService.insertFileManagement(fileManagement));
+    }
+
+    /**
+     * 修改文件管理(业务数据关联)
+     */
+    @Log(title = "文件管理(业务数据关联)", businessType = BusinessType.UPDATE)
+    @PutMapping
+    @ApiOperation(value = "修改文件管理(业务数据关联)")
+    public AjaxResult edit(@RequestBody FileManagement fileManagement) {
+        return toAjax(fileManagementService.updateFileManagement(fileManagement));
+    }
+
+    /**
+     * 删除文件管理(业务数据关联)
+     */
+    @Log(title = "文件管理(业务数据关联)", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    @ApiOperation(value = "删除文件管理(业务数据关联)")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(fileManagementService.deleteFileManagementByIds(ids));
+    }
+}

+ 136 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/MobilePageDataController.java

@@ -0,0 +1,136 @@
+package com.zkqy.business.controller;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.zkqy.business.entity.MobilePageData;
+import com.zkqy.business.service.IMobilePageDataService;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.common.enums.BusinessType;
+
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.execution.produce.dispersed.entity.CommonEntity;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 移动端数据Controller
+ *
+ * @author zkqy
+ * @date 2024-04-18
+ */
+@RestController
+@RequestMapping("/system/mobilePageData")
+@Api(value = "/system/data", description = "移动端数据-接口")
+public class MobilePageDataController extends BaseController {
+
+    @Autowired
+    private IMobilePageDataService mobilePageDataService;
+
+    /**
+     * 查询移动端数据列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:data:list')")
+    @GetMapping("/list")
+    @ApiOperation(value = "查询移动端数据列表")
+    public TableDataInfo list(MobilePageData mobilePageData) {
+        startPage();
+        List<MobilePageData> list = mobilePageDataService.selectMobilePageDataList(mobilePageData);
+        return getDataTable(list);
+    }
+
+
+
+
+    /**
+     * 查询移动端数据列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:data:list')")
+    @GetMapping("/getIndexTrue")
+    @ApiOperation(value = "查询当前租户的首页信息")
+    public AjaxResult IndexTrue() throws JsonProcessingException {
+//        return success(mobilePageDataService.selectMobilePageDataById(id));
+        CommonEntity commonEntity=new CommonEntity();
+        MobilePageData mobilePageData = mobilePageDataService.selectMobilePageDataIndexTrue(commonEntity);
+        return AjaxResult.success(mobilePageData);
+    }
+
+    /**
+     * 查询移动端数据列表
+     * 带条件的查询列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:data:list')")
+    @PostMapping("/getConditionsIndexTrue")
+    @ApiOperation(value = "查询当前租户的首页信息")
+    public AjaxResult IndexTrue(@RequestBody CommonEntity commonEntity) throws JsonProcessingException {
+//        return success(mobilePageDataService.selectMobilePageDataById(id));
+        MobilePageData mobilePageData = mobilePageDataService.selectMobilePageDataIndexTrue(commonEntity);
+        return AjaxResult.success(mobilePageData);
+    }
+
+    
+    /**
+     * 导出移动端数据列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:data:export')")
+    @Log(title = "移动端数据", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    @ApiOperation(value = "导出移动端数据列表")
+    public void export(HttpServletResponse response, MobilePageData mobilePageData) {
+        List<MobilePageData> list = mobilePageDataService.selectMobilePageDataList(mobilePageData);
+        ExcelUtil<MobilePageData> util = new ExcelUtil<MobilePageData>(MobilePageData.class);
+        util.exportExcel(response, list, "移动端数据数据");
+    }
+
+
+
+    /**
+     * 获取移动端数据详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:data:query')")
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "获取移动端数据详细信息")
+    public AjaxResult getInfo(@PathVariable("id") Long id) throws JsonProcessingException {
+        return success(mobilePageDataService.selectMobilePageDataById(id));
+    }
+
+    /**
+     * 新增移动端数据
+     */
+    @PreAuthorize("@ss.hasPermi('system:data:add')")
+    @Log(title = "移动端数据", businessType = BusinessType.INSERT)
+    @PostMapping
+    @ApiOperation(value = "新增移动端数据")
+    public AjaxResult add(@RequestBody MobilePageData mobilePageData) {
+        return toAjax(mobilePageDataService.insertMobilePageData(mobilePageData));
+    }
+
+    /**
+     * 修改移动端数据
+     */
+    @PreAuthorize("@ss.hasPermi('system:data:edit')")
+    @Log(title = "移动端数据", businessType = BusinessType.UPDATE)
+    @PutMapping
+    @ApiOperation(value = "修改移动端数据")
+    public AjaxResult edit(@RequestBody MobilePageData mobilePageData) {
+        return toAjax(mobilePageDataService.updateMobilePageData(mobilePageData));
+    }
+
+    /**
+     * 删除移动端数据
+     */
+    @PreAuthorize("@ss.hasPermi('system:data:remove')")
+    @Log(title = "移动端数据", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    @ApiOperation(value = "删除移动端数据")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(mobilePageDataService.deleteMobilePageDataByIds(ids));
+    }
+}

+ 118 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/MobilePageTableListController.java

@@ -0,0 +1,118 @@
+package com.zkqy.business.controller;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.zkqy.common.annotation.Log;
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.enums.BusinessType;
+import com.zkqy.business.entity.MobilePageTableList;
+import com.zkqy.business.service.IMobilePageTableListService;
+import com.zkqy.common.utils.poi.ExcelUtil;
+import com.zkqy.common.core.page.TableDataInfo;
+
+/**
+ * 页面列表Controller
+ *
+ * @author zkqy
+ * @date 2024-05-21
+ */
+@RestController
+@RequestMapping("/system/页面列表")
+@Api(value = "/system/页面列表", description = "页面列表-接口")
+public class MobilePageTableListController extends BaseController
+{
+
+    @Autowired
+    private IMobilePageTableListService mobilePageTableListService;
+
+    /**
+     * 查询页面列表列表
+     */
+    //@PreAuthorize("@ss.hasPermi('system:页面列表:list')")
+    @GetMapping("/list")
+    @ApiOperation(value = "查询页面列表列表")
+    public TableDataInfo list(MobilePageTableList mobilePageTableList)
+    {
+        startPage();
+        List<MobilePageTableList> list = mobilePageTableListService.selectMobilePageTableListList(mobilePageTableList);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出页面列表列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:页面列表:export')")
+    @Log(title = "页面列表", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    @ApiOperation(value = "导出页面列表列表")
+    public void export(HttpServletResponse response, MobilePageTableList mobilePageTableList)
+    {
+        ObjectMapper objectMapper=new ObjectMapper();
+
+        List<MobilePageTableList> list = mobilePageTableListService.selectMobilePageTableListList(mobilePageTableList);
+        ExcelUtil<MobilePageTableList> util = new ExcelUtil<MobilePageTableList>(MobilePageTableList.class);
+        util.exportExcel(response, list, "页面列表数据");
+    }
+
+    /**
+     * 获取页面列表详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:页面列表:query')")
+    @GetMapping(value = "/{id}")
+    @ApiOperation(value = "获取页面列表详细信息")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(mobilePageTableListService.selectMobilePageTableListById(id));
+    }
+
+    /**
+     * 新增页面列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:页面列表:add')")
+    @Log(title = "页面列表", businessType = BusinessType.INSERT)
+    @PostMapping
+    @ApiOperation(value = "新增页面列表")
+    public AjaxResult add(@RequestBody MobilePageTableList mobilePageTableList)
+    {
+        return toAjax(mobilePageTableListService.insertMobilePageTableList(mobilePageTableList));
+    }
+
+    /**
+     * 修改页面列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:页面列表:edit')")
+    @Log(title = "页面列表", businessType = BusinessType.UPDATE)
+    @PutMapping
+    @ApiOperation(value = "修改页面列表")
+    public AjaxResult edit(@RequestBody MobilePageTableList mobilePageTableList)
+    {
+        return toAjax(mobilePageTableListService.updateMobilePageTableList(mobilePageTableList));
+    }
+
+    /**
+     * 删除页面列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:页面列表:remove')")
+    @Log(title = "页面列表", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    @ApiOperation(value = "删除页面列表")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(mobilePageTableListService.deleteMobilePageTableListByIds(ids));
+    }
+}

+ 50 - 0
zkqy-business/src/main/java/com/zkqy/business/controller/TableSqlController.java

@@ -0,0 +1,50 @@
+package com.zkqy.business.controller;
+
+import com.zkqy.common.core.controller.BaseController;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.page.TableDataInfo;
+import com.zkqy.execution.produce.dispersed.entity.TableSql;
+import com.zkqy.execution.produce.dispersed.service.ITableSqlService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+
+/**
+ * table 联合查询sql存储Controller
+ * 
+ * @author ruoyi
+ * @date 2023-07-19
+ */
+@RestController
+@RequestMapping("/system/sql")
+public class TableSqlController extends BaseController
+{
+
+    @Autowired
+    private ITableSqlService tableSqlService;
+
+    /**
+     * 查询table 联合查询sql存储列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:sql:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(TableSql tableSql)
+    {
+        startPage();
+        List<TableSql> list = tableSqlService.selectTableSqlList(tableSql);
+        return getDataTable(list);
+    }
+
+    /**
+     * 获取table 联合查询sql存储详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:sql:query')")
+    @GetMapping(value = "/{tId}")
+    public AjaxResult getInfo(@PathVariable("tId") Long tId)
+    {
+        return success(tableSqlService.selectTableSqlByTId(tId));
+    }
+}

+ 32 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/BlobTypeHandler.java

@@ -0,0 +1,32 @@
+package com.zkqy.business.entity;
+
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+
+import java.sql.*;
+
+public class BlobTypeHandler extends BaseTypeHandler<Blob> {  
+  
+    @Override  
+    public void setNonNullParameter(PreparedStatement ps, int i, Blob parameter, JdbcType jdbcType) throws SQLException {  
+        ps.setBlob(i, parameter);  
+    }  
+  
+    @Override  
+    public Blob getNullableResult(ResultSet rs, String columnName) throws SQLException {  
+        Blob blob = rs.getBlob(columnName);
+        return blob;  
+    }  
+  
+    @Override  
+    public Blob getNullableResult(ResultSet rs, int columnIndex) throws SQLException {  
+        Blob blob = rs.getBlob(columnIndex);  
+        return blob;  
+    }  
+  
+    @Override  
+    public Blob getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {  
+        Blob blob = cs.getBlob(columnIndex);  
+        return blob;  
+    }  
+}

+ 293 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/DragForm.java

@@ -0,0 +1,293 @@
+package com.zkqy.business.entity;
+
+import com.zkqy.common.annotation.Excel;
+import com.zkqy.common.core.domain.BaseEntity;
+
+/**
+ * 动态表单
+ * 对象 drag_form
+ *
+ * @author ruoyi
+ * @date 2023-07-12
+ */
+public class DragForm extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 表单主键
+     */
+    private Long fId;
+
+    /** 表单key */
+    private String formKey;
+
+    /**
+     * sql编号
+     */
+    @Excel(name = "sql编号")
+    private String sqlKey;
+
+    /**
+     * 表单名称
+     */
+    @Excel(name = "表单名称")
+    private String dfName;
+
+    /**
+     * 表单别名
+     */
+    @Excel(name = "表单别名")
+    private String dfNickname;
+
+    /**
+     * 表单vue模版
+     */
+    @Excel(name = "表单vue模版")
+    private String dfVueTemplate;
+
+    /**
+     * 表单html模版
+     */
+    @Excel(name = "表单html模版")
+    private String dfHtmlTemplate;
+
+    /**
+     * 表单sql
+     */
+    @Excel(name = "表单sql")
+    private String dfFormSql;
+
+    /**
+     * 节点ID
+     */
+    @Excel(name = "节点ID")
+    private Long dfNodeId;
+
+    /**
+     * 数据源名称
+     */
+    @Excel(name = "数据源名称")
+    private String dfDatabase;
+
+    /**
+     * 绑定表名称
+     */
+    @Excel(name = "绑定表名称")
+    private String dfTableName;
+
+    /**
+     * 源文件存放地址
+     */
+    @Excel(name = "源文件存放地址")
+    private String dfFliePath;
+
+    /**
+     * 表单描述
+     */
+    @Excel(name = "表单描述")
+    private String dfNotes;
+
+    /**
+     * 逻辑删除
+     */
+    private String delFlag;
+
+    /**
+     * 备用列
+     */
+
+    private String spare;
+
+    /**
+     * 备用列
+     */
+
+    private String spare1;
+
+    //动态表格编号
+    private Long dtId;
+
+
+    public Long getfId() {
+        return fId;
+    }
+
+    public void setfId(Long fId) {
+        this.fId = fId;
+    }
+
+    public String getFormKey() {
+        return formKey;
+    }
+
+    public void setFormKey(String formKey) {
+        this.formKey = formKey;
+    }
+
+    public String getSqlKey() {
+        return sqlKey;
+    }
+
+    public void setSqlKey(String sqlKey) {
+        this.sqlKey = sqlKey;
+    }
+
+    public String getDfName() {
+        return dfName;
+    }
+
+    public void setDfName(String dfName) {
+        this.dfName = dfName;
+    }
+
+    public String getDfNickname() {
+        return dfNickname;
+    }
+
+    public void setDfNickname(String dfNickname) {
+        this.dfNickname = dfNickname;
+    }
+
+    public String getDfVueTemplate() {
+        return dfVueTemplate;
+    }
+
+    public void setDfVueTemplate(String dfVueTemplate) {
+        this.dfVueTemplate = dfVueTemplate;
+    }
+
+    public String getDfHtmlTemplate() {
+        return dfHtmlTemplate;
+    }
+
+    public void setDfHtmlTemplate(String dfHtmlTemplate) {
+        this.dfHtmlTemplate = dfHtmlTemplate;
+    }
+
+    public String getDfFormSql() {
+        return dfFormSql;
+    }
+
+    public void setDfFormSql(String dfFormSql) {
+        this.dfFormSql = dfFormSql;
+    }
+
+    public Long getDfNodeId() {
+        return dfNodeId;
+    }
+
+    public void setDfNodeId(Long dfNodeId) {
+        this.dfNodeId = dfNodeId;
+    }
+
+    public String getDfDatabase() {
+        return dfDatabase;
+    }
+
+    public void setDfDatabase(String dfDatabase) {
+        this.dfDatabase = dfDatabase;
+    }
+
+    public String getDfTableName() {
+        return dfTableName;
+    }
+
+    public void setDfTableName(String dfTableName) {
+        this.dfTableName = dfTableName;
+    }
+
+    public String getDfFliePath() {
+        return dfFliePath;
+    }
+
+    public void setDfFliePath(String dfFliePath) {
+        this.dfFliePath = dfFliePath;
+    }
+
+    public String getDfNotes() {
+        return dfNotes;
+    }
+
+    public void setDfNotes(String dfNotes) {
+        this.dfNotes = dfNotes;
+    }
+
+    public String getDelFlag() {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag) {
+        this.delFlag = delFlag;
+    }
+
+    public String getSpare() {
+        return spare;
+    }
+
+    public void setSpare(String spare) {
+        this.spare = spare;
+    }
+
+    public String getSpare1() {
+        return spare1;
+    }
+
+    public void setSpare1(String spare1) {
+        this.spare1 = spare1;
+    }
+
+    public Long getDtId() {
+        return dtId;
+    }
+
+    public void setDtId(Long dtId) {
+        this.dtId = dtId;
+    }
+
+    @Override
+    public String toString() {
+        return "DragForm{" +
+                "fId=" + fId +
+                ", formKey='" + formKey + '\'' +
+                ", sqlKey='" + sqlKey + '\'' +
+                ", dfName='" + dfName + '\'' +
+                ", dfNickname='" + dfNickname + '\'' +
+                ", dfVueTemplate='" + dfVueTemplate + '\'' +
+                ", dfHtmlTemplate='" + dfHtmlTemplate + '\'' +
+                ", dfFormSql='" + dfFormSql + '\'' +
+                ", dfNodeId=" + dfNodeId +
+                ", dfDatabase='" + dfDatabase + '\'' +
+                ", dfTableName='" + dfTableName + '\'' +
+                ", dfFliePath='" + dfFliePath + '\'' +
+                ", dfNotes='" + dfNotes + '\'' +
+                ", delFlag='" + delFlag + '\'' +
+                ", spare='" + spare + '\'' +
+                ", spare1='" + spare1 + '\'' +
+                ", dtId=" + dtId +
+                '}';
+    }
+
+    public DragForm() {
+
+    }
+
+    public DragForm(Long fId,String formKey, String sqlKey, String dfName, String dfNickname, String dfVueTemplate, String dfHtmlTemplate, String dfFormSql, Long dfNodeId, String dfDatabase, String dfTableName, String dfFliePath, String dfNotes, String delFlag, String spare, String spare1, Long dtId) {
+        this.fId = fId;
+        this.formKey = formKey;
+        this.sqlKey = sqlKey;
+        this.dfName = dfName;
+        this.dfNickname = dfNickname;
+        this.dfVueTemplate = dfVueTemplate;
+        this.dfHtmlTemplate = dfHtmlTemplate;
+        this.dfFormSql = dfFormSql;
+        this.dfNodeId = dfNodeId;
+        this.dfDatabase = dfDatabase;
+        this.dfTableName = dfTableName;
+        this.dfFliePath = dfFliePath;
+        this.dfNotes = dfNotes;
+        this.delFlag = delFlag;
+        this.spare = spare;
+        this.spare1 = spare1;
+        this.dtId = dtId;
+    }
+}

+ 267 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/DragTable.java

@@ -0,0 +1,267 @@
+package com.zkqy.business.entity;
+
+import com.zkqy.common.annotation.Excel;
+import com.zkqy.common.core.domain.BaseEntity;
+
+/**
+ * 动态表格对象 drag_table
+ *
+ * @author ruoyi
+ * @date 2023-07-31
+ */
+public class DragTable extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 表格主键
+     */
+    private Long tId;
+
+    /**
+     * 表格名称
+     */
+    @Excel(name = "表格名称")
+    private String dtName;
+
+    /**
+     * 表格类型
+     */
+    @Excel(name = "表格名称")
+    private String dtType;
+
+
+    /**
+     * 表格别名
+     */
+    @Excel(name = "表格别名")
+    private String dtNickname;
+
+    /**
+     * table编号
+     */
+    @Excel(name = "table编号")
+    private String tableKey;
+
+    /**
+     * sql编号
+     */
+    @Excel(name = "sql编号")
+    private String sqlKey;
+
+    /**
+     * 绑定表名称
+     */
+    @Excel(name = "绑定表名称")
+    private String dtTableName;
+
+    /**
+     * 表格描述
+     */
+    @Excel(name = "表格描述")
+    private String dtNotes;
+
+    /**
+     * 列字段标题名称
+     */
+    @Excel(name = "列字段标题名称")
+    private String dtColumnName;
+
+    /**
+     * 时间格式
+     */
+    @Excel(name = "时间格式")
+    private String timeFormat;
+
+    /**
+     * 备用列
+     */
+
+    private String spare;
+
+    /**
+     * 备用列
+     */
+
+    private String spare1;
+
+    /**
+     * 逻辑删除
+     */
+    private String delFlag;
+
+    /**
+     * 是否显示列表复选框(0:显示;1;不显示)
+     */
+    private String isSelection;
+
+    /**
+     * 回显数据(前端修改回显数据使用)
+     */
+    private String echoData;
+
+    /**
+     * 菜单编号
+     */
+    private Long menuId;
+
+    /**
+     * 当前表单的唯一标识,修改删除使用
+     */
+    private String primaryKey;
+
+    @Override
+    public String toString() {
+        return "DragTable{" +
+                "tId=" + tId +
+                ", dtName='" + dtName + '\'' +
+                ", dtNickname='" + dtNickname + '\'' +
+                ", tableKey='" + tableKey + '\'' +
+                ", sqlKey='" + sqlKey + '\'' +
+                ", dtTableName='" + dtTableName + '\'' +
+                ", dtNotes='" + dtNotes + '\'' +
+                ", dtColumnName='" + dtColumnName + '\'' +
+                ", timeFormat='" + timeFormat + '\'' +
+                ", spare='" + spare + '\'' +
+                ", spare1='" + spare1 + '\'' +
+                ", delFlag='" + delFlag + '\'' +
+                ", isSelection='" + isSelection + '\'' +
+                ", echoData='" + echoData + '\'' +
+                ", menuId=" + menuId +
+                ", primaryKey='" + primaryKey + '\'' +
+                '}';
+    }
+
+    public Long gettId() {
+        return tId;
+    }
+
+    public void settId(Long tId) {
+        this.tId = tId;
+    }
+
+    public String getDtType() {return dtType;}
+
+    public void setDtType(String dtType) {this.dtType = dtType;}
+
+    public String getDtName() {
+        return dtName;
+    }
+
+    public void setDtName(String dtName) {
+        this.dtName = dtName;
+    }
+
+    public String getDtNickname() {
+        return dtNickname;
+    }
+
+    public void setDtNickname(String dtNickname) {
+        this.dtNickname = dtNickname;
+    }
+
+    public String getTableKey() {
+        return tableKey;
+    }
+
+    public void setTableKey(String tableKey) {
+        this.tableKey = tableKey;
+    }
+
+    public String getSqlKey() {
+        return sqlKey;
+    }
+
+    public void setSqlKey(String sqlKey) {
+        this.sqlKey = sqlKey;
+    }
+
+    public String getDtTableName() {
+        return dtTableName;
+    }
+
+    public void setDtTableName(String dtTableName) {
+        this.dtTableName = dtTableName;
+    }
+
+    public String getDtNotes() {
+        return dtNotes;
+    }
+
+    public void setDtNotes(String dtNotes) {
+        this.dtNotes = dtNotes;
+    }
+
+    public String getDtColumnName() {
+        return dtColumnName;
+    }
+
+    public void setDtColumnName(String dtColumnName) {
+        this.dtColumnName = dtColumnName;
+    }
+
+    public String getTimeFormat() {
+        return timeFormat;
+    }
+
+    public void setTimeFormat(String timeFormat) {
+        this.timeFormat = timeFormat;
+    }
+
+    public String getSpare() {
+        return spare;
+    }
+
+    public void setSpare(String spare) {
+        this.spare = spare;
+    }
+
+    public String getSpare1() {
+        return spare1;
+    }
+
+    public void setSpare1(String spare1) {
+        this.spare1 = spare1;
+    }
+
+    public String getDelFlag() {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag) {
+        this.delFlag = delFlag;
+    }
+
+    public String getIsSelection() {
+        return isSelection;
+    }
+
+    public void setIsSelection(String isSelection) {
+        this.isSelection = isSelection;
+    }
+
+    public String getEchoData() {
+        return echoData;
+    }
+
+    public void setEchoData(String echoData) {
+        this.echoData = echoData;
+    }
+
+    public Long getMenuId() {
+        return menuId;
+    }
+
+    public void setMenuId(Long menuId) {
+        this.menuId = menuId;
+    }
+
+    public String getPrimaryKey() {
+        return primaryKey;
+    }
+
+    public void setPrimaryKey(String primaryKey) {
+        this.primaryKey = primaryKey;
+    }
+
+
+}

+ 320 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/DragTableBtn.java

@@ -0,0 +1,320 @@
+package com.zkqy.business.entity;
+
+import com.zkqy.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 格绑定的自定义按钮对象 drag_table_btn
+ *
+ * @author ruoyi
+ * @date 2023-11-07
+ */
+public class DragTableBtn extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 父级ID
+     */
+    private Long btnParentId;
+
+    /**
+     * 祖籍列表
+     */
+    private String ancestorsId;
+
+    /**
+     * 按钮别名
+     */
+    private String btnKey;
+
+    /**
+     * 按钮组类型
+     */
+    private String btnGroupType;
+
+    /**
+     * 按钮组名称
+     */
+    private String btnGroupName;
+
+    /**
+     * 按钮名称
+     */
+    private String btnName;
+
+    /**
+     * 按钮类型(0:操作按钮,1,其他,2表单,3跳转,4流程,5脚本,6目录)
+     */
+    private String btnType;
+
+    /**
+     * 按钮图标
+     */
+    private String btnIcon;
+
+    /**
+     * 表单唯一标识
+     */
+    private String btnFormKey;
+
+    /**
+     * 表单唯一标识
+     */
+    private String btnFormType;
+
+    /**
+     * 流程唯一标识
+     */
+    private String btnProcessKey;
+
+    /**
+     * 表格唯一标识
+     */
+    private String btnTableKey;
+
+    /**
+     * 脚本唯一标识
+     */
+    private String btnScriptKey;
+
+    /**
+     * 弹窗表格唯一标识
+     */
+    private String btnTableFormGroupKey;
+
+    /**
+     * 按钮显示条件
+     */
+    private String btnShowCondition;
+
+    /**
+     * 操作参数
+     */
+    private String btnParams;
+
+    /**
+     * 权限字符
+     */
+    private String btnHasPermi;
+
+    /**
+     * 按钮顺序
+     */
+    private Long btnSort;
+
+    /**
+     * 删除标志(0:否;1:是)
+     */
+    private String delFlag;
+
+
+    /**
+     * 子菜单
+     */
+    private List<DragTableBtn> children = new ArrayList<DragTableBtn>();
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getBtnParentId() {
+        return btnParentId;
+    }
+
+    public void setBtnParentId(Long btnParentId) {
+        this.btnParentId = btnParentId;
+    }
+
+    public String getAncestorsId() {
+        return ancestorsId;
+    }
+
+    public void setAncestorsId(String ancestorsId) {
+        this.ancestorsId = ancestorsId;
+    }
+
+    public String getBtnKey() {
+        return btnKey;
+    }
+
+    public void setBtnKey(String btnKey) {
+        this.btnKey = btnKey;
+    }
+
+    public String getBtnGroupName() {
+        return btnGroupName;
+    }
+
+    public void setBtnGroupName(String btnGroupName) {
+        this.btnGroupName = btnGroupName;
+    }
+
+    public String getBtnName() {
+        return btnName;
+    }
+
+    public void setBtnName(String btnName) {
+        this.btnName = btnName;
+    }
+
+    public String getBtnType() {
+        return btnType;
+    }
+
+    public void setBtnType(String btnType) {
+        this.btnType = btnType;
+    }
+
+    public String getBtnFormKey() {
+        return btnFormKey;
+    }
+
+    public void setBtnFormKey(String btnFormKey) {
+        this.btnFormKey = btnFormKey;
+    }
+
+    public String getBtnProcessKey() {
+        return btnProcessKey;
+    }
+
+    public void setBtnProcessKey(String btnProcessKey) {
+        this.btnProcessKey = btnProcessKey;
+    }
+
+    public String getBtnTableKey() {
+        return btnTableKey;
+    }
+
+    public void setBtnTableKey(String btnTableKey) {
+        this.btnTableKey = btnTableKey;
+    }
+
+    public String getBtnScriptKey() {
+        return btnScriptKey;
+    }
+
+    public void setBtnScriptKey(String btnScriptKey) {
+        this.btnScriptKey = btnScriptKey;
+    }
+
+    public String getBtnShowCondition() {
+        return btnShowCondition;
+    }
+
+    public void setBtnShowCondition(String btnShowCondition) {
+        this.btnShowCondition = btnShowCondition;
+    }
+
+    public String getBtnParams() {
+        return btnParams;
+    }
+
+    public void setBtnParams(String btnParams) {
+        this.btnParams = btnParams;
+    }
+
+    public String getBtnHasPermi() {
+        return btnHasPermi;
+    }
+
+    public void setBtnHasPermi(String btnHasPermi) {
+        this.btnHasPermi = btnHasPermi;
+    }
+
+    public Long getBtnSort() {
+        return btnSort;
+    }
+
+    public void setBtnSort(Long btnSort) {
+        this.btnSort = btnSort;
+    }
+
+    public String getDelFlag() {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag) {
+        this.delFlag = delFlag;
+    }
+
+
+    public List<DragTableBtn> getChildren() {
+        return children;
+    }
+
+    public void setChildren(List<DragTableBtn> children) {
+        this.children = children;
+    }
+
+    public String getBtnIcon() {
+        return btnIcon;
+    }
+
+    public void setBtnIcon(String btnIcon) {
+        this.btnIcon = btnIcon;
+    }
+
+    public String getBtnTableFormGroupKey() {
+        return btnTableFormGroupKey;
+    }
+
+    public void setBtnTableFormGroupKey(String btnTableFormGroupKey) {
+        this.btnTableFormGroupKey = btnTableFormGroupKey;
+    }
+
+    public String getBtnFormType() {
+        return btnFormType;
+    }
+
+    public void setBtnFormType(String btnFormType) {
+        this.btnFormType = btnFormType;
+    }
+
+    public String getBtnGroupType() {
+        return btnGroupType;
+    }
+
+    public void setBtnGroupType(String btnGroupType) {
+        this.btnGroupType = btnGroupType;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("DragTableBtn{");
+        sb.append("id=").append(id);
+        sb.append(", btnParentId=").append(btnParentId);
+        sb.append(", ancestorsId='").append(ancestorsId).append('\'');
+        sb.append(", btnKey='").append(btnKey).append('\'');
+        sb.append(", btnGroupName='").append(btnGroupName).append('\'');
+        sb.append(", btnName='").append(btnName).append('\'');
+        sb.append(", btnType='").append(btnType).append('\'');
+        sb.append(", btnIcon='").append(btnIcon).append('\'');
+        sb.append(", btnFormKey='").append(btnFormKey).append('\'');
+        sb.append(", btnFormType='").append(btnFormType).append('\'');
+        sb.append(", btnProcessKey='").append(btnProcessKey).append('\'');
+        sb.append(", btnTableKey='").append(btnTableKey).append('\'');
+        sb.append(", btnScriptKey='").append(btnScriptKey).append('\'');
+        sb.append(", btnTableFormGroupKey='").append(btnTableFormGroupKey).append('\'');
+        sb.append(", btnShowCondition='").append(btnShowCondition).append('\'');
+        sb.append(", btnParams='").append(btnParams).append('\'');
+        sb.append(", btnHasPermi='").append(btnHasPermi).append('\'');
+        sb.append(", btnSort=").append(btnSort);
+        sb.append(", delFlag='").append(delFlag).append('\'');
+        sb.append(", children=").append(children);
+        sb.append('}');
+        return sb.toString();
+    }
+}

+ 52 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/DragTableBtnRelevance.java

@@ -0,0 +1,52 @@
+package com.zkqy.business.entity;
+
+import com.zkqy.common.annotation.Excel;
+import com.zkqy.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * 动态格和动态格按钮关联对象 drag_table_btn_relevance
+ * 
+ * @author ruoyi
+ * @date 2023-11-09
+ */
+public class DragTableBtnRelevance extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 动态表格key(唯一标识) */
+    @Excel(name = "动态表格key", readConverterExp = "唯=一标识")
+    private String tableKey;
+
+    /** 动态表格按钮key(唯一标识) */
+    @Excel(name = "动态表格按钮key", readConverterExp = "唯=一标识")
+    private String btnKey;
+
+    public void setTableKey(String tableKey) 
+    {
+        this.tableKey = tableKey;
+    }
+
+    public String getTableKey() 
+    {
+        return tableKey;
+    }
+    public void setBtnKey(String btnKey) 
+    {
+        this.btnKey = btnKey;
+    }
+
+    public String getBtnKey() 
+    {
+        return btnKey;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("tableKey", getTableKey())
+            .append("btnKey", getBtnKey())
+            .toString();
+    }
+}

+ 332 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/DragTableCondition.java

@@ -0,0 +1,332 @@
+package com.zkqy.business.entity;
+
+import com.zkqy.common.annotation.Excel;
+import com.zkqy.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 动态表格条件对象 drag_table_condition
+ *
+ * @author ruoyi
+ * @date 2023-07-31
+ */
+public class DragTableCondition extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 编号
+     */
+    private Long tcId;
+
+    /**
+     * 动态表格编号
+     */
+    @Excel(name = "动态表格编号")
+    private Long tId;
+
+    /**
+     * 条件名称
+     */
+    @Excel(name = "条件名称")
+    private String conditionName;
+
+    /**
+     * 条件字段
+     */
+    @Excel(name = "条件字段")
+    private String conditionField;
+
+    /**
+     * 条件描述
+     */
+    @Excel(name = "条件描述")
+    private String conditionNotes;
+
+    /**
+     * 条件类型
+     */
+    @Excel(name = "条件类型")
+    private String conditionType;
+
+    /**
+     * 默认值
+     */
+    @Excel(name = "默认值")
+    private String conditionDefaultValue;
+
+    /**
+     * 排序
+     */
+    @Excel(name = "排序")
+    private Long sort;
+
+    /**
+     * 表名称(下拉框关联)
+     */
+    @Excel(name = "表名称", readConverterExp = "下=拉框关联")
+    private String conditionTableName;
+
+    /**
+     * 表字段名称(下拉框关联)/ 字典类型
+     */
+    @Excel(name = "表字段名称", readConverterExp = "下=拉框关联")
+    private String conditionTableFieldName;
+
+    /**
+     * 表字段key(下拉框关联)/ 唯一标识
+     */
+    @Excel(name = "表字段key", readConverterExp = "下=拉框关联")
+    private String conditionTableFieldKey;
+
+    /**
+     * 数据来源(0:字典;1:表字段)
+     */
+    @Excel(name = "数据来源", readConverterExp = "0=:字典;1:表字段")
+    private String conditionDatasource;
+
+    /**
+     * 组件类型(时间组件、btn等type类型参照element官方api中的类型 )
+     */
+    @Excel(name = "组件类型", readConverterExp = "时=间组件、btn等type类型参照element官方api中的类型")
+    private String componentType;
+
+    /**
+     * 组件大小
+     */
+    @Excel(name = "组件大小")
+    private String componentSize;
+
+    /**
+     * 组件图标
+     */
+    @Excel(name = "组件图标")
+    private String componentIcon;
+
+    /**
+     * 是否隐藏(0 显示; 1 隐藏)
+     */
+    @Excel(name = "是否隐藏(0 显示; 1 隐藏)")
+    private String isHidden;
+
+    /**
+     * 逻辑删除(0 否; 1 是)
+     */
+    private String delFlag;
+
+    /**
+     * 下拉框列表
+     */
+    List<Map<String, Object>> dropDownList;
+
+    public DragTableCondition() {
+    }
+
+    public DragTableCondition(Long tId, String conditionField) {
+        this.tId = tId;
+        this.conditionField = conditionField;
+    }
+
+    public DragTableCondition(Long tId, String conditionField, String conditionDefaultValue) {
+        this.tId = tId;
+        this.conditionField = conditionField;
+        this.conditionDefaultValue = conditionDefaultValue;
+    }
+
+    public DragTableCondition(Long tcId, Long tId, String conditionName, String conditionField, String conditionNotes, String conditionType, String conditionDefaultValue, Long sort, String conditionTableName, String conditionTableFieldName, String conditionTableFieldKey, String conditionDatasource, String componentType, String componentSize, String componentIcon, String isHidden, String delFlag, List<Map<String, Object>> dropDownList) {
+        this.tcId = tcId;
+        this.tId = tId;
+        this.conditionName = conditionName;
+        this.conditionField = conditionField;
+        this.conditionNotes = conditionNotes;
+        this.conditionType = conditionType;
+        this.conditionDefaultValue = conditionDefaultValue;
+        this.sort = sort;
+        this.conditionTableName = conditionTableName;
+        this.conditionTableFieldName = conditionTableFieldName;
+        this.conditionTableFieldKey = conditionTableFieldKey;
+        this.conditionDatasource = conditionDatasource;
+        this.componentType = componentType;
+        this.componentSize = componentSize;
+        this.componentIcon = componentIcon;
+        this.isHidden = isHidden;
+        this.delFlag = delFlag;
+        this.dropDownList = dropDownList;
+    }
+
+    public void setTcId(Long tcId) {
+        this.tcId = tcId;
+    }
+
+    public Long getTcId() {
+        return tcId;
+    }
+
+    public void settId(Long tId) {
+        this.tId = tId;
+    }
+
+    public Long gettId() {
+        return tId;
+    }
+
+    public void setConditionName(String conditionName) {
+        this.conditionName = conditionName;
+    }
+
+    public String getConditionName() {
+        return conditionName;
+    }
+
+    public void setConditionField(String conditionField) {
+        this.conditionField = conditionField;
+    }
+
+    public String getConditionField() {
+        return conditionField;
+    }
+
+    public void setConditionNotes(String conditionNotes) {
+        this.conditionNotes = conditionNotes;
+    }
+
+    public String getConditionNotes() {
+        return conditionNotes;
+    }
+
+    public void setConditionType(String conditionType) {
+        this.conditionType = conditionType;
+    }
+
+    public String getConditionType() {
+        return conditionType;
+    }
+
+    public void setConditionDefaultValue(String conditionDefaultValue) {
+        this.conditionDefaultValue = conditionDefaultValue;
+    }
+
+    public String getConditionDefaultValue() {
+        return conditionDefaultValue;
+    }
+
+    public void setSort(Long sort) {
+        this.sort = sort;
+    }
+
+    public Long getSort() {
+        return sort;
+    }
+
+    public void setConditionTableName(String conditionTableName) {
+        this.conditionTableName = conditionTableName;
+    }
+
+    public String getConditionTableName() {
+        return conditionTableName;
+    }
+
+    public void setConditionTableFieldName(String conditionTableFieldName) {
+        this.conditionTableFieldName = conditionTableFieldName;
+    }
+
+    public String getConditionTableFieldName() {
+        return conditionTableFieldName;
+    }
+
+    public void setConditionDatasource(String conditionDatasource) {
+        this.conditionDatasource = conditionDatasource;
+    }
+
+    public String getConditionTableFieldKey() {
+        return conditionTableFieldKey;
+    }
+
+    public void setConditionTableFieldKey(String conditionTableFieldKey) {
+        this.conditionTableFieldKey = conditionTableFieldKey;
+    }
+
+    public String getConditionDatasource() {
+        return conditionDatasource;
+    }
+
+    public void setComponentType(String componentType) {
+        this.componentType = componentType;
+    }
+
+    public String getComponentType() {
+        return componentType;
+    }
+
+    public void setComponentSize(String componentSize) {
+        this.componentSize = componentSize;
+    }
+
+    public String getComponentSize() {
+        return componentSize;
+    }
+
+    public void setComponentIcon(String componentIcon) {
+        this.componentIcon = componentIcon;
+    }
+
+    public String getComponentIcon() {
+        return componentIcon;
+    }
+
+    public void setIsHidden(String isHidden) {
+        this.isHidden = isHidden;
+    }
+
+    public String getIsHidden() {
+        return isHidden;
+    }
+
+    public void setDelFlag(String delFlag) {
+        this.delFlag = delFlag;
+    }
+
+    public String getDelFlag() {
+        return delFlag;
+    }
+
+    public List<Map<String, Object>> getDropDownList() {
+        return dropDownList;
+    }
+
+    public void setDropDownList(List<Map<String, Object>> dropDownList) {
+        this.dropDownList = dropDownList;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("tcId", getTcId())
+                .append("tId", gettId())
+                .append("conditionName", getConditionName())
+                .append("conditionField", getConditionField())
+                .append("conditionNotes", getConditionNotes())
+                .append("conditionType", getConditionType())
+                .append("conditionDefaultValue", getConditionDefaultValue())
+                .append("sort", getSort())
+                .append("conditionTableName", getConditionTableName())
+                .append("conditionTableFieldName", getConditionTableFieldName())
+                .append("conditionTableFieldKey", getConditionTableFieldKey())
+                .append("conditionDatasource", getConditionDatasource())
+                .append("componentType", getComponentType())
+                .append("componentSize", getComponentSize())
+                .append("componentIcon", getComponentIcon())
+                .append("isHidden", getIsHidden())
+                .append("delFlag", getDelFlag())
+                .append("createBy", getCreateBy())
+                .append("createTime", getCreateTime())
+                .append("updateBy", getUpdateBy())
+                .append("updateTime", getUpdateTime())
+                .append("dropDownList", getDropDownList())
+                .toString();
+    }
+}

+ 53 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/DragTableForm.java

@@ -0,0 +1,53 @@
+package com.zkqy.business.entity;
+
+import com.zkqy.common.core.domain.BaseEntity;
+
+/**
+ * 动态表格表达关联表 drag_table_form
+ *
+ * @author ruoyi
+ */
+public class DragTableForm extends BaseEntity {
+
+    /** 编号 */
+    private Long id;
+
+    /** 动态表格id */
+    private Long dtId;
+
+    /** 动态表单id */
+    private Long dfId;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getDtId() {
+        return dtId;
+    }
+
+    public void setDtId(Long dtId) {
+        this.dtId = dtId;
+    }
+
+    public Long getDfId() {
+        return dfId;
+    }
+
+    public void setDfId(Long dfId) {
+        this.dfId = dfId;
+    }
+
+    @Override
+    public String toString() {
+        return "DragTableForm{" +
+                "id=" + id +
+                ", dtId=" + dtId +
+                ", dfId=" + dfId +
+                '}';
+    }
+}

+ 123 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/DragTableGroup.java

@@ -0,0 +1,123 @@
+package com.zkqy.business.entity;
+
+import com.zkqy.common.annotation.Excel;
+import com.zkqy.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * @author hmc
+ * @date 2023-11-01 14:19
+ * @Description: 拖拽格组对象 drag_table_group
+ */
+public class DragTableGroup extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /** 主键 */
+    private Long id;
+
+    /** 表格组名称 */
+    @Excel(name = "表格组名称")
+    private String groupName;
+
+
+    /** 表格组key名称 */
+    @Excel(name = "表格组key")
+    private String groupKey;
+
+
+    /** 表格组类型 */
+    @Excel(name = "表格组key")
+    private String groupType;
+
+    /** 表格组描述 */
+    @Excel(name = "表格组描述")
+    private String groupDescription;
+
+    /** 存放表格联动信息 {tablekey:dfasdfa,顺序:1} */
+    @Excel(name = "存放表格联动信息")
+    private String groupTableInfo;
+
+
+
+    /**
+     * 逻辑删除
+     */
+    private String delFlag;
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getGroupName() {
+        return groupName;
+    }
+
+    public void setGroupName(String groupName) {
+        this.groupName = groupName;
+    }
+
+    public String getGroupDescription() {
+        return groupDescription;
+    }
+
+    public void setGroupDescription(String groupDescription) {
+        this.groupDescription = groupDescription;
+    }
+
+    public String getGroupTableInfo() {
+        return groupTableInfo;
+    }
+
+    public void setGroupTableInfo(String groupTableInfo) {
+        this.groupTableInfo = groupTableInfo;
+    }
+
+    public String getGroupKey() {
+        return groupKey;
+    }
+
+    public void setGroupKey(String groupKey) {
+        this.groupKey = groupKey;
+    }
+
+
+    public String getGroupType() {
+        return groupType;
+    }
+
+    public void setGroupType(String groupType) {
+        this.groupType = groupType;
+    }
+
+
+    public String getDelFlag() {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag) {
+        this.delFlag = delFlag;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("id", getId())
+                .append("groupName", getGroupName())
+                .append("groupDescription", getGroupDescription())
+                .append("groupTableInfo", getGroupTableInfo())
+                .append("createById", getCreateById())
+                .append("createBy", getCreateBy())
+                .append("createTime", getCreateTime())
+                .append("updateById", getUpdateById())
+                .append("updateBy", getUpdateBy())
+                .append("updateTime", getUpdateTime())
+                .toString();
+    }
+}

+ 153 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/DragTableStatistic.java

@@ -0,0 +1,153 @@
+package com.zkqy.business.entity;
+
+import com.zkqy.common.annotation.Excel;
+import com.zkqy.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * 动态表格统计对象 drag_table_statistic
+ * 
+ * @author ruoyi
+ * @date 2023-10-27
+ */
+public class DragTableStatistic extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 编号 */
+    private Long id;
+
+    /** 统计标题 */
+    @Excel(name = "统计标题")
+    private String statisticTitle;
+
+    /** 表格key */
+    @Excel(name = "表格key")
+    private String tableKey;
+
+    /** 统计描述 */
+    @Excel(name = "统计描述")
+    private String statisticDescription;
+
+    /** 统计类型 */
+    @Excel(name = "统计类型")
+    private String statisticType;
+
+    /** 统计字段 */
+    @Excel(name = "统计字段")
+    private String statisticField;
+
+    /** 统计对象 */
+    @Excel(name = "统计对象")
+    private String statisticObject;
+
+    /** 执行sql */
+    @Excel(name = "执行sql")
+    private String sqlKey;
+
+    /** 删除标志(0:否;2:是) */
+    private String delFlag;
+
+    //执行sql返回结果
+    private Object result;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getStatisticTitle() {
+        return statisticTitle;
+    }
+
+    public void setStatisticTitle(String statisticTitle) {
+        this.statisticTitle = statisticTitle;
+    }
+
+    public String getTableKey() {
+        return tableKey;
+    }
+
+    public void setTableKey(String tableKey) {
+        this.tableKey = tableKey;
+    }
+
+    public String getStatisticDescription() {
+        return statisticDescription;
+    }
+
+    public void setStatisticDescription(String statisticDescription) {
+        this.statisticDescription = statisticDescription;
+    }
+
+    public String getStatisticType() {
+        return statisticType;
+    }
+
+    public void setStatisticType(String statisticType) {
+        this.statisticType = statisticType;
+    }
+
+    public String getStatisticField() {
+        return statisticField;
+    }
+
+    public void setStatisticField(String statisticField) {
+        this.statisticField = statisticField;
+    }
+
+    public String getStatisticObject() {
+        return statisticObject;
+    }
+
+    public void setStatisticObject(String statisticObject) {
+        this.statisticObject = statisticObject;
+    }
+
+    public String getSqlKey() {
+        return sqlKey;
+    }
+
+    public void setSqlKey(String sqlKey) {
+        this.sqlKey = sqlKey;
+    }
+
+    public String getDelFlag() {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag) {
+        this.delFlag = delFlag;
+    }
+
+    public Object getResult() {
+        return result;
+    }
+
+    public void setResult(Object result) {
+        this.result = result;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("statisticTitle", getStatisticTitle())
+            .append("tableKey", getTableKey())
+            .append("statisticDescription", getStatisticDescription())
+            .append("statisticType", getStatisticType())
+            .append("statisticField", getStatisticField())
+            .append("statisticObject", getStatisticObject())
+            .append("sqlKey", getSqlKey())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 189 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/DragTableStyle.java

@@ -0,0 +1,189 @@
+package com.zkqy.business.entity;
+
+import com.zkqy.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * 动态格样式对象 drag_table_style
+ * 
+ * @author ruoyi
+ * @date 2023-11-03
+ */
+public class DragTableStyle extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键 */
+    private Long id;
+
+    /** 样式名称 */
+    private String styleName;
+
+    /** 样式代码 */
+    private String styleCode;
+
+    /** 动态表格主键 */
+    private String tableKey;
+
+    /** 显示样式条件/字典类型 */
+    private String styleCondtion;
+
+    /** 字段名称 */
+    private String styleField;
+
+    /** 类型(0:整行1:单个字段2:字典类型) */
+    private Long styleType;
+
+    /** 样式描述 */
+    private String styleDescription;
+
+    /** 备用列(未启用) */
+    private String spare1;
+
+    /** 备用列(未启用) */
+    private String spare2;
+
+    /** 删除标志(0:否 2:是) */
+    private String delFlag;
+
+    /** 创建者id */
+    private Long createById;
+
+    /** 更新者id */
+    private Long updateById;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+    public void setStyleName(String styleName) 
+    {
+        this.styleName = styleName;
+    }
+
+    public String getStyleName() 
+    {
+        return styleName;
+    }
+    public void setStyleCode(String styleCode) 
+    {
+        this.styleCode = styleCode;
+    }
+
+    public String getStyleCode() 
+    {
+        return styleCode;
+    }
+    public void setTableKey(String tableKey) 
+    {
+        this.tableKey = tableKey;
+    }
+
+    public String getTableKey() 
+    {
+        return tableKey;
+    }
+    public void setStyleCondtion(String styleCondtion) 
+    {
+        this.styleCondtion = styleCondtion;
+    }
+
+    public String getStyleCondtion() 
+    {
+        return styleCondtion;
+    }
+    public void setStyleField(String styleField) 
+    {
+        this.styleField = styleField;
+    }
+
+    public String getStyleField() 
+    {
+        return styleField;
+    }
+    public void setStyleType(Long styleType) 
+    {
+        this.styleType = styleType;
+    }
+
+    public Long getStyleType() 
+    {
+        return styleType;
+    }
+    public void setStyleDescription(String styleDescription) 
+    {
+        this.styleDescription = styleDescription;
+    }
+
+    public String getStyleDescription() 
+    {
+        return styleDescription;
+    }
+    public void setSpare1(String spare1) 
+    {
+        this.spare1 = spare1;
+    }
+
+    public String getSpare1() 
+    {
+        return spare1;
+    }
+    public void setSpare2(String spare2) 
+    {
+        this.spare2 = spare2;
+    }
+
+    public String getSpare2() 
+    {
+        return spare2;
+    }
+    public void setDelFlag(String delFlag) 
+    {
+        this.delFlag = delFlag;
+    }
+
+    public String getDelFlag() 
+    {
+        return delFlag;
+    }
+    public void setCreateById(Long createById) 
+    {
+        this.createById = createById;
+    }
+
+
+    public void setUpdateById(Long updateById) 
+    {
+        this.updateById = updateById;
+    }
+
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("styleName", getStyleName())
+            .append("styleCode", getStyleCode())
+            .append("tableKey", getTableKey())
+            .append("styleCondtion", getStyleCondtion())
+            .append("styleField", getStyleField())
+            .append("styleType", getStyleType())
+            .append("styleDescription", getStyleDescription())
+            .append("spare1", getSpare1())
+            .append("spare2", getSpare2())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createById", getCreateById())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateById", getUpdateById())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 238 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/FileManagement.java

@@ -0,0 +1,238 @@
+package com.zkqy.business.entity;
+
+import com.zkqy.common.core.domain.BaseEntityPlus;
+import com.zkqy.common.annotation.Excel;
+
+import java.util.Arrays;
+
+/**
+ * 文件管理(业务数据关联)对象 file_management
+ *
+ * @author hzh
+ * @date 2024-07-04
+ */
+public class FileManagement extends BaseEntityPlus {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    private Long id;
+
+    /**
+     * 文件组标识
+     */
+    private String fileGroupKey;
+
+    /**
+     * 原始文件名称
+     */
+    @Excel(name = "原始文件名称")
+    private String originalFileName;
+
+    /**
+     * 新文件名称
+     */
+    @Excel(name = "新文件名称")
+    private String newFileName;
+
+    /**
+     * 服务器文件相对路径
+     */
+    @Excel(name = "服务器文件相对路径")
+    private String filePath;
+
+    /**
+     * 文件类型(filePattern:文件形式、base64:64编码形式、bytes:字节形式)
+     */
+    @Excel(name = "文件类型", readConverterExp = "filePattern:文件形式、base64:64编码形式、bytes:字节形式")
+    private String fileType;
+
+    /**
+     * 文件大小
+     */
+    @Excel(name = "文件大小")
+    private Long fileSize;
+
+    /**
+     * 文件内容
+     */
+    @Excel(name = "文件内容")
+    private String fileContent;
+
+    /**
+     * 文件字节数据
+     */
+    @Excel(name = "文件字节数据")
+    private byte[] fileData;
+
+    /**
+     * 文件下载地址(只有文件形式会有值)
+     */
+    @Excel(name = "文件下载地址(只有文件形式会有值)")
+    private String fileDownloadUrl;
+
+    /**
+     * 创建者编号
+     */
+    @Excel(name = "创建者编号")
+    private Long createById;
+
+    /**
+     * 更新者编号
+     */
+    @Excel(name = "更新者编号")
+    private Long updateById;
+
+    /**
+     * 删除标志(0:否;2:是)
+     */
+    private String delFlag;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getFileGroupKey() {
+        return fileGroupKey;
+    }
+
+    public void setFileGroupKey(String fileGroupKey) {
+        this.fileGroupKey = fileGroupKey;
+    }
+
+    public String getOriginalFileName() {
+        return originalFileName;
+    }
+
+    public void setOriginalFileName(String originalFileName) {
+        this.originalFileName = originalFileName;
+    }
+
+    public String getNewFileName() {
+        return newFileName;
+    }
+
+    public void setNewFileName(String newFileName) {
+        this.newFileName = newFileName;
+    }
+
+    public String getFilePath() {
+        return filePath;
+    }
+
+    public void setFilePath(String filePath) {
+        this.filePath = filePath;
+    }
+
+    public String getFileType() {
+        return fileType;
+    }
+
+    public void setFileType(String fileType) {
+        this.fileType = fileType;
+    }
+
+    public Long getFileSize() {
+        return fileSize;
+    }
+
+    public void setFileSize(Long fileSize) {
+        this.fileSize = fileSize;
+    }
+
+    public String getFileContent() {
+        return fileContent;
+    }
+
+    public void setFileContent(String fileContent) {
+        this.fileContent = fileContent;
+    }
+
+    public byte[] getFileData() {
+        return fileData;
+    }
+
+    public void setFileData(byte[] fileData) {
+        this.fileData = fileData;
+    }
+
+    public String getFileDownloadUrl() {
+        return fileDownloadUrl;
+    }
+
+    public void setFileDownloadUrl(String fileDownloadUrl) {
+        this.fileDownloadUrl = fileDownloadUrl;
+    }
+
+    @Override
+    public Long getCreateById() {
+        return createById;
+    }
+
+    @Override
+    public void setCreateById(Long createById) {
+        this.createById = createById;
+    }
+
+    @Override
+    public Long getUpdateById() {
+        return updateById;
+    }
+
+    @Override
+    public void setUpdateById(Long updateById) {
+        this.updateById = updateById;
+    }
+
+    public String getDelFlag() {
+        return delFlag;
+    }
+
+    public void setDelFlag(String delFlag) {
+        this.delFlag = delFlag;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("FileManagement{");
+        sb.append("id=").append(id);
+        sb.append(", fileGroupKey='").append(fileGroupKey).append('\'');
+        sb.append(", originalFileName='").append(originalFileName).append('\'');
+        sb.append(", newFileName='").append(newFileName).append('\'');
+        sb.append(", filePath='").append(filePath).append('\'');
+        sb.append(", fileType='").append(fileType).append('\'');
+        sb.append(", fileSize=").append(fileSize);
+        sb.append(", fileContent='").append(fileContent).append('\'');
+        sb.append(", fileData=").append(Arrays.toString(fileData));
+        sb.append(", fileDownloadUrl='").append(fileDownloadUrl).append('\'');
+        sb.append(", createById=").append(createById);
+        sb.append(", updateById=").append(updateById);
+        sb.append(", delFlag='").append(delFlag).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    public FileManagement() {
+    }
+
+    public FileManagement(Long id, String fileGroupKey, String originalFileName, String newFileName, String filePath, String fileType, Long fileSize, String fileContent, byte[] fileData, String fileDownloadUrl, Long createById, Long updateById, String delFlag) {
+        this.id = id;
+        this.fileGroupKey = fileGroupKey;
+        this.originalFileName = originalFileName;
+        this.newFileName = newFileName;
+        this.filePath = filePath;
+        this.fileType = fileType;
+        this.fileSize = fileSize;
+        this.fileContent = fileContent;
+        this.fileData = fileData;
+        this.fileDownloadUrl = fileDownloadUrl;
+        this.createById = createById;
+        this.updateById = updateById;
+        this.delFlag = delFlag;
+    }
+}

+ 127 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/MobilePageData.java

@@ -0,0 +1,127 @@
+package com.zkqy.business.entity;
+
+import com.zkqy.common.annotation.Excel;
+import com.zkqy.common.core.domain.BaseEntity;
+
+/**
+ * 移动端数据对象 mobile_page_data
+ * 
+ * @author zkqy
+ * @date 2024-04-18
+ */
+public class MobilePageData extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键 */
+    private Long id;
+
+    /** 名称 */
+    @Excel(name = "名称")
+    private String name;
+
+    /** 模版json */
+    @Excel(name = "模版json")
+    private String pageJson;
+
+    @Excel(name = "是否是首页")
+    private String isIndex;
+
+    @Excel(name = "表单对应数据库字段")
+    private String  fromMapDb;
+
+    @Excel(name = "下拉框对应的数据表")
+    private String  selectQualifiedField;
+
+    @Excel(name = "下拉框数据(1、默认数据 2、动态数据)")
+    private  String selectMapValueList;
+
+    @Excel(name="是否包含列表")
+    private  String  isExistsList;
+
+    public String getIsExistsList() {
+        return isExistsList;
+    }
+
+    public void setIsExistsList(String isExistsList) {
+        this.isExistsList = isExistsList;
+    }
+
+    public MobilePageTableList mobilePageTableList;
+
+
+
+    public MobilePageTableList getMobilePageTableList() {
+        return mobilePageTableList;
+    }
+
+    public void setMobilePageTableList(MobilePageTableList mobilePageTableList) {
+        this.mobilePageTableList = mobilePageTableList;
+    }
+
+    public String getFromMapDb() {
+        return fromMapDb;
+    }
+
+    public void setFromMapDb(String fromMapDb) {
+        this.fromMapDb = fromMapDb;
+    }
+
+    public String getSelectQualifiedField() {
+        return selectQualifiedField;
+    }
+
+    public void setSelectQualifiedField(String selectQualifiedField) {
+        this.selectQualifiedField = selectQualifiedField;
+    }
+
+    public String getSelectMapValueList() {
+        return selectMapValueList;
+    }
+
+    public void setSelectMapValueList(String selectMapValueList) {
+        this.selectMapValueList = selectMapValueList;
+    }
+
+    public String getIsIndex() {
+        return isIndex;
+    }
+
+    public void setIsIndex(String isIndex) {
+        this.isIndex = isIndex;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPageJson() {
+        return pageJson;
+    }
+
+    public void setPageJson(String pageJson) {
+        this.pageJson = pageJson;
+    }
+
+    @Override
+    public String toString() {
+        return "MobilePageData{" +
+                "id=" + id +
+                ", name='" + name + '\'' +
+                ", pageJson='" + pageJson + '\'' +
+                ", isIndex='" + isIndex + '\'' +
+                '}';
+    }
+}

+ 214 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/MobilePageTableList.java

@@ -0,0 +1,214 @@
+package com.zkqy.business.entity;
+
+import com.zkqy.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.zkqy.common.annotation.Excel;
+
+/**
+ * 页面列表对象 mobile_page_table_list
+ * 
+ * @author zkqy
+ * @date 2024-05-21
+ */
+public class MobilePageTableList extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 主键自增 */
+    private Long id;
+
+    /** 页面id */
+    @Excel(name = "页面id")
+    private Long pageId;
+
+    /** 中文表名称 */
+    @Excel(name = "中文表名称")
+    private String tableNameDes;
+
+    /** 0:单表,1:多表 */
+    @Excel(name = "0:单表,1:多表")
+    private String isSingleTable;
+
+    /** 表名称集合 */
+    @Excel(name = "表名称集合")
+    private String tableNames;
+
+    /** 列表展示字段信息及属性 */
+    @Excel(name = "列表展示字段信息及属性")
+    private String tableColumnName;
+
+    /** 展示描述 */
+    @Excel(name = "展示描述")
+    private String tableColumnDesc;
+
+    /** 表的连接关系 */
+    @Excel(name = "表的连接关系")
+    private String tableJoin;
+
+    /** 表的查询条件 */
+    @Excel(name = "表的查询条件")
+    private String tableQueryConditions;
+
+    /** 时间范围查询 */
+    @Excel(name = "时间范围查询")
+    private String timeRangeFilters;
+
+    /** 数据排序查询 */
+    @Excel(name = "数据排序查询")
+    private String tablelistSort;
+
+    /** 列表映射数据 */
+    @Excel(name = "列表映射数据")
+    private String listMapValue;
+
+    /** 拓展字段 */
+    @Excel(name = "拓展字段")
+    private String extensions;
+
+
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+    public void setPageId(Long pageId) 
+    {
+        this.pageId = pageId;
+    }
+
+    public Long getPageId() 
+    {
+        return pageId;
+    }
+    public void setTableNameDes(String tableNameDes) 
+    {
+        this.tableNameDes = tableNameDes;
+    }
+
+    public String getTableNameDes() 
+    {
+        return tableNameDes;
+    }
+    public void setIsSingleTable(String isSingleTable) 
+    {
+        this.isSingleTable = isSingleTable;
+    }
+
+    public String getIsSingleTable() 
+    {
+        return isSingleTable;
+    }
+    public void setTableNames(String tableNames) 
+    {
+        this.tableNames = tableNames;
+    }
+
+    public String getTableNames() 
+    {
+        return tableNames;
+    }
+    public void setTableColumnName(String tableColumnName) 
+    {
+        this.tableColumnName = tableColumnName;
+    }
+
+    public String getTableColumnName() 
+    {
+        return tableColumnName;
+    }
+    public void setTableColumnDesc(String tableColumnDesc) 
+    {
+        this.tableColumnDesc = tableColumnDesc;
+    }
+
+    public String getTableColumnDesc() 
+    {
+        return tableColumnDesc;
+    }
+    public void setTableJoin(String tableJoin) 
+    {
+        this.tableJoin = tableJoin;
+    }
+
+    public String getTableJoin() 
+    {
+        return tableJoin;
+    }
+    public void setTableQueryConditions(String tableQueryConditions) 
+    {
+        this.tableQueryConditions = tableQueryConditions;
+    }
+
+    public String getTableQueryConditions() 
+    {
+        return tableQueryConditions;
+    }
+    public void setTimeRangeFilters(String timeRangeFilters) 
+    {
+        this.timeRangeFilters = timeRangeFilters;
+    }
+
+    public String getTimeRangeFilters() 
+    {
+        return timeRangeFilters;
+    }
+    public void setTablelistSort(String tablelistSort) 
+    {
+        this.tablelistSort = tablelistSort;
+    }
+
+    public String getTablelistSort() 
+    {
+        return tablelistSort;
+    }
+    public void setListMapValue(String listMapValue) 
+    {
+        this.listMapValue = listMapValue;
+    }
+
+    public String getListMapValue() 
+    {
+        return listMapValue;
+    }
+    public void setExtensions(String extensions) 
+    {
+        this.extensions = extensions;
+    }
+
+    public String getExtensions() 
+    {
+        return extensions;
+    }
+
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("pageId", getPageId())
+            .append("tableNameDes", getTableNameDes())
+            .append("isSingleTable", getIsSingleTable())
+            .append("tableNames", getTableNames())
+            .append("tableColumnName", getTableColumnName())
+            .append("tableColumnDesc", getTableColumnDesc())
+            .append("tableJoin", getTableJoin())
+            .append("tableQueryConditions", getTableQueryConditions())
+            .append("timeRangeFilters", getTimeRangeFilters())
+            .append("tablelistSort", getTablelistSort())
+            .append("listMapValue", getListMapValue())
+            .append("extensions", getExtensions())
+            .append("createTime", getCreateTime())
+            .append("createById", getCreateById())
+            .append("createBy", getCreateBy())
+            .append("updateBy", getUpdateBy())
+            .append("updateById", getUpdateById())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 113 - 0
zkqy-business/src/main/java/com/zkqy/business/entity/TableInfo.java

@@ -0,0 +1,113 @@
+package com.zkqy.business.entity;
+
+
+
+/**
+ * 表字段信息表
+ */
+
+public class TableInfo {
+
+    /** 字段名称 */
+    private String fieldName;
+
+    /** 字段类型 */
+    private String fieldType;
+
+    /** 是否为空 */
+    private Boolean isNull;
+
+    /** 是否为主键 */
+    private Boolean isPrimary;
+
+    /** 自增 */
+    private Boolean isAuto;
+
+    /** 字段描述 */
+    private String fieldDescription;
+
+    /** 字段长度 */
+    private Long fieldLength;
+
+    public TableInfo() {
+    }
+
+    @Override
+    public String toString() {
+        return "TableInfo{" +
+                "fieldName='" + fieldName + '\'' +
+                ", fieldType='" + fieldType + '\'' +
+                ", isNull=" + isNull +
+                ", isPrimary=" + isPrimary +
+                ", isAuto=" + isAuto +
+                ", fieldDescription='" + fieldDescription + '\'' +
+                ", fieldLength=" + fieldLength +
+                '}';
+    }
+
+    public String getFieldName() {
+        return fieldName;
+    }
+
+    public void setFieldName(String fieldName) {
+        this.fieldName = fieldName;
+    }
+
+    public String getFieldType() {
+        return fieldType;
+    }
+
+    public void setFieldType(String fieldType) {
+        this.fieldType = fieldType;
+    }
+
+    public Boolean getNull() {
+        return isNull;
+    }
+
+    public void setNull(Boolean aNull) {
+        isNull = aNull;
+    }
+
+    public Boolean getPrimary() {
+        return isPrimary;
+    }
+
+    public void setPrimary(Boolean primary) {
+        isPrimary = primary;
+    }
+
+    public Boolean getAuto() {
+        return isAuto;
+    }
+
+    public void setAuto(Boolean auto) {
+        isAuto = auto;
+    }
+
+    public String getFieldDescription() {
+        return fieldDescription;
+    }
+
+    public void setFieldDescription(String fieldDescription) {
+        this.fieldDescription = fieldDescription;
+    }
+
+    public Long getFieldLength() {
+        return fieldLength;
+    }
+
+    public void setFieldLength(Long fieldLength) {
+        this.fieldLength = fieldLength;
+    }
+
+    public TableInfo(String fieldName, String fieldType, Boolean isNull, Boolean isPrimary, Boolean isAuto, String fieldDescription, Long fieldLength) {
+        this.fieldName = fieldName;
+        this.fieldType = fieldType;
+        this.isNull = isNull;
+        this.isPrimary = isPrimary;
+        this.isAuto = isAuto;
+        this.fieldDescription = fieldDescription;
+        this.fieldLength = fieldLength;
+    }
+}

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels