zhaojinyu 3 месяцев назад
Сommit
b996c4a5b5
100 измененных файлов с 3977 добавлено и 0 удалено
  1. 8 0
      .idea/.gitignore
  2. 64 0
      .idea/compiler.xml
  3. 57 0
      .idea/encodings.xml
  4. 45 0
      .idea/jarRepositories.xml
  5. 12 0
      .idea/misc.xml
  6. 7 0
      .idea/vcs.xml
  7. 129 0
      README.md
  8. 25 0
      jnpf-boot-common/jnpf-common-ai/pom.xml
  9. 187 0
      jnpf-boot-common/jnpf-common-ai/src/main/java/jnpf/config/AiAutoConfiguration.java
  10. 113 0
      jnpf-boot-common/jnpf-common-ai/src/main/java/jnpf/config/AiProperties.java
  11. 53 0
      jnpf-boot-common/jnpf-common-ai/src/main/java/jnpf/constants/AiConstants.java
  12. 42 0
      jnpf-boot-common/jnpf-common-ai/src/main/java/jnpf/service/OpenAiService.java
  13. 87 0
      jnpf-boot-common/jnpf-common-ai/src/main/java/jnpf/service/impl/DefaultOpenAiServiceImpl.java
  14. 41 0
      jnpf-boot-common/jnpf-common-ai/src/main/java/jnpf/service/impl/DisabledOpenAiServiceImpl.java
  15. 121 0
      jnpf-boot-common/jnpf-common-ai/target/classes/META-INF/spring-configuration-metadata.json
  16. BIN
      jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/config/AiAutoConfiguration$AiEnabledConfiguration$1.class
  17. BIN
      jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/config/AiAutoConfiguration$AiEnabledConfiguration.class
  18. BIN
      jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/config/AiAutoConfiguration.class
  19. BIN
      jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/config/AiProperties$ChatOption.class
  20. BIN
      jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/config/AiProperties$Proxy.class
  21. BIN
      jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/config/AiProperties.class
  22. BIN
      jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/constants/AiConstants$Model.class
  23. BIN
      jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/constants/AiConstants.class
  24. BIN
      jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/service/OpenAiService.class
  25. BIN
      jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/service/impl/DefaultOpenAiServiceImpl$1.class
  26. BIN
      jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/service/impl/DefaultOpenAiServiceImpl.class
  27. BIN
      jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/service/impl/DisabledOpenAiServiceImpl.class
  28. BIN
      jnpf-boot-common/jnpf-common-ai/target/jnpf-common-ai-5.2.0-RELEASE.jar
  29. 3 0
      jnpf-boot-common/jnpf-common-ai/target/maven-archiver/pom.properties
  30. 13 0
      jnpf-boot-common/jnpf-common-ai/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
  31. 6 0
      jnpf-boot-common/jnpf-common-ai/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
  32. 71 0
      jnpf-boot-common/jnpf-common-auth/pom.xml
  33. 148 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/config/AsyncConfig.java
  34. 48 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/config/AuthAutoConfigration.java
  35. 61 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/config/JnpfOauthConfig.java
  36. 104 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/config/JnpfTokenConfig.java
  37. 83 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/consts/AuthConsts.java
  38. 40 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/consts/DeviceType.java
  39. 46 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/consts/LoginTicketStatus.java
  40. 29 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/consts/ScanCodeTicketStatus.java
  41. 288 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/granter/AbstractTokenGranter.java
  42. 24 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/granter/TokenGranter.java
  43. 84 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/granter/TokenGranterBuilder.java
  44. 38 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/granter/UserDetailsServiceBuilder.java
  45. 37 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/model/LoginTicketModel.java
  46. 25 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/model/ScanCodeLoginConfigModel.java
  47. 61 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/service/LoginService.java
  48. 19 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/service/UserDetailService.java
  49. 121 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/util/TenantProvider.java
  50. 68 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/util/TicketUtil.java
  51. 545 0
      jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/util/UserProvider.java
  52. 222 0
      jnpf-boot-common/jnpf-common-auth/target/classes/META-INF/spring-configuration-metadata.json
  53. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/config/AsyncConfig.class
  54. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/config/AuthAutoConfigration.class
  55. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/config/JnpfOauthConfig.class
  56. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/config/JnpfTokenConfig.class
  57. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/consts/AuthConsts.class
  58. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/consts/DeviceType.class
  59. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/consts/LoginTicketStatus.class
  60. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/consts/ScanCodeTicketStatus.class
  61. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/granter/AbstractTokenGranter.class
  62. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/granter/TokenGranter.class
  63. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/granter/TokenGranterBuilder.class
  64. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/granter/UserDetailsServiceBuilder.class
  65. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/model/LoginTicketModel.class
  66. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/model/ScanCodeLoginConfigModel.class
  67. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/service/LoginService.class
  68. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/service/UserDetailService.class
  69. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/util/TenantProvider.class
  70. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/util/TicketUtil.class
  71. BIN
      jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/util/UserProvider.class
  72. BIN
      jnpf-boot-common/jnpf-common-auth/target/jnpf-common-auth-5.2.0-RELEASE.jar
  73. 3 0
      jnpf-boot-common/jnpf-common-auth/target/maven-archiver/pom.properties
  74. 20 0
      jnpf-boot-common/jnpf-common-auth/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
  75. 19 0
      jnpf-boot-common/jnpf-common-auth/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
  76. 23 0
      jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/pom.xml
  77. 84 0
      jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/src/main/java/cn/afterturn/easypoi/util/PoiValidationUtil.java
  78. BIN
      jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/target/classes/cn/afterturn/easypoi/util/PoiValidationUtil.class
  79. BIN
      jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/target/jnpf-common-office-v3-5.2.0-RELEASE.jar
  80. 3 0
      jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/target/maven-archiver/pom.properties
  81. 1 0
      jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
  82. 1 0
      jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
  83. 16 0
      jnpf-boot-common/jnpf-common-connector/pom.xml
  84. 24 0
      jnpf-boot-common/jnpf-common-connector/src/main/java/jnpf/permission/connector/HttpRequestUserInfoService.java
  85. 43 0
      jnpf-boot-common/jnpf-common-connector/src/main/java/jnpf/permission/connector/UserInfoService.java
  86. BIN
      jnpf-boot-common/jnpf-common-connector/target/classes/jnpf/permission/connector/HttpRequestUserInfoService.class
  87. BIN
      jnpf-boot-common/jnpf-common-connector/target/classes/jnpf/permission/connector/UserInfoService.class
  88. BIN
      jnpf-boot-common/jnpf-common-connector/target/jnpf-common-connector-5.2.0-RELEASE.jar
  89. 3 0
      jnpf-boot-common/jnpf-common-connector/target/maven-archiver/pom.properties
  90. 2 0
      jnpf-boot-common/jnpf-common-connector/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
  91. 2 0
      jnpf-boot-common/jnpf-common-connector/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
  92. 287 0
      jnpf-boot-common/jnpf-common-core/pom.xml
  93. 27 0
      jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/EncryptApi.java
  94. 32 0
      jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/HandleLog.java
  95. 119 0
      jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/JnpfField.java
  96. 18 0
      jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/OrganizeAdminIsTrator.java
  97. 17 0
      jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/OrganizePermission.java
  98. 17 0
      jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/PositionPermission.java
  99. 18 0
      jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/RolePermission.java
  100. 23 0
      jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/SaCheckSame.java

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 64 - 0
.idea/compiler.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <annotationProcessing>
+      <profile name="Maven default annotation processors profile" enabled="true">
+        <sourceOutputDir name="target/generated-sources/annotations" />
+        <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
+        <outputRelativeToContentRoot value="true" />
+        <module name="jnpf-common-mq" />
+        <module name="jnpf-common-cloudshardingsphere" />
+        <module name="jnpf-common-ai" />
+        <module name="jnpf-common-event" />
+        <module name="jnpf-common-seata" />
+        <module name="jnpf-common-connector" />
+        <module name="jnpf-common-file" />
+        <module name="jnpf-common-i18n" />
+        <module name="jnpf-common-core" />
+        <module name="jnpf-common-security" />
+        <module name="jnpf-common-redis" />
+        <module name="jnpf-common-scheduletask" />
+        <module name="jnpf-common-dubbo" />
+        <module name="jnpf-common-feign" />
+        <module name="jnpf-common-office-v3" />
+        <module name="jnpf-common-database" />
+        <module name="jnpf-common-shardingsphere" />
+        <module name="jnpf-common-swagger" />
+        <module name="jnpf-common-auth" />
+        <module name="jnpf-common-selenium" />
+        <module name="jnpf-common-sms" />
+        <module name="jnpf-common-office" />
+      </profile>
+    </annotationProcessing>
+  </component>
+  <component name="JavacSettings">
+    <option name="ADDITIONAL_OPTIONS_OVERRIDE">
+      <module name="jnpf-boot-common" options="-parameters" />
+      <module name="jnpf-cloud-common" options="-parameters" />
+      <module name="jnpf-common" options="-parameters" />
+      <module name="jnpf-common-ai" options="-parameters" />
+      <module name="jnpf-common-auth" options="-parameters" />
+      <module name="jnpf-common-cloudshardingsphere" options="-parameters" />
+      <module name="jnpf-common-connector" options="-parameters" />
+      <module name="jnpf-common-core" options="-parameters" />
+      <module name="jnpf-common-database" options="-parameters" />
+      <module name="jnpf-common-dubbo" options="-parameters" />
+      <module name="jnpf-common-event" options="-parameters" />
+      <module name="jnpf-common-feign" options="-parameters" />
+      <module name="jnpf-common-file" options="-parameters" />
+      <module name="jnpf-common-i18n" options="-parameters" />
+      <module name="jnpf-common-mq" options="-parameters" />
+      <module name="jnpf-common-office" options="-parameters" />
+      <module name="jnpf-common-office-v3" options="-parameters" />
+      <module name="jnpf-common-redis" options="-parameters" />
+      <module name="jnpf-common-scheduletask" options="-parameters" />
+      <module name="jnpf-common-seata" options="-parameters" />
+      <module name="jnpf-common-security" options="-parameters" />
+      <module name="jnpf-common-selenium" options="-parameters" />
+      <module name="jnpf-common-shardingsphere" options="-parameters" />
+      <module name="jnpf-common-sms" options="-parameters" />
+      <module name="jnpf-common-swagger" options="-parameters" />
+      <module name="jnpf-dependencies" options="-parameters" />
+    </option>
+  </component>
+</project>

+ 57 - 0
.idea/encodings.xml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding">
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-ai/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-ai/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-auth/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-auth/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-connector/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-connector/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-core/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-core/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-database/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-database/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-event/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-event/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-file/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-file/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-i18n/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-i18n/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-office/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-office/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-redis/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-redis/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-scheduletask/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-scheduletask/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-security/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-security/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-selenium/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-selenium/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-shardingsphere/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-shardingsphere/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-sms/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-sms/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-swagger/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/jnpf-common-swagger/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-boot-common/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-cloud-common/jnpf-common-cloudshardingsphere/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-cloud-common/jnpf-common-cloudshardingsphere/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-cloud-common/jnpf-common-dubbo/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-cloud-common/jnpf-common-dubbo/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-cloud-common/jnpf-common-feign/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-cloud-common/jnpf-common-feign/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-cloud-common/jnpf-common-mq/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-cloud-common/jnpf-common-mq/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-cloud-common/jnpf-common-seata/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-cloud-common/jnpf-common-seata/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-cloud-common/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-cloud-common/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-dependencies/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/jnpf-dependencies/src/main/resources" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
+  </component>
+</project>

+ 45 - 0
.idea/jarRepositories.xml

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RemoteRepositoriesConfiguration">
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Central Repository" />
+      <option name="url" value="http://127.0.0.1:9999/repository/maven-public/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="getui-nexus" />
+      <option name="name" value="getui-nexus" />
+      <option name="url" value="http://127.0.0.1:9999/repository/maven-public/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="getui-nexus" />
+      <option name="name" value="getui-nexus" />
+      <option name="url" value="http://127.0.0.1:9999/service/rest/repository/browse/maven-public/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Maven Central repository" />
+      <option name="url" value="https://repo1.maven.org/maven2" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Central Repository" />
+      <option name="url" value="http://127.0.0.1:9999/service/rest/repository/browse/maven-public/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Central Repository" />
+      <option name="url" value="http://maven.aliyun.com/nexus/content/groups/public" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="jboss.community" />
+      <option name="name" value="JBoss Community repository" />
+      <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="getui-nexus" />
+      <option name="name" value="getui-nexus" />
+      <option name="url" value="http://mvn.gt.igexin.com/nexus/content/repositories/releases/" />
+    </remote-repository>
+  </component>
+</project>

+ 12 - 0
.idea/misc.xml

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

+ 7 - 0
.idea/vcs.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 129 - 0
README.md

