Explorar el Código

项目初始化

user5 hace 1 año
commit
faa5c4a107
Se han modificado 100 ficheros con 9315 adiciones y 0 borrados
  1. 1647 0
      .idea/workspace.xml
  2. 40 0
      jeeplus-api/jeeplus-api.iml
  3. 186 0
      jeeplus-api/jeeplus-file-api/jeeplus-file-api.iml
  4. 21 0
      jeeplus-api/jeeplus-file-api/pom.xml
  5. 39 0
      jeeplus-api/jeeplus-file-api/src/main/java/com/jeeplus/common/factory/FileApiFallbackFactory.java
  6. 37 0
      jeeplus-api/jeeplus-file-api/src/main/java/com/jeeplus/common/feign/IFileApi.java
  7. 191 0
      jeeplus-api/jeeplus-public-modules-api/jeeplus-public-modules-api.iml
  8. 27 0
      jeeplus-api/jeeplus-public-modules-api/pom.xml
  9. 90 0
      jeeplus-api/jeeplus-public-modules-api/src/main/java/com/jeeplus/sys/domain/WorkAttachmentInfo.java
  10. 131 0
      jeeplus-api/jeeplus-public-modules-api/src/main/java/com/jeeplus/sys/factory/WorkAttachmentApiFallbackFactory.java
  11. 195 0
      jeeplus-api/jeeplus-public-modules-api/src/main/java/com/jeeplus/sys/feign/IWorkAttachmentApi.java
  12. 82 0
      jeeplus-api/jeeplus-public-modules-api/src/main/java/com/jeeplus/sys/service/dto/WorkAttachmentInfoDTO.java
  13. 190 0
      jeeplus-api/jeeplus-system-api/jeeplus-system-api.iml
  14. 32 0
      jeeplus-api/jeeplus-system-api/pom.xml
  15. 45 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/excel/converter/ExcelDictDTOConverter.java
  16. 54 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/excel/converter/ExcelOfficeDTOConverter.java
  17. 60 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/excel/converter/ExcelPostListDTOConverter.java
  18. 60 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/excel/converter/ExcelRoleListDTOConverter.java
  19. 54 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/excel/converter/ExcelUserDTOConverter.java
  20. 138 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/service/TreeDTOService.java
  21. 260 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/service/TreeService.java
  22. 103 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/service/dto/BaseDTO.java
  23. 103 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/service/dto/TreeDTO.java
  24. 33 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/factory/AssessApiFallbackFactory.java
  25. 47 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/factory/FinanceApiFallbackFactory.java
  26. 117 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/factory/FlowableApiFallbackFactory.java
  27. 51 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/factory/HumanApiFallBackFactory.java
  28. 33 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/feign/IAssessApi.java
  29. 32 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/feign/IFinanceApi.java
  30. 119 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/feign/IFlowableApi.java
  31. 50 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/feign/IHumanApi.java
  32. 30 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/mail/factory/MailApiFallbackFactory.java
  33. 23 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/mail/feign/IMailApi.java
  34. 73 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/Cert.java
  35. 71 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/DataRule.java
  36. 105 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/Log.java
  37. 103 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/Office.java
  38. 53 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/Role.java
  39. 68 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/Tenant.java
  40. 134 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/User.java
  41. 29 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/ConfigApiFallbackFactory.java
  42. 40 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/DictApiFallbackFactory.java
  43. 29 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/LogApiFallbackFactory.java
  44. 62 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/OfficeApiFallbackFactory.java
  45. 35 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/PostApiFallbackFactory.java
  46. 48 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/RoleApiFallbackFactory.java
  47. 29 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/TenantApiFallbackFactory.java
  48. 215 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/UserApiFallbackFactory.java
  49. 20 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/IConfigApi.java
  50. 40 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/IDictApi.java
  51. 18 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/ILogApi.java
  52. 69 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/IOfficeApi.java
  53. 27 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/IPostApi.java
  54. 44 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/IRoleApi.java
  55. 18 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/ITenantApi.java
  56. 310 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/IUserApi.java
  57. 41 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/AreaDTO.java
  58. 88 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/CertDTO.java
  59. 77 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/DataRuleDTO.java
  60. 39 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/DictTypeInfoDTO.java
  61. 57 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/DictValueInfoDTO.java
  62. 109 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/MenuDTO.java
  63. 114 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/OfficeDTO.java
  64. 65 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/PostDTO.java
  65. 166 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/RoleDTO.java
  66. 52 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/TenantDTO.java
  67. 377 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/UserDTO.java
  68. 21 0
      jeeplus-api/pom.xml
  69. 264 0
      jeeplus-auth/jeeplus-auth.iml
  70. 102 0
      jeeplus-auth/pom.xml
  71. 34 0
      jeeplus-auth/src/main/java/com/jeeplus/auth/JeeplusAuthApplication.java
  72. 289 0
      jeeplus-auth/src/main/java/com/jeeplus/auth/controller/LoginController.java
  73. 23 0
      jeeplus-auth/src/main/java/com/jeeplus/auth/controller/app/AppLoginController.java
  74. 34 0
      jeeplus-auth/src/main/java/com/jeeplus/auth/model/LoginForm.java
  75. 57 0
      jeeplus-auth/src/main/resources/bootstrap.yml
  76. 185 0
      jeeplus-common/jeeplus-common-core/jeeplus-common-core.iml
  77. 201 0
      jeeplus-common/jeeplus-common-core/pom.xml
  78. 80 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/aop/demo/DemoAspect.java
  79. 12 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/aop/demo/annotation/DemoMode.java
  80. 20 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/aop/demo/config/DemoAspectConfiguration.java
  81. 8 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/aop/demo/exception/DemoException.java
  82. 125 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/beanvalidator/BeanValidators.java
  83. 36 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/AppNameConstants.java
  84. 51 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/CacheNames.java
  85. 38 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/CommonConstants.java
  86. 14 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/ErrorConstants.java
  87. 43 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/enums/MenuTypeEnum.java
  88. 38 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/enums/OfficeTypeEnum.java
  89. 25 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/converter/StringToDateConverter.java
  90. 70 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/converter/mapper/JsonMapper.java
  91. 98 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/EasyExcelUtils.java
  92. 63 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/ExcelFieldDTOConverter.java
  93. 107 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/ExcelListener.java
  94. 32 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/ExcelOptions.java
  95. 7 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/ExportMode.java
  96. 11 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/annotation/ExcelDictProperty.java
  97. 15 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/annotation/ExcelFieldProperty.java
  98. 7 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/annotation/ExportMode.java
  99. 60 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/redis/RedisConfig.java
  100. 0 0
      jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/redis/RedisUtils.java

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1647 - 0
.idea/workspace.xml


+ 40 - 0
jeeplus-api/jeeplus-api.iml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.13.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.13.3" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.27" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.4.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.9.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.64" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.64" level="project" />
+    <orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.4.2.Final" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.mapstruct:mapstruct-processor:1.4.2.Final" level="project" />
+  </component>
+</module>

+ 186 - 0
jeeplus-api/jeeplus-file-api/jeeplus-file-api.iml

@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" generated="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="jeeplus-common-core" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.13.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.13.3" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.27" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.0.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.6" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.4.5" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign:feign-core:10.10.1" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:10.10.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.6" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish:jakarta.el:3.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.1.7.Final" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel-core:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel-support:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
+    <orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
+    <orderEntry type="library" name="Maven: org.ehcache:ehcache:3.9.2" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish.jaxb:jaxb-runtime:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish.jaxb:txw2:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: com.sun.istack:istack-commons-runtime:3.0.11" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.microsoft.sqlserver:mssql-jdbc:8.4.1.jre8" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.jtds:jtds:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: mysql:mysql-connector-java:8.0.23" level="project" />
+    <orderEntry type="library" name="Maven: org.postgresql:postgresql:42.2.19" level="project" />
+    <orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.5.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.2.8" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid:1.2.8" level="project" />
+    <orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-dbcp:commons-dbcp:1.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-pool:commons-pool:1.6" level="project" />
+    <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.4.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
+    <orderEntry type="library" name="Maven: org.jeeplus:ddlutils:1.3" level="project" />
+    <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.7.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging-api:1.0.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.0.4" level="project" />
+    <orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ant:ant:1.9.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ant:ant-launcher:1.9.4" level="project" />
+    <orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.13" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:29.0-jre" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
+    <orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.11" level="project" />
+    <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-boot-starter:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-oas:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger.core.v3:swagger-annotations:2.1.2" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger.core.v3:swagger-models:2.1.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spi:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-schema:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-core:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.22" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.github.classgraph:classgraph:4.8.83" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-webmvc:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-webflux:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-data-rest:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:2.0.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:2.0.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.json-lib:json-lib:jdk15:2.4" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.ezmorph:ezmorph:1.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: p6spy:p6spy:3.9.1" level="project" />
+    <orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.18" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-core:4.5.25" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.6" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.13" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.14" level="project" />
+    <orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
+    <orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
+    <orderEntry type="library" name="Maven: org.jacoco:org.jacoco.agent:runtime:0.8.7" level="project" />
+    <orderEntry type="library" name="Maven: org.ini4j:ini4j:0.5.4" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-api:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-util:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-noop:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-dysmsapi:2.1.0" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.9.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.64" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.64" level="project" />
+    <orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.4.2.Final" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.mapstruct:mapstruct-processor:1.4.2.Final" level="project" />
+  </component>
+</module>

+ 21 - 0
jeeplus-api/jeeplus-file-api/pom.xml

@@ -0,0 +1,21 @@
+<?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>jeeplus-api</artifactId>
+        <groupId>org.jeeplus</groupId>
+        <version>9.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jeeplus-file-api</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.jeeplus</groupId>
+            <artifactId>jeeplus-common-core</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+    </dependencies>
+</project>

+ 39 - 0
jeeplus-api/jeeplus-file-api/src/main/java/com/jeeplus/common/factory/FileApiFallbackFactory.java

@@ -0,0 +1,39 @@
+package com.jeeplus.common.factory;
+
+import com.jeeplus.common.feign.IFileApi;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 文件服务降级处理
+ *
+ * @author jeeplus
+ */
+
+@Slf4j
+@Component
+public class FileApiFallbackFactory implements FallbackFactory <IFileApi> {
+    @Override
+    public IFileApi create(Throwable throwable) {
+        log.error ( "文件服务调用失败:{}", throwable.getMessage ( ) );
+        throwable.printStackTrace ( );
+        return new IFileApi ( ) {
+
+            @Override
+            public void download(String uploadPath, String name, HttpServletResponse response) throws Exception {
+
+            }
+
+            @Override
+            public ResponseEntity upload(HttpServletRequest request, MultipartFile file) {
+                return null;
+            }
+        };
+    }
+}

+ 37 - 0
jeeplus-api/jeeplus-file-api/src/main/java/com/jeeplus/common/feign/IFileApi.java

@@ -0,0 +1,37 @@
+package com.jeeplus.common.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.common.factory.FileApiFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+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.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@FeignClient(contextId = "fileApi", name = AppNameConstants.APP_FILE_SERVICE, fallbackFactory = FileApiFallbackFactory.class)
+public interface IFileApi {
+
+    /**
+     * 获取文件网络地址
+     *
+     * @return
+     * @throws IOException
+     * @throws IllegalStateException
+     */
+    @GetMapping("/file/download")
+    void download(@RequestParam("uploadPath") String uploadPath, @RequestParam(value = "name", required = false) String name, @RequestParam(value = "response", required = false) HttpServletResponse response) throws Exception;
+
+    /**
+     * 上传文件
+     *
+     * @return
+     * @throws IOException
+     */
+    @RequestMapping("/file/upload")
+    ResponseEntity upload(@RequestParam(value = "request", required = false) HttpServletRequest request, @RequestParam(value = "file", required = false) MultipartFile file);
+}

+ 191 - 0
jeeplus-api/jeeplus-public-modules-api/jeeplus-public-modules-api.iml

@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" generated="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="jeeplus-common-core" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.13.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.13.3" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.27" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.0.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.6" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.4.5" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign:feign-core:10.10.1" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:10.10.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.6" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish:jakarta.el:3.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.1.7.Final" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel-core:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel-support:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
+    <orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
+    <orderEntry type="library" name="Maven: org.ehcache:ehcache:3.9.2" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish.jaxb:jaxb-runtime:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish.jaxb:txw2:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: com.sun.istack:istack-commons-runtime:3.0.11" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.microsoft.sqlserver:mssql-jdbc:8.4.1.jre8" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.jtds:jtds:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: mysql:mysql-connector-java:8.0.23" level="project" />
+    <orderEntry type="library" name="Maven: org.postgresql:postgresql:42.2.19" level="project" />
+    <orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.5.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.2.8" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid:1.2.8" level="project" />
+    <orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-dbcp:commons-dbcp:1.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-pool:commons-pool:1.6" level="project" />
+    <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.4.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
+    <orderEntry type="library" name="Maven: org.jeeplus:ddlutils:1.3" level="project" />
+    <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.7.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging-api:1.0.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.0.4" level="project" />
+    <orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ant:ant:1.9.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ant:ant-launcher:1.9.4" level="project" />
+    <orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.13" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:29.0-jre" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
+    <orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.11" level="project" />
+    <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-boot-starter:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-oas:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger.core.v3:swagger-annotations:2.1.2" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger.core.v3:swagger-models:2.1.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spi:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-schema:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-core:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.22" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.github.classgraph:classgraph:4.8.83" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-webmvc:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-webflux:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-data-rest:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:2.0.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:2.0.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.json-lib:json-lib:jdk15:2.4" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.ezmorph:ezmorph:1.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: p6spy:p6spy:3.9.1" level="project" />
+    <orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.18" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-core:4.5.25" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.6" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.13" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.14" level="project" />
+    <orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
+    <orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
+    <orderEntry type="library" name="Maven: org.jacoco:org.jacoco.agent:runtime:0.8.7" level="project" />
+    <orderEntry type="library" name="Maven: org.ini4j:ini4j:0.5.4" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-api:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-util:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-noop:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-dysmsapi:2.1.0" level="project" />
+    <orderEntry type="module" module-name="jeeplus-system-api" />
+    <orderEntry type="library" name="Maven: org.flowable:flowable-json-converter:6.7.2" level="project" />
+    <orderEntry type="library" name="Maven: org.flowable:flowable-bpmn-model:6.7.2" level="project" />
+    <orderEntry type="library" name="Maven: joda-time:joda-time:2.10.10" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.30" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.9.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.64" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.64" level="project" />
+    <orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.4.2.Final" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.mapstruct:mapstruct-processor:1.4.2.Final" level="project" />
+  </component>
+</module>

+ 27 - 0
jeeplus-api/jeeplus-public-modules-api/pom.xml

@@ -0,0 +1,27 @@
+<?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>jeeplus-api</artifactId>
+        <groupId>org.jeeplus</groupId>
+        <version>9.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jeeplus-public-modules-api</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.jeeplus</groupId>
+            <artifactId>jeeplus-common-core</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jeeplus</groupId>
+            <artifactId>jeeplus-system-api</artifactId>
+            <version>9.0</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+</project>

+ 90 - 0
jeeplus-api/jeeplus-public-modules-api/src/main/java/com/jeeplus/sys/domain/WorkAttachmentInfo.java

@@ -0,0 +1,90 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jeeplus.core.domain.BaseEntity;
+import com.jeeplus.sys.service.dto.UserDTO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 用户Entity
+ *
+ * @author jeeplus
+ * @version 2021-12-05
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("work_attachment")
+public class WorkAttachmentInfo extends BaseEntity {
+
+    private String by;
+
+    private UserDTO createBy;
+
+    private String name;
+
+    private String size;
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 附件地址
+     */
+    private String url;
+
+    /**
+     * 文件类型(文件后缀名)
+     */
+    private String type;
+
+    /**
+     * 附件对应父节点id(记录是谁的id)
+     */
+    private String attachmentId;
+
+    /**
+     * 文件名
+     */
+    private String attachmentName;
+
+    /**
+     * 文件所属业务模块(数据字典配置)
+     */
+    private String attachmentFlag;
+
+    /**
+     * 所属模块子模块
+     */
+    private String moduleType;
+
+    /**
+     * 附件类型
+     */
+    private String attachmentType;
+
+    /**
+     * 附件大小
+     */
+    private String fileSize;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 文件描述
+     */
+    private String description;
+
+    /**
+     * 附件临时地址
+     *该属性不是实体字段
+     */
+    @TableField(exist = false)
+    private String temporaryUrl;
+}

+ 131 - 0
jeeplus-api/jeeplus-public-modules-api/src/main/java/com/jeeplus/sys/factory/WorkAttachmentApiFallbackFactory.java

@@ -0,0 +1,131 @@
+package com.jeeplus.sys.factory;
+
+import com.jeeplus.sys.domain.WorkAttachmentInfo;
+import com.jeeplus.sys.feign.IWorkAttachmentApi;
+import com.jeeplus.sys.service.dto.WorkAttachmentInfoDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 用户服务降级处理
+ *
+ * @author jeeplus
+ */
+@Slf4j
+@Component
+public class WorkAttachmentApiFallbackFactory implements FallbackFactory <IWorkAttachmentApi> {
+    @Override
+    public IWorkAttachmentApi create(Throwable throwable) {
+        log.error ( "附件服务调用失败:{}", throwable.getMessage ( ) );
+        throwable.printStackTrace ( );
+        return new IWorkAttachmentApi( ) {
+
+            @Override
+            public List<WorkAttachmentInfo> selectWorkAttachmentByAttachmentId(String id) {
+                return null;
+            }
+
+            @Override
+            public void insertWorkAttachment(Map<String, String> map) {
+
+            }
+
+            @Override
+            public void deleteById(String id) {
+
+            }
+
+            @Override
+            public void deleteByAttachmentId(String attachmentId) {
+
+            }
+
+            @Override
+            public void deleteByAttachmentIdNotInIds(String attachmentId, List<String> delIds) {
+
+            }
+
+            @Override
+            public void saveOrUpdateFileListFlag(Map<String, String> map) {
+
+            }
+
+            @Override
+            public void saveOrUpdateFileList(Map<String, String> map) {
+
+            }
+
+            @Override
+            public List<WorkAttachmentInfo> selectListByAttachmentId(String attachmentId) {
+                return null;
+            }
+
+            @Override
+            public void deleteByIds(String ids) {
+
+            }
+
+            @Override
+            public String saveFile(Map<String, String> map) {
+                return null;
+            }
+
+            @Override
+            public void downByStreamSaveLocal(String key, String fileName, String downFileStr) {
+
+            }
+
+            @Override
+            public String genSerialNum(String companyId, String bizCode,String currentToken) {
+                return null;
+            }
+
+            @Override
+            public String genSerialNumNoSort(String companyId, String bizCode,String currentToken) throws Exception {
+                return null;
+            }
+
+            @Override
+            public String genSerialReviewNum(String companyId, String bizCode, String currentToken) throws Exception {
+                return null;
+            }
+
+            @Override
+            public List<WorkAttachmentInfo> getByAttachmentIdAndUrlAndAttachmentFlag(WorkAttachmentInfo workattachment) {
+                return null;
+            }
+
+            @Override
+            public void downQzByStreamSaveLocal(String key, String fileName, String downFileStr) {
+
+            }
+
+            @Override
+            public String datePath() {
+                return null;
+            }
+
+            @Override
+            public String uploadFile2OSS(InputStream inStream, String fileDir, String fileName) {
+                return null;
+            }
+            @Override
+            public String uploadFileSignatureOSS(String filePath, String fileDir, String fileName) {
+                return null;
+            }
+
+            @Override
+            public void saveMsg2(Map<String, String> map) {
+
+            }
+
+        };
+    }
+}

+ 195 - 0
jeeplus-api/jeeplus-public-modules-api/src/main/java/com/jeeplus/sys/feign/IWorkAttachmentApi.java

@@ -0,0 +1,195 @@
+package com.jeeplus.sys.feign;
+
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.sys.domain.WorkAttachmentInfo;
+import com.jeeplus.sys.factory.WorkAttachmentApiFallbackFactory;
+import com.jeeplus.sys.service.dto.UserDTO;
+import com.jeeplus.sys.service.dto.WorkAttachmentInfoDTO;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+
+@FeignClient(contextId = "workAttachmentApi", name = AppNameConstants.APP_PUBLIC_MODULES, fallbackFactory = WorkAttachmentApiFallbackFactory.class)
+public interface IWorkAttachmentApi {
+
+
+    /**
+     * 查询电子章文件信息
+     * @param id
+     * @return
+     */
+    @PostMapping("/oss/file/selectWorkAttachmentByAttachmentId")
+    List<WorkAttachmentInfo> selectWorkAttachmentByAttachmentId(@RequestParam(value = "id")String id);
+
+    /**
+     * 财务模块保存附件使用
+     * @param map
+     */
+    @RequestMapping(value = "/oss/file/financeFileSave", method = RequestMethod.POST)
+    void insertWorkAttachment (@RequestBody Map<String ,String > map);
+
+    /**
+     * 财务模块使用,根据id删除附件
+     * @param id
+     */
+    @GetMapping("/oss/file/deleteById")
+    void deleteById(@RequestParam(value = "id")String id);
+
+    /**
+     * 财务模块使用,根据attachmentId删除附件
+     * @param attachmentId
+     */
+    @GetMapping("/oss/file/deleteByAttachmentId")
+    void deleteByAttachmentId(@RequestParam(value = "attachmentId")String attachmentId);
+
+    @RequestMapping(value = "/oss/file/deleteByAttachmentIdNotInIds", method = RequestMethod.POST)
+    void deleteByAttachmentIdNotInIds(@RequestParam(value = "attachmentId")String attachmentId,
+                                      @RequestParam(value = "delIds")List<String> delIds);
+
+    /**
+     * 保存/修改附件
+     * @param map
+     */
+    @RequestMapping(value = "/oss/file/saveOrUpdateFileListFlag", method = RequestMethod.POST)
+    void saveOrUpdateFileListFlag(@RequestBody Map<String ,String > map);
+
+    /**
+     * 保存附件信息
+     * @param map
+     */
+    @RequestMapping(value = "/oss/file/saveOrUpdateFileList", method = RequestMethod.POST)
+    void saveOrUpdateFileList(@RequestBody Map<String ,String > map);
+
+    /**
+     * 根据attachmentId查询附件信息
+     * @param attachmentId
+     * @return
+     */
+    @PostMapping("/oss/file/selectListByAttachmentId")
+    List<WorkAttachmentInfo> selectListByAttachmentId(@RequestParam(value = "attachmentId")String attachmentId);
+
+    /**
+     * 财务模块使用,根据attachmentId删除附件
+     * @param ids
+     */
+    @RequestMapping(value = "/oss/file/deleteByIds", method = RequestMethod.POST)
+    void deleteByIds(@RequestBody String ids);
+
+    /**
+     * 保存附件信息
+     * @param map
+     */
+    @RequestMapping(value = "/oss/file/saveFile", method = RequestMethod.POST)
+    String saveFile(@RequestBody Map<String ,String > map);
+
+    /**
+     * 附件下载到本地指定文件夹
+     * @param key
+     * @param fileName
+     * @param downFileStr
+     */
+    @RequestMapping(value = "/oss/file/downByStreamSaveLocal", method = RequestMethod.POST)
+    void downByStreamSaveLocal(@RequestParam(value = "key")String key,
+                               @RequestParam(value = "fileName")String fileName,
+                               @RequestParam(value = "downFileStr")String downFileStr);
+
+    /**
+     * 获取编号模板编号
+     * @param companyId
+     * @param bizCode
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "/oss/file/genSerialNum", method = RequestMethod.POST)
+    String genSerialNum(@RequestParam(value = "companyId")String companyId,
+                               @RequestParam(value = "bizCode")String bizCode,
+                               @RequestParam(value = "currentToken")String currentToken
+                        ) throws Exception;
+
+    /**
+     * 获取编号模板报告编号
+     * @param companyId
+     * @param bizCode
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "/oss/file/genSerialNumNoSort", method = RequestMethod.POST)
+    String genSerialNumNoSort(@RequestParam(value = "companyId")String companyId,
+                              @RequestParam(value = "bizCode")String bizCode,
+                              @RequestParam(value = "currentToken")String currentToken
+                        ) throws Exception;
+
+    /**
+     * 获取编号模板报告编号
+     * @param companyId
+     * @param bizCode
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "/oss/file/genSerialReviewNum", method = RequestMethod.POST)
+    String genSerialReviewNum(@RequestParam(value = "companyId")String companyId,
+                              @RequestParam(value = "bizCode")String bizCode,
+                              @RequestParam(value = "currentToken")String currentToken
+    ) throws Exception;
+
+    /**
+     * 根据关联id和url查询数据信息
+     * @param workattachment
+     * @return
+     */
+    @RequestMapping(value = "/oss/file/getByAttachmentIdAndUrlAndAttachmentFlag", method = RequestMethod.POST)
+    List<WorkAttachmentInfo> getByAttachmentIdAndUrlAndAttachmentFlag(@RequestBody WorkAttachmentInfo workattachment);
+
+    /**
+     * 附件下载到本地指定文件夹(签章系统)
+     * @param key
+     * @param fileName
+     * @param downFileStr
+     */
+    @RequestMapping(value = "/oss/file/downQzByStreamSaveLocal", method = RequestMethod.POST)
+    void downQzByStreamSaveLocal(@RequestParam(value = "key")String key,
+                                 @RequestParam(value = "fileName")String fileName,
+                                 @RequestParam(value = "downFileStr")String downFileStr);
+
+    @PostMapping("/oss/file/datePath")
+    String datePath();
+
+    /**
+     * 上传到OSS服务器  如果同名文件会覆盖服务器上的
+     * @param inStream
+     * @param fileDir
+     * @param fileName
+     * @return
+     */
+    @RequestMapping(value = "/oss/file/uploadFile2OSS", method = RequestMethod.POST)
+    String uploadFile2OSS(@RequestParam(value = "inStream")InputStream inStream,
+                          @RequestParam(value = "fileDir")String fileDir,
+                          @RequestParam(value = "fileName")String fileName);
+
+    /**
+     * 上传到OSS服务器  如果同名文件会覆盖服务器上的(签章文件上传)
+     * @param filePath
+     * @param fileDir
+     * @param fileName
+     * @return
+     */
+    @RequestMapping(value = "/oss/file/uploadFileSignatureOSS", method = RequestMethod.POST)
+    String uploadFileSignatureOSS(@RequestParam(value = "filePath")String filePath,
+                          @RequestParam(value = "fileDir")String fileDir,
+                          @RequestParam(value = "fileName")String fileName);
+
+    /**
+     * 保存附件信息
+     * @param map
+     */
+    @RequestMapping(value = "/oss/file/saveMsg2", method = RequestMethod.POST)
+    void saveMsg2(@RequestBody Map<String ,String > map);
+}
+
+

