andy 1 vuosi sitten
vanhempi
commit
dfb13ed3f6
32 muutettua tiedostoa jossa 1298 lisäystä ja 560 poistoa
  1. 81 0
      mainFactory/.gitignore
  2. 44 0
      mainFactory/docs/asciiDoc/修改用户密码.adoc
  3. 31 0
      mainFactory/docs/markdown/template.md
  4. 35 0
      mainFactory/docs/markdown/修改用户密码接口.md
  5. 34 0
      mainFactory/docs/markdown/刷新应用令牌接口.md
  6. 32 0
      mainFactory/docs/markdown/强制登录接口.md
  7. 32 0
      mainFactory/docs/markdown/用户健康度检查接口.md
  8. 39 0
      mainFactory/docs/markdown/登出注销接口.md
  9. 30 0
      mainFactory/docs/markdown/登录接口.md
  10. 32 0
      mainFactory/docs/markdown/获取应用令牌.md
  11. 70 0
      mainFactory/docs/markdown/获取应用令牌服务.md
  12. 33 0
      mainFactory/docs/markdown/获取用户权限接口.md
  13. 31 0
      mainFactory/docs/markdown/获取验证码接口.md
  14. 261 0
      mainFactory/docs/概要/用户和权限.md
  15. 7 4
      mainFactory/src/main/java/org/bfkj/api/SecurityApi.java
  16. 13 11
      mainFactory/src/main/java/org/bfkj/apos/LogAop.java
  17. 16 9
      mainFactory/src/main/java/org/bfkj/application/AuthApplicationImpl.java
  18. 23 5
      mainFactory/src/main/java/org/bfkj/domain/Application.java
  19. 11 0
      mainFactory/src/main/java/org/bfkj/domain/Userinfo.java
  20. 5 5
      mainFactory/src/main/java/org/bfkj/domain/Userloginlog.java
  21. 7 0
      mainFactory/src/main/java/org/bfkj/dtos/CodeResultCache.java
  22. 18 0
      mainFactory/src/main/java/org/bfkj/envs/HttpEnv.java
  23. 11 9
      mainFactory/src/main/java/org/bfkj/services/ApplicationService.java
  24. 30 5
      mainFactory/src/main/java/org/bfkj/services/ApplicationconnectlogService.java
  25. 280 341
      mainFactory/src/main/java/org/bfkj/services/SecurityService.java
  26. 3 2
      mainFactory/src/main/java/org/bfkj/services/UserinfoService.java
  27. 12 30
      mainFactory/src/main/java/org/bfkj/services/UserloginlogService.java
  28. 34 13
      mainFactory/src/main/java/org/bfkj/services/cache/CodeCacheService.java
  29. 1 6
      mainFactory/src/main/java/org/bfkj/utils/CommonUtil.java
  30. 8 98
      mainFactory/src/main/java/org/bfkj/utils/HttpRequestUtil.java
  31. 19 22
      mainFactory/src/main/java/org/bfkj/utils/RandomGraphic.java
  32. 15 0
      mainFactory/src/test/java/org/bfkj/utils/RandomGraphicTest.java

+ 81 - 0
mainFactory/.gitignore

@@ -0,0 +1,81 @@
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# AWS User-specific
+.idea/**/aws.xml
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn.  Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# SonarLint plugin
+.idea/sonarlint/
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+/.idea/
+/docs/

+ 44 - 0
mainFactory/docs/asciiDoc/修改用户密码.adoc

@@ -0,0 +1,44 @@
+= MD5加密方法
+
+== 功能概述
+该方法用于对源字符串进行MD5加密。
+
+== 方法定义
+[source, java]
+----
+public static String toMD5(String source) throws NoSuchAlgorithmException
+----
+
+== 参数说明
+|===
+|参数名称 | 参数类型 | 参数说明
+|source | String | 要进行MD5加密的源字符串
+|===
+
+|===
+|
+|===
+
+== 返回值
+|===
+|返回值类型 | 返回值说明
+|String | 经过MD5加密后的结果字符串
+|===
+
+== 异常
+|===
+|异常类型 | 异常说明
+|NoSuchAlgorithmException | 当无法获取MD5算法时,可能会抛出此异常
+|===
+
+== 实现逻辑
+1. 创建一个 `MessageDigest` 对象 `md`,并使用 `MessageDigest.getInstance("MD5")` 获取使用MD5算法的实例。
+2. 将源字符串 `source` 转换为字节数组,并使用 `md.update(source.getBytes())` 将源字符串更新到 `md` 对象中。
+3. 对 `md` 对象进行摘要操作,并将结果保存在字节数组 `digest` 中,使用 `md.digest()` 方法。
+4. 创建一个 `StringBuilder` 对象 `sb` 用于拼接摘要结果的十六进制字符串。
+5. 遍历摘要结果的字节数组 `digest`,对每个字节进行位运算,并将结果转换为十六进制字符串 `hex`。
+6. 如果 `hex` 的长度为1,将字符 '0' 添加到 `sb` 中。
+7. 将 `hex` 添加到 `sb` 中。
+8. 返回 `sb.toString()`,即经过MD5加密后的结果字符串。
+
+以上是MD5加密方法的设计文档。根据该文档,可以使用该方法对源字符串进行MD5加密。如有需要,可以根据实际情况进行修改和补充。

+ 31 - 0
mainFactory/docs/markdown/template.md

@@ -0,0 +1,31 @@
+##  [服务名称]
+
+### 1. 功能概述
+[功能概述]
+
+### 2. 类和方法定义
+
+#### 2.1 类定义
+- [类1]:[类1的功能描述]
+- [类2]:[类2的功能描述]
+  ...
+
+#### 2.2 方法定义
+[方法签名]
+
+
+#### 2.3 参数说明
+- [参数1]: [参数1的说明]
+- [参数2]: [参数2的说明]
+...
+
+#### 2.4 返回值
+- [返回值]: [返回值的说明]
+
+#### 2.5 异常
+- [异常1]: [异常1的说明]
+- [异常2]: [异常2的说明]
+...
+
+### 3. 实现逻辑
+[具体的实现逻辑,包括步骤、调用的方法和逻辑判断]

+ 35 - 0
mainFactory/docs/markdown/修改用户密码接口.md

@@ -0,0 +1,35 @@
+## 修改用户密码
+### 1. 功能概述
+该方法用于更改用户密码。
+
+### 2. 类和方法定义
+#### 2.1 类定义
+所属类:当前类所在的类(根据您提供的代码,类未提供)
+方法名:changePwd
+
+#### 2.2 方法定义
+public ResponseEntity changePwd(Map<String, Object> headers, Map<String, Object> body, HttpServletRequest httpRequest) throws JsonProcessingException
+
+
+#### 2.3 参数说明
+- `headers`:类型为`Map<String, Object>`,存储请求头信息的参数。
+- `body`:类型为`Map<String, Object>`,存储请求体信息的参数。
+- `httpRequest`:类型为HttpServletRequest,用于获取HTTP请求信息的参数。
+
+#### 2.4 返回值
+返回一个ResponseEntity对象。
+
+#### 2.5 异常
+- `JsonProcessingException`:当对象序列化为JSON字符串时抛出此异常。
+
+#### 2.6 请求路径
+- POST请求路径:user/changePassword
+- 或者POST请求路径:foxlibc/reset-passwd
+
+### 3. 实现逻辑
+
+1. 调用`combineData`方法将`headers`、`body`和`httpRequest`合并为一个`Map<String, Object>`对象,并将结果存储在`requestData`变量中。
+
+2. 调用`securityService.changePassword`方法传入`requestData`执行密码更改操作,得到返回结果`result`。
+
+3. 返回一个包含`result.getReturnData()`的ResponseEntity对象。

+ 34 - 0
mainFactory/docs/markdown/刷新应用令牌接口.md

@@ -0,0 +1,34 @@
+## 刷新应用令牌
+### 1. 功能概述
+该方法用于测试令牌(token)的验证,并返回验证结果。
+
+### 2. 类和方法定义
+#### 2.1 类定义
+所属类:当前类所在的类(根据您提供的代码,类未提供)
+方法名:testToken
+
+#### 2.2 方法定义
+public ResponseEntity testToken(@RequestHeader Map<String, Object> headers, @RequestBody Map<String, Object> body, HttpServletRequest httpRequest) throws JsonProcessingException
+
+#### 2.3 参数说明
+- `headers`:类型为`Map<String, Object>`,存储请求头信息的参数。
+- `body`:类型为`Map<String, Object>`,存储请求体信息的参数。
+- `httpRequest`:类型为HttpServletRequest,用于获取HTTP请求信息的参数。
+
+#### 2.4 返回值
+返回一个ResponseEntity对象。
+
+#### 2.5 异常
+- `JsonProcessingException`:当对象序列化为JSON字符串时抛出此异常。
+
+### 3. 实现逻辑
+
+1. 调用`combineData`方法将`headers`、`body`和`httpRequest`合并为一个`Map<String, Object>`对象,并将结果存储在`requestData`变量中。
+
+2. 调用`securityService.verifyToken`方法传入`requestData`进行令牌验证,得到返回结果`result`。
+
+3. 从`result`的返回数据中获取`R<Map<String, Object>>`对象`returnData`。
+
+4. 从`returnData`的返回数据中移除键为"appplication"的数据。
+
+5. 返回一个包含`returnData`的ResponseEntity对象。

+ 32 - 0
mainFactory/docs/markdown/强制登录接口.md

@@ -0,0 +1,32 @@
+## 强制登录
+### 1. 功能概述
+该方法用于强制用户登录,并返回登录结果。
+
+### 2. 类和方法定义
+#### 2.1 类定义
+所属类:当前类所在的类(根据您提供的代码,类未提供)
+方法名:forceLogin
+
+#### 2.2 方法定义
+
+public ResponseEntity forceLogin(Map<String, Object> headers, Map<String, Object> body, HttpServletRequest httpRequest) throws JsonProcessingException, NoSuchAlgorithmException 
+
+#### 2.3 参数说明
+- `headers`:类型为`Map<String, Object>`,存储请求头信息的参数。
+- `body`:类型为`Map<String, Object>`,存储请求体信息的参数。
+- `httpRequest`:类型为HttpServletRequest,用于获取HTTP请求信息的参数。
+
+#### 2.4 返回值
+返回一个ResponseEntity对象。
+
+#### 2.5 异常
+- `JsonProcessingException`:当对象序列化为JSON字符串时抛出此异常。
+- `NoSuchAlgorithmException`:当使用未知的加密算法时抛出此异常。
+
+### 3. 实现逻辑
+
+1. 调用`combineData`方法将`headers`、`body`和`httpRequest`合并为一个`Map<String, Object>`对象,并将结果存储在`requestData`变量中。
+
+2. 调用`securityService.forceLogin`方法传入`requestData`进行强制登录操作,得到返回结果`result`。
+
+3. 返回一个包含`result.getReturnData()`的ResponseEntity对象。

+ 32 - 0
mainFactory/docs/markdown/用户健康度检查接口.md

@@ -0,0 +1,32 @@
+## 用户健康检查
+### 1. 功能概述
+该方法用于检查用户健康状态。
+
+### 2. 类和方法定义
+#### 2.1 类定义
+所属类:当前类所在的类(根据您提供的代码,类未提供)
+方法名:health
+
+#### 2.2 方法定义
+
+public ResponseEntity health(Map<String, Object> headers, Map<String, Object> body, HttpServletRequest httpRequest)
+
+
+#### 2.3 参数说明
+- `headers`:类型为`Map<String, Object>`,存储请求头信息的参数。
+- `body`:类型为`Map<String, Object>`,存储请求体信息的参数。
+- `httpRequest`:类型为HttpServletRequest,用于获取HTTP请求信息的参数。
+
+#### 2.4 返回值
+返回一个ResponseEntity对象。
+
+#### 2.5 请求路径
+- POST请求路径:该方法的请求路径未提供
+
+### 3. 实现逻辑
+1. 调用`combineData`方法将`headers`、`body`和`httpRequest`合并为一个`Map<String, Object>`对象,并将结果存储在`requestData`变量中。
+
+2. 调用`securityService.userHeartbeat`方法传入`requestData`执行系统健康检查操作,得到返回结果`result`。
+
+3. 返回一个包含`result.getReturnData()`的ResponseEntity对象。
+

+ 39 - 0
mainFactory/docs/markdown/登出注销接口.md

@@ -0,0 +1,39 @@
+## 登出注销
+
+### 1. 功能概述
+该方法用于用户注销登录。
+
+### 2. 类和方法定义
+#### 2.1 类定义
+所属类:当前类所在的类(根据您提供的代码,类未提供)
+方法名:logOut
+
+#### 2.2 方法定义
+
+public ResponseEntity logOut(Map<String, Object> headers, Map<String, Object> body, HttpServletRequest httpRequest) throws JsonProcessingException
+
+
+#### 2.3 参数说明
+- `headers`:类型为`Map<String, Object>`,存储请求头信息的参数。
+- `body`:类型为`Map<String, Object>`,存储请求体信息的参数。
+- `httpRequest`:类型为HttpServletRequest,用于获取HTTP请求信息的参数。
+
+#### 2.4 返回值
+返回一个ResponseEntity对象。
+
+#### 2.5 异常
+- `JsonProcessingException`:当对象序列化为JSON字符串时抛出此异常。
+
+#### 2.6 请求路径
+- POST请求路径:user/logOut
+- 或者POST请求路径:foxlibc/sign-out
+
+### 3. 实现逻辑
+
+1. 调用`combineData`方法将`headers`、`body`和`httpRequest`合并为一个`Map<String, Object>`对象,并将结果存储在`requestData`变量中。
+
+2. 调用`securityService.logOut`方法传入`requestData`执行用户注销操作,得到返回结果`result`。
+
+3. 返回一个包含`result.getReturnData()`的ResponseEntity对象。
+
+以上是根据您提供的代码给出的方法定义、参数说明和实现逻辑概述。如果您对具体步骤还有疑问或需要进一步的解释,请随时提问。

+ 30 - 0
mainFactory/docs/markdown/登录接口.md

@@ -0,0 +1,30 @@
+## 登录
+### 1. 功能概述
+该方法用于用户登录,并返回登录结果。
+
+### 2. 类和方法定义
+#### 2.1 类定义
+所属类:当前类所在的类(根据您提供的代码,类未提供)
+方法名:login
+
+#### 2.2 方法定义
+public ResponseEntity login(Map<String, Object> headers, Map<String, Object> body, HttpServletRequest httpRequest) throws JsonProcessingException
+
+#### 2.3 参数说明
+- `headers`:类型为`Map<String, Object>`,存储请求头信息的参数。
+- `body`:类型为`Map<String, Object>`,存储请求体信息的参数。
+- `httpRequest`:类型为HttpServletRequest,用于获取HTTP请求信息的参数。
+
+#### 2.4 返回值
+返回一个ResponseEntity对象。
+
+#### 2.5 异常
+- `JsonProcessingException`:当对象序列化为JSON字符串时抛出此异常。
+
+### 3. 实现逻辑
+
+1. 调用`combineData`方法将`headers`、`body`和`httpRequest`合并为一个`Map<String, Object>`对象,并将结果存储在`requestData`变量中。
+
+2. 调用`securityService.login`方法传入`requestData`进行登录操作,得到返回结果`result`。
+
+3. 返回一个包含`result.getReturnData()`的ResponseEntity对象。

+ 32 - 0
mainFactory/docs/markdown/获取应用令牌.md

