diff --git a/.editorconfig b/.editorconfig
index 25b312e..a3834f2 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,18 +1,18 @@
-# http://editorconfig.org
-root = true
-
-# 空格替代Tab缩进在各种编辑工具下效果一致
-[*]
-indent_style = space
-indent_size = 4
-charset = utf-8
-end_of_line = lf
-trim_trailing_whitespace = true
-insert_final_newline = true
-
-[*.{json,yml,yaml}]
-indent_size = 2
-
-[*.md]
-insert_final_newline = false
-trim_trailing_whitespace = false
+# http://editorconfig.org
+root = true
+
+# 空格替代Tab缩进在各种编辑工具下效果一致
+[*]
+indent_style = space
+indent_size = 4
+charset = utf-8
+end_of_line = lf
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.{json,yml,yaml}]
+indent_size = 2
+
+[*.md]
+insert_final_newline = false
+trim_trailing_whitespace = false
diff --git a/.gitignore b/.gitignore
index 0e70380..45d6b3b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,54 +1,54 @@
-######################################################################
-# Build Tools
-
-.gradle
-/build/
-!gradle/wrapper/gradle-wrapper.jar
-
-target/
-!.mvn/wrapper/maven-wrapper.jar
-
-######################################################################
-# IDE
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-
-### IntelliJ IDEA ###
-.idea
-.vscode
-.lingma
-*.iws
-*.iml
-*.ipr
-
-### JRebel ###
-rebel.xml
-
-### NetBeans ###
-nbproject/private/
-build/*
-nbbuild/
-nbdist/
-.nb-gradle/
-
-######################################################################
-# Others
-*.log
-*.xml.versionsBackup
-*.swp
-
-!*/build/*.java
-!*/build/*.html
-!*/build/*.xml
-
-.flattened-pom.xml
-/logs/
-/ruoyi-admin/logs/
-/.vscode/
-/.lingma/
+######################################################################
+# Build Tools
+
+.gradle
+/build/
+!gradle/wrapper/gradle-wrapper.jar
+
+target/
+!.mvn/wrapper/maven-wrapper.jar
+
+######################################################################
+# IDE
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+
+### IntelliJ IDEA ###
+.idea
+.vscode
+.lingma
+*.iws
+*.iml
+*.ipr
+
+### JRebel ###
+rebel.xml
+
+### NetBeans ###
+nbproject/private/
+build/*
+nbbuild/
+nbdist/
+.nb-gradle/
+
+######################################################################
+# Others
+*.log
+*.xml.versionsBackup
+*.swp
+
+!*/build/*.java
+!*/build/*.html
+!*/build/*.xml
+
+.flattened-pom.xml
+/logs/
+/ruoyi-admin/logs/
+/.vscode/
+/.lingma/
diff --git a/LICENSE b/LICENSE
index 32b3071..856e91f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,20 +1,20 @@
-The MIT License (MIT)
-
-Copyright (c) 2019 RuoYi-Vue-Plus
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+The MIT License (MIT)
+
+Copyright (c) 2019 RuoYi-Vue-Plus
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/bun.zip b/bun.zip
new file mode 100644
index 0000000..74d1006
Binary files /dev/null and b/bun.zip differ
diff --git a/node.zip b/node.zip
new file mode 100644
index 0000000..ca75abb
Binary files /dev/null and b/node.zip differ
diff --git a/pom.xml b/pom.xml
index 5c5fdbc..e2fb00e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,531 +1,531 @@
-
-
- 4.0.0
-
- org.dromara
- ruoyi-vue-plus
- ${revision}
-
- new-xgt
- 效果图业务系统
-
-
- 5.2.3
- 3.3.5
- UTF-8
- UTF-8
- 22
- 3.5.16
- 2.7.0
- 0.15.0
- 5.2.3
- 4.0.3
- 2.3
- 1.39.0
- 3.5.9
- 3.9.1
- 5.8.31
- 3.3.4
- 3.39.0
- 2.2.7
- 4.3.1
- 2.14.4
- 1.2.0
- 1.4.5
- 0.2.0
- 1.18.34
- 1.76
- 1.16.6
-
- 2.7.0
-
-
- 2.28.22
- 0.31.3
-
- 3.3.3
-
- 1.2.83
-
- 8.7.2-20241022
-
- 7.0.1
-
-
- 3.2.2
- 3.2.2
- 3.11.0
- 3.1.2
- 1.3.0
-
-
-
-
- local
-
-
- local
- info
- ruoyi
- 123456
-
-
-
- dev
-
-
- dev
- info
- ruoyi
- 123456
-
-
-
- true
-
-
-
- prod
-
- prod
- warn
- ruoyi
- 123456
-
-
-
-
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-dependencies
- ${spring-boot.version}
- pom
- import
-
-
-
-
- cn.hutool
- hutool-bom
- ${hutool.version}
- pom
- import
-
-
-
- org.flowable
- flowable-bom
- ${flowable.version}
- pom
- import
-
-
-
-
- me.zhyd.oauth
- JustAuth
- ${justauth.version}
-
-
-
-
- org.dromara
- ruoyi-common-bom
- ${revision}
- pom
- import
-
-
-
- org.springdoc
- springdoc-openapi-starter-webmvc-api
- ${springdoc.version}
-
-
-
- com.github.therapi
- therapi-runtime-javadoc
- ${therapi-javadoc.version}
-
-
-
- org.projectlombok
- lombok
- ${lombok.version}
-
-
-
- org.apache.poi
- poi
- ${poi.version}
-
-
- org.apache.poi
- poi-ooxml
- ${poi.version}
-
-
- com.alibaba
- easyexcel
- ${easyexcel.version}
-
-
- org.apache.poi
- poi-ooxml-schemas
-
-
-
-
-
-
- org.apache.velocity
- velocity-engine-core
- ${velocity.version}
-
-
-
-
- cn.dev33
- sa-token-spring-boot3-starter
- ${satoken.version}
-
-
-
- cn.dev33
- sa-token-jwt
- ${satoken.version}
-
-
- cn.hutool
- hutool-all
-
-
-
-
- cn.dev33
- sa-token-core
- ${satoken.version}
-
-
-
-
- com.baomidou
- dynamic-datasource-spring-boot3-starter
- ${dynamic-ds.version}
-
-
-
- org.mybatis
- mybatis
- ${mybatis.version}
-
-
-
- com.baomidou
- mybatis-plus-spring-boot3-starter
- ${mybatis-plus.version}
-
-
-
- com.baomidou
- mybatis-plus-jsqlparser
- ${mybatis-plus.version}
-
-
-
- com.baomidou
- mybatis-plus-annotation
- ${mybatis-plus.version}
-
-
-
-
- p6spy
- p6spy
- ${p6spy.version}
-
-
-
-
- software.amazon.awssdk
- s3
- ${aws.sdk.version}
-
-
-
- software.amazon.awssdk.crt
- aws-crt
- ${aws.crt.version}
-
-
-
- software.amazon.awssdk
- s3-transfer-manager
- ${aws.sdk.version}
-
-
-
- org.dromara.sms4j
- sms4j-spring-boot-starter
- ${sms4j.version}
-
-
-
- de.codecentric
- spring-boot-admin-starter-server
- ${spring-boot-admin.version}
-
-
- de.codecentric
- spring-boot-admin-starter-client
- ${spring-boot-admin.version}
-
-
-
-
- org.redisson
- redisson-spring-boot-starter
- ${redisson.version}
-
-
-
- com.baomidou
- lock4j-redisson-spring-boot-starter
- ${lock4j.version}
-
-
-
-
- com.aizuda
- snail-job-client-starter
- ${snailjob.version}
-
-
- com.aizuda
- snail-job-client-job-core
- ${snailjob.version}
-
-
-
- com.alibaba
- transmittable-thread-local
- ${alibaba-ttl.version}
-
-
-
-
- org.bouncycastle
- bcprov-jdk15to18
- ${bouncycastle.version}
-
-
-
- io.github.linpeilie
- mapstruct-plus-spring-boot-starter
- ${mapstruct-plus.version}
-
-
-
-
- org.lionsoul
- ip2region
- ${ip2region.version}
-
-
-
- commons-io
- commons-io
- 2.15.0
-
-
-
- com.alibaba
- fastjson
- ${fastjson.version}
-
-
-
- org.dromara
- ruoyi-system
- ${revision}
-
-
-
- org.dromara
- ruoyi-job
- ${revision}
-
-
-
- org.dromara
- ruoyi-generator
- ${revision}
-
-
-
- org.dromara
- ruoyi-demo
- ${revision}
-
-
-
-
- org.dromara
- ruoyi-workflow
- ${revision}
-
-
-
- org.dromara
- ruoyi-work
- ${revision}
-
-
-
-
-
-
- ruoyi-admin
- ruoyi-common
- ruoyi-extend
- ruoyi-modules
-
- pom
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
- ${java.version}
- ${java.version}
- ${project.build.sourceEncoding}
-
-
- com.github.therapi
- therapi-runtime-javadoc-scribe
- ${therapi-javadoc.version}
-
-
- org.projectlombok
- lombok
- ${lombok.version}
-
-
- org.springframework.boot
- spring-boot-configuration-processor
- ${spring-boot.version}
-
-
- io.github.linpeilie
- mapstruct-plus-processor
- ${mapstruct-plus.version}
-
-
- org.projectlombok
- lombok-mapstruct-binding
- ${mapstruct-plus.lombok.version}
-
-
-
- -parameters
-
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- ${maven-surefire-plugin.version}
-
- -Dfile.encoding=UTF-8
-
- ${profiles.active}
-
- exclude
-
-
-
-
- org.codehaus.mojo
- flatten-maven-plugin
- ${flatten-maven-plugin.version}
-
- true
- resolveCiFriendliesOnly
-
-
-
- flatten
- process-resources
-
- flatten
-
-
-
- flatten.clean
- clean
-
- clean
-
-
-
-
-
-
-
- src/main/resources
-
- false
-
-
- src/main/resources
-
-
- application*
- bootstrap*
- banner*
-
-
- true
-
-
-
-
-
-
- public
- huawei nexus
- https://mirrors.huaweicloud.com/repository/maven/
-
- true
-
-
-
-
-
-
- public
- huawei nexus
- https://mirrors.huaweicloud.com/repository/maven/
-
- true
-
-
- false
-
-
-
-
-
-
-
+
+
+ 4.0.0
+
+ org.dromara
+ ruoyi-vue-plus
+ ${revision}
+
+ new-xgt
+ 效果图业务系统
+
+
+ 5.2.3
+ 3.3.5
+ UTF-8
+ UTF-8
+ 22
+ 3.5.16
+ 2.7.0
+ 0.15.0
+ 5.2.3
+ 4.0.3
+ 2.3
+ 1.39.0
+ 3.5.9
+ 3.9.1
+ 5.8.31
+ 3.3.4
+ 3.39.0
+ 2.2.7
+ 4.3.1
+ 2.14.4
+ 1.2.0
+ 1.4.5
+ 0.2.0
+ 1.18.34
+ 1.76
+ 1.16.6
+
+ 2.7.0
+
+
+ 2.28.22
+ 0.31.3
+
+ 3.3.3
+
+ 1.2.83
+
+ 8.7.2-20241022
+
+ 7.0.1
+
+
+ 3.2.2
+ 3.2.2
+ 3.11.0
+ 3.1.2
+ 1.3.0
+
+
+
+
+ local
+
+
+ local
+ info
+ ruoyi
+ 123456
+
+
+
+ dev
+
+
+ dev
+ info
+ ruoyi
+ 123456
+
+
+
+ true
+
+
+
+ prod
+
+ prod
+ warn
+ ruoyi
+ 123456
+
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+ cn.hutool
+ hutool-bom
+ ${hutool.version}
+ pom
+ import
+
+
+
+ org.flowable
+ flowable-bom
+ ${flowable.version}
+ pom
+ import
+
+
+
+
+ me.zhyd.oauth
+ JustAuth
+ ${justauth.version}
+
+
+
+
+ org.dromara
+ ruoyi-common-bom
+ ${revision}
+ pom
+ import
+
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-api
+ ${springdoc.version}
+
+
+
+ com.github.therapi
+ therapi-runtime-javadoc
+ ${therapi-javadoc.version}
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+
+ org.apache.poi
+ poi
+ ${poi.version}
+
+
+ org.apache.poi
+ poi-ooxml
+ ${poi.version}
+
+
+ com.alibaba
+ easyexcel
+ ${easyexcel.version}
+
+
+ org.apache.poi
+ poi-ooxml-schemas
+
+
+
+
+
+
+ org.apache.velocity
+ velocity-engine-core
+ ${velocity.version}
+
+
+
+
+ cn.dev33
+ sa-token-spring-boot3-starter
+ ${satoken.version}
+
+
+
+ cn.dev33
+ sa-token-jwt
+ ${satoken.version}
+
+
+ cn.hutool
+ hutool-all
+
+
+
+
+ cn.dev33
+ sa-token-core
+ ${satoken.version}
+
+
+
+
+ com.baomidou
+ dynamic-datasource-spring-boot3-starter
+ ${dynamic-ds.version}
+
+
+
+ org.mybatis
+ mybatis
+ ${mybatis.version}
+
+
+
+ com.baomidou
+ mybatis-plus-spring-boot3-starter
+ ${mybatis-plus.version}
+
+
+
+ com.baomidou
+ mybatis-plus-jsqlparser
+ ${mybatis-plus.version}
+
+
+
+ com.baomidou
+ mybatis-plus-annotation
+ ${mybatis-plus.version}
+
+
+
+
+ p6spy
+ p6spy
+ ${p6spy.version}
+
+
+
+
+ software.amazon.awssdk
+ s3
+ ${aws.sdk.version}
+
+
+
+ software.amazon.awssdk.crt
+ aws-crt
+ ${aws.crt.version}
+
+
+
+ software.amazon.awssdk
+ s3-transfer-manager
+ ${aws.sdk.version}
+
+
+
+ org.dromara.sms4j
+ sms4j-spring-boot-starter
+ ${sms4j.version}
+
+
+
+ de.codecentric
+ spring-boot-admin-starter-server
+ ${spring-boot-admin.version}
+
+
+ de.codecentric
+ spring-boot-admin-starter-client
+ ${spring-boot-admin.version}
+
+
+
+
+ org.redisson
+ redisson-spring-boot-starter
+ ${redisson.version}
+
+
+
+ com.baomidou
+ lock4j-redisson-spring-boot-starter
+ ${lock4j.version}
+
+
+
+
+ com.aizuda
+ snail-job-client-starter
+ ${snailjob.version}
+
+
+ com.aizuda
+ snail-job-client-job-core
+ ${snailjob.version}
+
+
+
+ com.alibaba
+ transmittable-thread-local
+ ${alibaba-ttl.version}
+
+
+
+
+ org.bouncycastle
+ bcprov-jdk15to18
+ ${bouncycastle.version}
+
+
+
+ io.github.linpeilie
+ mapstruct-plus-spring-boot-starter
+ ${mapstruct-plus.version}
+
+
+
+
+ org.lionsoul
+ ip2region
+ ${ip2region.version}
+
+
+
+ commons-io
+ commons-io
+ 2.15.0
+
+
+
+ com.alibaba
+ fastjson
+ ${fastjson.version}
+
+
+
+ org.dromara
+ ruoyi-system
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-job
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-generator
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-demo
+ ${revision}
+
+
+
+
+ org.dromara
+ ruoyi-workflow
+ ${revision}
+
+
+
+ org.dromara
+ ruoyi-work
+ ${revision}
+
+
+
+
+
+
+ ruoyi-admin
+ ruoyi-common
+ ruoyi-extend
+ ruoyi-modules
+
+ pom
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${java.version}
+ ${java.version}
+ ${project.build.sourceEncoding}
+
+
+ com.github.therapi
+ therapi-runtime-javadoc-scribe
+ ${therapi-javadoc.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ ${spring-boot.version}
+
+
+ io.github.linpeilie
+ mapstruct-plus-processor
+ ${mapstruct-plus.version}
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+ ${mapstruct-plus.lombok.version}
+
+
+
+ -parameters
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+ -Dfile.encoding=UTF-8
+
+ ${profiles.active}
+
+ exclude
+
+
+
+
+ org.codehaus.mojo
+ flatten-maven-plugin
+ ${flatten-maven-plugin.version}
+
+ true
+ resolveCiFriendliesOnly
+
+
+
+ flatten
+ process-resources
+
+ flatten
+
+
+
+ flatten.clean
+ clean
+
+ clean
+
+
+
+
+
+
+
+ src/main/resources
+
+ false
+
+
+ src/main/resources
+
+
+ application*
+ bootstrap*
+ banner*
+
+
+ true
+
+
+
+
+
+
+ public
+ huawei nexus
+ https://mirrors.huaweicloud.com/repository/maven/
+
+ true
+
+
+
+
+
+
+ public
+ huawei nexus
+ https://mirrors.huaweicloud.com/repository/maven/
+
+ true
+
+
+ false
+
+
+
+
+
+
+
diff --git a/ruoyi-admin/Dockerfile b/ruoyi-admin/Dockerfile
index e0be8ae..4886e0c 100644
--- a/ruoyi-admin/Dockerfile
+++ b/ruoyi-admin/Dockerfile
@@ -1,28 +1,28 @@
-# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
-FROM bellsoft/liberica-openjdk-debian:17.0.11-cds
-#FROM bellsoft/liberica-openjdk-debian:21.0.5-cds
-#FROM findepi/graalvm:java17-native
-
-LABEL maintainer="Lion Li"
-
-RUN mkdir -p /ruoyi/server/logs \
- /ruoyi/server/temp \
- /ruoyi/skywalking/agent
-
-WORKDIR /ruoyi/server
-
-ENV SERVER_PORT=8080 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
-
-EXPOSE ${SERVER_PORT}
-
-ADD ./target/ruoyi-admin.jar ./app.jar
-
-SHELL ["/bin/bash", "-c"]
-
-ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \
- # 应用名称 如果想区分集群节点监控 改成不同的名称即可
- #-Dskywalking.agent.service_name=ruoyi-server \
- #-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \
- -XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \
- -jar app.jar
-
+# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
+FROM bellsoft/liberica-openjdk-debian:17.0.11-cds
+#FROM bellsoft/liberica-openjdk-debian:21.0.5-cds
+#FROM findepi/graalvm:java17-native
+
+LABEL maintainer="Lion Li"
+
+RUN mkdir -p /ruoyi/server/logs \
+ /ruoyi/server/temp \
+ /ruoyi/skywalking/agent
+
+WORKDIR /ruoyi/server
+
+ENV SERVER_PORT=8080 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
+
+EXPOSE ${SERVER_PORT}
+
+ADD ./target/ruoyi-admin.jar ./app.jar
+
+SHELL ["/bin/bash", "-c"]
+
+ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \
+ # 应用名称 如果想区分集群节点监控 改成不同的名称即可
+ #-Dskywalking.agent.service_name=ruoyi-server \
+ #-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \
+ -XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \
+ -jar app.jar
+
diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 4ddee14..3d691d4 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -1,146 +1,155 @@
-
-
-
- ruoyi-vue-plus
- org.dromara
- ${revision}
-
- 4.0.0
- jar
- xgt-admin
-
-
- web服务入口
-
-
-
-
+
+
+
+ ruoyi-vue-plus
+ org.dromara
+ ${revision}
+
+ 4.0.0
+ jar
+ xgt-admin
+
+
+ web服务入口
+
+
+
+
com.mysql
mysql-connector-j
+ 8.4.0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.dromara
- ruoyi-common-doc
-
-
-
- org.dromara
- ruoyi-common-social
-
-
-
- org.dromara
- ruoyi-common-ratelimiter
-
-
-
- org.dromara
- ruoyi-common-mail
-
-
-
- org.dromara
- ruoyi-system
-
-
-
- org.dromara
- ruoyi-job
-
-
-
-
- org.dromara
- ruoyi-generator
-
-
-
- org.dromara
- ruoyi-work
-
-
-
- de.codecentric
- spring-boot-admin-starter-client
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.dromara
+ ruoyi-common-doc
+
+
+
+ org.dromara
+ ruoyi-common-social
+
+
+
+ org.dromara
+ ruoyi-common-ratelimiter
+
+
+
+ org.dromara
+ ruoyi-common-mail
+
+
+
+ org.dromara
+ ruoyi-system
+
+
+
+ org.dromara
+ ruoyi-job
+
+
+
+
+ org.dromara
+ ruoyi-generator
+
+
+
+ org.dromara
+ ruoyi-work
+
+
+
+ de.codecentric
+ spring-boot-admin-starter-client
+
+
org.springframework.boot
spring-boot-starter-test
test
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ${project.artifactId}
-
-
- org.springframework.boot
- spring-boot-maven-plugin
- ${spring-boot.version}
-
-
-
- repackage
-
-
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
- ${maven-jar-plugin.version}
-
-
- org.apache.maven.plugins
- maven-war-plugin
- ${maven-war-plugin.version}
-
- false
- ${project.artifactId}
-
-
-
-
-
-
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${project.artifactId}
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+ repackage
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ ${maven-jar-plugin.version}
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ ${maven-war-plugin.version}
+
+ false
+ ${project.artifactId}
+
+
+
+
+
+
diff --git a/ruoyi-admin/src/main/java/org/dromara/XgtAdminApplication.java b/ruoyi-admin/src/main/java/org/dromara/XgtAdminApplication.java
index bd35d05..b38d507 100644
--- a/ruoyi-admin/src/main/java/org/dromara/XgtAdminApplication.java
+++ b/ruoyi-admin/src/main/java/org/dromara/XgtAdminApplication.java
@@ -1,23 +1,23 @@
-package org.dromara;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
-
-/**
- * 启动程序
- *
- * @author Lion Li
- */
-
-@SpringBootApplication
-public class XgtAdminApplication {
-
- public static void main(String[] args) {
- SpringApplication application = new SpringApplication(XgtAdminApplication.class);
- application.setApplicationStartup(new BufferingApplicationStartup(2048));
- application.run(args);
- System.out.println("(♥◠‿◠)ノ゙ 效果图业务系统启动成功 ლ(´ڡ`ლ)゙");
- }
-
-}
+package org.dromara;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
+
+/**
+ * 启动程序
+ *
+ * @author Lion Li
+ */
+
+@SpringBootApplication
+public class XgtAdminApplication {
+
+ public static void main(String[] args) {
+ SpringApplication application = new SpringApplication(XgtAdminApplication.class);
+ application.setApplicationStartup(new BufferingApplicationStartup(2048));
+ application.run(args);
+ System.out.println("(♥◠‿◠)ノ゙ 效果图业务系统启动成功 ლ(´ڡ`ლ)゙");
+ }
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/XgtAdminServletInitializer.java b/ruoyi-admin/src/main/java/org/dromara/XgtAdminServletInitializer.java
index 20a2886..86e9c37 100644
--- a/ruoyi-admin/src/main/java/org/dromara/XgtAdminServletInitializer.java
+++ b/ruoyi-admin/src/main/java/org/dromara/XgtAdminServletInitializer.java
@@ -1,18 +1,18 @@
-package org.dromara;
-
-import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
-
-/**
- * web容器中进行部署
- *
- * @author Lion Li
- */
-public class XgtAdminServletInitializer extends SpringBootServletInitializer {
-
- @Override
- protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
- return application.sources(XgtAdminApplication.class);
- }
-
-}
+package org.dromara;
+
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+/**
+ * web容器中进行部署
+ *
+ * @author Lion Li
+ */
+public class XgtAdminServletInitializer extends SpringBootServletInitializer {
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(XgtAdminApplication.class);
+ }
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/HttpContextUtils.java b/ruoyi-admin/src/main/java/org/dromara/web/common/HttpContextUtils.java
index db7d3ab..3bf352a 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/HttpContextUtils.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/HttpContextUtils.java
@@ -1,36 +1,36 @@
-/*
- * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
- *
- * https://www.mall4j.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-
-package org.dromara.web.common;
-
-import jakarta.servlet.http.HttpServletRequest;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
-
-/**
- * @author lanhai
- */
-public class HttpContextUtils {
-
- public static HttpServletRequest getHttpServletRequest() {
- return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
- }
-
- public static String getDomain(){
- HttpServletRequest request = getHttpServletRequest();
- StringBuffer url = request.getRequestURL();
- return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
- }
-
- public static String getOrigin(){
- HttpServletRequest request = getHttpServletRequest();
- return request.getHeader("Origin");
- }
-}
+/*
+ * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
+ *
+ * https://www.mall4j.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+
+package org.dromara.web.common;
+
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+/**
+ * @author lanhai
+ */
+public class HttpContextUtils {
+
+ public static HttpServletRequest getHttpServletRequest() {
+ return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+ }
+
+ public static String getDomain(){
+ HttpServletRequest request = getHttpServletRequest();
+ StringBuffer url = request.getRequestURL();
+ return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
+ }
+
+ public static String getOrigin(){
+ HttpServletRequest request = getHttpServletRequest();
+ return request.getHeader("Origin");
+ }
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/OauthCacheNames.java b/ruoyi-admin/src/main/java/org/dromara/web/common/OauthCacheNames.java
index a2d7572..499b845 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/OauthCacheNames.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/OauthCacheNames.java
@@ -1,38 +1,38 @@
-package org.dromara.web.common;
-
-/**
- * @author 菠萝凤梨
- * @date 2022/3/28 14:32
- */
-public interface OauthCacheNames {
-
- /**
- * oauth 授权相关key
- */
- String OAUTH_PREFIX = "mall4j_oauth:";
-
- /**
- * token 授权相关key
- */
- String OAUTH_TOKEN_PREFIX = OAUTH_PREFIX + "token:";
-
- /**
- * 保存token 缓存使用key
- */
- String ACCESS = OAUTH_TOKEN_PREFIX + "access:";
-
- /**
- * 刷新token 缓存使用key
- */
- String REFRESH_TO_ACCESS = OAUTH_TOKEN_PREFIX + "refresh_to_access:";
-
- /**
- * 根据uid获取保存的token key缓存使用的key
- */
- String UID_TO_ACCESS = OAUTH_TOKEN_PREFIX + "uid_to_access:";
-
- /**
- * 保存token的用户信息使用的key
- */
- String USER_INFO = OAUTH_TOKEN_PREFIX + "user_info:";
-}
+package org.dromara.web.common;
+
+/**
+ * @author 菠萝凤梨
+ * @date 2022/3/28 14:32
+ */
+public interface OauthCacheNames {
+
+ /**
+ * oauth 授权相关key
+ */
+ String OAUTH_PREFIX = "mall4j_oauth:";
+
+ /**
+ * token 授权相关key
+ */
+ String OAUTH_TOKEN_PREFIX = OAUTH_PREFIX + "token:";
+
+ /**
+ * 保存token 缓存使用key
+ */
+ String ACCESS = OAUTH_TOKEN_PREFIX + "access:";
+
+ /**
+ * 刷新token 缓存使用key
+ */
+ String REFRESH_TO_ACCESS = OAUTH_TOKEN_PREFIX + "refresh_to_access:";
+
+ /**
+ * 根据uid获取保存的token key缓存使用的key
+ */
+ String UID_TO_ACCESS = OAUTH_TOKEN_PREFIX + "uid_to_access:";
+
+ /**
+ * 保存token的用户信息使用的key
+ */
+ String USER_INFO = OAUTH_TOKEN_PREFIX + "user_info:";
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/PageParam.java b/ruoyi-admin/src/main/java/org/dromara/web/common/PageParam.java
index b6524db..b4111a9 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/PageParam.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/PageParam.java
@@ -1,128 +1,128 @@
-/*
- * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
- *
- * https://www.mall4j.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-
-package org.dromara.web.common;
-
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import io.swagger.v3.oas.annotations.Hidden;
-import io.swagger.v3.oas.annotations.media.Schema;
-import org.springdoc.core.annotations.ParameterObject;
-
-import java.util.List;
-
-/**
- * @author lanhai
- */
-@Schema
-@ParameterObject
-public class PageParam extends Page {
-
-
- /**
- * 每页显示条数,默认 10
- */
- @Schema(description = "每页大小,默认10")
- private long size = 10;
-
- /**
- * 当前页
- */
- @Schema(description = "当前页,默认1")
- private long current = 1;
-
- /**
- * 查询数据列表
- */
- @Hidden
- private List records;
- /**
- * 总数
- */
- @Hidden
- private long total = 0;
-
-
- /**
- * 是否进行 count 查询
- */
- @JsonIgnore
- private boolean isSearchCount = true;
-
- @JsonIgnore
- private String countId;
- @JsonIgnore
- private Long maxLimit;
- @JsonIgnore
- private boolean optimizeCountSql;
-
- @Override
- public List getRecords() {
- return this.records;
- }
-
- @Override
- public Page setRecords(List records) {
- this.records = records;
- return this;
- }
-
- @Override
- public long getTotal() {
- return this.total;
- }
-
- @Override
- public Page setTotal(long total) {
- this.total = total;
- return this;
- }
-
- @JsonIgnore
- public boolean getSearchCount() {
- if (total < 0) {
- return false;
- }
- return isSearchCount;
- }
-
- @Override
- public Page setSearchCount(boolean isSearchCount) {
- this.isSearchCount = isSearchCount;
- return this;
- }
-
- @Override
- public long getSize() {
- return this.size;
- }
-
- @Override
- public Page setSize(long size) {
- int maxSize = 100;
- if (size > maxSize) {
- this.size = maxSize;
- } else {
- this.size = size;
- }
- return this;
- }
-
- @Override
- public long getCurrent() {
- return this.current;
- }
-
- @Override
- public Page setCurrent(long current) {
- this.current = current;
- return this;
- }
-}
+/*
+ * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
+ *
+ * https://www.mall4j.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+
+package org.dromara.web.common;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.v3.oas.annotations.Hidden;
+import io.swagger.v3.oas.annotations.media.Schema;
+import org.springdoc.core.annotations.ParameterObject;
+
+import java.util.List;
+
+/**
+ * @author lanhai
+ */
+@Schema
+@ParameterObject
+public class PageParam extends Page {
+
+
+ /**
+ * 每页显示条数,默认 10
+ */
+ @Schema(description = "每页大小,默认10")
+ private long size = 10;
+
+ /**
+ * 当前页
+ */
+ @Schema(description = "当前页,默认1")
+ private long current = 1;
+
+ /**
+ * 查询数据列表
+ */
+ @Hidden
+ private List records;
+ /**
+ * 总数
+ */
+ @Hidden
+ private long total = 0;
+
+
+ /**
+ * 是否进行 count 查询
+ */
+ @JsonIgnore
+ private boolean isSearchCount = true;
+
+ @JsonIgnore
+ private String countId;
+ @JsonIgnore
+ private Long maxLimit;
+ @JsonIgnore
+ private boolean optimizeCountSql;
+
+ @Override
+ public List getRecords() {
+ return this.records;
+ }
+
+ @Override
+ public Page setRecords(List records) {
+ this.records = records;
+ return this;
+ }
+
+ @Override
+ public long getTotal() {
+ return this.total;
+ }
+
+ @Override
+ public Page setTotal(long total) {
+ this.total = total;
+ return this;
+ }
+
+ @JsonIgnore
+ public boolean getSearchCount() {
+ if (total < 0) {
+ return false;
+ }
+ return isSearchCount;
+ }
+
+ @Override
+ public Page setSearchCount(boolean isSearchCount) {
+ this.isSearchCount = isSearchCount;
+ return this;
+ }
+
+ @Override
+ public long getSize() {
+ return this.size;
+ }
+
+ @Override
+ public Page setSize(long size) {
+ int maxSize = 100;
+ if (size > maxSize) {
+ this.size = maxSize;
+ } else {
+ this.size = size;
+ }
+ return this;
+ }
+
+ @Override
+ public long getCurrent() {
+ return this.current;
+ }
+
+ @Override
+ public Page setCurrent(long current) {
+ this.current = current;
+ return this;
+ }
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/PasswordManager.java b/ruoyi-admin/src/main/java/org/dromara/web/common/PasswordManager.java
index c652534..08f3706 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/PasswordManager.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/PasswordManager.java
@@ -1,53 +1,53 @@
-/*
- * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
- *
- * https://www.mall4j.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-package org.dromara.web.common;
-
-import cn.hutool.crypto.SecureUtil;
-import cn.hutool.crypto.symmetric.AES;
-import org.dromara.common.core.exception.user.UserException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.nio.charset.StandardCharsets;
-
-/**
- * @author 菠萝凤梨
- * @date 2022/1/19 16:02
- */
-@Component
-public class PasswordManager {
- private static final Logger logger = LoggerFactory.getLogger(PasswordManager.class);
-
- /**
- * 用于aes签名的key,16位
- */
- @Value("${auth.password.signKey:-mall4j-password}")
- public String passwordSignKey;
-
- public String decryptPassword(String data) {
- // 在使用oracle的JDK时,JAR包必须签署特殊的证书才能使用。
- // 解决方案 1.使用openJDK或者非oracle的JDK(建议) 2.添加证书
- // hutool的aes报错可以打开下面那段代码
- SecureUtil.disableBouncyCastle();
- AES aes = new AES(passwordSignKey.getBytes(StandardCharsets.UTF_8));
- String decryptStr;
- String decryptPassword;
- try {
- decryptStr = aes.decryptStr(data);
- decryptPassword = decryptStr.substring(13);
- } catch (Exception e) {
- logger.error("Exception:", e);
- throw new UserException("AES解密错误", e);
- }
- return decryptPassword;
- }
-}
+/*
+ * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
+ *
+ * https://www.mall4j.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+package org.dromara.web.common;
+
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.symmetric.AES;
+import org.dromara.common.core.exception.user.UserException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * @author 菠萝凤梨
+ * @date 2022/1/19 16:02
+ */
+@Component
+public class PasswordManager {
+ private static final Logger logger = LoggerFactory.getLogger(PasswordManager.class);
+
+ /**
+ * 用于aes签名的key,16位
+ */
+ @Value("${auth.password.signKey:-mall4j-password}")
+ public String passwordSignKey;
+
+ public String decryptPassword(String data) {
+ // 在使用oracle的JDK时,JAR包必须签署特殊的证书才能使用。
+ // 解决方案 1.使用openJDK或者非oracle的JDK(建议) 2.添加证书
+ // hutool的aes报错可以打开下面那段代码
+ SecureUtil.disableBouncyCastle();
+ AES aes = new AES(passwordSignKey.getBytes(StandardCharsets.UTF_8));
+ String decryptStr;
+ String decryptPassword;
+ try {
+ decryptStr = aes.decryptStr(data);
+ decryptPassword = decryptStr.substring(13);
+ } catch (Exception e) {
+ logger.error("Exception:", e);
+ throw new UserException("AES解密错误", e);
+ }
+ return decryptPassword;
+ }
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/ResponseEnum.java b/ruoyi-admin/src/main/java/org/dromara/web/common/ResponseEnum.java
index 6e52e09..b3855ed 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/ResponseEnum.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/ResponseEnum.java
@@ -1,69 +1,69 @@
-/*
- * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
- *
- * https://www.mall4j.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-package org.dromara.web.common;
-
-/**
- * @author FrozenWatermelon
- * @date 2020/7/9
- */
-public enum ResponseEnum {
-
- /**
- * ok
- */
- OK("00000", "ok"),
- SHOW_FAIL("A00001", ""),
-
- /**
- * 用于直接显示提示用户的错误,内容由输入内容决定
- */
-
- /**
- * 用于直接显示提示系统的成功,内容由输入内容决定
- */
- SHOW_SUCCESS("A00002", ""),
-
- /**
- * 未授权
- */
- UNAUTHORIZED("A00004", "Unauthorized"),
-
- /**
- * 服务器出了点小差
- */
- EXCEPTION("A00005", "服务器出了点小差"),
- /**
- * 方法参数没有校验,内容由输入内容决定
- */
- METHOD_ARGUMENT_NOT_VALID("A00014", "方法参数没有校验");
-
- private final String code;
-
- private final String msg;
-
- public String value() {
- return code;
- }
-
- public String getMsg() {
- return msg;
- }
-
- ResponseEnum(String code, String msg) {
- this.code = code;
- this.msg = msg;
- }
-
- @Override
- public String toString() {
- return "ResponseEnum{" + "code='" + code + '\'' + ", msg='" + msg + '\'' + "} " + super.toString();
- }
-
-}
+/*
+ * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
+ *
+ * https://www.mall4j.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+package org.dromara.web.common;
+
+/**
+ * @author FrozenWatermelon
+ * @date 2020/7/9
+ */
+public enum ResponseEnum {
+
+ /**
+ * ok
+ */
+ OK("00000", "ok"),
+ SHOW_FAIL("A00001", ""),
+
+ /**
+ * 用于直接显示提示用户的错误,内容由输入内容决定
+ */
+
+ /**
+ * 用于直接显示提示系统的成功,内容由输入内容决定
+ */
+ SHOW_SUCCESS("A00002", ""),
+
+ /**
+ * 未授权
+ */
+ UNAUTHORIZED("A00004", "Unauthorized"),
+
+ /**
+ * 服务器出了点小差
+ */
+ EXCEPTION("A00005", "服务器出了点小差"),
+ /**
+ * 方法参数没有校验,内容由输入内容决定
+ */
+ METHOD_ARGUMENT_NOT_VALID("A00014", "方法参数没有校验");
+
+ private final String code;
+
+ private final String msg;
+
+ public String value() {
+ return code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ ResponseEnum(String code, String msg) {
+ this.code = code;
+ this.msg = msg;
+ }
+
+ @Override
+ public String toString() {
+ return "ResponseEnum{" + "code='" + code + '\'' + ", msg='" + msg + '\'' + "} " + super.toString();
+ }
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/SecurityUtils.java b/ruoyi-admin/src/main/java/org/dromara/web/common/SecurityUtils.java
index 14ed80a..f227b82 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/SecurityUtils.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/SecurityUtils.java
@@ -1,49 +1,49 @@
-package org.dromara.web.common;
-
-
-import lombok.experimental.UtilityClass;
-
-/**
- * @author LGH
- */
-@UtilityClass
-public class SecurityUtils {
-
- private static final String USER_REQUEST = "/api/";
-
- /**
- * 获取用户
- */
- public YamiUser getUser() {
- if (!HttpContextUtils.getHttpServletRequest().getRequestURI().startsWith(USER_REQUEST)) {
- // 用户相关的请求,应该以/p开头!!!
- throw new RuntimeException("登录过期或已失效");
- }
-
- String accessToken = HttpContextUtils.getHttpServletRequest().getHeader("accessToken");
- TokenStore tokenStore = new TokenStore();
- UserInfoInTokenBO userInfoInTokenBO = tokenStore.getUserInfoByAccessToken(accessToken,false);
-
- YamiUser yamiUser = new YamiUser();
- yamiUser.setUserId(userInfoInTokenBO.getUserId());
- yamiUser.setBizUserId(userInfoInTokenBO.getBizUserId());
- yamiUser.setEnabled(userInfoInTokenBO.getEnabled());
- yamiUser.setShopId(userInfoInTokenBO.getShopId());
- yamiUser.setStationId(userInfoInTokenBO.getOtherId());
- return yamiUser;
- }
-
- /**
- * 获取用户ID
- */
- public Long getUserInfo() {
- Long userId = null;
- try {
- userId = getUser().getUserId();
- } catch (RuntimeException e) {
- // 处理异常
- System.out.println(e.getMessage());
- }
- return userId;
- }
-}
+package org.dromara.web.common;
+
+
+import lombok.experimental.UtilityClass;
+
+/**
+ * @author LGH
+ */
+@UtilityClass
+public class SecurityUtils {
+
+ private static final String USER_REQUEST = "/api/";
+
+ /**
+ * 获取用户
+ */
+ public YamiUser getUser() {
+ if (!HttpContextUtils.getHttpServletRequest().getRequestURI().startsWith(USER_REQUEST)) {
+ // 用户相关的请求,应该以/p开头!!!
+ throw new RuntimeException("登录过期或已失效");
+ }
+
+ String accessToken = HttpContextUtils.getHttpServletRequest().getHeader("accessToken");
+ TokenStore tokenStore = new TokenStore();
+ UserInfoInTokenBO userInfoInTokenBO = tokenStore.getUserInfoByAccessToken(accessToken,false);
+
+ YamiUser yamiUser = new YamiUser();
+ yamiUser.setUserId(userInfoInTokenBO.getUserId());
+ yamiUser.setBizUserId(userInfoInTokenBO.getBizUserId());
+ yamiUser.setEnabled(userInfoInTokenBO.getEnabled());
+ yamiUser.setShopId(userInfoInTokenBO.getShopId());
+ yamiUser.setStationId(userInfoInTokenBO.getOtherId());
+ return yamiUser;
+ }
+
+ /**
+ * 获取用户ID
+ */
+ public Long getUserInfo() {
+ Long userId = null;
+ try {
+ userId = getUser().getUserId();
+ } catch (RuntimeException e) {
+ // 处理异常
+ System.out.println(e.getMessage());
+ }
+ return userId;
+ }
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/ServerResponseEntity.java b/ruoyi-admin/src/main/java/org/dromara/web/common/ServerResponseEntity.java
index ceffb75..a12a82c 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/ServerResponseEntity.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/ServerResponseEntity.java
@@ -1,199 +1,199 @@
-package org.dromara.web.common;
-
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.Serializable;
-import java.util.Objects;
-
-/**
- * @author lanhai
- */
-@Slf4j
-public class ServerResponseEntity implements Serializable {
-
- /**
- * 状态码
- */
- private String code;
-
- /**
- * 信息
- */
- private String msg;
-
- /**
- * 数据
- */
- private T data;
-
- /**
- * 版本
- */
- private String version;
-
- /**
- * 时间
- */
- private Long timestamp;
-
-/* private String sign;
-
- public String getSign() {
- return sign;
- }
-
- public void setSign(String sign) {
- this.sign = sign;
- }*/
-
- public String getCode() {
- return code;
- }
-
- public void setCode(String code) {
- this.code = code;
- }
-
- public String getMsg() {
- return msg;
- }
-
- public void setMsg(String msg) {
- this.msg = msg;
- }
-
- public T getData() {
- return data;
- }
-
- public ServerResponseEntity setData(T data) {
- this.data = data;
- return this;
- }
-
- public String getVersion() {
- return version;
- }
-
- public void setVersion(String version) {
- this.version = version;
- }
-
- public Long getTimestamp() {
- return timestamp;
- }
-
- public void setTimestamp(Long timestamp) {
- this.timestamp = timestamp;
- }
-
- public boolean isSuccess() {
- return Objects.equals(ResponseEnum.OK.value(), this.code);
- }
- public boolean isFail() {
- return !Objects.equals(ResponseEnum.OK.value(), this.code);
- }
-
- public ServerResponseEntity() {
- // 版本号
- this.version = "1.0";
- }
-
- public static ServerResponseEntity success(T data) {
- ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
- serverResponseEntity.setData(data);
- serverResponseEntity.setCode(ResponseEnum.OK.value());
- serverResponseEntity.setTimestamp(System.currentTimeMillis());
- serverResponseEntity.setMsg("success");
- return serverResponseEntity;
- }
-
- public static ServerResponseEntity success() {
- ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
- serverResponseEntity.setCode(ResponseEnum.OK.value());
- serverResponseEntity.setMsg(ResponseEnum.OK.getMsg());
- serverResponseEntity.setMsg("success");
- serverResponseEntity.setTimestamp(System.currentTimeMillis());
- return serverResponseEntity;
- }
-
- public static ServerResponseEntity success(Integer code, T data) {
- return success(String.valueOf(code), data);
- }
-
- public static ServerResponseEntity success(String code, T data) {
- ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
- serverResponseEntity.setCode(code);
- serverResponseEntity.setData(data);
- serverResponseEntity.setMsg("success");
- serverResponseEntity.setTimestamp(System.currentTimeMillis());
- return serverResponseEntity;
- }
-
- /**
- * 前端显示失败消息
- * @param msg 失败消息
- * @return
- */
- public static ServerResponseEntity showFailMsg(String msg) {
- log.error(msg);
- ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
- serverResponseEntity.setMsg(msg);
- serverResponseEntity.setCode(ResponseEnum.SHOW_FAIL.value());
- serverResponseEntity.setTimestamp(System.currentTimeMillis());
- return serverResponseEntity;
- }
-
- public static ServerResponseEntity fail(ResponseEnum responseEnum) {
- log.error(responseEnum.toString());
- ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
- serverResponseEntity.setMsg(responseEnum.getMsg());
- serverResponseEntity.setCode(responseEnum.value());
- serverResponseEntity.setTimestamp(System.currentTimeMillis());
- return serverResponseEntity;
- }
-
- public static ServerResponseEntity fail(ResponseEnum responseEnum, T data) {
- log.error(responseEnum.toString());
- ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
- serverResponseEntity.setMsg(responseEnum.getMsg());
- serverResponseEntity.setCode(responseEnum.value());
- serverResponseEntity.setData(data);
- serverResponseEntity.setTimestamp(System.currentTimeMillis());
- return serverResponseEntity;
- }
-
- public static ServerResponseEntity fail(String code, String msg, T data) {
- log.error(msg);
- ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
- serverResponseEntity.setMsg(msg);
- serverResponseEntity.setCode(code);
- serverResponseEntity.setData(data);
- serverResponseEntity.setTimestamp(System.currentTimeMillis());
- return serverResponseEntity;
- }
-
- public static ServerResponseEntity fail(String code, String msg) {
- return fail(code, msg, null);
- }
-
- public static ServerResponseEntity fail(Integer code, T data) {
- ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
- serverResponseEntity.setCode(String.valueOf(code));
- serverResponseEntity.setData(data);
- serverResponseEntity.setTimestamp(System.currentTimeMillis());
- return serverResponseEntity;
- }
-
- @Override
- public String toString() {
- return "ServerResponseEntity{" +
- "code='" + code + '\'' +
- ", msg='" + msg + '\'' +
- ", data=" + data +
- ", version='" + version + '\'' +
- ", timestamp=" + timestamp +
-// ", sign='" + sign + '\'' +
- '}';
- }
-}
+package org.dromara.web.common;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * @author lanhai
+ */
+@Slf4j
+public class ServerResponseEntity implements Serializable {
+
+ /**
+ * 状态码
+ */
+ private String code;
+
+ /**
+ * 信息
+ */
+ private String msg;
+
+ /**
+ * 数据
+ */
+ private T data;
+
+ /**
+ * 版本
+ */
+ private String version;
+
+ /**
+ * 时间
+ */
+ private Long timestamp;
+
+/* private String sign;
+
+ public String getSign() {
+ return sign;
+ }
+
+ public void setSign(String sign) {
+ this.sign = sign;
+ }*/
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public ServerResponseEntity setData(T data) {
+ this.data = data;
+ return this;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public Long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(Long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public boolean isSuccess() {
+ return Objects.equals(ResponseEnum.OK.value(), this.code);
+ }
+ public boolean isFail() {
+ return !Objects.equals(ResponseEnum.OK.value(), this.code);
+ }
+
+ public ServerResponseEntity() {
+ // 版本号
+ this.version = "1.0";
+ }
+
+ public static ServerResponseEntity success(T data) {
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setData(data);
+ serverResponseEntity.setCode(ResponseEnum.OK.value());
+ serverResponseEntity.setTimestamp(System.currentTimeMillis());
+ serverResponseEntity.setMsg("success");
+ return serverResponseEntity;
+ }
+
+ public static ServerResponseEntity success() {
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setCode(ResponseEnum.OK.value());
+ serverResponseEntity.setMsg(ResponseEnum.OK.getMsg());
+ serverResponseEntity.setMsg("success");
+ serverResponseEntity.setTimestamp(System.currentTimeMillis());
+ return serverResponseEntity;
+ }
+
+ public static ServerResponseEntity success(Integer code, T data) {
+ return success(String.valueOf(code), data);
+ }
+
+ public static ServerResponseEntity success(String code, T data) {
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setCode(code);
+ serverResponseEntity.setData(data);
+ serverResponseEntity.setMsg("success");
+ serverResponseEntity.setTimestamp(System.currentTimeMillis());
+ return serverResponseEntity;
+ }
+
+ /**
+ * 前端显示失败消息
+ * @param msg 失败消息
+ * @return
+ */
+ public static ServerResponseEntity showFailMsg(String msg) {
+ log.error(msg);
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setMsg(msg);
+ serverResponseEntity.setCode(ResponseEnum.SHOW_FAIL.value());
+ serverResponseEntity.setTimestamp(System.currentTimeMillis());
+ return serverResponseEntity;
+ }
+
+ public static ServerResponseEntity fail(ResponseEnum responseEnum) {
+ log.error(responseEnum.toString());
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setMsg(responseEnum.getMsg());
+ serverResponseEntity.setCode(responseEnum.value());
+ serverResponseEntity.setTimestamp(System.currentTimeMillis());
+ return serverResponseEntity;
+ }
+
+ public static ServerResponseEntity fail(ResponseEnum responseEnum, T data) {
+ log.error(responseEnum.toString());
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setMsg(responseEnum.getMsg());
+ serverResponseEntity.setCode(responseEnum.value());
+ serverResponseEntity.setData(data);
+ serverResponseEntity.setTimestamp(System.currentTimeMillis());
+ return serverResponseEntity;
+ }
+
+ public static ServerResponseEntity fail(String code, String msg, T data) {
+ log.error(msg);
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setMsg(msg);
+ serverResponseEntity.setCode(code);
+ serverResponseEntity.setData(data);
+ serverResponseEntity.setTimestamp(System.currentTimeMillis());
+ return serverResponseEntity;
+ }
+
+ public static ServerResponseEntity fail(String code, String msg) {
+ return fail(code, msg, null);
+ }
+
+ public static ServerResponseEntity fail(Integer code, T data) {
+ ServerResponseEntity serverResponseEntity = new ServerResponseEntity<>();
+ serverResponseEntity.setCode(String.valueOf(code));
+ serverResponseEntity.setData(data);
+ serverResponseEntity.setTimestamp(System.currentTimeMillis());
+ return serverResponseEntity;
+ }
+
+ @Override
+ public String toString() {
+ return "ServerResponseEntity{" +
+ "code='" + code + '\'' +
+ ", msg='" + msg + '\'' +
+ ", data=" + data +
+ ", version='" + version + '\'' +
+ ", timestamp=" + timestamp +
+// ", sign='" + sign + '\'' +
+ '}';
+ }
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/TokenInfoBO.java b/ruoyi-admin/src/main/java/org/dromara/web/common/TokenInfoBO.java
index 51ad7e6..c53e524 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/TokenInfoBO.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/TokenInfoBO.java
@@ -1,38 +1,38 @@
-/*
- * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
- *
- * https://www.mall4j.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-package org.dromara.web.common;
-
-
-import lombok.Data;
-
-/**
- * token信息,该信息存在redis中
- *
- * @author 菠萝凤梨
- * @date 2022/3/25 17:33
- */
-@Data
-public class TokenInfoBO {
-
- /**
- * 保存在token信息里面的用户信息
- */
- private UserInfoInTokenBO userInfoInToken;
-
- private String accessToken;
-
- private String refreshToken;
-
- /**
- * 在多少秒后过期
- */
- private Integer expiresIn;
-
-}
+/*
+ * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
+ *
+ * https://www.mall4j.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+package org.dromara.web.common;
+
+
+import lombok.Data;
+
+/**
+ * token信息,该信息存在redis中
+ *
+ * @author 菠萝凤梨
+ * @date 2022/3/25 17:33
+ */
+@Data
+public class TokenInfoBO {
+
+ /**
+ * 保存在token信息里面的用户信息
+ */
+ private UserInfoInTokenBO userInfoInToken;
+
+ private String accessToken;
+
+ private String refreshToken;
+
+ /**
+ * 在多少秒后过期
+ */
+ private Integer expiresIn;
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/TokenInfoVO.java b/ruoyi-admin/src/main/java/org/dromara/web/common/TokenInfoVO.java
index ac60a66..54aa390 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/TokenInfoVO.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/TokenInfoVO.java
@@ -1,23 +1,23 @@
-package org.dromara.web.common;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-/**
- * token信息,该信息用户返回给前端,前端请求携带accessToken进行用户校验
- *
- * @author FrozenWatermelon
- * @date 2020/7/2
- */
-@Data
-public class TokenInfoVO {
-
- @Schema(description = "accessToken" )
- private String accessToken;
-
- @Schema(description = "refreshToken" )
- private String refreshToken;
-
- @Schema(description = "在多少秒后过期" )
- private Integer expiresIn;
-}
+package org.dromara.web.common;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * token信息,该信息用户返回给前端,前端请求携带accessToken进行用户校验
+ *
+ * @author FrozenWatermelon
+ * @date 2020/7/2
+ */
+@Data
+public class TokenInfoVO {
+
+ @Schema(description = "accessToken" )
+ private String accessToken;
+
+ @Schema(description = "refreshToken" )
+ private String refreshToken;
+
+ @Schema(description = "在多少秒后过期" )
+ private Integer expiresIn;
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/TokenStore.java b/ruoyi-admin/src/main/java/org/dromara/web/common/TokenStore.java
index 2ed33b0..4eb649c 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/TokenStore.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/TokenStore.java
@@ -1,171 +1,171 @@
-package org.dromara.web.common;
-
-import cn.dev33.satoken.stp.StpUtil;
-import cn.hutool.core.util.StrUtil;
-import org.dromara.common.core.exception.user.UserException;
-import org.dromara.common.redis.utils.RedisUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-import org.springframework.util.CollectionUtils;
-
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * token管理 1. 登陆返回token 2. 刷新token 3. 清除用户过去token 4. 校验token
- *
- * @author FrozenWatermelon
- * @date 2020/7/2
- */
-@Component
-public class TokenStore {
-
- private static final Logger logger = LoggerFactory.getLogger(TokenStore.class);
-
-// private final RedisTemplate redisTemplate;
-
- /*public TokenStore(RedisTemplate redisTemplate) {
- this.redisTemplate = redisTemplate;
- }*/
-
- /**
- * 以Sa-Token技术生成token,并返回token信息
- * @param userInfoInToken
- * @return
- */
- public TokenInfoBO storeAccessSaToken(UserInfoInTokenBO userInfoInToken) {
- //生成过期时间
- int timeoutSecond = getExpiresIn(userInfoInToken.getSysType());
- Duration accessTokenExpires = Duration.ofSeconds(timeoutSecond);
-
- String uid = this.getUid(userInfoInToken.getSysType().toString(), userInfoInToken.getUserId());
- StpUtil.login(uid, timeoutSecond);
- String token = StpUtil.getTokenValue();
- // 用户信息存入缓存 token生成
- String keyName = OauthCacheNames.USER_INFO + token;
- RedisUtils.deleteObject(keyName);
- RedisUtils.setCacheObject(keyName, userInfoInToken, accessTokenExpires);
- // 数据封装返回(token不用加密)
- TokenInfoBO tokenInfoBO = new TokenInfoBO();
- tokenInfoBO.setUserInfoInToken(userInfoInToken);
- tokenInfoBO.setExpiresIn(timeoutSecond);
- tokenInfoBO.setAccessToken(token);
- tokenInfoBO.setRefreshToken(token);
- return tokenInfoBO;
- }
-
- /**
- * 计算过期时间(单位:秒)
- * @param sysType
- * @return
- */
- private int getExpiresIn(int sysType) {
- // 3600秒
- int expiresIn = 3600;
- // 普通用户token过期时间
- if (Objects.equals(sysType, 0)) {
- expiresIn = expiresIn * 24 * 30;
- }
- // 系统管理员的token过期时间
- if (Objects.equals(sysType, 1)) {
- expiresIn = expiresIn * 24 * 30;
- }
- return expiresIn;
- }
-
- /**
- * 根据accessToken 获取用户信息
- * @param accessToken accessToken
- * @param needDecrypt 是否需要解密
- * @return 用户信息
- */
- public UserInfoInTokenBO getUserInfoByAccessToken(String accessToken, boolean needDecrypt) {
- if (StrUtil.isBlank(accessToken)) {
- throw new UserException("accessToken is blank");
- }
- String keyName = OauthCacheNames.USER_INFO + accessToken;
- Object redisCache = RedisUtils.getCacheObject(keyName);
- if (redisCache == null) {
- throw new UserException("-2","登录过期,请重新登录");
- }
- return (UserInfoInTokenBO) redisCache;
- }
-
- /**
- * 刷新token,并返回新的token
- * @param refreshToken
- * @return
- */
- public TokenInfoBO refreshToken(String refreshToken) {
- if (StrUtil.isBlank(refreshToken)) {
- throw new UserException("refreshToken is blank");
- }
- // 删除旧token
- UserInfoInTokenBO userInfoInTokenBO = getUserInfoByAccessToken(refreshToken, false);
- this.deleteCurrentToken(refreshToken);
- // 保存一份新的token
- return storeAccessSaToken(userInfoInTokenBO);
- }
-
- /**
- * 删除指定用户的全部的token
- */
- public void deleteAllToken(String sysType, Long userId) {
- // 删除用户缓存
- String uid = this.getUid(sysType, userId);
- List tokens = StpUtil.getTokenValueListByLoginId(uid);
- if (!CollectionUtils.isEmpty(tokens)) {
- List keyNames = new ArrayList<>();
- for (String token : tokens) {
- keyNames.add(OauthCacheNames.USER_INFO + token);
- }
- RedisUtils.deleteObject(keyNames);
- }
- // 移除token
- StpUtil.logout(userId);
- }
-
- /**
- * 生成token,并返回token展示信息
- * @param userInfoInToken
- * @return
- */
- public TokenInfoVO storeAndGetVo(UserInfoInTokenBO userInfoInToken) {
- if (!userInfoInToken.getEnabled()){
- // 用户已禁用,请联系客服
- throw new UserException("用户已禁用,请联系客服");
- }
- TokenInfoBO tokenInfoBO = storeAccessSaToken(userInfoInToken);
- // 数据封装返回
- TokenInfoVO tokenInfoVO = new TokenInfoVO();
- tokenInfoVO.setAccessToken(tokenInfoBO.getAccessToken());
- tokenInfoVO.setRefreshToken(tokenInfoBO.getRefreshToken());
- tokenInfoVO.setExpiresIn(tokenInfoBO.getExpiresIn());
- return tokenInfoVO;
- }
-
- /**
- * 删除当前登录的token
- * @param accessToken 令牌
- */
- public void deleteCurrentToken(String accessToken) {
- // 删除用户缓存
- String keyName = OauthCacheNames.USER_INFO + accessToken;
- RedisUtils.deleteObject(keyName);
- // 移除token
- StpUtil.logoutByTokenValue(accessToken);
- }
-
- /**
- * 生成各系统唯一uid
- * @param sysType 系统类型
- * @param userId 用户id
- * @return
- */
- private String getUid(String sysType, Long userId) {
- return sysType + ":" + userId;
- }
-}
+package org.dromara.web.common;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.util.StrUtil;
+import org.dromara.common.core.exception.user.UserException;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * token管理 1. 登陆返回token 2. 刷新token 3. 清除用户过去token 4. 校验token
+ *
+ * @author FrozenWatermelon
+ * @date 2020/7/2
+ */
+@Component
+public class TokenStore {
+
+ private static final Logger logger = LoggerFactory.getLogger(TokenStore.class);
+
+// private final RedisTemplate redisTemplate;
+
+ /*public TokenStore(RedisTemplate redisTemplate) {
+ this.redisTemplate = redisTemplate;
+ }*/
+
+ /**
+ * 以Sa-Token技术生成token,并返回token信息
+ * @param userInfoInToken
+ * @return
+ */
+ public TokenInfoBO storeAccessSaToken(UserInfoInTokenBO userInfoInToken) {
+ //生成过期时间
+ int timeoutSecond = getExpiresIn(userInfoInToken.getSysType());
+ Duration accessTokenExpires = Duration.ofSeconds(timeoutSecond);
+
+ String uid = this.getUid(userInfoInToken.getSysType().toString(), userInfoInToken.getUserId());
+ StpUtil.login(uid, timeoutSecond);
+ String token = StpUtil.getTokenValue();
+ // 用户信息存入缓存 token生成
+ String keyName = OauthCacheNames.USER_INFO + token;
+ RedisUtils.deleteObject(keyName);
+ RedisUtils.setCacheObject(keyName, userInfoInToken, accessTokenExpires);
+ // 数据封装返回(token不用加密)
+ TokenInfoBO tokenInfoBO = new TokenInfoBO();
+ tokenInfoBO.setUserInfoInToken(userInfoInToken);
+ tokenInfoBO.setExpiresIn(timeoutSecond);
+ tokenInfoBO.setAccessToken(token);
+ tokenInfoBO.setRefreshToken(token);
+ return tokenInfoBO;
+ }
+
+ /**
+ * 计算过期时间(单位:秒)
+ * @param sysType
+ * @return
+ */
+ private int getExpiresIn(int sysType) {
+ // 3600秒
+ int expiresIn = 3600;
+ // 普通用户token过期时间
+ if (Objects.equals(sysType, 0)) {
+ expiresIn = expiresIn * 24 * 30;
+ }
+ // 系统管理员的token过期时间
+ if (Objects.equals(sysType, 1)) {
+ expiresIn = expiresIn * 24 * 30;
+ }
+ return expiresIn;
+ }
+
+ /**
+ * 根据accessToken 获取用户信息
+ * @param accessToken accessToken
+ * @param needDecrypt 是否需要解密
+ * @return 用户信息
+ */
+ public UserInfoInTokenBO getUserInfoByAccessToken(String accessToken, boolean needDecrypt) {
+ if (StrUtil.isBlank(accessToken)) {
+ throw new UserException("accessToken is blank");
+ }
+ String keyName = OauthCacheNames.USER_INFO + accessToken;
+ Object redisCache = RedisUtils.getCacheObject(keyName);
+ if (redisCache == null) {
+ throw new UserException("-2","登录过期,请重新登录");
+ }
+ return (UserInfoInTokenBO) redisCache;
+ }
+
+ /**
+ * 刷新token,并返回新的token
+ * @param refreshToken
+ * @return
+ */
+ public TokenInfoBO refreshToken(String refreshToken) {
+ if (StrUtil.isBlank(refreshToken)) {
+ throw new UserException("refreshToken is blank");
+ }
+ // 删除旧token
+ UserInfoInTokenBO userInfoInTokenBO = getUserInfoByAccessToken(refreshToken, false);
+ this.deleteCurrentToken(refreshToken);
+ // 保存一份新的token
+ return storeAccessSaToken(userInfoInTokenBO);
+ }
+
+ /**
+ * 删除指定用户的全部的token
+ */
+ public void deleteAllToken(String sysType, Long userId) {
+ // 删除用户缓存
+ String uid = this.getUid(sysType, userId);
+ List tokens = StpUtil.getTokenValueListByLoginId(uid);
+ if (!CollectionUtils.isEmpty(tokens)) {
+ List keyNames = new ArrayList<>();
+ for (String token : tokens) {
+ keyNames.add(OauthCacheNames.USER_INFO + token);
+ }
+ RedisUtils.deleteObject(keyNames);
+ }
+ // 移除token
+ StpUtil.logout(userId);
+ }
+
+ /**
+ * 生成token,并返回token展示信息
+ * @param userInfoInToken
+ * @return
+ */
+ public TokenInfoVO storeAndGetVo(UserInfoInTokenBO userInfoInToken) {
+ if (!userInfoInToken.getEnabled()){
+ // 用户已禁用,请联系客服
+ throw new UserException("用户已禁用,请联系客服");
+ }
+ TokenInfoBO tokenInfoBO = storeAccessSaToken(userInfoInToken);
+ // 数据封装返回
+ TokenInfoVO tokenInfoVO = new TokenInfoVO();
+ tokenInfoVO.setAccessToken(tokenInfoBO.getAccessToken());
+ tokenInfoVO.setRefreshToken(tokenInfoBO.getRefreshToken());
+ tokenInfoVO.setExpiresIn(tokenInfoBO.getExpiresIn());
+ return tokenInfoVO;
+ }
+
+ /**
+ * 删除当前登录的token
+ * @param accessToken 令牌
+ */
+ public void deleteCurrentToken(String accessToken) {
+ // 删除用户缓存
+ String keyName = OauthCacheNames.USER_INFO + accessToken;
+ RedisUtils.deleteObject(keyName);
+ // 移除token
+ StpUtil.logoutByTokenValue(accessToken);
+ }
+
+ /**
+ * 生成各系统唯一uid
+ * @param sysType 系统类型
+ * @param userId 用户id
+ * @return
+ */
+ private String getUid(String sysType, Long userId) {
+ return sysType + ":" + userId;
+ }
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/UserInfoInTokenBO.java b/ruoyi-admin/src/main/java/org/dromara/web/common/UserInfoInTokenBO.java
index 017f361..e7d2e23 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/UserInfoInTokenBO.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/UserInfoInTokenBO.java
@@ -1,71 +1,71 @@
-/*
- * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
- *
- * https://www.mall4j.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-package org.dromara.web.common;
-
-import lombok.Data;
-
-import java.util.Set;
-
-/**
- * 保存在token信息里面的用户信息
- *
- * @author 菠萝凤梨
- * @date 2022/3/25 17:33
- */
-@Data
-public class UserInfoInTokenBO {
-
- /**
- * 用户在自己系统的用户id
- */
- private Long userId;
-
- /**
- * 租户id (商家id)
- */
- private Long shopId;
-
- /**
- * 昵称
- */
- private String nickName;
-
- /**
- * 系统类型 0:普通用户 1:系统管理员
- *
- */
- private Integer sysType;
-
- /**
- * 是否是管理员
- */
- private Integer isAdmin;
-
- /**
- * 业务系统用户id
- */
- private String bizUserId;
-
- /**
- * 权限列表
- */
- private Set perms;
-
- /**
- * 状态 1 正常 0 无效
- */
- private Boolean enabled;
-
- /**
- * 其他Id
- */
- private Long otherId;
-
-}
+/*
+ * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
+ *
+ * https://www.mall4j.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+package org.dromara.web.common;
+
+import lombok.Data;
+
+import java.util.Set;
+
+/**
+ * 保存在token信息里面的用户信息
+ *
+ * @author 菠萝凤梨
+ * @date 2022/3/25 17:33
+ */
+@Data
+public class UserInfoInTokenBO {
+
+ /**
+ * 用户在自己系统的用户id
+ */
+ private Long userId;
+
+ /**
+ * 租户id (商家id)
+ */
+ private Long shopId;
+
+ /**
+ * 昵称
+ */
+ private String nickName;
+
+ /**
+ * 系统类型 0:普通用户 1:系统管理员
+ *
+ */
+ private Integer sysType;
+
+ /**
+ * 是否是管理员
+ */
+ private Integer isAdmin;
+
+ /**
+ * 业务系统用户id
+ */
+ private String bizUserId;
+
+ /**
+ * 权限列表
+ */
+ private Set perms;
+
+ /**
+ * 状态 1 正常 0 无效
+ */
+ private Boolean enabled;
+
+ /**
+ * 其他Id
+ */
+ private Long otherId;
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/UserRegisterParam.java b/ruoyi-admin/src/main/java/org/dromara/web/common/UserRegisterParam.java
index 87fca15..8a34462 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/UserRegisterParam.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/UserRegisterParam.java
@@ -1,45 +1,45 @@
-package org.dromara.web.common;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotBlank;
-import lombok.Data;
-import org.dromara.common.core.validate.AddGroup;
-
-/**
- * @author lh
- */
-@Data
-@Schema(description = "用户登录信息")
-public class UserRegisterParam {
-
- @Schema(description = "密码")
- private String passWord;
-
- @Schema(description = "邮箱")
- private String userMail;
-
- @Schema(description = "昵称")
- private String nickName;
-
- @Schema(description = "用户名")
- private String userName;
-
- @Schema(description = "手机号")
- @NotBlank(message = "手机号码不能为空", groups = { AddGroup.class})
- private String mobile;
-
- @Schema(description = "头像")
- private String img;
-
- @Schema(description = "校验登陆注册验证码成功的标识")
- private String checkRegisterSmsFlag;
-
- @Schema(description = "当账户未绑定时,临时的uid")
- private String tempUid;
-
- @Schema(description = "用户id")
- private Long userId;
-
- @Schema(description = "微信openId")
- private String openId;
-}
+package org.dromara.web.common;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+import org.dromara.common.core.validate.AddGroup;
+
+/**
+ * @author lh
+ */
+@Data
+@Schema(description = "用户登录信息")
+public class UserRegisterParam {
+
+ @Schema(description = "密码")
+ private String passWord;
+
+ @Schema(description = "邮箱")
+ private String userMail;
+
+ @Schema(description = "昵称")
+ private String nickName;
+
+ @Schema(description = "用户名")
+ private String userName;
+
+ @Schema(description = "手机号")
+ @NotBlank(message = "手机号码不能为空", groups = { AddGroup.class})
+ private String mobile;
+
+ @Schema(description = "头像")
+ private String img;
+
+ @Schema(description = "校验登陆注册验证码成功的标识")
+ private String checkRegisterSmsFlag;
+
+ @Schema(description = "当账户未绑定时,临时的uid")
+ private String tempUid;
+
+ @Schema(description = "用户id")
+ private Long userId;
+
+ @Schema(description = "微信openId")
+ private String openId;
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/common/YamiUser.java b/ruoyi-admin/src/main/java/org/dromara/web/common/YamiUser.java
index ec6d5d6..07da5ce 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/common/YamiUser.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/common/YamiUser.java
@@ -1,39 +1,39 @@
-/*
- * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
- *
- * https://www.mall4j.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-package org.dromara.web.common;
-
-import lombok.Data;
-
-/**
- * 用户详细信息
- * @author LGH
- */
-@Data
-public class YamiUser {
-
- /**
- * 用户ID
- */
- private Long userId;
-
- private String bizUserId;
-
- private Boolean enabled;
-
- /**
- * 自提点Id
- */
- private Long stationId;
-
- /**
- * 店铺Id
- */
- private Long shopId;
-}
+/*
+ * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
+ *
+ * https://www.mall4j.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+package org.dromara.web.common;
+
+import lombok.Data;
+
+/**
+ * 用户详细信息
+ * @author LGH
+ */
+@Data
+public class YamiUser {
+
+ /**
+ * 用户ID
+ */
+ private Long userId;
+
+ private String bizUserId;
+
+ private Boolean enabled;
+
+ /**
+ * 自提点Id
+ */
+ private Long stationId;
+
+ /**
+ * 店铺Id
+ */
+ private Long shopId;
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
index dbe5daa..785087d 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
@@ -1,247 +1,247 @@
-package org.dromara.web.controller;
-
-import cn.dev33.satoken.annotation.SaIgnore;
-import cn.dev33.satoken.exception.NotLoginException;
-import cn.hutool.core.codec.Base64;
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.ObjectUtil;
-import jakarta.servlet.http.HttpServletRequest;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import me.zhyd.oauth.model.AuthResponse;
-import me.zhyd.oauth.model.AuthUser;
-import me.zhyd.oauth.request.AuthRequest;
-import me.zhyd.oauth.utils.AuthStateUtils;
-import org.anyline.util.encrypt.MD5Util;
-import org.dromara.common.core.constant.SystemConstants;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.core.domain.model.LoginBody;
-import org.dromara.common.core.domain.model.PasswordLoginBody;
-import org.dromara.common.core.domain.model.RegisterBody;
-import org.dromara.common.core.domain.model.SocialLoginBody;
-import org.dromara.common.core.utils.*;
-import org.dromara.common.encrypt.annotation.ApiEncrypt;
-import org.dromara.common.json.utils.JsonUtils;
-import org.dromara.common.json.utils.UserUtils;
-import org.dromara.common.satoken.utils.LoginHelper;
-import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
-import org.dromara.common.social.config.properties.SocialProperties;
-import org.dromara.common.social.utils.SocialUtils;
-import org.dromara.common.sse.dto.SseMessageDto;
-import org.dromara.common.sse.utils.SseMessageUtils;
-import org.dromara.common.tenant.helper.TenantHelper;
-import org.dromara.system.domain.bo.SysTenantBo;
-import org.dromara.system.domain.vo.SysClientVo;
-import org.dromara.system.domain.vo.SysTenantVo;
-import org.dromara.system.service.ISysClientService;
-import org.dromara.system.service.ISysConfigService;
-import org.dromara.system.service.ISysSocialService;
-import org.dromara.system.service.ISysTenantService;
-import org.dromara.web.domain.vo.LoginTenantVo;
-import org.dromara.web.domain.vo.LoginVo;
-import org.dromara.web.domain.vo.TenantListVo;
-import org.dromara.web.service.IAuthStrategy;
-import org.dromara.web.service.SysLoginService;
-import org.dromara.web.service.SysRegisterService;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 认证
- *
- * @author Lion Li
- */
-@Slf4j
-@SaIgnore
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/auth")
-public class AuthController {
-
- private final SocialProperties socialProperties;
- private final SysLoginService loginService;
- private final SysRegisterService registerService;
- private final ISysConfigService configService;
- private final ISysTenantService tenantService;
- private final ISysSocialService socialUserService;
- private final ISysClientService clientService;
- private final ScheduledExecutorService scheduledExecutorService;
-
-
- /**
- * 登录方法
- *
- * @param body 登录信息
- * @return 结果
- */
- @ApiEncrypt
- @PostMapping("/login")
- public R login(@RequestBody String body, HttpServletRequest request) {
- LoginBody loginBody = JsonUtils.parseObject(body, LoginBody.class);
- ValidatorUtils.validate(loginBody);
- // 授权类型和客户端id
- String clientId = loginBody.getClientId();
- String grantType = loginBody.getGrantType();
- SysClientVo client = clientService.queryByClientId(clientId);
-// validateCaptcha(body,request);
- // 查询不到 client 或 client 内不包含 grantType
- if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) {
- log.info("客户端id: {} 认证类型:{} 异常!.", clientId, grantType);
- return R.fail(MessageUtils.message("auth.grant.type.error"));
- } else if (!SystemConstants.NORMAL.equals(client.getStatus())) {
- return R.fail(MessageUtils.message("auth.grant.type.blocked"));
- }
- // 校验租户
- loginService.checkTenant(loginBody.getTenantId());
- // 登录
- LoginVo loginVo = IAuthStrategy.login(body, client, grantType);
-
- Long userId = LoginHelper.getUserId();
- scheduledExecutorService.schedule(() -> {
- SseMessageDto dto = new SseMessageDto();
- dto.setMessage("欢迎登录效果图业务后台管理系统");
- dto.setUserIds(List.of(userId));
- SseMessageUtils.publishMessage(dto);
- }, 5, TimeUnit.SECONDS);
- return R.ok(loginVo);
- }
-
- /**
- * 第三方登录请求
- *
- * @param source 登录来源
- * @return 结果
- */
- @GetMapping("/binding/{source}")
- public R authBinding(@PathVariable("source") String source,
- @RequestParam String tenantId, @RequestParam String domain) {
- SocialLoginConfigProperties obj = socialProperties.getType().get(source);
- if (ObjectUtil.isNull(obj)) {
- return R.fail(source + "平台账号暂不支持");
- }
- AuthRequest authRequest = SocialUtils.getAuthRequest(source, socialProperties);
- Map map = new HashMap<>();
- map.put("tenantId", tenantId);
- map.put("domain", domain);
- map.put("state", AuthStateUtils.createState());
- String authorizeUrl = authRequest.authorize(Base64.encode(JsonUtils.toJsonString(map), StandardCharsets.UTF_8));
- return R.ok("操作成功", authorizeUrl);
- }
-
- /**
- * 第三方登录回调业务处理 绑定授权
- *
- * @param loginBody 请求体
- * @return 结果
- */
- @PostMapping("/social/callback")
- public R socialCallback(@RequestBody SocialLoginBody loginBody) {
- // 获取第三方登录信息
- AuthResponse response = SocialUtils.loginAuth(
- loginBody.getSource(), loginBody.getSocialCode(),
- loginBody.getSocialState(), socialProperties);
- AuthUser authUserData = response.getData();
- // 判断授权响应是否成功
- if (!response.ok()) {
- return R.fail(response.getMsg());
- }
- loginService.socialRegister(authUserData);
- return R.ok();
- }
-
-
- /**
- * 取消授权
- *
- * @param socialId socialId
- */
- @DeleteMapping(value = "/unlock/{socialId}")
- public R unlockSocial(@PathVariable Long socialId) {
- Boolean rows = socialUserService.deleteWithValidById(socialId);
- return rows ? R.ok() : R.fail("取消授权失败");
- }
-
-
- /**
- * 退出登录
- */
- @PostMapping("/logout")
- public R logout() {
- loginService.logout();
- return R.ok("退出成功");
- }
-
- /**
- * 用户注册
- */
- @ApiEncrypt
- @PostMapping("/register")
- public R register(@Validated @RequestBody RegisterBody user) {
- if (!configService.selectRegisterEnabled(user.getTenantId())) {
- return R.fail("当前系统没有开启注册功能!");
- }
- registerService.register(user);
- return R.ok();
- }
-
- /**
- * 登录页面租户下拉框
- *
- * @return 租户列表
- */
- @GetMapping("/tenant/list")
- public R tenantList(HttpServletRequest request) throws Exception {
- // 返回对象
- LoginTenantVo result = new LoginTenantVo();
- boolean enable = TenantHelper.isEnable();
- result.setTenantEnabled(enable);
- // 如果未开启租户这直接返回
- if (!enable) {
- return R.ok(result);
- }
-
- List tenantList = tenantService.queryList(new SysTenantBo());
- List voList = MapstructUtils.convert(tenantList, TenantListVo.class);
- try {
- // 如果只超管返回所有租户
- if (LoginHelper.isSuperAdmin()) {
- result.setVoList(voList);
- return R.ok(result);
- }
- } catch (NotLoginException ignored) {
- }
-
- // 获取域名
- String host;
- String referer = request.getHeader("referer");
- if (StringUtils.isNotBlank(referer)) {
- // 这里从referer中取值是为了本地使用hosts添加虚拟域名,方便本地环境调试
- host = referer.split("//")[1].split("/")[0];
- } else {
- host = new URL(request.getRequestURL().toString()).getHost();
- }
- // 根据域名进行筛选
- List list = StreamUtils.filter(voList, vo ->
- StringUtils.equalsIgnoreCase(vo.getDomain(), host));
- result.setVoList(CollUtil.isNotEmpty(list) ? list : voList);
- return R.ok(result);
- }
-
-
- public static void validateCaptcha(String body, HttpServletRequest request) {
- PasswordLoginBody loginBody = JsonUtils.parseObject(body, PasswordLoginBody.class);
- ValidatorUtils.validate(loginBody);
- String username = loginBody.getUsername();
- String name = MD5Util.crypto(username);
- UserUtils.validate(name,body,request);
- }
-
-}
+package org.dromara.web.controller;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import cn.dev33.satoken.exception.NotLoginException;
+import cn.hutool.core.codec.Base64;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import me.zhyd.oauth.model.AuthResponse;
+import me.zhyd.oauth.model.AuthUser;
+import me.zhyd.oauth.request.AuthRequest;
+import me.zhyd.oauth.utils.AuthStateUtils;
+import org.anyline.util.encrypt.MD5Util;
+import org.dromara.common.core.constant.SystemConstants;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.domain.model.LoginBody;
+import org.dromara.common.core.domain.model.PasswordLoginBody;
+import org.dromara.common.core.domain.model.RegisterBody;
+import org.dromara.common.core.domain.model.SocialLoginBody;
+import org.dromara.common.core.utils.*;
+import org.dromara.common.encrypt.annotation.ApiEncrypt;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.common.json.utils.UserUtils;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
+import org.dromara.common.social.config.properties.SocialProperties;
+import org.dromara.common.social.utils.SocialUtils;
+import org.dromara.common.sse.dto.SseMessageDto;
+import org.dromara.common.sse.utils.SseMessageUtils;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.system.domain.bo.SysTenantBo;
+import org.dromara.system.domain.vo.SysClientVo;
+import org.dromara.system.domain.vo.SysTenantVo;
+import org.dromara.system.service.ISysClientService;
+import org.dromara.system.service.ISysConfigService;
+import org.dromara.system.service.ISysSocialService;
+import org.dromara.system.service.ISysTenantService;
+import org.dromara.web.domain.vo.LoginTenantVo;
+import org.dromara.web.domain.vo.LoginVo;
+import org.dromara.web.domain.vo.TenantListVo;
+import org.dromara.web.service.IAuthStrategy;
+import org.dromara.web.service.SysLoginService;
+import org.dromara.web.service.SysRegisterService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 认证
+ *
+ * @author Lion Li
+ */
+@Slf4j
+@SaIgnore
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/auth")
+public class AuthController {
+
+ private final SocialProperties socialProperties;
+ private final SysLoginService loginService;
+ private final SysRegisterService registerService;
+ private final ISysConfigService configService;
+ private final ISysTenantService tenantService;
+ private final ISysSocialService socialUserService;
+ private final ISysClientService clientService;
+ private final ScheduledExecutorService scheduledExecutorService;
+
+
+ /**
+ * 登录方法
+ *
+ * @param body 登录信息
+ * @return 结果
+ */
+ @ApiEncrypt
+ @PostMapping("/login")
+ public R login(@RequestBody String body, HttpServletRequest request) {
+ LoginBody loginBody = JsonUtils.parseObject(body, LoginBody.class);
+ ValidatorUtils.validate(loginBody);
+ // 授权类型和客户端id
+ String clientId = loginBody.getClientId();
+ String grantType = loginBody.getGrantType();
+ SysClientVo client = clientService.queryByClientId(clientId);
+// validateCaptcha(body,request);
+ // 查询不到 client 或 client 内不包含 grantType
+ if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) {
+ log.info("客户端id: {} 认证类型:{} 异常!.", clientId, grantType);
+ return R.fail(MessageUtils.message("auth.grant.type.error"));
+ } else if (!SystemConstants.NORMAL.equals(client.getStatus())) {
+ return R.fail(MessageUtils.message("auth.grant.type.blocked"));
+ }
+ // 校验租户
+ loginService.checkTenant(loginBody.getTenantId());
+ // 登录
+ LoginVo loginVo = IAuthStrategy.login(body, client, grantType);
+
+ Long userId = LoginHelper.getUserId();
+ scheduledExecutorService.schedule(() -> {
+ SseMessageDto dto = new SseMessageDto();
+ dto.setMessage("欢迎登录效果图业务后台管理系统");
+ dto.setUserIds(List.of(userId));
+ SseMessageUtils.publishMessage(dto);
+ }, 5, TimeUnit.SECONDS);
+ return R.ok(loginVo);
+ }
+
+ /**
+ * 第三方登录请求
+ *
+ * @param source 登录来源
+ * @return 结果
+ */
+ @GetMapping("/binding/{source}")
+ public R authBinding(@PathVariable("source") String source,
+ @RequestParam String tenantId, @RequestParam String domain) {
+ SocialLoginConfigProperties obj = socialProperties.getType().get(source);
+ if (ObjectUtil.isNull(obj)) {
+ return R.fail(source + "平台账号暂不支持");
+ }
+ AuthRequest authRequest = SocialUtils.getAuthRequest(source, socialProperties);
+ Map map = new HashMap<>();
+ map.put("tenantId", tenantId);
+ map.put("domain", domain);
+ map.put("state", AuthStateUtils.createState());
+ String authorizeUrl = authRequest.authorize(Base64.encode(JsonUtils.toJsonString(map), StandardCharsets.UTF_8));
+ return R.ok("操作成功", authorizeUrl);
+ }
+
+ /**
+ * 第三方登录回调业务处理 绑定授权
+ *
+ * @param loginBody 请求体
+ * @return 结果
+ */
+ @PostMapping("/social/callback")
+ public R socialCallback(@RequestBody SocialLoginBody loginBody) {
+ // 获取第三方登录信息
+ AuthResponse response = SocialUtils.loginAuth(
+ loginBody.getSource(), loginBody.getSocialCode(),
+ loginBody.getSocialState(), socialProperties);
+ AuthUser authUserData = response.getData();
+ // 判断授权响应是否成功
+ if (!response.ok()) {
+ return R.fail(response.getMsg());
+ }
+ loginService.socialRegister(authUserData);
+ return R.ok();
+ }
+
+
+ /**
+ * 取消授权
+ *
+ * @param socialId socialId
+ */
+ @DeleteMapping(value = "/unlock/{socialId}")
+ public R unlockSocial(@PathVariable Long socialId) {
+ Boolean rows = socialUserService.deleteWithValidById(socialId);
+ return rows ? R.ok() : R.fail("取消授权失败");
+ }
+
+
+ /**
+ * 退出登录
+ */
+ @PostMapping("/logout")
+ public R logout() {
+ loginService.logout();
+ return R.ok("退出成功");
+ }
+
+ /**
+ * 用户注册
+ */
+ @ApiEncrypt
+ @PostMapping("/register")
+ public R register(@Validated @RequestBody RegisterBody user) {
+ if (!configService.selectRegisterEnabled(user.getTenantId())) {
+ return R.fail("当前系统没有开启注册功能!");
+ }
+ registerService.register(user);
+ return R.ok();
+ }
+
+ /**
+ * 登录页面租户下拉框
+ *
+ * @return 租户列表
+ */
+ @GetMapping("/tenant/list")
+ public R tenantList(HttpServletRequest request) throws Exception {
+ // 返回对象
+ LoginTenantVo result = new LoginTenantVo();
+ boolean enable = TenantHelper.isEnable();
+ result.setTenantEnabled(enable);
+ // 如果未开启租户这直接返回
+ if (!enable) {
+ return R.ok(result);
+ }
+
+ List tenantList = tenantService.queryList(new SysTenantBo());
+ List voList = MapstructUtils.convert(tenantList, TenantListVo.class);
+ try {
+ // 如果只超管返回所有租户
+ if (LoginHelper.isSuperAdmin()) {
+ result.setVoList(voList);
+ return R.ok(result);
+ }
+ } catch (NotLoginException ignored) {
+ }
+
+ // 获取域名
+ String host;
+ String referer = request.getHeader("referer");
+ if (StringUtils.isNotBlank(referer)) {
+ // 这里从referer中取值是为了本地使用hosts添加虚拟域名,方便本地环境调试
+ host = referer.split("//")[1].split("/")[0];
+ } else {
+ host = new URL(request.getRequestURL().toString()).getHost();
+ }
+ // 根据域名进行筛选
+ List list = StreamUtils.filter(voList, vo ->
+ StringUtils.equalsIgnoreCase(vo.getDomain(), host));
+ result.setVoList(CollUtil.isNotEmpty(list) ? list : voList);
+ return R.ok(result);
+ }
+
+
+ public static void validateCaptcha(String body, HttpServletRequest request) {
+ PasswordLoginBody loginBody = JsonUtils.parseObject(body, PasswordLoginBody.class);
+ ValidatorUtils.validate(loginBody);
+ String username = loginBody.getUsername();
+ String name = MD5Util.crypto(username);
+ UserUtils.validate(name,body,request);
+ }
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java
index 1a476a9..b637c13 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java
@@ -1,136 +1,136 @@
-package org.dromara.web.controller;
-
-import cn.dev33.satoken.annotation.SaIgnore;
-import cn.hutool.captcha.AbstractCaptcha;
-import cn.hutool.captcha.generator.CodeGenerator;
-import cn.hutool.core.util.IdUtil;
-import cn.hutool.core.util.RandomUtil;
-import jakarta.validation.constraints.NotBlank;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.common.core.constant.Constants;
-import org.dromara.common.core.constant.GlobalConstants;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.core.utils.SpringUtils;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.core.utils.reflect.ReflectUtils;
-import org.dromara.common.mail.config.properties.MailProperties;
-import org.dromara.common.mail.utils.MailUtils;
-import org.dromara.common.ratelimiter.annotation.RateLimiter;
-import org.dromara.common.ratelimiter.enums.LimitType;
-import org.dromara.common.redis.utils.RedisUtils;
-import org.dromara.common.web.config.properties.CaptchaProperties;
-import org.dromara.common.web.enums.CaptchaType;
-import org.dromara.sms4j.api.SmsBlend;
-import org.dromara.sms4j.api.entity.SmsResponse;
-import org.dromara.sms4j.core.factory.SmsFactory;
-import org.dromara.web.domain.vo.CaptchaVo;
-import org.springframework.expression.Expression;
-import org.springframework.expression.ExpressionParser;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.time.Duration;
-import java.util.LinkedHashMap;
-
-/**
- * 验证码操作处理
- *
- * @author Lion Li
- */
-@SaIgnore
-@Slf4j
-@Validated
-@RequiredArgsConstructor
-@RestController
-public class CaptchaController {
-
- private final CaptchaProperties captchaProperties;
- private final MailProperties mailProperties;
-
- /**
- * 短信验证码
- *
- * @param phonenumber 用户手机号
- */
- @RateLimiter(key = "#phonenumber", time = 60, count = 1)
- @GetMapping("/resource/sms/code")
- public R smsCode(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) {
- String key = GlobalConstants.CAPTCHA_CODE_KEY + phonenumber;
- String code = RandomUtil.randomNumbers(4);
- RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
- // 验证码模板id 自行处理 (查数据库或写死均可)
- String templateId = "";
- LinkedHashMap map = new LinkedHashMap<>(1);
- map.put("code", code);
- SmsBlend smsBlend = SmsFactory.getSmsBlend("config1");
- SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, templateId, map);
- if (!smsResponse.isSuccess()) {
- log.error("验证码短信发送异常 => {}", smsResponse);
- return R.fail(smsResponse.getData().toString());
- }
- return R.ok();
- }
-
- /**
- * 邮箱验证码
- *
- * @param email 邮箱
- */
- @RateLimiter(key = "#email", time = 60, count = 1)
- @GetMapping("/resource/email/code")
- public R emailCode(@NotBlank(message = "{user.email.not.blank}") String email) {
- if (!mailProperties.getEnabled()) {
- return R.fail("当前系统没有开启邮箱功能!");
- }
- String key = GlobalConstants.CAPTCHA_CODE_KEY + email;
- String code = RandomUtil.randomNumbers(4);
- RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
- try {
- MailUtils.sendText(email, "登录验证码", "您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。");
- } catch (Exception e) {
- log.error("验证码短信发送异常 => {}", e.getMessage());
- return R.fail(e.getMessage());
- }
- return R.ok();
- }
-
- /**
- * 生成验证码
- */
- @RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
- @GetMapping("/auth/code")
- public R getCode() {
- CaptchaVo captchaVo = new CaptchaVo();
- boolean captchaEnabled = captchaProperties.getEnable();
- if (!captchaEnabled) {
- captchaVo.setCaptchaEnabled(false);
- return R.ok(captchaVo);
- }
- // 保存验证码信息
- String uuid = IdUtil.simpleUUID();
- String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid;
- // 生成验证码
- CaptchaType captchaType = captchaProperties.getType();
- boolean isMath = CaptchaType.MATH == captchaType;
- Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength();
- CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length);
- AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz());
- captcha.setGenerator(codeGenerator);
- captcha.createCode();
- // 如果是数学验证码,使用SpEL表达式处理验证码结果
- String code = captcha.getCode();
- if (isMath) {
- ExpressionParser parser = new SpelExpressionParser();
- Expression exp = parser.parseExpression(StringUtils.remove(code, "="));
- code = exp.getValue(String.class);
- }
- RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
- captchaVo.setUuid(uuid);
- captchaVo.setImg(captcha.getImageBase64());
- return R.ok(captchaVo);
- }
-
-}
+package org.dromara.web.controller;
+
+import cn.dev33.satoken.annotation.SaIgnore;
+import cn.hutool.captcha.AbstractCaptcha;
+import cn.hutool.captcha.generator.CodeGenerator;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.RandomUtil;
+import jakarta.validation.constraints.NotBlank;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.constant.GlobalConstants;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.reflect.ReflectUtils;
+import org.dromara.common.mail.config.properties.MailProperties;
+import org.dromara.common.mail.utils.MailUtils;
+import org.dromara.common.ratelimiter.annotation.RateLimiter;
+import org.dromara.common.ratelimiter.enums.LimitType;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.web.config.properties.CaptchaProperties;
+import org.dromara.common.web.enums.CaptchaType;
+import org.dromara.sms4j.api.SmsBlend;
+import org.dromara.sms4j.api.entity.SmsResponse;
+import org.dromara.sms4j.core.factory.SmsFactory;
+import org.dromara.web.domain.vo.CaptchaVo;
+import org.springframework.expression.Expression;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.Duration;
+import java.util.LinkedHashMap;
+
+/**
+ * 验证码操作处理
+ *
+ * @author Lion Li
+ */
+@SaIgnore
+@Slf4j
+@Validated
+@RequiredArgsConstructor
+@RestController
+public class CaptchaController {
+
+ private final CaptchaProperties captchaProperties;
+ private final MailProperties mailProperties;
+
+ /**
+ * 短信验证码
+ *
+ * @param phonenumber 用户手机号
+ */
+ @RateLimiter(key = "#phonenumber", time = 60, count = 1)
+ @GetMapping("/resource/sms/code")
+ public R smsCode(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) {
+ String key = GlobalConstants.CAPTCHA_CODE_KEY + phonenumber;
+ String code = RandomUtil.randomNumbers(4);
+ RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
+ // 验证码模板id 自行处理 (查数据库或写死均可)
+ String templateId = "";
+ LinkedHashMap map = new LinkedHashMap<>(1);
+ map.put("code", code);
+ SmsBlend smsBlend = SmsFactory.getSmsBlend("config1");
+ SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, templateId, map);
+ if (!smsResponse.isSuccess()) {
+ log.error("验证码短信发送异常 => {}", smsResponse);
+ return R.fail(smsResponse.getData().toString());
+ }
+ return R.ok();
+ }
+
+ /**
+ * 邮箱验证码
+ *
+ * @param email 邮箱
+ */
+ @RateLimiter(key = "#email", time = 60, count = 1)
+ @GetMapping("/resource/email/code")
+ public R emailCode(@NotBlank(message = "{user.email.not.blank}") String email) {
+ if (!mailProperties.getEnabled()) {
+ return R.fail("当前系统没有开启邮箱功能!");
+ }
+ String key = GlobalConstants.CAPTCHA_CODE_KEY + email;
+ String code = RandomUtil.randomNumbers(4);
+ RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
+ try {
+ MailUtils.sendText(email, "登录验证码", "您本次验证码为:" + code + ",有效性为" + Constants.CAPTCHA_EXPIRATION + "分钟,请尽快填写。");
+ } catch (Exception e) {
+ log.error("验证码短信发送异常 => {}", e.getMessage());
+ return R.fail(e.getMessage());
+ }
+ return R.ok();
+ }
+
+ /**
+ * 生成验证码
+ */
+ @RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
+ @GetMapping("/auth/code")
+ public R getCode() {
+ CaptchaVo captchaVo = new CaptchaVo();
+ boolean captchaEnabled = captchaProperties.getEnable();
+ if (!captchaEnabled) {
+ captchaVo.setCaptchaEnabled(false);
+ return R.ok(captchaVo);
+ }
+ // 保存验证码信息
+ String uuid = IdUtil.simpleUUID();
+ String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid;
+ // 生成验证码
+ CaptchaType captchaType = captchaProperties.getType();
+ boolean isMath = CaptchaType.MATH == captchaType;
+ Integer length = isMath ? captchaProperties.getNumberLength() : captchaProperties.getCharLength();
+ CodeGenerator codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), length);
+ AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz());
+ captcha.setGenerator(codeGenerator);
+ captcha.createCode();
+ // 如果是数学验证码,使用SpEL表达式处理验证码结果
+ String code = captcha.getCode();
+ if (isMath) {
+ ExpressionParser parser = new SpelExpressionParser();
+ Expression exp = parser.parseExpression(StringUtils.remove(code, "="));
+ code = exp.getValue(String.class);
+ }
+ RedisUtils.setCacheObject(verifyKey, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
+ captchaVo.setUuid(uuid);
+ captchaVo.setImg(captcha.getImageBase64());
+ return R.ok(captchaVo);
+ }
+
+}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/IndexController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/IndexController.java
index c40b3a2..f87c6e2 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/controller/IndexController.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/IndexController.java
@@ -1,772 +1,772 @@
-package org.dromara.web.controller;
-
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.dev33.satoken.annotation.SaIgnore;
-import cn.hutool.core.util.ObjectUtil;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.Parameters;
-import jakarta.validation.constraints.NotNull;
-import lombok.RequiredArgsConstructor;
-import org.dromara.common.core.config.RuoYiConfig;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.core.domain.model.LoginUser;
-import org.dromara.common.core.utils.DateUtils;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.idempotent.annotation.RepeatSubmit;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.satoken.utils.LoginHelper;
-import org.dromara.system.domain.bo.SysDeptBo;
-import org.dromara.system.domain.bo.SysPictureBo;
-import org.dromara.system.domain.bo.SysUserBo;
-import org.dromara.system.domain.vo.SysPictureVo;
-import org.dromara.system.domain.vo.SysUserVo;
-import org.dromara.system.service.ISysPictureService;
-import org.dromara.system.service.ISysUserService;
-import org.dromara.web.utils.WxXcxUtils;
-import org.dromara.work.domain.TpReceipt;
-import org.dromara.work.domain.bo.*;
-import org.dromara.work.domain.vo.*;
-import org.dromara.work.service.*;
-import org.springframework.web.bind.annotation.*;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-/**
- * 首页
- *
- * @author Lion Li
- */
-@SaIgnore
-@RequiredArgsConstructor
-@RestController
-public class IndexController {
-
- /**
- * 系统基础配置
- */
- private final RuoYiConfig ruoyiConfig;
-
- private final ITpOrderService tpOrderService;
-
- private final ISysUserService sysUserService;
-
- private final ITpWechatService tpWechatService;
-
- private final ITpReceiptService tpReceiptService;
-
- private final IOrderService orderService;
-
- private final ITpNewOrderService tpNewOrderService;
-
- private final ISysPictureService sysPictureService;
-
- private final ITpProdService tpProdService;
-
- private final ITpFollowService tpFollowService;
-
- private final ITpWorksService tpWorksService;
-
- /**
- * 访问首页,提示语
- */
- @GetMapping("/")
- public String index() {
- return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion());
- }
-
- /**
- * 分页获取画册列表
- */
- @GetMapping("/banner")
- public R> list(SysPictureBo bo, PageQuery pageQuery) {
- bo.setStatus(1L);
- return R.ok(sysPictureService.selectPageList(bo, pageQuery));
- }
-
- /**
- * 根据ID获取画册详情
- */
- @GetMapping("/banner/{id}")
- public R getSysPictureInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
- return R.ok(sysPictureService.queryById(id));
- }
-
- /**
- * 分页获取商品列表
- */
- @GetMapping("/prod")
- public R> list(TpProdBo bo, PageQuery pageQuery) {
- bo.setStatus(1L);
- return R.ok(tpProdService.queryPageList(bo, pageQuery));
- }
-
- /**
- * 根据ID获取商品详情
- */
- @GetMapping("/prod/{id}")
- public R getTpProdInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
- return R.ok(tpProdService.queryById(id));
- }
-
- /**
- * 根据url获取微信JS-SDK使用权限签名
- */
- @PostMapping("/wx/jssdk")
- public R