+ 82 - 0
jeeplus-api/jeeplus-public-modules-api/src/main/java/com/jeeplus/sys/service/dto/WorkAttachmentInfoDTO.java

@@ -0,0 +1,82 @@
+package com.jeeplus.sys.service.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.jeeplus.core.service.dto.BaseDTO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author: 徐滕
+ * @version: 2023-07-10 09:20
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class WorkAttachmentInfoDTO extends BaseDTO {
+
+    private String name;
+
+    private String size;
+
+    private String by;
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 附件地址
+     */
+    private String url;
+
+    /**
+     * 文件类型(文件后缀名)
+     */
+    private String type;
+
+    /**
+     * 附件对应父节点id(记录是谁的id)
+     */
+    private String attachmentId;
+
+    /**
+     * 文件名
+     */
+    private String attachmentName;
+
+    /**
+     * 文件所属业务模块(数据字典配置)
+     */
+    private String attachmentFlag;
+
+    /**
+     * 所属模块子模块
+     */
+    private String moduleType;
+
+    /**
+     * 附件类型
+     */
+    private String attachmentType;
+
+    /**
+     * 附件大小
+     */
+    private String fileSize;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 文件描述
+     */
+    private String description;
+
+    /**
+     * 附件临时地址
+     *该属性不是实体字段
+     */
+    @TableField(exist = false)
+    private String temporaryUrl;
+
+
+}

+ 190 - 0
jeeplus-api/jeeplus-system-api/jeeplus-system-api.iml

@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" generated="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="jeeplus-common-core" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.13.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.13.3" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.27" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.0.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.6" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.4.5" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign:feign-core:10.10.1" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:10.10.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.6" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish:jakarta.el:3.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.1.7.Final" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel-core:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel-support:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
+    <orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
+    <orderEntry type="library" name="Maven: org.ehcache:ehcache:3.9.2" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish.jaxb:jaxb-runtime:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish.jaxb:txw2:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: com.sun.istack:istack-commons-runtime:3.0.11" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.microsoft.sqlserver:mssql-jdbc:8.4.1.jre8" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.jtds:jtds:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: mysql:mysql-connector-java:8.0.23" level="project" />
+    <orderEntry type="library" name="Maven: org.postgresql:postgresql:42.2.19" level="project" />
+    <orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.5.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.2.8" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid:1.2.8" level="project" />
+    <orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-dbcp:commons-dbcp:1.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-pool:commons-pool:1.6" level="project" />
+    <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.4.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
+    <orderEntry type="library" name="Maven: org.jeeplus:ddlutils:1.3" level="project" />
+    <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.7.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging-api:1.0.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.0.4" level="project" />
+    <orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ant:ant:1.9.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ant:ant-launcher:1.9.4" level="project" />
+    <orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.13" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:29.0-jre" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
+    <orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.11" level="project" />
+    <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-boot-starter:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-oas:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger.core.v3:swagger-annotations:2.1.2" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger.core.v3:swagger-models:2.1.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spi:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-schema:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-core:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.22" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.github.classgraph:classgraph:4.8.83" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-webmvc:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-webflux:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-data-rest:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:2.0.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:2.0.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.json-lib:json-lib:jdk15:2.4" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.ezmorph:ezmorph:1.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: p6spy:p6spy:3.9.1" level="project" />
+    <orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.18" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-core:4.5.25" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.6" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.13" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.14" level="project" />
+    <orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
+    <orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
+    <orderEntry type="library" name="Maven: org.jacoco:org.jacoco.agent:runtime:0.8.7" level="project" />
+    <orderEntry type="library" name="Maven: org.ini4j:ini4j:0.5.4" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-api:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-util:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-noop:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-dysmsapi:2.1.0" level="project" />
+    <orderEntry type="library" name="Maven: org.flowable:flowable-json-converter:6.7.2" level="project" />
+    <orderEntry type="library" name="Maven: org.flowable:flowable-bpmn-model:6.7.2" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: joda-time:joda-time:2.10.10" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.30" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.9.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.64" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.64" level="project" />
+    <orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.4.2.Final" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.mapstruct:mapstruct-processor:1.4.2.Final" level="project" />
+  </component>
+</module>

+ 32 - 0
jeeplus-api/jeeplus-system-api/pom.xml

@@ -0,0 +1,32 @@
+<?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>jeeplus-api</artifactId>
+        <groupId>org.jeeplus</groupId>
+        <version>9.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jeeplus-system-api</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.jeeplus</groupId>
+            <artifactId>jeeplus-common-core</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.flowable</groupId>
+            <artifactId>flowable-json-converter</artifactId>
+            <version>6.7.2</version>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.flowable</groupId>-->
+<!--            <artifactId>flowable-spring-boot-starter-process-rest</artifactId>-->
+<!--            <version>6.7.2</version>-->
+<!--            <scope>provided</scope>-->
+<!--        </dependency>-->
+    </dependencies>
+</project>

+ 45 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/excel/converter/ExcelDictDTOConverter.java

@@ -0,0 +1,45 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.core.excel.converter;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+import com.jeeplus.common.excel.annotation.ExcelDictProperty;
+import com.jeeplus.sys.feign.IDictApi;
+
+/**
+ * 字典类型转换
+ *
+ * @author jeeplus
+ * @version 2022-08-01
+ */
+
+public class ExcelDictDTOConverter implements Converter <String> {
+
+
+    @Override
+    public String convertToJavaData(ReadCellData <?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        String dictType = contentProperty.getField ( ).getAnnotation ( ExcelDictProperty.class ).value ( );
+        String val = cellData.getStringValue ( );
+        return SpringUtil.getBean ( IDictApi.class ).getDictValue ( val, dictType, "-" );
+    }
+
+    @Override
+    public WriteCellData <?> convertToExcelData(String value, ExcelContentProperty contentProperty,
+                                                GlobalConfiguration globalConfiguration) {
+
+
+        String dictType = contentProperty.getField ( ).getAnnotation ( ExcelDictProperty.class ).value ( );
+
+        WriteCellData <Object> objectWriteCellData = new WriteCellData <> ( SpringUtil.getBean ( IDictApi.class ).getDictLabel ( value, dictType, "-" ) );
+        return objectWriteCellData;
+    }
+
+
+}
+

+ 54 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/excel/converter/ExcelOfficeDTOConverter.java