@@ -0,0 +1,32 @@
+## 获取应用令牌
+### 1. 功能概述
+该方法用于获取令牌(token)。
+
+### 2. 类和方法定义
+#### 2.1 类定义
+
+#### 2.2 方法定义
+public ResponseEntity<R<Map<String, Object>>> getToken(Map<String, Object> headers, Map<String, Object> body, HttpServletRequest httpRequest) throws JsonProcessingException, NoSuchAlgorithmException
+
+#### 2.3 参数说明
+- `headers`:类型为`Map<String, Object>`,存储请求头信息的参数。
+- `body`:类型为`Map<String, Object>`,存储请求体信息的参数。
+- `httpRequest`:类型为HttpServletRequest,用于获取HTTP请求信息的参数。
+
+#### 2.4 返回值
+返回一个ResponseEntity对象,其泛型为`R<Map<String, Object>>`。
+
+#### 2.5 异常
+- `JsonProcessingException`:当对象序列化为JSON字符串时抛出此异常。
+- `NoSuchAlgorithmException`:当尝试使用不存在的加密算法时抛出此异常。
+
+#### 2.6 请求路径
+- POST请求路径:该方法的请求路径未提供
+
+### 3. 实现逻辑
+
+1. 调用`combineData`方法将`headers`、`body`和`httpRequest`合并为一个`Map<String, Object>`对象,并将结果存储在`requestData`变量中。
+
+2. 调用`securityService.getToken`方法传入`requestData`执行获取令牌操作,得到返回结果`result`。
+
+3. 返回一个包含`result.getReturnData()`的ResponseEntity对象。

+ 70 - 0
mainFactory/docs/markdown/获取应用令牌服务.md

@@ -0,0 +1,70 @@
+## 获取应用令牌服务
+
+### 1. 功能概述
+
+该方法用于获取应用令牌。根据传入的请求数据,验证 `appid` 和 `appSecret`,生成令牌,并返回相应的结果。
+
+### 2. 类和方法定义
+
+#### 2.1 类定义
+
+- `ServiceDto`:封装了方法执行的结果和相关日志的类。
+- `LogEntity`:表示日志实体的类。
+- `Applog`:表示应用日志实体类
+
+#### 2.2 方法定义
+
+public ServiceDto<Map<String, Object>,LogEntity>getToken(Map<String, Object> requestData)throws
+JsonProcessingException,NoSuchAlgorithmException
+
+#### 2.3 参数说明
+
+- `requestData` (Map<String, Object>): 包含请求数据的map对象
+
+#### 2.4 返回值
+
+- `ServiceDto<Map<String, Object>, LogEntity>`: 一个泛型为 `<Map<String, Object>, LogEntity>` 的 `ServiceDto`
+  对象,包含结果数据以及日志信息。
+
+#### 2.5 异常
+
+- `JsonProcessingException`: 在处理JSON数据时可能抛出的异常。
+- `NoSuchAlgorithmException`: 在加密时可能抛出的异常。
+
+### 3. 实现逻辑
+
+1. 从 `requestData` 中获取 `appid`、`appSecret`、`requestIp` 和 `sessionId` 参数。
+
+2. 创建一个 `ServiceDto<Map<String, Object>, LogEntity>` 对象 `serviceDto`。
+
+3. 调用 `applicationconnectlogService` 的 `removeExpiresData()` 方法,用于删除过期的数据。
+
+4. 调用 `applicationService` 的 `findByAppIdAndAppSecret` 方法,通过 `appid` 和 `appSecret` 查找对应的 `Application` 对象。
+
+5. 如果找到了有效的 `application`:
+    1. 调用 `applicationconnectlogService` 的 `findByAppidAndRequestIp` 方法,通过 `appid` 和 `requestIp`
+       查找对应的 `Appconnectlog` 对象。
+    2. 获取当前时间 `now`。
+    3. 如果未找到 `applicationconnectlog`,则创建一个新的 `Appconnectlog` 对象:
+        1. 生成令牌 `md5Token`,通过 `CommonUtil.toMD5` 方法将当前时间 `now` 和 `sessionId` 拼接后进行 MD5 加密。
+        2. 设置 `Apptoken`、`appid` 和 `requestip`。
+    4. 获取 `apptokeneffective` 值,即令牌的有效期时长(单位为分钟)。
+    5. 计算过期时间 `expiresTime`,为当前时间 `now` 加上有效期时长 `apptokeneffective`。
+    6. 更新 `applicationconnectlog` 的过期时间 `expiretime`、请求时间 `requesttime` 和最后时间 `lasttime`。
+    7. 调用 `applicationconnectlogService` 的 `saveOrUpdate` 方法保存或更新 `applicationconnectlog` 对象。
+    8. 创建一个 `data` 的 `HashMap` 对象,用于存储返回的数据:
+    9. 将 `applicationconnectlog`
+       的 `apptoken`、`expiretime`、`appname`、`appengname`、`applogo`、`appsmalllogo`、`background`
+       和 `appcoderule` 放入 `data` 中。
+    10. 将 `data` 设置为 `serviceDto` 的返回数据,并设置成功标志为 `true`。
+6. 如果未找到有效的 `application`:
+    1. 设置 `serviceDto` 的成功标志为 `false`,并设置错误信息为 "appid或者appsecret错误"。
+7. 创建一个 `Applog` 对象 `logData`,并设置相应的属性值:
+    1. 设置 `appid` 为 `appid`。
+    2. 设置 `apiname` 为 `application` 的 `appname`,如果 `application` 为空,则设置为 `null`。
+    3. 设置 `requestip` 为 `requestIp`。
+    4. 设置 `sessionid` 为 `sessionId`。
+    5. 设置 `inputdata` 为将 `requestData` 转换为 JSON 字符串。
+    6. 设置 `outputdata` 为将 `serviceDto` 的返回数据转换为 JSON 字符串。
+8. 设置 `serviceDto` 的日志数据为 `logData`。
+9. 返回 `serviceDto`。

+ 33 - 0
mainFactory/docs/markdown/获取用户权限接口.md

@@ -0,0 +1,33 @@
+## 获取用户权限
+### 1. 功能概述
+该方法用于获取用户权限,并返回权限列表。
+
+### 2. 类和方法定义
+#### 2.1 类定义
+所属类:当前类所在的类(根据您提供的代码,类未提供)
+方法名:getPermissions
+
+#### 2.2 方法定义
+
+public ResponseEntity getPermissions(Map<String, Object> headers, Map<String, Object> body, HttpServletRequest httpRequest) throws JsonProcessingException
+
+
+#### 2.3 参数说明
+- `headers`:类型为`Map<String, Object>`,存储请求头信息的参数。
+- `body`:类型为`Map<String, Object>`,存储请求体信息的参数。
+- `httpRequest`:类型为HttpServletRequest,用于获取HTTP请求信息的参数。
+
+#### 2.4 返回值
+返回一个ResponseEntity对象。
+
+#### 2.5 异常
+- `JsonProcessingException`:当对象序列化为JSON字符串时抛出此异常。
+
+### 3. 实现逻辑
+
+1. 调用`combineData`方法将`headers`、`body`和`httpRequest`合并为一个`Map<String, Object>`对象,并将结果存储在`requestData`变量中。
+
+2. 调用`securityService.permission`方法传入`requestData`进行权限获取操作,得到返回结果`result`。
+
+3. 返回一个包含`result.getReturnData()`的ResponseEntity对象。
+

+ 31 - 0
mainFactory/docs/markdown/获取验证码接口.md

@@ -0,0 +1,31 @@
+## 获取应用验证码
+
+### 1. 功能概述
+该方法用于获取验证码,并返回验证码的生成图片的base64结果。
+
+### 2. 类和方法定义
+#### 2.1 类定义
+所属类:当前类所在的类(根据您提供的代码,类未提供)
+方法名:getCode
+
+#### 2.2 方法定义
+public ResponseEntity getCode(@RequestHeader Map<String, Object> headers, @RequestBody Map<String, Object> body, HttpServletRequest httpRequest) throws JsonProcessingException
+
+#### 2.3 参数说明
+- `headers`:类型为`Map<String, Object>`,存储请求头信息的参数。
+- `body`:类型为`Map<String, Object>`,存储请求体信息的参数。
+- `httpRequest`:类型为HttpServletRequest,用于获取HTTP请求信息的参数。
+
+#### 2.4 返回值
+返回一个ResponseEntity对象。
+
+#### 2.5 异常
+- `JsonProcessingException`:当对象序列化为JSON字符串时抛出此异常。
+
+### 3. 实现逻辑
+
+1. 调用`combineData`方法将`headers`、`body`和`httpRequest`合并为一个`Map<String, Object>`对象,并将结果存储在`requestData`变量中。
+
+2. 调用`securityService.verifyCode`方法传入`requestData`进行验证码验证,得到返回结果`result`。
+
+3. 返回一个包含`result.getReturnData()`的ResponseEntity对象。

+ 261 - 0
mainFactory/docs/概要/用户和权限.md