@@ -0,0 +1,129 @@
+> 特别说明:源码、JDK、数据库、Redis等安装或存放路径禁止包含中文、空格、特殊字符等
+
+## 一 项目结构
+
+```text
+├── jnpf-boot-common - 单体版本涉及依赖 
+│   ├── jnpf-common-auth - 认证模块
+│   ├── jnpf-common-compatible - 兼容模块文件夹
+│           ├── jnpf-common-office-v3- Boot3 Office
+│   ├── jnpf-common-connector - 单点数据推送模块
+│   ├── jnpf-common-core - 基础类及常用工具
+│   ├── jnpf-common-database - 数据库配置及多数据库兼容
+│   ├── jnpf-common-event - 事件发布
+│   ├── jnpf-common-file - 文件工具类模块
+│   ├── jnpf-common-i18n - 文件工具类模块
+│   ├── jnpf-common-office - office操作模块
+│   ├── jnpf-common-redis -  缓存工具Redis组件配置
+│   ├── jnpf-common-scheduletask - 调度工具
+│   ├── jnpf-common-security - 接口鉴权配置
+│   ├── jnpf-common-selenium - 浏览器模拟
+│   ├── jnpf-common-shardingsphere - shardingsphere配置
+│   ├── jnpf-common-sms - 短信模块
+│   ├── jnpf-common-swagger - API组件Swagger配置
+│   └── pom.xml
+├── jnpf-cloud-common - 微服务版本涉及依赖 
+│   ├── jnpf-common-cloudshardingsphere - 微服务shardingsphere配置
+│   ├── jnpf-common-dubbo - Dubbo拦截器, 自动封装认证信息
+│   ├── jnpf-common-mq - 消息队列
+│   ├── jnpf-common-feign - 远程调用Feign组件配置
+│   ├── jnpf-common-seata - seata依赖
+│   └── pom.xml
+├── jnpf-dependencies - 所有依赖版本
+│   └── pom.xml
+├── pom.xml
+└── README.md - 项目说明文档
+```
+
+## 二 环境要求
+
+| 类目    | 版本或建议  |
+|-------|---------|
+| 硬件    | 开发电脑建议使用I3及以上CPU,16G及以上内存  |
+| 操作系统  | Windows 10/11,MacOS   |
+| JDK   | 默认使用JDK 21,兼容JDK 8/11、JDK17(需调整部分代码),推荐使用 `OpenJDK`,如 `Liberica JDK`、`Eclipse Temurin`、`Alibaba Dragonwell`、`BiSheng`等发行版; |
+| Maven | 依赖管理工具,推荐使用 `3.6.3` 及以上版本  |
+| IDE   | 代码集成开发环境,推荐使用 `IDEA2024` 及以上版本,兼容 `Eclipse`、 `Spring Tool Suite` 等IDE工具 |
+
+## 三 关联项目
+
+> 为以下项目提供基础依赖
+
+| 项目 | 分支            | 说明 |
+| --- |---------------| --- |
+| jnpf-file-core-starter | v5.2.x-stable | 文件基础依赖项目源码 |
+| jnpf-java-datareport-univer | v5.2.x-stable | Univer报表源码 |
+| jnpf-java-datareport-univer-core | v5.2.x-stable | Univer报表核心依赖源码 |
+| jnpf-scheduletask | v5.2.x-stable | 任务调度客户端依赖及服务端项目源码 |
+| jnpf-java-boot  | v5.2.x-stable | Java单体后端项目源码 |
+| jnpf-java-cloud | v5.2.x-stable | Java微服务后端项目源码 |
+
+## 四 使用方式
+
+### 4.1 前置条件
+
+#### 4.1.1 本地安装jnpf-common-core
+
+在IDEA中,双击右侧 `Maven` 中 `jnpf-common` > `jnpf-boot-common` > `jnpf-common-core` > `Lifecycle` > `install`,将 `jnpf-common-core` 包安装至本地
+
+#### 4.1.2 本地安装jnpf-dependencies
+
+在IDEA中,双击右侧 `Maven` 中 `jnpf-common` > `jnpf-dependencies` > `Lifecycle` > `install`,将 `jnpf-dependencies` 包安装至本地
+
+#### 4.1.3 本地安装file-core-starter
+
+IDEA打开 `jnpf-file-core-starter` 项目, 双击右侧 `Maven`中 `jnpf-file-core-starter` > `Lifecycle` > `install`,将 `jnpf-file-core-starter` 包安装至本地
+
+#### 4.1.4 本地安装scheduletask
+
+IDEA打开 `jnpf-scheduletask` 项目, 双击右侧 `Maven`中`jnpf-scheduletask` > `Lifecycle` > `install`,将 `jnpf-scheduletask` 包安装至本地
+
+### 4.2 本地安装
+
+在IDEA中,双击右侧 `Maven` 中 `jnpf-common` > `Lifecycle` > `install`,将 `jnpf-common` 包安装至本地
+
+### 4.3 私服发布
+> 若无Maven私服,忽略本节内容
+
+#### 4.3.1 配置Maven
+
+打开Maven安装目录中的 `conf/setttings.xml`,
+
+在 `<servers></servers>` 节点增加 `<server></server>` ,如下所示:
+
+```xml
+  <!-- 发布版 -->
+  <server>
+    <id>maven-releases</id>
+    <username>jnpf-user(账号,结合私服配置设置)</username>
+    <password>123456(密码,结合私服配置设置)</password>
+  </server>
+```
+
+#### 4.3.2 配置项目
+> 注意:pom.xml里 `<id>` 和 setting.xml 配置里 `<id>` 对应。
+
+修改 `jnpf-common/jnpf-dependencies/pom.xml` 文件
+
+```xml
+<distributionManagement>
+  <repository>
+    <id>maven-releases</id>
+    <name>maven-releases</name>
+    <url>http://nexus.jnpfsoft.com/repository/maven-releases/</url>
+  </repository>
+</distributionManagement>
+```
+
+#### 4.3.3 发布到私服
+
+在IDEA中,双击右侧 `Maven` 中 `jnpf-common` > `Lifecycle` > `deploy` 发布至私服。
+
+## 五 更新版本号
+
+打开 `jnpf-common/jnpf-dependencies/` 目录,执行如下命令
+
+```
+# mvn versions:set -DnewVersion=5.2.0-RELEASE
+mvn versions:set -DnewVersion=版本号
+```

+ 25 - 0
jnpf-boot-common/jnpf-common-ai/pom.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.jnpf</groupId>
+        <artifactId>jnpf-boot-common</artifactId>
+        <version>5.2.0-RELEASE</version>
+    </parent>
+
+    <artifactId>jnpf-common-ai</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.jnpf</groupId>
+            <artifactId>jnpf-common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.unfbx</groupId>
+            <artifactId>chatgpt-java</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 187 - 0
jnpf-boot-common/jnpf-common-ai/src/main/java/jnpf/config/AiAutoConfiguration.java

@@ -0,0 +1,187 @@
+package jnpf.config;
+
+import com.unfbx.chatgpt.OpenAiClient;
+import com.unfbx.chatgpt.function.KeyRandomStrategy;
+import com.unfbx.chatgpt.function.KeyStrategyFunction;
+import com.unfbx.chatgpt.interceptor.DefaultOpenAiAuthInterceptor;
+import com.unfbx.chatgpt.interceptor.OpenAiAuthInterceptor;
+import jnpf.constants.AiConstants;
+import jnpf.service.OpenAiService;
+import jnpf.service.impl.DefaultOpenAiServiceImpl;
+import jnpf.service.impl.DisabledOpenAiServiceImpl;
+import jnpf.util.StringUtil;
+import okhttp3.Authenticator;
+import okhttp3.OkHttpClient;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.Proxy;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * AI客户端 自动配置
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ * @date 2024/10/9 14:03
+ */
+@Configuration(proxyBeanMethods = false)
+public class AiAutoConfiguration {
+
+    @Bean
+    @ConditionalOnMissingBean
+    @ConditionalOnProperty(prefix = AiConstants.CONFIGURATION_PREFIX, name = "enabled", havingValue = "false", matchIfMissing = true)
+    public OpenAiService getDisabledOpenAiService() {
+        return new DisabledOpenAiServiceImpl();
+    }
+
+    @Configuration(proxyBeanMethods = false)
+    @ConditionalOnProperty(prefix = AiConstants.CONFIGURATION_PREFIX, name = "enabled", havingValue = "true")
+    public static class AiEnabledConfiguration{
+
+
+        @Bean
+        @ConfigurationProperties(prefix = AiConstants.CONFIGURATION_PREFIX)
+        public AiProperties getAiProperties() {
+            return new AiProperties();
+        }
+
+        @Bean
+        public OpenAiService getDefaultOpenAiService(OpenAiClient openAiClient, AiProperties aiProperties) {
+            return new DefaultOpenAiServiceImpl(openAiClient, aiProperties);
+        }
+
+        @Bean
+        @ConditionalOnMissingBean
+        public OpenAiClient getOpenAiClient(@Qualifier(AiConstants.DEFAULT_HTTP_CLIENT_BEAN_NAME) OkHttpClient okHttpClient
+                , KeyStrategyFunction keyStrategyFunction, OpenAiAuthInterceptor authInterceptor, AiProperties aiProperties) {
+            String apiHost = aiProperties.getApiHost();
+            // 需要以 / 结尾
+            if(!apiHost.isEmpty() && !apiHost.endsWith("/")){
+                apiHost +="/";
+            }
+            // 构造openAiClient
+            return OpenAiClient.builder()
+                    .apiHost(apiHost)
+                    .apiKey(aiProperties.getApiKey())
+                    .keyStrategy(keyStrategyFunction)
+                    .authInterceptor(authInterceptor)
+                    .okHttpClient(okHttpClient)
+                    .build();
+        }
+
+    /*@Bean
+    @ConditionalOnMissingBean
+    public OpenAiStreamClient getOpenAiStreamClient(@Qualifier(AiConstants.DEFAULT_HTTP_CLIENT_BEAN_NAME) OkHttpClient okHttpClient
+            , KeyStrategyFunction keyStrategyFunction, OpenAiAuthInterceptor authInterceptor, AiProperties aiProperties) {
+        String apiHost = aiProperties.getApiHost();
+        // 需要以 / 结尾
+        if(!apiHost.isEmpty() && !apiHost.endsWith("/")){
+            apiHost +="/";
+        }
+        // 构造openAiClient
+        return OpenAiStreamClient.builder()
+                .apiHost(apiHost)
+                .apiKey(aiProperties.getApiKey())
+                .keyStrategy(keyStrategyFunction)
+                .authInterceptor(authInterceptor)
+                .okHttpClient(okHttpClient)
+                .build();
+    }*/
+
+
+        /**
+         * 多Key选择策略
+         */
+        @Bean
+        @ConditionalOnMissingBean
+        public KeyStrategyFunction getDefaultOpenAiKeyStrategyFunction() {
+            return new KeyRandomStrategy();
+        }
+
+        /**
+         * 认证拦截器
+         * @see com.unfbx.chatgpt.interceptor.DynamicKeyOpenAiAuthInterceptor 动态移除无效Key
+         */
+        @Bean
+        @ConditionalOnMissingBean
+        public OpenAiAuthInterceptor getDefaultOpenAiAuthInterceptor() {
+            return new DefaultOpenAiAuthInterceptor();
+        }
+
+        /**
+         * 默认okhttpclient
+         */
+        @Bean(name = AiConstants.DEFAULT_HTTP_CLIENT_BEAN_NAME)
+        @ConditionalOnMissingBean(name = AiConstants.DEFAULT_HTTP_CLIENT_BEAN_NAME)
+        public OkHttpClient getDefaultOpenAiOkHttpClient(AiProperties aiProperties) {
+            OkHttpClient.Builder builder = new OkHttpClient
+                    .Builder();
+
+            if(aiProperties.getProxy() != null
+                    && StringUtil.isNotEmpty(aiProperties.getProxy().getHost()) && aiProperties.getProxy().getPort() != null){
+                // 设置代理
+                builder.proxy(new Proxy(aiProperties.getProxy().getType(), new InetSocketAddress(aiProperties.getProxy().getHost(), aiProperties.getProxy().getPort())));
+                // 设置代理认证
+                if(StringUtil.isNotEmpty(aiProperties.getProxy().getUsername()) && StringUtil.isNotEmpty(aiProperties.getProxy().getPassword())){
+                    builder.proxyAuthenticator(Authenticator.JAVA_NET_AUTHENTICATOR);
+                    java.net.Authenticator.setDefault(new java.net.Authenticator() {
+                        @Override
+                        protected PasswordAuthentication getPasswordAuthentication() {
+                            // 返回代理的用户名和密码
+                            return new PasswordAuthentication(aiProperties.getProxy().getUsername(), aiProperties.getProxy().getPassword().toCharArray());
+                        }
+                    });
+                }
+            }
+        /*try {
+            // 创建一个信任所有证书的 TrustManager
+            final TrustManager[] trustAllCerts = new TrustManager[]{
+                    new X509TrustManager() {
+                        @Override
+                        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                        }
+
+                        @Override
+                        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                        }
+
+                        @Override
+                        public X509Certificate[] getAcceptedIssuers() {
+                            return new X509Certificate[]{};
+                        }
+                    }
+            };
+
+            // 安装所有信任管理器
+            final SSLContext sslContext = SSLContext.getInstance("SSL");
+            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
+
+            // 创建 OkHttpClient 并配置 SSL socket factory 和 hostname verifier
+            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+
+            // 信任所有证书
+            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
+            builder.hostnameVerifier((hostname, session) -> true);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }*/
+
+            return builder
+                    .callTimeout(aiProperties.getTimeout(), TimeUnit.SECONDS)
+                    .connectTimeout(aiProperties.getTimeout(), TimeUnit.SECONDS)
+                    .writeTimeout(aiProperties.getTimeout(), TimeUnit.SECONDS)
+                    .readTimeout(aiProperties.getTimeout(), TimeUnit.SECONDS)
+                    .build();
+        }
+
+
+    }
+
+}

+ 113 - 0
jnpf-boot-common/jnpf-common-ai/src/main/java/jnpf/config/AiProperties.java

@@ -0,0 +1,113 @@
+package jnpf.config;
+
+import jnpf.constants.AiConstants;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * AI 配置
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ * @date 2024/10/9 14:03
+ */
+@Data
+public class AiProperties {
+
+    /**
+     * 是否启用
+     */
+    private boolean enabled;
+
+    /**
+     * openai服务器
+     */
+    private String apiHost = AiConstants.OPENAI_HOST;
+
+    /**
+     * openai key
+     */
+    private List<String> apiKey;
+
+    /**
+     * 超时时间
+     */
+    private Long timeout = 30L;
+
+    /**
+     * 代理配置
+     */
+    private Proxy proxy = new Proxy();
+
+    /**
+     * 对话配置
+     */
+    private ChatOption chat = new ChatOption();
+
+
+
+
+    @Data
+    public class ChatOption{
+
+        /**
+         * @see AiConstants.Model
+         */
+        private String mode = AiConstants.Model.QWEN_25_3;
+
+        /**
+         * 设置seed参数会使文本生成过程更具有确定性,通常用于使模型每次运行的结果一致。
+         * 在每次模型调用时传入相同的seed值(由您指定),并保持其他参数不变,模型将很可能返回相同的结果。
+         */
+        private Integer seed = 1234;
+
+        /**
+         * 允许模型生成的最大Token数。
+         */
+        private Integer maxTokens = 1500;
+
+        /**
+         * 核采样的概率阈值,用于控制模型生成文本的多样性。
+         * top_p越高,生成的文本更多样。反之,生成的文本更确定。
+         * 由于temperature与top_p均可以控制生成文本的多样性,因此建议您只设置其中一个值。
+         */
+        private Double topP = 0.8;
+
+        /**
+         * 采样温度,用于控制模型生成文本的多样性。
+         * temperature越高,生成的文本更多样,反之,生成的文本更确定。
+         * 由于temperature与top_p均可以控制生成文本的多样性,因此建议您只设置其中一个值。
+         */
+        private Double temperature = 0.85;
+
+        private boolean enableSearch = true;
+
+    }
+
+
+    @Data
+    public class Proxy{
+        /**
+         * HTTP, SOCKS
+         */
+        private java.net.Proxy.Type type = java.net.Proxy.Type.HTTP;
+        /**
+         * 代理域名
+         */
+        private String host;
+        /**
+         * 代理端口
+         */
+        private Integer port;
+        /**
+         * 代理用户名
+         */
+        private String username;
+        /**
+         * 代理密码
+         */
+        private String password;
+    }
+
+}

+ 53 - 0
jnpf-boot-common/jnpf-common-ai/src/main/java/jnpf/constants/AiConstants.java