@@ -0,0 +1,54 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.core.excel.converter;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+import com.jeeplus.sys.feign.IOfficeApi;
+import com.jeeplus.sys.service.dto.OfficeDTO;
+
+/**
+ * 字段类型转换
+ *
+ * @author jeeplus
+ * @version 2016-03-10
+ */
+
+public class ExcelOfficeDTOConverter implements Converter <OfficeDTO> {
+
+    @Override
+    public Class <?> supportJavaTypeKey() {
+        return OfficeDTO.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public OfficeDTO convertToJavaData(ReadCellData <?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        String val = cellData.getStringValue ( );
+        OfficeDTO officeDTO = SpringUtil.getBean ( IOfficeApi.class ).getOfficeDTOByName ( val );
+        return officeDTO;
+    }
+
+    @Override
+    public WriteCellData <?> convertToExcelData(OfficeDTO value, ExcelContentProperty contentProperty,
+                                                GlobalConfiguration globalConfiguration) {
+
+        if ( value != null && value.getName ( ) != null ) {
+            return new WriteCellData <> ( value.getName ( ) );
+        }
+        return new WriteCellData <> ( "" );
+    }
+
+
+}
+

+ 60 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/excel/converter/ExcelPostListDTOConverter.java

@@ -0,0 +1,60 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.core.excel.converter;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+import com.google.common.collect.Lists;
+import com.jeeplus.sys.feign.IPostApi;
+import com.jeeplus.sys.service.dto.PostDTO;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 岗位类型转换
+ *
+ * @author jeeplus
+ * @version 2016-03-10
+ */
+
+public class ExcelPostListDTOConverter implements Converter <List <PostDTO>> {
+
+    @Override
+    public Class <?> supportJavaTypeKey() {
+        return List.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public List <PostDTO> convertToJavaData(ReadCellData <?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+
+        List <PostDTO> postList = Lists.newArrayList ( );
+        String val = cellData.getStringValue ( );
+        for (String postName : StrUtil.split ( val, "," )) {
+            PostDTO postDTO = SpringUtil.getBean ( IPostApi.class ).getPostDTOByName ( postName );
+            postList.add ( postDTO );
+        }
+        return postList.size ( ) > 0 ? postList : null;
+    }
+
+    @Override
+    public WriteCellData <?> convertToExcelData(List <PostDTO> postDTOList, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        List <String> postNames = postDTOList.stream ( ).map ( postDTO -> postDTO.getName ( ) ).collect ( Collectors.toList ( ) );
+        return new WriteCellData <> ( StrUtil.join ( ",", postNames ) );
+    }
+
+
+}
+

+ 60 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/excel/converter/ExcelRoleListDTOConverter.java

@@ -0,0 +1,60 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.core.excel.converter;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+import com.google.common.collect.Lists;
+import com.jeeplus.sys.feign.IRoleApi;
+import com.jeeplus.sys.service.dto.RoleDTO;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 字段类型转换
+ *
+ * @author jeeplus
+ * @version 2016-03-10
+ */
+
+public class ExcelRoleListDTOConverter implements Converter <List <RoleDTO>> {
+
+    @Override
+    public Class <?> supportJavaTypeKey() {
+        return List.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public List <RoleDTO> convertToJavaData(ReadCellData <?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+
+        List <RoleDTO> roleList = Lists.newArrayList ( );
+        String val = cellData.getStringValue ( );
+        for (String roleName : StrUtil.split ( val, "," )) {
+            RoleDTO roleDTO = SpringUtil.getBean ( IRoleApi.class ).getRoleDTOByName ( roleName );
+            roleList.add ( roleDTO );
+        }
+        return roleList.size ( ) > 0 ? roleList : null;
+    }
+
+    @Override
+    public WriteCellData <?> convertToExcelData(List <RoleDTO> roleDTOList, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        List <String> roleNames = roleDTOList.stream ( ).map ( roleDTO -> roleDTO.getName ( ) ).collect ( Collectors.toList ( ) );
+        return new WriteCellData <> ( StrUtil.join ( ",", roleNames ) );
+    }
+
+
+}
+

+ 54 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/excel/converter/ExcelUserDTOConverter.java

@@ -0,0 +1,54 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.core.excel.converter;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+import com.jeeplus.sys.feign.IUserApi;
+import com.jeeplus.sys.service.dto.UserDTO;
+
+/**
+ * 字段类型转换
+ *
+ * @author jeeplus
+ * @version 2016-03-10
+ */
+
+public class ExcelUserDTOConverter implements Converter <UserDTO> {
+
+    @Override
+    public Class <?> supportJavaTypeKey() {
+        return UserDTO.class;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+
+    @Override
+    public UserDTO convertToJavaData(ReadCellData <?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        String val = cellData.getStringValue ( );
+        UserDTO officeDTO = SpringUtil.getBean ( IUserApi.class ).getUserDTOByName ( val );
+        return officeDTO;
+    }
+
+    @Override
+    public WriteCellData <?> convertToExcelData(UserDTO value, ExcelContentProperty contentProperty,
+                                                GlobalConfiguration globalConfiguration) {
+
+        if ( value != null && value.getName ( ) != null ) {
+            return new WriteCellData <> ( value.getName ( ) );
+        }
+        return new WriteCellData <> ( "" );
+    }
+
+
+}
+

+ 138 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/service/TreeDTOService.java

@@ -0,0 +1,138 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.core.service;
+
+import cn.hutool.core.util.StrUtil;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.jeeplus.core.domain.TreeEntity;
+import com.jeeplus.core.domain.TreeMapper;
+import com.jeeplus.core.service.dto.TreeDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.lang.reflect.ParameterizedType;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Service基类
+ *
+ * @author jeeplus
+ * @version 2021-05-16
+ */
+@Slf4j
+@Transactional
+public abstract class TreeDTOService<D extends TreeMapper <T>, T extends TreeEntity <T>, DTO extends TreeDTO <DTO>> extends TreeService <D, T> {
+
+
+    private Class <DTO> clzzDTO;
+
+    public TreeDTOService() {
+        clzzDTO = (Class <DTO>) ((ParameterizedType) getClass ( ).getGenericSuperclass ( )).getActualTypeArguments ( )[2];
+    }
+
+
+    /**
+     * 获取JSON树形数据。
+     *
+     * @return
+     */
+    public List <DTO> treeDataDTO() {
+        return treeDataDTO ( null );
+    }
+
+
+    public abstract List <DTO> listDTO();
+
+    /**
+     * 获取JSON树形数据。
+     *
+     * @param extId 排除的ID
+     * @return
+     */
+    public List <DTO> treeDataDTO(String extId) {
+        List <DTO> allList = this.listDTO ( );
+        try {
+            DTO root = clzzDTO.getConstructor ( ).newInstance ( );
+            root.setId ( TreeDTO.getRootId ( ) );
+            List <DTO> rootTree = this.formatListToTree ( root, allList, extId );
+            return rootTree;
+        } catch (Exception e) {
+            log.error ( "{}", e );
+            return null;
+        }
+
+    }
+
+
+    /**
+     * 以root为根节点, 将allList从线性列表转为树形列表
+     *
+     * @param root    根节点, 为空抛出空指针异常
+     * @param allList 所有需要参与构造为树的列表
+     * @param extId   需要排除在树之外的节点(子节点一并被排除)
+     * @return java.util.List<T>
+     * @Author 滕鑫源
+     * @Date 2020/10/23 17:04
+     **/
+    public List <DTO> formatListToTree(DTO root, List <DTO> allList, String extId) {
+        String rootId = root.getId ( );
+
+        // 最终的树形态
+        List <DTO> trees = Lists.newArrayList ( );
+
+        // 把需要构造树的所有列表, 根据以父id作为key, 整理为列表
+        Map <String, List <DTO>> treeMap = Maps.newHashMap ( );
+        for (DTO entity : allList) {
+            List <DTO> entities = treeMap.get ( entity.getParentId ( ) );
+            if ( entities == null ) {
+                entities = Lists.newLinkedList ( );
+            }
+
+            // 剔除排除项, 构造treeMap, 转递归为线性操作
+            if ( StrUtil.isBlank ( extId ) || (!extId.equals ( entity.getId ( ) ) && entity.getParentIds ( ).indexOf ( "," + extId + "," ) == -1) ) {
+                entities.add ( entity );
+                treeMap.put ( entity.getParentId ( ), entities );
+            }
+        }
+
+        // 没有给定的子树, 返回空树
+        if ( treeMap.get ( rootId ) == null || treeMap.get ( rootId ).isEmpty ( ) ) {
+            return trees;
+        }
+
+        // 开始递归格式化
+        List <DTO> children = treeMap.get ( rootId );
+        for (DTO parent : children) {
+            formatFillChildren ( parent, treeMap );
+            trees.add ( parent );
+        }
+        if ( StrUtil.equals ( rootId, TreeDTO.getRootId ( ) ) ) {
+            return children;
+        } else {
+            root.setChildren ( trees );
+            return Lists.newArrayList ( root );
+        }
+    }
+
+    /**
+     * 从treeMap中取出子节点填入parent, 并递归此操作
+     *
+     * @param parent
+     * @param treeMap
+     * @return void
+     * @Author 滕鑫源
+     * @Date 2020/9/30 16:33
+     **/
+    private void formatFillChildren(DTO parent, Map <String, List <DTO>> treeMap) {
+        List <DTO> children = treeMap.get ( parent.getId ( ) );
+        parent.setChildren ( children );
+        if ( children != null && !children.isEmpty ( ) ) {
+            for (DTO child : children) {
+                formatFillChildren ( child, treeMap );
+            }
+        }
+    }
+}

+ 260 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/service/TreeService.java

@@ -0,0 +1,260 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.core.service;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.jeeplus.core.domain.TreeEntity;
+import com.jeeplus.core.domain.TreeMapper;
+import com.jeeplus.core.dto.DragNode;
+import com.jeeplus.core.service.dto.TreeDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Service基类
+ *
+ * @author jeeplus
+ * @version 2021-05-16
+ */
+@Slf4j
+@Transactional
+public abstract class TreeService<D extends TreeMapper <T>, T extends TreeEntity <T>> extends ServiceImpl <D, T> {
+
+    public boolean saveOrUpdate(T entity) {
+        T parent;
+        // 如果没有设置父节点,则代表为跟节点,有则获取父节点实体
+        if ( TreeDTO.getRootId ( ).equals ( entity.getParentId ( ) ) || StrUtil.isBlank ( entity.getParentId ( ) ) ) {
+            parent = null;
+        } else {
+            parent = super.getById ( entity.getParentId ( ) );
+        }
+        if ( parent == null ) {
+            try {
+                parent = entityClass.getConstructor ( ).newInstance ( );
+                parent.setId ( TreeDTO.getRootId ( ) );
+
+            } catch (Exception e) {
+                log.error ( "{}", e );
+            }
+            entity.setParentId ( parent.getId ( ) );
+            parent.setParentIds ( StrUtil.EMPTY );
+        }
+        // 获取修改前的parentIds,用于更新子节点的parentIds
+        String oldParentIds = StrUtil.isNotBlank ( entity.getId ( ) ) ? super.getById ( entity.getId ( ) ).getParentIds ( ) : null;
+        // 设置新的父节点串
+        entity.setParentIds ( parent.getParentIds ( ) + parent.getId ( ) + "," );
+        // 保存或更新实体
+        super.saveOrUpdate ( entity );
+        LambdaQueryWrapper <T> queryWrapper = new LambdaQueryWrapper <> ( (Class <T>) entity.getClass ( ) ).like ( T::getParentIds, "," + entity.getId ( ) + "," );
+        List <T> list = super.list ( queryWrapper );
+        for (T e : list) {
+            if ( e.getParentIds ( ) != null && oldParentIds != null ) {
+                e.setParentIds ( e.getParentIds ( ).replace ( oldParentIds, entity.getParentIds ( ) ) );
+                super.updateById ( e );
+            }
+        }
+        return true;
+
+    }
+
+    public void sortList(DragNode <T> dragNode) {
+        String dropType = dragNode.getDropType ( );
+        T dropNode = dragNode.getDropNode ( );
+        T draggingNode = dragNode.getDraggingNode ( );
+        String parentId = dropNode.getParentId ( );
+        LambdaQueryWrapper <T> queryWrapper = new LambdaQueryWrapper <> ( (Class <T>) dropNode.getClass ( ) ).eq ( T::getParentId, parentId ).orderByAsc ( T::getSort );
+        List <T> sourceList = super.list ( queryWrapper );
+        if ( "inner".equals ( dropType ) ) {
+            draggingNode.setParentId ( dropNode.getId ( ) );
+            int size = sourceList.size ( );
+            if ( size > 0 ) {
+                draggingNode.setSort ( sourceList.get ( size - 1 ).getSort ( ) + 30 );
+            } else {
+                draggingNode.setSort ( 30 );
+            }
+            this.saveOrUpdate ( draggingNode );
+
+        } else {
+
+            draggingNode.setParentId ( dropNode.getParentId ( ) );
+            List <T> list = Lists.newArrayList ( );
+
+            T before = null;
+            T after = null;
+            for (int i = 0; i < sourceList.size ( ); i++) {
+                T e = sourceList.get ( i );
+                if ( parentId.equals ( e.getParentId ( ) ) ) {
+                    if ( e.getId ( ).equals ( dropNode.getId ( ) ) ) {
+                        if ( "before".equals ( dropType ) ) {
+                            after = e;
+                            if ( i - 1 >= 0 ) {
+                                before = sourceList.get ( i - 1 );
+                            }
+                            list.add ( draggingNode );
+                            list.add ( e );
+                        } else {
+                            before = e;
+                            if ( i + 1 < sourceList.size ( ) ) {
+                                after = sourceList.get ( i + 1 );
+                            }
+                            list.add ( e );
+                            list.add ( draggingNode );
+                        }
+                    } else if ( !e.getId ( ).equals ( draggingNode.getId ( ) ) ) {
+                        list.add ( e );
+                    }
+                }
+            }
+
+            if ( before == null && after != null && after.getSort ( ) >= 1 ) {
+                draggingNode.setSort ( after.getSort ( ) / 2 );
+                this.saveOrUpdate ( draggingNode );
+            } else if ( after == null && before != null ) {
+                draggingNode.setSort ( before.getSort ( ) + 30 );
+                this.saveOrUpdate ( draggingNode );
+            } else if ( before != null && after != null && after.getSort ( ) - 2 >= before.getSort ( ) ) { // 只需要对当前节点设置排序
+                draggingNode.setSort ( (after.getSort ( ) + before.getSort ( )) / 2 );
+                this.saveOrUpdate ( draggingNode );
+            } else { // 需要全局更新排序
+                for (int i = 0; i < list.size ( ); i++) {
+                    T entity = list.get ( i );
+                    entity.setSort ( (i + 1) * 30 );
+                    this.saveOrUpdate ( entity );
+                }
+            }
+
+        }
+
+    }
+
+    public List <T> getChildren(T parent) {
+        LambdaQueryWrapper <T> queryWrapper = new LambdaQueryWrapper <> ( (Class <T>) parent.getClass ( ) ).eq ( T::getParentId, parent.getId ( ) );
+        return super.list ( queryWrapper );
+    }
+
+    /**
+     * 删除数据
+     *
+     * @param id
+     */
+    public boolean removeWithChildrenById(String id) {
+        LambdaQueryWrapper <T> queryWrapper = new LambdaQueryWrapper <> ( (Class <T>) entityClass ).like ( StrUtil.isNotBlank ( id ), T::getParentIds, "," + id + "," ).or ( ).eq ( StrUtil.isNotBlank ( id ), T::getId, id );
+        return super.remove ( queryWrapper );
+    }
+
+    /**
+     * 批量删除数据
+     */
+    public void removeWithChildrenByIds(List <String> idList) {
+        idList.stream ( ).forEach ( this::removeWithChildrenById );
+    }
+
+    /**
+     * 获取JSON树形数据。
+     *
+     * @return
+     */
+    public List <T> treeData() {
+        return treeData ( null );
+    }
+
+
+    /**
+     * 获取JSON树形数据。
+     *
+     * @param extId 排除的ID
+     * @return
+     */
+    public List <T> treeData(String extId) {
+        List <T> allList = super.list ( new LambdaQueryWrapper <> ( (Class <T>) entityClass ).orderByAsc ( T::getSort ) );
+        try {
+            T root = entityClass.getConstructor ( ).newInstance ( );
+            root.setId ( TreeDTO.getRootId ( ) );
+            List <T> rootTree = this.formatListToTree ( root, allList, extId );
+            return rootTree;
+        } catch (Exception e) {
+            log.error ( "{}", e );
+            return null;
+        }
+
+    }
+
+
+    /**
+     * 以root为根节点, 将allList从线性列表转为树形列表
+     *
+     * @param root    根节点, 为空抛出空指针异常
+     * @param allList 所有需要参与构造为树的列表
+     * @param extId   需要排除在树之外的节点(子节点一并被排除)
+     * @return java.util.List<T>
+     * @Author 滕鑫源
+     * @Date 2020/10/23 17:04
+     **/
+    public List <T> formatListToTree(T root, List <T> allList, String extId) {
+        String rootId = root.getId ( );
+
+        // 最终的树形态
+        List <T> trees = Lists.newArrayList ( );
+
+        // 把需要构造树的所有列表, 根据以父id作为key, 整理为列表
+        Map <String, List <T>> treeMap = Maps.newHashMap ( );
+        for (T entity : allList) {
+            List <T> entities = treeMap.get ( entity.getParentId ( ) );
+            if ( entities == null ) {
+                entities = Lists.newLinkedList ( );
+            }
+
+            // 剔除排除项, 构造treeMap, 转递归为线性操作
+            if ( StrUtil.isBlank ( extId ) || (!extId.equals ( entity.getId ( ) ) && entity.getParentIds ( ).indexOf ( "," + extId + "," ) == -1) ) {
+                entities.add ( entity );
+                treeMap.put ( entity.getParentId ( ), entities );
+            }
+        }
+
+        // 没有给定的子树, 返回空树
+        if ( treeMap.get ( rootId ) == null || treeMap.get ( rootId ).isEmpty ( ) ) {
+            return trees;
+        }
+
+        // 开始递归格式化
+        List <T> children = treeMap.get ( rootId );
+        for (T parent : children) {
+            formatFillChildren ( parent, treeMap );
+            trees.add ( parent );
+        }
+        if ( StrUtil.equals ( rootId, TreeDTO.getRootId ( ) ) ) {
+            return children;
+        } else {
+            root.setChildren ( trees );
+            return Lists.newArrayList ( root );
+        }
+    }
+
+    /**
+     * 从treeMap中取出子节点填入parent, 并递归此操作
+     *
+     * @param parent
+     * @param treeMap
+     * @return void
+     * @Author 滕鑫源
+     * @Date 2020/9/30 16:33
+     **/
+    private void formatFillChildren(T parent, Map <String, List <T>> treeMap) {
+        List <T> children = treeMap.get ( parent.getId ( ) );
+        parent.setChildren ( children );
+        if ( children != null && !children.isEmpty ( ) ) {
+            for (T child : children) {
+                formatFillChildren ( child, treeMap );
+            }
+        }
+    }
+
+}

+ 103 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/service/dto/BaseDTO.java

@@ -0,0 +1,103 @@
+package com.jeeplus.core.service.dto;
+
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.jeeplus.config.swagger.IgnoreSwaggerParameter;
+import com.jeeplus.sys.service.dto.TenantDTO;
+import com.jeeplus.sys.service.dto.UserDTO;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public abstract class BaseDTO<T> implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * taskId
+     */
+    protected String taskId;
+
+    /**
+     * 流程id
+     */
+    protected String procInsId;
+
+    /**
+     * 流程信息
+     */
+    protected String processDefinitionId;
+
+    /**
+     * 实体主键
+     */
+    @ExcelIgnore
+    protected String id;
+
+    /**
+     * 创建日期
+     */
+    @ExcelIgnore
+    @IgnoreSwaggerParameter
+    @ApiModelProperty(hidden = true)
+    protected Date createTime;
+
+    /**
+     * 创建人
+     */
+    @ExcelIgnore
+    @IgnoreSwaggerParameter
+    @ApiModelProperty(hidden = true)
+    protected UserDTO createBy;
+
+    /**
+     * 更新日期
+     */
+    @ExcelIgnore
+    @IgnoreSwaggerParameter
+    @ApiModelProperty(hidden = true)
+    protected Date updateTime;
+
+    /**
+     * 更新人
+     */
+    @ExcelIgnore
+    @IgnoreSwaggerParameter
+    @ApiModelProperty(hidden = true)
+    protected UserDTO updateBy;
+
+    /**
+     * 逻辑删除标记
+     */
+    @ExcelIgnore
+    @IgnoreSwaggerParameter
+    @ApiModelProperty(hidden = true)
+    protected Integer delFlag;
+
+    @ExcelIgnore
+    @IgnoreSwaggerParameter
+    @ApiModelProperty(hidden = true)
+    protected TenantDTO tenantDTO;
+
+    /**
+     * 构造函数
+     */
+    public BaseDTO() {
+
+    }
+
+    /**
+     * 构造函数
+     *
+     * @param id
+     */
+    public BaseDTO(String id) {
+        this.id = id;
+    }
+
+
+}
+

+ 103 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/core/service/dto/TreeDTO.java

@@ -0,0 +1,103 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.core.service.dto;
+
+import cn.hutool.core.util.ReflectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.common.collect.Lists;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * 数据dto类
+ *
+ * @author jeeplus
+ * @version 2021-05-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public abstract class TreeDTO<T> extends BaseDTO <T> {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 父级元素
+     */
+    protected T parent;
+
+    /**
+     * 子元素
+     */
+    private List <T> children = Lists.newArrayList ( );
+
+    /**
+     * 所有父级编号
+     */
+    protected String parentIds;
+
+    /**
+     * 名称
+     */
+    protected String name;
+
+    /**
+     * 排序
+     */
+    protected Integer sort;
+
+    /**
+     * 构造函数
+     */
+    public TreeDTO() {
+        super ( );
+    }
+
+    /**
+     * 构造函数
+     *
+     * @param id
+     */
+    public TreeDTO(String id) {
+        super ( id );
+    }
+
+    /**
+     * 获取上级id
+     *
+     * @return
+     */
+    public String getParentId() {
+        String id = null;
+        if ( parent != null ) {
+            id = (String) ReflectUtil.getFieldValue ( parent, "id" );
+        }
+        return StrUtil.isNotBlank ( id ) ? id : getRootId ( );
+    }
+
+    /**
+     * 获取上级name
+     *
+     * @return
+     */
+    public String getParentName() {
+        String name = null;
+        if ( parent != null ) {
+            name = (String) ReflectUtil.getFieldValue ( parent, "name" );
+        }
+        return StrUtil.isNotBlank ( name ) ? name : "";
+    }
+
+    /**
+     * 默认根节点
+     *
+     * @return
+     */
+    @JsonIgnore
+    public static String getRootId() {
+        return "0";
+    }
+}

+ 33 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/factory/AssessApiFallbackFactory.java

@@ -0,0 +1,33 @@
+package com.jeeplus.flowable.factory;
+
+import com.jeeplus.flowable.feign.IAssessApi;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * 财务服务降级处理
+ * @author: 王强
+ * @create: 2023-07-26 17:03
+ **/
+@Slf4j
+@Component
+public class AssessApiFallbackFactory implements FallbackFactory<IAssessApi> {
+
+    @Override
+    public IAssessApi create(Throwable cause) {
+        log.error ( "财务服务调用失败:{}", cause.getMessage ( ) );
+        return new IAssessApi() {
+
+            @Override
+            public void updateArchiveStatus(String id, String archiveStatus, String overArchiveStatus) {
+
+            }
+
+            @Override
+            public String getOverdueFilingProjectList() {
+                return null;
+            }
+        };
+    }
+}

+ 47 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/factory/FinanceApiFallbackFactory.java

@@ -0,0 +1,47 @@
+package com.jeeplus.flowable.factory;
+
+import com.jeeplus.flowable.feign.IAssessApi;
+import com.jeeplus.flowable.feign.IFinanceApi;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 会计服务降级处理
+ * @author: 徐滕
+ * @create: 2023-10-16 16:21
+ **/
+@Slf4j
+@Component
+public class FinanceApiFallbackFactory implements FallbackFactory<IFinanceApi> {
+
+    @Override
+    public IFinanceApi create(Throwable cause) {
+        log.error ( "会计服务调用失败:{}", cause.getMessage ( ) );
+        return new IFinanceApi() {
+
+            @Override
+            public String getNotFiledYetList() {
+                return null;
+            }
+
+            @Override
+            public List<String> getCwProjectData(String id) {
+                return null;
+            }
+
+            @Override
+            public List<String> getMembersId(String id) {
+                return null;
+            }
+
+            @Override
+            public void insertMembers(String projectId, String membersId,String userId) {
+
+            }
+
+        };
+    }
+}

+ 117 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/factory/FlowableApiFallbackFactory.java

@@ -0,0 +1,117 @@
+package com.jeeplus.flowable.factory;
+
+import com.jeeplus.flowable.feign.IFlowableApi;
+import com.jeeplus.mail.feign.IMailApi;
+import com.jeeplus.sys.service.dto.UserDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.flowable.bpmn.model.FlowNode;
+//import org.flowable.task.api.Task;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 流程服务降级处理
+ */
+@Slf4j
+@Component
+public class FlowableApiFallbackFactory implements FallbackFactory <IFlowableApi> {
+
+    @Override
+    public IFlowableApi create(Throwable throwable) {
+        log.error ( "流程服务调用失败:{}", throwable.getMessage ( ) );
+        return new IFlowableApi() {
+
+            @Override
+            public Map historicTaskList3(String procInsId) {
+                return null;
+            }
+
+            @Override
+            public Map historicTaskList2(String procInsId) {
+                return null;
+            }
+
+            @Override
+            public Map getByNameForFen(String name) {
+                return null;
+            }
+
+            @Override
+            public String startForFen(Map<String, String> map) {
+                return null;
+            }
+
+            @Override
+            public Map<String ,String > startForFenNew(Map<String, Map<String, String>> map) {
+                return null;
+            }
+
+            @Override
+            public String updateAssignee(Map<String, String> map) {
+                return null;
+            }
+
+            @Override
+            public void insertMyNotice(Map<String, String> map) {
+
+            }
+
+            @Override
+            public void updateMyNotice(Map<String, String> map) {
+
+            }
+
+            @Override
+            public String getRepetitionCountBymyNoticeTitle(Map<String, String> map) {
+                return null;
+            }
+
+            @Override
+            public String add(Map<String, String> map) {
+                return null;
+            }
+
+            @Override
+            public String taskDispose(Map<String, String> map) {
+                return null;
+            }
+
+            @Override
+            public FlowNode getCurrentTask(String processInstanceId) {
+                return null;
+            }
+
+            @Override
+            public String getTaskIdByprocInstId(String procInsId) {
+                return null;
+            }
+
+            @Override
+            public List<String> getTaskAuditUsers(String taskId) {
+                return null;
+            }
+
+            @GetMapping("/flowable/task/getCurrentTaskName")
+            @Override
+            public String getCurrentTaskName(String processInstanceId) {
+                return null;
+            }
+
+            @Override
+            public void auditByProcInsIdAndFlag(String procInsId, String flag, String assignee, String comm) {
+
+            }
+
+            @Override
+            public boolean checkIsLastTask(String procInsId) {
+                return false;
+            }
+        };
+    }
+}

+ 51 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/factory/HumanApiFallBackFactory.java

@@ -0,0 +1,51 @@
+package com.jeeplus.flowable.factory;
+
+import com.jeeplus.flowable.feign.IHumanApi;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @author 王强
+ * @version 1.0
+ * @date 2023-09-21 9:22
+ */
+@Slf4j
+@Component
+public class HumanApiFallBackFactory implements FallbackFactory<IHumanApi> {
+
+    @Override
+    public IHumanApi create(Throwable cause) {
+        log.error ( "人力资源服务调用失败:{}", cause.getMessage ( ) );
+        return new IHumanApi() {
+
+
+            @Override
+            public String getTimeOutRegisters() {
+                return null;
+            }
+
+            @Override
+            public String getTimeOutReimburseRegisters() {
+                return null;
+            }
+
+            @Override
+            public String getFormalUserInfo() {
+                return null;
+            }
+
+            @Override
+            public void insertIntoEnrollmentRegistrationInfo(String value) {
+
+            }
+
+            @Override
+            public List<String> getAllUserIdInSuccess() {
+                return null;
+            }
+        };
+    }
+}

+ 33 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/feign/IAssessApi.java

@@ -0,0 +1,33 @@
+package com.jeeplus.flowable.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.flowable.factory.AssessApiFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * @author: 王强
+ * @create: 2023-07-26 17:01
+ **/
+@FeignClient(contextId = "assessApi", name = AppNameConstants.APP_ASSESS_MODULES, fallbackFactory = AssessApiFallbackFactory.class)
+public interface IAssessApi {
+
+    /**
+     * 修改报告归档 归档状态信息
+     * @param id
+     * @param archiveStatus
+     * @param overArchiveStatus
+     */
+    @GetMapping(value = "/program/projectList/updateArchiveStatus")
+    void updateArchiveStatus(@RequestParam(value = "id")String id,
+                             @RequestParam(value = "archiveStatus")String archiveStatus,
+                             @RequestParam(value = "overArchiveStatus")String overArchiveStatus);
+
+    /**
+     * 查询项目签发单完成后3天未归档项目信息
+     * @return
+     */
+    @GetMapping(value = "/program/projectList/getOverdueFilingProjectList")
+    String getOverdueFilingProjectList();
+}

+ 32 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/feign/IFinanceApi.java

@@ -0,0 +1,32 @@
+package com.jeeplus.flowable.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.flowable.factory.AssessApiFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author: 徐滕
+ * @create: 2023-10-16 16:21
+ **/
+@FeignClient(contextId = "financeApi", name = AppNameConstants.APP_FINANCE_MODULES, fallbackFactory = AssessApiFallbackFactory.class)
+public interface IFinanceApi {
+
+    /**
+     * 查询暂时未归档报告归档数据
+     * @return
+     */
+    @GetMapping(value = "/cwProjectReportArchive/getNotFiledYetList")
+    String getNotFiledYetList();
+
+    @GetMapping(value = "/cwProjectRecords/getCwProjectData")
+    List<String> getCwProjectData(@RequestParam(value = "id") String id);
+
+    @GetMapping(value = "/cwProjectRecords/getMembersId")
+    List<String> getMembersId(@RequestParam(value = "id")String id);
+
+    @RequestMapping(value = "/cwProjectRecords/insertMembers", method = RequestMethod.POST)
+    void insertMembers(@RequestParam(value = "projectId")String projectId,@RequestParam(value = "membersId")String membersId,@RequestParam(value = "userId")String userId);
+}

+ 119 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/feign/IFlowableApi.java

@@ -0,0 +1,119 @@
+package com.jeeplus.flowable.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.flowable.factory.FlowableApiFallbackFactory;
+import org.flowable.bpmn.model.FlowNode;
+//import org.flowable.task.api.Task;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.cloud.openfeign.SpringQueryMap;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+//import org.flowable.task.api.Task;
+
+import java.util.List;
+import java.util.Map;
+
+
+@FeignClient(contextId = "flowableApi", name = AppNameConstants.APP_FLOWABLE_SERVICE, fallbackFactory = FlowableApiFallbackFactory.class)
+public interface IFlowableApi {
+
+    @RequestMapping(value = "/flowable/task/historicTaskList3", method = RequestMethod.POST)
+    Map historicTaskList3(@RequestParam(value = "procInsId")String procInsId);
+
+    @RequestMapping(value = "/flowable/task/historicTaskList2", method = RequestMethod.POST)
+    Map historicTaskList2(@RequestParam(value = "procInsId")String procInsId);
+
+    @RequestMapping(value = "/flowable/process/getByNameForFen", method = RequestMethod.POST)
+    Map getByNameForFen(@RequestParam(value = "name")String name);
+
+    @RequestMapping(value = "/flowable/task/startForFen", method = RequestMethod.POST)
+    String startForFen(@RequestBody Map<String ,String > map);
+
+    @RequestMapping(value = "/flowable/task/startForFenNew", method = RequestMethod.POST)
+    Map<String ,String > startForFenNew(@RequestBody Map<String ,Map<String ,String > > map);
+
+    @RequestMapping(value = "/flowable/task/updateAssignee", method = RequestMethod.POST)
+    String updateAssignee(@RequestBody Map<String ,String > map);
+    /**
+     * 根据通知信息查询数据
+     * @param map
+     * @return
+     */
+    @RequestMapping(value = "/flowable/task/insertMyNotice2", method = RequestMethod.POST)
+    void insertMyNotice(@RequestBody Map<String ,String > map);
+
+    /**
+     * 根据通知信息查询数据
+     * @param map
+     * @return
+     */
+    @RequestMapping(value = "/flowable/task/updateMyNotice2", method = RequestMethod.POST)
+    void updateMyNotice(@RequestBody Map<String ,String > map);
+
+    /**
+     * 根据通知信息查询数据
+     * @param map
+     * @return
+     */
+    @RequestMapping(value = "/flowable/task/getRepetitionCountBymyNoticeTitle", method = RequestMethod.POST)
+    String getRepetitionCountBymyNoticeTitle(@RequestBody Map<String ,String > map);
+
+    /**
+     * 发送通知
+     */
+    @RequestMapping(value = "/flowable/task/add", method = RequestMethod.POST)
+    String add(@RequestBody Map<String ,String > map);
+
+    /**
+     * 已经签收或者等待签收的任务
+     * @param map
+     * @return
+     */
+    @RequestMapping(value = "/flowable/task/taskDispose", method = RequestMethod.POST)
+    String taskDispose(@RequestBody Map<String ,String > map);
+
+    /**
+     * 根据processInstanceId获取taskId
+     * @param processInstanceId
+     * @return
+     */
+    @GetMapping(value = "/flowable/task/getCurrentTask")
+    FlowNode getCurrentTask(@RequestParam(value = "processInstanceId") String processInstanceId);
+
+    /**
+     * 根据procInsId获取taskId
+     * @param procInsId
+     * @return
+     */
+    @GetMapping(value = "/flowable/task/getTaskIdByprocInstId")
+    String getTaskIdByprocInstId(@RequestParam(value = "procInsId") String procInsId);
+
+    /**
+     * 获取当前节点审核人
+     * @param taskId
+     * @return
+     */
+    @GetMapping(value = "/flowable/task/getTaskAuditUsers")
+    List <String> getTaskAuditUsers(@RequestParam(value = "taskId") String taskId);
+
+    /**
+     * 获取当前节点名称
+     * @param processInstanceId
+     * @return
+     */
+    @GetMapping(value = "/flowable/task/getCurrentTaskName")
+    String getCurrentTaskName(@RequestParam(value = "processInstanceId") String processInstanceId);
+
+    /**
+     * 审核通过或驳回
+     */
+    @GetMapping(value = "/flowable/task/auditByProcInsIdAndFlag")
+    void auditByProcInsIdAndFlag(@RequestParam(value = "procInsId")String procInsId,@RequestParam(value = "flag")String flag,
+                                 @RequestParam(value = "assignee")String assignee,@RequestParam(value = "comm")String comm);
+
+    /**
+     * 检查是否为最后一个审核节点
+     */
+    @GetMapping(value = "/flowable/task/checkIsLastTask")
+    boolean checkIsLastTask(@RequestParam(value = "procInsId")String procInsId);
+}

+ 50 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/flowable/feign/IHumanApi.java

@@ -0,0 +1,50 @@
+package com.jeeplus.flowable.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.flowable.factory.HumanApiFallBackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+/**
+ * @author 王强
+ * @version 1.0
+ * @date 2023-09-21 9:20
+ */
+@FeignClient(contextId = "humanApi", name = AppNameConstants.APP_HUMAN_MODULES, fallbackFactory = HumanApiFallBackFactory.class)
+public interface IHumanApi {
+
+    /**
+     * 查询3天未发送日志状态为实习中的人员信息
+     * @return
+     */
+    @GetMapping(value = "/register/getTimeOutRegisters")
+    String getTimeOutRegisters();
+
+    /**
+     * 获取最后一次发起报销且实习状态为结束,并且报销状态为完成的
+     * @return
+     */
+    @GetMapping(value = "/register/getTimeOutReimburseRegisters")
+    String getTimeOutReimburseRegisters();
+
+    /**
+     * 获取正式工在职状态为离职的,并且user表中未删除的
+     * @return
+     */
+    @GetMapping(value = "/register/getFormalUserInfo")
+    String getFormalUserInfo();
+
+    /**
+     * 定时任务发起  个人信息完善所用
+     * @param value
+     */
+    @GetMapping(value = "/enrollmentRegistration/insertIntoEnrollmentRegistrationInfo")
+    void insertIntoEnrollmentRegistrationInfo(@RequestParam(value = "value")String value);
+
+    //获取所有的入职登记表中的有效数据的id
+    @GetMapping(value = "/enrollmentRegistration/getAllUserIdInSuccess")
+    List<String> getAllUserIdInSuccess();
+}

+ 30 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/mail/factory/MailApiFallbackFactory.java

@@ -0,0 +1,30 @@
+package com.jeeplus.mail.factory;
+
+import com.jeeplus.mail.feign.IMailApi;
+import com.jeeplus.sys.service.dto.UserDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 用户服务降级处理
+ *
+ * @author jeeplus
+ */
+@Slf4j
+@Component
+public class MailApiFallbackFactory implements FallbackFactory <IMailApi> {
+
+    @Override
+    public IMailApi create(Throwable throwable) {
+        log.error ( "站内信服务调用失败:{}", throwable.getMessage ( ) );
+        return new IMailApi ( ) {
+
+            @Override
+            public void sendEmail(List <UserDTO> receivers, String title, String content) {
+            }
+        };
+    }
+}

+ 23 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/mail/feign/IMailApi.java

@@ -0,0 +1,23 @@
+package com.jeeplus.mail.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.sys.factory.DictApiFallbackFactory;
+import com.jeeplus.sys.service.dto.UserDTO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+
+@FeignClient(contextId = "mailApi", name = AppNameConstants.APP_SYSTEM_SERVICE, fallbackFactory = DictApiFallbackFactory.class)
+public interface IMailApi {
+    /**
+     * 获取租户Id
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/mail/sendEmail")
+    void sendEmail(List <UserDTO> receivers, @RequestParam(value = "title", required = false) String title, @RequestParam(value = "content", required = false) String content);
+
+}

+ 73 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/Cert.java

@@ -0,0 +1,73 @@
+package com.jeeplus.sys.domain;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jeeplus.core.domain.BaseEntity;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 组织机构-人员资质-人员职业资格证
+ * @TableName sys_cert
+ */
+@Data
+@TableName("sys_cert")
+public class Cert extends BaseEntity {
+
+    /**
+     * 备注信息
+     */
+    private String remarks;
+
+    /**
+     * 人员id
+     */
+    private String userId;
+
+    /**
+     * 证书类型
+     */
+    private String type;
+
+    /**
+     * 证书编号
+     */
+    private String no;
+
+    /**
+     * 发证机关
+     */
+    private String authorities;
+
+    /**
+     * 发证日期
+     */
+    private Date issuedDate;
+
+    /**
+     * 注册日期
+     */
+    private Date enrollDate;
+
+    /**
+     * 到期日期
+     */
+    private Date expireDate;
+
+    /**
+     * 注册证书编号
+     */
+    private String enrollCertNo;
+
+    /**
+     * 专业
+     */
+    private String profession;
+
+    /**
+     * 文件地址
+     */
+    private String fileUrl;
+
+    private static final long serialVersionUID = 1L;
+}

+ 71 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/DataRule.java

@@ -0,0 +1,71 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.domain;
+
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jeeplus.core.domain.BaseEntity;
+import com.jeeplus.core.query.Query;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 数据权限Entity
+ *
+ * @author lgf
+ * @version 2021-04-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("sys_datarule")
+public class DataRule extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 所属菜单
+     */
+    @Query
+    private String menuId;
+
+    /**
+     * 数据规则名称
+     */
+    private String name;
+
+    /**
+     * 实体类名
+     */
+    private String className;
+
+    /**
+     * 规则字段
+     */
+    @TableField("t_field")
+    private String field;
+
+    /**
+     * 规则条件
+     */
+    @TableField("t_express")
+    private String express;
+
+    /**
+     * 规则值
+     */
+    @TableField("t_value")
+    private String value;
+
+    /**
+     * 自定义sql
+     */
+    private String sqlSegment;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+}

+ 105 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/Log.java

@@ -0,0 +1,105 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jeeplus.core.domain.BaseEntity;
+import com.jeeplus.core.query.Query;
+import com.jeeplus.core.query.QueryType;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 日志Entity
+ *
+ * @author jeeplus
+ * @version 2021-8-19
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("sys_log")
+public class Log extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 日志类型(1:接入日志;2:错误日志)
+     */
+    @Query(type = QueryType.EQ)
+    private String type;
+
+    /**
+     * 日志标题
+     */
+    private String title;
+
+    /**
+     * 操作用户的IP地址
+     */
+    private String remoteAddr;
+
+    /**
+     * 操作用户的IP地址
+     */
+    private String requestUri;
+
+    /**
+     * 请求类型
+     */
+    private String requestType;
+
+    /**
+     * 操作的方式
+     */
+    private String method;
+
+    /**
+     * 操作提交的数据
+     */
+    private String params;
+
+    /**
+     * 返回值
+     */
+    private String result;
+    /**
+     * 操作用户代理信息
+     */
+    private String userAgent;
+
+    /**
+     * 异常信息
+     */
+    private String exception;
+
+    /**
+     * 耗时
+     */
+    private Long recordTime;
+
+    /**
+     * 更新日期
+     */
+    @Deprecated
+    @TableField(exist = false)
+    private Date updateTime;
+
+    /**
+     * 更新人
+     */
+    @Deprecated
+    @TableField(exist = false)
+    private String updateById;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+
+}

+ 103 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/Office.java

@@ -0,0 +1,103 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.domain;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jeeplus.core.domain.TreeEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 机构Entity
+ *
+ * @author jeeplus
+ * @version 2021-05-15
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("sys_office")
+public class Office extends TreeEntity <Office> {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 0为私有,1为公有
+     */
+    private String isPublic;
+
+    /**
+     * 归属区域
+     */
+    private String area;
+
+    /**
+     * 机构编码
+     */
+    private String code;
+
+    /**
+     * 机构类型(1:公司;2:部门)
+     */
+    private String type;
+
+    /**
+     * 机构等级(1:一级;2:二级;3:三级;4:四级)
+     */
+    private String grade;
+
+    /**
+     * 联系地址
+     */
+    private String address;
+
+    /**
+     * 邮政编码
+     */
+    private String zipCode;
+
+    /**
+     * 负责人
+     */
+    private String master;
+
+    /**
+     * 电话
+     */
+    private String phone;
+
+    /**
+     * 传真
+     */
+    private String fax;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 是否可用
+     */
+    private String useable;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 构造函数
+     */
+    public Office() {
+        super ( );
+    }
+
+    /**
+     * 构造函数
+     */
+    public Office(String id) {
+        super ( id );
+    }
+
+}

+ 53 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/Role.java

@@ -0,0 +1,53 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jeeplus.core.domain.BaseEntity;
+import com.jeeplus.core.query.Query;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 角色Entity
+ *
+ * @author jeeplus
+ * @version 2021-09-05
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("sys_role")
+public class Role extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 角色名称
+     */
+    @Query
+    private String name;
+
+    /**
+     * 英文名称
+     */
+    private String enName;
+
+    /**
+     * 是否系统数据
+     */
+    @TableField("is_sys")
+    private String sysData;
+
+    /**
+     * 是否可用
+     */
+    private String useable;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+}

+ 68 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/Tenant.java

@@ -0,0 +1,68 @@
+/**
+ * Copyright © 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jeeplus.core.domain.BaseEntity;
+import com.jeeplus.core.query.Query;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 岗位Entity
+ *
+ * @author 刘高峰
+ * @version 2020-08-17
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("sys_tenant")
+public class Tenant extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 实体主键
+     */
+    @TableId(type = IdType.INPUT)
+    private String id;
+    /**
+     * 租户颜色
+     */
+    private String color;
+    /**
+     * 租户名
+     */
+    @Query
+    private String name;
+    /**
+     * 租户开始日期
+     */
+    private Date beginDate;
+    /**
+     * 租户结束日期
+     */
+    private Date endDate;
+    /**
+     * 租户状态
+     */
+    private String status;
+    /**
+     * 绑定域名
+     */
+    private String domain;
+    /**
+     * 获取不存在的字段
+     */
+    @TableField(exist = false)
+    @Deprecated
+    private String tenantId;
+
+
+}