@@ -0,0 +1,261 @@
+#### 用户新增
+
+|     用户新增     |                   |                                |        |    |     |             |                  |
+|:------------:|:-----------------:|:------------------------------:|:------:|:--:|:---:|:-----------:|:----------------:|
+|     接口地址     |                   | https://******/openApi/newdata |
+| Content-Type |                   |        application/json        |
+|     请求方式     |                   |              POST              |
+|     请求参数     |
+|      序号      |        参数         |               名称               |   类型   | 非空 | 长度  |     位置      |        备注        |
+|      1       |     usertoken     |              用户令牌              |  字符串   | Y  | 32  |   Header    |       用户令牌       |
+|      2       |     serviceid     |              服务编号              |   整数   | Y  |  -  |    Body     |      固定101       |
+|      3       |    dataContent    |              请求数据              | JSON对象 | Y  |  -  |    Body     |      表的请求内容      |
+|      4       |    usergroupid    |             用户组编号              |   整数   |    |  -  | dataContent |      用户组ID       |
+|      5       |     username      |              用户名               |  字符串   | Y  | 50  | dataContent |       用户名        |
+|      6       |      account      |              用户账号              |  字符串   | Y  | 50  | dataContent |       用户账号       |
+|      7       |   userdescribe    |              用户描述              |  字符串   |    | 200 | dataContent |        描述        |
+|      8       |     isenable      |              是否启用              |   整数   | Y  |  -  | dataContent | 是否启用,1表示启用,0表示禁用 |
+|      9       | secondarypassword |             用户二级密码             |  字符串   | Y  | 50  | dataContent |       二级密码       |
+|     返回参数     |
+|      1       |       code        |               编码               |   整数   | Y  |  -  |             |   返回的编码 0,表示成功   |
+|      2       |      message      |               消息               |  字符串   | N  |  -  |             |     返回的错误消息      |
+|      3       |    returnData     |             返回的数据              |  对象数组  | N  |  -  |             |    返回的具体数据内容     |
+
+#### 用户修改
+
+|     用户修改     |              |                                   |        |    |     |             |              |
+|:------------:|:------------:|:---------------------------------:|:------:|:--:|:---:|:-----------:|:------------:|
+|     接口地址     |              | https://******/openApi/modifydata |
+| Content-Type |              |         application/json          |
+|     请求方式     |              |               POST                |
+|     请求参数     |
+|      序号      |      参数      |                名称                 |   类型   | 非空 | 长度  |     位置      |      备注      |
+|      1       |  usertoken   |               用户令牌                |  字符串   | Y  | 32  |   Header    |     用户令牌     |
+|      2       |  serviceid   |               服务编号                |   整数   | Y  |  -  |    Body     |    固定102     |
+|      3       | dataContent  |              表的请求内容               | JSON对象 | Y  |  -  |    Body     |    表的请求内容    |
+|      3       |    userid    |               用户编号                |   整数   | N  |  -  | dataContent |     用户编号     |
+|      4       | usergroupid  |               用户组ID               |   整数   | Y  |  -  | dataContent |    用户组ID     |
+|      5       |   username   |                用户名                |  字符串   | Y  | 50  | dataContent |     用户名      |
+|      6       |   account    |                账号                 |  字符串   | Y  | 50  | dataContent |      账号      |
+|      7       | userdescribe |                描述                 |  字符串   | Y  | 200 | dataContent |      描述      |
+|      8       |   isenable   |               是否启用                |   布尔   | Y  |  -  | dataContent |     是否启用     |
+|     返回参数     |
+|      1       |     code     |                编码                 |   整数   | Y  |  -  |             | 返回的编码 0,表示成功 |
+|      2       |   message    |                消息                 |  字符串   | N  |  -  |             |   返回的错误消息    |
+|      3       |  returnData  |               返回的数据               |  对象数组  | N  |  -  |             |  返回的具体数据内容   |
+
+#### 用户删除
+
+|     用户删除     |             |                                 |        |    |    |             |              |
+|:------------:|:-----------:|:-------------------------------:|:------:|:--:|:--:|:-----------:|:------------:|
+|     接口地址     |             | https://******/openApi/movedata |
+| Content-Type |             |        application/json         |
+|     请求方式     |             |              POST               |
+|     请求参数     |
+|      序号      |     参数      |               名称                |   类型   | 非空 | 长度 |     位置      |      备注      |
+|      1       |  usertoken  |              用户令牌               |  字符串   | Y  | 32 |   Header    |     用户令牌     |
+|      2       |  serviceid  |              服务编号               |   整数   | Y  | -  |    Body     |    固定103     |
+|      3       | dataContent |             表的请求内容              | JSON对象 | Y  | -  |    Body     |    表的请求内容    |
+|      3       |   userid    |              用户编号               |   整数   | Y  | -  | dataContent |     用户编号     |
+|     返回参数     |
+|      1       |    code     |               编码                |   整数   | Y  | -  |             | 返回的编码 0,表示成功 |
+|      2       |   message   |               消息                |  字符串   | N  | -  |             |   返回的错误消息    |
+|      3       | returnData  |              返回的数据              |  对象数组  | N  | -  |             |  返回的具体数据内容   |
+
+#### 用户查询
+
+|     用户查询     |              |                              |        |    |     |             |              |
+|:------------:|:------------:|:----------------------------:|:------:|:--:|:---:|:-----------:|:------------:|
+|     接口地址     |              | https://******/openApi/query |
+| Content-Type |              |       application/json       |
+|     请求方式     |              |             POST             |
+|     请求参数     |
+|      序号      |      参数      |              名称              |   类型   | 非空 | 长度  |     位置      |      备注      |
+|      1       |  usertoken   |             用户令牌             |  字符串   | Y  | 32  |   Header    |     用户令牌     |
+|      2       |  serviceid   |             服务编号             |   整数   | Y  |  -  |    Body     |    固定104     |
+|      3       | dataContent  |            表的请求内容            | JSON对象 | Y  |  -  |    Body     |    表的请求内容    |
+|      3       |    userid    |             用户编号             |   整数   | N  |  -  | dataContent |     用户编号     |
+|      3       | usergroupid  |            用户组id             |   整数   | N  |  -  | dataContent |    用户组id     |
+|     返回参数     |
+|      1       |     code     |              编码              |   整数   | Y  |  -  |             | 返回的编码 0,表示成功 |
+|      2       |   message    |              消息              |  字符串   | N  |  -  |             |   返回的错误消息    |
+|      3       |  returnData  |            返回的数据             |  对象数组  | N  |  -  |  返回的具体数据内容  |
+|      3       |    userid    |             用户编号             |   整数   | Y  |  -  | returnData  |     用户编号     |
+|      4       | usergroupid  |            用户组ID             |   整数   | N  |  -  | returnData  |    用户组ID     |
+|      5       |   username   |             用户名              |  字符串   | Y  | 50  | returnData  |     用户名      |
+|      6       |   account    |              账号              |  字符串   | Y  | 50  | returnData  |      账号      |
+|      7       | userdescribe |              描述              |  字符串   | N  | 200 | returnData  |      描述      |
+|      8       |   isenable   |             是否启用             |   布尔   | Y  |  -  | returnData  |     是否启用     |
+
+#### 用户组新增
+
+|    用户组新增     |                   |                                |        |    |     |             |              |
+|:------------:|:-----------------:|:------------------------------:|:------:|:--:|:---:|:-----------:|:------------:|
+|     接口地址     |                   | https://******/openApi/newdata |
+| Content-Type |                   |        application/json        |
+|     请求方式     |                   |              POST              |
+|     请求参数     |
+|      序号      |        参数         |               名称               |   类型   | 非空 | 长度  |     位置      |      备注      |
+|      1       |     usertoken     |              用户令牌              |  字符串   | Y  | 32  |   Header    |     用户令牌     |
+|      2       |     serviceid     |              服务编号              |   整数   | Y  |  -  |    Body     |    固定111     |
+|      3       |    dataContent    |             表的请求内容             | JSON对象 | Y  |  -  |    Body     |    表的请求内容    |
+|      5       |    superiorid     |            上级用户组编号             |  字符串   | Y  | 50  | dataContent |   上级用户组编号    |
+|      6       |   usergroupname   |             用户组名称              |  字符串   | Y  | 50  | dataContent |    用户组名称     |
+|      7       | usergroupdescribe |             用户组描述              |  字符串   | Y  | 200 | dataContent |    用户组描述     |
+|     返回参数     |
+|      1       |       code        |               编码               |   整数   | Y  |  -  |             | 返回的编码 0,表示成功 |
+|      2       |      message      |               消息               |  字符串   | N  |  -  |             |   返回的错误消息    |
+|      3       |    returnData     |             返回的数据              |  对象数组  | N  |  -  |             |  返回的具体数据内容   |
+
+#### 用户组修改
+
+|    用户组修改     |                   |                                   |        |    |     |             |              |
+|:------------:|:-----------------:|:---------------------------------:|:------:|:--:|:---:|:-----------:|:------------:|
+|     接口地址     |                   | https://******/openApi/modifydata |
+| Content-Type |                   |         application/json          |
+|     请求方式     |                   |               POST                |
+|     请求参数     |
+|      序号      |        参数         |                名称                 |   类型   | 非空 | 长度  |     位置      |      备注      |
+|      1       |     usertoken     |               用户令牌                |  字符串   | Y  | 32  |   Header    |     用户令牌     |
+|      2       |     serviceid     |               服务编号                |   整数   | Y  |  -  |    Body     |    固定112     |
+|      3       |    dataContent    |              表的请求内容               | JSON对象 | Y  |  -  |    Body     |    表的请求内容    |
+|      4       |    usergroupid    |               用户组编号               |   整数   | Y  |  -  | dataContent |    用户组编号     |
+|      5       |    superiorid     |              上级用户组编号              |  字符串   | Y  | 50  | dataContent |   上级用户组编号    |
+|      6       |   usergroupname   |               用户组名称               |  字符串   | Y  | 50  | dataContent |    用户组名称     |
+|      7       | usergroupdescribe |               用户组描述               |  字符串   | Y  | 200 | dataContent |    用户组描述     |
+|     返回参数     |
+|      1       |       code        |                编码                 |   整数   | Y  |  -  |             | 返回的编码 0,表示成功 |
+|      2       |      message      |                消息                 |  字符串   | N  |  -  |             |   返回的错误消息    |
+|      3       |    returnData     |               返回的数据               |  对象数组  | N  |  -  |             |  返回的具体数据内容   |
+
+#### 用户组删除
+
+|    用户组删除     |             |                                 |        |    |    |             |              |
+|:------------:|:-----------:|:-------------------------------:|:------:|:--:|:--:|:-----------:|:------------:|
+|     接口地址     |             | https://******/openApi/movedata |
+| Content-Type |             |        application/json         |
+|     请求方式     |             |              POST               |
+|     请求参数     |
+|      序号      |     参数      |               名称                |   类型   | 非空 | 长度 |     位置      |      备注      |
+|      1       |  usertoken  |              用户令牌               |  字符串   | Y  | 32 |   Header    |     用户令牌     |
+|      2       |  serviceid  |              服务编号               |   整数   | Y  | -  |    Body     |    固定113     |
+|      3       | dataContent |             表的请求内容              | JSON对象 | Y  | -  |    Body     |    表的请求内容    |
+|      3       | usergroupid |              用户组编号              |   整数   | Y  | -  | dataContent |    用户组编号     |
+|     返回参数     |
+|      1       |    code     |               编码                |   整数   | Y  | -  |             | 返回的编码 0,表示成功 |
+|      2       |   message   |               消息                |  字符串   | N  | -  |             |   返回的错误消息    |
+|      3       | returnData  |              返回的数据              |  对象数组  | N  | -  |             |  返回的具体数据内容   |
+
+#### 用户组查询
+
+|    用户组查询     |                   |                              |        |    |     |             |              |
+|:------------:|:-----------------:|:----------------------------:|:------:|:--:|:---:|:-----------:|:------------:|
+|     接口地址     |                   | https://******/openApi/query |
+| Content-Type |                   |       application/json       |
+|     请求方式     |                   |             POST             |
+|     请求参数     |
+|      序号      |        参数         |              名称              |   类型   | 非空 | 长度  |     位置      |      备注      |
+|      1       |     usertoken     |             用户令牌             |  字符串   | Y  | 32  |   Header    |     用户令牌     |
+|      2       |     serviceid     |             服务编号             |   整数   | Y  |  -  |    Body     |    固定114     |
+|      3       |    dataContent    |            表的请求内容            | JSON对象 | Y  |  -  |    Body     |    表的请求内容    |
+|      3       |    usergroupid    |            用户组id             |   整数   | N  |  -  | dataContent |    用户组id     |
+|     返回参数     |
+|      1       |       code        |              编码              |   整数   | Y  |  -  |             | 返回的编码 0,表示成功 |
+|      2       |      message      |              消息              |  字符串   | N  |  -  |             |   返回的错误消息    |
+|      3       |    returnData     |            返回的数据             |  对象数组  | N  |  -  |             |  返回的具体数据内容   |
+|      4       |    usergroupid    |            用户组编号             |   整数   | Y  |  -  | returnData  |    用户组编号     |
+|      5       |    superiorid     |           上级用户组编号            |   整数   | Y  |  -  | returnData  |   上级用户组编号    |
+|      6       |   usergroupname   |            用户组名称             |  字符串   | Y  | 50  | returnData  |    用户组名称     |
+|      7       | usergroupdescribe |            用户组描述             |  字符串   | Y  | 200 | returnData  |    用户组描述     |
+
+#### 用户权限新增
+
+|    用户权限新增    |                     |                                |        |    |     |             |              |
+|:------------:|:-------------------:|:------------------------------:|:------:|:--:|:---:|:-----------:|:------------:|
+|     接口地址     |                     | https://******/openApi/newdata |
+| Content-Type |                     |        application/json        |
+|     请求方式     |                     |              POST              |
+|     请求参数     |
+|      序号      |         参数          |               名称               |   类型   | 非空 | 长度  |     位置      |      备注      |
+|      1       |      usertoken      |              用户令牌              |  字符串   | Y  | 32  |   Header    |     用户令牌     |
+|      2       |      serviceid      |             固定102              |   整数   | Y  |  -  |    Body     |    固定102     |
+|      3       |     dataContent     |             表的请求内容             | JSON对象 | Y  |  -  |    Body     |    表的请求内容    |
+|      4       |  userpermissionsid  |             用户权限编号             |   整数   | Y  |  -  | dataContent |    用户权限编号    |
+|      4       |       userid        |             用户组编号              |   整数   | Y  |  -  | dataContent |    用户组编号     |
+|      5       | pageconfigurationid |             页面配置编号             |   整数   | N  |  -  | dataContent |    页面配置编号    |
+|      6       |      serviceid      |              服务编号              |   整数   | N  |  -  | dataContent |     服务编号     |
+|      7       |  insertcolumnlist   |             新增权限列              |  字符串   | N  | 200 | dataContent |    新增权限列     |
+|      7       |  updatecolumnlist   |             更新权限列              |  字符串   | N  | 200 | dataContent |    更新权限列     |
+|      7       |  selectcolumnlist   |             查询权限列              |  字符串   | N  | 200 | dataContent |    查询权限列     |
+|      7       |      filterset      |              行权限               |  字符串   | N  | 200 | dataContent |     行权限      |
+|     返回参数     |
+|      1       |        code         |               编码               |   整数   | Y  |  -  |             | 返回的编码 0,表示成功 |
+|      2       |       message       |               消息               |  字符串   | N  |  -  |             |   返回的错误消息    |
+|      3       |     returnData      |             返回的数据              |  对象数组  | N  |  -  |             |  返回的具体数据内容   |
+
+#### 用户权限修改
+
+|    用户权限修改    |                     |                                   |        |    |     |             |              |
+|:------------:|:-------------------:|:---------------------------------:|:------:|:--:|:---:|:-----------:|:------------:|
+|     接口地址     |                     | https://******/openApi/modifydata |
+| Content-Type |                     |         application/json          |
+|     请求方式     |                     |               POST                |
+|     请求参数     |
+|      序号      |         参数          |                名称                 |   类型   | 非空 | 长度  |     位置      |      备注      |
+|      1       |      usertoken      |               用户令牌                |  字符串   | Y  | 32  |   Header    |     用户令牌     |
+|      2       |      serviceid      |               固定102               |   整数   | Y  |  -  |    Body     |    固定102     |
+|      3       |     dataContent     |              表的请求内容               | JSON对象 | Y  |  -  |    Body     |    表的请求内容    |
+|      4       |       userid        |               用户组编号               |   整数   | Y  |  -  | dataContent |    用户组编号     |
+|      5       | pageconfigurationid |              页面配置编号               |   整数   | N  |  -  | dataContent |    页面配置编号    |
+|      6       |      serviceid      |               服务编号                |   整数   | N  |  -  | dataContent |     服务编号     |
+|      7       |  insertcolumnlist   |               新增权限列               |  字符串   | N  | 200 | dataContent |    新增权限列     |
+|      7       |  updatecolumnlist   |               更新权限列               |  字符串   | N  | 200 | dataContent |    更新权限列     |
+|      7       |  selectcolumnlist   |               查询权限列               |  字符串   | N  | 200 | dataContent |    查询权限列     |
+|      7       |      filterset      |                行权限                |  字符串   | N  | 200 | dataContent |     行权限      |
+|     返回参数     |
+|      1       |        code         |                编码                 |   整数   | Y  |  -  |             | 返回的编码 0,表示成功 |
+|      2       |       message       |                消息                 |  字符串   | N  |  -  |             |   返回的错误消息    |
+|      3       |     returnData      |               返回的数据               |  对象数组  | N  |  -  |             |  返回的具体数据内容   |
+
+#### 用户权限删除
+
+|    用户权限删除    |             |                                 |        |    |    |             |              |
+|:------------:|:-----------:|:-------------------------------:|:------:|:--:|:--:|:-----------:|:------------:|
+|     接口地址     |             | https://******/openApi/movedata |
+| Content-Type |             |        application/json         |
+|     请求方式     |             |              POST               |
+|     请求参数     |
+|      序号      |     参数      |               名称                |   类型   | 非空 | 长度 |     位置      |      备注      |
+|      1       |  usertoken  |              用户令牌               |  字符串   | Y  | 32 |   Header    |     用户令牌     |
+|      2       |  serviceid  |              固定103              |   整数   | Y  | -  |    Body     |    固定103     |
+|      3       | dataContent |             表的请求内容              | JSON对象 | Y  | -  |    Body     |    表的请求内容    |
+|      3       |   userid    |              用户编号               |   整数   | Y  | -  | dataContent |     用户编号     |
+|     返回参数     |
+|      1       |    code     |               编码                |   整数   | Y  | -  |             | 返回的编码 0,表示成功 |
+|      2       |   message   |               消息                |  字符串   | N  | -  |             |   返回的错误消息    |
+|      3       | returnData  |              返回的数据              |  对象数组  | N  | -  |             |  返回的具体数据内容   |
+
+#### 用户权限查询
+
+|    用户权限查询    |                     |                              |        |    |     |             |              |
+|:------------:|:-------------------:|:----------------------------:|:------:|:--:|:---:|:-----------:|:------------:|
+|     接口地址     |                     | https://******/openApi/query |
+| Content-Type |                     |       application/json       |
+|     请求方式     |                     |             POST             |
+|     请求参数     |
+|      序号      |         参数          |              名称              |   类型   | 非空 | 长度  |     位置      |      备注      |
+|      1       |      usertoken      |             用户令牌             |  字符串   | Y  | 32  |   Header    |     用户令牌     |
+|      2       |      serviceid      |            固定104             |   整数   | Y  |  -  |    Body     |    固定104     |
+|      3       |     dataContent     |            表的请求内容            | JSON对象 | Y  |  -  |    Body     |    表的请求内容    |
+|      3       |       userid        |             用户编号             |   整数   | Y  |  -  | dataContent |     用户编号     |
+|     返回参数     |
+|      1       |        code         |              编码              |   整数   | Y  |  -  |             | 返回的编码 0,表示成功 |
+|      2       |       message       |              消息              |  字符串   | N  |  -  |             |   返回的错误消息    |
+|      3       |     returnData      |            返回的数据             |  对象数组  | N  |  -  |             |  返回的具体数据内容   |
+|      4       |       userid        |             用户编号             |   整数   | Y  |  -  | dataContent |    用户组编号     |
+|      5       | pageconfigurationid |            页面配置编号            |   整数   | N  |  -  | dataContent |    页面配置编号    |
+|      6       |      serviceid      |             服务编号             |   整数   | N  |  -  | dataContent |     服务编号     |
+|      7       |  insertcolumnlist   |            新增权限列             |  字符串   | N  | 200 | dataContent |    新增权限列     |
+|      7       |  updatecolumnlist   |            更新权限列             |  字符串   | N  | 200 | dataContent |    更新权限列     |
+|      7       |  selectcolumnlist   |            查询权限列             |  字符串   | N  | 200 | dataContent |    查询权限列     |
+|      7       |      filterset      |             行权限              |  字符串   | N  | 200 | dataContent |   行权限过滤条件    |

+ 7 - 4
mainFactory/src/main/java/org/bfkj/api/SecurityApi.java

@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestHeader;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.security.NoSuchAlgorithmException;
 import java.util.List;
 import java.util.Map;
 