@@ -0,0 +1,53 @@
+package jnpf.constants;
+
+/**
+ * AI 常量
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ * @date 2024/10/9 14:05
+ */
+public class AiConstants {
+
+    public static final String OPENAI_HOST = "https://dashscope.aliyuncs.com/compatible-mode/";
+
+    public static final String CONFIGURATION_PREFIX = "spring.cloud.ai.openai";
+
+    public static final String DEFAULT_HTTP_CLIENT_BEAN_NAME = "defaultOpenAiHttpClient";
+
+    public static final String GEN_MODEL_COMPNENT = "- input - textarea - inputNumber - switch - radio - checkbox - select - datePicker - timePicker - uploadFile - uploadImg - colorPicker - rate - slider - editor - qrcode - barcode - depSelect - posSelect - userSelect - roleSelect - areaSelect - signature - sign - location";
+
+    public static final String GEN_MODEL_QUETION = "根据当前业务需求,设计相应的表单结构。请仅返回JSON数据,不包含其他任何形式的内容。预期结果是一个JSON数组,因涉及不同表单需求,故可能包含多个表单对象。请确保命名规避数据库与编程保留字。\n" +
+            "所需表单应充分利用以下组件列表进行设计: " + GEN_MODEL_COMPNENT + "。\n" +
+            "参考给定的JSON格式,属性包含:中文名(tableTitle)、英文名(tableName)、字段列表(fields);字段列表是一个json数组,包含字段英文名(fieldName)、字段中文名(fieldTitle)等;" +
+            "创建表单结构,示例如下: [ { \"tableTitle\": \"商城订单\", \"tableName\": \"online_order_form\", \"fields\": [ {\"fieldTitle\": \"订单编号\", \"fieldName\": \"order_id\", \"fieldDbType\": \"varchar\", \"fieldComponent\": \"input\"}, {\"fieldTitle\": \"订单状态\", \"fieldName\": \"order_status\", \"fieldDbType\": \"int\", \"fieldComponent\": \"radio\", \"fieldOptions\":[{\"id\":\"1\", \"fullName\":\"未付款\"},{\"id\":\"2\", \"fullName\":\"已付款\"}]}] }, { \"tableTitle\": \"订单商品明细\", \"tableName\": \"order_item_details\", \"fields\": [ {\"fieldTitle\": \"订单ID(外键)\", \"fieldName\": \"order_id_fk\", \"fieldDbType\": \"varchar\", \"fieldComponent\": \"input\"}, {\"fieldTitle\": \"商品名称\", \"fieldName\": \"product_name\", \"fieldDbType\": \"varchar\", \"fieldComponent\": \"input\"}, {\"fieldTitle\": \"商品数量\", \"fieldName\": \"quantity\", \"fieldDbType\": \"int\", \"fieldComponent\": \"inputNumber\"}] } ]\n" +
+            "请依据实际业务逻辑,合理选择组件与字段类型,确保设计的表单既能满足数据收集需求,又便于用户操作。";
+
+
+
+    /**
+     * 模型名称
+     * @see com.unfbx.chatgpt.entity.chat.ChatCompletion.Model
+     * <a href="https://help.aliyun.com/zh/model-studio/getting-started/models">阿里官方稳定模型列表</a>
+     */
+    public static class Model{
+
+        /**
+         * 通义千问系列效果最好的模型,适合复杂、多步骤的任务。
+         */
+        public static final String QWEN_MAX = "qwen-max";
+        /**
+         * 通义千问系列速度最快、成本很低的模型,适合简单任务。
+         */
+        public static final String QWEN_TURBO = "qwen-turbo";
+        /**
+         * 通义千问开源版, 可部署参数最高的版本, 云版本收费
+         */
+        public static final String QWEN_25_72 = "qwen2.5-72b-instruct";
+        /**
+         * 通义千问开源版, 官方提供接口免费版本, 云版本限时免费
+         */
+        public static final String QWEN_25_3 = "qwen2.5-3b-instruct";
+
+    }
+}

+ 42 - 0
jnpf-boot-common/jnpf-common-ai/src/main/java/jnpf/service/OpenAiService.java

@@ -0,0 +1,42 @@
+package jnpf.service;
+
+import com.unfbx.chatgpt.entity.chat.Message;
+import jnpf.model.ai.AiFormModel;
+
+import java.util.List;
+
+
+/**
+ * AI服务工具
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ * @date 2024/10/9 14:38
+ */
+public interface OpenAiService {
+
+    /**
+     * 简单对话
+     * @param prompt
+     */
+    String completion(String prompt);
+
+    /**
+     * 连续对话
+     * @param messages 历史对话内容
+     */
+    String completion(Message... messages);
+
+    /**
+     * 生成表单
+     * @param businessName 业务名称
+     * @return
+     */
+    String generatorModelStr(String businessName);
+
+    /**
+     * 生成表单
+     * @param prompt
+     * @return
+     */
+    List<AiFormModel> generatorModelVO(String prompt);
+}

+ 87 - 0
jnpf-boot-common/jnpf-common-ai/src/main/java/jnpf/service/impl/DefaultOpenAiServiceImpl.java

@@ -0,0 +1,87 @@
+package jnpf.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.TypeReference;
+import com.unfbx.chatgpt.OpenAiClient;
+import com.unfbx.chatgpt.entity.chat.ChatCompletion;
+import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse;
+import com.unfbx.chatgpt.entity.chat.Message;
+import jnpf.config.AiProperties;
+import jnpf.constant.MsgCode;
+import jnpf.constants.AiConstants;
+import jnpf.exception.DataException;
+import jnpf.model.ai.AiFormModel;
+import jnpf.service.OpenAiService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * OpenAi 实现类
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ * @date 2024/10/9 14:39
+ */
+@Slf4j
+@AllArgsConstructor
+public class DefaultOpenAiServiceImpl implements OpenAiService {
+
+    private OpenAiClient openAiClient;
+    private AiProperties aiProperties;
+
+    @Override
+    public String completion(String prompt) {
+        Message sendMessage = Message.builder().role(Message.Role.USER).content(prompt).build();
+        ChatCompletion chatCompletion = getDefaultChatComletion(sendMessage);
+        ChatCompletionResponse chatCompletionResponse = openAiClient.chatCompletion(chatCompletion);
+        return chatCompletionResponse.getChoices().stream().map(chatChoice -> chatChoice.getMessage().getContent()).collect(Collectors.joining());
+    }
+
+    @Override
+    public String generatorModelStr(String businessName) {
+        Message sysMessage = Message.builder().role(Message.Role.SYSTEM).content(AiConstants.GEN_MODEL_QUETION).build();
+        String userTemplate = "当前业务需求是:";
+        Message sendMessage = Message.builder().role(Message.Role.USER).content(userTemplate + businessName).build();
+
+        ChatCompletion chatCompletion = getDefaultChatComletion(sysMessage, sendMessage);
+        ChatCompletionResponse chatCompletionResponse = openAiClient.chatCompletion(chatCompletion);
+        return chatCompletionResponse.getChoices().stream().map(chatChoice -> chatChoice.getMessage().getContent()).collect(Collectors.joining());
+    }
+
+    @Override
+    public List<AiFormModel> generatorModelVO(String prompt) {
+        String result = "";
+        List<AiFormModel> aiFormModels;
+        try {
+            result = generatorModelStr(prompt);
+            aiFormModels = JSON.parseObject(result, new TypeReference<List<AiFormModel>>() {});
+        } catch (Exception e){
+            log.error("AI表单生成转换失败: {}, {}", result, e.getMessage());
+            throw new DataException(MsgCode.SYS181.get());
+        }
+        return aiFormModels;
+    }
+
+    @Override
+    public String completion(Message... messages) {
+        ChatCompletion chatCompletion = getDefaultChatComletion(messages);
+        ChatCompletionResponse chatCompletionResponse = openAiClient.chatCompletion(chatCompletion);
+        return chatCompletionResponse.getChoices().stream().map(chatChoice -> chatChoice.getMessage().getContent()).collect(Collectors.joining());
+    }
+
+    private ChatCompletion getDefaultChatComletion(Message... messages){
+        AiProperties.ChatOption chatOption = aiProperties.getChat();
+        return ChatCompletion.builder()
+                .model(chatOption.getMode())
+                .temperature(chatOption.getTemperature())
+                .topP(chatOption.getTopP())
+                .seed(chatOption.getSeed())
+                .maxTokens(chatOption.getMaxTokens())
+                .messages(Arrays.asList(messages)).build();
+    }
+
+
+}

+ 41 - 0
jnpf-boot-common/jnpf-common-ai/src/main/java/jnpf/service/impl/DisabledOpenAiServiceImpl.java

@@ -0,0 +1,41 @@
+package jnpf.service.impl;
+
+import com.unfbx.chatgpt.entity.chat.Message;
+import jnpf.constant.MsgCode;
+import jnpf.exception.DataException;
+import jnpf.model.ai.AiFormModel;
+import jnpf.service.OpenAiService;
+
+import java.util.List;
+
+/**
+ * 未启用是空实现
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ * @date 2024/10/15 17:00
+ */
+public class DisabledOpenAiServiceImpl implements OpenAiService {
+    @Override
+    public String completion(String prompt) {
+        return throwError();
+    }
+
+    @Override
+    public String completion(Message... messages) {
+        return throwError();
+    }
+
+    @Override
+    public String generatorModelStr(String businessName) {
+        return throwError();
+    }
+
+    @Override
+    public List<AiFormModel> generatorModelVO(String prompt) {
+        return throwError();
+    }
+
+    public <T> T throwError(){
+        throw new DataException(MsgCode.SYS180.get());
+    }
+}

+ 121 - 0
jnpf-boot-common/jnpf-common-ai/target/classes/META-INF/spring-configuration-metadata.json

@@ -0,0 +1,121 @@
+{
+  "groups": [
+    {
+      "name": "spring.cloud.ai.openai",
+      "type": "jnpf.config.AiProperties",
+      "sourceType": "jnpf.config.AiAutoConfiguration$AiEnabledConfiguration",
+      "sourceMethod": "getAiProperties()"
+    },
+    {
+      "name": "spring.cloud.ai.openai.chat",
+      "type": "jnpf.config.AiProperties$ChatOption",
+      "sourceType": "jnpf.config.AiProperties",
+      "sourceMethod": "getChat()"
+    },
+    {
+      "name": "spring.cloud.ai.openai.proxy",
+      "type": "jnpf.config.AiProperties$Proxy",
+      "sourceType": "jnpf.config.AiProperties",
+      "sourceMethod": "getProxy()"
+    }
+  ],
+  "properties": [
+    {
+      "name": "spring.cloud.ai.openai.api-host",
+      "type": "java.lang.String",
+      "description": "openai服务器",
+      "sourceType": "jnpf.config.AiProperties"
+    },
+    {
+      "name": "spring.cloud.ai.openai.api-key",
+      "type": "java.util.List<java.lang.String>",
+      "description": "openai key",
+      "sourceType": "jnpf.config.AiProperties"
+    },
+    {
+      "name": "spring.cloud.ai.openai.chat.enable-search",
+      "type": "java.lang.Boolean",
+      "sourceType": "jnpf.config.AiProperties$ChatOption",
+      "defaultValue": true
+    },
+    {
+      "name": "spring.cloud.ai.openai.chat.max-tokens",
+      "type": "java.lang.Integer",
+      "description": "允许模型生成的最大Token数。",
+      "sourceType": "jnpf.config.AiProperties$ChatOption",
+      "defaultValue": 1500
+    },
+    {
+      "name": "spring.cloud.ai.openai.chat.mode",
+      "type": "java.lang.String",
+      "description": "@see AiConstants.Model",
+      "sourceType": "jnpf.config.AiProperties$ChatOption"
+    },
+    {
+      "name": "spring.cloud.ai.openai.chat.seed",
+      "type": "java.lang.Integer",
+      "description": "设置seed参数会使文本生成过程更具有确定性,通常用于使模型每次运行的结果一致。 在每次模型调用时传入相同的seed值(由您指定),并保持其他参数不变,模型将很可能返回相同的结果。",
+      "sourceType": "jnpf.config.AiProperties$ChatOption",
+      "defaultValue": 1234
+    },
+    {
+      "name": "spring.cloud.ai.openai.chat.temperature",
+      "type": "java.lang.Double",
+      "description": "采样温度,用于控制模型生成文本的多样性。 temperature越高,生成的文本更多样,反之,生成的文本更确定。 由于temperature与top_p均可以控制生成文本的多样性,因此建议您只设置其中一个值。",
+      "sourceType": "jnpf.config.AiProperties$ChatOption",
+      "defaultValue": 0.85
+    },
+    {
+      "name": "spring.cloud.ai.openai.chat.top-p",
+      "type": "java.lang.Double",
+      "description": "核采样的概率阈值,用于控制模型生成文本的多样性。 top_p越高,生成的文本更多样。反之,生成的文本更确定。 由于temperature与top_p均可以控制生成文本的多样性,因此建议您只设置其中一个值。",
+      "sourceType": "jnpf.config.AiProperties$ChatOption",
+      "defaultValue": 0.8
+    },
+    {
+      "name": "spring.cloud.ai.openai.enabled",
+      "type": "java.lang.Boolean",
+      "description": "是否启用",
+      "sourceType": "jnpf.config.AiProperties",
+      "defaultValue": false
+    },
+    {
+      "name": "spring.cloud.ai.openai.proxy.host",
+      "type": "java.lang.String",
+      "description": "代理域名",
+      "sourceType": "jnpf.config.AiProperties$Proxy"
+    },
+    {
+      "name": "spring.cloud.ai.openai.proxy.password",
+      "type": "java.lang.String",
+      "description": "代理密码",
+      "sourceType": "jnpf.config.AiProperties$Proxy"
+    },
+    {
+      "name": "spring.cloud.ai.openai.proxy.port",
+      "type": "java.lang.Integer",
+      "description": "代理端口",
+      "sourceType": "jnpf.config.AiProperties$Proxy"
+    },
+    {
+      "name": "spring.cloud.ai.openai.proxy.type",
+      "type": "java.net.Proxy$Type",
+      "description": "HTTP, SOCKS",
+      "sourceType": "jnpf.config.AiProperties$Proxy"
+    },
+    {
+      "name": "spring.cloud.ai.openai.proxy.username",
+      "type": "java.lang.String",
+      "description": "代理用户名",
+      "sourceType": "jnpf.config.AiProperties$Proxy"
+    },
+    {
+      "name": "spring.cloud.ai.openai.timeout",
+      "type": "java.lang.Long",
+      "description": "超时时间",
+      "sourceType": "jnpf.config.AiProperties",
+      "defaultValue": 30
+    }
+  ],
+  "hints": []
+}

BIN
jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/config/AiAutoConfiguration$AiEnabledConfiguration$1.class


BIN
jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/config/AiAutoConfiguration$AiEnabledConfiguration.class


BIN
jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/config/AiAutoConfiguration.class


BIN
jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/config/AiProperties$ChatOption.class


BIN
jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/config/AiProperties$Proxy.class


BIN
jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/config/AiProperties.class


BIN
jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/constants/AiConstants$Model.class


BIN
jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/constants/AiConstants.class


BIN
jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/service/OpenAiService.class


BIN
jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/service/impl/DefaultOpenAiServiceImpl$1.class


BIN
jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/service/impl/DefaultOpenAiServiceImpl.class


BIN
jnpf-boot-common/jnpf-common-ai/target/classes/jnpf/service/impl/DisabledOpenAiServiceImpl.class


BIN
jnpf-boot-common/jnpf-common-ai/target/jnpf-common-ai-5.2.0-RELEASE.jar


+ 3 - 0
jnpf-boot-common/jnpf-common-ai/target/maven-archiver/pom.properties

@@ -0,0 +1,3 @@
+artifactId=jnpf-common-ai
+groupId=com.jnpf
+version=5.2.0-RELEASE

+ 13 - 0
jnpf-boot-common/jnpf-common-ai/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst

@@ -0,0 +1,13 @@
+jnpf\config\AiProperties$Proxy.class
+jnpf\config\AiAutoConfiguration$AiEnabledConfiguration$1.class
+jnpf\constants\AiConstants$Model.class
+jnpf\config\AiAutoConfiguration.class
+jnpf\service\impl\DisabledOpenAiServiceImpl.class
+jnpf\config\AiAutoConfiguration$AiEnabledConfiguration.class
+jnpf\constants\AiConstants.class
+META-INF\spring-configuration-metadata.json
+jnpf\service\impl\DefaultOpenAiServiceImpl.class
+jnpf\config\AiProperties$ChatOption.class
+jnpf\service\impl\DefaultOpenAiServiceImpl$1.class
+jnpf\service\OpenAiService.class
+jnpf\config\AiProperties.class

+ 6 - 0
jnpf-boot-common/jnpf-common-ai/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst

@@ -0,0 +1,6 @@
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-ai\src\main\java\jnpf\config\AiAutoConfiguration.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-ai\src\main\java\jnpf\config\AiProperties.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-ai\src\main\java\jnpf\constants\AiConstants.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-ai\src\main\java\jnpf\service\impl\DefaultOpenAiServiceImpl.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-ai\src\main\java\jnpf\service\impl\DisabledOpenAiServiceImpl.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-ai\src\main\java\jnpf\service\OpenAiService.java

+ 71 - 0
jnpf-boot-common/jnpf-common-auth/pom.xml

@@ -0,0 +1,71 @@
+<?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>jnpf-boot-common</artifactId>
+        <groupId>com.jnpf</groupId>
+        <version>5.2.0-RELEASE</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jnpf-common-auth</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.jnpf</groupId>
+            <artifactId>jnpf-common-redis</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-jwt</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>cn.hutool</groupId>
+                    <artifactId>hutool-jwt</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-redis-jackson</artifactId>
+            <!--<exclusions>
+                <exclusion>
+                    <artifactId>spring-boot-starter-data-redis</artifactId>
+                    <groupId>org.springframework.boot</groupId>
+                </exclusion>
+            </exclusions>-->
+        </dependency>
+    </dependencies>
+
+
+    <profiles>
+        <profile>
+            <id>boot3</id>
+            <activation>
+                <jdk>[17,)</jdk>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>cn.dev33</groupId>
+                    <artifactId>sa-token-spring-boot3-starter</artifactId>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>boot2</id>
+            <activation>
+                <jdk>(,17)</jdk>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>cn.dev33</groupId>
+                    <artifactId>sa-token-spring-boot-starter</artifactId>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
+
+</project>

+ 148 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/config/AsyncConfig.java

@@ -0,0 +1,148 @@
+package jnpf.config;
+
+import jnpf.base.UserInfo;
+import jnpf.model.tenant.TenantVO;
+import jnpf.util.TenantHolder;
+import jnpf.util.UserProvider;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+/**
+ * 提供一个全局的Spring线程池对象
+ *
+ * @author JNPF开发平台组
+ * @version V3.1.0
+ * @copyright 引迈信息技术有限公司(https://www.jnpfsoft.com)
+ * @date 2021-12-10
+ */
+@Slf4j
+@Configuration
+@EnableAsync(proxyTargetClass = true)
+@AllArgsConstructor
+public class AsyncConfig implements AsyncConfigurer {
+
+
+//    private final Map<Object, Integer> asyncTaskCount = new HashMap<>();
+
+
+
+    @Primary
+    @Bean("threadPoolTaskExecutor")
+    @Override
+    public Executor getAsyncExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        // 设置线程池核心容量
+        executor.setCorePoolSize(10);
+        // 设置线程池最大容量
+        executor.setMaxPoolSize(50);
+        // 设置任务队列长度
+        executor.setQueueCapacity(2000);
+        // 设置线程超时时间
+        executor.setKeepAliveSeconds(30);
+        // 设置线程名称前缀
+        executor.setThreadNamePrefix("sysTaskExecutor");
+        // 设置任务丢弃后的处理策略
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        executor.setTaskDecorator( r ->{
+            //实现线程上下文穿透, 异步线程内无法获取之前的Request,租户信息等, 如有新的上下文对象在此处添加
+            //此方法在请求结束后在无法获取request, 下方完整异步Servlet请求
+//            RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
+            TenantVO tenantVO = TenantHolder.getLocalTenantCache();
+            UserInfo userInfo = UserProvider.getUser();
+            return () -> {
+                try {
+//                    if(attributes!= null) {
+//                        RequestContextHolder.setRequestAttributes(attributes);
+//                    }
+                    if(tenantVO != null){
+                        TenantHolder.setLocalTenantCache(tenantVO);
+                    }
+                    UserProvider.setLocalLoginUser(userInfo);
+                    r.run();
+                } finally {
+                    UserProvider.clearLocalUser();
+                    RequestContextHolder.resetRequestAttributes();
+                    TenantHolder.clearLocalTenantCache();
+                }
+            };
+        });
+
+        /*
+        //Tomcat异步Servlet只能增加吞吐量, 不能减少响应时间
+        executor.setTaskDecorator( r ->{
+            //实现线程上下文穿透, 异步线程内无法获取之前的Request,租户信息等, 如有新的上下文对象在此处添加
+            RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
+            String dataSourceId = DataSourceContextHolder.getDatasourceId();
+            String dataSourceName = DataSourceContextHolder.getDatasourceName();
+            final AsyncContext asyncContext = (AsyncContext) Optional.ofNullable(null).orElseGet(()->{
+                if(attributes!= null) {
+                    HttpServletRequest request = ((ServletRequestAttributes) attributes).getRequest();
+                    HttpServletResponse response = ((ServletRequestAttributes) attributes).getResponse();
+                    synchronized (AsyncConfig.class) {
+                        //开启多个异步
+                        AsyncContext tmpAsyncContext = request.isAsyncStarted() ? request.getAsyncContext() : request.startAsync(request, response);
+                        asyncTaskCount.put(tmpAsyncContext, asyncTaskCount.getOrDefault(tmpAsyncContext, 0) +1);
+                        return tmpAsyncContext;
+                    }
+                }
+                return null;
+            });
+            return () -> {
+                if (asyncContext != null) {
+                    asyncContext.start(() -> {
+                        if (dataSourceId != null || dataSourceName != null) {
+                            DataSourceContextHolder.setDatasource(dataSourceId, dataSourceName);
+                        }
+                        RequestContextHolder.setRequestAttributes(attributes);
+                        try {
+                            r.run();
+                        }finally{
+                            synchronized (AsyncConfig.class){
+                                //多个异步 最后一个执行关闭
+                                int count = asyncTaskCount.get(asyncContext)-1;
+                                if(count > 0){
+                                    asyncTaskCount.put(asyncContext, count);
+                                }else{
+                                    asyncTaskCount.remove(asyncContext);
+                                    asyncContext.complete();
+                                }
+                            }
+                            RequestContextHolder.resetRequestAttributes();
+                            DataSourceContextHolder.clearDatasourceType();
+                        }
+                    });
+                } else {
+                    if (dataSourceId != null || dataSourceName != null) {
+                        DataSourceContextHolder.setDatasource(dataSourceId, dataSourceName);
+                    }
+                    try {
+                        r.run();
+                    }finally{
+                        DataSourceContextHolder.clearDatasourceType();
+                    }
+                }
+            };
+        });
+         */
+        return executor;
+    }
+
+
+    @Bean("defaultExecutor")
+    public ThreadPoolTaskExecutor getAsyncExecutorDef(@Qualifier("threadPoolTaskExecutor") Executor executor) {
+        return (ThreadPoolTaskExecutor) executor;
+    }
+
+}

+ 48 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/config/AuthAutoConfigration.java

@@ -0,0 +1,48 @@
+package jnpf.config;
+
+import cn.dev33.satoken.config.SaTokenConfig;
+import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
+import cn.dev33.satoken.stp.StpLogic;
+import jnpf.consts.AuthConsts;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+
+/**
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ */
+@Configuration
+public class AuthAutoConfigration {
+
+
+    @Primary
+    @Bean
+    @ConfigurationProperties(prefix = "oauth.login")
+    public SaTokenConfig getJnpfTokenConfig() {
+        return new JnpfTokenConfig();
+    }
+
+
+    @Bean
+    @ConditionalOnMissingBean
+    @ConfigurationProperties(prefix = JnpfOauthConfig.PREFIX)
+    public JnpfOauthConfig getJnpfOauthConfig(){
+        return new JnpfOauthConfig();
+    }
+
+    @Primary
+    @Bean(AuthConsts.ACCOUNT_LOGIC_BEAN_DEFAULT)
+    public StpLogic getJnpfTokenJwtLogic() {
+        return new StpLogicJwtForSimple(AuthConsts.ACCOUNT_TYPE_DEFAULT);
+    }
+
+    @Bean(AuthConsts.ACCOUNT_LOGIC_BEAN_TENANT)
+    public StpLogic getJnpfTenantTokenJwtLogic() {
+        return new StpLogicJwtForSimple(AuthConsts.ACCOUNT_TYPE_TENANT);
+    }
+}

+ 61 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/config/JnpfOauthConfig.java

@@ -0,0 +1,61 @@
+package jnpf.config;
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+
+
+/**
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ */
+@Data
+public class JnpfOauthConfig {
+
+    public static final String PREFIX = "oauth";
+
+    /**
+     * 服务器域名
+     * @see ConfigValueUtil#getApiDomain()
+     */
+    @Deprecated
+    @Value("${config.ApiDomain:}")
+    private String jnpfDomain;
+
+
+    /**
+     * 开启单点登录, 需额外代码支持
+     */
+    private Boolean ssoEnabled = false;
+
+    /**
+     * 后端登录完整路径路径
+     */
+    private String loginPath;
+
+    /**
+     * 默认发起的登录协议
+     */
+    private String defaultSSO = "cas";
+
+    /**
+     * 轮询Ticket有效期, 秒
+     */
+    private long ticketTimeout = 60;
+
+    /**
+     * pc端服务器域名
+     * @see ConfigValueUtil#getFrontDomain()
+     */
+    @Deprecated
+    @Value("${config.FrontDomain:}")
+    private String jnpfFrontDomain;
+
+    /**
+     * app端服务器域名
+     * @see ConfigValueUtil#getAppDomain()
+     */
+    @Deprecated
+    @Value("${config.AppDomain:}")
+    private String jnpfAppDomain;
+
+}

+ 104 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/config/JnpfTokenConfig.java

@@ -0,0 +1,104 @@
+package jnpf.config;
+
+import cn.dev33.satoken.config.SaTokenConfig;
+import jnpf.consts.AuthConsts;
+import jnpf.model.BaseSystemInfo;
+import jnpf.util.Constants;
+import jnpf.util.TenantProvider;
+
+import java.util.Optional;
+
+
+/**
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ */
+public class JnpfTokenConfig extends SaTokenConfig {
+
+
+    @Override
+    public long getTimeout() {
+        BaseSystemInfo baseSystemInfo = getSycConfig();
+        if(baseSystemInfo == null){
+            return super.getTimeout();
+        }else {
+            return Long.parseLong(getSycConfig().getTokenTimeout()) * 60L;
+        }
+    }
+
+    @Override
+    public Boolean getIsConcurrent() {
+        BaseSystemInfo baseSystemInfo = getSycConfig();
+        if(baseSystemInfo == null){
+            return super.getIsConcurrent();
+        }else {
+            return Optional.ofNullable(getSycConfig().getSingleLogin()).orElse(1)==2;
+        }
+    }
+
+    @Override
+    public String getJwtSecretKey() {
+        String secrekey = super.getJwtSecretKey();
+        if(secrekey == null){
+            return AuthConsts.JWT_SECRET;
+        }
+        return secrekey;
+    }
+
+    @Override
+    public String getCurrDomain() {
+        return super.getCurrDomain();
+    }
+
+    @Override
+    public String getTokenPrefix() {
+        return AuthConsts.TOKEN_PREFIX;
+    }
+
+    @Override
+    public Boolean getTokenSessionCheckLogin() {
+        return false;
+    }
+
+    @Override
+    public Boolean getIsPrint() {
+        return false;
+    }
+
+    @Override
+    public Boolean getIsShare() {
+        return false;
+    }
+
+    @Override
+    public String getTokenName() {
+        return Constants.AUTHORIZATION;
+    }
+
+    @Override
+    public Boolean getIsReadCookie() {
+        return false;
+    }
+
+    @Override
+    public Boolean getIsReadBody() {
+        return false;
+    }
+
+    @Override
+    public Boolean getIsReadHeader() {
+        return true;
+    }
+
+    @Override
+    public int getMaxLoginCount() {
+        return -1;
+    }
+
+    private BaseSystemInfo getSycConfig(){
+        return TenantProvider.getBaseSystemInfo();
+    }
+
+
+}

+ 83 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/consts/AuthConsts.java

@@ -0,0 +1,83 @@
+package jnpf.consts;
+
+
+import cn.dev33.satoken.same.SaSameUtil;
+import jnpf.service.UserDetailService;
+
+/**
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ */
+public class AuthConsts {
+
+    public static final String DEF_TENANT_ID = "";
+    public static final String DEF_TENANT_DB = "";
+
+    public static final String ACCOUNT_TYPE_DEFAULT = "login";
+    public static final String ACCOUNT_TYPE_TENANT = "tenant";
+    public static final String ACCOUNT_LOGIC_BEAN_DEFAULT = "defaultStpLogic";
+    public static final String ACCOUNT_LOGIC_BEAN_TENANT = "tenantStpLogic";
+
+    public static final String PAR_GRANT_TYPE = "grant_type";
+
+    public static final String SYSTEM_INFO = "system_info";
+
+    /**
+     * 跨服务调用验证KEY
+     */
+    public static final String INNER_TOKEN_KEY = SaSameUtil.SAME_TOKEN;
+
+    /**
+     * 网关调用验证KEY
+     */
+    public static final String INNER_GATEWAY_TOKEN_KEY = INNER_TOKEN_KEY + "_GATEWAY";
+
+    public static final String TENANT_SESSION = "tenant:";
+
+    public static final String TOKEN_PREFIX = "bearer";
+    public static final String TOKEN_PREFIX_SP = TOKEN_PREFIX + " ";
+
+    public static final String PARAMS_JNPF_TICKET = "jnpf_ticket";
+    public static final String PARAMS_SSO_LOGOUT_TICKET = "ticket";
+
+    public static final Integer REDIRECT_PAGETYPE_LOGIN = 1;
+    public static final Integer REDIRECT_PAGETYPE_LOGOUT = 2;
+
+    public static final Integer TMP_TOKEN_UNLOGIN = -1;
+    public static final Integer TMP_TOKEN_ERRLOGIN = -2;
+
+    public static final String ONLINE_TICKET_KEY = "online_ticket:";
+    public static final String ONLINE_TICKET_TOKEN = "online_token";
+
+    public static final String JWT_SECRET = "WviMjFNC72VKwGqm5LPoheQo5XN9iN4d";
+
+    /**
+     * clientId
+     */
+    public static final String Client_Id = "Client_Id";
+
+
+    /**
+     * 用户信息获取方式 account
+     */
+    public static final String USERDETAIL_ACCOUNT = UserDetailService.USER_DETAIL_PREFIX + "UserAccount";
+    /**
+     * 用户信息获取方式 user_id
+     */
+    public static final String USERDETAIL_USER_ID = UserDetailService.USER_DETAIL_PREFIX + "UserId";
+
+    /**
+     * 认证方式 常规账号密码
+     */
+    public static final String GRANT_TYPE_PASSWORD = "password";
+    /**
+     * 认证方式 单点 CAS
+     */
+    public static final String GRANT_TYPE_CAS = "cas";
+    /**
+     * 认证方式 单点 OAUTH
+     */
+    public static final String GRANT_TYPE_OAUTH = "auth2";
+
+}

+ 40 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/consts/DeviceType.java

@@ -0,0 +1,40 @@
+package jnpf.consts;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+/**
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ */
+@Getter
+@AllArgsConstructor
+public enum DeviceType {
+
+    /**
+     * pc端
+     */
+    PC("PC"),
+
+    /**
+     * app端 手机都归为移动 自行扩展
+     */
+    APP("APP"),
+
+    /**
+     * 程序运行中使用的无限制临时用户
+     */
+    TEMPUSER("TEMPUSER"),
+
+
+    /**
+     * 程序运行中使用的限制临时用户, 不可访问主系统, CurrentUser接口报错
+     */
+    TEMPUSERLIMITED("TEMPUSERLIMITED");
+
+
+    private final String device;
+
+}