+ 134 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/User.java

@@ -0,0 +1,134 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.domain;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jeeplus.core.domain.BaseEntity;
+import com.jeeplus.core.query.Query;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 用户Entity
+ *
+ * @author jeeplus
+ * @version 2021-12-05
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("sys_user")
+public class User extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 归属公司
+     */
+    private String companyId;
+
+    /**
+     * 归属部门
+     */
+    private String officeId;
+
+    /**
+     * 登录名
+     */
+    @Query
+    private String loginName;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * 工号
+     */
+    private String no;
+
+    /**
+     * 姓名
+     */
+    @Query
+    private String name;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 电话
+     */
+    private String phone;
+
+    /**
+     * 手机
+     */
+    private String mobile;
+
+    /**
+     * 最后登录IP
+     */
+    private String loginIp;
+
+    /**
+     * 最后登录日期
+     */
+    private Date loginDate;
+
+    /**
+     * 是否允许登陆
+     */
+    private String loginFlag;
+
+    /**
+     * 头像
+     */
+    private String photo;
+
+    /**
+     * 二维码
+     */
+    private String qrCode;
+
+    /**
+     * 签名
+     */
+    private String sign;
+
+
+    /**
+     * 平台超级管理员标志
+     */
+    private Boolean isAdmin;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    private String manageOfficeIds;   //管理的部门id
+
+    private String UpPassword;//用户的密码是否修改
+
+    /**
+     * 构造函数
+     */
+    public User() {
+
+    }
+
+    /**
+     * 构造函数
+     */
+    public User(String id) {
+        super ( id );
+    }
+
+
+}

+ 29 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/ConfigApiFallbackFactory.java

@@ -0,0 +1,29 @@
+package com.jeeplus.sys.factory;
+
+import com.jeeplus.sys.feign.IConfigApi;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * 配置信息服务降级处理
+ *
+ * @author jeeplus
+ */
+
+@Slf4j
+@Component
+public class ConfigApiFallbackFactory implements FallbackFactory <IConfigApi> {
+    @Override
+    public IConfigApi create(Throwable throwable) {
+        log.error ( "配置服务调用失败:{}", throwable.getMessage ( ) );
+        throwable.printStackTrace ( );
+        return new IConfigApi ( ) {
+
+            @Override
+            public String getProductName(String tenantId) {
+                return null;
+            }
+        };
+    }
+}

+ 40 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/DictApiFallbackFactory.java

@@ -0,0 +1,40 @@
+package com.jeeplus.sys.factory;
+
+import com.jeeplus.sys.feign.IDictApi;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 字典服务降级处理
+ *
+ * @author jeeplus
+ */
+
+@Slf4j
+@Component
+public class DictApiFallbackFactory implements FallbackFactory <IDictApi> {
+    @Override
+    public IDictApi create(Throwable throwable) {
+        log.error ( "字典服务调用失败:{}", throwable.getMessage ( ) );
+        throwable.printStackTrace ( );
+        return new IDictApi ( ) {
+            @Override
+            public String getDictValue(String label, String type, String defaultValue) {
+                return null;
+            }
+
+            @Override
+            public String getDictLabel(String value, String type, String defaultLabel) {
+                return null;
+            }
+
+            @Override
+            public String getDictMap(String dict) {
+                return null;
+            }
+        };
+    }
+}

+ 29 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/LogApiFallbackFactory.java

@@ -0,0 +1,29 @@
+package com.jeeplus.sys.factory;
+
+import com.jeeplus.sys.domain.Log;
+import com.jeeplus.sys.feign.ILogApi;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * 日志服务降级处理
+ *
+ * @author jeeplus
+ */
+@Slf4j
+@Component
+public class LogApiFallbackFactory implements FallbackFactory <ILogApi> {
+
+    @Override
+    public ILogApi create(Throwable throwable) {
+        log.error ( "日志服务调用失败:{}", throwable.getMessage ( ) );
+        throwable.printStackTrace ( );
+        return new ILogApi ( ) {
+            @Override
+            public void save(Log log) {
+
+            }
+        };
+    }
+}

+ 62 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/OfficeApiFallbackFactory.java

@@ -0,0 +1,62 @@
+package com.jeeplus.sys.factory;
+
+import com.jeeplus.sys.domain.Office;
+import com.jeeplus.sys.feign.IOfficeApi;
+import com.jeeplus.sys.service.dto.OfficeDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 机构服务降级处理
+ *
+ * @author jeeplus
+ */
+
+@Slf4j
+@Component
+public class OfficeApiFallbackFactory implements FallbackFactory <IOfficeApi> {
+    @Override
+    public IOfficeApi create(Throwable throwable) {
+        log.error ( "机构服务调用失败:{}", throwable.getMessage ( ) );
+        throwable.printStackTrace ( );
+        return new IOfficeApi ( ) {
+            @Override
+            public OfficeDTO getOfficeDTOByName(String name) {
+                return null;
+            }
+
+            @Override
+            public Office selectById(String id) {
+                return null;
+            }
+
+            @Override
+            public OfficeDTO getOfficeById(String id) {
+                return null;
+            }
+
+            @Override
+            public List<String> getOfficeNameByIds(List<String> ids) {
+                return null;
+            }
+
+            @Override
+            public List<Office> selectListByParentId(String parentId) {
+                return null;
+            }
+
+            @Override
+            public List<Office> selectListByIsPublic(String isPublic) {
+                return null;
+            }
+
+            @Override
+            public OfficeDTO getParentOfficeById(String id) {
+                return null;
+            }
+        };
+    }
+}

+ 35 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/PostApiFallbackFactory.java

@@ -0,0 +1,35 @@
+package com.jeeplus.sys.factory;
+
+import com.jeeplus.sys.feign.IPostApi;
+import com.jeeplus.sys.service.dto.PostDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * 岗位服务降级处理
+ *
+ * @author jeeplus
+ */
+
+@Slf4j
+@Component
+public class PostApiFallbackFactory implements FallbackFactory <IPostApi> {
+    @Override
+    public IPostApi create(Throwable throwable) {
+        log.error ( "角色服务调用失败:{}", throwable.getMessage ( ) );
+        throwable.printStackTrace ( );
+        return new IPostApi ( ) {
+
+            @Override
+            public PostDTO getPostDTOByName(String name) {
+                return null;
+            }
+
+            @Override
+            public String getPostDTOByNameJSON(String name) {
+                return null;
+            }
+        };
+    }
+}

+ 48 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/RoleApiFallbackFactory.java

@@ -0,0 +1,48 @@
+package com.jeeplus.sys.factory;
+
+import com.jeeplus.sys.feign.IRoleApi;
+import com.jeeplus.sys.service.dto.RoleDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 角色服务降级处理
+ *
+ * @author jeeplus
+ */
+
+@Slf4j
+@Component
+public class RoleApiFallbackFactory implements FallbackFactory <IRoleApi> {
+    @Override
+    public IRoleApi create(Throwable throwable) {
+        log.error ( "角色服务调用失败:{}", throwable.getMessage ( ) );
+        throwable.printStackTrace ( );
+        return new IRoleApi ( ) {
+
+            @Override
+            public RoleDTO getRoleDTOByName(String name) {
+                return null;
+            }
+
+            @Override
+            public List<RoleDTO> getRoleDTOByNameAndTenantId(Map<String, String> keyMap) {
+                return null;
+            }
+
+            @Override
+            public RoleDTO getRoleDTOByName2(String name) {
+                return null;
+            }
+
+            @Override
+            public RoleDTO getRoleDTOById(String id) {
+                return null;
+            }
+        };
+    }
+}

+ 29 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/TenantApiFallbackFactory.java

@@ -0,0 +1,29 @@
+package com.jeeplus.sys.factory;
+
+import com.jeeplus.sys.feign.ITenantApi;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * 租户服务降级处理
+ *
+ * @author jeeplus
+ */
+
+@Slf4j
+@Component
+public class TenantApiFallbackFactory implements FallbackFactory <ITenantApi> {
+    @Override
+    public ITenantApi create(Throwable throwable) {
+        log.error ( "租户服务调用失败:{}", throwable.getMessage ( ) );
+        throwable.printStackTrace ( );
+        return new ITenantApi ( ) {
+
+            @Override
+            public String getCurrentTenantId() {
+                return null;
+            }
+        };
+    }
+}

+ 215 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/factory/UserApiFallbackFactory.java

@@ -0,0 +1,215 @@
+package com.jeeplus.sys.factory;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.google.common.collect.Lists;
+import com.jeeplus.sys.domain.User;
+import com.jeeplus.sys.feign.IUserApi;
+import com.jeeplus.sys.service.dto.CertDTO;
+import com.jeeplus.sys.service.dto.DataRuleDTO;
+import com.jeeplus.sys.service.dto.UserDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 用户服务降级处理
+ *
+ * @author jeeplus
+ */
+@Slf4j
+@Component
+public class UserApiFallbackFactory implements FallbackFactory <IUserApi> {
+    @Override
+    public IUserApi create(Throwable throwable) {
+        log.error ( "用户服务调用失败:{}", throwable.getMessage ( ) );
+        throwable.printStackTrace ( );
+        return new IUserApi ( ) {
+            @Override
+            public List<UserDTO> getAllUserInfos() {
+                return null;
+            }
+
+            @Override
+            public Integer selectCountByMobile(String mobile) {
+                return null;
+            }
+
+            @Override
+            public Map<String, Object> sendRandomCodes(String mobile, String randomCode) throws IOException {
+                return null;
+            }
+
+            public UserDTO getByLoginName(String loginName, String tenantId) {
+                return null;
+            }
+            public UserDTO getByLoginNameNotTenantId(String loginName) {
+                return null;
+            }
+
+            public void clearCache(UserDTO userDTO) {
+
+            }
+
+            public List <DataRuleDTO> getDataRuleList(UserDTO userDTO) {
+                return Lists.newArrayList ( );
+            }
+
+            @Override
+            public void updateUser(UserDTO userDTO) {
+
+            }
+
+            @Override
+            public void deleteById(String id) {
+
+            }
+
+            @Override
+            public Set <String> getPermissions(String loginName) {
+                return new HashSet <> ( );
+            }
+
+            @Override
+            public UserDTO getByToken(String token) {
+                return null;
+            }
+
+            @Override
+            public UserDTO getById(String id) {
+                return null;
+            }
+
+            @Override
+            public String getByIdForXXL(String id) {
+                return null;
+            }
+
+            @Override
+            public UserDTO getFlowAbleById(String id) {
+                return null;
+            }
+
+            @Override
+            public List <UserDTO> findListByPostId(String postId) {
+                return Lists.newArrayList ( );
+            }
+
+            @Override
+            public List<UserDTO> getAllUserInfo() {
+                return null;
+            }
+
+            @Override
+            public List <UserDTO> findListFlowAbleByPostId(String postId) {
+                return Lists.newArrayList ( );
+            }
+
+            @Override
+            public List<String> findIdListFlowAbleByPostId(String postId) {
+                return null;
+            }
+
+            @Override
+            public List <UserDTO> findListByRoleId(String roleId) {
+                return Lists.newArrayList ( );
+            }
+
+            @Override
+            public List <UserDTO> findListByCompanyId(String companyId) {
+                return Lists.newArrayList ( );
+            }
+
+            @Override
+            public List <UserDTO> findListByOfficeId(String officeId) {
+                return Lists.newArrayList ( );
+            }
+
+            @Override
+            public boolean isEnableLogin(String tenantId, String username) {
+                return true;
+            }
+
+            @Override
+            public UserDTO getUserDTOByName(String name) {
+                return null;
+            }
+
+            @Override
+            public void updateUserUpPassword(UserDTO userDTO) {
+
+            }
+
+            @Override
+            public String getSysParam(String parameter,String token) {
+                return null;
+            }
+
+            @Override
+            public List<CertDTO> getCertListByUserId() {
+                return null;
+            }
+
+            @Override
+            public String getFileDir(String url) {
+                return null;
+            }
+
+            @Override
+            public boolean delFile(String id) {
+                return false;
+            }
+
+            @Override
+            public List<UserDTO> getUserInfoByEnName(String enName) {
+                return null;
+            }
+
+            @Override
+            public List<User> selectListByName(String name) {
+                return null;
+            }
+
+            @Override
+            public List<User> getUserByOfficeAll(String operatorOffice) {
+                return null;
+            }
+
+            @Override
+            public IPage<UserDTO> findPage() {
+                return null;
+            }
+
+            @Override
+            public void saveOrUpdate(UserDTO userDTO) {
+
+            }
+
+            @Override
+            public String enterpriseSearchByName(String keyword) {
+                return null;
+            }
+
+            @Override
+            public String enterpriseTicketInfoQueryById(String id) {
+                return null;
+            }
+
+            @Override
+            public String getUserIdByName(String name) {
+                return null;
+            }
+
+            @Override
+            public Integer getUserPostCountById(String id) {
+                return null;
+            }
+
+        };
+    }
+}

+ 20 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/IConfigApi.java

@@ -0,0 +1,20 @@
+package com.jeeplus.sys.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.sys.factory.TenantApiFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@FeignClient(contextId = "configApi", name = AppNameConstants.APP_SYSTEM_SERVICE, fallbackFactory = TenantApiFallbackFactory.class)
+public interface IConfigApi {
+    /**
+     * 获取租户Id
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/config/getProductName")
+    String getProductName(@RequestParam("tenantId") String tenantId);
+
+
+}

+ 40 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/IDictApi.java

@@ -0,0 +1,40 @@
+package com.jeeplus.sys.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.sys.factory.DictApiFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+@FeignClient(contextId = "dictApi", name = AppNameConstants.APP_SYSTEM_SERVICE, fallbackFactory = DictApiFallbackFactory.class)
+public interface IDictApi {
+    /**
+     * 获取字典值
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/dict/getDictValue")
+    String getDictValue(@RequestParam(value = "label") String label, @RequestParam(value = "type") String type, @RequestParam(value = "defaultValue", required = false) String defaultValue);
+
+    /**
+     * 获取字典标签
+     *
+     * @param value
+     * @param type
+     * @param defaultLabel
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/dict/getDictLabel")
+    String getDictLabel(@RequestParam(value = "value") String value, @RequestParam(value = "type") String type, @RequestParam(value = "defaultLabel", required = false) String defaultLabel);
+
+    /**
+     * 获取字典标签
+     *
+     * @param dict
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/dict/getDictMap")
+    String getDictMap(@RequestParam(value = "dict") String dict);
+}

+ 18 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/ILogApi.java

@@ -0,0 +1,18 @@
+package com.jeeplus.sys.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.sys.domain.Log;
+import com.jeeplus.sys.factory.LogApiFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+@FeignClient(contextId = "logApi", name = AppNameConstants.APP_SYSTEM_SERVICE, fallbackFactory = LogApiFallbackFactory.class)
+public interface ILogApi {
+
+    /**
+     * 保存日志
+     */
+    @PostMapping(value = "/feign/log/save")
+    void save(@RequestBody Log log);
+}

+ 69 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/IOfficeApi.java