@@ -38,7 +39,7 @@ public class SecurityApi {
      * @return
      */
     @PostMapping("user/getToken")
-    public ResponseEntity<R<Map<String, Object>>> getToken(@RequestHeader Map<String, Object> headers, @RequestBody Map<String, Object> body, HttpServletRequest httpRequest) throws JsonProcessingException {
+    public ResponseEntity<R<Map<String, Object>>> getToken(@RequestHeader Map<String, Object> headers, @RequestBody Map<String, Object> body, HttpServletRequest httpRequest) throws JsonProcessingException, NoSuchAlgorithmException {
         Map<String, Object> requestData = combineData(headers, body, httpRequest);
         ServiceDto<Map<String, Object>, LogEntity> result = securityService.getToken(requestData);
         return ResponseEntity.ok(result.getReturnData());
@@ -69,7 +70,9 @@ public class SecurityApi {
         Map<String, Object> requestData = combineData(headers, body, httpRequest);
 
         ServiceDto<Map<String, Object>, LogEntity> result = securityService.verifyToken(requestData);
-        return ResponseEntity.ok(result.getReturnData());
+        R<Map<String, Object>> returnData = result.getReturnData();
+        returnData.getReturnData().remove("appplication");
+        return ResponseEntity.ok(returnData);
     }
 
     /**
@@ -94,7 +97,7 @@ public class SecurityApi {
      * @return
      */
     @PostMapping({"user/forceLogin", "foxlibc/force_sign"})
-    public ResponseEntity forceLogin(@RequestHeader Map<String, Object> headers, @RequestBody Map<String, Object> body, HttpServletRequest httpRequest) throws JsonProcessingException {
+    public ResponseEntity forceLogin(@RequestHeader Map<String, Object> headers, @RequestBody Map<String, Object> body, HttpServletRequest httpRequest) throws JsonProcessingException, NoSuchAlgorithmException {
         Map<String, Object> requestData = combineData(headers, body, httpRequest);
         ServiceDto<Map<String, Object>, LogEntity> result = securityService.forceLogin(requestData);
         return ResponseEntity.ok(result.getReturnData());
@@ -167,7 +170,7 @@ public class SecurityApi {
     @PostMapping({"user/health", "foxlibc/health"})
     public ResponseEntity health(@RequestHeader Map<String, Object> headers, @RequestBody Map<String, Object> body, HttpServletRequest httpRequest) {
         Map<String, Object> requestData = combineData(headers, body, httpRequest);
-        ServiceDto<List<Permissions>, LogEntity> result = securityService.userHeartbeat(requestData);
+        ServiceDto<Map<String,Object>, LogEntity> result = securityService.userHeartbeat(requestData);
         return ResponseEntity.ok(result.getReturnData());
     }
 }

+ 13 - 11
mainFactory/src/main/java/org/bfkj/apos/LogAop.java

@@ -14,6 +14,7 @@ import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -43,7 +44,7 @@ public class LogAop {
                 List<Applog> temp = applogs;
                 applogs = new ArrayList<>();
                 String sql = "insert into  applog(logtime, appid, apiname, requestip, sessionid, inputdata, outputdata) values(?,?,?,?,?,?,?)";
-                myDbHelper.JDBCBatch(sql, temp.stream().map(it -> ( new Object[]{it.getLogtime(), it.getAppid(), it.getApiname(), it.getRequestip(), it.getSessionid(), it.getInputdata(), it.getOutputdata()})).map(it -> ((Object) Arrays.stream(it).toList())).toList(), null);
+                myDbHelper.JDBCBatch(sql, temp.stream().map(it -> (new Object[]{it.getLogtime(), it.getAppid(), it.getApiname(), it.getRequestip(), it.getSessionid(), it.getInputdata(), it.getOutputdata()})).map(it -> ((Object) Arrays.stream(it).toList())).toList(), null);
             }
             if (!userlogs.isEmpty()) {
                 List<Userlog> temp = userlogs;
@@ -85,18 +86,19 @@ public class LogAop {
         Log annotation = method.getAnnotation(Log.class);
         Log.LogType value = annotation.value();
 
-        switch (value) {
-            case SERVICE -> {
-                if (serviceDto.isSuccess()) {
-                    servicelogs.add((Servicelog) serviceDto.getLogData());
-                } else {
-                    serviceerrlogs.add((Serviceerrlog) serviceDto.getLogData());
+        if (Objects.nonNull(serviceDto.getLogData())) {
+            switch (value) {
+                case SERVICE -> {
+                    if (serviceDto.isSuccess()) {
+                        servicelogs.add((Servicelog) serviceDto.getLogData());
+                    } else {
+                        serviceerrlogs.add((Serviceerrlog) serviceDto.getLogData());
+                    }
                 }
+                case SYSTEM -> systemerrlogs.add((Systemerrlog) serviceDto.getLogData());
+                case USER -> userlogs.add((Userlog) serviceDto.getLogData());
+                case APP -> applogs.add((Applog) serviceDto.getLogData());
             }
-            case SYSTEM -> systemerrlogs.add((Systemerrlog) serviceDto.getLogData());
-            case USER -> userlogs.add((Userlog) serviceDto.getLogData());
-            case APP -> applogs.add((Applog) serviceDto.getLogData());
         }
-
     }
 }

+ 16 - 9
mainFactory/src/main/java/org/bfkj/application/AuthApplicationImpl.java

@@ -4,9 +4,13 @@ package org.bfkj.application;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.bfkj.config.AppConfig;
 import org.bfkj.config.ObjectMap;
-import org.bfkj.utils.*;
+import org.bfkj.utils.LogUtils;
+import org.bfkj.utils.MapTools;
+import org.bfkj.utils.MyDbHelper;
+import org.bfkj.utils.RandomGraphic;
 import org.springframework.stereotype.Service;
 
+import java.io.IOException;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -186,23 +190,26 @@ public class AuthApplicationImpl {
         }
         // 生成验证码
         String appRuleStr = appRule.toString();  //A2N4
-        Map<String, Object> map = RandomGraphic.generateVerifyCode(Integer.parseInt(appRuleStr.substring(appRuleStr.length() - 1)), codeFormat);
-        if (null == map) {
+        RandomGraphic.CodeResult map = null;
+        try {
+            map = RandomGraphic.generateVerifyCode(Integer.parseInt(appRuleStr.substring(appRuleStr.length() - 1)), codeFormat);
+        } catch (IOException e) {
             return processFail("生成验证码失败");
         }
         try {
-            myDbHelper.updateByCondition("update t_application_login set app_code = ?,app_code_expire = DATE_ADD(NOW(),INTERVAL  " + appCodeEffective + " SECOND )  where app_token=?", null, map.get("verifyCode").toString(), app_token);
+            myDbHelper.updateByCondition("update t_application_login set app_code = ?,app_code_expire = DATE_ADD(NOW(),INTERVAL  " + appCodeEffective + " SECOND )  where app_token=?", null, map.verifyCode(), app_token);
             Map<String, Object> listResult = myDbHelper.queryByParamsReturnList("select * from t_application_login where  app_token=?  ", app_token);
             List<Map<String, Object>> applicationInfo = MapTools.getMapList(listResult);
             if (listResult.get("code").equals("-1") || null == applicationInfo) {
                 return processFail("获取验证规则失败");
 
             }
-            return processSuccess(new HashMap<String, Object>() {{
-                put("verifyCode", map.get("verifyCodeImage"));
-                put("app_code_expire", applicationInfo.get(0).get("app_code_expire"));
+            HashMap<String, Object> returnData = new HashMap<>();
 
-            }});
+            returnData.put("verifyCode", map.verifyCodeImage());
+            returnData.put("app_code_expire", applicationInfo.get(0).get("app_code_expire"));
+
+            return processSuccess(returnData);
         } catch (Exception e) {
             return processFail("验证码异常:" + LogUtils.getException(e));
         }
@@ -439,7 +446,7 @@ public class AuthApplicationImpl {
                 inList.add(auth_id);
                 inList.add(insertMap.get("columnName").toString());
                 inList.add(insertMap.get("columnLable").toString());
-                if (Objects.nonNull(tableName)){
+                if (Objects.nonNull(tableName)) {
                     inList.add(insertMap.get("columnDescribe"));
                 }
                 insertParams.add(inList.toArray());

+ 23 - 5
mainFactory/src/main/java/org/bfkj/domain/Application.java

@@ -1,6 +1,7 @@
 package org.bfkj.domain;
 
 import java.io.Serializable;
+import java.time.LocalDateTime;
 
 /**
  * 应用表
@@ -68,6 +69,12 @@ public class Application implements Serializable {
     private Long apptokeneffective;
     /**
      * 验证码规则
+     * C 字母
+     * N 数字
+     * W 特殊字符
+     * U 大写
+     * L 小写
+     * 最后4为 为最小长度(2位)+最大长度(2位)
      */
 
 
@@ -86,7 +93,10 @@ public class Application implements Serializable {
      *
      */
 
-    private Integer securitycoderulelength;
+    private String passwordrule;
+
+    private Integer passwordeffective;
+
 
     public Integer getApplicationid() {
         return applicationid;
@@ -192,11 +202,19 @@ public class Application implements Serializable {
         this.multilogin = multilogin;
     }
 
-    public Integer getSecuritycoderulelength() {
-        return securitycoderulelength;
+    public String getPasswordrule() {
+        return passwordrule;
+    }
+
+    public void setPasswordrule(String passwordrule) {
+        this.passwordrule = passwordrule;
+    }
+
+    public Integer getPasswordeffective() {
+        return passwordeffective;
     }
 
-    public void setSecuritycoderulelength(Integer securitycoderulelength) {
-        this.securitycoderulelength = securitycoderulelength;
+    public void setPasswordeffective(Integer passwordeffective) {
+        this.passwordeffective = passwordeffective;
     }
 }

+ 11 - 0
mainFactory/src/main/java/org/bfkj/domain/Userinfo.java

@@ -1,6 +1,7 @@
 package org.bfkj.domain;
 
 import java.io.Serializable;
+import java.time.LocalDateTime;
 
 /**
 * 用户表
@@ -60,6 +61,16 @@ public class Userinfo implements Serializable {
     
     private String secondarypassword;
 
+
+    private LocalDateTime lastestchangepasswordtime;
+    public LocalDateTime getLastestchangepasswordtime() {
+        return lastestchangepasswordtime;
+    }
+
+    public void setLastestchangepasswordtime(LocalDateTime lastestchangepasswordtime) {
+        this.lastestchangepasswordtime = lastestchangepasswordtime;
+    }
+
     /**
     * 自增长主键用户编号
     */

+ 5 - 5
mainFactory/src/main/java/org/bfkj/domain/Userloginlog.java

@@ -77,14 +77,14 @@ public class Userloginlog implements Serializable {
 
     private String apptoken;
 
-    private Boolean isexpires;
+    private LocalDateTime expirestime;
 
-    public Boolean getIsexpires() {
-        return isexpires;
+    public LocalDateTime getExpirestime() {
+        return expirestime;
     }
 
-    public void setIsexpires(Boolean isexpires) {
-        this.isexpires = isexpires;
+    public void setExpirestime(LocalDateTime expirestime) {
+        this.expirestime = expirestime;
     }
 
     public String getApptoken() {

+ 7 - 0
mainFactory/src/main/java/org/bfkj/dtos/CodeResultCache.java

@@ -0,0 +1,7 @@
+package org.bfkj.dtos;
+
+import java.time.LocalDateTime;
+
+public record CodeResultCache(String code, LocalDateTime exprieTime) {
+
+}

+ 18 - 0
mainFactory/src/main/java/org/bfkj/envs/HttpEnv.java

@@ -0,0 +1,18 @@
+package org.bfkj.envs;
+
+/**
+ * @author l7871
+ */
+public class HttpEnv {
+    private HttpEnv() {
+    }
+
+    public static final String APP_TOKEN = "token";
+    public static final String USER_TOKEN = "usertoken";
+
+    public static final String REQUEST_IP = "requestip";
+    public static final String SESSION_ID = "sessionid";
+    public static final String VERIFY_CODE = "verifycode";
+    public static final String APP_ID = "appid";
+    public static final String APP_SECRET = "appsecret";
+}

+ 11 - 9
mainFactory/src/main/java/org/bfkj/services/ApplicationService.java

@@ -4,21 +4,15 @@ package org.bfkj.services;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.bfkj.domain.Application;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.core.RowMapper;
 import org.springframework.stereotype.Service;
 
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Map;
-
 @Service
 public class ApplicationService {
 
-    private ObjectMapper objectMapper=new ObjectMapper();
+    private ObjectMapper objectMapper = new ObjectMapper();
 
     private final JdbcTemplate securityJdbcTemplate;
 
@@ -32,9 +26,17 @@ public class ApplicationService {
     }
 
     public Application findByAppId(String id) {
-       return (Application) securityJdbcTemplate.queryForObject("select * from application where appid = ? ", new BeanPropertyRowMapper(Application.class),id);
-
+        return (Application) securityJdbcTemplate.queryForObject("select * from application where appid = ? ", new BeanPropertyRowMapper(Application.class), id);
+    }
 
+    public Application findByAppIdAndAppSecret(String id, String appSecret) {
+        return securityJdbcTemplate.queryForList("select * from application where appid = ?  and appsecret = ?", id, appSecret).stream().findAny().map(it -> {
+            try {
+                return objectMapper.readValue(objectMapper.writeValueAsString(it), Application.class);
+            } catch (JsonProcessingException e) {
+                throw new RuntimeException(e);
+            }
+        }).orElse(null);
     }
 
 }

+ 30 - 5
mainFactory/src/main/java/org/bfkj/services/ApplicationconnectlogService.java

@@ -1,13 +1,17 @@
 package org.bfkj.services;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 import org.bfkj.domain.Appconnectlog;
-import org.bfkj.domain.Application;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
+import java.util.Objects;
 
 @Service
 public class ApplicationconnectlogService {
@@ -15,13 +19,24 @@ public class ApplicationconnectlogService {
     private final JdbcTemplate securityJdbcTemplate;
 
 
+    private ObjectMapper objectMapper = new ObjectMapper() {{
+        registerModule(new Jdk8Module());
+        registerModule(new JavaTimeModule());
+    }};
+
+
     public ApplicationconnectlogService(@Qualifier("securityJdbcTemplate") JdbcTemplate securityJdbcTemplate) {
         this.securityJdbcTemplate = securityJdbcTemplate;
     }
 
-    public void save(Appconnectlog appconnectlog) {
-        securityJdbcTemplate.update("insert into appconnectlog ( appid, requesttime, requestip, apptoken, expiretime, lasttime) values (?,?,?,?,?,?)",
-                appconnectlog.getAppid(), appconnectlog.getRequesttime(), appconnectlog.getRequestip(), appconnectlog.getApptoken(), appconnectlog.getExpiretime(), appconnectlog.getLasttime());
+    public void saveOrUpdate(Appconnectlog appconnectlog) {
+        if (Objects.isNull(appconnectlog.getConnid())) {
+            securityJdbcTemplate.update("insert into appconnectlog ( appid, requesttime, requestip, apptoken, expiretime, lasttime) values (?,?,?,?,?,?)",
+                    appconnectlog.getAppid(), appconnectlog.getRequesttime(), appconnectlog.getRequestip(), appconnectlog.getApptoken(), appconnectlog.getExpiretime(), appconnectlog.getLasttime());
+        } else {
+            securityJdbcTemplate.update("update  appconnectlog set appid=?, requesttime=?, requestip=?, apptoken=?, expiretime=?, lasttime=? where connid=?",
+                    appconnectlog.getAppid(), appconnectlog.getRequesttime(), appconnectlog.getRequestip(), appconnectlog.getApptoken(), appconnectlog.getExpiretime(), appconnectlog.getLasttime(), appconnectlog.getAppid());
+        }
 
     }
 
@@ -30,7 +45,7 @@ public class ApplicationconnectlogService {
 
     }
 
-    public boolean updateApplicationLogTokenExpiresTime(String appId, String token,String requestid, LocalDateTime expiresTime) {
+    public boolean updateApplicationLogTokenExpiresTime(String appId, String token, String requestid, LocalDateTime expiresTime) {
         return securityJdbcTemplate.update("update appconnectlog set expiretime=? where apptoken =? and requestip =? and appid=?",
                 expiresTime, token, requestid, appId) != 0;
     }
@@ -45,4 +60,14 @@ public class ApplicationconnectlogService {
         securityJdbcTemplate.update("delete from appconnectlog where expiretime < NOW() and 1 = ?", 1);
     }
 
+    public Appconnectlog findByAppidAndRequestIp(String appId, String requestIp) {
+        return securityJdbcTemplate.queryForList("select * from appconnectlog where appid = ? and requestip = ?", appId, requestIp).stream().findAny().map(it -> {
+            try {
+                return objectMapper.readValue(objectMapper.writeValueAsString(it), Appconnectlog.class);
+            } catch (JsonProcessingException e) {
+                throw new RuntimeException(e);
+            }
+        }).orElse(null);
+    }
+
 }

+ 280 - 341
mainFactory/src/main/java/org/bfkj/services/SecurityService.java

@@ -4,6 +4,8 @@ package org.bfkj.services;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 import org.bfkj.apos.Log;
 import org.bfkj.domain.*;
 import org.bfkj.domain.log.Applog;
@@ -11,30 +13,35 @@ import org.bfkj.domain.log.LogEntity;
 import org.bfkj.domain.log.Userlog;
 import org.bfkj.dtos.R;
 import org.bfkj.dtos.ServiceDto;
+import org.bfkj.envs.HttpEnv;
 import org.bfkj.services.cache.CodeCacheService;
 import org.bfkj.utils.CommonUtil;
 import org.bfkj.utils.RandomGraphic;
 import org.springframework.stereotype.Service;
 
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 
+import static org.bfkj.envs.HttpEnv.*;
+
 @Service
 public class SecurityService {
 
 
-    private final static Map<String, List<String>> alias = new HashMap<>();
+    private static final Map<String, List<String>> alias = new HashMap<>();
 
     static {
-        alias.put("appid", List.of("appid", "app_id", "appId", "APPID"));
-        alias.put("appsecret", List.of("appSecret", "app_secret", "APP_SECRET", "appsecret", "APPSECRET"));
-        alias.put("sessionid", List.of("sessionId", "sessionid", "SESSIONID", "SESSION_ID", "session_id"));
-        alias.put("requestip", List.of("requestIp", "requestip", "request_ip", "REQUEST_IP", "request_ip", "REQUESTIP", "ip"));
+        alias.put(APP_ID, List.of(APP_ID, "app_id", "appId", "APPID"));
+        alias.put(APP_SECRET, List.of(APP_SECRET, "appSecret", "app_secret", "APP_SECRET", "appsecret", "APPSECRET"));
+        alias.put(SESSION_ID, List.of(SESSION_ID, "sessionId", "SESSIONID", "SESSION_ID", "session_id"));
+        alias.put(REQUEST_IP, List.of(REQUEST_IP, "requestIp", "request_ip", "REQUEST_IP", "request_ip", "REQUESTIP", "ip"));
         alias.put("username", List.of("username", "userName", "user_name", "USER_NAME", "USERNAME"));
         alias.put("password", List.of("password", "pwd", "PWD", "PASSWORD"));
         alias.put("version", List.of("version", "Version", "VERSION"));
-        alias.put("verifycode", List.of("verifycode", "verifyCode", "code"));
+        alias.put(VERIFY_CODE, List.of(VERIFY_CODE, "verifyCode", "code"));
     }
 
     private final ApplicationService applicationService;
@@ -43,10 +50,8 @@ public class SecurityService {
     private final PermissionsService permissionsService;
     private final UserinfoService userinfoService;
     private final CodeCacheService codeCacheService;
-    private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-    private ObjectMapper objectMapper = new ObjectMapper() {{
-        setSerializationInclusion(JsonInclude.Include.NON_NULL);
-    }};
+    private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+    private final ObjectMapper objectMapper;
 
     public SecurityService(ApplicationService applicationService, ApplicationconnectlogService applicationconnectlogService, UserloginlogService userloginlogService, PermissionsService permissionsService, UserinfoService userinfoService, CodeCacheService codeCacheService) {
         this.applicationService = applicationService;
@@ -55,65 +60,65 @@ public class SecurityService {
         this.permissionsService = permissionsService;
         this.userinfoService = userinfoService;
         this.codeCacheService = codeCacheService;
+        this.objectMapper = new ObjectMapper();
+        this.objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+        this.objectMapper.registerModule(new Jdk8Module());
+        this.objectMapper.registerModule(new JavaTimeModule());
     }
 
     //安全类服务
     //连接认证--获取连接令牌
     @Log(Log.LogType.APP)
-    public ServiceDto<Map<String, Object>, LogEntity> getToken(Map<String, Object> requestData) throws JsonProcessingException {
-        Optional<String> appid = getValue("appid", requestData);
-        Optional<String> appSecret = getValue("appsecret", requestData);
-        Optional<String> requestIp = getValue("requestip", requestData);
-        Optional<String> sessionId = getValue("sessionid", requestData);
+    public ServiceDto<Map<String, Object>, LogEntity> getToken(Map<String, Object> requestData) throws JsonProcessingException, NoSuchAlgorithmException {
+        String appid = getValue(APP_ID, requestData);
+        String appSecret = getValue(APP_SECRET, requestData);
+        String requestIp = getValue(REQUEST_IP, requestData);
+        String sessionId = getValue(SESSION_ID, requestData);
         ServiceDto<Map<String, Object>, LogEntity> serviceDto = new ServiceDto<>();
-        Application application = null;
-        if (appid.isPresent() && appSecret.isPresent()) {
-//            无条件删除过期的数据
-            applicationconnectlogService.removeExpiresData();
+        Application application;
 
-            application = applicationService.findByAppId(appid.get());
-            if (appSecret.get().equals(application.getAppsecret())) {
+        applicationconnectlogService.removeExpiresData();
+        application = applicationService.findByAppIdAndAppSecret(appid, appSecret);
+        if (Objects.nonNull(application)) {
+
+            Appconnectlog applicationconnectlog = applicationconnectlogService.findByAppidAndRequestIp(appid, requestIp);
+            LocalDateTime now = LocalDateTime.now();
+            if (Objects.isNull(applicationconnectlog)) {
+                applicationconnectlog = new Appconnectlog();
 //            令牌
-                String md5Token = CommonUtil.toMD5("%s:%s".formatted(LocalDateTime.now(), sessionId));
-//            有效期时长
-                Long apptokeneffective = application.getApptokeneffective();
-//            过期时间
-                LocalDateTime expiresTime = LocalDateTime.now().plusSeconds(apptokeneffective);
-//            新增记录
-                Appconnectlog applicationconnectlog = new Appconnectlog();
-
-                applicationconnectlog.setAppid(appid.get());
-                applicationconnectlog.setExpiretime(expiresTime);
+                String md5Token = CommonUtil.toMD5("%s:%s".formatted(now, sessionId));
                 applicationconnectlog.setApptoken(md5Token);
-                applicationconnectlog.setRequestip(requestIp.get());
-                applicationconnectlog.setRequesttime(LocalDateTime.now());
-                applicationconnectlog.setLasttime(LocalDateTime.now());
-                applicationconnectlogService.save(applicationconnectlog);
-                Map<String, Object> data = new HashMap<>();
-                data.put("token", md5Token);
-                data.put("expirestime", expiresTime.format(dateTimeFormatter));
-                data.put("appname", application.getAppname());
-                data.put("appenname", application.getAppengname());
-                data.put("logo", application.getApplogo());
-                data.put("smalllogo", application.getSmalllogo());
-                data.put("background", application.getBackgroundimage());
-                data.put("securitycoderule", application.getSecuritycoderule());
-                serviceDto.setReturnData(R.success("0", data));
-                serviceDto.setSuccess(true);
-
-            } else {
-                serviceDto.setSuccess(false);
-                serviceDto.setReturnData(R.fail("-1", "用户或密码错误"));
+                applicationconnectlog.setAppid(appid);
+                applicationconnectlog.setRequestip(requestIp);
             }
+//            有效期时长(分钟)
+            Long apptokeneffective = application.getApptokeneffective();
+//            过期时间分钟
+            LocalDateTime expiresTime = now.plusMinutes(apptokeneffective);
+            applicationconnectlog.setExpiretime(expiresTime);
+            applicationconnectlog.setRequesttime(now);
+            applicationconnectlog.setLasttime(now);
+            applicationconnectlogService.saveOrUpdate(applicationconnectlog);
+            Map<String, Object> data = new HashMap<>();
+            data.put("apptoken", applicationconnectlog.getApptoken());
+            data.put("appeffective", expiresTime.format(dateTimeFormatter));
+            data.put("appname", application.getAppname());
+            data.put("appengname", application.getAppengname());
+            data.put("applogo", application.getApplogo());
+            data.put("appsmalllogo", application.getSmalllogo());
+            data.put("background", application.getBackgroundimage());
+            data.put("appcoderule", application.getSecuritycoderule());
+            serviceDto.setReturnData(R.success("0", data));
+            serviceDto.setSuccess(true);
         } else {
             serviceDto.setSuccess(false);
-            serviceDto.setReturnData(R.fail("-1", "appid 或者 appSecret 错误"));
+            serviceDto.setReturnData(R.fail("-1", "appid或者appsecret错误"));
         }
         Applog logData = new Applog();
-        logData.setAppid(appid.orElse(null));
+        logData.setAppid(appid);
         logData.setApiname((Objects.nonNull(application) ? application.getAppname() : null));
-        logData.setRequestip(requestIp.get());
-        logData.setSessionid(sessionId.get());
+        logData.setRequestip(requestIp);
+        logData.setSessionid(sessionId);
         logData.setInputdata(objectMapper.writeValueAsString(requestData));
         logData.setOutputdata(objectMapper.writeValueAsString(serviceDto.getReturnData()));
         serviceDto.setLogData(logData);
@@ -123,46 +128,35 @@ public class SecurityService {
     //校验连接令牌
     @Log(Log.LogType.APP)
     public ServiceDto<Map<String, Object>, LogEntity> verifyToken(Map<String, Object> requestData) throws JsonProcessingException {
-        Optional<String> token = getValue("token", requestData);
+        String token = getValue(APP_TOKEN, requestData);
 
-        Optional<String> requestIp = getValue("requestip", requestData);
+        String requestIp = getValue(REQUEST_IP, requestData);
 
         ServiceDto<Map<String, Object>, LogEntity> serviceDto = new ServiceDto<>();
         String appid = null;
-        if (token.isEmpty()) {
-            serviceDto.setSuccess(false);
-            serviceDto.setReturnData(R.fail("-1", "token错误"));
+        Application application = null;
+        applicationconnectlogService.removeExpiresData();
+        Appconnectlog applicationLog = applicationconnectlogService.findByTokenAndRequestIp(token, requestIp);
+        if (Objects.nonNull(applicationLog)) {
+            appid = applicationLog.getAppid();
+            application = applicationService.findByAppId(appid);
+            serviceDto.setSuccess(true);
+            Map<String, Object> data = new HashMap<>();
+            data.put("validstatus", true);
+            data.put("appid", applicationLog.getAppid());
+            data.put("application", application);
+            serviceDto.setReturnData(R.success("0", "token校验通过", data));
         } else {
-            Appconnectlog applicationLog = applicationconnectlogService.findByTokenAndRequestIp(token.get(), requestIp.get());
-
-            if (Objects.nonNull(applicationLog)) {
-                appid = applicationLog.getAppid();
-                if (LocalDateTime.now().isAfter(applicationLog.getExpiretime())) {
-                    serviceDto.setSuccess(false);
-                    serviceDto.setReturnData(R.fail("-1", "token已过期"));
-                } else {
-                    serviceDto.setSuccess(true);
-
-                    Map<String, Object> data = new HashMap<>();
-                    data.put("validstatus", true);
-                    data.put("appid", applicationLog.getAppid());
-                    serviceDto.setReturnData(R.success("0", "token校验通过", data));
-                }
-            } else {
-                Map<String, Object> data = new HashMap<>();
-                data.put("validstatus", false);
-                serviceDto.setReturnData(R.success("-1", "token校验通过", data));
-            }
+            Map<String, Object> data = new HashMap<>();
+            data.put("validstatus", false);
+            serviceDto.setReturnData(R.success("-1", "token无效", data));
         }
         Applog logData = new Applog();
         logData.setAppid(appid);
-        Application application = applicationService.findByAppId(appid);
-
         logData.setApiname((Objects.nonNull(application) ? application.getAppname() : null));
-
-        logData.setRequestip(requestIp.get());
-        Optional<String> sessionId = getValue("sessionid", requestData);
-        logData.setSessionid(sessionId.get());
+        logData.setRequestip(requestIp);
+        String sessionId = getValue(SESSION_ID, requestData);
+        logData.setSessionid(sessionId);
         logData.setInputdata(objectMapper.writeValueAsString(requestData));
         logData.setOutputdata(objectMapper.writeValueAsString(serviceDto.getReturnData()));
         serviceDto.setLogData(logData);
@@ -172,37 +166,38 @@ public class SecurityService {
     //刷新连接令牌
     @Log(Log.LogType.APP)
     public ServiceDto<Map<String, Object>, LogEntity> refreshToken(Map<String, Object> requestData) throws JsonProcessingException {
-        ServiceDto<Map<String, Object>, LogEntity> verified = verifyToken(requestData);
 
-        if (!verified.isSuccess()) {
-            return verified;
-        }
-        ServiceDto<Map<String, Object>, LogEntity> resultData = new ServiceDto<>();
-        Optional<String> requestIp = getValue("requestIp", requestData);
-        Optional<String> token = getValue("token", requestData);
-        String appid = (String) verified.getReturnData().getReturnData().get("appid");
-        Application application = applicationService.findByAppId(appid);
-        LocalDateTime expiresTime = LocalDateTime.now().plusSeconds(application.getApptokeneffective());
-        if (applicationconnectlogService.updateApplicationLogTokenExpiresTime(appid, token.get(), requestIp.get(), expiresTime)) {
-            Map<String, Object> data = new HashMap<>();
-            data.put("expirestime", expiresTime.format(dateTimeFormatter));
-            data.put("token", token.get());
-            resultData.setSuccess(true);
-            resultData.setReturnData(R.success("0", data));
+        ServiceDto<Map<String, Object>, LogEntity> resultData = verifyToken(requestData);
+        Application application = null;
 
-        } else {
-            resultData.setReturnData(R.fail("-1", "刷新令牌失败"));
-            resultData.setSuccess(false);
+        String appid = null;
+        String sessionId = getValue(SESSION_ID, requestData);
+
+        String requestIp = getValue(REQUEST_IP, requestData);
+        if (resultData.isSuccess()) {
+            String token = getValue(APP_TOKEN, requestData);
+            application = (Application) resultData.getReturnData().getReturnData().get("application");
+            appid = application.getAppid();
+
+            LocalDateTime expiresTime = LocalDateTime.now().plusSeconds(application.getApptokeneffective());
+            String tokenStr = token;
+            if (applicationconnectlogService.updateApplicationLogTokenExpiresTime(appid, tokenStr, requestIp, expiresTime)) {
+                Map<String, Object> data = new HashMap<>();
+                data.put("expirestime", expiresTime.format(dateTimeFormatter));
+                data.put("token", tokenStr);
+                resultData.setSuccess(true);
+                resultData.setReturnData(R.success("0", data));
+            } else {
+                resultData.setReturnData(R.fail("-1", "刷新令牌失败"));
+                resultData.setSuccess(false);
+            }
         }
 
         Applog logData = new Applog();
         logData.setAppid(appid);
-
         logData.setApiname((Objects.nonNull(application) ? application.getAppname() : null));
-
-        logData.setRequestip(requestIp.get());
-        Optional<String> sessionId = getValue("sessionid", requestData);
-        logData.setSessionid(sessionId.get());
+        logData.setRequestip(requestIp);
+        logData.setSessionid(sessionId);
         logData.setInputdata(objectMapper.writeValueAsString(requestData));
         logData.setOutputdata(objectMapper.writeValueAsString(resultData.getReturnData()));
         resultData.setLogData(logData);
@@ -214,40 +209,43 @@ public class SecurityService {
     public ServiceDto<Map<String, Object>, LogEntity> verifyCode(Map<String, Object> requestData) throws JsonProcessingException {
 
         ServiceDto<Map<String, Object>, LogEntity> resultData = verifyToken(requestData);
-        Optional<String> appidOpt = Optional.empty();
-        Optional<String> appnameOpt = Optional.empty();
-        Optional<String> sessionId = getValue("sessionid", requestData);
-        Optional<String> requestIp = getValue("requestip", requestData);
+        String sessionId = getValue(SESSION_ID, requestData);
+        String requestIp = getValue(REQUEST_IP, requestData);
+        Application application = null;
         if (resultData.isSuccess()) {
-            String appid = (String) resultData.getReturnData().getReturnData().get("appid");
-            appidOpt.of(appid);
-            Application application = applicationService.findByAppId(appid);
-            if (Objects.nonNull(application)) {
-                appnameOpt.of(application.getAppname());
-                String securitycoderule = application.getSecuritycoderule();
-                Long securitycodeeffective = application.getSecuritycodeeffective();
-                Integer securitycoderulelength = application.getSecuritycoderulelength();
-                Map<String, Object> codeMap = RandomGraphic.generateVerifyCode(securitycoderulelength, securitycoderule);
-
-                String code = codeMap.get("verifyCode").toString();
-                String verifyCodeImage = codeMap.get("verifyCodeImage").toString();
-                codeCacheService.addCode(code, sessionId.get(), appid, securitycodeeffective, requestIp.get());
-
-//            编译后的验证码
+            application = (Application) resultData.getReturnData().getReturnData().get("application");
+            String securitycoderule = application.getSecuritycoderule();
+            Rule rule = parserRule(securitycoderule);
+            if (Objects.isNull(rule.range)) {
+                resultData.setSuccess(true);
                 Map<String, Object> data = new HashMap<>();
-                data.put("verifyCodeImage", verifyCodeImage);
+                data.put("verifyCodeImage", null);
                 resultData.setReturnData(R.success("0", data));
-                resultData.setSuccess(true);
-
+            } else {
+                try {
+                    RandomGraphic.CodeResult codeMap = RandomGraphic.generateVerifyCode(rule.max, rule.range);
+                    String code = codeMap.verifyCode();
+                    String verifyCodeImage = codeMap.verifyCodeImage();
+                    codeCacheService.addCode(code, sessionId, application.getAppid(), application.getSecuritycodeeffective(), requestIp);
+//            编译后的验证码
+                    Map<String, Object> data = new HashMap<>();
+                    data.put("verifyCodeImage", verifyCodeImage);
+                    resultData.setReturnData(R.success("0", data));
+                    resultData.setSuccess(true);
+                } catch (IOException e) {
+                    resultData.setReturnData(R.fail("-1", "生成验证码失败: " + e.getMessage()));
+                    resultData.setSuccess(false);
+                }
             }
+
+
         }
         Applog logData = new Applog();
-        logData.setAppid(appidOpt.orElse(null));
+        logData.setAppid(Objects.nonNull(application) ? application.getAppid() : null);
+        logData.setApiname(Objects.nonNull(application) ? application.getAppname() : null);
 
-        logData.setApiname(appnameOpt.orElse(null));
-
-        logData.setRequestip(requestIp.get());
-        logData.setSessionid(sessionId.get());
+        logData.setRequestip(requestIp);
+        logData.setSessionid(sessionId);
         logData.setInputdata(objectMapper.writeValueAsString(requestData));
         logData.setOutputdata(objectMapper.writeValueAsString(resultData.getReturnData()));
         resultData.setLogData(logData);
@@ -260,151 +258,106 @@ public class SecurityService {
     @Log(Log.LogType.USER)
     public ServiceDto<Map<String, Object>, LogEntity> login(Map<String, Object> requestData) throws JsonProcessingException {
 //        首先,通过verifyToken方法验证app的令牌(token)是否有效(返回是否有效、appid)。
-        Optional<String> requestip = getValue("requestip", requestData);
-        Optional<String> sessionid = getValue("sessionid", requestData);
-        Optional<String> username = getValue("username", requestData);
-        Optional<String> password = getValue("password", requestData);
-        Optional<String> verifycode = getValue("verifycode", requestData);
+        String requestip = getValue(REQUEST_IP, requestData);
+        String sessionid = getValue(SESSION_ID, requestData);
+        String username = getValue("username", requestData);
+        String password = getValue("password", requestData);
+        String verifycode = getValue(VERIFY_CODE, requestData);
         ServiceDto<Map<String, Object>, LogEntity> resultData = verifyToken(requestData);
-        Optional<Long> userid = Optional.empty();
+        Long userid = 0L;
         if (resultData.isSuccess()) {
 
-            String appid = resultData.getReturnData().getReturnData().get("appid").toString();
+            Application application = (Application) resultData.getReturnData().getReturnData().get("application");
 
-            Application application = applicationService.findByAppId(appid);
             String securitycoderule = application.getSecuritycoderule();
-//        if (Objects.nonNull(securitycoderule) && !codeCacheService.check(verifycode.get(), sessionid.get(), appid, requestip.get())) {
-//            resultData.setSuccess(false);
-//            resultData.setReturnData(R.fail("-1", "验证码错误"));
-//            return resultData;
-//        }
+            if (Objects.nonNull(securitycoderule) && !codeCacheService.check(verifycode, sessionid, application.getAppid(), requestip)) {
+                resultData.setSuccess(false);
+                resultData.setReturnData(R.fail("-1", "验证码错误"));
+                return resultData;
+            }
 
 
-            Userinfo userinfo = userinfoService.findByUsernameAndPassword(username.get(), password.get());
-            userid.ofNullable(userinfo.getUserid());
+            String token = getValue("token", requestData);
+            Userinfo userinfo = userinfoService.findByUsernameAndPassword(username, password);
             if (Objects.isNull(userinfo)) {
                 resultData.setSuccess(false);
                 resultData.setReturnData(R.fail("-1", "用户名或密码错误"));
             } else {
+                userid = userinfo.getUserid();
 
-                Userloginlog userloginlog = userloginlogService.findByUserIdAndSessionId(userinfo.getUserid(), sessionid.get());
+                List<Userloginlog> userloginlogs = userloginlogService.findByUserId(userinfo.getUserid());
 
                 Map<String, Object> data = new HashMap<>();
-                if (Objects.nonNull(userloginlog)) {
-
-                    data.put("userstatus", "2");
+                Integer multilogin = application.getMultilogin();
+//                没有登录 或者允许多机登录
+                String requestIp = requestip;
+                String sessionId = sessionid;
+                String appToken = token;
+                if (userloginlogs.isEmpty() || 1 == multilogin) {
+                    data.put("userstatus", "0");
                     resultData.setSuccess(true);
-
+                    userloginlogService.insertUserLoginLog(requestIp, sessionId, userinfo.getUserid(), null, appToken, application.getAppid());
                     resultData.setReturnData(R.success("0", data));
                 } else {
-                    Integer multilogin = application.getMultilogin();
-                    Optional<String> token = getValue("token", requestData);
-                    if (1 == multilogin) {
-                        userloginlogService.insertUserLoginLog(requestip.get(), sessionid.get(), userinfo.getUserid(), null, token.get(), appid);
-
-                        data.put("userstatus", "0");
-                        resultData.setSuccess(true);
-                        resultData.setReturnData(R.success("0", data));
-                    } else {
-
-
-                        List<Userloginlog> userloginlogs = userloginlogService.findByUserId(userinfo.getUserid());
-//            没有登录
-                        if (userloginlogs.isEmpty()) {
-                            data.put("userstatus", "0");
-                            resultData.setSuccess(true);
-                            resultData.setReturnData(R.fail("0", "data"));
-                        } else {
-                            data.put("userstatus", "1");
-                            resultData.setSuccess(true);
-                            resultData.setReturnData(R.fail("0", "data"));
-                        }
-                        Appconnectlog appconnectlog = new Appconnectlog();
-                        appconnectlog.setApptoken(appconnectlog.getApptoken());
-                        appconnectlog.setAppid(appid);
-                        appconnectlog.setLasttime(LocalDateTime.now());
-                        appconnectlog.setRequesttime(LocalDateTime.now());
-                        appconnectlog.setRequestip(requestip.get());
-                        appconnectlog.setExpiretime(LocalDateTime.now().plusSeconds(application.getApptokeneffective()));
-                        applicationconnectlogService.save(appconnectlog);
-
-                        codeCacheService.remove(verifycode.get(), sessionid.get(), appid, requestip.get());
+//                    有登录
+                    data.put("userstatus", "0");
+                    resultData.setSuccess(true);
+                    resultData.setReturnData(R.fail("1", "data"));
+                    if (userloginlogs.stream().filter(it -> it.getSessionid().equals(sessionId) && Objects.nonNull(it.getUsertoken())).findFirst().isEmpty()) {
+                        userloginlogService.insertUserLoginLog(requestIp, sessionId, userinfo.getUserid(), null, appToken, application.getAppid());
                     }
+                    Appconnectlog appconnectlog = new Appconnectlog();
+                    appconnectlog.setApptoken(appconnectlog.getApptoken());
+                    appconnectlog.setAppid(application.getAppid());
+                    appconnectlog.setLasttime(LocalDateTime.now());
+                    appconnectlog.setRequesttime(LocalDateTime.now());
+                    appconnectlog.setRequestip(requestIp);
+                    appconnectlog.setExpiretime(LocalDateTime.now().plusSeconds(application.getApptokeneffective()));
+                    applicationconnectlogService.saveOrUpdate(appconnectlog);
+
+                    codeCacheService.remove(sessionId, application.getAppid(), requestIp);
+
                 }
             }
         }
 
         Userlog logData = new Userlog();
-        logData.setUserid(userid.orElse(null));
+        logData.setUserid(userid);
 
-        logData.setUsername(username.orElse(null));
+        logData.setUsername(username);
 
-        logData.setRequestip(requestip.get());
-        Optional<String> sessionId = getValue("sessionid", requestData);
-        logData.setSessionid(sessionId.orElse(null));
+        logData.setRequestip(requestip);
+        logData.setSessionid(sessionid);
         logData.setInputdata(objectMapper.writeValueAsString(requestData));
         logData.setOutputdata(objectMapper.writeValueAsString(resultData.getReturnData()));
         resultData.setLogData(logData);
         return resultData;
-
-
-//
-//        如果令牌有效,继续执行以下步骤:
-//        从requestData中获取sessionid、requestip、用户名、密码、验证码(md5)。
-//        通过appid字段查找对应的application表记录
-//                判断记录中验证码规则
-//        如需验证验证码
-//                根据appid,ip,sessionid,和验证码查询数据库
-//        如不通过 返回错误
-//        验证用户名密码(根据用户名、密码到数据库查询即可,同时还可获取到userid)
-//        如不通过 返回错误
-//        通过userid、sessionid在userloginlog中查找
-//        如找到  用户状态设置为2
-//        如未找到
-//        获取application记录中的multilogin字段。
-//        如果 multilogin 等于1 则
-//        在userloginlog表中插入一条新的登录记录(userid、sessionid、ip、apptoken)。
-//        将用户状态设置为0
-//        如果 multilogin 不等于1 则
-//        通过用户ID在userloginlog表中查找对应的登录记录。
-//        如果登录记录不为空,
-//        将用户状态设置为1。
-//        如果登录记录为空,
-//        将用户状态设置为0。
-//        在userloginlog表中插入一条新的登录记录。
-//        将用户状态添加到result中。
-//        返回result作为用户令牌的结果。
-//        否则
-//                返回错误
     }
 
 
     //强制登录
     @Log(Log.LogType.USER)
-    public ServiceDto<Map<String, Object>, LogEntity> forceLogin(Map<String, Object> requestData) throws JsonProcessingException {
-        Optional<String> requestip = getValue("requestip", requestData);
-        Optional<String> sessionid = getValue("sessionid", requestData);
+    public ServiceDto<Map<String, Object>, LogEntity> forceLogin(Map<String, Object> requestData) throws JsonProcessingException, NoSuchAlgorithmException {
+        String requestip = getValue(REQUEST_IP, requestData);
+        String sessionid = getValue(SESSION_ID, requestData);
         ServiceDto<Map<String, Object>, LogEntity> result = verifyToken(requestData);
-        Optional<Long> userid = Optional.empty();
-        Optional<String> username = Optional.empty();
+        Userinfo userinfo = null;
+        Application application = null;
         if (result.isSuccess()) {
-            Optional<String> apptoken = getValue("token", requestData);
-            String appid = result.getReturnData().getReturnData().get("appid").toString();
-            Application application = applicationService.findByAppId(appid);
+            String apptoken = getValue(APP_TOKEN, requestData);
+            application = (Application) result.getReturnData().getReturnData().get("application");
             result.setSuccess(false);
             if (Objects.isNull(application)) {
                 result.setReturnData(R.fail("-1", "没有找到应用配置"));
             } else {
-                Userloginlog userloginlog = userloginlogService.findByAppTokenAndSessionIdAndRequestIp(apptoken.get(), sessionid.get(), requestip.get());
+                Userloginlog userloginlog = userloginlogService.findByAppTokenAndSessionIdAndRequestIpAndAppId(apptoken, sessionid, requestip, application.getAppid());
                 if (Objects.isNull(userloginlog)) {
                     result.setReturnData(R.fail("-1", "登录失败"));
                 } else {
-                    userid.of(userloginlog.getUserid());
-                    Userinfo userinfo = userinfoService.findByUserId(userid.get());
-                    username.of(userinfo.getUsername());
+                    userinfo = userinfoService.findByUserId(userloginlog.getUserid());
                     Long securitycodeeffective = application.getSecuritycodeeffective();
                     LocalDateTime expiresTime = LocalDateTime.now().plusSeconds(securitycodeeffective);
-                    String userToken = CommonUtil.toMD5("%s:%s".formatted(LocalDateTime.now(), sessionid.get()));
+                    String userToken = CommonUtil.toMD5("%s:%s".formatted(LocalDateTime.now(), sessionid));
                     userloginlogService.updateUserToken(userloginlog.getLoginid(), userToken);
                     result.setSuccess(true);
                     HashMap<String, Object> data = new HashMap<>();
@@ -413,23 +366,22 @@ public class SecurityService {
                     result.setReturnData(R.success("0", data));
                     Integer multilogin = application.getMultilogin();
                     if (multilogin == 1) {
-                        userloginlogService.removeByLogIdAndUserIdAndAppId(userloginlog.getLoginid(), userloginlog.getUserid(), userloginlog.getAppid());
-                    } else {
-                        userloginlogService.removeExpires();
+                        userloginlogService.removeByLogIdAndUserIdAndAppId(userloginlog.getLoginid());
                     }
+                    userloginlogService.removeExpires();
+
                 }
             }
         }
-
-
+        codeCacheService.remove(sessionid, Objects.nonNull(application) ? application.getAppid() : "", requestip);
         Userlog logData = new Userlog();
-        logData.setUserid(userid.orElse(null));
+        logData.setUserid(Objects.nonNull(userinfo) ? userinfo.getUserid() : null);
 
-        logData.setUsername(username.orElse(null));
+        logData.setUsername(Objects.nonNull(userinfo) ? userinfo.getUsername() : null);
 
 
-        logData.setRequestip(requestip.get());
-        logData.setSessionid(sessionid.orElse(null));
+        logData.setRequestip(requestip);
+        logData.setSessionid(sessionid);
         logData.setInputdata(objectMapper.writeValueAsString(requestData));
         logData.setOutputdata(objectMapper.writeValueAsString(result.getReturnData()));
         result.setLogData(logData);
@@ -456,9 +408,9 @@ public class SecurityService {
     }
 
     private ServiceDto<Map<String, Object>, LogEntity> checkUserToken(Map<String, Object> requestData) {
-        Optional<String> userToken = getValue("usertoken", requestData);
-        Optional<String> sessionId = getValue("sessionid", requestData);
-        Userloginlog userloginlog = userloginlogService.findByUserToken(userToken.get(), sessionId.get());
+        String userToken = getValue(USER_TOKEN, requestData);
+        String sessionId = getValue(SESSION_ID, requestData);
+        Userloginlog userloginlog = userloginlogService.findByUserToken(userToken, sessionId);
 
         String appid = userloginlog.getAppid();
         Application application = applicationService.findByAppId(appid);
@@ -469,6 +421,10 @@ public class SecurityService {
             return result;
         } else {
             result.setSuccess(true);
+            Userinfo userinfo = userinfoService.findByUserId(userloginlog.getUserid());
+            HashMap<String, Object> data = new HashMap<>();
+            data.put("userInfo", userinfo);
+            result.setReturnData(R.success("0", data));
             return result;
         }
 
@@ -478,26 +434,21 @@ public class SecurityService {
     @Log(Log.LogType.USER)
     public ServiceDto<Map<String, Object>, LogEntity> logOut(Map<String, Object> requestData) throws JsonProcessingException {
         ServiceDto<Map<String, Object>, LogEntity> resultData = checkUserToken(requestData);
-        Optional<Long> userid = Optional.empty();
-        Optional<String> username = Optional.empty();
-        Optional<String> sessionId = getValue("sessionid", requestData);
-        Optional<String> requestIp = getValue("requestip", requestData);
+        String sessionId = getValue(SESSION_ID, requestData);
+        String requestIp = getValue(REQUEST_IP, requestData);
+        Userinfo userInfo = null;
         if (resultData.isSuccess()) {
-            Optional<String> userToken = getValue("usertoken", requestData);
-            Userloginlog userloginlog = userloginlogService.findByUserToken(userToken.get(), sessionId.get());
-            userid.of(userloginlog.getUserid());
-            Userinfo userinfo = userinfoService.findByUserId(userloginlog.getUserid());
-            username.of(userinfo.getUsername());
-            userloginlogService.removeUserLoginLogByUserId(userloginlog.getUserid());
-            permissionsService.removePermissions(userloginlog.getUserid());
+            userInfo = (Userinfo) resultData.getReturnData().getReturnData().get("userInfo");
+            userloginlogService.removeUserLoginLogByUserId(userInfo.getUserid());
+            permissionsService.removePermissions(userInfo.getUserid());
             resultData.setReturnData(R.success("0", "成功", null));
         }
 
         Userlog logData = new Userlog();
-        logData.setUserid(userid.orElse(null));
-        logData.setUsername(username.orElse(null));
-        logData.setRequestip(requestIp.get());
-        logData.setSessionid(sessionId.get());
+        logData.setUserid(Objects.nonNull(userInfo) ? userInfo.getUserid() : null);
+        logData.setUsername(Objects.nonNull(userInfo) ? userInfo.getUsername() : null);
+        logData.setRequestip(requestIp);
+        logData.setSessionid(sessionId);
         logData.setInputdata(objectMapper.writeValueAsString(requestData));
         logData.setOutputdata(objectMapper.writeValueAsString(resultData.getReturnData()));
         resultData.setLogData(logData);
@@ -511,29 +462,22 @@ public class SecurityService {
 
         ServiceDto<Map<String, Object>, LogEntity> checked = checkUserToken(requestData);
         ServiceDto<List<Permissions>, LogEntity> resultData = new ServiceDto<>();
-        Optional<Long> userid = Optional.empty();
-        Optional<String> username = Optional.empty();
-        Optional<String> sessionId = getValue("sessionid", requestData);
-        Optional<String> requestIp = getValue("requestip", requestData);
+        String sessionId = getValue(SESSION_ID, requestData);
+        String requestIp = getValue(REQUEST_IP, requestData);
+        Userinfo userInfo = null;
         if (!checked.isSuccess()) {
             resultData.setSuccess(false);
             resultData.setReturnData(R.fail("-1", checked.getReturnData().getMessage()));
         } else {
-            Optional<String> userToken = getValue("usertoken", requestData);
-            Userloginlog userloginlog = userloginlogService.findByUserToken(userToken.get(), sessionId.get());
-            userid.of(userloginlog.getUserid());
-            Userinfo userinfo = userinfoService.findByUserId(userloginlog.getUserid());
-            username.of(userinfo.getUsername());
-            List<Permissions> ps = permissionsService.getPermissions(userloginlog.getUserid().toString());
+            userInfo = (Userinfo) checked.getReturnData().getReturnData().get("userInfo");
+            List<Permissions> ps = permissionsService.getPermissions(userInfo.getUserid().toString());
             resultData.setReturnData(R.success("0", ps));
-
         }
-
         Userlog logData = new Userlog();
-        logData.setUserid(userid.orElse(null));
-        logData.setUsername(username.orElse(null));
-        logData.setRequestip(requestIp.orElse(null));
-        logData.setSessionid(sessionId.orElse(null));
+        logData.setUserid(Objects.nonNull(userInfo) ? userInfo.getUserid() : null);
+        logData.setUsername(Objects.nonNull(userInfo) ? userInfo.getUsername() : null);
+        logData.setRequestip(requestIp);
+        logData.setSessionid(sessionId);
         logData.setInputdata(objectMapper.writeValueAsString(requestData));
         logData.setOutputdata(objectMapper.writeValueAsString(resultData.getReturnData()));
         resultData.setLogData(logData);
@@ -542,46 +486,41 @@ public class SecurityService {
 
     //应用API及数据权限
     public ServiceDto<Map<String, Object>, LogEntity> changePassword(Map<String, Object> requestData) throws JsonProcessingException {
-        Optional<Long> userid = Optional.empty();
-        Optional<String> username = Optional.empty();
-        Optional<String> sessionId = getValue("sessionid", requestData);
-        Optional<String> requestIp = getValue("requestip", requestData);
+        String username = "";
+        String sessionId = getValue(SESSION_ID, requestData);
+        String requestIp = getValue(REQUEST_IP, requestData);
         ServiceDto<Map<String, Object>, LogEntity> resultData = checkUserToken(requestData);
+        Userinfo userInfo = null;
         if (resultData.isSuccess()) {
-            Optional<String> oldPassword = getValue("oldpassword", requestData);
-            Optional<String> password = getValue("password", requestData);
-
-            Optional<String> userToken = getValue("usertoken", requestData);
-            Userloginlog userloginlog = userloginlogService.findByUserToken(userToken.get(), sessionId.get());
-            Long userId = userloginlog.getUserid();
-            userid.of(userId);
-
-            Userinfo userinfo = userinfoService.findByUserId(userId);
-            if (Objects.nonNull(userinfo)) {
-                username.of(userinfo.getUsername());
-                String userpassword = userinfo.getUserpassword();
-                if (!userpassword.equals(oldPassword.get())) {
-                    resultData.setSuccess(false);
-                    resultData.setReturnData(R.fail("-1", "密码错误"));
-                } else {
-                    userinfoService.updateUserPassword(userId, password.get());
-                }
-                resultData.setSuccess(true);
-                resultData.setReturnData(R.success("-1", "成功", null));
-            } else {
+            String oldPassword = getValue("oldpassword", requestData);
+            String password = getValue("password", requestData);
+
 
+            userInfo = (Userinfo) resultData.getReturnData().getReturnData().get("userInfo");
+            String userpassword = userInfo.getUserpassword();
+            if (!userpassword.equals(oldPassword)) {
                 resultData.setSuccess(false);
-                resultData.setReturnData(R.fail("-1", "用户没有找到"));
-            }
+                resultData.setReturnData(R.fail("-1", "密码错误"));
+            } else {
+                LocalDateTime now = LocalDateTime.now();
+                boolean isTrue = userinfoService.updateUserPassword(password, now, userInfo.getUserid(), oldPassword);
+
+                resultData.setSuccess(isTrue);
+                if (isTrue) {
+                    resultData.setReturnData(R.success("0", "成功", null));
+                } else {
 
+                    resultData.setReturnData(R.fail("-1", "成功"));
+                }
+            }
         }
 
 
         Userlog logData = new Userlog();
-        logData.setUserid(userid.orElse(null));
-        logData.setUsername(username.orElse(null));
-        logData.setRequestip(requestIp.get());
-        logData.setSessionid(sessionId.get());
+        logData.setUserid(Objects.nonNull(userInfo) ? userInfo.getUserid() : null);
+        logData.setUsername(username);
+        logData.setRequestip(requestIp);
+        logData.setSessionid(sessionId);
         logData.setInputdata(objectMapper.writeValueAsString(requestData));
         logData.setOutputdata(objectMapper.writeValueAsString(resultData.getReturnData()));
         resultData.setLogData(logData);
@@ -589,44 +528,44 @@ public class SecurityService {
     }
 
     //用户心跳
-    public ServiceDto<List<Permissions>, LogEntity> userHeartbeat(Map<String, Object> requestData) {
-        ServiceDto<Map<String, Object>, LogEntity> checked = checkUserToken(requestData);
-        ServiceDto<List<Permissions>, LogEntity> resultData = new ServiceDto<>();
-        if (!checked.isSuccess()) {
-            resultData.setSuccess(false);
-            resultData.setReturnData(R.fail("-1", checked.getReturnData().getMessage()));
-            return resultData;
-        } else {
-            Optional<String> userToken = getValue("usertoken", requestData);
-            Optional<String> sessionId = getValue("sessionid", requestData);
-            Userloginlog userloginlog1 = userloginlogService.findByUserToken(userToken.get(), sessionId.get());
-            if (Objects.nonNull(userloginlog1)) {
-                List<Userloginlog> userloginlogs = userloginlogService.findByUserId(userloginlog1.getUserid());
+    public ServiceDto<Map<String, Object>, LogEntity> userHeartbeat(Map<String, Object> requestData) {
+        ServiceDto<Map<String, Object>, LogEntity> resultData = checkUserToken(requestData);
+        if (resultData.isSuccess()) {
+            resultData.setReturnData(R.success("0", null));
+        }
+        return resultData;
+    }
 
-                if (Objects.nonNull(userloginlogs) && !userloginlogs.isEmpty()) {
-                    for (Userloginlog userloginlog : userloginlogs) {
 
-                        userloginlogService.updateLoginLogUserLastTimeById(userloginlog.getLoginid(), sessionId.get());
-                        resultData.setReturnData(R.success("0", "用户在线", null));
-                        resultData.setSuccess(true);
+    private String getValue(String key, Map<String, Object> data) {
+        return alias.getOrDefault(key, Collections.singletonList(key)).stream().map(data::get).filter(Objects::nonNull).map(Object::toString).findAny().orElse(null);
+    }
 
-                    }
-                    if (!resultData.isSuccess()) {
-                        resultData.setReturnData(R.success("-1", "查询失败", null));
-                        resultData.setSuccess(false);
-                    }
+    private Rule parserRule(String rule) {
+        if (Objects.isNull(rule)) {
+            return new Rule(null, 0, 0);
+        }
+        String range = "";
+        if (rule.contains("N")) {
+            range += "0123456789";
+        }
+        if (rule.contains("U")) {
+            range += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+        }
 
-                } else {
-                    resultData.setReturnData(R.success("-1", "查询失败", null));
-                    resultData.setSuccess(false);
-                }
-            }
+        if (rule.contains("L") || (!rule.contains("U") && !rule.contains("L"))) {
+            range += "abcdefghijklmnopqrstuvwxyz";
         }
-        return resultData;
+
+        if (rule.contains("W")) {
+            range += "~`!@#$%^&*(),./<>?;:|";
+        }
+        String minStr = rule.substring(rule.length() - 4, rule.length() - 2);
+        String maxStr = rule.substring(rule.length() - 2);
+        return new Rule(range, Integer.parseInt(minStr), Integer.parseInt(maxStr));
     }
 
+    private record Rule(String range, int min, int max) {
 
-    private Optional<String> getValue(String key, Map<String, Object> data) {
-        return alias.getOrDefault(key, Collections.singletonList(key)).stream().map(data::get).filter(Objects::nonNull).map(Object::toString).findAny();
     }
 }

+ 3 - 2
mainFactory/src/main/java/org/bfkj/services/UserinfoService.java

@@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDateTime;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -47,8 +48,8 @@ public class UserinfoService {
 
     }
 
-    public void updateUserPassword(Long userId, String password) {
-        securityJdbcTemplate.update("update userinfo set userpassword=? where userid=?", password, userId);
+    public boolean updateUserPassword(String newPassword, LocalDateTime localDateTime, Long userId, String oldpassword) {
+        return 0 < securityJdbcTemplate.update("update userinfo set userpassword=? and lastestchangepasswordtime=?  where userid=? and userpassword=?", newPassword, localDateTime, userId, oldpassword);
     }
 
     public Userinfo findByUsername(String username) {

+ 12 - 30
mainFactory/src/main/java/org/bfkj/services/UserloginlogService.java

@@ -4,7 +4,6 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
-import jakarta.annotation.Nonnull;
 import jakarta.annotation.Nullable;
 import org.bfkj.domain.Userloginlog;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -37,7 +36,7 @@ public class UserloginlogService {
 
     public List<Userloginlog> findByUserId(Long userId) {
 
-        List<Map<String, Object>> maps = securityJdbcTemplate.queryForList("select * from userloginlog where userid=? and isexpires=0 ", userId);
+        List<Map<String, Object>> maps = securityJdbcTemplate.queryForList("select * from userloginlog where userid=? and expirestime > now() ", userId);
         return maps.stream().map(it -> {
             try {
                 return objectMapper.readValue(objectMapper.writeValueAsString(it), Userloginlog.class);
@@ -49,9 +48,9 @@ public class UserloginlogService {
 
     }
 
-    public Userloginlog findByUserIdAndSessionId(Long userId, String sessionId) {
+    public Userloginlog findByAppTokenAndSessionIdAndRequestIpAndAppId(String appToken, String sessionId, String requestIp, String appId) {
 
-        List<Map<String, Object>> result = securityJdbcTemplate.queryForList("select * from userloginlog where userid=? and sessionid=? and isexpires=0 ", userId, sessionId);
+        List<Map<String, Object>> result = securityJdbcTemplate.queryForList("select * from userloginlog where apptoken=? and sessionid=? and requestip=?  and appid=? ", appToken, sessionId, requestIp, appId);
         if (result.isEmpty()) {
             return null;
         }
@@ -62,37 +61,19 @@ public class UserloginlogService {
         }
     }
 
-    public Userloginlog findByAppTokenAndSessionIdAndRequestIp(String appToken, String sessionId, String requestIp) {
-
-        List<Map<String, Object>> result = securityJdbcTemplate.queryForList("select * from userloginlog where apptoken=? and sessionid=? and requestip=? and isexpires=0 ", appToken, sessionId, requestIp);
-        if (result.isEmpty()) {
-            return null;
-        }
-        try {
-            return objectMapper.readValue(objectMapper.writeValueAsString(result.get(0)), Userloginlog.class);
-        } catch (JsonProcessingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public void removeUserLoginLog(@Nullable String apptokeneffective) {
-        securityJdbcTemplate.update("delete from userloginlog where DATE_ADD(lasttime,INTERVAL ? MICROSECOND ) < now()",
-                apptokeneffective);
-    }
-
 
     public void removeUserLoginLogByUserId(@Nullable Long userId) {
 
-        securityJdbcTemplate.update("update userloginlog set isexpires=1 where userid = ?", userId);
+        securityJdbcTemplate.update("delete from userloginlog where userid = ?", userId);
     }
 
-    public void updateLoginLogUserLastTimeById(@Nullable Long id, @Nonnull String sessionId) {
-        securityJdbcTemplate.update("update userloginlog set lasttime=now() where loginid=? and sessionid=?", id, sessionId);
+    public void updateUserLoginLogLastTimeById(@Nullable Long id) {
+        securityJdbcTemplate.update("update userloginlog set lasttime=? where loginid=? ", LocalDateTime.now(), id);
     }
 
     public Userloginlog findByUserToken(String userToken, String sessionId) {
 
-        List<Map<String, Object>> maps = securityJdbcTemplate.queryForList("select * from userloginlog where isexpires=0 and usertoken=? and sessionid=?", userToken, sessionId);
+        List<Map<String, Object>> maps = securityJdbcTemplate.queryForList("select * from userloginlog where expirestime > now() and usertoken=? and sessionid=?", userToken, sessionId);
 
         if (maps.isEmpty()) {
             return null;
@@ -106,15 +87,16 @@ public class UserloginlogService {
 
 
     public void updateUserToken(Long loginid, String userToken) {
-        securityJdbcTemplate.update("update userloginlog set apptoken=?,usertoken=?,lasttime=? where isexpires=0 and loginid=?", null, userToken, LocalDateTime.now(), loginid);
+        LocalDateTime now = LocalDateTime.now();
+        securityJdbcTemplate.update("update userloginlog set apptoken=?,usertoken=?,lasttime=?,expirestime=? where  loginid=?", null, userToken, now, now, loginid);
 
     }
 
-    public void removeByLogIdAndUserIdAndAppId(Long loginId, Long userid, String appid) {
-        securityJdbcTemplate.update("delete  from userloginlog where (userid=? and appid=? and loginid <> ?) or isexpires=1", userid, appid, loginId);
+    public void removeByLogIdAndUserIdAndAppId(Long loginId) {
+        securityJdbcTemplate.update("delete  from userloginlog where loginid=? ", loginId);
     }
 
     public void removeExpires() {
-        securityJdbcTemplate.update("delete  from userloginlog where  isexpires=1");
+        securityJdbcTemplate.update("delete  from userloginlog where  expirestime > now()");
     }
 }

+ 34 - 13
mainFactory/src/main/java/org/bfkj/services/cache/CodeCacheService.java

@@ -1,37 +1,58 @@
 package org.bfkj.services.cache;
 
-import org.bfkj.domain.Tempsecuritycode;
+import jakarta.annotation.Nonnull;
+import org.bfkj.dtos.CodeResultCache;
 import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 
 @Service
 public class CodeCacheService {
 
     private final JdbcTemplate securityJdbcTemplate;
 
-    public CodeCacheService(@Qualifier("securityJdbcTemplate")  JdbcTemplate securityJdbcTemplate) {
+    private final Map<String, CodeResultCache> codeResultCacheMap = new HashMap<>();
+
+    public CodeCacheService(@Qualifier("securityJdbcTemplate") JdbcTemplate securityJdbcTemplate) {
         this.securityJdbcTemplate = securityJdbcTemplate;
     }
 
-    public void addCode(String code, String sessionId, String appid, Long securitycodeeffective, String requestIp) {
+
+    public void addCode(@Nonnull String code,@Nonnull String sessionId,@Nonnull String appid,@Nonnull Long securitycodeeffective,@Nonnull String requestIp) {
 //      使用数据库
-        LocalDateTime localDateTime = LocalDateTime.now().plusSeconds(securitycodeeffective);
-        securityJdbcTemplate.update("insert into tempsecuritycode(appid,requestip,sessionid,securitycode,expiretime) values (?,?,?,?,?)",appid,requestIp,sessionId,code,localDateTime);
-        securityJdbcTemplate.update("delete from tempsecuritycode where expiretime < now()");
+        LocalDateTime now = LocalDateTime.now();
+        LocalDateTime localDateTime = now.plusSeconds(securitycodeeffective);
+        synchronized (codeResultCacheMap) {
+            remove(now);
+            codeResultCacheMap.put(sessionId + appid + requestIp, new CodeResultCache(code, localDateTime));
+        }
+
     }
 
-    public boolean check(String code, String sessionId, String appid,String requestIp) {
-        List<Map<String, Object>> map = securityJdbcTemplate.queryForList("select * from tempsecuritycode where securitycode=? and sessionid=? and appid=? and requestip=?", code, sessionId, appid, requestIp);
-        return Objects.nonNull(map) && !map.isEmpty();
+    public boolean check(@Nonnull String code,@Nonnull String sessionId,@Nonnull String appid,@Nonnull String requestIp) {
+        synchronized (codeResultCacheMap) {
+            CodeResultCache codeResultCache = codeResultCacheMap.get(sessionId + appid + requestIp);
+            return Objects.nonNull(codeResultCache) && codeResultCache.exprieTime().isAfter(LocalDateTime.now()) && codeResultCache.code().equals(code);
+        }
+    }
 
+    public void remove(@Nonnull String sessionId,@Nonnull String appid,@Nonnull String requestIp) {
+        synchronized (codeResultCacheMap) {
+            codeResultCacheMap.remove(sessionId + appid + requestIp);
+        }
     }
-    public void remove(String code, String sessionId, String appid,String requestIp) {
-         securityJdbcTemplate.update("delete from tempsecuritycode where securitycode=? and sessionid=? and appid=? and requestip=?", code, sessionId, appid, requestIp);
 
+    private void remove(LocalDateTime localDateTime) {
+
+        List<Map.Entry<String, CodeResultCache>> entries = codeResultCacheMap.entrySet().stream().filter(it -> it.getValue().exprieTime().isBefore(localDateTime)).toList();
+        for (Map.Entry<String, CodeResultCache> entry : entries) {
+            codeResultCacheMap.remove(entry.getKey());
+        }
     }
 }

+ 1 - 6
mainFactory/src/main/java/org/bfkj/utils/CommonUtil.java

@@ -14,8 +14,7 @@ import java.security.NoSuchAlgorithmException;
  */
 public final class CommonUtil {
 
-    public static String toMD5(String source) {
-        try {
+    public static String toMD5(String source) throws NoSuchAlgorithmException {
             MessageDigest md = MessageDigest.getInstance("MD5");
             md.update(source.getBytes());
             byte[] digest = md.digest();
@@ -28,10 +27,6 @@ public final class CommonUtil {
                 sb.append(hex);
             }
             return sb.toString();
-        } catch (NoSuchAlgorithmException e) {
-            e.printStackTrace();
-        }
-        return null;
     }
 
 }

+ 8 - 98
mainFactory/src/main/java/org/bfkj/utils/HttpRequestUtil.java

@@ -6,39 +6,12 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 
-public final class HttpRequestUtil {
-
-    public static String getUserToken( Map<String, String> header) {
-
-        return header.getOrDefault("userToken", header.get("Authorization"));
-    }
-
-    public static String getApplicationToken( Map<String, String> header) {
-
-        return header.getOrDefault("token", header.get("Authorization"));
-    }
-
-    public static String getAppId( Map<String, String> header) {
-        return header.get("appId");
-    }
-
-    public static String getServiceId( Map<String, Object> body) {
-
-        Object serviceId = body.get("serviceId");
-        if (serviceId == null) {
-            serviceId = body.get("id");
-        }
-
-
-        if (serviceId != null) {
-            return serviceId.toString();
-        }
-        return null;
-
-    }
+import static org.bfkj.envs.HttpEnv.REQUEST_IP;
+import static org.bfkj.envs.HttpEnv.SESSION_ID;
 
+public final class HttpRequestUtil {
 
-    public static  Map<String, Object> combineData(Map<String, Object> headers, Map<String, Object> body, HttpServletRequest httpRequest) {
+    public static Map<String, Object> combineData(Map<String, Object> headers, Map<String, Object> body, HttpServletRequest httpRequest) {
         Map<String, Object> requestData = new HashMap<>();
         if (Objects.nonNull(headers)) {
             requestData.putAll(headers);
@@ -47,80 +20,17 @@ public final class HttpRequestUtil {
             requestData.putAll(body);
         }
 
-        requestData.put("requestip", HttpRequestUtil.getRemoteAddr(httpRequest));
-        requestData.put("sessionid", HttpRequestUtil.getSessionId(httpRequest));
+        requestData.put(REQUEST_IP, HttpRequestUtil.getRemoteAddr(httpRequest));
+        requestData.put(SESSION_ID, HttpRequestUtil.getSessionId(httpRequest));
         return requestData;
     }
 
-    
-    public static String getUsername( Map<String, Object> body) {
-
-        Object username = body.get("username");
-        if (username != null) {
-            return username.toString();
-
-        }
-
-        throw new IllegalArgumentException("没有找到username 参数");
-    }
-
-    
-    public static String getUserId( Map<String, Object> body) {
-        Object userId = body.get("userId");
-        if (userId != null) {
-            return userId.toString();
-
-        }
-
-        throw new IllegalArgumentException("没有找到userId 参数");
-    }
-
-    
-    public static String getPassword( Map<String, Object> body) {
-        Object password = body.get("password");
-        return password.toString();
-    }
-
-
-    public static String getAppSecret( Map<String, String> header,  Map<String, Object> body) {
-        String appSecret = header.get("appSecret");
-        if (appSecret == null) {
-            Object appSecret1 = body.get("appSecret");
-            appSecret = appSecret1 != null ? appSecret1.toString() : null;
-        }
-
-        if (appSecret == null) {
-            throw new IllegalArgumentException("没有找到appSecret 参数");
-        } else {
-            return appSecret;
-        }
-    }
-
-    public static String getVersion( Map<String, String> header,  Map<String, Object> body) {
-        String version = header.get("version");
-        if (version == null) {
-            Object version1 = body.get("version");
-            version = version1 != null ? version1.toString() : null;
-        }
-
-        return version;
-    }
-
-    
-    public static String getWorkId( Map<String, Object> body) {
-        Object workId = body.get("workId");
-        if (workId != null) {
-            return workId.toString();
-        }
-
-        throw new IllegalArgumentException("没有找到workId 参数");
-    }
 
-    public static String getRemoteAddr( HttpServletRequest request) {
+    public static String getRemoteAddr(HttpServletRequest request) {
         return request.getRemoteAddr();
     }
 
-    public static String getSessionId( HttpServletRequest request) {
+    public static String getSessionId(HttpServletRequest request) {
         return request.getSession().getId();
     }
 }

+ 19 - 22
mainFactory/src/main/java/org/bfkj/utils/RandomGraphic.java

@@ -7,10 +7,7 @@ import javax.imageio.ImageIO;
 import java.awt.*;
 import java.awt.geom.AffineTransform;
 import java.awt.image.BufferedImage;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
+import java.io.*;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
 import java.util.Arrays;
@@ -38,21 +35,15 @@ public class RandomGraphic {
      * @param sources    验证码字符源
      */
 
-    public static Map<String, Object> generateVerifyCode(int verifySize, String sources) {
+    public static CodeResult generateVerifyCode(int verifySize, String sources) throws IOException {
         int codesLen = sources.length();
 
-        try {
             StringBuilder verifyCode = new StringBuilder(verifySize);
             for (int i = 0; i < verifySize; i++) {
                 verifyCode.append(sources.charAt(random.nextInt(codesLen - 1)));
             }
-            Map<String, Object> returnData = new HashMap<>();
-            returnData.put("verifyCode", verifyCode.toString());
-            returnData.put("verifyCodeImage", outputImage(116, 40, verifyCode.toString()));
-            return returnData;
-        } catch (IOException e) {
-            return null;
-        }
+            return new CodeResult(verifyCode.toString(), outputImage(116, 40, verifyCode.toString()));
+
     }
 
     /**
@@ -96,15 +87,19 @@ public class RandomGraphic {
         g2.setColor(getRandColor(100, 160));
         int fontSize = h - 4; //
 
-        Font font = null;
-        try {
-            File fontFile = new ClassPathResource("font/SourceHanSansSC-Regular-2.otf").getFile();
-            font = Font.createFont(Font.TRUETYPE_FONT, fontFile);
-        } catch (FontFormatException | FileNotFoundException e) {
-            font = new Font("Algerian", Font.ITALIC, fontSize);
-        }
+//        Font font = null;
+//        try {
+//            File fontFile = new ClassPathResource("font/SourceHanSansSC-Regular-2.otf").getFile();
+//            font = Font.createFont(Font.TRUETYPE_FONT, fontFile);
+//        } catch (FontFormatException | FileNotFoundException e) {
+//            font = new Font(Font.SANS_SERIF, Font.ITALIC, fontSize);
+//        }
+
+//        g2.setFont(font);
+//        Font font = g2.getFont();
+
+        g2.setFont(new Font(g2.getFont().getName(),Font.ITALIC,fontSize));
 
-        g2.setFont(font);
         char[] chars = code.toCharArray();
         for (int i = 0; i < verifySize; i++) {
             AffineTransform affine = new AffineTransform();
@@ -116,7 +111,7 @@ public class RandomGraphic {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         ImageIO.write(image, "GIF", out);
         byte[] b = out.toByteArray();
-        return Base64.encodeBase64String(b).replaceAll("[\\s*\t\n\r]", "");
+        return "data:image/gif;base64,"+ Base64.encodeBase64String(b).replaceAll("[\\s*\t\n\r]", "");
     }
 
     private static Color getRandColor(int fc, int bc) {
@@ -173,4 +168,6 @@ public class RandomGraphic {
             g.drawLine(i, (int) d + h1, i, h1);
         }
     }
+
+    public static record CodeResult(String verifyCode,String verifyCodeImage){}
 }

+ 15 - 0
mainFactory/src/test/java/org/bfkj/utils/RandomGraphicTest.java

@@ -0,0 +1,15 @@
+package org.bfkj.utils;
+
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class RandomGraphicTest {
+
+    @Test
+    public void generateVerifyCode() throws IOException {
+        RandomGraphic.CodeResult result = RandomGraphic.generateVerifyCode(4, "ABCDEFG");
+        System.out.println(result.verifyCodeImage());
+    }
+}