+ 46 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/consts/LoginTicketStatus.java

@@ -0,0 +1,46 @@
+package jnpf.consts;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+/**
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ */
+@Getter
+@AllArgsConstructor
+public enum LoginTicketStatus {
+
+    /**
+     * 登录成功
+     */
+    Success(1),
+    /**
+     * 未登录
+     */
+    UnLogin(2),
+    /**
+     * 登录失败
+     */
+    ErrLogin(3),
+    /**
+     * 未绑定
+     */
+    UnBind(4),
+    /**
+     * 失效
+     */
+    Invalid(5),
+    /**
+     * 多租户
+     */
+    Multitenancy(6),
+    /**
+     * 第三方账号未绑定账号,请绑定后重试
+     */
+    UnBindMes(7),;
+
+    private int status;
+}

+ 29 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/consts/ScanCodeTicketStatus.java

@@ -0,0 +1,29 @@
+package jnpf.consts;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum ScanCodeTicketStatus {
+
+    /**
+     * 已失效
+     */
+    Invalid(-1),
+    /**
+     * 未扫码
+     */
+    UnScanCode(0),
+    /**
+     * 已扫码
+     */
+    ScanCode(1),
+    /**
+     * 登录成功
+     */
+    Success(2);
+
+
+    private int status;
+}

+ 288 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/granter/AbstractTokenGranter.java