@@ -0,0 +1,69 @@
+package com.jeeplus.sys.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.sys.domain.Office;
+import com.jeeplus.sys.factory.OfficeApiFallbackFactory;
+import com.jeeplus.sys.service.dto.OfficeDTO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@FeignClient(contextId = "officeApi", name = AppNameConstants.APP_SYSTEM_SERVICE, fallbackFactory = OfficeApiFallbackFactory.class)
+public interface IOfficeApi {
+    /**
+     * 获取机构
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/office/getOfficeDTOByName")
+    OfficeDTO getOfficeDTOByName(@RequestParam(value = "name") String name);
+
+    /**
+     * 根据id获取组织
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/office/selectById")
+    Office selectById(@RequestParam(value = "id") String id);
+
+    /**
+     * 根据office.id 查询部门的所有父节点信息
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/office/getOfficeById")
+    OfficeDTO getOfficeById(@RequestParam(value = "id") String id);
+
+    /**
+     * 根据当前人管理的部门id查询这些部门信息
+     * @param ids
+     * @return
+     */
+    @RequestMapping(value = "/feign/sys/office/getOfficeNameByIds", method = RequestMethod.POST)
+    List<String> getOfficeNameByIds(@RequestBody List<String> ids);
+
+    /**
+     * 根据父级id查询组织信息
+     * @param parentId
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/office/selectListByParentId")
+    List<Office> selectListByParentId(@RequestParam(value = "parentId")String parentId);
+
+    /**
+     * 根据父级id查询组织信息
+     * @param isPublic
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/office/selectListByIsPublic")
+    List<Office> selectListByIsPublic(@RequestParam(value = "isPublic")String isPublic);
+
+    /**
+     * 根据id 查询父级部门信息
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/office/getParentOfficeById")
+    OfficeDTO getParentOfficeById(@RequestParam(value = "id") String id);
+}

+ 27 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/IPostApi.java

@@ -0,0 +1,27 @@
+package com.jeeplus.sys.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.sys.factory.PostApiFallbackFactory;
+import com.jeeplus.sys.service.dto.PostDTO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@FeignClient(contextId = "postApi", name = AppNameConstants.APP_SYSTEM_SERVICE, fallbackFactory = PostApiFallbackFactory.class)
+public interface IPostApi {
+    /**
+     * 获取角色
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/dict/getPostDTOByName")
+    PostDTO getPostDTOByName(@RequestParam(value = "name") String name);
+
+    /**
+     * 获取角色
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/dict/getPostDTOByNameJSON")
+    String getPostDTOByNameJSON(@RequestParam(value = "name") String name);
+}

+ 44 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/IRoleApi.java

@@ -0,0 +1,44 @@
+package com.jeeplus.sys.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.sys.factory.RoleApiFallbackFactory;
+import com.jeeplus.sys.service.dto.RoleDTO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@FeignClient(contextId = "roleApi", name = AppNameConstants.APP_SYSTEM_SERVICE, fallbackFactory = RoleApiFallbackFactory.class)
+public interface IRoleApi {
+    /**
+     * 获取角色
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/role/getRoleDTOByName")
+    RoleDTO getRoleDTOByName(@RequestParam(value = "name") String name);
+
+    /**
+     * 获取角色
+     *
+     * @return
+     */
+    @RequestMapping(value = "/feign/sys/role/getRoleDTOByNameAndTenantId", method = RequestMethod.POST)
+    List<RoleDTO> getRoleDTOByNameAndTenantId(@RequestBody Map<String ,String > keyMap);
+    /**
+     * 获取角色
+     *
+     * @return
+     */
+    @GetMapping(value = "/sys/role/getRoleDTOByName2")
+    RoleDTO getRoleDTOByName2(@RequestParam(value = "name") String name);
+    /**
+     * 获取角色
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/role/getRoleDTOById")
+    RoleDTO getRoleDTOById(@RequestParam(value = "id") String id);
+
+}

+ 18 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/ITenantApi.java

@@ -0,0 +1,18 @@
+package com.jeeplus.sys.feign;
+
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.sys.factory.TenantApiFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+
+@FeignClient(contextId = "tenantApi", name = AppNameConstants.APP_SYSTEM_SERVICE, fallbackFactory = TenantApiFallbackFactory.class)
+public interface ITenantApi {
+    /**
+     * 获取租户Id
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/tenant/getCurrentTenantId")
+    String getCurrentTenantId();
+
+}

+ 310 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/feign/IUserApi.java

@@ -0,0 +1,310 @@
+package com.jeeplus.sys.feign;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.jeeplus.common.constant.AppNameConstants;
+import com.jeeplus.sys.domain.User;
+import com.jeeplus.sys.factory.UserApiFallbackFactory;
+import com.jeeplus.sys.service.dto.CertDTO;
+import com.jeeplus.sys.service.dto.DataRuleDTO;
+import com.jeeplus.sys.service.dto.UserDTO;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+@FeignClient(contextId = "userApi", name = AppNameConstants.APP_SYSTEM_SERVICE, fallbackFactory = UserApiFallbackFactory.class)
+public interface IUserApi {
+
+    String BASE_URL = "/feign/sys/user";
+
+    @RequestMapping(value = BASE_URL + "/getAllUserInfos", method = RequestMethod.GET)
+    List<UserDTO> getAllUserInfos();
+
+    /**
+     * 根据联系电话查询用户
+     * @return
+     */
+    @RequestMapping(value = BASE_URL + "/selectCountByMobile", method = RequestMethod.POST)
+    Integer selectCountByMobile(@RequestParam(value = "mobile")String mobile);
+    /**
+     * 发送短信
+     * @param mobile
+     * @param randomCode
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/sendRandomCodes")
+    Map<String ,Object> sendRandomCodes(@RequestParam(value = "mobile")String mobile, @RequestParam(value = "randomCode")String randomCode) throws IOException;
+
+    /**
+     * 根据登录名获取用户
+     *
+     * @param loginName
+     * @return 取不到返回null
+     */
+    @GetMapping(value = BASE_URL + "/getByLoginName")
+    UserDTO getByLoginName(@RequestParam(value = "loginName") String loginName, @RequestParam(value = "tenantId") String tenantId);
+
+    /**
+     * 根据登录名获取用户
+     *
+     * @param loginName
+     * @return 取不到返回null
+     */
+    @GetMapping(value = BASE_URL + "/getByLoginNameNotTenantId")
+    UserDTO getByLoginNameNotTenantId(@RequestParam(value = "loginName") String loginName);
+
+    /**
+     * 清除用户缓存
+     */
+    @PostMapping(value = BASE_URL + "/clearCache")
+    void clearCache(@RequestBody UserDTO userDTO);
+
+    /**
+     * 获取用户数据权限
+     */
+
+    @PostMapping(value = BASE_URL + "/getDataRuleList")
+    List <DataRuleDTO> getDataRuleList(@RequestBody UserDTO userDTO);
+
+    /**
+     * 更新用户
+     *
+     * @param userDTO
+     */
+    @PostMapping(value = BASE_URL + "/updateUser")
+    void updateUser(@RequestBody UserDTO userDTO);
+
+    /**
+     * 根据id删除用户
+     * @param id
+     */
+    @PostMapping(value = BASE_URL + "/deleteById")
+    void deleteById(@RequestParam("id") String id);
+
+    /**
+     * 获取用户访问权限
+     *
+     * @param loginName
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/getPermissions")
+    Set <String> getPermissions(@RequestParam(value = "loginName") String loginName);
+
+    /**
+     * 获取token获取当前登录用户
+     *
+     * @return
+     */
+    @RequestMapping(value = BASE_URL + "/getByToken", method = RequestMethod.POST)
+    UserDTO getByToken(@RequestParam("token") String token);
+
+    /**
+     * 根据id获取用户
+     *
+     * @param id
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/getById")
+    UserDTO getById(@RequestParam("id") String id);
+
+    /**
+     * 根据id获取用户
+     *
+     * @param id
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/getByIdForXXL")
+    String getByIdForXXL(@RequestParam("id") String id);
+
+    /**
+     * 根据id获取用户
+     *
+     * @param id
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/getFlowAbleById")
+    UserDTO getFlowAbleById(@RequestParam("id") String id);
+
+    /**
+     * 根据岗位id获取用户列表
+     *
+     * @param postId
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/findListByPostId")
+    List <UserDTO> findListByPostId(@RequestParam("postId") String postId);
+
+    /**
+     * 获取所有的用户信息
+     *
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/getAllUserInfo")
+    List <UserDTO> getAllUserInfo();
+
+    /**
+     * 根据岗位id获取用户列表
+     *
+     * @param postId
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/findListFlowAbleByPostId")
+    List <UserDTO> findListFlowAbleByPostId(@RequestParam("postId") String postId);
+
+    /**
+     * 根据岗位id获取用户列表
+     *
+     * @param postId
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/findIdListFlowAbleByPostId")
+    List <String> findIdListFlowAbleByPostId(@RequestParam("postId") String postId);
+
+    /**
+     * 根据角色id获取用户列表
+     *
+     * @param roleId
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/findListByRoleId")
+    List <UserDTO> findListByRoleId(@RequestParam("roleId") String roleId);
+
+    /**
+     * 根据公司id获取用户列表
+     *
+     * @param companyId
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/findListByCompanyId")
+    List <UserDTO> findListByCompanyId(@RequestParam("companyId") String companyId);
+
+    /**
+     * 根据部门id获取用户列表
+     *
+     * @param officeId
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/findListByOfficeId")
+    List <UserDTO> findListByOfficeId(@RequestParam("officeId") String officeId);
+
+    /**
+     * 单一登录逻辑处理
+     *
+     * @param loginName
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/isEnableLogin")
+    boolean isEnableLogin(@RequestParam("tenantId") String tenantId, @RequestParam("loginName") String loginName);
+
+    /**
+     * 获取角色
+     *
+     * @return
+     */
+    @GetMapping(value = "/feign/sys/user/getUserDTOByName")
+    UserDTO getUserDTOByName(@RequestParam(value = "name") String name);
+
+    /**
+     * 修改用户更新密码状态信息
+     *
+     * @param userDTO
+     * @return 取不到返回null
+     */
+    @GetMapping(value = BASE_URL + "/updateUserUpPassword")
+    void updateUserUpPassword(@RequestBody UserDTO userDTO);
+
+    /**
+     * 获取系统参数
+     * @param parameter
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/getSysParam")
+    String getSysParam(@RequestParam(value = "parameter") String parameter,@RequestParam(value = "token") String token);
+
+    @GetMapping(value = BASE_URL + "/getCertListByUserId")
+    List<CertDTO> getCertListByUserId();
+
+    /**
+     * 获取文件的Dir
+     * @param url
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/getFileDir")
+    String getFileDir(@RequestParam(value = "url")String url);
+
+    /**
+     * 删除文件
+     * @param id
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/delFile")
+    boolean delFile(@RequestParam(value = "id")String id);
+
+    /**
+     * 根据角色英文名称查询角色下人员信息
+     * @param enName 角色英文名称
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/getUserInfoByEnName")
+    List<UserDTO> getUserInfoByEnName(@RequestParam(value = "enName")String enName);
+
+    /**
+     * 根据姓名查询用户信息
+     * @param name
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/selectListByName")
+    List<User> selectListByName(@RequestParam(value = "name")String name);
+
+    /**
+     * 根据经办人部门查询所有的用户信息
+     * @param operatorOffice
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/getUserByOfficeAll")
+    List<User> getUserByOfficeAll(@RequestParam(value = "operatorOffice")String operatorOffice);
+
+    @GetMapping(value = BASE_URL + "/findPage")
+    IPage<UserDTO> findPage();
+
+    @RequestMapping(value = BASE_URL + "/saveOrUpdate", method = RequestMethod.POST)
+    void saveOrUpdate(@RequestBody UserDTO userDTO);
+
+    /**
+     * 根据关键字查询相关企业
+     * @param keyword
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/enterpriseSearchByName")
+    String enterpriseSearchByName(@RequestParam(value = "keyword")String keyword);
+
+    /**
+     * 根据id查询企业税号
+     * @param id
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/enterpriseTicketInfoQueryById")
+    String enterpriseTicketInfoQueryById(@RequestParam(value = "id")String id);
+
+    /**
+     * 根据用户name获取用户id
+     * @param name
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/getUserIdByName")
+    String getUserIdByName(@RequestParam(value = "name")String name);
+
+    /**
+     * 根据用户id查询是否存在“部门主任”岗位
+     * @param id
+     * @return
+     */
+    @GetMapping(value = BASE_URL + "/getUserPostCountById")
+    Integer getUserPostCountById(@RequestParam(value = "id")String id);
+}
+
+

+ 41 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/AreaDTO.java

@@ -0,0 +1,41 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.service.dto;
+
+import com.jeeplus.core.service.dto.TreeDTO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.Size;
+
+/**
+ * 区域DTO
+ *
+ * @author jeeplus
+ * @version 2021-05-15
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class AreaDTO extends TreeDTO <AreaDTO> {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 区域编码
+     */
+    @Size(min = 0, max = 64)
+    private String code;
+
+    /**
+     * 区域类型(1:国家;2:省份、直辖市;3:地市;4:区县)
+     */
+    @Size(min = 1, max = 1)
+    private String type;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+}

+ 88 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/CertDTO.java

@@ -0,0 +1,88 @@
+package com.jeeplus.sys.service.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.jeeplus.core.service.dto.BaseDTO;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 组织机构-人员资质-人员职业资格证
+ * @TableName sys_cert
+ */
+@Data
+public class CertDTO extends BaseDTO {
+
+    /**
+     * 备注信息
+     */
+    private String remarks;
+
+    /**
+     * 人员id
+     */
+    private String userId;
+
+    /**
+     * 证书类型
+     */
+    private String type;
+
+    /**
+     * 证书编号
+     */
+    private String no;
+
+    /**
+     * 发证机关
+     */
+    private String authorities;
+
+    /**
+     * 发证日期
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date issuedDate;
+
+    /**
+     * 注册日期
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date enrollDate;
+
+    /**
+     * 到期日期
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date expireDate;
+
+    /**
+     * 注册证书编号
+     */
+    private String enrollCertNo;
+
+    /**
+     * 专业
+     */
+    private String profession;
+
+    /**
+     * 文件地址
+     */
+    private String fileUrl;
+
+    /**
+     * 文件临时地址
+     */
+    private String fileLsUrl;
+
+    private static final long serialVersionUID = 1L;
+
+
+
+    private String certType;
+}

+ 77 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/DataRuleDTO.java

@@ -0,0 +1,77 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.service.dto;
+
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HtmlUtil;
+import com.jeeplus.core.service.dto.BaseDTO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 数据权限Entity
+ *
+ * @author lgf
+ * @version 2021-04-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DataRuleDTO extends BaseDTO {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 所属菜单
+     */
+    private String menuId;
+
+    /**
+     * 数据规则名称
+     */
+    private String name;
+
+    /**
+     * 实体类名
+     */
+    private String className;
+
+    /**
+     * 规则字段
+     */
+    private String field;
+
+    /**
+     * 规则条件
+     */
+    private String express;
+
+    /**
+     * 规则值
+     */
+    private String value;
+
+    /**
+     * 自定义sql
+     */
+    private String sqlSegment;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+
+    public String getDataScopeSql() {
+        StringBuffer sqlBuffer = new StringBuffer ( );
+        if ( StrUtil.isNotBlank ( field ) && StrUtil.isNotBlank ( value ) ) {
+            sqlBuffer.append ( field + " " + HtmlUtil.unescape ( express ) + " " + value + " " );
+        }
+        if ( StrUtil.isNotBlank ( sqlSegment ) ) {
+            sqlBuffer.append ( HtmlUtil.unescape ( sqlSegment ) + " " );
+        }
+
+        return sqlBuffer.toString ( );
+    }
+}

+ 39 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/DictTypeInfoDTO.java

@@ -0,0 +1,39 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.service.dto;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.core.service.dto.BaseDTO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * 数据字典Entity
+ *
+ * @author lgf
+ * @version 2021-01-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DictTypeInfoDTO extends BaseDTO {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 类型
+     */
+    private String type;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 子表列表
+     */
+    private List <DictValueInfoDTO> dictValueDTOList = Lists.newArrayList ( );
+}

+ 57 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/DictValueInfoDTO.java

@@ -0,0 +1,57 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.service.dto;
+
+
+import com.jeeplus.core.service.dto.BaseDTO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 数据字典Entity
+ *
+ * @author lgf
+ * @version 2021-05-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DictValueInfoDTO extends BaseDTO {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 标签页
+     */
+    private String label;
+
+    /**
+     * 键值
+     */
+    private String value;
+
+    /**
+     * 排序
+     */
+    private String sort;
+
+    /**
+     * 字典类型
+     */
+    private DictTypeInfoDTO dictTypeDTO;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 构造函数
+     *
+     * @param dictTypeDTO
+     */
+    public DictValueInfoDTO(DictTypeInfoDTO dictTypeDTO) {
+        this.dictTypeDTO = dictTypeDTO;
+    }
+
+}

+ 109 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/MenuDTO.java

@@ -0,0 +1,109 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.service.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.jeeplus.core.service.dto.TreeDTO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.Size;
+import java.util.List;
+
+/**
+ * 菜单Entity
+ *
+ * @author jeeplus
+ * @version 2021-05-15
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class MenuDTO extends TreeDTO <MenuDTO> {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 多语言编码
+     */
+    private String code;
+
+    /**
+     * 链接
+     */
+    @Size(min = 0, max = 2000)
+    private String href;
+
+    /**
+     * 目标( iframe 1)
+     */
+    @Size(min = 0, max = 20)
+    private String target;
+
+    /**
+     * 图标
+     */
+    @Size(min = 0, max = 100)
+    private String icon;
+
+    /**
+     * 是否在菜单中显示(1:显示;0:不显示)
+     */
+    @Size(min = 1, max = 1)
+    private String isShow;
+
+    /**
+     * 按钮类型
+     */
+    private String type;
+
+    /**
+     * 权限标识
+     */
+    @Size(min = 0, max = 200)
+    private String permission;
+
+    /**
+     * 数据权限
+     */
+    private List <DataRuleDTO> dataRuleDTOList;
+
+    /**
+     * 用户ID
+     */
+    private String userId;
+
+    /**
+     * 是否固定在标签页
+     */
+    private String affix;
+
+    /**
+     * 隐藏面包屑
+     */
+    private String hiddenBreadcrumb;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 排序
+     *
+     * @param list
+     * @param sourceList
+     * @param parentId
+     */
+    @JsonIgnore
+    public static void sortList(List <MenuDTO> list, List <MenuDTO> sourceList, String parentId) {
+        for (int i = 0; i < sourceList.size ( ); i++) {
+            MenuDTO e = sourceList.get ( i );
+            if ( e.getParent ( ) != null && parentId.equals ( e.getParent ( ).getId ( ) ) ) {
+                list.add ( e );
+            }
+        }
+    }
+
+
+}

+ 114 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/OfficeDTO.java

@@ -0,0 +1,114 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.service.dto;
+
+import com.jeeplus.core.service.dto.TreeDTO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.Size;
+import java.util.List;
+
+/**
+ * 机构Entity
+ *
+ * @author jeeplus
+ * @version 2021-05-15
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class OfficeDTO extends TreeDTO <OfficeDTO> {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 是否公用
+     */
+    private String isPublic;
+
+    private String tenantId;
+    /**
+     * 归属区域
+     */
+    private String area;
+
+    /**
+     * 机构编码
+     */
+    @Size(min = 0, max = 64)
+    private String code;
+
+    /**
+     * 机构类型(1:公司;2:部门)
+     */
+    @Size(min = 1, max = 1)
+    private String type;
+
+    /**
+     * 机构等级(1:一级;2:二级;3:三级;4:四级)
+     */
+    @Size(min = 1, max = 1)
+    private String grade;
+
+    /**
+     * 联系地址
+     */
+    @Size(min = 0, max = 255)
+    private String address;
+
+    /**
+     * 邮政编码
+     */
+    @Size(min = 0, max = 64)
+    private String zipCode;
+
+    /**
+     * 负责人
+     */
+    private String master;
+
+    /**
+     * 电话
+     */
+    @Size(max = 64)
+    private String phone;
+
+    /**
+     * 传真
+     */
+    @Size(max = 64)
+    private String fax;
+
+    /**
+     * 邮箱
+     */
+    @Size(max = 64)
+    private String email;
+
+    /**
+     * 是否可用
+     */
+    private String useable;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 子部门
+     */
+    private List <String> childDeptList;
+
+    /**
+     * 是否可用
+     */
+    private boolean disabled = false;
+
+    /**
+     * 是否可用
+     */
+    private boolean typeFlag = false;
+
+}

+ 65 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/PostDTO.java

@@ -0,0 +1,65 @@
+/**
+ * Copyright © 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.service.dto;
+
+import com.jeeplus.core.service.dto.BaseDTO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * 岗位Entity
+ *
+ * @author 刘高峰
+ * @version 2021-08-17
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class PostDTO extends BaseDTO {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 岗位名称
+     */
+    @NotEmpty
+    private String name;
+
+    /**
+     * 岗位编码
+     */
+    @NotEmpty
+    private String code;
+
+    /**
+     * 岗位类型
+     */
+    @NotEmpty
+    private String type;
+
+    /**
+     * 岗位状态
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 岗位排序
+     */
+    private Integer sort;        // 岗位排序
+
+    public PostDTO() {
+        super ( );
+    }
+
+    public PostDTO(String id) {
+        super ( id );
+    }
+
+}

+ 166 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/RoleDTO.java

@@ -0,0 +1,166 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.service.dto;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.common.collect.Lists;
+import com.jeeplus.config.swagger.IgnoreSwaggerParameter;
+import com.jeeplus.core.service.dto.BaseDTO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.apache.commons.lang3.StringUtils;
+import org.hibernate.validator.constraints.Length;
+
+import java.util.List;
+
+/**
+ * 角色Entity
+ *
+ * @author jeeplus
+ * @version 2021-09-05
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class RoleDTO extends BaseDTO {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 角色名称
+     */
+    @Length(min = 1, max = 100)
+    private String name;
+
+    /**
+     * 英文名称
+     */
+    @Length(min = 1, max = 100)
+    private String enName;
+
+    /**
+     * 原角色名称
+     */
+    private String oldName;
+
+    /**
+     * 原英文名称
+     */
+    private String oldEnName;
+
+    /**
+     * 是否是系统数据
+     */
+    private String sysData;
+
+    /**
+     * 是否是可用
+     */
+    private String useable;
+
+    /**
+     * 根据用户ID查询角色列表
+     */
+    @IgnoreSwaggerParameter
+    private UserDTO userDTO;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 拥有菜单列表
+     */
+    @JsonIgnore
+    private List <MenuDTO> menuDTOList = Lists.newArrayList ( );
+
+    /**
+     * 数据范围
+     */
+    @JsonIgnore
+    private List <DataRuleDTO> dataRuleDTOList = Lists.newArrayList ( );
+
+    public RoleDTO() {
+    }
+
+    public RoleDTO(String id) {
+        super ( id );
+    }
+
+    @JsonIgnore
+    public List <String> getMenuIdList() {
+        List <String> menuIdList = Lists.newArrayList ( );
+        for (MenuDTO menu : menuDTOList) {
+            menuIdList.add ( menu.getId ( ) );
+        }
+        return menuIdList;
+    }
+
+    public void setMenuIdList(List <String> menuIdList) {
+        menuDTOList = Lists.newArrayList ( );
+        for (String menuId : menuIdList) {
+            MenuDTO menuDTO = new MenuDTO ( );
+            menuDTO.setId ( menuId );
+            menuDTOList.add ( menuDTO );
+        }
+    }
+
+    public String getMenuIds() {
+        return StringUtils.join ( getMenuIdList ( ), "," );
+    }
+
+    public void setMenuIds(String menuIds) {
+        menuDTOList = Lists.newArrayList ( );
+        if ( menuIds != null ) {
+            String[] ids = StringUtils.split ( menuIds, "," );
+            setMenuIdList ( Lists.newArrayList ( ids ) );
+        }
+    }
+
+
+    /**
+     * 获取权限字符串列表
+     */
+    public List <String> getPermissions() {
+        List <String> permissions = Lists.newArrayList ( );
+        for (MenuDTO menuDTO : menuDTOList) {
+            if ( menuDTO.getPermission ( ) != null && !"".equals ( menuDTO.getPermission ( ) ) ) {
+                permissions.add ( menuDTO.getPermission ( ) );
+            }
+        }
+        return permissions;
+    }
+
+
+    @JsonIgnore
+    public List <String> getDataRuleIdList() {
+        List <String> dataRuleIdList = Lists.newArrayList ( );
+        for (DataRuleDTO dataRule : dataRuleDTOList) {
+            dataRuleIdList.add ( dataRule.getId ( ) );
+        }
+        return dataRuleIdList;
+    }
+
+    public void setDataRuleIdList(List <String> dataRuleIdList) {
+        dataRuleDTOList = Lists.newArrayList ( );
+        for (String dataRuleId : dataRuleIdList) {
+            DataRuleDTO dataRuleDTO = new DataRuleDTO ( );
+            dataRuleDTO.setId ( dataRuleId );
+            dataRuleDTOList.add ( dataRuleDTO );
+        }
+    }
+
+    public String getDataRuleIds() {
+        return StringUtils.join ( getDataRuleIdList ( ), "," );
+    }
+
+    public void setDataRuleIds(String dataRuleIds) {
+        dataRuleDTOList = Lists.newArrayList ( );
+        if ( dataRuleIds != null ) {
+            String[] ids = StringUtils.split ( dataRuleIds, "," );
+            setDataRuleIdList ( Lists.newArrayList ( ids ) );
+        }
+    }
+
+}

+ 52 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/TenantDTO.java

@@ -0,0 +1,52 @@
+/**
+ * Copyright © 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.service.dto;
+
+import com.jeeplus.core.query.Query;
+import com.jeeplus.core.service.dto.BaseDTO;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 岗位Entity
+ *
+ * @author 刘高峰
+ * @version 2020-08-17
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class TenantDTO extends BaseDTO {
+
+    private static final long serialVersionUID = 1L;
+    /**
+     * 租户名
+     */
+    @Query
+    private String name;
+
+    /**
+     * 租户颜色
+     */
+    private String color;
+    /**
+     * 租户开始日期
+     */
+    private Date beginDate;
+    /**
+     * 租户结束日期
+     */
+    private Date endDate;
+    /**
+     * 租户状态
+     */
+    private String status;
+    /**
+     * 绑定域名
+     */
+    private String domain;
+
+
+}

+ 377 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/UserDTO.java

@@ -0,0 +1,377 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.sys.service.dto;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.common.collect.Lists;
+import com.jeeplus.common.excel.annotation.ExcelDictProperty;
+import com.jeeplus.config.swagger.IgnoreSwaggerParameter;
+import com.jeeplus.core.excel.converter.ExcelDictDTOConverter;
+import com.jeeplus.core.excel.converter.ExcelOfficeDTOConverter;
+import com.jeeplus.core.excel.converter.ExcelPostListDTOConverter;
+import com.jeeplus.core.excel.converter.ExcelRoleListDTOConverter;
+import com.jeeplus.core.query.Query;
+import com.jeeplus.core.query.QueryType;
+import com.jeeplus.core.service.dto.BaseDTO;
+import com.jeeplus.sys.feign.ITenantApi;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 用户Entity
+ *
+ * @author jeeplus
+ * @version 2021-12-05
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class UserDTO extends BaseDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 财务公司签字注师被选择次数
+     */
+    private Integer accountantUserFlag;
+
+    /**
+     * 财务公司签字注师被选择次数
+     */
+    private Integer accountantUserCount;
+
+    /**
+     * 执业资格证类型
+     */
+    private String certType;
+
+    /**
+     * 前端组件传‘true’则查询全部
+     */
+    private String selectAll;
+
+    /**
+     * 角色信息
+     */
+    private List<RoleDTO> roleList;
+
+    private String manageOfficeIds;   //管理的部门id
+
+    /**
+     * 管理的部门名称
+     */
+    private List<String> manageOfficeNameList;
+
+    /**
+     * 执业资格证列表
+     */
+    private List<CertDTO> certDTOList;
+
+    private OfficeDTO corporationDTO;   //公司信息
+
+
+    /**
+     * 登录名
+     */
+    @Length(min = 1, max = 100)
+    @Query
+    @ExcelProperty("登录名")
+    private String loginName;
+
+    /**
+     * 密码
+     */
+    @Length(min = 1, max = 100)
+    @ExcelIgnore
+    private String password;
+
+
+    /**
+     * 姓名
+     */
+    @Length(min = 1, max = 100)
+    @Query(tableColumn = "a.name")
+    @ExcelProperty("姓名")
+    private String name;
+
+
+    /**
+     * 工号
+     */
+    @Length(min = 1, max = 100)
+    @ExcelProperty("工号")
+    private String no;
+
+    /**
+     * 归属公司
+     */
+    @NotNull(message = "公司不能为空")
+    @Query(type = QueryType.EQ, tableColumn = "c.id", javaField = "companyDTO.id")
+    @IgnoreSwaggerParameter
+    @ExcelProperty(value = "公司", converter = ExcelOfficeDTOConverter.class)
+    private OfficeDTO companyDTO;
+
+    /**
+     * 归属部门
+     */
+    @NotNull(message = "部门不能为空")
+    @Query(type = QueryType.EQ, tableColumn = "o.id", javaField = "officeDTO.id")
+    @IgnoreSwaggerParameter
+    @ExcelProperty(value = "部门", converter = ExcelOfficeDTOConverter.class)
+    private OfficeDTO officeDTO;
+
+    /**
+     * 邮箱
+     */
+    @Email(message = "邮箱格式不正确")
+    @Length(min = 0, max = 100)
+    @ExcelProperty("邮箱")
+    private String email;
+
+    /**
+     * 电话
+     */
+    @Length(min = 0, max = 100)
+    @ExcelProperty("电话")
+    private String phone;
+
+    /**
+     * 手机
+     */
+    @Length(min = 0, max = 100)
+    @ExcelProperty("手机")
+    private String mobile;
+
+    /**
+     * 最后登录IP
+     */
+    @IgnoreSwaggerParameter
+    @ExcelIgnore
+    private String loginIp;
+
+    /**
+     * 最后登录日期
+     */
+    @IgnoreSwaggerParameter
+    @ExcelIgnore
+    private Date loginDate;
+
+    /**
+     * 是否允许登录
+     */
+    @ExcelProperty(value = "是否允许登录", converter = ExcelDictDTOConverter.class)
+    @ExcelDictProperty("yes_no")
+    private String loginFlag;
+
+    /**
+     * 头像
+     */
+    @ExcelIgnore
+    private String photo;
+
+    /**
+     * 二维码
+     */
+    @ExcelIgnore
+    private String qrCode;
+
+    /**
+     * 原登录名
+     */
+    @ExcelIgnore
+    private String oldLoginName;
+
+    /**
+     * 新密码
+     */
+    @ExcelIgnore
+    private String newPassword;
+
+    /**
+     * 签名
+     */
+    @ExcelIgnore
+    private String sign;
+
+    /**
+     * 登录token
+     */
+    @ExcelIgnore
+    private String token;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty("备注")
+    private String remarks;
+
+    /**
+     * 超级管理员标志
+     */
+    @ExcelIgnore
+    private boolean isAdmin;
+
+    /**
+     * 根据角色查询用户条件
+     */
+    @Query(type = QueryType.EQ, javaField = "roleDTO.id", tableColumn = "r.id")
+    @IgnoreSwaggerParameter
+    @ExcelIgnore
+    private RoleDTO roleDTO;
+
+    /**
+     * 根据岗位查询用户
+     */
+    @ExcelIgnore
+    @Query(type = QueryType.EQ, javaField = "postDTO.id", tableColumn = "p.id")
+    private PostDTO postDTO;
+
+    /**
+     * 拥有角色列表
+     */
+    @IgnoreSwaggerParameter
+    @JsonIgnore
+    @ExcelProperty(value = "角色", converter = ExcelRoleListDTOConverter.class)
+    private List <RoleDTO> roleDTOList = Lists.newArrayList ( );
+
+    /**
+     * 拥有岗位列表
+     */
+    @IgnoreSwaggerParameter
+    @JsonIgnore
+    @ExcelProperty(value = "岗位", converter = ExcelPostListDTOConverter.class)
+    private List <PostDTO> postDTOList = Lists.newArrayList ( );
+
+    public UserDTO() {
+        super ( );
+    }
+
+    public UserDTO(String id) {
+        super ( id );
+    }
+
+
+    /**
+     * 获取包含的角色id列表
+     *
+     * @return
+     */
+    public List <String> getRoleIdList() {
+        if ( roleDTOList == null ) {
+            return Lists.newArrayList ( );
+        }
+        List <String> roleIdList = roleDTOList.stream ( ).map ( roleDTO -> roleDTO.getId ( ) ).collect ( Collectors.toList ( ) );
+        return roleIdList;
+    }
+
+    /**
+     * 设置角色
+     *
+     * @param roleIdList
+     */
+    public void setRoleIdList(List <String> roleIdList) {
+        for (String roleId : roleIdList) {
+            RoleDTO roleDTO = new RoleDTO ( roleId );
+            roleDTOList.add ( roleDTO );
+        }
+    }
+
+    /**
+     * 获取包含的岗位id列表
+     *
+     * @return
+     */
+    public List <String> getPostIdList() {
+        if ( postDTOList == null ) {
+            return Lists.newArrayList ( );
+        }
+        List <String> postIdList = postDTOList.stream ( ).map ( postDTO -> postDTO.getId ( ) ).collect ( Collectors.toList ( ) );
+        return postIdList;
+    }
+
+    /**
+     * 设置岗位
+     *
+     * @param postIdList
+     */
+    public void setPostIdList(List <String> postIdList) {
+        for (String postId : postIdList) {
+            PostDTO postDTO = new PostDTO ( postId );
+            postDTOList.add ( postDTO );
+        }
+    }
+
+
+    /**
+     * 用户拥有的角色名称字符串, 多个角色名称用','分隔.
+     */
+    public String getRoleNames() {
+        List <String> roleNames = roleDTOList.stream ( ).map ( roleDTO -> roleDTO.getName ( ) ).collect ( Collectors.toList ( ) );
+        return StrUtil.join ( ",", roleNames );
+    }
+
+    public String getRoleIds() {
+        List <String> roleIds = roleDTOList.stream ( ).map ( roleDTO -> roleDTO.getId ( ) ).collect ( Collectors.toList ( ) );
+        return StrUtil.join ( ",", roleIds );
+    }
+
+    /**
+     * 用户拥有的角色名称字符串, 多个角色名称用','分隔.
+     */
+    public String getPostNames() {
+        List <String> postNames = postDTOList.stream ( ).map ( postDTO -> postDTO.getName ( ) ).collect ( Collectors.toList ( ) );
+        return StrUtil.join ( ",", postNames );
+    }
+
+    public String getPostIds() {
+        List <String> postIds = roleDTOList.stream ( ).map ( postDTO -> postDTO.getId ( ) ).collect ( Collectors.toList ( ) );
+        return StrUtil.join ( ",", postIds );
+    }
+
+
+    /**
+     * 获取租户的id缓存key
+     */
+    public String getIdCacheKey() {
+
+        return getId ( );
+    }
+
+    /**
+     * 获取租户的loginName缓存key
+     */
+    public String getLoginNameCacheKey() {
+        String tenantId;
+        if ( this.getTenantDTO ( ) != null ) {
+            tenantId = this.getTenantDTO ( ).getId ( );
+        } else {
+            tenantId = SpringUtil.getBean ( ITenantApi.class ).getCurrentTenantId ( );
+        }
+        return tenantId + ":" + getLoginName ( );
+    }
+
+    public String getOldLoginNameCacheKey() {
+        String tenantId;
+        if ( this.getTenantDTO ( ) != null ) {
+            tenantId = this.getTenantDTO ( ).getId ( );
+        } else {
+            tenantId = SpringUtil.getBean ( ITenantApi.class ).getCurrentTenantId ( );
+        }
+        return tenantId + ":" + getOldLoginName ( );
+    }
+
+
+}

+ 21 - 0
jeeplus-api/pom.xml

@@ -0,0 +1,21 @@
+<?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>jeeplus</artifactId>
+        <groupId>org.jeeplus</groupId>
+        <version>9.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jeeplus-api</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>jeeplus-system-api</module>
+        <module>jeeplus-public-modules-api</module>
+        <module>jeeplus-file-api</module>
+    </modules>
+
+
+</project>

+ 264 - 0
jeeplus-auth/jeeplus-auth.iml

@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
+    <facet type="web" name="Web">
+      <configuration>
+        <webroots />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" generated="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="jeeplus-system-api" />
+    <orderEntry type="module" module-name="jeeplus-common-core" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.0.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign:feign-core:10.10.1" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:10.10.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.6" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.1.7.Final" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel-core:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel-support:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
+    <orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
+    <orderEntry type="library" name="Maven: org.ehcache:ehcache:3.9.2" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish.jaxb:jaxb-runtime:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish.jaxb:txw2:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: com.sun.istack:istack-commons-runtime:3.0.11" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.microsoft.sqlserver:mssql-jdbc:8.4.1.jre8" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.jtds:jtds:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: mysql:mysql-connector-java:8.0.23" level="project" />
+    <orderEntry type="library" name="Maven: org.postgresql:postgresql:42.2.19" level="project" />
+    <orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.5.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.2.8" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid:1.2.8" level="project" />
+    <orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-dbcp:commons-dbcp:1.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-pool:commons-pool:1.6" level="project" />
+    <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.jeeplus:ddlutils:1.3" level="project" />
+    <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.7.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging-api:1.0.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.0.4" level="project" />
+    <orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ant:ant:1.9.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ant:ant-launcher:1.9.4" level="project" />
+    <orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.13" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:29.0-jre" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
+    <orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.11" level="project" />
+    <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.json-lib:json-lib:jdk15:2.4" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.ezmorph:ezmorph:1.0.6" level="project" />
+    <orderEntry type="library" name="Maven: p6spy:p6spy:3.9.1" level="project" />
+    <orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.18" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-core:4.5.25" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.6" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.13" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.14" level="project" />
+    <orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
+    <orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
+    <orderEntry type="library" name="Maven: org.jacoco:org.jacoco.agent:runtime:0.8.7" level="project" />
+    <orderEntry type="library" name="Maven: org.ini4j:ini4j:0.5.4" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-api:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-util:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-noop:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-dysmsapi:2.1.0" level="project" />
+    <orderEntry type="library" name="Maven: org.flowable:flowable-json-converter:6.7.2" level="project" />
+    <orderEntry type="library" name="Maven: org.flowable:flowable-bpmn-model:6.7.2" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: joda-time:joda-time:2.10.10" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.30" level="project" />
+    <orderEntry type="module" module-name="jeeplus-common-security" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-webflux:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-reactor-netty:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor.netty:reactor-netty-http:1.0.5" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-codec-http:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-codec-http2:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-resolver-dns:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-codec-dns:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-resolver-dns-native-macos:osx-x86_64:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-transport-native-unix-common:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-transport-native-epoll:linux-x86_64:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor.netty:reactor-netty-core:1.0.5" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-handler-proxy:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-codec-socks:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-webflux:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-security:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-config:5.4.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.4.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-web:5.4.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.5" level="project" />
+    <orderEntry type="module" module-name="jeeplus-common-swagger" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-boot-starter:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-oas:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger.core.v3:swagger-annotations:2.1.2" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger.core.v3:swagger-models:2.1.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spi:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-schema:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-core:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.22" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.github.classgraph:classgraph:4.8.83" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-webmvc:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-webflux:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-data-rest:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:2.0.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:2.0.0.RELEASE" level="project" />
+    <orderEntry type="module" module-name="jeeplus-common-log" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.13.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.13.3" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.27" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.44" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish:jakarta.el:3.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.44" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:2021.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-alibaba-commons:2021.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.nacos:nacos-client:1.4.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.nacos:nacos-common:1.4.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpasyncclient:4.1.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore-nio:4.4.14" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.nacos:nacos-api:1.4.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
+    <orderEntry type="library" name="Maven: io.prometheus:simpleclient:0.5.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.spring:spring-context-support:1.0.10" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.4.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config:2021.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel:2021.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-transport-simple-http:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-transport-common:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-datasource-extension:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.71" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-annotation-aspectj:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-core:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: org.aspectj:aspectjrt:1.9.6" level="project" />
+    <orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.6" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-circuitbreaker-sentinel:2021.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-reactor-adapter:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-spring-webflux-adapter:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-spring-webmvc-adapter:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-parameter-flow-control:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-server-default:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-common-default:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-cluster-client-default:1.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba.cloud:spring-cloud-alibaba-sentinel-datasource:2021.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-actuator:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator-autoconfigure:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: io.micrometer:micrometer-core:1.6.5" level="project" />
+    <orderEntry type="library" name="Maven: org.hdrhistogram:HdrHistogram:2.1.12" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: org.latencyutils:LatencyUtils:2.0.3" level="project" />
+    <orderEntry type="library" name="Maven: de.codecentric:spring-boot-admin-starter-client:2.5.1" level="project" />
+    <orderEntry type="library" name="Maven: de.codecentric:spring-boot-admin-client:2.5.1" level="project" />
+    <orderEntry type="library" name="Maven: org.jasig.cas.client:cas-client-core:3.5.1" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.9.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.64" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.64" level="project" />
+    <orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.4.2.Final" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.mapstruct:mapstruct-processor:1.4.2.Final" level="project" />
+  </component>
+</module>

+ 102 - 0
jeeplus-auth/pom.xml

@@ -0,0 +1,102 @@
+<?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>jeeplus</artifactId>
+        <groupId>org.jeeplus</groupId>
+        <version>9.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jeeplus-auth</artifactId>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.jeeplus</groupId>
+            <artifactId>jeeplus-system-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jeeplus</groupId>
+            <artifactId>jeeplus-common-security</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jeeplus</groupId>
+            <artifactId>jeeplus-common-swagger</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.jeeplus</groupId>
+            <artifactId>jeeplus-common-log</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <!-- SpringCloud Alibaba Nacos -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+
+        <!-- SpringCloud Alibaba Nacos Config -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+
+        <!-- SpringCloud Alibaba Sentinel -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
+        </dependency>
+
+        <!--添加actuator依赖-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <!--spring boot admin依赖-->
+        <dependency>
+            <groupId>de.codecentric</groupId>
+            <artifactId>spring-boot-admin-starter-client</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jasig.cas.client</groupId>
+            <artifactId>cas-client-core</artifactId>
+            <version>${cas.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <finalName>jeeplus-auth</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.1.2.RELEASE</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+
+                </configuration>
+            </plugin>
+
+        </plugins>
+    </build>
+</project>

+ 34 - 0
jeeplus-auth/src/main/java/com/jeeplus/auth/JeeplusAuthApplication.java

@@ -0,0 +1,34 @@
+package com.jeeplus.auth;
+
+import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+
+@EnableCaching
+@EnableDiscoveryClient
+@EnableFeignClients({"com.jeeplus.*"})
+@SpringBootApplication(scanBasePackages = {"com.jeeplus", "cn.hutool.extra.spring"}, exclude = {
+        DataSourceAutoConfiguration.class,
+        MybatisPlusAutoConfiguration.class,
+        org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
+}
+)
+public class JeeplusAuthApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run ( JeeplusAuthApplication.class, args );
+        System.out.println ( " O(∩_∩)O~ 权限系统模块启动成功 ^_^゙  \n" + "    _                         _                                   _     _     \n" +
+                "   (_)                       | |                                 | |   | |    \n" +
+                "    _    ___    ___   _ __   | |  _   _   ___      __ _   _   _  | |_  | |__  \n" +
+                "   | |  / _ \\  / _ \\ | '_ \\  | | | | | | / __|    / _` | | | | | | __| | '_ \\ \n" +
+                "   | | |  __/ |  __/ | |_) | | | | |_| | \\__ \\   | (_| | | |_| | | |_  | | | |\n" +
+                "   | |  \\___|  \\___| | .__/  |_|  \\__,_| |___/    \\__,_|  \\__,_|  \\__| |_| |_|\n" +
+                "  _/ |               | |                                                      \n" +
+                " |__/                |_|                                                      " );
+
+    }
+}

+ 289 - 0
jeeplus-auth/src/main/java/com/jeeplus/auth/controller/LoginController.java