@@ -0,0 +1,288 @@
+package jnpf.granter;
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.stp.SaLoginModel;
+import cn.dev33.satoken.stp.StpUtil;
+import jnpf.base.ActionResult;
+import jnpf.base.UserInfo;
+import jnpf.config.ConfigValueUtil;
+import jnpf.constant.MsgCode;
+import jnpf.consts.AuthConsts;
+import jnpf.consts.DeviceType;
+import jnpf.consts.LoginTicketStatus;
+import jnpf.exception.LoginException;
+import jnpf.exception.TenantDatabaseException;
+import jnpf.model.BaseSystemInfo;
+import jnpf.model.LoginTicketModel;
+import jnpf.model.logout.LogoutResultModel;
+import jnpf.model.tenant.TenantVO;
+import jnpf.service.LoginService;
+import jnpf.util.RedisUtil;
+import jnpf.util.TenantProvider;
+import jnpf.util.TicketUtil;
+import jnpf.util.UserProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.Ordered;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.PathMatcher;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static jnpf.consts.AuthConsts.DEF_TENANT_DB;
+import static jnpf.consts.AuthConsts.DEF_TENANT_ID;
+
+
+/**
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ */
+public abstract class AbstractTokenGranter implements TokenGranter, Ordered {
+
+
+    @Autowired(required = false)
+    protected LoginService loginService;
+    @Autowired
+    protected UserProvider userProvider;
+    @Autowired
+    protected ConfigValueUtil configValueUtil;
+    @Autowired
+    protected RedisUtil redisUtil;
+
+    protected static PathMatcher pathMatcher = new AntPathMatcher();
+
+    private String authenticationUrl;
+
+
+    public AbstractTokenGranter(String authenticationUrl){
+        this.authenticationUrl = authenticationUrl;
+    }
+
+
+    /**
+     * 最终登录用户
+     * @param userInfo 包含账户名, 登录方式
+     * @return
+     */
+    protected String loginAccount(UserInfo userInfo, BaseSystemInfo baseSystemInfo) throws LoginException {
+        try{
+            //获取用户实现类接口名称
+            userInfo.setUserDetailKey(getUserDetailKey());
+            //获取登录信息
+            userInfo = getUserInfo(userInfo, baseSystemInfo);
+            //预登陆
+            preLogin(userInfo, baseSystemInfo);
+            //登录
+            login(userInfo, baseSystemInfo);
+        }catch(Exception e){
+            try {
+                loginFailure(userInfo, baseSystemInfo, e);
+            }catch (Exception e1){
+                throw e1;
+            }
+            throw e;
+        }
+        loginSuccess(userInfo, baseSystemInfo);
+        //返回token信息
+        return userInfo.getToken();
+    }
+
+    /**
+     * 切换多租户
+     * @param userInfo
+     * @return userAccount, tenantId, tenandDb
+     * @throws LoginException
+     */
+    protected UserInfo switchTenant(UserInfo userInfo) throws LoginException {
+        if (configValueUtil.isMultiTenancy()) {
+            userInfo = loginService.getTenantAccount(userInfo);
+            return userInfo;
+
+        }
+        userInfo.setTenantId(DEF_TENANT_ID);
+        userInfo.setTenantDbConnectionString(DEF_TENANT_DB);
+        userInfo.setTenantDbType(TenantVO.NONE);
+        return userInfo;
+    }
+
+    /**
+     * 获取系统配置
+     * @param userInfo
+     * @return
+     */
+    protected BaseSystemInfo getSysconfig(UserInfo userInfo) throws LoginException {
+        BaseSystemInfo baseSystemInfo = loginService.getBaseSystemConfig(userInfo.getTenantId());
+        if(baseSystemInfo != null && baseSystemInfo.getSingleLogin() != null){
+            TenantProvider.setBaseSystemInfo(baseSystemInfo);
+        }else{
+            throw new TenantDatabaseException().setLogMsg(MsgCode.LOG110.get());
+        }
+        return baseSystemInfo;
+    }
+
+    /**
+     * 获取登录设备
+     * @return
+     */
+    protected DeviceType getDeviceType(){
+        return UserProvider.getDeviceForAgent();
+    }
+
+
+    /**
+     * 生成登录用户信息
+     * @param userInfo
+     * @return
+     */
+    protected UserInfo getUserInfo(UserInfo userInfo, BaseSystemInfo sysConfigInfo) throws LoginException {
+        userInfo.setGrantType(getGrantType());
+        userInfo = loginService.userInfo(userInfo, sysConfigInfo);
+        return userInfo;
+    }
+
+
+    /**
+     * 登录前执行
+     * @param userInfo
+     * @param baseSystemInfo
+     */
+    protected void preLogin(UserInfo userInfo, BaseSystemInfo baseSystemInfo) throws LoginException {
+
+    }
+
+    /**
+     * 登录操作
+     * @param userInfo
+     * @param baseSystemInfo
+     */
+    protected void login(UserInfo userInfo, BaseSystemInfo baseSystemInfo) throws LoginException {
+        UserProvider.login(userInfo, getLoginModel(userInfo, baseSystemInfo));
+    }
+
+    /**
+     * 登录成功触发
+     * @param userInfo
+     * @param baseSystemInfo
+     */
+    protected void loginSuccess(UserInfo userInfo, BaseSystemInfo baseSystemInfo){
+
+    }
+
+    /**
+     * 登录失败触发
+     * @param baseSystemInfo
+     */
+    protected void loginFailure(UserInfo userInfo, BaseSystemInfo baseSystemInfo, Exception e){
+
+    }
+
+    protected abstract String getUserDetailKey();
+
+    protected String createToken(UserInfo userInfo, BaseSystemInfo baseSystemInfo){
+        //登录
+        UserProvider.login(userInfo, getLoginModel(userInfo, baseSystemInfo));
+        return StpUtil.getTokenValueNotCut();
+    }
+
+    /**
+     * 更新轮询结果为成功
+     */
+    protected void updateTicketSuccess(UserInfo userInfo){
+        String ticket = getJnpfTicket();
+        if(!ticket.isEmpty()) {
+            LoginTicketModel loginTicketModel = new LoginTicketModel()
+                            .setStatus(LoginTicketStatus.Success.getStatus())
+                            .setValue(StpUtil.getTokenValueNotCut())
+                            .setTheme(userInfo.getTheme());
+            TicketUtil.updateTicket(ticket, loginTicketModel, null);
+        }
+    }
+
+    /**
+     * 更新轮询结果为失败
+     */
+    protected void updateTicketError(String msg){
+        String ticket = getJnpfTicket();
+        if(!ticket.isEmpty()) {
+            LoginTicketModel loginTicketModel = new LoginTicketModel()
+                            .setStatus(LoginTicketStatus.ErrLogin.getStatus())
+                            .setValue(msg);
+            TicketUtil.updateTicket(ticket, loginTicketModel, null);
+        }
+    }
+
+
+    /**
+     * 获取轮询ticket
+     * @return
+     */
+    protected String getJnpfTicket(){
+        return SaHolder.getRequest().getParam(AuthConsts.PARAMS_JNPF_TICKET, "");
+    }
+
+    protected boolean isValidJnpfTicket(){
+        String jnpfTicket = getJnpfTicket();
+        if(!jnpfTicket.isEmpty()){
+            LoginTicketModel loginTicketModel = TicketUtil.parseTicket(jnpfTicket);
+            if(loginTicketModel == null){
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 获取登录参数
+     * @param userInfo
+     * @param baseSystemInfo
+     * @return
+     */
+    protected SaLoginModel getLoginModel(UserInfo userInfo, BaseSystemInfo baseSystemInfo){
+        SaLoginModel loginModel = new SaLoginModel();
+        loginModel.setTimeout(userInfo.getTokenTimeout() * 60L);
+        loginModel.setExtraData(getTokenExtraData(userInfo, baseSystemInfo));
+        if(userInfo.getLoginDevice() == null) {
+            loginModel.setDevice(getDeviceType().getDevice());
+            userInfo.setLoginDevice(loginModel.device);
+        }else{
+            loginModel.setDevice(userInfo.getLoginDevice());
+        }
+        return loginModel;
+    }
+
+    /**
+     * 获取额外的JWT内容
+     * @param userInfo
+     * @param baseSystemInfo
+     * @return
+     */
+    protected Map<String, Object> getTokenExtraData(UserInfo userInfo, BaseSystemInfo baseSystemInfo){
+        Map<String, Object> tokenInfo = new HashMap<>();
+//        tokenInfo.put("token", StpUtil.getTokenValue());
+        tokenInfo.put("singleLogin", baseSystemInfo == null ? null : baseSystemInfo.getSingleLogin());
+        tokenInfo.put("user_name", userInfo.getUserAccount());
+        tokenInfo.put("user_id", userInfo.getUserId());
+        tokenInfo.put("exp", userInfo.getOverdueTime().getTime());
+        tokenInfo.put("token", userInfo.getId());
+        return tokenInfo;
+    }
+
+    @Override
+    public ActionResult<LogoutResultModel> logout() {
+        UserProvider.logout();
+        return ActionResult.success();
+    }
+
+    protected abstract String getGrantType();
+
+
+    @Override
+    public boolean requiresAuthentication() {
+        String path = SaHolder.getRequest().getRequestPath();
+        if(path != null && path.startsWith("/api/oauth")){
+            path = path.replace("/api/oauth", "");
+        }
+        return pathMatcher.match(authenticationUrl, path);
+    }
+}

+ 24 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/granter/TokenGranter.java

@@ -0,0 +1,24 @@
+package jnpf.granter;
+
+import jnpf.base.ActionResult;
+import jnpf.exception.LoginException;
+import jnpf.model.logout.LogoutResultModel;
+
+import java.util.Map;
+
+
+/**
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ */
+public interface TokenGranter {
+
+    ActionResult granter(Map<String, String> loginParameters) throws LoginException;
+
+
+    ActionResult<LogoutResultModel> logout();
+
+    boolean requiresAuthentication();
+
+}

+ 84 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/granter/TokenGranterBuilder.java

@@ -0,0 +1,84 @@
+package jnpf.granter;
+
+import jnpf.base.UserInfo;
+import jnpf.config.JnpfOauthConfig;
+import jnpf.constant.MsgCode;
+import jnpf.consts.AuthConsts;
+import jnpf.exception.LoginException;
+import jnpf.util.UserProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+/**
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ */
+@Component
+public class TokenGranterBuilder {
+
+    @Autowired
+    private UserProvider userProvider;
+    @Autowired
+    private JnpfOauthConfig oauthConfig;
+
+    private final Map<String, TokenGranter> granterPool = new ConcurrentHashMap<>();
+
+    public TokenGranterBuilder(Map<String, TokenGranter> granterPool) {
+        granterPool.forEach(this.granterPool::put);
+    }
+
+    /**
+     * 获取TokenGranter
+     *
+     * @param grantType 授权类型
+     * @return ITokenGranter
+     */
+    public TokenGranter getGranter(String grantType) throws LoginException {
+        TokenGranter tokenGranter = null;
+        if(!oauthConfig.getSsoEnabled()) {
+            tokenGranter = granterPool.get(grantType);
+        }
+        if(tokenGranter == null){
+            //URL匹配
+            for (TokenGranter value : granterPool.values()) {
+                if(value.requiresAuthentication()){
+                    tokenGranter = value;
+                    break;
+                }
+            }
+        }
+        if(tokenGranter == null){
+            if(oauthConfig.getSsoEnabled()) {
+                throw new LoginException(MsgCode.LOG111.get());
+            }else{
+                throw new LoginException(MsgCode.LOG112.get());
+            }
+        }
+        return tokenGranter;
+    }
+
+
+    /**
+     * 获取当前登录用户的TokenGranter
+     * @return
+     * @throws LoginException
+     */
+    public TokenGranter getGranterByLogin(String grandType) {
+        if(grandType == null || grandType.isEmpty()){
+            UserInfo userInfo = userProvider.get();
+            if(userInfo.getGrantType() != null){
+                grandType = userInfo.getGrantType();
+            }else {
+                grandType = AuthConsts.GRANT_TYPE_PASSWORD;
+            }
+        }
+        return granterPool.get(grandType);
+    }
+
+
+}

+ 38 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/granter/UserDetailsServiceBuilder.java

@@ -0,0 +1,38 @@
+package jnpf.granter;
+
+import jnpf.consts.AuthConsts;
+import jnpf.service.UserDetailService;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ */
+@Component
+public class UserDetailsServiceBuilder {
+
+
+    private final Map<String, UserDetailService> userDetailServices = new ConcurrentHashMap<>();
+
+    public UserDetailsServiceBuilder(Map<String, UserDetailService> userDetailServices) {
+        userDetailServices.forEach(this.userDetailServices::put);
+    }
+
+
+    /**
+     * 根据类型获取合适的UserDetailService
+     * @param detailType
+     * @return
+     */
+    public UserDetailService getUserDetailService(String detailType){
+        if(detailType == null){
+            detailType = AuthConsts.USERDETAIL_ACCOUNT;
+        }
+        return userDetailServices.get(detailType);
+    }
+
+}

+ 37 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/model/LoginTicketModel.java

@@ -0,0 +1,37 @@
+package jnpf.model;
+
+import jnpf.consts.LoginTicketStatus;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.NonNull;
+import lombok.experimental.Accessors;
+
+/**
+ * 轮询登录模型
+ */
+@Data
+@Accessors(chain = true)
+public class LoginTicketModel {
+
+    /**
+     * 状态
+     * @see LoginTicketStatus
+     */
+    @NonNull
+    private int status = LoginTicketStatus.UnLogin.getStatus();
+
+    /**
+     * 额外的值, 登录Token、第三方登录的ID
+     */
+    private String value;
+
+    /**
+     * 前端主题
+     */
+    private String theme;
+    /**
+     * 票据有效期, 时间戳
+     */
+    private Long ticketTimeout;
+
+}

+ 25 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/model/ScanCodeLoginConfigModel.java

@@ -0,0 +1,25 @@
+package jnpf.model;
+
+import jnpf.consts.ScanCodeTicketStatus;
+import lombok.Data;
+import lombok.NonNull;
+
+@Data
+public class ScanCodeLoginConfigModel {
+
+    /**
+     * 状态
+     * @see ScanCodeTicketStatus
+     */
+    @NonNull
+    private int status = ScanCodeTicketStatus.UnScanCode.getStatus();
+
+    /**
+     * 额外的值, 登录Token、第三方登录的ID
+     */
+    private String value;
+    /**
+     * 票据有效期, 时间戳
+     */
+    private Long ticketTimeout;
+}

+ 61 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/service/LoginService.java

@@ -0,0 +1,61 @@
+package jnpf.service;
+
+import jnpf.base.UserInfo;
+import jnpf.exception.LoginException;
+import jnpf.model.BaseSystemInfo;
+import jnpf.model.login.PcUserVO;
+
+/**
+ * 登陆业务层
+ *
+ * @author JNPF开发平台组
+ * @version V3.1.0
+ * @copyright 引迈信息技术有限公司(https://www.jnpfsoft.com)
+ * @date 2021-03-23
+ */
+public interface LoginService {
+
+    /**
+     * 租戶登录验证
+     *
+     * @param userInfo
+     * @return userAccount, tenantId, tenandDb
+     * @throws LoginException
+     */
+    UserInfo getTenantAccount(UserInfo userInfo) throws LoginException;
+
+    /**
+     * 生成用户登录信息
+     * @param userInfo   账户信息
+     * @param sysConfigInfo 系统配置
+     * @return
+     * @throws LoginException
+     */
+    UserInfo userInfo(UserInfo userInfo, BaseSystemInfo sysConfigInfo) throws LoginException;
+
+    /**
+     * 获取用户登陆信息
+     *
+     * @return
+     */
+    PcUserVO getCurrentUser(String type, String systemCode);
+
+    /**
+     * 修改密码信息发送
+     *
+     * @return
+     */
+    void updatePasswordMessage();
+
+    /**
+     *
+     * @param tenantId
+     * @param tenantDb
+     * @param isAssignDataSource 是否租户指定数据源
+     * @return
+     */
+    BaseSystemInfo getBaseSystemConfig(String tenantId);
+
+
+
+}

+ 19 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/service/UserDetailService.java

@@ -0,0 +1,19 @@
+package jnpf.service;
+
+import jnpf.base.UserInfo;
+import jnpf.exception.LoginException;
+import org.springframework.core.Ordered;
+
+public interface UserDetailService extends Ordered {
+
+    static final String USER_DETAIL_PREFIX = "USERDETAIL_";
+
+    /**
+     * 获取用户信息
+     * @param userInfo
+     * @return UserEntity
+     * @param <T>
+     */
+    <T> T loadUserEntity(UserInfo userInfo) throws LoginException;
+
+}

+ 121 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/util/TenantProvider.java

@@ -0,0 +1,121 @@
+package jnpf.util;
+
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.session.SaSessionCustomUtil;
+import jnpf.model.BaseSystemInfo;
+import lombok.extern.slf4j.Slf4j;
+
+import static jnpf.consts.AuthConsts.DEF_TENANT_ID;
+import static jnpf.consts.AuthConsts.TENANT_SESSION;
+
+
+/**
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ */
+@Slf4j
+public class TenantProvider {
+
+
+    private static final long tenantTimeout = 60 * 60 * 24 * 30L;
+
+    /**
+     * 获取租户Redis存储对象
+     *
+     * @param tenantId
+     * @return
+     */
+    public static SaSession getTenantSession(String tenantId) {
+        if (tenantId == null) {
+//            tenantId = TenantHolder.getDatasourceId();
+//            if (tenantId == null) {
+                tenantId = DEF_TENANT_ID;
+//            }
+        }
+        SaSession saSession = SaSessionCustomUtil.getSessionById(TENANT_SESSION + tenantId);
+        if (saSession != null && !saSession.get("init", false)) {
+            saSession.set("init", true);
+            saSession.updateTimeout(tenantTimeout);
+        }
+        return saSession;
+    }
+
+    /**
+     * 存入租户缓存空间
+     *
+     * @param tenantId
+     * @param key
+     * @param value
+     */
+    public static void putTenantCache(String tenantId, String key, Object value) {
+        SaSession saSession = getTenantSession(tenantId);
+        if (saSession != null) {
+            saSession.set(key, value).updateTimeout(tenantTimeout);
+        }
+    }
+
+    /**
+     * 获取租户缓存数据
+     *
+     * @param tenantId
+     * @param key
+     * @param <T>
+     * @return
+     */
+    public static <T> T getTenantCache(String tenantId, String key) {
+        SaSession saSession = getTenantSession(tenantId);
+        if (saSession != null) {
+            return (T) saSession.get(key);
+        }
+        return null;
+    }
+
+    /**
+     * 删除租户缓存数据
+     *
+     * @param tenantId
+     * @param key
+     */
+    public static void delTenantCache(String tenantId, String key) {
+        SaSession saSession = getTenantSession(tenantId);
+        if (saSession != null) {
+            saSession.delete(key);
+        }
+    }
+
+    public static void renewTimeout(String tenantId, long timeout) {
+        if (tenantId == null) {
+            tenantId = DEF_TENANT_ID;
+        }
+        SaSession saSession = getTenantSession(tenantId);
+        if (saSession != null) {
+            saSession.updateTimeout(timeout);
+        }
+    }
+
+
+    private static ThreadLocal<BaseSystemInfo> systemInfoThreadLocal = new ThreadLocal<>();
+
+    /**
+     * 获取系统设置信息
+     *
+     * @return
+     */
+    public static BaseSystemInfo getBaseSystemInfo() {
+        BaseSystemInfo systemInfo = systemInfoThreadLocal.get();
+        return systemInfo;
+    }
+
+
+    public static void setBaseSystemInfo(BaseSystemInfo baseSystemInfo) {
+        systemInfoThreadLocal.set(baseSystemInfo);
+    }
+
+
+    public static void clearBaseSystemIfo() {
+        systemInfoThreadLocal.remove();
+    }
+
+
+
+}

+ 68 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/util/TicketUtil.java

@@ -0,0 +1,68 @@
+package jnpf.util;
+
+import cn.dev33.satoken.SaManager;
+import cn.dev33.satoken.temp.SaTempUtil;
+import cn.dev33.satoken.util.SaTokenConsts;
+import org.springframework.stereotype.Component;
+
+
+/**
+ *
+ * @author JNPF开发平台组
+ * @copyright 引迈信息技术有限公司
+ */
+@Component
+public class TicketUtil {
+
+
+    /**
+     * 创建临时TOKEN
+     * @param value 值
+     * @param timeout 有效时间, 秒
+     * @return
+     */
+    public static String createTicket(Object value, long timeout){
+        return SaTempUtil.createToken(value, timeout);
+    }
+
+    /**
+     * 获取临时TOKEN内的数据
+     * @see #createTicket(Object, long)
+     * @param ticket 票据
+     * @return
+     * @param <T>
+     */
+    public static <T> T parseTicket(String ticket){
+        return (T) SaTempUtil.parseToken(ticket);
+    }
+
+    /**
+     * 移除临时Token
+     * @param ticket
+     */
+    public static void deleteTicket(String ticket){
+        SaTempUtil.deleteToken(ticket);
+    }
+
+    /**
+     * 更新Ticket内的内容
+     * @see #createTicket(Object, long)
+     * @param ticket 票据
+     * @param value 新值
+     * @param timeout 超时时间, 秒, 可空为不更新
+     */
+    public static void updateTicket(String ticket, Object value, Long timeout){
+        Object obj = parseTicket(ticket);
+        if(obj == null) return;
+        String key = getTicketKey(ticket);
+        if(timeout != null){
+            SaManager.getSaTokenDao().setObject(key, value, timeout);
+        }else{
+            SaManager.getSaTokenDao().updateObject(key, value);
+        }
+    }
+
+    private static String getTicketKey(String ticket){
+        return SaManager.getSaTemp().splicingKeyTempToken(SaTokenConsts.DEFAULT_TEMP_TOKEN_SERVICE, ticket);
+    }
+}

+ 545 - 0
jnpf-boot-common/jnpf-common-auth/src/main/java/jnpf/util/UserProvider.java

@@ -0,0 +1,545 @@
+package jnpf.util;
+
+import cn.dev33.satoken.same.SaSameUtil;
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.session.TokenSign;
+import cn.dev33.satoken.stp.SaLoginModel;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.text.StrPool;
+import jnpf.base.UserInfo;
+import jnpf.consts.DeviceType;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static jnpf.consts.AuthConsts.TOKEN_PREFIX_SP;
+
+
+/**
+ * @author JNPF开发平台组
+ * @version V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date 2021/3/16 10:57
+ */
+@Slf4j
+@Component
+public class UserProvider {
+
+    private static RedisUtil redisUtil;
+    private static CacheKeyUtil cacheKeyUtil;
+
+    public static final String USER_INFO_KEY = "userInfo";
+
+    private static final ThreadLocal<UserInfo> USER_CACHE = new ThreadLocal<>();
+
+    public UserProvider(RedisUtil redisUtil, CacheKeyUtil cacheKeyUtil) {
+        UserProvider.redisUtil = redisUtil;
+        UserProvider.cacheKeyUtil = cacheKeyUtil;
+    }
+
+
+
+    // =================== 登录相关操作 ===================
+
+    /**
+     * 登录系统 适用于Request环境
+     *
+     * @param userInfo 登录用户信息
+     */
+    public static void login(UserInfo userInfo) {
+        setLocalLoginUser(userInfo);
+        StpUtil.login(splicingLoginId(userInfo.getUserId()));
+        userInfo.setToken(StpUtil.getTokenValueNotCut());
+        setLoginUser(userInfo);
+    }
+
+    /**
+     * 登录系统 适用于Request环境
+     *
+     * @param userInfo   用户信息
+     * @param loginModel 登录参数
+     */
+    public static void login(UserInfo userInfo, SaLoginModel loginModel) {
+        setLocalLoginUser(userInfo);
+        StpUtil.login(splicingLoginId(userInfo.getUserId()), loginModel);
+        userInfo.setToken(StpUtil.getTokenValueNotCut());
+        setLoginUser(userInfo);
+    }
+
+    /**
+     * 适用于非Request环境
+     * @param userInfo
+     * @param loginModel
+     */
+    public static void loginNoRequest(UserInfo userInfo, SaLoginModel loginModel) {
+        setLocalLoginUser(userInfo);
+        String token = StpUtil.createLoginSession(splicingLoginId(userInfo.getUserId()), loginModel);
+        userInfo.setToken(TOKEN_PREFIX_SP + token);
+        setLoginUser(userInfo);
+    }
+
+
+    // =================== 登录用户ID相关操作 ===================
+
+    /**
+     * 获取指定TOKEN用户ID
+     *
+     * @param token
+     * @return
+     */
+    public static String getLoginUserId(String token) {
+        String loginId = (String) StpUtil.getLoginIdByToken(token);
+        return parseLoginId(loginId);
+    }
+
+    /**
+     * 获取当前用户ID, 包含临时切换用户ID
+     *
+     * @return
+     */
+    public static String getLoginUserId() {
+        String loginId = getUser().getUserId();
+        return parseLoginId(loginId);
+    }
+
+
+
+    // =================== 用户ID拼接相关操作 ===================
+
+
+    /**
+     * 拼接租户下的用户ID
+     *
+     * @param userId
+     * @return
+     */
+    public static String splicingLoginId(String userId) {
+        return splicingLoginId(userId, null);
+    }
+
+    /**
+     * 拼接租户下的用户ID
+     * @param userId
+     * @param tenantId
+     * @return
+     */
+    private static String splicingLoginId(String userId, String tenantId) {
+        if(StringUtil.isEmpty(tenantId)){
+            tenantId = TenantHolder.getDatasourceId();
+        }
+        if (!StringUtil.isEmpty(tenantId)) {
+            return tenantId + StrPool.COLON + userId;
+        }
+        return userId;
+    }
+
+    /**
+     * 解析租户下的登录ID
+     * @param loginId
+     * @return
+     */
+    private static String parseLoginId(String loginId) {
+        if (loginId != null && loginId.contains(StrPool.COLON)) {
+            loginId = loginId.substring(loginId.indexOf(StrPool.COLON) + 1);
+        }
+        return loginId;
+    }
+
+    /**
+     * Token是否有效
+     *
+     * @param token
+     * @return
+     */
+    public static Boolean isValidToken(String token) {
+        UserInfo userInfo = getUser(token);
+        return userInfo.getUserId() != null;
+    }
+
+
+    // =================== UserInfo缓存相关操作 ===================
+
+
+    /**
+     * 设置Redis用户数据
+     */
+    public static void setLoginUser(UserInfo userInfo) {
+        StpUtil.getTokenSessionByToken(cutToken(userInfo.getToken())).set(USER_INFO_KEY, userInfo);
+    }
+
+    /**
+     * 设置本地用户数据
+     */
+    public static void setLocalLoginUser(UserInfo userInfo) {
+        USER_CACHE.set(userInfo);
+    }
+
+    /**
+     * 获取本地用户数据
+     */
+    public static UserInfo getLocalLoginUser() {
+        return USER_CACHE.get();
+    }
+
+    /**
+     * 清空本地用户数据
+     */
+    public static void clearLocalUser() {
+        USER_CACHE.remove();
+    }
+
+
+
+
+    /**
+     * 获取用户缓存
+     * 保留旧方法
+     *
+     * @param token
+     * @return
+     */
+    public UserInfo get(String token) {
+        return UserProvider.getUser(token);
+    }
+
+    /**
+     * 获取用户缓存
+     *
+     * @return
+     */
+    public UserInfo get() {
+        return UserProvider.getUser();
+    }
+
+
+    /**
+     * 根据用户ID, 租户ID获取随机获取一个UserInfo
+     * @param userId
+     * @param tenantId
+     * @return
+     */
+    public static UserInfo getUser(String userId, String tenantId){
+        return getUser(userId, tenantId, null, null);
+    }
+
+    /**
+     * 根据用户ID, 租户ID, 设备类型获取随机获取一个UserInfo
+     * @param userId
+     * @param tenantId
+     * @param includeDevice 指定的设备类型中查找
+     * @param excludeDevice 排除指定设备类型
+     * @return
+     */
+    public static UserInfo getUser(String userId, String tenantId, List<String> includeDevice, List<String> excludeDevice){
+        SaSession session = StpUtil.getSessionByLoginId(splicingLoginId(userId, tenantId), false);
+        if (session != null) {
+            List<TokenSign> tokenSignList = session.tokenSignListCopy();
+            if (!tokenSignList.isEmpty()) {
+                tokenSignList = tokenSignList.stream().filter(tokenSign -> {
+                    if(!ObjectUtils.isEmpty(excludeDevice)){
+                        if(excludeDevice.contains(tokenSign.getDevice())){
+                            return false;
+                        }
+                    }
+                    if(!ObjectUtils.isEmpty(includeDevice)){
+                        if(!includeDevice.contains(tokenSign.getDevice())){
+                            return false;
+                        }
+                    }
+                    return true;
+                }).collect(Collectors.toList());
+                if(!tokenSignList.isEmpty()){
+                    return getUser(tokenSignList.get(0).getValue());
+                }
+            }
+        }
+        return new UserInfo();
+    }
+
+    /**
+     * 获取用户缓存
+     *
+     * @param token
+     * @return
+     */
+    public static UserInfo getUser(String token) {
+        UserInfo userInfo = null;
+        String tokens = null;
+        if (token != null) {
+            tokens = cutToken(token);
+        } else {
+            try {
+                //处理非Web环境报错
+                tokens = StpUtil.getTokenValue();
+            } catch (Exception e) {
+            }
+        }
+        if (tokens != null) {
+            if (StpUtil.getLoginIdByToken(tokens) != null) {
+                userInfo = (UserInfo) StpUtil.getTokenSessionByToken(tokens).get(USER_INFO_KEY);
+            }
+        }
+        if (userInfo == null) {
+            userInfo = new UserInfo();
+        }
+        return userInfo;
+    }
+
+    /**
+     * 获取用户缓存
+     *
+     * @return
+     */
+    public static UserInfo getUser() {
+//        if(StpUtil.getTokenValue() == null){
+//            return  new UserInfo();
+//        }
+        UserInfo userInfo = USER_CACHE.get();
+        if (userInfo != null) {
+            return userInfo;
+        }
+        userInfo = UserProvider.getUser(null);
+        if (userInfo.getUserId() != null) {
+            USER_CACHE.set(userInfo);
+        }
+        return userInfo;
+    }
+
+    // =================== Token相关操作 ===================
+
+    /**
+     * 去除Token前缀
+     *
+     * @param token
+     * @return
+     */
+    public static String cutToken(String token) {
+        if (token != null && token.startsWith(TOKEN_PREFIX_SP)) {
+            token = token.substring(TOKEN_PREFIX_SP.length());
+        }
+        return token;
+    }
+
+    /**
+     * 获取token
+     */
+    public static String getToken() {
+        String toke = getAuthorize();
+        return toke;
+    }
+
+
+    /**
+     * 获取Authorize
+     */
+    public static String getAuthorize() {
+        String authorize = ServletUtil.getHeader(Constants.AUTHORIZATION);
+        return authorize;
+    }
+
+
+    /**
+     * TOKEN续期
+     */
+    public static void renewTimeout() {
+        if (StpUtil.getTokenValue() != null) {
+            UserInfo userInfo = UserProvider.getUser();
+            if(userInfo.getUserId() == null || userInfo.getTokenTimeout() == null) {
+                //避免请求过网关之后TOKEN失效(携带TOKEN调用登录接口之后账号被顶替)
+                return;
+            }
+            StpUtil.renewTimeout(userInfo.getTokenTimeout() * 60L);
+            SaSession saSession = StpUtil.getSessionByLoginId(splicingLoginId(userInfo.getUserId()), false);
+            if (saSession != null) {
+                saSession.updateTimeout(userInfo.getTokenTimeout() * 60L);
+            }
+        }
+    }
+
+    /**
+     * 获取所有Token记录
+     * 包含无效状态的用户、临时用户
+     *
+     * @return
+     */
+    public static List<String> getLoginUserListToken() {
+        return StpUtil.searchTokenValue("", -1, -1, true).stream().map(token -> token.replace(StpUtil.stpLogic.splicingKeyTokenValue(""), "")).collect(Collectors.toList());
+    }
+
+
+    // =================== 临时Token相关操作 ===================
+
+
+    /**
+     * 获取内部服务传递验证TOKEN
+     *
+     * @return
+     */
+    public static String getInnerAuthToken() {
+        return SaSameUtil.getToken();
+    }
+
+    /**
+     * 验证内部传递Token是否有效 抛出异常
+     * @param token
+     */
+    public static void checkInnerToken(String token){
+        SaSameUtil.checkToken(token);
+    }
+
+    /**
+     * 验证内部传递Token是否有效
+     * @param token
+     */
+    public static boolean isValidInnerToken(String token){
+        return SaSameUtil.isValid(token);
+    }
+
+
+    // =================== 退出相关操作 ===================
+
+
+    /**
+     * 根据用户ID踢出全部用户
+     * @param userId
+     */
+    public static void kickoutByUserId(String userId, String tenantId) {
+        StpUtil.kickout(splicingLoginId(userId, tenantId));
+    }
+
+    /**
+     * 根据Token踢出指定会话
+     * @param tokens
+     */
+    public static void kickoutByToken(String... tokens) {
+        for (String token : tokens) {
+            StpUtil.kickoutByTokenValue(token);
+        }
+    }
+
+    /**
+     * 退出当前Token, 不清除用户其他系统缓存
+     */
+    public static void logout() {
+        StpUtil.logout();
+
+    }
+
+    /**
+     * 退出指定Token, 不清除用户其他系统缓存
+     *
+     * @param token
+     */
+    public static void logoutByToken(String token) {
+        if (token == null) {
+            logout();
+        } else {
+            StpUtil.logoutByTokenValue(cutToken(token));
+        }
+    }
+
+    /**
+     * 退出指定设备类型的用户的全部登录信息, 不清除用户其他系统缓存
+     *
+     * @param userId
+     * @param deviceType
+     */
+    public static void logoutByUserId(String userId, DeviceType deviceType) {
+        StpUtil.logout(splicingLoginId(userId), deviceType.getDevice());
+    }
+
+    /**
+     * 退出指定用户的全部登录信息, 清除相关缓存
+     *
+     * @param userId
+     */
+    public static void logoutByUserId(String userId) {
+        StpUtil.logout(splicingLoginId(userId));
+        removeOtherCache(userId);
+
+    }
+
+    // =================== 用户权限 ===================
+
+    /**
+     * 获取当前用户拥有的权限列表(菜单编码列表、功能ID列表)
+     * @return
+     */
+    public static List<String> getPermissionList(){
+        return StpUtil.getPermissionList();
+    }
+
+    /**
+     * 获取当前用户拥有的角色列表
+     * @return
+     */
+    public static List<String> getRoleList(){
+        return StpUtil.getRoleList();
+    }
+
+
+
+
+
+    // =================== 其他缓存相关操作 ===================
+
+    /**
+     * 移除
+     */
+    public static void removeOtherCache(String userId) {
+        redisUtil.remove(cacheKeyUtil.getUserAuthorize() + userId);
+        redisUtil.remove(cacheKeyUtil.getSystemInfo());
+    }
+
+    /**
+     * 是否在线
+     */
+    public boolean isOnLine(String userId) {
+        return StpUtil.getTokenValueByLoginId(splicingLoginId(userId), getDeviceForAgent().getDevice()) != null;
+    }
+
+
+    /**
+     * 是否登陆
+     */
+    public static boolean isLogined() {
+        return StpUtil.isLogin();
+    }
+
+    /**
+     * 指定Token是否有效
+     * @param token
+     * @return
+     */
+    public static boolean isValid(String token) {
+        return StpUtil.getLoginIdByToken(token) != null;
+    }
+
+
+    public static DeviceType getDeviceForAgent() {
+        if (ServletUtil.getIsMobileDevice()) {
+            return DeviceType.APP;
+        } else {
+            return DeviceType.PC;
+        }
+    }
+
+    /**
+     * 判断用户是否是临时用户
+     * @param userInfo
+     * @return
+     */
+    public static boolean isTempUser(UserInfo userInfo){
+        if(userInfo == null){
+            userInfo = getUser();
+        }
+        return DeviceType.TEMPUSER.getDevice().equals(userInfo.getLoginDevice())
+                || DeviceType.TEMPUSERLIMITED.getDevice().equals(userInfo.getLoginDevice());
+    }
+
+
+
+}

+ 222 - 0
jnpf-boot-common/jnpf-common-auth/target/classes/META-INF/spring-configuration-metadata.json

@@ -0,0 +1,222 @@
+{
+  "groups": [
+    {
+      "name": "oauth",
+      "type": "jnpf.config.JnpfOauthConfig",
+      "sourceType": "jnpf.config.AuthAutoConfigration",
+      "sourceMethod": "getJnpfOauthConfig()"
+    },
+    {
+      "name": "oauth.login",
+      "type": "cn.dev33.satoken.config.SaTokenConfig",
+      "sourceType": "jnpf.config.AuthAutoConfigration",
+      "sourceMethod": "getJnpfTokenConfig()"
+    }
+  ],
+  "properties": [
+    {
+      "name": "oauth.default-s-s-o",
+      "type": "java.lang.String",
+      "description": "默认发起的登录协议",
+      "sourceType": "jnpf.config.JnpfOauthConfig",
+      "defaultValue": "cas"
+    },
+    {
+      "name": "oauth.login-path",
+      "type": "java.lang.String",
+      "description": "后端登录完整路径路径",
+      "sourceType": "jnpf.config.JnpfOauthConfig"
+    },
+    {
+      "name": "oauth.login.active-timeout",
+      "type": "java.lang.Long",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.auto-renew",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.basic",
+      "type": "java.lang.String",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.check-same-token",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.cookie",
+      "type": "cn.dev33.satoken.config.SaCookieConfig",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.curr-domain",
+      "type": "java.lang.String",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.data-refresh-period",
+      "type": "java.lang.Integer",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.dynamic-active-timeout",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.is-color-log",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.is-concurrent",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.is-log",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.is-print",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.is-read-body",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.is-read-cookie",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.is-read-header",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.is-share",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.is-write-header",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.jwt-secret-key",
+      "type": "java.lang.String",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.log-level",
+      "type": "java.lang.String",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.log-level-int",
+      "type": "java.lang.Integer",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.max-login-count",
+      "type": "java.lang.Integer",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.max-try-times",
+      "type": "java.lang.Integer",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.same-token-timeout",
+      "type": "java.lang.Long",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.sign",
+      "type": "cn.dev33.satoken.config.SaSignConfig",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.timeout",
+      "type": "java.lang.Long",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.token-name",
+      "type": "java.lang.String",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.token-prefix",
+      "type": "java.lang.String",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.token-session-check-login",
+      "type": "java.lang.Boolean",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.login.token-style",
+      "type": "java.lang.String",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig"
+    },
+    {
+      "name": "oauth.sso-enabled",
+      "type": "java.lang.Boolean",
+      "description": "开启单点登录, 需额外代码支持",
+      "sourceType": "jnpf.config.JnpfOauthConfig",
+      "defaultValue": false
+    },
+    {
+      "name": "oauth.ticket-timeout",
+      "type": "java.lang.Long",
+      "description": "轮询Ticket有效期, 秒",
+      "sourceType": "jnpf.config.JnpfOauthConfig",
+      "defaultValue": 60
+    },
+    {
+      "name": "oauth.jnpf-app-domain",
+      "type": "java.lang.String",
+      "description": "app端服务器域名 @see ConfigValueUtil#getAppDomain()",
+      "sourceType": "jnpf.config.JnpfOauthConfig",
+      "deprecated": true,
+      "deprecation": {}
+    },
+    {
+      "name": "oauth.jnpf-domain",
+      "type": "java.lang.String",
+      "description": "服务器域名 @see ConfigValueUtil#getApiDomain()",
+      "sourceType": "jnpf.config.JnpfOauthConfig",
+      "deprecated": true,
+      "deprecation": {}
+    },
+    {
+      "name": "oauth.jnpf-front-domain",
+      "type": "java.lang.String",
+      "description": "pc端服务器域名 @see ConfigValueUtil#getFrontDomain()",
+      "sourceType": "jnpf.config.JnpfOauthConfig",
+      "deprecated": true,
+      "deprecation": {}
+    },
+    {
+      "name": "oauth.login.activity-timeout",
+      "type": "java.lang.Long",
+      "sourceType": "cn.dev33.satoken.config.SaTokenConfig",
+      "deprecated": true,
+      "deprecation": {}
+    }
+  ],
+  "hints": []
+}

BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/config/AsyncConfig.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/config/AuthAutoConfigration.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/config/JnpfOauthConfig.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/config/JnpfTokenConfig.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/consts/AuthConsts.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/consts/DeviceType.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/consts/LoginTicketStatus.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/consts/ScanCodeTicketStatus.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/granter/AbstractTokenGranter.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/granter/TokenGranter.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/granter/TokenGranterBuilder.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/granter/UserDetailsServiceBuilder.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/model/LoginTicketModel.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/model/ScanCodeLoginConfigModel.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/service/LoginService.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/service/UserDetailService.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/util/TenantProvider.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/util/TicketUtil.class


BIN
jnpf-boot-common/jnpf-common-auth/target/classes/jnpf/util/UserProvider.class


BIN
jnpf-boot-common/jnpf-common-auth/target/jnpf-common-auth-5.2.0-RELEASE.jar


+ 3 - 0
jnpf-boot-common/jnpf-common-auth/target/maven-archiver/pom.properties

@@ -0,0 +1,3 @@
+artifactId=jnpf-common-auth
+groupId=com.jnpf
+version=5.2.0-RELEASE

+ 20 - 0
jnpf-boot-common/jnpf-common-auth/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst

@@ -0,0 +1,20 @@
+jnpf\util\TenantProvider.class
+jnpf\util\UserProvider.class
+jnpf\granter\AbstractTokenGranter.class
+jnpf\service\UserDetailService.class
+jnpf\service\LoginService.class
+jnpf\util\TicketUtil.class
+jnpf\config\JnpfTokenConfig.class
+jnpf\model\LoginTicketModel.class
+jnpf\model\ScanCodeLoginConfigModel.class
+jnpf\consts\DeviceType.class
+META-INF\spring-configuration-metadata.json
+jnpf\config\AsyncConfig.class
+jnpf\consts\AuthConsts.class
+jnpf\granter\UserDetailsServiceBuilder.class
+jnpf\consts\ScanCodeTicketStatus.class
+jnpf\consts\LoginTicketStatus.class
+jnpf\config\AuthAutoConfigration.class
+jnpf\config\JnpfOauthConfig.class
+jnpf\granter\TokenGranter.class
+jnpf\granter\TokenGranterBuilder.class

+ 19 - 0
jnpf-boot-common/jnpf-common-auth/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst

@@ -0,0 +1,19 @@
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\config\AsyncConfig.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\config\AuthAutoConfigration.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\config\JnpfOauthConfig.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\config\JnpfTokenConfig.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\consts\AuthConsts.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\consts\DeviceType.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\consts\LoginTicketStatus.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\consts\ScanCodeTicketStatus.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\granter\AbstractTokenGranter.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\granter\TokenGranter.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\granter\TokenGranterBuilder.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\granter\UserDetailsServiceBuilder.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\model\LoginTicketModel.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\model\ScanCodeLoginConfigModel.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\service\LoginService.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\service\UserDetailService.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\util\TenantProvider.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\util\TicketUtil.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-auth\src\main\java\jnpf\util\UserProvider.java

+ 23 - 0
jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/pom.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>jnpf-boot-common</artifactId>
+        <groupId>com.jnpf</groupId>
+        <version>5.2.0-RELEASE</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>jnpf-common-office-v3</artifactId>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>com.jnpf</groupId>
+            <artifactId>jnpf-common-office</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 84 - 0
jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/src/main/java/cn/afterturn/easypoi/util/PoiValidationUtil.java

@@ -0,0 +1,84 @@
+/**
+ * Copyright 2013-2015 JueYue (qrb.jueyue@gmail.com)
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package cn.afterturn.easypoi.util;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.Validation;
+import jakarta.validation.Validator;
+import jakarta.validation.ValidatorFactory;
+
+/**
+ * 导入可选校验 ImportParams.needVerify
+ * HIBERNATE 校验工具类
+ * @author JueYue
+ *  2015年11月11日 下午10:04:07
+ */
+public class PoiValidationUtil {
+
+    private final static Validator VALIDATOR;
+
+    static {
+        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
+        VALIDATOR = factory.getValidator();
+    }
+
+    public static String validation(Object obj, Class[] verfiyGroup) {
+        Set<ConstraintViolation<Object>> set = null;
+        if(verfiyGroup != null){
+            set = VALIDATOR.validate(obj,verfiyGroup);
+        }else{
+            set = VALIDATOR.validate(obj);
+        }
+        if (set!= null && set.size() > 0) {
+            return getValidateErrMsg(set);
+        }
+        return null;
+    }
+
+    private static String getValidateErrMsg(Set<ConstraintViolation<Object>> set) {
+        StringBuilder builder = new StringBuilder();
+        for (ConstraintViolation<Object> constraintViolation : set) {
+            Class cls = constraintViolation.getRootBean().getClass();
+            String fieldName = constraintViolation.getPropertyPath().toString();
+            List<Field> fields = new ArrayList<>(Arrays.asList(cls.getDeclaredFields()));
+            Class superClass = cls.getSuperclass();
+            if (superClass != null) {
+                fields.addAll(Arrays.asList(superClass.getDeclaredFields()));
+            }
+            String name = null;
+            for (Field field: fields) {
+                if (field.getName().equals(fieldName) && field.isAnnotationPresent(Excel.class)) {
+                    name = field.getAnnotation(Excel.class).name();
+                    break;
+                }
+            }
+            if (name == null) {
+                name = fieldName;
+            }
+            builder.append(name).append(constraintViolation.getMessage()).append(",");
+        }
+        return builder.substring(0, builder.length() - 1);
+    }
+
+}

BIN
jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/target/classes/cn/afterturn/easypoi/util/PoiValidationUtil.class


BIN
jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/target/jnpf-common-office-v3-5.2.0-RELEASE.jar


+ 3 - 0
jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/target/maven-archiver/pom.properties

@@ -0,0 +1,3 @@
+artifactId=jnpf-common-office-v3
+groupId=com.jnpf
+version=5.2.0-RELEASE

+ 1 - 0
jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst

@@ -0,0 +1 @@
+cn\afterturn\easypoi\util\PoiValidationUtil.class

+ 1 - 0
jnpf-boot-common/jnpf-common-compatible/jnpf-common-office-v3/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst

@@ -0,0 +1 @@
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-compatible\jnpf-common-office-v3\src\main\java\cn\afterturn\easypoi\util\PoiValidationUtil.java

+ 16 - 0
jnpf-boot-common/jnpf-common-connector/pom.xml

@@ -0,0 +1,16 @@
+<?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>jnpf-boot-common</artifactId>
+        <groupId>com.jnpf</groupId>
+        <version>5.2.0-RELEASE</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jnpf-common-connector</artifactId>
+
+
+</project>

+ 24 - 0
jnpf-boot-common/jnpf-common-connector/src/main/java/jnpf/permission/connector/HttpRequestUserInfoService.java

@@ -0,0 +1,24 @@
+package jnpf.permission.connector;
+
+import java.util.Map;
+
+/**
+ * 用户推送
+ *
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2022/8/3 13:50
+ */
+public interface HttpRequestUserInfoService {
+
+    /**
+     * 同步数据到本地数据库
+     *
+     * @param userEntity
+     * @param method
+     * @param tenantId
+     */
+    void syncUserInfo(Map<String, Object> userEntity, String method, String tenantId);
+
+}

+ 43 - 0
jnpf-boot-common/jnpf-common-connector/src/main/java/jnpf/permission/connector/UserInfoService.java

@@ -0,0 +1,43 @@
+package jnpf.permission.connector;
+
+import java.util.Map;
+
+/**
+ * 拉取用户
+ *
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2022/7/28 14:27
+ */
+public interface UserInfoService {
+
+    /**
+     * 添加
+     *
+     * @param map
+     */
+    Boolean create(Map<String, Object> map);
+
+    /**
+     * 修改
+     *
+     * @param map
+     */
+    Boolean update(Map<String, Object> map);
+
+    /**
+     * 删除
+     *
+     * @param map
+     */
+    Boolean delete(Map<String, Object> map);
+
+    /**
+     * 获取信息
+     *
+     * @param id
+     */
+    Map<String, Object> getInfo(String id);
+
+}

BIN
jnpf-boot-common/jnpf-common-connector/target/classes/jnpf/permission/connector/HttpRequestUserInfoService.class


BIN
jnpf-boot-common/jnpf-common-connector/target/classes/jnpf/permission/connector/UserInfoService.class


BIN
jnpf-boot-common/jnpf-common-connector/target/jnpf-common-connector-5.2.0-RELEASE.jar


+ 3 - 0
jnpf-boot-common/jnpf-common-connector/target/maven-archiver/pom.properties

@@ -0,0 +1,3 @@
+artifactId=jnpf-common-connector
+groupId=com.jnpf
+version=5.2.0-RELEASE

+ 2 - 0
jnpf-boot-common/jnpf-common-connector/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst

@@ -0,0 +1,2 @@
+jnpf\permission\connector\HttpRequestUserInfoService.class
+jnpf\permission\connector\UserInfoService.class

+ 2 - 0
jnpf-boot-common/jnpf-common-connector/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst

@@ -0,0 +1,2 @@
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-connector\src\main\java\jnpf\permission\connector\HttpRequestUserInfoService.java
+C:\Users\zhaojinyu\Desktop\USKY\jnpf5.2\jnpf-common\jnpf-boot-common\jnpf-common-connector\src\main\java\jnpf\permission\connector\UserInfoService.java

+ 287 - 0
jnpf-boot-common/jnpf-common-core/pom.xml

@@ -0,0 +1,287 @@
+<?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>jnpf-boot-common</artifactId>
+        <groupId>com.jnpf</groupId>
+        <version>5.2.0-RELEASE</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jnpf-common-core</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>cn.afterturn</groupId>
+            <artifactId>easypoi-annotation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-annotation</artifactId>
+        </dependency>
+        <!--<dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>-->
+
+        <dependency>
+            <groupId>com.nimbusds</groupId>
+            <artifactId>nimbus-jose-jwt</artifactId>
+        </dependency>
+
+        <!-- Alibaba Fastjson -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+
+        <!-- lang3 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+
+
+        <!-- excel工具 -->
+
+        <!-- Quartz -->
+        <dependency>
+            <groupId>org.quartz-scheduler</groupId>
+            <artifactId>quartz</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>HikariCP-java7</artifactId>
+                    <groupId>com.zaxxer</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <!--二维码-->
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>core</artifactId>
+        </dependency>
+
+        <!-- 拼音 -->
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+        </dependency>
+
+        <!-- Jackson -->
+        <!--<dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>-->
+
+        <!-- 公共资源池 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+        </dependency>
+
+        <!-- 字段验证 -->
+        <!--<dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+        </dependency>-->
+        <dependency>
+            <groupId>org.hibernate.validator</groupId>
+            <artifactId>hibernate-validator</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+
+        <!--<dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+        </dependency>-->
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.owasp.antisamy</groupId>
+            <artifactId>antisamy</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>commons-io</artifactId>
+                    <groupId>commons-io</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!-- commons-text -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-text</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>net.lingala.zip4j</groupId>
+            <artifactId>zip4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.yitter</groupId>
+            <artifactId>yitter-idgenerator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-core</artifactId>
+            <version>${mybatis-plus.vesion}</version>
+        </dependency>
+        <!-- 淘汰配置兼容 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-properties-migrator</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>javax.servlet</groupId>-->
+<!--            <artifactId>javax.servlet-api</artifactId>-->
+<!--            <optional>true</optional>-->
+<!--            <scope>provided</scope>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>jakarta.servlet</groupId>-->
+<!--            <artifactId>jakarta.servlet-api</artifactId>-->
+<!--            <optional>true</optional>-->
+<!--            <scope>provided</scope>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>jakarta.annotation</groupId>-->
+<!--            <artifactId>jakarta.annotation-api</artifactId>-->
+<!--            <version>2.1.1</version>-->
+<!--            <optional>true</optional>-->
+<!--            <scope>provided</scope>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>javax.annotation</groupId>-->
+<!--            <artifactId>javax.annotation-api</artifactId>-->
+<!--            <version>1.3.2</version>-->
+<!--            <optional>true</optional>-->
+<!--            <scope>provided</scope>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>jakarta.validation</groupId>-->
+<!--            <artifactId>jakarta.validation-api</artifactId>-->
+<!--            <version>3.0.2</version>-->
+<!--            <optional>true</optional>-->
+<!--            <scope>provided</scope>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>javax.validation</groupId>-->
+<!--            <artifactId>validation-api</artifactId>-->
+<!--            <version>2.0.1.Final</version>-->
+<!--            <optional>true</optional>-->
+<!--            <scope>provided</scope>-->
+<!--        </dependency>-->
+        <!--集成logstash-->
+        <dependency>
+            <groupId>net.logstash.logback</groupId>
+            <artifactId>logstash-logback-encoder</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>jackson-databind</artifactId>
+                    <groupId>com.fasterxml.jackson.core</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!-- Skywalking 日志上报 -->
+        <dependency>
+            <groupId>org.apache.skywalking</groupId>
+            <artifactId>apm-toolkit-logback-1.x</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>boot3</id>
+            <activation>
+                <jdk>[17,)</jdk>
+            </activation>
+            <dependencies>
+                <!-- Java Servlet -->
+                <dependency>
+                    <groupId>jakarta.servlet</groupId>
+                    <artifactId>jakarta.servlet-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>io.swagger.core.v3</groupId>
+                    <artifactId>swagger-annotations-jakarta</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>jakarta.annotation</groupId>
+                    <artifactId>jakarta.annotation-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.openjdk.nashorn</groupId>
+                    <artifactId>nashorn-core</artifactId>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>boot2</id>
+            <activation>
+                <jdk>(,17)</jdk>
+            </activation>
+            <dependencies>
+                <!-- Java Servlet -->
+                <dependency>
+                    <groupId>javax.servlet</groupId>
+                    <artifactId>javax.servlet-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>io.swagger.core.v3</groupId>
+                    <artifactId>swagger-annotations</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>javax.annotation</groupId>
+                    <artifactId>javax.annotation-api</artifactId>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
+
+</project>

+ 27 - 0
jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/EncryptApi.java

@@ -0,0 +1,27 @@
+package jnpf.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 接口传输加密
+ * 加密请求和返回结果: @EncryptApi
+ * 只加密请求: @EncryptApi(encryptRequest = false)
+ * 只加密返回结果: @EncryptApi(encryptResponse = false)
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD,ElementType.PARAMETER})
+public @interface EncryptApi {
+
+    /**
+     * 加密请求内容
+     */
+    boolean encryptRequest() default true;
+
+    /**
+     * 加密返回结果
+     */
+    boolean encryptResponse() default true;
+}

+ 32 - 0
jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/HandleLog.java

@@ -0,0 +1,32 @@
+package jnpf.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 请求日志注解
+ *
+ * @author :JNPF开发平台组
+ * @version: V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date :2022/3/15 11:19
+ */
+@Documented
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HandleLog {
+
+    /**
+     * 操作模块
+     *
+     * @return
+     */
+    String moduleName() default "";
+
+    /**
+     * 操作方式
+     *
+     * @return
+     */
+    String requestMethod() default "";
+
+}

+ 119 - 0
jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/JnpfField.java

@@ -0,0 +1,119 @@
+package jnpf.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 控件属性
+ *
+ * @author JNPF开发平台组
+ * @version V3.4.3
+ * @copyright 引迈信息技术有限公司(https://www.jnpfsoft.com)
+ * @date  2022/9/19
+ */
+@Documented
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface JnpfField {
+
+	String vModel() default "";
+
+	String label() default "";
+
+	/**
+	 * 是否多选
+	 */
+	boolean multiple() default false;
+
+	String jnpfKey() default "";
+
+	/**
+	 * 显示层级
+	 */
+	String showLevel() default "";
+
+	/**
+	 * 省市区显示层级
+	 */
+	String level() default "0";
+
+	/**
+	 * 单据规则
+	 */
+	String rule() default "";
+
+	String activeTxt() default "开";
+
+	String inactiveTxt() default "关";
+
+	int min() default -1;
+
+	int max() default -1;
+
+	/**
+	 *
+	 * 是否唯一
+	 */
+	boolean unique() default false;
+
+
+	boolean isUpdate() default false;
+
+	/**
+	 * 单行输入正则
+	 */
+	String regex() default "";
+
+
+	/**
+	 * 表名
+	 */
+	String relationTable() default "";
+	
+	String tableName() default "";
+
+	/**
+	 * 时间
+	 */
+	String format() default "";
+
+	/**
+	 * 数据接口
+	 */
+	String dataType() default "";
+
+	String dataLabel() default "fullName";
+
+	String dataValue() default "id";
+
+	String dataChildren() default "children";
+
+	String propsUrl() default "";
+
+	String dictionaryType() default "";
+
+	String options() default "";
+
+	String ableDepIds() default "[]";
+
+	String ablePosIds() default "[]";
+
+	String ableUserIds() default "[]";
+
+	String ableRoleIds() default "[]";
+
+	String ableGroupIds() default "[]";
+
+	String ableIds() default "[]";
+
+	String selectType() default "";
+
+	/**
+	 * 开始时间
+	 */
+	String startTime() default "";
+
+	/**
+	 * 结束时间
+	 */
+	String endTime() default "";
+}

+ 18 - 0
jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/OrganizeAdminIsTrator.java

@@ -0,0 +1,18 @@
+package jnpf.annotation;
+
+
+import java.lang.annotation.*;
+
+/**
+ *
+ * @author JNPF开发平台组
+ * @version V3.1.0
+ * @copyright 引迈信息技术有限公司
+ * @date 2021/3/16 8:53
+ */
+@Documented
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OrganizeAdminIsTrator {
+    String value() default "";
+}

+ 17 - 0
jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/OrganizePermission.java

@@ -0,0 +1,17 @@
+package jnpf.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 组织权限验证
+ *
+ * @author JNPF开发平台组
+ * @version V3.1.0
+ * @copyright 引迈信息技术有限公司(https://www.jnpfsoft.com)
+ * @date 2021-10-30
+ */
+@Documented
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OrganizePermission {
+}

+ 17 - 0
jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/PositionPermission.java

@@ -0,0 +1,17 @@
+package jnpf.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 组织权限验证
+ *
+ * @author JNPF开发平台组
+ * @version V3.1.0
+ * @copyright 引迈信息技术有限公司(https://www.jnpfsoft.com)
+ * @date 2021-10-30
+ */
+@Documented
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PositionPermission {
+}

+ 18 - 0
jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/RolePermission.java

@@ -0,0 +1,18 @@
+package jnpf.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 角色权限验证
+ *
+ * @author JNPF开发平台组
+ * @version V3.1.0
+ * @copyright 引迈信息技术有限公司(https://www.jnpfsoft.com)
+ * @date 2021-10-30
+ */
+@Documented
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RolePermission {
+
+}

+ 23 - 0
jnpf-boot-common/jnpf-common-core/src/main/java/jnpf/annotation/SaCheckSame.java

@@ -0,0 +1,23 @@
+package jnpf.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 内部请求校验:校验是否来自内部请求
+ *
+ * <p> 可标注在方法、类上(效果等同于标注在此类的所有方法上)
+ *
+ * @author JNPF开发平台组
+ * @version V5.1.0
+ * @copyright 引迈信息技术有限公司(https://www.jnpfsoft.com)
+ * @date 2024-12-31
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD, ElementType.TYPE })
+public @interface SaCheckSame {
+
+
+}

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