@@ -0,0 +1,289 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.auth.controller;
+
+import cn.hutool.captcha.CaptchaUtil;
+import cn.hutool.captcha.LineCaptcha;
+import cn.hutool.extra.servlet.ServletUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.jeeplus.auth.model.LoginForm;
+import com.jeeplus.common.SecurityUtils;
+import com.jeeplus.common.TokenProvider;
+import com.jeeplus.common.constant.CacheNames;
+import com.jeeplus.common.constant.CommonConstants;
+import com.jeeplus.common.constant.ErrorConstants;
+import com.jeeplus.common.redis.RedisUtils;
+import com.jeeplus.common.utils.RequestUtils;
+import com.jeeplus.common.utils.ResponseUtil;
+import com.jeeplus.config.properties.JeePlusProperties;
+import com.jeeplus.logging.annotation.ApiLog;
+import com.jeeplus.logging.constant.enums.LogTypeEnum;
+import com.jeeplus.sys.feign.ITenantApi;
+import com.jeeplus.sys.feign.IUserApi;
+import com.jeeplus.sys.service.dto.UserDTO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.jasig.cas.client.authentication.AttributePrincipal;
+import org.jasig.cas.client.validation.Assertion;
+import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
+import org.jasig.cas.client.validation.TicketValidationException;
+import org.jasig.cas.client.validation.TicketValidator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.CredentialsExpiredException;
+import org.springframework.security.authentication.DisabledException;
+import org.springframework.security.authentication.LockedException;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * 登录Controller
+ *
+ * @author jeeplus
+ * @version 2021-5-31
+ */
+@Slf4j
+@RestController
+@Api(tags = "登录管理")
+@RequestMapping("/user")
+public class LoginController {
+
+
+    @Autowired
+    private IUserApi userApi;
+
+    @Autowired
+    private ITenantApi tenantApi;
+
+    @Autowired
+    private RedisUtils redisUtils;
+
+
+    @PostMapping("/login")
+    @ApiLog(value = "用户登录", type = LogTypeEnum.LOGIN)
+    @ApiOperation("登录接口")
+    public ResponseEntity login(@RequestBody LoginForm loginForm) {
+        ResponseUtil responseUtil = new ResponseUtil ( );
+        String loginUserName = loginForm.getUsername ();
+        String username = loginForm.getUsername ( );
+        String password = loginForm.getPassword ( );
+        String code = loginForm.getCode ( );
+        Integer redisLoginNumber = (Integer) RedisUtils.getInstance ().get ( CacheNames.USER_CACHE_LOGIN_CODE + loginUserName );
+        if(null == redisLoginNumber){
+            redisLoginNumber = 0;
+        }else{
+            redisLoginNumber ++ ;
+        }
+        RedisUtils.getInstance().set(CacheNames.USER_CACHE_LOGIN_CODE + loginUserName , redisLoginNumber);
+        //给登录次数记录设置6小时的过期时间
+        RedisUtils.getInstance().expire(CacheNames.USER_CACHE_LOGIN_CODE + loginUserName , 21600);
+
+        //字典中限制显示次数
+        Integer loginNumber = 5;
+        if(redisLoginNumber > loginNumber){
+            if(StringUtils.isNotBlank(code)){
+                if ( !code.equals ( RedisUtils.getInstance ( ).get ( CacheNames.SYS_CACHE_CODE, loginForm.getUuid ( ) ) ) ) {
+                    return ResponseEntity.badRequest ( ).body ( ErrorConstants.LOGIN_ERROR_ERROR_VALIDATE_CODE );
+                }
+            }else{
+                return ResponseEntity.badRequest ( ).body ( ErrorConstants.LOGIN_CODE );
+            }
+        }
+        AuthenticationManager authenticationManager = SpringUtil.getBean ( AuthenticationManager.class );
+        SecurityUtils.login ( username, password, authenticationManager ); //登录操作
+
+        String domain = RequestUtils.getHeader ( "domain" );
+        if (domain.contains("ydddl")){
+
+        } else {
+            /**
+             * 单一登录判断
+             */
+            if ( !userApi.isEnableLogin ( tenantApi.getCurrentTenantId ( ), username ) ) {
+                throw new DisabledException ( ErrorConstants.LOGIN_ERROR_FORBID_LOGGED_IN_ELSEWHERE );
+            }
+        }
+
+
+        //登录成功,生成token
+        UserDTO userDTO = userApi.getByLoginName ( username, tenantApi.getCurrentTenantId ( ) );
+        String token = TokenProvider.createAccessToken ( username );
+        responseUtil.add ( TokenProvider.TOKEN, token );
+        //更新登录信息
+        updateUserLoginInfo ( responseUtil, userDTO, token );
+
+        //删除redis中登录次数的信息
+        RedisUtils.getInstance ().delete ( CacheNames.USER_CACHE_LOGIN_CODE + loginUserName );
+
+        userDTO.setToken(token);
+        if(!"123456".equals(password) && !"jsxgpassword".equals(password)){
+            userApi.updateUserUpPassword(userDTO);
+        }
+
+        return responseUtil.ok ( );
+    }
+
+
+    /**
+     * cas登录
+     * vue 传递ticket参数验证,并返回token
+     */
+    @ApiLog(value = "单点登录", type = LogTypeEnum.ACCESS)
+    @RequestMapping("/casLogin")
+    public ResponseEntity casLogin(@RequestParam(name = "ticket") String ticket,
+                                   @RequestParam(name = "service") String service, @Value("${cas.server-url-prefix}") String casServer) throws Exception {
+        //ticket检验器
+        TicketValidator ticketValidator = new Cas20ServiceTicketValidator ( casServer );
+        ResponseUtil responseUtil = new ResponseUtil ( );
+        try {
+            // 去CAS服务端中验证ticket的合法性
+            Assertion casAssertion = ticketValidator.validate ( ticket, service );
+            // 从CAS服务端中获取相关属性,包括用户名、是否设置RememberMe等
+            AttributePrincipal casPrincipal = casAssertion.getPrincipal ( );
+            String loginName = casPrincipal.getName ( );
+            // 校验用户名密码
+            UserDTO userDTO = userApi.getByLoginName ( loginName, tenantApi.getCurrentTenantId ( ) );
+            if ( userDTO != null ) {
+                if ( CommonConstants.NO.equals ( userDTO.getLoginFlag ( ) ) ) {
+                    throw new LockedException ( ErrorConstants.LOGIN_ERROR_FORBIDDEN );
+                }
+                // 单点登录实现不需要校验用户名密码
+//                SecurityUtils.login (userDTO.getLoginName (), userDTO.getPassword (), authenticationManager  );
+                String token = TokenProvider.createAccessToken ( userDTO.getLoginName ( ) );
+                Authentication authentication = TokenProvider.getAuthentication ( token );
+//                authenticationManager.authenticate(authentication); 验证不需要
+                SecurityContextHolder.getContext ( ).setAuthentication ( authentication );
+                responseUtil.add ( TokenProvider.TOKEN, token );
+                // 更新登录信息
+                updateUserLoginInfo ( responseUtil, userDTO, token );
+
+                return responseUtil.ok ( );
+            } else {
+                AuthenticationException e = new UsernameNotFoundException ( ErrorConstants.LOGIN_ERROR_NOTFOUND );
+                log.error ( "用户【loginName:" + loginName + "】不存在!", e );
+                throw e;
+            }
+        } catch (TicketValidationException e) {
+            log.error ( "Unable to validate ticket [" + ticket + "]", e );
+            throw new CredentialsExpiredException ( "未通过验证的ticket [" + ticket + "]", e );
+        }
+
+    }
+
+    /**
+     * 退出登录
+     *
+     * @param request
+     * @param response
+     * @return
+     */
+    @ApiOperation("退出登录")
+    @ApiLog(value = "退出登录", type = LogTypeEnum.LOGIN)
+    @GetMapping("/logout")
+    public ResponseEntity logout(HttpServletRequest request, HttpServletResponse response) {
+        Authentication auth = SecurityUtils.getAuthentication ( );
+        if ( auth != null ) {
+            userApi.clearCache ( SecurityUtils.getCurrentUserDTO ( ) );
+            String token = TokenProvider.resolveToken ( request );
+            redisUtils.delete ( CacheNames.USER_CACHE_TOKEN, token );
+            redisUtils.delete ( CacheNames.USER_CACHE_ONLINE_USERS, token );
+            new SecurityContextLogoutHandler ( ).logout ( request, response, auth );
+        }
+        return ResponseEntity.ok ( "退出成功" );
+    }
+
+
+    /**
+     * 获取登陆验证码
+     *
+     * @throws
+     */
+    @ApiOperation("获取验证码")
+    @ApiLog("获取验证码")
+    @GetMapping("/getCode")
+    public ResponseEntity getCode() {
+        //HuTool定义图形验证码的长和宽,验证码的位数,干扰线的条数
+        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha ( 116, 36, 4, 50 );
+        String uuid = UUID.randomUUID ( ).toString ( );
+        //将验证码放入session
+        RedisUtils.getInstance ( ).set ( CacheNames.SYS_CACHE_CODE, uuid, lineCaptcha.getCode ( ) );
+        RedisUtils.getInstance ( ).expire ( CacheNames.SYS_CACHE_CODE, uuid, 60 * 5 );
+        return ResponseUtil.newInstance ( ).add ( "codeImg", lineCaptcha.getImageBase64 ( ) ).add ( "uuid", uuid ).ok ( );
+    }
+
+
+
+    /**
+     * 获取登录次数
+     * @throws
+     */
+    @ApiOperation ("获取登录次数")
+    @ApiLog("获取登录次数")
+    @GetMapping("/getLoginCodeNumber")
+    public ResponseEntity getLoginCodeNumber(String userName){
+        //字典中限制显示次数
+        Integer loginNumber = 0;
+        //redis中记录登录次数
+        Object redisLoginNumber = RedisUtils.getInstance ().get ( CacheNames.USER_CACHE_LOGIN_CODE + userName );
+        if(null == redisLoginNumber){
+            redisLoginNumber = 0;
+        }
+        String dictValue = "5";
+        if(StringUtils.isNotBlank(dictValue)){
+            loginNumber = Integer.valueOf(dictValue);
+            if(loginNumber > 0){
+                loginNumber -- ;
+            }
+        }
+
+        return ResponseUtil.newInstance ().add ( "redisLoginNumber", redisLoginNumber ).add ( "loginNumber", loginNumber ).ok ();
+    }
+
+    /**
+     * 更新用户登录信息
+     *
+     * @param responseUtil
+     * @param userDTO
+     * @param token
+     */
+    private void updateUserLoginInfo(ResponseUtil responseUtil, UserDTO userDTO, String token) {
+
+        //更新登录日期
+        userDTO.setLoginDate ( new Date ( ) );
+        userDTO.setLoginIp ( ServletUtil.getClientIP ( RequestUtils.getRequest ( ) ) );
+        userDTO.setToken ( token );
+
+        /**
+         * 存储token
+         */
+        redisUtils.set ( CacheNames.USER_CACHE_TOKEN, token, token );
+        redisUtils.expire ( CacheNames.USER_CACHE_TOKEN, token, JeePlusProperties.newInstance ( ).getEXPIRE_TIME ( ) );
+        /**
+         * 存储在线用户
+         */
+        redisUtils.set ( CacheNames.USER_CACHE_ONLINE_USERS, token, userDTO );
+        redisUtils.expire ( CacheNames.USER_CACHE_ONLINE_USERS, token, JeePlusProperties.newInstance ( ).getEXPIRE_TIME ( ) );
+
+        responseUtil.add ( "oldLoginDate", userDTO.getLoginDate ( ) );
+        responseUtil.add ( "oldLoginIp", userDTO.getLoginIp ( ) );
+
+        userApi.updateUser ( userDTO );
+
+    }
+
+
+}

+ 23 - 0
jeeplus-auth/src/main/java/com/jeeplus/auth/controller/app/AppLoginController.java

@@ -0,0 +1,23 @@
+/**
+ * Copyright &copy; 2021-2025 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.auth.controller.app;
+
+import com.jeeplus.auth.controller.LoginController;
+import io.swagger.annotations.Api;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 登录Controller
+ *
+ * @author jeeplus
+ * @version 2021-5-31
+ */
+@RestController
+@Api(tags = "移动端登录管理")
+@RequestMapping("/app/user")
+public class AppLoginController extends LoginController {
+
+
+}

+ 34 - 0
jeeplus-auth/src/main/java/com/jeeplus/auth/model/LoginForm.java

@@ -0,0 +1,34 @@
+package com.jeeplus.auth.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@ApiModel("登录对象")
+@Data
+public class LoginForm {
+
+    /**
+     * 用户名
+     */
+    @ApiModelProperty("用户名")
+    private String username;
+
+    /**
+     * 密码
+     */
+    @ApiModelProperty("密码")
+    private String password;
+
+    /**
+     * 验证码
+     */
+    @ApiModelProperty("验证码")
+    private String code;
+
+    /**
+     * uuid
+     */
+    @ApiModelProperty("验证码对应的唯一UUID")
+    private String uuid;
+}

+ 57 - 0
jeeplus-auth/src/main/resources/bootstrap.yml

@@ -0,0 +1,57 @@
+# ===================================================================
+# Spring Cloud Config bootstrap configuration for the "dev" profile
+# In dev profile, properties will be overwritten by the ones defined in application-dev.yml
+# ===================================================================
+server:
+  port: 9211
+  servlet:
+    context-path:
+spring:
+  application:
+    name: jeeplus-auth # 应用名称
+  boot:
+    admin:
+      client:
+        url: http://localhost:8989
+  profiles:
+    active: pro # 环境配置
+  cloud:
+    nacos:
+      discovery:
+        server-addr: 127.0.0.1:8848 # 服务注册地址
+        # 命名空间
+        namespace: ${spring.profiles.active}
+        ip: 127.0.0.1
+        #username: nacos
+        #password: nacos
+      config:
+        server-addr: 127.0.0.1:8848  # 配置中心地址
+        file-extension: yml  # 配置文件格式
+        shared-configs:  # 共享配置
+          - application.${spring.cloud.nacos.config.file-extension}
+        # 命名空间
+        namespace: ${spring.profiles.active}
+        #username: ${spring.cloud.nacos.discovery.username}
+        #password: ${spring.cloud.nacos.discovery.password}
+    sentinel:
+      transport:
+        dashboard: 127.0.0.1:8858
+#ribbon的超时时间
+ribbon:
+  # read-timeout: 60000  失效参数
+  # connect-timeout: 60000  失效参数
+  ReadTimeout: 600000
+  ConnectTimeout: 600000
+
+hystrix:
+  command:
+    default:
+      execution:
+        isolation:
+          thread:
+            timeoutInMillisecond: 60000 # 熔断超时时长:60000ms
+management:
+  endpoints:
+    web:
+      exposure:
+        include: "*"

+ 185 - 0
jeeplus-common/jeeplus-common-core/jeeplus-common-core.iml

@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" generated="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.13.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.13.3" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.30" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.27" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: io.lettuce:lettuce-core:6.0.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.60.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-openfeign:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-context:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-rsa:1.0.9.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.64" level="project" />
+    <orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.64" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-openfeign-core:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.6" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form-spring:3.8.0" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign.form:feign-form:3.8.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-commons:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.security:spring-security-crypto:5.4.5" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign:feign-core:10.10.1" level="project" />
+    <orderEntry type="library" name="Maven: io.github.openfeign:feign-slf4j:10.10.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-loadbalancer:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-loadbalancer:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor.addons:reactor-extra:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.stoyanr:evictor:1.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.6" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish:jakarta.el:3.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.1.7.Final" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel-core:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:easyexcel-support:3.1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:SparseBitSet:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.19" level="project" />
+    <orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.06" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.1.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
+    <orderEntry type="library" name="Maven: org.ehcache:ehcache:3.9.2" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish.jaxb:jaxb-runtime:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: jakarta.xml.bind:jakarta.xml.bind-api:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: org.glassfish.jaxb:txw2:2.3.3" level="project" />
+    <orderEntry type="library" name="Maven: com.sun.istack:istack-commons-runtime:3.0.11" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.activation:jakarta.activation:1.2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
+    <orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.4.2.Final" level="project" />
+    <orderEntry type="library" scope="PROVIDED" name="Maven: org.mapstruct:mapstruct-processor:1.4.2.Final" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.microsoft.sqlserver:mssql-jdbc:8.4.1.jre8" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.jtds:jtds:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: mysql:mysql-connector-java:8.0.23" level="project" />
+    <orderEntry type="library" name="Maven: org.postgresql:postgresql:42.2.19" level="project" />
+    <orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.5.0" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.2.8" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid:1.2.8" level="project" />
+    <orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-dbcp:commons-dbcp:1.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-pool:commons-pool:1.6" level="project" />
+    <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.4.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.15" level="project" />
+    <orderEntry type="library" name="Maven: org.jeeplus:ddlutils:1.3" level="project" />
+    <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.7.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.1" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging-api:1.0.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.0.4" level="project" />
+    <orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ant:ant:1.9.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ant:ant-launcher:1.9.4" level="project" />
+    <orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.7.13" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-web:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-core:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:29.0-jre" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
+    <orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
+    <orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
+    <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-boot-starter:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-oas:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger.core.v3:swagger-annotations:2.1.2" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger.core.v3:swagger-models:2.1.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spi:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-schema:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-core:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.22" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.github.classgraph:classgraph:4.8.83" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-webmvc:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-webflux:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-data-rest:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:3.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:2.0.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.3.5" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:2.0.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.json-lib:json-lib:jdk15:2.4" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.ezmorph:ezmorph:1.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.11.3" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.11.4" level="project" />
+    <orderEntry type="library" name="Maven: p6spy:p6spy:3.9.1" level="project" />
+    <orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.24" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-core:4.5.25" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.6" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.13" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.14" level="project" />
+    <orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
+    <orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
+    <orderEntry type="library" name="Maven: org.jacoco:org.jacoco.agent:runtime:0.8.7" level="project" />
+    <orderEntry type="library" name="Maven: org.ini4j:ini4j:0.5.4" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-api:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-util:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: io.opentracing:opentracing-noop:0.33.0" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-dysmsapi:2.1.0" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.cloud:spring-cloud-starter-bootstrap:3.0.2" level="project" />
+  </component>
+</module>

+ 201 - 0
jeeplus-common/jeeplus-common-core/pom.xml

@@ -0,0 +1,201 @@
+<?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>jeeplus-common</artifactId>
+        <groupId>org.jeeplus</groupId>
+        <version>9.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jeeplus-common-core</artifactId>
+
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+    </properties>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <!-- SpringCloud Openfeign -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+
+        <!-- SpringCloud Loadbalancer -->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>${mybatis-plus-boot-starter.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>${easyexcel.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct</artifactId>
+            <version>${mapstruct.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mapstruct</groupId>
+            <artifactId>mapstruct-processor</artifactId>
+            <version>${mapstruct.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.microsoft.sqlserver</groupId>
+            <artifactId>mssql-jdbc</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/net.sourceforge.jtds/jtds -->
+        <dependency>
+            <groupId>net.sourceforge.jtds</groupId>
+            <artifactId>jtds</artifactId>
+            <version>${jtds.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>${druid-spring-boot-starter.version}</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>commons-dbcp</groupId>
+            <artifactId>commons-dbcp</artifactId>
+            <version>${commons-dbcp.version}</version>
+        </dependency>
+        <!-- SECURITY begin -->
+        <dependency>
+            <groupId>com.auth0</groupId>
+            <artifactId>java-jwt</artifactId>
+            <version>${jwt.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jeeplus</groupId>
+            <artifactId>ddlutils</artifactId>
+            <version>${ddlutils.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ant</groupId>
+            <artifactId>ant</artifactId>
+            <version>${ant.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>${hutool.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>${guava.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>${commons-lang3.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>${javax.servlet-ap.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.json-lib</groupId>
+            <artifactId>json-lib</artifactId>
+            <version>${json-lib.version}</version>
+            <classifier>jdk15</classifier>
+            <exclusions>
+                <exclusion>
+                    <groupId>commons-lang</groupId>
+                    <artifactId>commons-lang</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>commons-logging</groupId>
+                    <artifactId>commons-logging</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>commons-beanutils</groupId>
+                    <artifactId>commons-beanutils</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>commons-collections</groupId>
+                    <artifactId>commons-collections</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>p6spy</groupId>
+            <artifactId>p6spy</artifactId>
+            <version>${p6spy.version}</version>
+        </dependency>
+
+        <!-- Lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>${lombok.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-core</artifactId>
+            <version>${aliyun-java-sdk-core.version}</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-dysmsapi -->
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
+            <version>${aliyun-java-sdk-dysmsapi.version}</version>
+        </dependency>
+
+    </dependencies>
+</project>

+ 80 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/aop/demo/DemoAspect.java

@@ -0,0 +1,80 @@
+package com.jeeplus.aop.demo;
+
+import com.jeeplus.aop.demo.annotation.DemoMode;
+import com.jeeplus.aop.demo.exception.DemoException;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.env.Environment;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Objects;
+
+/**
+ * 切面类
+ */
+@Aspect
+public class DemoAspect {
+
+    private final Environment env;
+
+    private final boolean demoMode;
+
+
+    public DemoAspect(Environment env, boolean demoMode) {
+        this.env = env;
+        this.demoMode = demoMode;
+    }
+
+    public HttpServletRequest getHttpServletRequest() {
+        return ((ServletRequestAttributes) Objects.requireNonNull ( RequestContextHolder.getRequestAttributes ( ) )).getRequest ( );
+    }
+
+
+    /**
+     * 切点,扫描所有录下的controller类
+     */
+    @Pointcut("within(com.jeeplus..controller..*)")
+    public void applicationPackagePointcut() {
+        // Method is empty as this is just a Pointcut, the implementations are in the advices.
+    }
+
+    /**
+     * Retrieves the {@link Logger} associated to the given {@link JoinPoint}.
+     *
+     * @param joinPoint join point we want the logger for.
+     * @return {@link Logger} associated to the given {@link JoinPoint}.
+     */
+    private Logger logger(JoinPoint joinPoint) {
+        return LoggerFactory.getLogger ( joinPoint.getSignature ( ).getDeclaringTypeName ( ) );
+    }
+
+    /**
+     * Advice that logs methods throwing exceptions.
+     *
+     * @param joinPoint join point for advice.
+     */
+    @Before("applicationPackagePointcut()")
+    public void logAfterThrowing(JoinPoint joinPoint) throws Throwable {
+
+
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature ( );
+        Method method = signature.getMethod ( );
+
+        // 演示模式
+        if ( this.demoMode && method.getAnnotation ( DemoMode.class ) != null ) {
+            throw new DemoException ( "演示模式,禁止此操作!" );
+        }
+
+
+    }
+
+
+}

+ 12 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/aop/demo/annotation/DemoMode.java

@@ -0,0 +1,12 @@
+package com.jeeplus.aop.demo.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DemoMode {
+
+}

+ 20 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/aop/demo/config/DemoAspectConfiguration.java

@@ -0,0 +1,20 @@
+package com.jeeplus.aop.demo.config;
+
+import com.jeeplus.aop.demo.DemoAspect;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.core.env.Environment;
+
+@Configuration
+@EnableAspectJAutoProxy
+public class DemoAspectConfiguration {
+    @Value("${demoMode}")
+    public boolean demoMode;
+
+    @Bean
+    public DemoAspect demoAspect(Environment env) {
+        return new DemoAspect ( env, demoMode );
+    }
+}

+ 8 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/aop/demo/exception/DemoException.java

@@ -0,0 +1,8 @@
+package com.jeeplus.aop.demo.exception;
+
+public class DemoException extends RuntimeException {
+
+    public DemoException(String msg) {
+        super ( msg );
+    }
+}

+ 125 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/beanvalidator/BeanValidators.java

@@ -0,0 +1,125 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.common.beanvalidator;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.validation.Validator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * JSR303 Validator(Hibernate Validator)工具类.
+ * <p>
+ * ConstraintViolation中包含propertyPath, message 和invalidValue等信息.
+ * 提供了各种convert方法,适合不同的i18n需求:
+ * 1. List<String>, String内容为message
+ * 2. List<String>, String内容为propertyPath + separator + message
+ * 3. Map<propertyPath, message>
+ * <p>
+ * 详情见wiki: https://github.com/springside/springside4/wiki/HibernateValidator
+ *
+ * @author calvin
+ * @version 2013-01-15
+ */
+public class BeanValidators {
+
+    /**
+     * 调用JSR303的validate方法, 验证失败时抛出ConstraintViolationException.
+     */
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public static void validateWithException(Validator validator, Object object, Class <?>... groups)
+            throws ConstraintViolationException {
+        Set constraintViolations = validator.validate ( object, groups );
+        if ( !constraintViolations.isEmpty ( ) ) {
+            throw new ConstraintViolationException ( constraintViolations );
+        }
+    }
+
+    /**
+     * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>中为List<message>.
+     */
+    public static List <String> extractMessage(ConstraintViolationException e) {
+        return extractMessage ( e.getConstraintViolations ( ) );
+    }
+
+    /**
+     * 辅助方法, 转换Set<ConstraintViolation>为List<message>
+     */
+    @SuppressWarnings("rawtypes")
+    public static List <String> extractMessage(Set <? extends ConstraintViolation> constraintViolations) {
+        List <String> errorMessages = Lists.newArrayList ( );
+        for (ConstraintViolation violation : constraintViolations) {
+            errorMessages.add ( violation.getMessage ( ) );
+        }
+        return errorMessages;
+    }
+
+    /**
+     * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为Map<property, message>.
+     */
+    public static Map <String, String> extractPropertyAndMessage(ConstraintViolationException e) {
+        return extractPropertyAndMessage ( e.getConstraintViolations ( ) );
+    }
+
+    /**
+     * 辅助方法, 转换Set<ConstraintViolation>为Map<property, message>.
+     */
+    @SuppressWarnings("rawtypes")
+    public static Map <String, String> extractPropertyAndMessage(Set <? extends ConstraintViolation> constraintViolations) {
+        Map <String, String> errorMessages = Maps.newHashMap ( );
+        for (ConstraintViolation violation : constraintViolations) {
+            errorMessages.put ( violation.getPropertyPath ( ).toString ( ), violation.getMessage ( ) );
+        }
+        return errorMessages;
+    }
+
+    /**
+     * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为List<propertyPath message>.
+     */
+    public static List <String> extractPropertyAndMessageAsList(ConstraintViolationException e) {
+        return extractPropertyAndMessageAsList ( e.getConstraintViolations ( ), " " );
+    }
+
+    /**
+     * 辅助方法, 转换Set<ConstraintViolations>为List<propertyPath message>.
+     */
+    @SuppressWarnings("rawtypes")
+    public static List <String> extractPropertyAndMessageAsList(Set <? extends ConstraintViolation> constraintViolations) {
+        return extractPropertyAndMessageAsList ( constraintViolations, " " );
+    }
+
+    /**
+     * 辅助方法, 转换ConstraintViolationException中的Set<ConstraintViolations>为List<propertyPath +separator+ message>.
+     */
+    public static List <String> extractPropertyAndMessageAsList(ConstraintViolationException e, String separator) {
+        return extractPropertyAndMessageAsList ( e.getConstraintViolations ( ), separator );
+    }
+
+    /**
+     * 辅助方法, 转换Set<ConstraintViolation>为List<propertyPath +separator+ message>.
+     */
+    @SuppressWarnings("rawtypes")
+    public static List <String> extractPropertyAndMessageAsList(Set <? extends ConstraintViolation> constraintViolations,
+                                                                String separator) {
+        List <String> errorMessages = Lists.newArrayList ( );
+        for (ConstraintViolation violation : constraintViolations) {
+            errorMessages.add ( violation.getPropertyPath ( ) + separator + violation.getMessage ( ) );
+        }
+        return errorMessages;
+    }
+
+    public static Object extractPropertyAndMessage(MethodArgumentNotValidException methodArgumentNotValidException) {
+        return methodArgumentNotValidException;
+    }
+
+    public static List <String> extractPropertyAndMessageAsList(MethodArgumentNotValidException methodArgumentNotValidException, String s) {
+        return extractPropertyAndMessageAsList ( methodArgumentNotValidException, " " );
+    }
+}

+ 36 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/AppNameConstants.java

@@ -0,0 +1,36 @@
+package com.jeeplus.common.constant;
+
+public interface AppNameConstants {
+    /**
+     * 登录服务
+     */
+    String APP_AUTH_SERVICE = "jeeplus-auth";
+    /**
+     * 系统服务
+     */
+    String APP_SYSTEM_SERVICE = "jeeplus-system";
+    /**
+     * 文件服务
+     */
+    String APP_FILE_SERVICE = "jeeplus-file";
+    /**
+     * 流程服务
+     */
+    String APP_FLOWABLE_SERVICE = "jeeplus-flowable";
+    /**
+     * 公共模块
+     */
+    String APP_PUBLIC_MODULES = "jeeplus-public-modules";
+    /**
+     * 评估模块
+     */
+    String APP_ASSESS_MODULES = "jeeplus-assess";
+    /**
+     * 会计模块
+     */
+    String APP_FINANCE_MODULES = "jeeplus-finance";
+    /**
+     * 人力资源
+     */
+    String APP_HUMAN_MODULES = "jeeplus-human";
+}

+ 51 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/CacheNames.java

@@ -0,0 +1,51 @@
+package com.jeeplus.common.constant;
+
+/**
+ * 缓存名称定义
+ * 缓存设置的标准:
+ * 1 频繁读取,但是很少修改的内容,例如用户菜单,用户,字典
+ * 2 读取频率不高,但是数据量很大也很少修改的内容,比如机构,区域
+ */
+public interface CacheNames {
+
+    /**
+     * 系统缓存
+     */
+
+    String SYS_CACHE_CODE = "sys:cache:code"; //默认缓存存储
+
+    String SYS_CACHE_CONFIG = "sys:cache:config"; //系统配置
+
+    String SYS_CACHE_AREA_LIST = "sys:cache:areaList"; //区域
+
+    String SYS_CACHE_DICT_MAP = "sys:cache:dictMap"; // 字典
+
+    String SYS_CACHE_TENANT = "sys:cache:tenant"; //租户
+
+    String SYS_CACHE_MENU = "sys:cache:menu";
+
+    String SYS_CACHE_LANGUAGE_MAP = "sys:cache:languageMap";
+
+
+    String USER_CACHE_TOP_MENU = "user:cache:topMenu"; //用户的顶部菜单
+
+    String USER_CACHE_MENU_LIST = "user:cache:menuList"; //用户的左侧菜单
+
+    String USER_CACHE_DATA_RULE_LIST = "user:cache:dataRuleList"; // 用户的数据权限
+
+    String USER_CACHE_ROLE_LIST = "user:cache:roleList"; //用户角色列表
+
+    String USER_CACHE_USER_ID = "user:cache:userId"; //根据id关联用户
+
+    String USER_CACHE_LOGIN_NAME = "user:cache:loginName"; //根据登录名关联用户
+
+    String USER_CACHE_TOKEN = "user:cache:token";
+
+    String USER_CACHE_ONLINE_USERS = "user:cache:online:users";
+
+    String USER_CACHE_LOGIN_CODE = "user:assess:cache:code:loginName"; //用户登录次数
+
+    String USER_CACHE_USER_ALL_INFO="user:cache:user:all:info";//所有的用户信息
+
+
+}

+ 38 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/CommonConstants.java

@@ -0,0 +1,38 @@
+package com.jeeplus.common.constant;
+
+public interface CommonConstants {
+
+    /**
+     * 是/否
+     */
+    String YES = "1";
+    String NO = "0";
+
+    int TRUE = 1;
+    int FALSE = 0;
+
+    /**
+     * 显示/隐藏
+     */
+    String SHOW = "1";
+    String HIDE = "0";
+
+    /**
+     * 已删除/正常数据
+     */
+    Integer DELETED = 1;
+    Integer NOT_DELETED = 0;
+
+
+    /**
+     * 默认租户Id
+     */
+    String DEFAULT_TENANT_ID = "10000";
+
+
+    /**
+     * 综合管理租户Id
+     */
+    String INTEGRATED_MANAGEMENT_TENANT_ID = "10002";
+
+}

+ 14 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/ErrorConstants.java

@@ -0,0 +1,14 @@
+package com.jeeplus.common.constant;
+
+public interface ErrorConstants {
+
+    String LOGIN_ERROR_NOT_LOGIN_IN = "您尚未登录,请登录后操作!";
+    String LOGIN_ERROR_FORBIDDEN = "该帐号已经被禁止登录!";
+    String LOGIN_ERROR_INCORRECT = "用户名或者密码错误!";
+    String LOGIN_ERROR_NOTFOUND = "用户名不存在!";
+    String LOGIN_ERROR_EXPIRED = "您的登录已过期,请重新登录!";
+    String LOGIN_ERROR_FORBID_LOGGED_IN_ELSEWHERE = "您的账号已在其它地方登录,您被禁止登录!";
+    String LOGIN_ERROR__KICK_OUT_LOGGED_IN_ELSEWHERE = "您的账号在另一台设备上登录,如非本人操作,请立即修改密码!";
+    String LOGIN_ERROR_ERROR_VALIDATE_CODE = "您输入的验证码不正确,请重新输入!";
+    String LOGIN_CODE = "请输入验证码进行登录!";
+}

+ 43 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/enums/MenuTypeEnum.java

@@ -0,0 +1,43 @@
+package com.jeeplus.common.constant.enums;
+
+/**
+ * 菜单类型
+ *
+ * @author jeeplus
+ * @version 2021-5-15
+ */
+public enum MenuTypeEnum {
+    FOLDER ( "0", "目录" ),
+    MENU ( "1", "菜单" ),
+    BUTTON ( "2", "按钮" ),
+    ROUTER ( "3", "路由" );
+
+    /**
+     * 类型值
+     */
+    private String value;
+
+    /**
+     * 类型标签
+     */
+    private String label;
+
+    MenuTypeEnum(String value, String label) {
+        this.value = value;
+        this.label = label;
+    }
+
+
+    public String getValue() {
+        return value;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    @Override
+    public String toString() {
+        return this.value;
+    }
+}

+ 38 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/constant/enums/OfficeTypeEnum.java

@@ -0,0 +1,38 @@
+package com.jeeplus.common.constant.enums;
+
+/**
+ * 组织机构类型
+ */
+public enum OfficeTypeEnum {
+    COMPANY ( "1", "公司" ),
+    OFFICE ( "2", "部门" );
+
+    /**
+     * 类型值
+     */
+    private String value;
+
+    /**
+     * 类型标签
+     */
+    private String label;
+
+    private OfficeTypeEnum(String value, String label) {
+        this.value = value;
+        this.label = label;
+    }
+
+
+    public String getValue() {
+        return value;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    @Override
+    public String toString() {
+        return this.value;
+    }
+}

+ 25 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/converter/StringToDateConverter.java

@@ -0,0 +1,25 @@
+package com.jeeplus.common.converter;
+
+import cn.hutool.core.util.StrUtil;
+import org.springframework.core.convert.converter.Converter;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class StringToDateConverter implements Converter <String, Date> {
+
+    @Override
+    public Date convert(String source) {
+        Date target = null;
+        if ( !StrUtil.isEmpty ( source ) ) {
+            SimpleDateFormat format = new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss" );
+            try {
+                target = format.parse ( source );
+            } catch (ParseException e) {
+                throw new RuntimeException ( String.format ( "parser %s to Date fail", source ) );
+            }
+        }
+        return target;
+    }
+}

+ 70 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/converter/mapper/JsonMapper.java

@@ -0,0 +1,70 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.common.converter.mapper;
+
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser.Feature;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.NullSerializer;
+import net.sf.json.JSONNull;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
+
+/**
+ * JSONMapper
+ * 定制返回给前台的数据格式
+ *
+ * @1654393149326127106
+ */
+@Component
+@Primary
+public class JsonMapper extends ObjectMapper {
+
+    private static final long serialVersionUID = 1L;
+
+
+    public JsonMapper() {
+        this.setSerializationInclusion ( Include.NON_NULL );
+        SimpleModule netSfJsonModule = new SimpleModule ( "net.sf.json" );
+        netSfJsonModule.addSerializer ( JSONNull.class, NullSerializer.instance );
+        this.registerModule ( netSfJsonModule );
+        this.configure ( Feature.ALLOW_SINGLE_QUOTES, true );
+        this.configure ( Feature.ALLOW_UNQUOTED_FIELD_NAMES, true );
+        this.disable ( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES );
+        this.getSerializerProvider ( ).setNullValueSerializer ( new JsonSerializer <Object> ( ) {
+            @Override
+            public void serialize(Object value, JsonGenerator jsonGenerator,
+                                  SerializerProvider provider) throws IOException {
+                jsonGenerator.writeString ( "" );
+            }
+
+        } );
+        // 进行HTML解码。
+        this.registerModule ( new SimpleModule ( ).addSerializer ( String.class, new JsonSerializer <String> ( ) {
+            @Override
+            public void serialize(String value, JsonGenerator jsonGenerator,
+                                  SerializerProvider provider) throws IOException {
+                //xss攻击避免
+                jsonGenerator.writeString ( value );
+            }
+        } ) );
+        // 时间格式化
+        this.configure ( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );
+        this.setDateFormat ( new SimpleDateFormat ( "yyyy-MM-dd HH:mm:ss" ) );
+
+        // 设置时区
+        this.setTimeZone ( TimeZone.getTimeZone ( "GMT+8:00" ) );
+    }
+
+
+}

+ 98 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/EasyExcelUtils.java

@@ -0,0 +1,98 @@
+package com.jeeplus.common.excel;
+
+import com.alibaba.excel.EasyExcel;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jeeplus.core.mapstruct.EntityWrapper;
+import lombok.Data;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @Author liugf
+ * @Description easyExcel导入导出通用工具类
+ * @Date 2022-7-29
+ * @Param
+ * @return
+ **/
+
+@Data
+public class EasyExcelUtils<T> {
+
+    private IService service;
+
+    private EntityWrapper wrapper;
+
+    public static EasyExcelUtils newInstance() {
+        return new EasyExcelUtils ( );
+    }
+
+    public static EasyExcelUtils newInstance(IService service, EntityWrapper wrapper) {
+        return new EasyExcelUtils ( service, wrapper );
+    }
+
+    public EasyExcelUtils() {
+
+    }
+
+    public EasyExcelUtils(IService service, EntityWrapper wrapper) {
+        this.service = service;
+        this.wrapper = wrapper;
+    }
+
+
+    /**
+     * 功能描述:复杂导出Excel,包括文件名以及表名,不创建表头
+     *
+     * @param list      导出的实体类
+     * @param sheetName sheet表名
+     * @param pojoClass 映射的实体类
+     * @param fileName  文件名
+     * @param response
+     * @return
+     * @author Steel.D
+     * @Date 2019-7-31 9:35
+     */
+
+    public void exportExcel(List <?> list, String sheetName, Class <?> pojoClass, String fileName, Collection <String> includeColumnFieldNames, HttpServletResponse response) throws IOException {
+
+        response.setContentType ( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" );
+        response.setCharacterEncoding ( "utf-8" );
+        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
+        fileName = URLEncoder.encode ( fileName, "UTF-8" ).replaceAll ( "\\+", "%20" );
+        response.setHeader ( "Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx" );
+        if ( includeColumnFieldNames != null ) {
+            EasyExcel.write ( response.getOutputStream ( ), pojoClass ).includeColumnFieldNames ( includeColumnFieldNames ).sheet ( sheetName ).doWrite ( list );
+        } else {
+            EasyExcel.write ( response.getOutputStream ( ), pojoClass ).sheet ( sheetName ).doWrite ( list );
+        }
+
+    }
+
+
+    /**
+     * 功能描述:根据接收的Excel文件来导入Excel,并封装成实体类
+     *
+     * @param file      上传的文件
+     * @param pojoClass Excel实体类
+     * @return
+     * @author Steel.D
+     * @Date 2019-7-31 11:30
+     */
+
+    public String importExcel(MultipartFile file, Class <T> pojoClass) throws IOException {
+        if ( file == null ) {
+            return "上传文件不能为空!";
+        }
+        ExcelListener excelListener = new ExcelListener ( this.service, this.wrapper );
+        EasyExcel.read ( file.getInputStream ( ), pojoClass, excelListener ).sheet ( ).doRead ( );
+        return excelListener.getMessage ( );
+
+    }
+
+
+}

+ 63 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/ExcelFieldDTOConverter.java

@@ -0,0 +1,63 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.common.excel;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jeeplus.common.excel.annotation.ExcelFieldProperty;
+import com.jeeplus.core.mapstruct.EntityWrapper;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.mapstruct.factory.Mappers;
+
+
+/**
+ * 字典类型转换
+ *
+ * @author jeeplus
+ * @version 2022-08-01
+ */
+
+public class ExcelFieldDTOConverter implements Converter <Object> {
+
+    @Override
+    public Object convertToJavaData(ReadCellData <?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        String key = contentProperty.getField ( ).getAnnotation ( ExcelFieldProperty.class ).value ( );
+        String filed = key.substring ( key.lastIndexOf ( "." ) + 1 );
+        String serviceClass = contentProperty.getField ( ).getAnnotation ( ExcelFieldProperty.class ).service ( );
+        String wrapperClass = contentProperty.getField ( ).getAnnotation ( ExcelFieldProperty.class ).wrapper ( );
+        String val = cellData.getStringValue ( );
+        QueryWrapper queryWrapper = new QueryWrapper ( );
+        queryWrapper.eq ( filed, val );
+        Object bean = ((IService) SpringUtil.getBean ( Class.forName ( serviceClass ) )).getOne ( queryWrapper );
+        Object dto = ((EntityWrapper) Mappers.getMapper ( Class.forName ( wrapperClass ) )).toDTO ( bean );
+        return dto;
+    }
+
+    @Override
+    public WriteCellData <?> convertToExcelData(Object value, ExcelContentProperty contentProperty,
+                                                GlobalConfiguration globalConfiguration) {
+
+
+        String key = contentProperty.getField ( ).getAnnotation ( ExcelFieldProperty.class ).value ( );
+        String filed = key.substring ( key.lastIndexOf ( "." ) + 1 );
+
+        try {
+            String val = PropertyUtils.getNestedProperty ( value, filed ).toString ( );
+            WriteCellData <Object> objectWriteCellData = new WriteCellData <> ( val );
+            return objectWriteCellData;
+        } catch (Exception e) {
+            WriteCellData <Object> objectWriteCellData = new WriteCellData <> ( "" );
+            return objectWriteCellData;
+        }
+
+    }
+
+}
+

+ 107 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/ExcelListener.java

@@ -0,0 +1,107 @@
+package com.jeeplus.common.excel;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.read.listener.ReadListener;
+import com.alibaba.excel.util.ListUtils;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.jeeplus.common.beanvalidator.BeanValidators;
+import com.jeeplus.core.mapstruct.EntityWrapper;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.validation.ConstraintViolationException;
+import javax.validation.Validator;
+import java.util.List;
+
+// 有个很重要的点 ExcelListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
+@Slf4j
+@Data
+public class ExcelListener<T> implements ReadListener <T> {
+
+    private String message;
+
+    /**
+     * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
+     */
+    private static final int BATCH_COUNT = 100;
+    /**
+     * 缓存的数据
+     */
+    private List <T> cachedDataList = ListUtils.newArrayListWithExpectedSize ( BATCH_COUNT );
+    /**
+     * 业务存储service
+     */
+    private IService service;
+
+    private EntityWrapper wrapper;
+
+
+    /**
+     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
+     *
+     * @param service
+     */
+    public ExcelListener(IService service, EntityWrapper wrapper) {
+        this.service = service;
+        this.wrapper = wrapper;
+    }
+
+    /**
+     * 这个每一条数据解析都会来调用
+     *
+     * @param data    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
+     * @param context
+     */
+    @Override
+    public void invoke(T data, AnalysisContext context) {
+        log.info ( "解析到一条数据:{}", data.toString ( ) );
+        cachedDataList.add ( data );
+        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
+        if ( cachedDataList.size ( ) >= BATCH_COUNT ) {
+            saveData ( );
+            // 存储完成清理 list
+            cachedDataList = ListUtils.newArrayListWithExpectedSize ( BATCH_COUNT );
+        }
+    }
+
+    /**
+     * 所有数据解析完成了 都会来调用
+     *
+     * @param context
+     */
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext context) {
+        // 保存数据到数据库
+        saveData ( );
+        log.info ( "所有数据解析完成!" );
+    }
+
+    /**
+     * 加上存储数据库
+     */
+    public void saveData() {
+        log.info ( "{}条数据,开始导入数据库!", cachedDataList.size ( ) );
+        Validator validator = SpringUtil.getBean ( Validator.class );
+        StringBuilder failureMsg = new StringBuilder ( );
+        cachedDataList.forEach ( cachedData -> {
+            try {
+                BeanValidators.validateWithException ( validator, cachedData );
+            } catch (ConstraintViolationException ex) {
+                List <String> messageList = BeanValidators.extractPropertyAndMessageAsList ( ex, ": " );
+                for (String message : messageList) {
+                    failureMsg.append ( message + "; " );
+                }
+            }
+        } );
+
+        if ( StrUtil.isNotEmpty ( failureMsg.toString ( ) ) ) {
+            this.message = failureMsg.toString ( );
+            log.info ( this.message );
+            return;
+        }
+        service.saveBatch ( wrapper.toEntity ( cachedDataList ) );
+        this.message = "导入数据库成功!";
+    }
+}

+ 32 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/ExcelOptions.java

@@ -0,0 +1,32 @@
+package com.jeeplus.common.excel;
+
+import com.google.common.collect.Lists;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ExcelOptions {
+    /**
+     * 选中的数据id
+     */
+    private List <String> selectIds = Lists.newArrayList ( );
+
+    /**
+     * 文件名
+     */
+    private String filename;
+    /**
+     * 导出模式 all, current, selected
+     */
+    private String mode = "all";
+    /**
+     * sheet name
+     */
+    private String sheetName;
+    /**
+     * 导出字段
+     */
+    private List <String> exportFields = Lists.newArrayList ( );
+
+}

+ 7 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/ExportMode.java

@@ -0,0 +1,7 @@
+package com.jeeplus.common.excel;
+
+public interface ExportMode {
+    String all = "all";
+    String current = "current";
+    String selected = "selected";
+}

+ 11 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/annotation/ExcelDictProperty.java

@@ -0,0 +1,11 @@
+package com.jeeplus.common.excel.annotation;
+
+import java.lang.annotation.*;
+
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface ExcelDictProperty {
+
+    String value() default "";
+}

+ 15 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/annotation/ExcelFieldProperty.java

@@ -0,0 +1,15 @@
+package com.jeeplus.common.excel.annotation;
+
+import java.lang.annotation.*;
+
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface ExcelFieldProperty {
+
+    String value() default "";
+
+    String service() default "";
+
+    String wrapper() default "";
+}

+ 7 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/excel/annotation/ExportMode.java

@@ -0,0 +1,7 @@
+package com.jeeplus.common.excel.annotation;
+
+public interface ExportMode {
+    String all = "all";
+    String current = "current";
+    String selected = "selected";
+}

+ 60 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/redis/RedisConfig.java

@@ -0,0 +1,60 @@
+package com.jeeplus.common.redis;
+
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.cache.RedisCacheWriter;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializationContext;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * redis缓存配置
+ */
+@Configuration
+@EnableCaching
+public class RedisConfig extends CachingConfigurerSupport {
+
+
+    /**
+     * RedisTemplate配置
+     *
+     * @param connectionFactory
+     * @return
+     */
+    @Bean
+    public RedisTemplate <String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
+        // 配置redisTemplate
+        RedisTemplate <String, Object> redisTemplate = new RedisTemplate <> ( );
+
+        redisTemplate.setKeySerializer ( new StringRedisSerializer ( ) );
+        redisTemplate.setValueSerializer ( new JdkSerializationRedisSerializer ( ) );
+        redisTemplate.setHashKeySerializer ( new StringRedisSerializer ( ) );
+        redisTemplate.setHashValueSerializer ( new StringRedisSerializer ( ) );
+
+        redisTemplate.setConnectionFactory ( connectionFactory );
+        return redisTemplate;
+    }
+
+
+    @Bean
+    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
+        //初始化一个RedisCacheWriter
+        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter ( connectionFactory );
+        //设置CacheManager的值序列化方式为JdkSerializationRedisSerializer,但其实RedisCacheConfiguration默认就是使用StringRedisSerializer序列化key,JdkSerializationRedisSerializer序列化value,所以以下注释代码为默认实现
+        ClassLoader loader = this.getClass ( ).getClassLoader ( );
+        JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer ( loader );
+        RedisSerializationContext.SerializationPair <Object> pair = RedisSerializationContext.SerializationPair.fromSerializer ( jdkSerializer );
+        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig ( ).serializeValuesWith ( pair );
+        //初始化RedisCacheManager
+        RedisCacheManager cacheManager = new RedisCacheManager ( redisCacheWriter, defaultCacheConfig );
+        return cacheManager;
+    }
+
+}

+ 0 - 0
jeeplus-common/jeeplus-common-core/src/main/java/com/jeeplus/common/redis/RedisUtils.java


Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio