diff --git a/README.md b/README.md index 887d4d14a..4ffaef9e7 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@

logo

-

RuoYi v3.6.7

+

RuoYi v3.6.5.0.9

基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构

- +

diff --git a/pom.xml b/pom.xml index 90cc5c810..e07cd0ec0 100644 --- a/pom.xml +++ b/pom.xml @@ -1,331 +1,395 @@ - - - 4.0.0 - - com.ruoyi - ruoyi - 3.6.7 - - ruoyi - http://www.ruoyi.vip - 若依微服务系统 - - - 3.6.7 - UTF-8 - UTF-8 - 1.8 - 2.7.18 - 2021.0.9 - 2021.0.6.1 - 2.7.16 - 1.27.2 - 2.3.3 - 2.0.0 - 1.2.27 - 4.3.1 - 2.21.0 - 2.3 - 2.0.60 - 0.9.1 - 8.2.2 - 4.1.2 - 1.6.9 - 2.14.4 - - 9.0.112 - 1.2.13 - 5.3.39 - - - - - - - - - org.springframework - spring-framework-bom - ${spring-framework.version} - pom - import - - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - - - com.alibaba.cloud - spring-cloud-alibaba-dependencies - ${spring-cloud-alibaba.version} - pom - import - - - - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - - - ch.qos.logback - logback-core - ${logback.version} - - - - ch.qos.logback - logback-classic - ${logback.version} - - - - - org.apache.tomcat.embed - tomcat-embed-core - ${tomcat.version} - - - - org.apache.tomcat.embed - tomcat-embed-el - ${tomcat.version} - - - - org.apache.tomcat.embed - tomcat-embed-websocket - ${tomcat.version} - - - - - com.github.tobato - fastdfs-client - ${tobato.version} - - - - - org.springdoc - springdoc-openapi-ui - ${springdoc.version} - - - - - pro.fessional - kaptcha - ${kaptcha.version} - - - - - com.github.pagehelper - pagehelper-spring-boot-starter - ${pagehelper.boot.version} - - - - - commons-io - commons-io - ${commons.io.version} - - - - - org.apache.poi - poi-ooxml - ${poi.version} - - - - - org.apache.velocity - velocity-engine-core - ${velocity.version} - - - - - com.alibaba.fastjson2 - fastjson2 - ${fastjson.version} - - - - - io.jsonwebtoken - jjwt - ${jjwt.version} - - - - - com.alibaba - transmittable-thread-local - ${transmittable-thread-local.version} - - - - - com.ruoyi - ruoyi-common-core - ${ruoyi.version} - - - - - com.ruoyi - ruoyi-common-swagger - ${ruoyi.version} - - - - - com.ruoyi - ruoyi-common-security - ${ruoyi.version} - - - - - com.ruoyi - ruoyi-common-sensitive - ${ruoyi.version} - - - - - com.ruoyi - ruoyi-common-datascope - ${ruoyi.version} - - - - - com.ruoyi - ruoyi-common-datasource - ${ruoyi.version} - - - - - com.ruoyi - ruoyi-common-seata - ${ruoyi.version} - - - - - com.ruoyi - ruoyi-common-log - ${ruoyi.version} - - - - - com.ruoyi - ruoyi-common-redis - ${ruoyi.version} - - - - - com.ruoyi - ruoyi-api-system - ${ruoyi.version} - - - - - - - ruoyi-auth - ruoyi-gateway - ruoyi-visual - ruoyi-modules - ruoyi-api - ruoyi-common - - pom - - - - - org.springframework.cloud - spring-cloud-starter-bootstrap - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${java.version} - ${java.version} - ${project.build.sourceEncoding} - - - - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot.version} - - - - repackage - - - - - - - - - - - public - aliyun nexus - https://maven.aliyun.com/repository/public - - true - - - - - - - public - aliyun nexus - https://maven.aliyun.com/repository/public - - true - - - false - - - - + + + 4.0.0 + + com.ruoyi + ruoyi + 3.6.5.0.9 + + ruoyi + http://www.ruoyi.vip + 若依微服务系统 + + + 3.6.5.0.9 + UTF-8 + UTF-8 + 1.8 + 2.7.18 + 2021.0.9 + 2021.0.6.1 + 2.7.16 + 1.27.2 + 2.3.3 + 2.0.0 + 1.2.23 + 4.3.1 + 2.19.0 + 2.3 + 2.0.53 + 0.9.1 + 8.2.2 + 4.1.2 + 1.6.9 + 2.14.4 + + 9.0.105 + 1.2.13 + 5.3.39 + 2.0.0 + 2.7.9 + + + + + + + + + org.springframework + spring-framework-bom + ${spring-framework.version} + pom + import + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring-cloud-alibaba.version} + pom + import + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + ch.qos.logback + logback-core + ${logback.version} + + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + org.apache.tomcat.embed + tomcat-embed-core + ${tomcat.version} + + + + org.apache.tomcat.embed + tomcat-embed-el + ${tomcat.version} + + + + org.apache.tomcat.embed + tomcat-embed-websocket + ${tomcat.version} + + + + + com.github.tobato + fastdfs-client + ${tobato.version} + + + + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + + + + + pro.fessional + kaptcha + ${kaptcha.version} + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.boot.version} + + + + + commons-io + commons-io + ${commons.io.version} + + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + + org.apache.velocity + velocity-engine-core + ${velocity.version} + + + + + com.alibaba.fastjson2 + fastjson2 + ${fastjson.version} + + + + + io.jsonwebtoken + jjwt + ${jjwt.version} + + + + + com.alibaba + transmittable-thread-local + ${transmittable-thread-local.version} + + + + + com.ruoyi + ruoyi-common-core + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-swagger + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-security + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-sensitive + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-datascope + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-datasource + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-seata + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-log + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common-redis + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-api-system + ${ruoyi.version} + + + de.codecentric + spring-boot-admin-starter-client + ${spring-boot-admin} + + + + + + ruoyi-auth + ruoyi-gateway + ruoyi-visual + ruoyi-modules + ruoyi-api + ruoyi-common + + pom + + + + + org.springframework.cloud + spring-cloud-starter-bootstrap + + + org.springframework.boot + spring-boot-starter-test + test + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test-junit + ${kotlin.version} + test + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.8 + + + add-source + generate-sources + + add-source + + + + src/main/java + src/main/kotlin + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + process-sources + + compile + + + + test-compile + test-compile + + test-compile + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + false + + + + \ No newline at end of file diff --git a/ruoyi-api/pom.xml b/ruoyi-api/pom.xml index 7f28ea28b..04ff21f4a 100644 --- a/ruoyi-api/pom.xml +++ b/ruoyi-api/pom.xml @@ -1,22 +1,22 @@ - - - - com.ruoyi - ruoyi - 3.6.7 - - 4.0.0 - - - ruoyi-api-system - - - ruoyi-api - pom - - - ruoyi-api系统接口 - - - + + + + com.ruoyi + ruoyi + 3.6.5.0.9 + + 4.0.0 + + + ruoyi-api-system + + + ruoyi-api + pom + + + ruoyi-api系统接口 + + + diff --git a/ruoyi-api/ruoyi-api-system/pom.xml b/ruoyi-api/ruoyi-api-system/pom.xml index e5db2dfe9..d0a42dc13 100644 --- a/ruoyi-api/ruoyi-api-system/pom.xml +++ b/ruoyi-api/ruoyi-api-system/pom.xml @@ -1,28 +1,62 @@ - - - - com.ruoyi - ruoyi-api - 3.6.7 - - 4.0.0 - - ruoyi-api-system - - - ruoyi-api-system系统接口模块 - - - - - - - com.ruoyi - ruoyi-common-core - - - - + + + + com.ruoyi + ruoyi-api + 3.6.5.0.9 + + 4.0.0 + + ruoyi-api-system + + + ruoyi-api-system系统接口模块 + + + + + + + com.ruoyi + ruoyi-common-core + + + com.zkjiadi + zkjiadi-mall-api + 1.0.7 + + + com.squareup.okhttp3 + okhttp + + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + process-sources + + compile + + + + test-compile + test-compile + + test-compile + + + + + + \ No newline at end of file diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java index c1a94b3d5..14ab3c53d 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java @@ -1,54 +1,61 @@ -package com.ruoyi.system.api; - -import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import com.ruoyi.common.core.constant.SecurityConstants; -import com.ruoyi.common.core.constant.ServiceNameConstants; -import com.ruoyi.common.core.domain.R; -import com.ruoyi.system.api.domain.SysUser; -import com.ruoyi.system.api.factory.RemoteUserFallbackFactory; -import com.ruoyi.system.api.model.LoginUser; - -/** - * 用户服务 - * - * @author ruoyi - */ -@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class) -public interface RemoteUserService -{ - /** - * 通过用户名查询用户信息 - * - * @param username 用户名 - * @param source 请求来源 - * @return 结果 - */ - @GetMapping("/user/info/{username}") - public R getUserInfo(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); - - /** - * 注册用户信息 - * - * @param sysUser 用户信息 - * @param source 请求来源 - * @return 结果 - */ - @PostMapping("/user/register") - public R registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); - - /** - * 记录用户登录IP地址和登录时间 - * - * @param sysUser 用户信息 - * @param source 请求来源 - * @return 结果 - */ - @PutMapping("/user/recordlogin") - public R recordUserLogin(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); -} +package com.ruoyi.system.api; + +import com.ruoyi.system.api.inner.InnerRemoteUserService; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.constant.ServiceNameConstants; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.factory.RemoteUserFallbackFactory; +import com.ruoyi.system.api.model.LoginUser; + +/** + * 用户服务 + * + * @author ruoyi + */ +@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class) +public interface RemoteUserService extends InnerRemoteUserService +{ + /** + * 通过用户名查询用户信息 + * + * @param username 用户名 + * @param source 请求来源 + * @return 结果 + */ + @GetMapping("/user/info/{username}") + public R getUserInfo(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 注册用户信息 + * + * @param sysUser 用户信息 + * @param source 请求来源 + * @return 结果 + */ + @PostMapping("/user/register") + public R registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 记录用户登录IP地址和登录时间 + * + * @param sysUser 用户信息 + * @param source 请求来源 + * @return 结果 + */ + @PutMapping("/user/recordlogin") + public R recordUserLogin(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 同步至go框架 + */ + @PostMapping("/user/syncGO") + public R syncGO(@RequestBody SysUser sysUser); +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java index 0658deef7..f5fda61c3 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java @@ -81,6 +81,12 @@ public class SysUser extends BaseEntity }) private SysDept dept; + /** 部门对象 */ + @Excels({ + @Excel(name = "微信UnionId", targetAttr = "wxUnionId", type = Type.EXPORT) + }) + private KSysUserAccount sysUserAccount; + /** 角色对象 */ private List roles; @@ -271,6 +277,14 @@ public class SysUser extends BaseEntity this.dept = dept; } + public KSysUserAccount getSysUserAccount() { + return sysUserAccount; + } + + public void setSysUserAccount(KSysUserAccount sysUserAccount) { + this.sysUserAccount = sysUserAccount; + } + public List getRoles() { return roles; @@ -334,6 +348,7 @@ public class SysUser extends BaseEntity .append("updateTime", getUpdateTime()) .append("remark", getRemark()) .append("dept", getDept()) + .append("userAccount", getSysUserAccount()) .toString(); } } diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteUserFallbackFactory.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteUserFallbackFactory.java index d0ae76a61..8b92b528a 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteUserFallbackFactory.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteUserFallbackFactory.java @@ -1,47 +1,93 @@ -package com.ruoyi.system.api.factory; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.cloud.openfeign.FallbackFactory; -import org.springframework.stereotype.Component; -import com.ruoyi.common.core.domain.R; -import com.ruoyi.system.api.RemoteUserService; -import com.ruoyi.system.api.domain.SysUser; -import com.ruoyi.system.api.model.LoginUser; - -/** - * 用户服务降级处理 - * - * @author ruoyi - */ -@Component -public class RemoteUserFallbackFactory implements FallbackFactory -{ - private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class); - - @Override - public RemoteUserService create(Throwable throwable) - { - log.error("用户服务调用失败:{}", throwable.getMessage()); - return new RemoteUserService() - { - @Override - public R getUserInfo(String username, String source) - { - return R.fail("获取用户失败:" + throwable.getMessage()); - } - - @Override - public R registerUserInfo(SysUser sysUser, String source) - { - return R.fail("注册用户失败:" + throwable.getMessage()); - } - - @Override - public R recordUserLogin(SysUser sysUser, String source) - { - return R.fail("记录用户登录信息失败:" + throwable.getMessage()); - } - }; - } -} +package com.ruoyi.system.api.factory; + +import com.github.pagehelper.Page; +import com.ruoyi.system.api.domain.KSysUserAccount; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.api.RemoteUserService; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.model.LoginUser; + +/** + * 用户服务降级处理 + * + * @author ruoyi + */ +@Component +public class RemoteUserFallbackFactory implements FallbackFactory +{ + private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class); + + @Override + public RemoteUserService create(Throwable throwable) + { + log.error("用户服务调用失败:{}", throwable.getMessage()); + return new RemoteUserService() + { + @NotNull + @Override + public R getById_Inner(Long userId, @NotNull String source) { + return R.fail("获取用户失败:" + throwable.getMessage()); + } + + @Override + public R getByWxUnionId_Inner(String unionid, String source) { + return R.fail("获取用户失败:" + throwable.getMessage()); + } + + @Override + public R getUserInfo(String username, String source) + { + return R.fail("获取用户失败:" + throwable.getMessage()); + } + + @NotNull + @Override + public R getByPhoneNumber_Inner(@NotNull String phoneNumber, @NotNull String source) { + return R.fail("获取用户失败:" + throwable.getMessage()); + } + + @Override + public R> findByPhoneNumberStartingWith_Inner(String phoneNumber, String source) { + return R.fail("获取用户失败:" + throwable.getMessage()); + } + + @Override + public R registerUserInfo(SysUser sysUser, String source) + { + return R.fail("注册用户失败:" + throwable.getMessage()); + } + + @Override + public R recordUserLogin(SysUser sysUser, String source) + { + return R.fail("记录用户登录信息失败:" + throwable.getMessage()); + } + + @Override + public R syncGO(SysUser sysUser) { + return R.fail("同步用户信息至GO失败:" + throwable.getMessage()); + } + + @NotNull + @Override + public R edit_Inner(@NotNull LoginUser user, @NotNull String source) { + return R.fail("修改用户信息失败:" + throwable.getMessage()); + } + + @Override + public R registerUserBySysUserAccount_Inner(KSysUserAccount sysUserAccount, Long deptId, String source) { + return R.fail("注册用户失败:" + throwable.getMessage()); + } + + @Override + public R unbindWeixin_Inner(Long userId, String source) { + return R.fail("解绑微信失败:" + throwable.getMessage()); + } + }; + } +} diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/inner/InnerRemoteUserService.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/inner/InnerRemoteUserService.java new file mode 100644 index 000000000..f2d038087 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/inner/InnerRemoteUserService.java @@ -0,0 +1,77 @@ +package com.ruoyi.system.api.inner; + +import com.github.pagehelper.Page; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.api.domain.KSysUserAccount; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.model.LoginUser; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +public interface InnerRemoteUserService { + /** + * 通过用户ID查询用户信息 + * + * @param userId 用户ID + * @param source 请求来源 + * @return 结果 + */ + @GetMapping("/inner/user/detail/{userId}") + R getById_Inner(@PathVariable("userId") Long userId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 通过用户ID查询用户信息 + * + * @param unionid 用户微信unionid + * @param source 请求来源 + * @return 结果 + */ + @GetMapping("/inner/user/detail/wx/unionid/{unionid}") + R getByWxUnionId_Inner(@PathVariable("unionid") String unionid, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 通过手机号查询用户信息 + * + * @param phoneNumber 用户名 + * @param source 请求来源 + * @return 结果 + */ + @GetMapping("/inner/user/info/phoneNumber/{phoneNumber:\\d+}") + R getByPhoneNumber_Inner(@PathVariable("phoneNumber") String phoneNumber, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 通过手机号查询用户信息 + * + * @param phoneNumber 用户名 + * @param source 请求来源 + * @return 结果 + */ + @GetMapping("/inner/user/list/phoneNumber/{phoneNumber:\\d+}") + R> findByPhoneNumberStartingWith_Inner(@PathVariable("phoneNumber") String phoneNumber, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + @PutMapping("/inner/user") + R edit_Inner(@RequestBody LoginUser user, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 注册用户信息 + * + * @param sysUserAccount 包含微信unionId + * @param deptId 包含部门ID + * @param source 请求来源 + * @return 结果 + */ + @PostMapping("/inner/user/register/dept/{deptId}/wx/unionid") + R registerUserBySysUserAccount_Inner(@RequestBody KSysUserAccount sysUserAccount, @PathVariable("deptId") Long deptId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 解绑微信 + * + * @param userId 用户ID + * @param source 请求来源 + * @return 结果 + */ + @PutMapping("/inner/user/{userId}/unbind/weixin") + R unbindWeixin_Inner(@PathVariable("userId") Long userId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); +} \ No newline at end of file diff --git a/ruoyi-api/ruoyi-api-system/src/main/kotlin/com/ruoyi/system/api/RemoteSysNoticeService.kt b/ruoyi-api/ruoyi-api-system/src/main/kotlin/com/ruoyi/system/api/RemoteSysNoticeService.kt new file mode 100644 index 000000000..8937034ef --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/kotlin/com/ruoyi/system/api/RemoteSysNoticeService.kt @@ -0,0 +1,19 @@ +package com.ruoyi.system.api + +import com.ruoyi.common.core.constant.ServiceNameConstants +import com.ruoyi.system.api.factory.RemoteUserFallbackFactory +import com.ruoyi.system.api.inner.InnerRemoteSysNoticeService +import org.springframework.cloud.openfeign.FeignClient + + +/** + * 公告服务 + * @author 栾成伟 + */ +@FeignClient( + contextId = "remoteSysNoticeService", + value = ServiceNameConstants.SYSTEM_SERVICE, + fallbackFactory = RemoteUserFallbackFactory::class +) +interface RemoteSysNoticeService : InnerRemoteSysNoticeService { +} \ No newline at end of file diff --git a/ruoyi-api/ruoyi-api-system/src/main/kotlin/com/ruoyi/system/api/domain/KSysUserAccount.kt b/ruoyi-api/ruoyi-api-system/src/main/kotlin/com/ruoyi/system/api/domain/KSysUserAccount.kt new file mode 100644 index 000000000..7da28c373 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/kotlin/com/ruoyi/system/api/domain/KSysUserAccount.kt @@ -0,0 +1,21 @@ +package com.ruoyi.system.api.domain + +import com.cyl.manager.ums.domain.entity.MemberWechat + +open class KSysUserAccount : MemberWechat() { + /** 用户ID */ + open var userId: Long? = null + set(value) { + memberId = value + field = value + } + get() = memberId + + /** 微信UnionId */ + open var wxUnionId: String? = null + set(value) { + unionid = value + field = value + } + get() = unionid +} \ No newline at end of file diff --git a/ruoyi-api/ruoyi-api-system/src/main/kotlin/com/ruoyi/system/api/factory/RemoteSysNoticeFallbackFactory.kt b/ruoyi-api/ruoyi-api-system/src/main/kotlin/com/ruoyi/system/api/factory/RemoteSysNoticeFallbackFactory.kt new file mode 100644 index 000000000..d3604c1a2 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/kotlin/com/ruoyi/system/api/factory/RemoteSysNoticeFallbackFactory.kt @@ -0,0 +1,24 @@ +package com.ruoyi.system.api.factory + +import com.ruoyi.common.core.domain.R +import com.ruoyi.system.api.RemoteSysNoticeService +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.cloud.openfeign.FallbackFactory +import org.springframework.stereotype.Component + +@Component +open class RemoteSysNoticeFallbackFactory : FallbackFactory { + companion object { + var log: Logger = LoggerFactory.getLogger(RemoteSysNoticeFallbackFactory::class.java) + } + + override fun create(throwable: Throwable): RemoteSysNoticeService { + log.error("公告服务调用失败:{}", throwable.message) + return object : RemoteSysNoticeService { + override fun getById_Inner(noticeId: Long, source: String): R { + return R.fail("获取公告失败") + } + } + } +} \ No newline at end of file diff --git a/ruoyi-api/ruoyi-api-system/src/main/kotlin/com/ruoyi/system/api/inner/InnerRemoteSysNoticeService.kt b/ruoyi-api/ruoyi-api-system/src/main/kotlin/com/ruoyi/system/api/inner/InnerRemoteSysNoticeService.kt new file mode 100644 index 000000000..509fb9ff3 --- /dev/null +++ b/ruoyi-api/ruoyi-api-system/src/main/kotlin/com/ruoyi/system/api/inner/InnerRemoteSysNoticeService.kt @@ -0,0 +1,20 @@ +package com.ruoyi.system.api.inner + +import com.ruoyi.common.core.constant.SecurityConstants +import com.ruoyi.common.core.domain.R +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestHeader +import org.springframework.web.bind.annotation.RequestParam + +interface InnerRemoteSysNoticeService { + /** + * 根据公告ID查询公告信息 + * @param noticeId 公告ID + * @return 公告信息 + */ + @GetMapping("/inner/notice/detail") + fun getById_Inner( + @RequestParam("noticeId") noticeId: Long, + @RequestHeader(SecurityConstants.FROM_SOURCE) source: String + ): R +} \ No newline at end of file diff --git a/ruoyi-auth/pom.xml b/ruoyi-auth/pom.xml index 0caca09aa..827294415 100644 --- a/ruoyi-auth/pom.xml +++ b/ruoyi-auth/pom.xml @@ -1,74 +1,77 @@ - - - com.ruoyi - ruoyi - 3.6.7 - - 4.0.0 - - ruoyi-auth - - - ruoyi-auth认证授权中心 - - - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-discovery - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-config - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-sentinel - - - - - org.springframework.boot - spring-boot-starter-web - - - - - org.springframework.boot - spring-boot-starter-actuator - - - - - com.ruoyi - ruoyi-common-security - - - - - - ${project.artifactId} - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - - - + + + com.ruoyi + ruoyi + 3.6.5.0.9 + + 4.0.0 + + ruoyi-auth + + + ruoyi-auth认证授权中心 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + com.ruoyi + ruoyi-common-security + + + de.codecentric + spring-boot-admin-starter-client + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + + diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java index 3b93514ed..300db923e 100644 --- a/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/controller/TokenController.java @@ -1,11 +1,11 @@ package com.ruoyi.auth.controller; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; import com.ruoyi.auth.form.LoginBody; import com.ruoyi.auth.form.RegisterBody; import com.ruoyi.auth.service.SysLoginService; @@ -46,11 +46,16 @@ public class TokenController String token = SecurityUtils.getToken(request); if (StringUtils.isNotEmpty(token)) { - String username = JwtUtils.getUserName(token); - // 删除用户缓存记录 - AuthUtil.logoutByToken(token); - // 记录用户退出日志 - sysLoginService.logout(username); + try{ + String username = JwtUtils.getUserName(token); + // 删除用户缓存记录 + AuthUtil.logoutByToken(token); + // 记录用户退出日志 + sysLoginService.logout(username); + }catch (Exception e){ + System.out.println(e.getMessage()); + return R.ok(); + } } return R.ok(); } @@ -75,4 +80,18 @@ public class TokenController sysLoginService.register(registerBody.getUsername(), registerBody.getPassword()); return R.ok(); } + + + /** + * 验证令牌的端点 + * 该方法用于验证客户端提供的令牌有效性 + * + * @return ResponseEntity: 返回一个空的响应体,表示令牌验证通过 + */ + @RequestMapping("verify") + public ResponseEntity verifyToken(HttpServletResponse response) { + response.setHeader("X-User-ID", String.valueOf(SecurityUtils.getUserId())); + // 返回一个HTTP 200 OK响应,表示令牌有效 + return ResponseEntity.ok().build(); + } } diff --git a/ruoyi-auth/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java b/ruoyi-auth/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java new file mode 100644 index 000000000..68e35e6b1 --- /dev/null +++ b/ruoyi-auth/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java @@ -0,0 +1,140 @@ +/* + * Copyright 2012-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.endpoint.web; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +/** + * Configuration properties for web management endpoints. + * + * @author Madhura Bhave + * @author Phillip Webb + * @since 2.0.0 + */ +@ConfigurationProperties(prefix = "management.endpoints.web") +public class WebEndpointProperties { + + private final Exposure exposure = new Exposure(); + + /** + * Base path for Web endpoints. Relative to the servlet context path + * (server.servlet.context-path) or WebFlux base path (spring.webflux.base-path) when + * the management server is sharing the main server port. Relative to the management + * server base path (management.server.base-path) when a separate management server + * port (management.server.port) is configured. + */ + private String basePath = "/actuator"; + private String baseUrl = null; + + /** + * Mapping between endpoint IDs and the path that should expose them. + */ + private final Map pathMapping = new LinkedHashMap<>(); + + private final Discovery discovery = new Discovery(); + + public Exposure getExposure() { + return this.exposure; + } + + public String getBasePath() { + return this.basePath; + } + + public void setBasePath(String basePath) { + Assert.isTrue(basePath.isEmpty() || basePath.startsWith("/"), "Base path must start with '/' or be empty"); + this.basePath = cleanBasePath(basePath); + } + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + private String cleanBasePath(String basePath) { + if (StringUtils.hasText(basePath) && basePath.endsWith("/")) { + return basePath.substring(0, basePath.length() - 1); + } + return basePath; + } + + public Map getPathMapping() { + return this.pathMapping; + } + + public Discovery getDiscovery() { + return this.discovery; + } + + public static class Exposure { + + /** + * Endpoint IDs that should be included or '*' for all. + */ + private Set include = new LinkedHashSet<>(); + + /** + * Endpoint IDs that should be excluded or '*' for all. + */ + private Set exclude = new LinkedHashSet<>(); + + public Set getInclude() { + return this.include; + } + + public void setInclude(Set include) { + this.include = include; + } + + public Set getExclude() { + return this.exclude; + } + + public void setExclude(Set exclude) { + this.exclude = exclude; + } + + } + + public static class Discovery { + + /** + * Whether the discovery page is enabled. + */ + private boolean enabled = true; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + } + +} diff --git a/ruoyi-auth/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java b/ruoyi-auth/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java new file mode 100644 index 000000000..1c7dae1bb --- /dev/null +++ b/ruoyi-auth/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java @@ -0,0 +1,113 @@ +/* + * Copyright 2012-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.servlet; + +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.endpoint.web.*; +import org.springframework.context.annotation.Lazy; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.util.pattern.PathPatternParser; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +/** + * A custom {@link HandlerMapping} that makes web endpoints available over HTTP using + * Spring MVC. + * + * @author Andy Wilkinson + * @author Phillip Webb + * @since 2.0.0 + */ +public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerMapping { + + private final EndpointLinksResolver linksResolver; + @Lazy + @Resource + private WebEndpointProperties webEndpointProperties; + + /** + * Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings + * for the given endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param endpointMediaTypes media types consumed and produced by the endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered + */ + public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, + EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, + EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping) { + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping); + this.linksResolver = linksResolver; + setOrder(-100); + } + + /** + * Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings + * for the given endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param endpointMediaTypes media types consumed and produced by the endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered + * @param pathPatternParser the path pattern parser + */ + public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, + EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, + EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping, + PathPatternParser pathPatternParser) { + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping, + pathPatternParser); + this.linksResolver = linksResolver; + setOrder(-100); + } + + @Override + protected LinksHandler getLinksHandler() { + return new WebMvcLinksHandler(); + } + + /** + * Handler for root endpoint providing links. + */ + class WebMvcLinksHandler implements LinksHandler { + + @Override + @ResponseBody + public Map> links(HttpServletRequest request, HttpServletResponse response) { + return Collections.singletonMap("_links", + WebMvcEndpointHandlerMapping.this.linksResolver.resolveLinks(ObjectUtils.isEmpty(webEndpointProperties.getBaseUrl())?request.getRequestURL().toString():(webEndpointProperties.getBaseUrl()+webEndpointProperties.getBasePath()))); + } + + @Override + public String toString() { + return "Actuator root web endpoint"; + } + + } + +} diff --git a/ruoyi-auth/src/main/resources/bootstrap-dev-prod.yml b/ruoyi-auth/src/main/resources/bootstrap-dev-prod.yml new file mode 100644 index 000000000..98e5063a3 --- /dev/null +++ b/ruoyi-auth/src/main/resources/bootstrap-dev-prod.yml @@ -0,0 +1,33 @@ +# Tomcat +server: + port: 9200 + +#测试环境 +spring: + application: + # 应用名称 + name: ruoyi-auth + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA +logging: + file: + name: prod-ruoyi-auth.log + pattern: + file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx" \ No newline at end of file diff --git a/ruoyi-auth/src/main/resources/bootstrap-dev.yml b/ruoyi-auth/src/main/resources/bootstrap-dev.yml new file mode 100644 index 000000000..adb73ea13 --- /dev/null +++ b/ruoyi-auth/src/main/resources/bootstrap-dev.yml @@ -0,0 +1,33 @@ +# Tomcat +server: + port: 9200 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-auth + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA +logging: + file: + name: dev-ruoyi-auth.log + pattern: + file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx" \ No newline at end of file diff --git a/ruoyi-auth/src/main/resources/bootstrap-prod.yml b/ruoyi-auth/src/main/resources/bootstrap-prod.yml new file mode 100644 index 000000000..fb65d54a8 --- /dev/null +++ b/ruoyi-auth/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,34 @@ +# Tomcat +server: + port: 9200 + +#测试环境 +spring: + application: + # 应用名称 + name: ruoyi-auth + cloud: + nacos: + discovery: + ip: 8.155.60.167 + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA +logging: + file: + name: prod-ruoyi-auth.log + pattern: + file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx" \ No newline at end of file diff --git a/ruoyi-auth/src/main/resources/bootstrap-test.yml b/ruoyi-auth/src/main/resources/bootstrap-test.yml new file mode 100644 index 000000000..4f32aefc8 --- /dev/null +++ b/ruoyi-auth/src/main/resources/bootstrap-test.yml @@ -0,0 +1,33 @@ +# Tomcat +server: + port: 9200 + +#测试环境 +spring: + application: + # 应用名称 + name: ruoyi-auth + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA +logging: + file: + name: test-ruoyi-auth.log + pattern: + file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx" \ No newline at end of file diff --git a/ruoyi-auth/src/main/resources/bootstrap.yml b/ruoyi-auth/src/main/resources/bootstrap.yml index f456b03c0..03234a17e 100644 --- a/ruoyi-auth/src/main/resources/bootstrap.yml +++ b/ruoyi-auth/src/main/resources/bootstrap.yml @@ -1,25 +1,4 @@ -# Tomcat -server: - port: 9200 - -# Spring -spring: - application: - # 应用名称 - name: ruoyi-auth - profiles: - # 环境配置 - active: dev - cloud: - nacos: - discovery: - # 服务注册地址 - server-addr: 127.0.0.1:8848 - config: - # 配置中心地址 - server-addr: 127.0.0.1:8848 - # 配置文件格式 - file-extension: yml - # 共享配置 - shared-configs: - - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# Spring默认环境配置 +spring: + profiles: + active: dev \ No newline at end of file diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index a28b7720e..34d7d3e07 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -1,30 +1,30 @@ - - - - com.ruoyi - ruoyi - 3.6.7 - - 4.0.0 - - - ruoyi-common-log - ruoyi-common-core - ruoyi-common-redis - ruoyi-common-seata - ruoyi-common-swagger - ruoyi-common-security - ruoyi-common-sensitive - ruoyi-common-datascope - ruoyi-common-datasource - - - ruoyi-common - pom - - - ruoyi-common通用模块 - - - + + + + com.ruoyi + ruoyi + 3.6.5.0.9 + + 4.0.0 + + + ruoyi-common-log + ruoyi-common-core + ruoyi-common-redis + ruoyi-common-seata + ruoyi-common-swagger + ruoyi-common-security + ruoyi-common-sensitive + ruoyi-common-datascope + ruoyi-common-datasource + + + ruoyi-common + pom + + + ruoyi-common通用模块 + + + diff --git a/ruoyi-common/ruoyi-common-core/pom.xml b/ruoyi-common/ruoyi-common-core/pom.xml index 7809e0454..4dadeb1c3 100644 --- a/ruoyi-common/ruoyi-common-core/pom.xml +++ b/ruoyi-common/ruoyi-common-core/pom.xml @@ -1,112 +1,112 @@ - - - - com.ruoyi - ruoyi-common - 3.6.7 - - 4.0.0 - - ruoyi-common-core - - - ruoyi-common-core核心模块 - - - - - - - org.springframework.cloud - spring-cloud-starter-openfeign - - - - - org.springframework.cloud - spring-cloud-starter-loadbalancer - - - - - org.springframework - spring-context-support - - - - - org.springframework - spring-web - - - - - com.alibaba - transmittable-thread-local - - - - - com.github.pagehelper - pagehelper-spring-boot-starter - - - - - org.springframework.boot - spring-boot-starter-validation - - - - - com.fasterxml.jackson.core - jackson-databind - - - - - com.alibaba.fastjson2 - fastjson2 - - - - - io.jsonwebtoken - jjwt - - - - - javax.xml.bind - jaxb-api - - - - - org.apache.commons - commons-lang3 - - - - - commons-io - commons-io - - - - - org.apache.poi - poi-ooxml - - - - - javax.servlet - javax.servlet-api - - - - - + + + + com.ruoyi + ruoyi-common + 3.6.5.0.9 + + 4.0.0 + + ruoyi-common-core + + + ruoyi-common-core核心模块 + + + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + + + org.springframework + spring-context-support + + + + + org.springframework + spring-web + + + + + com.alibaba + transmittable-thread-local + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-validation + + + + + com.fasterxml.jackson.core + jackson-databind + + + + + com.alibaba.fastjson2 + fastjson2 + + + + + io.jsonwebtoken + jjwt + + + + + javax.xml.bind + jaxb-api + + + + + org.apache.commons + commons-lang3 + + + + + commons-io + commons-io + + + + + org.apache.poi + poi-ooxml + + + + + javax.servlet + javax.servlet-api + + + + + diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java index 7e790ff96..0d69def5c 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/SecurityConstants.java @@ -12,6 +12,20 @@ public class SecurityConstants */ public static final String DETAILS_USER_ID = "user_id"; + /** + * 用户ID字段 + */ + public static final String DETAILS_SUB = "sub"; + + /** + * 用户ID字段 + */ + public static final String DETAILS_IAT= "iat"; + /** + * 用户ID字段 + */ + public static final String DETAILS_EXP= "exp"; + /** * 用户名字段 */ @@ -22,6 +36,11 @@ public class SecurityConstants */ public static final String AUTHORIZATION_HEADER = "Authorization"; + /** + * WEBSOCKET头字段 + */ + public final static String WEBSOCKET_HEADER = "Sec-WebSocket-Key"; + /** * 请求来源 */ diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TokenConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TokenConstants.java index a373028e4..2de45edd0 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TokenConstants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/TokenConstants.java @@ -16,5 +16,4 @@ public class TokenConstants * 令牌秘钥 */ public final static String SECRET = "abcdefghijklmnopqrstuvwxyz"; - } diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java index abe93c0c0..14ea876c8 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/JwtUtils.java @@ -1,13 +1,18 @@ package com.ruoyi.common.core.utils; +import java.util.Base64; import java.util.Map; import com.ruoyi.common.core.constant.SecurityConstants; import com.ruoyi.common.core.constant.TokenConstants; +import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.text.Convert; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; +import javax.naming.AuthenticationException; +import javax.servlet.http.HttpServletResponse; + /** * Jwt工具类 * @@ -15,7 +20,7 @@ import io.jsonwebtoken.SignatureAlgorithm; */ public class JwtUtils { - public static String secret = TokenConstants.SECRET; + public static String secret = Base64.getEncoder().encodeToString(TokenConstants.SECRET.getBytes()) ; /** * 从数据声明生成令牌 diff --git a/ruoyi-common/ruoyi-common-datascope/pom.xml b/ruoyi-common/ruoyi-common-datascope/pom.xml index 19525a265..9d2e3f7e7 100644 --- a/ruoyi-common/ruoyi-common-datascope/pom.xml +++ b/ruoyi-common/ruoyi-common-datascope/pom.xml @@ -1,27 +1,27 @@ - - - - com.ruoyi - ruoyi-common - 3.6.7 - - 4.0.0 - - ruoyi-common-datascope - - - ruoyi-common-datascope权限范围 - - - - - - - com.ruoyi - ruoyi-common-security - - - + + + + com.ruoyi + ruoyi-common + 3.6.5.0.9 + + 4.0.0 + + ruoyi-common-datascope + + + ruoyi-common-datascope权限范围 + + + + + + + com.ruoyi + ruoyi-common-security + + + \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-datasource/pom.xml b/ruoyi-common/ruoyi-common-datasource/pom.xml index 7edcb15b6..2b473a07b 100644 --- a/ruoyi-common/ruoyi-common-datasource/pom.xml +++ b/ruoyi-common/ruoyi-common-datasource/pom.xml @@ -1,35 +1,35 @@ - - - - com.ruoyi - ruoyi-common - 3.6.7 - - 4.0.0 - - ruoyi-common-datasource - - - ruoyi-common-datasource多数据源 - - - - - - - com.alibaba - druid-spring-boot-starter - ${druid.version} - - - - - com.baomidou - dynamic-datasource-spring-boot-starter - ${dynamic-ds.version} - - - + + + + com.ruoyi + ruoyi-common + 3.6.5.0.9 + + 4.0.0 + + ruoyi-common-datasource + + + ruoyi-common-datasource多数据源 + + + + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + + com.baomidou + dynamic-datasource-spring-boot-starter + ${dynamic-ds.version} + + + \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-log/pom.xml b/ruoyi-common/ruoyi-common-log/pom.xml index 7bc45a7af..2b015834a 100644 --- a/ruoyi-common/ruoyi-common-log/pom.xml +++ b/ruoyi-common/ruoyi-common-log/pom.xml @@ -1,27 +1,27 @@ - - - - com.ruoyi - ruoyi-common - 3.6.7 - - 4.0.0 - - ruoyi-common-log - - - ruoyi-common-log日志记录 - - - - - - - com.ruoyi - ruoyi-common-security - - - + + + + com.ruoyi + ruoyi-common + 3.6.5.0.9 + + 4.0.0 + + ruoyi-common-log + + + ruoyi-common-log日志记录 + + + + + + + com.ruoyi + ruoyi-common-security + + + \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-redis/pom.xml b/ruoyi-common/ruoyi-common-redis/pom.xml index 3c889080e..9b5611dd8 100644 --- a/ruoyi-common/ruoyi-common-redis/pom.xml +++ b/ruoyi-common/ruoyi-common-redis/pom.xml @@ -1,33 +1,33 @@ - - - - com.ruoyi - ruoyi-common - 3.6.7 - - 4.0.0 - - ruoyi-common-redis - - - ruoyi-common-redis缓存服务 - - - - - - - org.springframework.boot - spring-boot-starter-data-redis - - - - - com.ruoyi - ruoyi-common-core - - - + + + + com.ruoyi + ruoyi-common + 3.6.5.0.9 + + 4.0.0 + + ruoyi-common-redis + + + ruoyi-common-redis缓存服务 + + + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + com.ruoyi + ruoyi-common-core + + + \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-seata/pom.xml b/ruoyi-common/ruoyi-common-seata/pom.xml index 4910a7a96..e4e65fcd4 100644 --- a/ruoyi-common/ruoyi-common-seata/pom.xml +++ b/ruoyi-common/ruoyi-common-seata/pom.xml @@ -1,27 +1,27 @@ - - - - com.ruoyi - ruoyi-common - 3.6.7 - - 4.0.0 - - ruoyi-common-seata - - - ruoyi-common-seata分布式事务 - - - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-seata - - - + + + + com.ruoyi + ruoyi-common + 3.6.5.0.9 + + 4.0.0 + + ruoyi-common-seata + + + ruoyi-common-seata分布式事务 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-seata + + + \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-security/pom.xml b/ruoyi-common/ruoyi-common-security/pom.xml index 2039916b4..b9ec03f55 100644 --- a/ruoyi-common/ruoyi-common-security/pom.xml +++ b/ruoyi-common/ruoyi-common-security/pom.xml @@ -1,39 +1,39 @@ - - - - com.ruoyi - ruoyi-common - 3.6.7 - - 4.0.0 - - ruoyi-common-security - - - ruoyi-common-security安全模块 - - - - - - - org.springframework - spring-webmvc - - - - - com.ruoyi - ruoyi-api-system - - - - - com.ruoyi - ruoyi-common-redis - - - - - + + + + com.ruoyi + ruoyi-common + 3.6.5.0.9 + + 4.0.0 + + ruoyi-common-security + + + ruoyi-common-security安全模块 + + + + + + + org.springframework + spring-webmvc + + + + + com.ruoyi + ruoyi-api-system + + + + + com.ruoyi + ruoyi-common-redis + + + + + diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java index 0a63b851e..1da75d608 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java @@ -1,9 +1,15 @@ package com.ruoyi.common.security.service; +import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; + +import com.alibaba.fastjson.JSON; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.impl.DefaultClaims; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -61,7 +67,10 @@ public class TokenService claimsMap.put(SecurityConstants.USER_KEY, token); claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId); claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName); - + claimsMap.put(SecurityConstants.DETAILS_SUB,userId); + int now = Math.toIntExact(System.currentTimeMillis() / 1000); + claimsMap.put(SecurityConstants.DETAILS_IAT,now); + claimsMap.put(SecurityConstants.DETAILS_EXP,now+TOKEN_EXPIRE_TIME*60); // 接口返回信息 Map rspMap = new HashMap(); rspMap.put("access_token", JwtUtils.createToken(claimsMap)); diff --git a/ruoyi-common/ruoyi-common-sensitive/pom.xml b/ruoyi-common/ruoyi-common-sensitive/pom.xml index 8cf75f319..8bd4be024 100644 --- a/ruoyi-common/ruoyi-common-sensitive/pom.xml +++ b/ruoyi-common/ruoyi-common-sensitive/pom.xml @@ -5,7 +5,7 @@ com.ruoyi ruoyi-common - 3.6.7 + 3.6.5.0.9 4.0.0 diff --git a/ruoyi-common/ruoyi-common-swagger/pom.xml b/ruoyi-common/ruoyi-common-swagger/pom.xml index 1cc4b1f03..1c1d4469e 100644 --- a/ruoyi-common/ruoyi-common-swagger/pom.xml +++ b/ruoyi-common/ruoyi-common-swagger/pom.xml @@ -1,33 +1,33 @@ - - - - com.ruoyi - ruoyi-common - 3.6.7 - - 4.0.0 - - ruoyi-common-swagger - - - ruoyi-common-swagger系统接口 - - - - - - - org.springframework.boot - spring-boot-starter-web - - - - - org.springdoc - springdoc-openapi-ui - - - - + + + + com.ruoyi + ruoyi-common + 3.6.5.0.9 + + 4.0.0 + + ruoyi-common-swagger + + + ruoyi-common-swagger系统接口 + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springdoc + springdoc-openapi-ui + + + + diff --git a/ruoyi-gateway/pom.xml b/ruoyi-gateway/pom.xml index d22ef271c..2027f7c28 100644 --- a/ruoyi-gateway/pom.xml +++ b/ruoyi-gateway/pom.xml @@ -1,105 +1,166 @@ - - - com.ruoyi - ruoyi - 3.6.7 - - 4.0.0 - - ruoyi-gateway - - - ruoyi-gateway网关模块 - - - - - - - org.springframework.cloud - spring-cloud-starter-gateway - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-discovery - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-config - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-sentinel - - - - - com.alibaba.cloud - spring-cloud-alibaba-sentinel-gateway - - - - - com.alibaba.csp - sentinel-datasource-nacos - - - - - org.springframework.boot - spring-boot-starter-actuator - - - - - org.springframework.cloud - spring-cloud-loadbalancer - - - - - pro.fessional - kaptcha - - - - - com.ruoyi - ruoyi-common-redis - - - - - org.springdoc - springdoc-openapi-webflux-ui - ${springdoc.version} - - - - - - ${project.artifactId} - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - - - + + + com.ruoyi + ruoyi + 3.6.5.0.9 + + 4.0.0 + + ruoyi-gateway + + + ruoyi-gateway网关模块 + + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + com.alibaba.cloud + spring-cloud-alibaba-sentinel-gateway + + + + + com.alibaba.csp + sentinel-datasource-nacos + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.springframework.cloud + spring-cloud-loadbalancer + + + + + pro.fessional + kaptcha + + + + + com.ruoyi + ruoyi-common-redis + + + + com.squareup.okhttp3 + okhttp + 3.12.13 + + + com.ujcms + ujcms-commons + 9.6.0.0.1 + + + org.springframework + spring-core + + + org.springframework + spring-web + + + + + + + org.springdoc + springdoc-openapi-webflux-ui + ${springdoc.version} + + + + + + + + de.codecentric + spring-boot-admin-starter-client + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + default-compile + none + + + default-testCompile + none + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + 16 + 16 + + + + + + diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/CaptchaConfig.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/CaptchaConfig.java index 963425e6c..db51775c4 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/CaptchaConfig.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/CaptchaConfig.java @@ -1,83 +1,115 @@ -package com.ruoyi.gateway.config; - -import java.util.Properties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import com.google.code.kaptcha.impl.DefaultKaptcha; -import com.google.code.kaptcha.util.Config; -import static com.google.code.kaptcha.Constants.*; - -/** - * 验证码配置 - * - * @author ruoyi - */ -@Configuration -public class CaptchaConfig -{ - @Bean(name = "captchaProducer") - public DefaultKaptcha getKaptchaBean() - { - DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); - Properties properties = new Properties(); - // 是否有边框 默认为true 我们可以自己设置yes,no - properties.setProperty(KAPTCHA_BORDER, "yes"); - // 验证码文本字符颜色 默认为Color.BLACK - properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); - // 验证码图片宽度 默认为200 - properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); - // 验证码图片高度 默认为50 - properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); - // 验证码文本字符大小 默认为40 - properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); - // KAPTCHA_SESSION_KEY - properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); - // 验证码文本字符长度 默认为5 - properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); - // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) - properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); - // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy - properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); - Config config = new Config(properties); - defaultKaptcha.setConfig(config); - return defaultKaptcha; - } - - @Bean(name = "captchaProducerMath") - public DefaultKaptcha getKaptchaBeanMath() - { - DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); - Properties properties = new Properties(); - // 是否有边框 默认为true 我们可以自己设置yes,no - properties.setProperty(KAPTCHA_BORDER, "yes"); - // 边框颜色 默认为Color.BLACK - properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); - // 验证码文本字符颜色 默认为Color.BLACK - properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); - // 验证码图片宽度 默认为200 - properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); - // 验证码图片高度 默认为50 - properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); - // 验证码文本字符大小 默认为40 - properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); - // KAPTCHA_SESSION_KEY - properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); - // 验证码文本生成器 - properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.gateway.config.KaptchaTextCreator"); - // 验证码文本字符间距 默认为2 - properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); - // 验证码文本字符长度 默认为5 - properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6"); - // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) - properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); - // 验证码噪点颜色 默认为Color.BLACK - properties.setProperty(KAPTCHA_NOISE_COLOR, "white"); - // 干扰实现类 - properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise"); - // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy - properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); - Config config = new Config(properties); - defaultKaptcha.setConfig(config); - return defaultKaptcha; - } +package com.ruoyi.gateway.config; + +import java.util.Properties; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.google.code.kaptcha.impl.DefaultKaptcha; +import com.google.code.kaptcha.util.Config; + +import static com.google.code.kaptcha.Constants.*; + +/** + * 验证码配置 + * + * @author ruoyi + */ +@Configuration +public class CaptchaConfig { + @Value("${" + KAPTCHA_TEXTPRODUCER_CHAR_LENGTH + "}") + private String textProducerCharLength; + + @Bean(name = "captchaProducer") + public DefaultKaptcha getKaptchaBean() { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, textProducerCharLength); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, com.google.code.kaptcha.impl.ShadowGimpy.class.getName()); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } + + @Bean(name = "captchaProducerMath") + public DefaultKaptcha getKaptchaBeanMath() { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 边框颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); + // 验证码文本生成器 + properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, com.ruoyi.gateway.config.KaptchaTextCreator.class.getName()); + // 验证码文本字符间距 默认为2 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6"); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 验证码噪点颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_NOISE_COLOR, "white"); + // 干扰实现类 + properties.setProperty(KAPTCHA_NOISE_IMPL, com.google.code.kaptcha.impl.NoNoise.class.getName()); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, com.google.code.kaptcha.impl.ShadowGimpy.class.getName()); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } + + @Bean(name = "captchaProducerNumber") + public DefaultKaptcha getKaptchaBeanNumber() { + DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); + Properties properties = new Properties(); + // 是否有边框 默认为true 我们可以自己设置yes,no + properties.setProperty(KAPTCHA_BORDER, "yes"); + // 验证码文本字符颜色 默认为Color.BLACK + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); + // 验证码图片宽度 默认为200 + properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); + // 验证码图片高度 默认为50 + properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); + // 验证码文本字符大小 默认为40 + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); + // KAPTCHA_SESSION_KEY + properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); + // 验证码文本生成器 + properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, com.ruoyi.gateway.config.KaptchaNumberCreator.class.getName()); + // 验证码文本字符长度 默认为5 + properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, textProducerCharLength); + // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) + properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); + // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy + properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, com.google.code.kaptcha.impl.ShadowGimpy.class.getName()); + Config config = new Config(properties); + defaultKaptcha.setConfig(config); + return defaultKaptcha; + } } \ No newline at end of file diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaNumberCreator.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaNumberCreator.java new file mode 100644 index 000000000..140e754f9 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/KaptchaNumberCreator.java @@ -0,0 +1,17 @@ +package com.ruoyi.gateway.config; + +import com.google.code.kaptcha.text.impl.DefaultTextCreator; +import com.ujcms.commons.security.Secures; + +/** + * 验证码数字生成器 + * + * @author hsdllcw + */ +public class KaptchaNumberCreator extends DefaultTextCreator { + + @Override + public String getText() { + return Secures.randomNumeric(getConfig().getTextProducerCharLength()); + } +} \ No newline at end of file diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CaptchaProperties.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CaptchaProperties.java index dea2e1685..0b15361c2 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CaptchaProperties.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/config/properties/CaptchaProperties.java @@ -1,46 +1,84 @@ -package com.ruoyi.gateway.config.properties; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.context.annotation.Configuration; - -/** - * 验证码配置 - * - * @author ruoyi - */ -@Configuration -@RefreshScope -@ConfigurationProperties(prefix = "security.captcha") -public class CaptchaProperties -{ - /** - * 验证码开关 - */ - private Boolean enabled; - - /** - * 验证码类型(math 数组计算 char 字符) - */ - private String type; - - public Boolean getEnabled() - { - return enabled; - } - - public void setEnabled(Boolean enabled) - { - this.enabled = enabled; - } - - public String getType() - { - return type; - } - - public void setType(String type) - { - this.type = type; - } -} +package com.ruoyi.gateway.config.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * 验证码配置 + * + * @author ruoyi + */ +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "security.captcha") +public class CaptchaProperties +{ + /** + * 验证码开关 + */ + private Boolean enabled; + + /** + * 验证码类型(math 数组计算 char 字符) + */ + private String type; + + public Boolean getEnabled() + { + return enabled; + } + + public void setEnabled(Boolean enabled) + { + this.enabled = enabled; + } + + public String getType() + { + return type; + } + + public void setType(String type) + { + this.type = type; + } + + public static class SMS { + @RefreshScope + @Configuration + @ConfigurationProperties(prefix = "security.captcha.sms.aliyuncs") + public static class Aliyuncs { + private String accessKeyId; + private String accessKeySecret; + private String signName; + private String templateCode; + public String getAccessKeyId() { + return accessKeyId; + } + public void setAccessKeyId(String accessKeyId) { + this.accessKeyId = accessKeyId; + } + public String getAccessKeySecret() { + return accessKeySecret; + } + + public void setAccessKeySecret(String accessKeySecret) { + this.accessKeySecret = accessKeySecret; + } + + public String getSignName() { + return signName; + } + public void setSignName(String signName) { + this.signName = signName; + } + public String getTemplateCode() { + return templateCode; + } + public void setTemplateCode(String templateCode) { + this.templateCode = templateCode; + } + } + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java index 51d39ef9f..e4d791851 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java @@ -44,7 +44,6 @@ public class AuthFilter implements GlobalFilter, Ordered { ServerHttpRequest request = exchange.getRequest(); ServerHttpRequest.Builder mutate = request.mutate(); - String url = request.getURI().getPath(); // 跳过不需要验证的路径 if (StringUtils.matches(url, ignoreWhite.getWhites())) @@ -56,11 +55,19 @@ public class AuthFilter implements GlobalFilter, Ordered { return unauthorizedResponse(exchange, "令牌不能为空"); } - Claims claims = JwtUtils.parseToken(token); + /*Claims claims = JwtUtils.parseToken(token); if (claims == null) { return unauthorizedResponse(exchange, "令牌已过期或验证不正确!"); - } + }*/ + Claims claims; + try{ + claims = JwtUtils.parseToken(token); + if (claims == null) + return unauthorizedResponse(exchange, "令牌已过期或验证不正确!"); + }catch (Exception e){ + return unauthorizedResponse(exchange, "令牌已过期或验证不正确!"); + } String userkey = JwtUtils.getUserKey(claims); boolean islogin = redisService.hasKey(getTokenKey(userkey)); if (!islogin) diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/GatewayExceptionHandler.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/GatewayExceptionHandler.java index 593e7e62a..2f017bddd 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/GatewayExceptionHandler.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/GatewayExceptionHandler.java @@ -34,7 +34,6 @@ public class GatewayExceptionHandler implements ErrorWebExceptionHandler } String msg; - if (ex instanceof NotFoundException) { msg = "服务未找到"; diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/ValidateCodeHandler.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/ValidateCodeHandler.java index ef197deb5..f3168bccc 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/ValidateCodeHandler.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/handler/ValidateCodeHandler.java @@ -1,41 +1,55 @@ -package com.ruoyi.gateway.handler; - -import java.io.IOException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.BodyInserters; -import org.springframework.web.reactive.function.server.HandlerFunction; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import com.ruoyi.common.core.exception.CaptchaException; -import com.ruoyi.common.core.web.domain.AjaxResult; -import com.ruoyi.gateway.service.ValidateCodeService; -import reactor.core.publisher.Mono; - -/** - * 验证码获取 - * - * @author ruoyi - */ -@Component -public class ValidateCodeHandler implements HandlerFunction -{ - @Autowired - private ValidateCodeService validateCodeService; - - @Override - public Mono handle(ServerRequest serverRequest) - { - AjaxResult ajax; - try - { - ajax = validateCodeService.createCaptcha(); - } - catch (CaptchaException | IOException e) - { - return Mono.error(e); - } - return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(ajax)); - } -} +package com.ruoyi.gateway.handler; + +import java.io.IOException; +import java.util.Objects; + +import com.ruoyi.common.core.utils.uuid.IdUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.server.HandlerFunction; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import com.ruoyi.common.core.exception.CaptchaException; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.gateway.service.ValidateCodeService; +import reactor.core.publisher.Mono; + +/** + * 验证码获取 + * + * @author ruoyi + */ +@Component +public class ValidateCodeHandler implements HandlerFunction +{ + @Autowired + private ValidateCodeService validateCodeService; + + @Override + public Mono handle(ServerRequest serverRequest) + { + AjaxResult ajax; + try + { + switch (serverRequest.queryParam("type").orElse("image")) { + case "sms": + if (Objects.nonNull(serverRequest.queryParam("receiver").orElse(null))) { + ajax = validateCodeService.createSMSCaptcha( + serverRequest.queryParam("receiver").orElse(null), + serverRequest.queryParam("uuid").orElse(IdUtils.simpleUUID()) + ); + break; + } + default: + ajax = validateCodeService.createCaptcha(); + } + } + catch (CaptchaException | IOException e) + { + return Mono.error(e); + } + return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(ajax)); + } +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/ValidateCodeService.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/ValidateCodeService.java index 615fb07bb..c1e0d5c7e 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/ValidateCodeService.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/ValidateCodeService.java @@ -1,23 +1,28 @@ -package com.ruoyi.gateway.service; - -import java.io.IOException; -import com.ruoyi.common.core.exception.CaptchaException; -import com.ruoyi.common.core.web.domain.AjaxResult; - -/** - * 验证码处理 - * - * @author ruoyi - */ -public interface ValidateCodeService -{ - /** - * 生成验证码 - */ - public AjaxResult createCaptcha() throws IOException, CaptchaException; - - /** - * 校验验证码 - */ - public void checkCaptcha(String key, String value) throws CaptchaException; -} +package com.ruoyi.gateway.service; + +import java.io.IOException; +import com.ruoyi.common.core.exception.CaptchaException; +import com.ruoyi.common.core.web.domain.AjaxResult; + +/** + * 验证码处理 + * + * @author ruoyi + */ +public interface ValidateCodeService +{ + /** + * 生成图片验证码 + */ + public AjaxResult createCaptcha() throws IOException, CaptchaException; + + /** + * 生成短信验证码 + */ + public AjaxResult createSMSCaptcha(String receiver,String uuid) throws IOException, CaptchaException; + + /** + * 校验验证码 + */ + public void checkCaptcha(String key, String value) throws CaptchaException; +} diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java index f45010266..3d1073766 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java @@ -1,118 +1,173 @@ -package com.ruoyi.gateway.service.impl; - -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.util.concurrent.TimeUnit; -import javax.annotation.Resource; -import javax.imageio.ImageIO; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.FastByteArrayOutputStream; -import com.google.code.kaptcha.Producer; -import com.ruoyi.common.core.constant.CacheConstants; -import com.ruoyi.common.core.constant.Constants; -import com.ruoyi.common.core.exception.CaptchaException; -import com.ruoyi.common.core.utils.StringUtils; -import com.ruoyi.common.core.utils.sign.Base64; -import com.ruoyi.common.core.utils.uuid.IdUtils; -import com.ruoyi.common.core.web.domain.AjaxResult; -import com.ruoyi.common.redis.service.RedisService; -import com.ruoyi.gateway.config.properties.CaptchaProperties; -import com.ruoyi.gateway.service.ValidateCodeService; - -/** - * 验证码实现处理 - * - * @author ruoyi - */ -@Service -public class ValidateCodeServiceImpl implements ValidateCodeService -{ - @Resource(name = "captchaProducer") - private Producer captchaProducer; - - @Resource(name = "captchaProducerMath") - private Producer captchaProducerMath; - - @Autowired - private RedisService redisService; - - @Autowired - private CaptchaProperties captchaProperties; - - /** - * 生成验证码 - */ - @Override - public AjaxResult createCaptcha() throws IOException, CaptchaException - { - AjaxResult ajax = AjaxResult.success(); - boolean captchaEnabled = captchaProperties.getEnabled(); - ajax.put("captchaEnabled", captchaEnabled); - if (!captchaEnabled) - { - return ajax; - } - - // 保存验证码信息 - String uuid = IdUtils.simpleUUID(); - String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; - - String capStr = null, code = null; - BufferedImage image = null; - - String captchaType = captchaProperties.getType(); - // 生成验证码 - if ("math".equals(captchaType)) - { - String capText = captchaProducerMath.createText(); - capStr = capText.substring(0, capText.lastIndexOf("@")); - code = capText.substring(capText.lastIndexOf("@") + 1); - image = captchaProducerMath.createImage(capStr); - } - else if ("char".equals(captchaType)) - { - capStr = code = captchaProducer.createText(); - image = captchaProducer.createImage(capStr); - } - - redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); - // 转换流信息写出 - FastByteArrayOutputStream os = new FastByteArrayOutputStream(); - try - { - ImageIO.write(image, "jpg", os); - } - catch (IOException e) - { - return AjaxResult.error(e.getMessage()); - } - - ajax.put("uuid", uuid); - ajax.put("img", Base64.encode(os.toByteArray())); - return ajax; - } - - /** - * 校验验证码 - */ - @Override - public void checkCaptcha(String code, String uuid) throws CaptchaException - { - if (StringUtils.isEmpty(code)) - { - throw new CaptchaException("验证码不能为空"); - } - String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); - String captcha = redisService.getCacheObject(verifyKey); - if (captcha == null) - { - throw new CaptchaException("验证码已失效"); - } - redisService.deleteObject(verifyKey); - if (!code.equalsIgnoreCase(captcha)) - { - throw new CaptchaException("验证码错误"); - } - } -} +package com.ruoyi.gateway.service.impl; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import javax.annotation.Resource; +import javax.imageio.ImageIO; + +import com.alibaba.fastjson2.JSONObject; +import com.ujcms.commons.sms.AliyunUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; +import org.springframework.util.FastByteArrayOutputStream; +import com.google.code.kaptcha.Producer; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.constant.Constants; +import com.ruoyi.common.core.exception.CaptchaException; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.sign.Base64; +import com.ruoyi.common.core.utils.uuid.IdUtils; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.gateway.config.properties.CaptchaProperties; +import com.ruoyi.gateway.service.ValidateCodeService; + +/** + * 验证码实现处理 + * + * @author ruoyi + */ +@Service +public class ValidateCodeServiceImpl implements ValidateCodeService +{ + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + @Resource(name = "captchaProducerNumber") + private Producer captchaProducerNumber; + + @Autowired + private RedisService redisService; + + @Autowired + private CaptchaProperties captchaProperties; + + @Autowired + private CaptchaProperties.SMS.Aliyuncs smsAliyuncs; + + @Autowired + private Environment environment; + + /** + * 生成验证码 + */ + @Override + public AjaxResult createCaptcha() throws IOException, CaptchaException + { + AjaxResult ajax = AjaxResult.success(); + boolean captchaEnabled = captchaProperties.getEnabled(); + ajax.put("captchaEnabled", captchaEnabled); + if (!captchaEnabled) + { + return ajax; + } + + // 保存验证码信息 + String uuid = IdUtils.simpleUUID(); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; + + String capStr = null, code = null; + BufferedImage image = null; + + String captchaType = captchaProperties.getType(); + // 生成验证码 + switch (captchaType) { + case "number": { + capStr = code = captchaProducerNumber.createText(); + image = captchaProducerNumber.createImage(capStr); + } + break; + case "math": { + String capText = captchaProducerMath.createText(); + capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + image = captchaProducerMath.createImage(capStr); + } + break; + default: { + capStr = code = captchaProducer.createText(); + image = captchaProducer.createImage(capStr); + } + break; + } + + redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + // 转换流信息写出 + FastByteArrayOutputStream os = new FastByteArrayOutputStream(); + try + { + ImageIO.write(image, "jpg", os); + } + catch (IOException e) + { + return AjaxResult.error(e.getMessage()); + } + + ajax.put("uuid", uuid); + ajax.put("img", Base64.encode(os.toByteArray())); + return ajax; + } + + @Override + public AjaxResult createSMSCaptcha(String receiver, String uuid) throws IOException, CaptchaException { + AjaxResult ajax = AjaxResult.success(); + boolean captchaEnabled = captchaProperties.getEnabled(); + ajax.put("captchaEnabled", captchaEnabled); + if (!captchaEnabled) { + return ajax; + } + // 保存验证码信息 + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + receiver + ":" + uuid; + long expire = redisService.getExpire(verifyKey); + if (expire <= 0) { + String code = captchaProducerNumber.createText(); + redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + expire = redisService.getExpire(verifyKey); + if (Arrays.stream(environment.getActiveProfiles()).toList().contains("prod")) { + AliyunUtils.sendSms( + smsAliyuncs.getAccessKeyId(), + smsAliyuncs.getAccessKeySecret(), + smsAliyuncs.getSignName(), + smsAliyuncs.getTemplateCode(), + JSONObject.of("code", code), + receiver + ); + } else { + ajax.put("captchaCode",code); + } + ajax.put("codeLength", code.length()); + } + ajax.put("expire", expire); + ajax.put("uuid", uuid); + return ajax; + } + + /** + * 校验验证码 + */ + @Override + public void checkCaptcha(String code, String uuid) throws CaptchaException + { + if (StringUtils.isEmpty(code)) + { + throw new CaptchaException("验证码不能为空"); + } + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); + String captcha = redisService.getCacheObject(verifyKey); + if (captcha == null) + { + throw new CaptchaException("验证码已失效"); + } + redisService.deleteObject(verifyKey); + if (!code.equalsIgnoreCase(captcha)) + { + throw new CaptchaException("验证码错误"); + } + } +} diff --git a/ruoyi-gateway/src/main/kotlin/com/ruoyi/gateway/config/CorsConfig.kt b/ruoyi-gateway/src/main/kotlin/com/ruoyi/gateway/config/CorsConfig.kt new file mode 100644 index 000000000..902c4573c --- /dev/null +++ b/ruoyi-gateway/src/main/kotlin/com/ruoyi/gateway/config/CorsConfig.kt @@ -0,0 +1,39 @@ +package com.ruoyi.gateway.config + +import org.apache.commons.lang3.ObjectUtils +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.http.HttpMethod +import org.springframework.http.HttpStatus +import org.springframework.web.server.WebFilter + + +@Configuration +open class CorsConfig { + @Value("\${cors.orgins}") + private val corsOrgins: String? = null + + @Bean + open fun corsFilter(): WebFilter { + return WebFilter { exchange, chain -> + val response = exchange.response + val request = exchange.request + if (!ObjectUtils.isEmpty(corsOrgins)) { + response.headers["Access-Control-Allow-Origin"] = corsOrgins + } else { + response.headers["Access-Control-Allow-Origin"] = "*" + } + response.headers["Access-Control-Expose-Headers"] = "*" + response.headers["Access-Control-Allow-Credentials"] = "true" + response.headers["Access-Control-Max-Age"] = "3600" + response.headers["Access-Control-Allow-Methods"] = "GET,POST,PUT,DELETE,OPTIONS,HEAD" + response.headers["Access-Control-Allow-Headers"] = "*" + if (HttpMethod.OPTIONS.equals(request.method)) { + response.statusCode = HttpStatus.OK + chain.filter(exchange) + } + chain.filter(exchange.mutate().request(request.mutate().build()).build()) + } + } +} \ No newline at end of file diff --git a/ruoyi-gateway/src/main/resources/bootstrap-dev.yml b/ruoyi-gateway/src/main/resources/bootstrap-dev.yml new file mode 100644 index 000000000..9efc6bb39 --- /dev/null +++ b/ruoyi-gateway/src/main/resources/bootstrap-dev.yml @@ -0,0 +1,48 @@ +# Tomcat +server: + port: 8080 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-gateway + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + sentinel: + # 取消控制台懒加载 + eager: true + transport: + # 控制台地址 + dashboard: nacos.zkjiadi.cc:8718 + # nacos配置持久化 + datasource: + ds1: + nacos: + server-addr: nacos.zkjiadi.cc + dataId: sentinel-ruoyi-gateway + groupId: DEFAULT_GROUP + data-type: json + rule-type: gw-flow +logging: + file: + name: dev-ruoyi-gateway.log + pattern: + file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx" \ No newline at end of file diff --git a/ruoyi-gateway/src/main/resources/bootstrap-prod.yml b/ruoyi-gateway/src/main/resources/bootstrap-prod.yml new file mode 100644 index 000000000..67cc209b4 --- /dev/null +++ b/ruoyi-gateway/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,49 @@ +# Tomcat +server: + port: 8080 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-gateway + cloud: + nacos: + discovery: + ip: 8.155.60.167 + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + sentinel: + # 取消控制台懒加载 + eager: true + transport: + # 控制台地址 + dashboard: nacos.zkjiadi.cc:8718 + # nacos配置持久化 + datasource: + ds1: + nacos: + server-addr: nacos.zkjiadi.cc + dataId: sentinel-ruoyi-gateway + groupId: DEFAULT_GROUP + data-type: json + rule-type: gw-flow +logging: + file: + name: prod-ruoyi-gateway.log + pattern: + file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx" \ No newline at end of file diff --git a/ruoyi-gateway/src/main/resources/bootstrap-test.yml b/ruoyi-gateway/src/main/resources/bootstrap-test.yml new file mode 100644 index 000000000..3418f8125 --- /dev/null +++ b/ruoyi-gateway/src/main/resources/bootstrap-test.yml @@ -0,0 +1,48 @@ +# Tomcat +server: + port: 8080 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-gateway + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + sentinel: + # 取消控制台懒加载 + eager: true + transport: + # 控制台地址 + dashboard: nacos.zkjiadi.cc:8718 + # nacos配置持久化 + datasource: + ds1: + nacos: + server-addr: nacos.zkjiadi.cc + dataId: sentinel-ruoyi-gateway + groupId: DEFAULT_GROUP + data-type: json + rule-type: gw-flow +logging: + file: + name: test-ruoyi-gateway.log + pattern: + file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx" \ No newline at end of file diff --git a/ruoyi-gateway/src/main/resources/bootstrap.yml b/ruoyi-gateway/src/main/resources/bootstrap.yml index b6dc98ae6..03234a17e 100644 --- a/ruoyi-gateway/src/main/resources/bootstrap.yml +++ b/ruoyi-gateway/src/main/resources/bootstrap.yml @@ -1,40 +1,4 @@ -# Tomcat -server: - port: 8080 - -# Spring -spring: - application: - # 应用名称 - name: ruoyi-gateway - profiles: - # 环境配置 - active: dev - cloud: - nacos: - discovery: - # 服务注册地址 - server-addr: 127.0.0.1:8848 - config: - # 配置中心地址 - server-addr: 127.0.0.1:8848 - # 配置文件格式 - file-extension: yml - # 共享配置 - shared-configs: - - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} - sentinel: - # 取消控制台懒加载 - eager: true - transport: - # 控制台地址 - dashboard: 127.0.0.1:8718 - # nacos配置持久化 - datasource: - ds1: - nacos: - server-addr: 127.0.0.1:8848 - dataId: sentinel-ruoyi-gateway - groupId: DEFAULT_GROUP - data-type: json - rule-type: gw-flow +# Spring默认环境配置 +spring: + profiles: + active: dev \ No newline at end of file diff --git a/ruoyi-modules/pom.xml b/ruoyi-modules/pom.xml index bcec3cc50..edc138aa5 100644 --- a/ruoyi-modules/pom.xml +++ b/ruoyi-modules/pom.xml @@ -1,25 +1,25 @@ - - - - com.ruoyi - ruoyi - 3.6.7 - - 4.0.0 - - - ruoyi-system - ruoyi-gen - ruoyi-job - ruoyi-file - - - ruoyi-modules - pom - - - ruoyi-modules业务模块 - - - + + + + com.ruoyi + ruoyi + 3.6.5.0.9 + + 4.0.0 + + + ruoyi-system + ruoyi-gen + ruoyi-job + ruoyi-file + + + ruoyi-modules + pom + + + ruoyi-modules业务模块 + + + diff --git a/ruoyi-modules/ruoyi-file/pom.xml b/ruoyi-modules/ruoyi-file/pom.xml index c4b4e6b2e..6e42fbf95 100644 --- a/ruoyi-modules/ruoyi-file/pom.xml +++ b/ruoyi-modules/ruoyi-file/pom.xml @@ -1,88 +1,92 @@ - - - - com.ruoyi - ruoyi-modules - 3.6.7 - - 4.0.0 - - ruoyi-modules-file - - - ruoyi-modules-file文件服务 - - - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-discovery - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-config - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-sentinel - - - - - org.springframework.boot - spring-boot-starter-actuator - - - - - org.springframework.boot - spring-boot-starter-web - - - - - com.github.tobato - fastdfs-client - - - - - io.minio - minio - ${minio.version} - - - - - com.ruoyi - ruoyi-api-system - - - - - - ${project.artifactId} - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - - + + + + com.ruoyi + ruoyi-modules + 3.6.5.0.9 + + 4.0.0 + + ruoyi-modules-file + + + ruoyi-modules-file文件服务 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.github.tobato + fastdfs-client + + + + + io.minio + minio + ${minio.version} + + + + + com.ruoyi + ruoyi-api-system + + + + de.codecentric + spring-boot-admin-starter-client + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-file/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java b/ruoyi-modules/ruoyi-file/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java new file mode 100644 index 000000000..68e35e6b1 --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java @@ -0,0 +1,140 @@ +/* + * Copyright 2012-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.endpoint.web; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +/** + * Configuration properties for web management endpoints. + * + * @author Madhura Bhave + * @author Phillip Webb + * @since 2.0.0 + */ +@ConfigurationProperties(prefix = "management.endpoints.web") +public class WebEndpointProperties { + + private final Exposure exposure = new Exposure(); + + /** + * Base path for Web endpoints. Relative to the servlet context path + * (server.servlet.context-path) or WebFlux base path (spring.webflux.base-path) when + * the management server is sharing the main server port. Relative to the management + * server base path (management.server.base-path) when a separate management server + * port (management.server.port) is configured. + */ + private String basePath = "/actuator"; + private String baseUrl = null; + + /** + * Mapping between endpoint IDs and the path that should expose them. + */ + private final Map pathMapping = new LinkedHashMap<>(); + + private final Discovery discovery = new Discovery(); + + public Exposure getExposure() { + return this.exposure; + } + + public String getBasePath() { + return this.basePath; + } + + public void setBasePath(String basePath) { + Assert.isTrue(basePath.isEmpty() || basePath.startsWith("/"), "Base path must start with '/' or be empty"); + this.basePath = cleanBasePath(basePath); + } + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + private String cleanBasePath(String basePath) { + if (StringUtils.hasText(basePath) && basePath.endsWith("/")) { + return basePath.substring(0, basePath.length() - 1); + } + return basePath; + } + + public Map getPathMapping() { + return this.pathMapping; + } + + public Discovery getDiscovery() { + return this.discovery; + } + + public static class Exposure { + + /** + * Endpoint IDs that should be included or '*' for all. + */ + private Set include = new LinkedHashSet<>(); + + /** + * Endpoint IDs that should be excluded or '*' for all. + */ + private Set exclude = new LinkedHashSet<>(); + + public Set getInclude() { + return this.include; + } + + public void setInclude(Set include) { + this.include = include; + } + + public Set getExclude() { + return this.exclude; + } + + public void setExclude(Set exclude) { + this.exclude = exclude; + } + + } + + public static class Discovery { + + /** + * Whether the discovery page is enabled. + */ + private boolean enabled = true; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + } + +} diff --git a/ruoyi-modules/ruoyi-file/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java b/ruoyi-modules/ruoyi-file/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java new file mode 100644 index 000000000..1c7dae1bb --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java @@ -0,0 +1,113 @@ +/* + * Copyright 2012-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.servlet; + +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.endpoint.web.*; +import org.springframework.context.annotation.Lazy; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.util.pattern.PathPatternParser; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +/** + * A custom {@link HandlerMapping} that makes web endpoints available over HTTP using + * Spring MVC. + * + * @author Andy Wilkinson + * @author Phillip Webb + * @since 2.0.0 + */ +public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerMapping { + + private final EndpointLinksResolver linksResolver; + @Lazy + @Resource + private WebEndpointProperties webEndpointProperties; + + /** + * Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings + * for the given endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param endpointMediaTypes media types consumed and produced by the endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered + */ + public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, + EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, + EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping) { + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping); + this.linksResolver = linksResolver; + setOrder(-100); + } + + /** + * Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings + * for the given endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param endpointMediaTypes media types consumed and produced by the endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered + * @param pathPatternParser the path pattern parser + */ + public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, + EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, + EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping, + PathPatternParser pathPatternParser) { + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping, + pathPatternParser); + this.linksResolver = linksResolver; + setOrder(-100); + } + + @Override + protected LinksHandler getLinksHandler() { + return new WebMvcLinksHandler(); + } + + /** + * Handler for root endpoint providing links. + */ + class WebMvcLinksHandler implements LinksHandler { + + @Override + @ResponseBody + public Map> links(HttpServletRequest request, HttpServletResponse response) { + return Collections.singletonMap("_links", + WebMvcEndpointHandlerMapping.this.linksResolver.resolveLinks(ObjectUtils.isEmpty(webEndpointProperties.getBaseUrl())?request.getRequestURL().toString():(webEndpointProperties.getBaseUrl()+webEndpointProperties.getBasePath()))); + } + + @Override + public String toString() { + return "Actuator root web endpoint"; + } + + } + +} diff --git a/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap-dev.yml b/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap-dev.yml new file mode 100644 index 000000000..d3fc5df26 --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap-dev.yml @@ -0,0 +1,28 @@ +# Tomcat +server: + port: 9300 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-file + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap-prod.yml b/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap-prod.yml new file mode 100644 index 000000000..00059ada4 --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,29 @@ +# Tomcat +server: + port: 9300 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-file + cloud: + nacos: + discovery: + ip: 8.155.60.167 + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap-test.yml b/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap-test.yml new file mode 100644 index 000000000..923ea5e53 --- /dev/null +++ b/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap-test.yml @@ -0,0 +1,28 @@ +# Tomcat +server: + port: 9300 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-file + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml index 55ff41125..03234a17e 100644 --- a/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml +++ b/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml @@ -1,25 +1,4 @@ -# Tomcat -server: - port: 9300 - -# Spring -spring: - application: - # 应用名称 - name: ruoyi-file - profiles: - # 环境配置 - active: dev - cloud: - nacos: - discovery: - # 服务注册地址 - server-addr: 127.0.0.1:8848 - config: - # 配置中心地址 - server-addr: 127.0.0.1:8848 - # 配置文件格式 - file-extension: yml - # 共享配置 - shared-configs: - - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# Spring默认环境配置 +spring: + profiles: + active: dev \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-gen/pom.xml b/ruoyi-modules/ruoyi-gen/pom.xml index 850950de7..808700eb5 100644 --- a/ruoyi-modules/ruoyi-gen/pom.xml +++ b/ruoyi-modules/ruoyi-gen/pom.xml @@ -1,87 +1,91 @@ - - - - com.ruoyi - ruoyi-modules - 3.6.7 - - 4.0.0 - - ruoyi-modules-gen - - - ruoyi-modules-gen代码生成 - - - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-discovery - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-config - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-sentinel - - - - - org.springframework.boot - spring-boot-starter-actuator - - - - - org.apache.velocity - velocity-engine-core - - - - - com.mysql - mysql-connector-j - - - - - com.ruoyi - ruoyi-common-log - - - - - com.ruoyi - ruoyi-common-swagger - - - - - - ${project.artifactId} - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - - + + + + com.ruoyi + ruoyi-modules + 3.6.5.0.9 + + 4.0.0 + + ruoyi-modules-gen + + + ruoyi-modules-gen代码生成 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.apache.velocity + velocity-engine-core + + + + + com.mysql + mysql-connector-j + + + + + com.ruoyi + ruoyi-common-log + + + + + com.ruoyi + ruoyi-common-swagger + + + + de.codecentric + spring-boot-admin-starter-client + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java new file mode 100644 index 000000000..68e35e6b1 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java @@ -0,0 +1,140 @@ +/* + * Copyright 2012-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.endpoint.web; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +/** + * Configuration properties for web management endpoints. + * + * @author Madhura Bhave + * @author Phillip Webb + * @since 2.0.0 + */ +@ConfigurationProperties(prefix = "management.endpoints.web") +public class WebEndpointProperties { + + private final Exposure exposure = new Exposure(); + + /** + * Base path for Web endpoints. Relative to the servlet context path + * (server.servlet.context-path) or WebFlux base path (spring.webflux.base-path) when + * the management server is sharing the main server port. Relative to the management + * server base path (management.server.base-path) when a separate management server + * port (management.server.port) is configured. + */ + private String basePath = "/actuator"; + private String baseUrl = null; + + /** + * Mapping between endpoint IDs and the path that should expose them. + */ + private final Map pathMapping = new LinkedHashMap<>(); + + private final Discovery discovery = new Discovery(); + + public Exposure getExposure() { + return this.exposure; + } + + public String getBasePath() { + return this.basePath; + } + + public void setBasePath(String basePath) { + Assert.isTrue(basePath.isEmpty() || basePath.startsWith("/"), "Base path must start with '/' or be empty"); + this.basePath = cleanBasePath(basePath); + } + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + private String cleanBasePath(String basePath) { + if (StringUtils.hasText(basePath) && basePath.endsWith("/")) { + return basePath.substring(0, basePath.length() - 1); + } + return basePath; + } + + public Map getPathMapping() { + return this.pathMapping; + } + + public Discovery getDiscovery() { + return this.discovery; + } + + public static class Exposure { + + /** + * Endpoint IDs that should be included or '*' for all. + */ + private Set include = new LinkedHashSet<>(); + + /** + * Endpoint IDs that should be excluded or '*' for all. + */ + private Set exclude = new LinkedHashSet<>(); + + public Set getInclude() { + return this.include; + } + + public void setInclude(Set include) { + this.include = include; + } + + public Set getExclude() { + return this.exclude; + } + + public void setExclude(Set exclude) { + this.exclude = exclude; + } + + } + + public static class Discovery { + + /** + * Whether the discovery page is enabled. + */ + private boolean enabled = true; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + } + +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java b/ruoyi-modules/ruoyi-gen/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java new file mode 100644 index 000000000..1c7dae1bb --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java @@ -0,0 +1,113 @@ +/* + * Copyright 2012-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.servlet; + +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.endpoint.web.*; +import org.springframework.context.annotation.Lazy; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.util.pattern.PathPatternParser; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +/** + * A custom {@link HandlerMapping} that makes web endpoints available over HTTP using + * Spring MVC. + * + * @author Andy Wilkinson + * @author Phillip Webb + * @since 2.0.0 + */ +public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerMapping { + + private final EndpointLinksResolver linksResolver; + @Lazy + @Resource + private WebEndpointProperties webEndpointProperties; + + /** + * Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings + * for the given endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param endpointMediaTypes media types consumed and produced by the endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered + */ + public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, + EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, + EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping) { + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping); + this.linksResolver = linksResolver; + setOrder(-100); + } + + /** + * Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings + * for the given endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param endpointMediaTypes media types consumed and produced by the endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered + * @param pathPatternParser the path pattern parser + */ + public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, + EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, + EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping, + PathPatternParser pathPatternParser) { + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping, + pathPatternParser); + this.linksResolver = linksResolver; + setOrder(-100); + } + + @Override + protected LinksHandler getLinksHandler() { + return new WebMvcLinksHandler(); + } + + /** + * Handler for root endpoint providing links. + */ + class WebMvcLinksHandler implements LinksHandler { + + @Override + @ResponseBody + public Map> links(HttpServletRequest request, HttpServletResponse response) { + return Collections.singletonMap("_links", + WebMvcEndpointHandlerMapping.this.linksResolver.resolveLinks(ObjectUtils.isEmpty(webEndpointProperties.getBaseUrl())?request.getRequestURL().toString():(webEndpointProperties.getBaseUrl()+webEndpointProperties.getBasePath()))); + } + + @Override + public String toString() { + return "Actuator root web endpoint"; + } + + } + +} diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap-dev.yml b/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap-dev.yml new file mode 100644 index 000000000..5624ff40a --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap-dev.yml @@ -0,0 +1,28 @@ +# Tomcat +server: + port: 9202 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-gen + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap-prod.yml b/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap-prod.yml new file mode 100644 index 000000000..f9e2a0bf0 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,29 @@ +# Tomcat +server: + port: 9202 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-gen + cloud: + nacos: + discovery: + ip: 8.155.60.167 + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap-test.yml b/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap-test.yml new file mode 100644 index 000000000..619e5fe51 --- /dev/null +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap-test.yml @@ -0,0 +1,28 @@ +# Tomcat +server: + port: 9202 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-gen + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap.yml index 0ef5a4575..03234a17e 100644 --- a/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap.yml +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap.yml @@ -1,25 +1,4 @@ -# Tomcat -server: - port: 9202 - -# Spring -spring: - application: - # 应用名称 - name: ruoyi-gen - profiles: - # 环境配置 - active: dev - cloud: - nacos: - discovery: - # 服务注册地址 - server-addr: 127.0.0.1:8848 - config: - # 配置中心地址 - server-addr: 127.0.0.1:8848 - # 配置文件格式 - file-extension: yml - # 共享配置 - shared-configs: - - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# Spring默认环境配置 +spring: + profiles: + active: dev \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-job/pom.xml b/ruoyi-modules/ruoyi-job/pom.xml index 54b4563b4..6b5440d5b 100644 --- a/ruoyi-modules/ruoyi-job/pom.xml +++ b/ruoyi-modules/ruoyi-job/pom.xml @@ -1,93 +1,109 @@ - - - - com.ruoyi - ruoyi-modules - 3.6.7 - - 4.0.0 - - ruoyi-modules-job - - - ruoyi-modules-job定时任务 - - - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-discovery - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-config - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-sentinel - - - - - org.springframework.boot - spring-boot-starter-actuator - - - - - org.quartz-scheduler - quartz - - - com.mchange - c3p0 - - - - - - - com.mysql - mysql-connector-j - - - - - com.ruoyi - ruoyi-common-log - - - - - com.ruoyi - ruoyi-common-swagger - - - - - - ${project.artifactId} - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - - + + + + com.ruoyi + ruoyi-modules + 3.6.5.0.9 + + 4.0.0 + + ruoyi-modules-job + + + ruoyi-modules-job定时任务 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.quartz-scheduler + quartz + + + com.mchange + c3p0 + + + + + + + com.mysql + mysql-connector-j + + + + + com.ruoyi + ruoyi-common-log + + + + + com.ruoyi + ruoyi-common-swagger + + + + de.codecentric + spring-boot-admin-starter-client + + + com.squareup.okhttp3 + okhttp + 3.12.13 + + + com.ujcms + ujcms-commons + 9.6.0.0.1 + compile + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/config/SmsConfig.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/config/SmsConfig.java new file mode 100644 index 000000000..9e483832d --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/config/SmsConfig.java @@ -0,0 +1,23 @@ +package com.ruoyi.job.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +/** + * 验证码配置 + * + * @author ruoyi + */ +@Data +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "security.sms.aliyuncs") +public class SmsConfig +{ + private String accessKeyId; + private String accessKeySecret; + private String signName; + private String templateCode; +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/domain/ScClassUserInfo.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/domain/ScClassUserInfo.java new file mode 100644 index 000000000..aacd7cf74 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/domain/ScClassUserInfo.java @@ -0,0 +1,78 @@ +package com.ruoyi.job.domain; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.ruoyi.common.core.web.domain.BaseEntity; +import com.ruoyi.job.util.ProgressFormatterUtil; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.springframework.data.annotation.Id; + +import java.math.BigDecimal; + +/** + * 直播预告报名信息导出实体 + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class ScClassUserInfo extends BaseEntity { + + @Id + private Long id; + + //@ExcelIgnore // 不导出该字段 + private Long userId; + + //@ExcelIgnore // 不导出该字段 + private Long classId; + + //@ColumnWidth(25) + // @ExcelProperty("名称(报名时)") + private String name; + + //@ColumnWidth(25) + //@ExcelProperty("单位") + private String firm; + + //@ColumnWidth(25) + //@ExcelProperty("专业") + private String specialized; + + //@ColumnWidth(35) + //@ExcelProperty("手机号") + private String phonenumber; + + //@ColumnWidth(35) + //@ExcelProperty("昵称") + private String nickName; + + /** + * 客户订单编号 + */ + //@ExcelProperty("客户订单编号") + private String userSn; + + //@ExcelIgnore + private Boolean todayAttendanceIs; + + @JsonIgnore + // @ExcelProperty("是否打卡") + private String attendanceIs; + + //@ExcelProperty("签到次数") + private Integer attendanceCount; + + //@ExcelIgnore + private BigDecimal progress; + + //@ExcelProperty("总学习进度") + private String progressPercent; + + public String getAttendanceIs() { + return attendanceCount.compareTo(0) > 0 ? "是" : "否"; + } + + public String getProgressPercent() { + return ProgressFormatterUtil.format(this.progress.multiply(BigDecimal.valueOf(100))); + } + +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/mapper/ScClassUserInfoMapper.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/mapper/ScClassUserInfoMapper.java new file mode 100644 index 000000000..71da2e0d9 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/mapper/ScClassUserInfoMapper.java @@ -0,0 +1,14 @@ +package com.ruoyi.job.mapper; + +import com.ruoyi.job.domain.ScClassUserInfo; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +//@Mapper +//public interface ScClassUserInfoMapper extends tk.mybatis.mapper.common.Mapper +public interface ScClassUserInfoMapper + { + List waitNoticeCourseUser(); + +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SmsService.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SmsService.java new file mode 100644 index 000000000..67a8602b1 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/SmsService.java @@ -0,0 +1,16 @@ +package com.ruoyi.job.service; + +import com.ruoyi.common.core.exception.CaptchaException; + +/** + * 验证码处理 + * + * @author ruoyi + */ +public interface SmsService +{ + /** + * 发送学习短信通知 + */ + public void sendStudyNoticeSms(String phone) throws CaptchaException; +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/impl/SmsServiceImpl.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/impl/SmsServiceImpl.java new file mode 100644 index 000000000..e8407555f --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/service/impl/SmsServiceImpl.java @@ -0,0 +1,35 @@ +package com.ruoyi.job.service.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.core.exception.CaptchaException; +import com.ruoyi.job.config.SmsConfig; +import com.ruoyi.job.service.SmsService; +import com.ujcms.commons.sms.AliyunUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * 验证码实现处理 + * + * @author ruoyi + */ +@Service +public class SmsServiceImpl implements SmsService +{ + @Autowired + private SmsConfig smsConfig; + + /** + * 发送学习短信通知 + */ + @Override + public void sendStudyNoticeSms(String phone) throws CaptchaException { + AliyunUtils.sendSms(smsConfig.getAccessKeyId(), + smsConfig.getAccessKeySecret(), + smsConfig.getSignName(), + smsConfig.getTemplateCode(), + JSONObject.of(), + phone + ); + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/task/LiveTask.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/task/LiveTask.java new file mode 100644 index 000000000..25f2aa07d --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/task/LiveTask.java @@ -0,0 +1,36 @@ +package com.ruoyi.job.task; + +import com.ruoyi.job.config.SmsConfig; +import com.ruoyi.job.domain.ScClassUserInfo; +import com.ruoyi.job.mapper.ScClassUserInfoMapper; +import com.ruoyi.job.service.SmsService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +@Slf4j +@Component("liveTask") +public class LiveTask { + @Resource + ScClassUserInfoMapper scClassUserInfoMapper; + @Autowired + private SmsService smsAliyuncs; + + @Autowired + private SmsConfig smsConfig; + /** + * 短信打卡 + */ + public void CourseSmsNotice(){ + List list = scClassUserInfoMapper.waitNoticeCourseUser(); + list.forEach(item->{ + if (item.getPhonenumber() != null && !item.getPhonenumber().trim().isEmpty()){ + log.info("发送打卡提醒 {} {} {}",item.getUserId(),item.getNickName(),item.getPhonenumber()); + smsAliyuncs.sendStudyNoticeSms(item.getPhonenumber()); + } + }); + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/ProgressFormatterUtil.java b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/ProgressFormatterUtil.java new file mode 100644 index 000000000..b88d4bb91 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/com/ruoyi/job/util/ProgressFormatterUtil.java @@ -0,0 +1,18 @@ +package com.ruoyi.job.util; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.NumberFormat; + +public class ProgressFormatterUtil { + public static String format(BigDecimal progress ) { + if (progress == null) return "0"; + // 保留两位小数(四舍五入) + BigDecimal scaled = progress.setScale(2, RoundingMode.HALF_UP); + // 去除末尾零和小数点 + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(2); + nf.setMinimumFractionDigits(0); + return nf.format(scaled) + "%"; + } +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java b/ruoyi-modules/ruoyi-job/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java new file mode 100644 index 000000000..68e35e6b1 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java @@ -0,0 +1,140 @@ +/* + * Copyright 2012-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.endpoint.web; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +/** + * Configuration properties for web management endpoints. + * + * @author Madhura Bhave + * @author Phillip Webb + * @since 2.0.0 + */ +@ConfigurationProperties(prefix = "management.endpoints.web") +public class WebEndpointProperties { + + private final Exposure exposure = new Exposure(); + + /** + * Base path for Web endpoints. Relative to the servlet context path + * (server.servlet.context-path) or WebFlux base path (spring.webflux.base-path) when + * the management server is sharing the main server port. Relative to the management + * server base path (management.server.base-path) when a separate management server + * port (management.server.port) is configured. + */ + private String basePath = "/actuator"; + private String baseUrl = null; + + /** + * Mapping between endpoint IDs and the path that should expose them. + */ + private final Map pathMapping = new LinkedHashMap<>(); + + private final Discovery discovery = new Discovery(); + + public Exposure getExposure() { + return this.exposure; + } + + public String getBasePath() { + return this.basePath; + } + + public void setBasePath(String basePath) { + Assert.isTrue(basePath.isEmpty() || basePath.startsWith("/"), "Base path must start with '/' or be empty"); + this.basePath = cleanBasePath(basePath); + } + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + private String cleanBasePath(String basePath) { + if (StringUtils.hasText(basePath) && basePath.endsWith("/")) { + return basePath.substring(0, basePath.length() - 1); + } + return basePath; + } + + public Map getPathMapping() { + return this.pathMapping; + } + + public Discovery getDiscovery() { + return this.discovery; + } + + public static class Exposure { + + /** + * Endpoint IDs that should be included or '*' for all. + */ + private Set include = new LinkedHashSet<>(); + + /** + * Endpoint IDs that should be excluded or '*' for all. + */ + private Set exclude = new LinkedHashSet<>(); + + public Set getInclude() { + return this.include; + } + + public void setInclude(Set include) { + this.include = include; + } + + public Set getExclude() { + return this.exclude; + } + + public void setExclude(Set exclude) { + this.exclude = exclude; + } + + } + + public static class Discovery { + + /** + * Whether the discovery page is enabled. + */ + private boolean enabled = true; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + } + +} diff --git a/ruoyi-modules/ruoyi-job/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java b/ruoyi-modules/ruoyi-job/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java new file mode 100644 index 000000000..1c7dae1bb --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java @@ -0,0 +1,113 @@ +/* + * Copyright 2012-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.servlet; + +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.endpoint.web.*; +import org.springframework.context.annotation.Lazy; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.util.pattern.PathPatternParser; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +/** + * A custom {@link HandlerMapping} that makes web endpoints available over HTTP using + * Spring MVC. + * + * @author Andy Wilkinson + * @author Phillip Webb + * @since 2.0.0 + */ +public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerMapping { + + private final EndpointLinksResolver linksResolver; + @Lazy + @Resource + private WebEndpointProperties webEndpointProperties; + + /** + * Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings + * for the given endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param endpointMediaTypes media types consumed and produced by the endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered + */ + public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, + EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, + EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping) { + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping); + this.linksResolver = linksResolver; + setOrder(-100); + } + + /** + * Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings + * for the given endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param endpointMediaTypes media types consumed and produced by the endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered + * @param pathPatternParser the path pattern parser + */ + public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, + EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, + EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping, + PathPatternParser pathPatternParser) { + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping, + pathPatternParser); + this.linksResolver = linksResolver; + setOrder(-100); + } + + @Override + protected LinksHandler getLinksHandler() { + return new WebMvcLinksHandler(); + } + + /** + * Handler for root endpoint providing links. + */ + class WebMvcLinksHandler implements LinksHandler { + + @Override + @ResponseBody + public Map> links(HttpServletRequest request, HttpServletResponse response) { + return Collections.singletonMap("_links", + WebMvcEndpointHandlerMapping.this.linksResolver.resolveLinks(ObjectUtils.isEmpty(webEndpointProperties.getBaseUrl())?request.getRequestURL().toString():(webEndpointProperties.getBaseUrl()+webEndpointProperties.getBasePath()))); + } + + @Override + public String toString() { + return "Actuator root web endpoint"; + } + + } + +} diff --git a/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap-dev.yml b/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap-dev.yml new file mode 100644 index 000000000..4626dd46b --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap-dev.yml @@ -0,0 +1,28 @@ +# Tomcat +server: + port: 9203 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-job + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap-prod.yml b/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap-prod.yml new file mode 100644 index 000000000..5ef2f6f5c --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,29 @@ +# Tomcat +server: + port: 9203 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-job + cloud: + nacos: + discovery: + ip: 8.155.60.167 + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap-test.yml b/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap-test.yml new file mode 100644 index 000000000..64630122c --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap-test.yml @@ -0,0 +1,28 @@ +# Tomcat +server: + port: 9203 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-job + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap.yml index b86f8c9e1..03234a17e 100644 --- a/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap.yml +++ b/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap.yml @@ -1,25 +1,4 @@ -# Tomcat -server: - port: 9203 - -# Spring -spring: - application: - # 应用名称 - name: ruoyi-job - profiles: - # 环境配置 - active: dev - cloud: - nacos: - discovery: - # 服务注册地址 - server-addr: 127.0.0.1:8848 - config: - # 配置中心地址 - server-addr: 127.0.0.1:8848 - # 配置文件格式 - file-extension: yml - # 共享配置 - shared-configs: - - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# Spring默认环境配置 +spring: + profiles: + active: dev \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-job/src/main/resources/mapper/job/ScClassUserInfoMapper.xml b/ruoyi-modules/ruoyi-job/src/main/resources/mapper/job/ScClassUserInfoMapper.xml new file mode 100644 index 000000000..5e405ee42 --- /dev/null +++ b/ruoyi-modules/ruoyi-job/src/main/resources/mapper/job/ScClassUserInfoMapper.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + diff --git a/ruoyi-modules/ruoyi-system/pom.xml b/ruoyi-modules/ruoyi-system/pom.xml index 02556a55b..dd9e6d39f 100644 --- a/ruoyi-modules/ruoyi-system/pom.xml +++ b/ruoyi-modules/ruoyi-system/pom.xml @@ -1,93 +1,118 @@ - - - - com.ruoyi - ruoyi-modules - 3.6.7 - - 4.0.0 - - ruoyi-modules-system - - - ruoyi-modules-system系统模块 - - - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-discovery - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-config - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-sentinel - - - - - org.springframework.boot - spring-boot-starter-actuator - - - - - com.mysql - mysql-connector-j - - - - - com.ruoyi - ruoyi-common-datasource - - - - - com.ruoyi - ruoyi-common-datascope - - - - - com.ruoyi - ruoyi-common-log - - - - - com.ruoyi - ruoyi-common-swagger - - - - - - ${project.artifactId} - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - - + + + + com.ruoyi + ruoyi-modules + 3.6.5.0.9 + + 4.0.0 + + ruoyi-modules-system + + + ruoyi-modules-system系统模块 + + + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + com.mysql + mysql-connector-j + + + + + com.ruoyi + ruoyi-common-datasource + + + + + com.ruoyi + ruoyi-common-datascope + + + + + com.ruoyi + ruoyi-common-log + + + + + com.ruoyi + ruoyi-common-swagger + + + + de.codecentric + spring-boot-admin-starter-client + + + + + ${project.artifactId} + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + process-sources + + compile + + + + test-compile + test-compile + + test-compile + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysNoticeController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysNoticeController.java index eb9061129..7429c6fe1 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysNoticeController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysNoticeController.java @@ -89,4 +89,13 @@ public class SysNoticeController extends BaseController { return toAjax(noticeService.deleteNoticeByIds(noticeIds)); } + + /** + * 根据标题查询通知公告 + */ + @GetMapping("/no-login/{noticeTitle}") + public AjaxResult getInfo(@PathVariable String noticeTitle) + { + return success(noticeService.selectNoticeByNoticeTitle(noticeTitle)); + } } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java index cc54ddf5e..74052636f 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java @@ -1,380 +1,390 @@ -package com.ruoyi.system.controller; - -import java.io.IOException; -import java.util.Date; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang3.ArrayUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; -import com.ruoyi.common.core.domain.R; -import com.ruoyi.common.core.text.Convert; -import com.ruoyi.common.core.utils.DateUtils; -import com.ruoyi.common.core.utils.StringUtils; -import com.ruoyi.common.core.utils.poi.ExcelUtil; -import com.ruoyi.common.core.web.controller.BaseController; -import com.ruoyi.common.core.web.domain.AjaxResult; -import com.ruoyi.common.core.web.page.TableDataInfo; -import com.ruoyi.common.log.annotation.Log; -import com.ruoyi.common.log.enums.BusinessType; -import com.ruoyi.common.security.annotation.InnerAuth; -import com.ruoyi.common.security.annotation.RequiresPermissions; -import com.ruoyi.common.security.service.TokenService; -import com.ruoyi.common.security.utils.SecurityUtils; -import com.ruoyi.system.api.domain.SysDept; -import com.ruoyi.system.api.domain.SysRole; -import com.ruoyi.system.api.domain.SysUser; -import com.ruoyi.system.api.model.LoginUser; -import com.ruoyi.system.service.ISysConfigService; -import com.ruoyi.system.service.ISysDeptService; -import com.ruoyi.system.service.ISysPermissionService; -import com.ruoyi.system.service.ISysPostService; -import com.ruoyi.system.service.ISysRoleService; -import com.ruoyi.system.service.ISysUserService; - -/** - * 用户信息 - * - * @author ruoyi - */ -@RestController -@RequestMapping("/user") -public class SysUserController extends BaseController -{ - @Autowired - private ISysUserService userService; - - @Autowired - private ISysRoleService roleService; - - @Autowired - private ISysDeptService deptService; - - @Autowired - private ISysPostService postService; - - @Autowired - private ISysPermissionService permissionService; - - @Autowired - private ISysConfigService configService; - - @Autowired - private TokenService tokenService; - - /** - * 获取用户列表 - */ - @RequiresPermissions("system:user:list") - @GetMapping("/list") - public TableDataInfo list(SysUser user) - { - startPage(); - List list = userService.selectUserList(user); - return getDataTable(list); - } - - @Log(title = "用户管理", businessType = BusinessType.EXPORT) - @RequiresPermissions("system:user:export") - @PostMapping("/export") - public void export(HttpServletResponse response, SysUser user) - { - List list = userService.selectUserList(user); - ExcelUtil util = new ExcelUtil(SysUser.class); - util.exportExcel(response, list, "用户数据"); - } - - @Log(title = "用户管理", businessType = BusinessType.IMPORT) - @RequiresPermissions("system:user:import") - @PostMapping("/importData") - public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception - { - ExcelUtil util = new ExcelUtil(SysUser.class); - List userList = util.importExcel(file.getInputStream()); - String operName = SecurityUtils.getUsername(); - String message = userService.importUser(userList, updateSupport, operName); - return success(message); - } - - @PostMapping("/importTemplate") - public void importTemplate(HttpServletResponse response) throws IOException - { - ExcelUtil util = new ExcelUtil(SysUser.class); - util.importTemplateExcel(response, "用户数据"); - } - - /** - * 获取当前用户信息 - */ - @InnerAuth - @GetMapping("/info/{username}") - public R info(@PathVariable("username") String username) - { - SysUser sysUser = userService.selectUserByUserName(username); - if (StringUtils.isNull(sysUser)) - { - return R.fail("用户名或密码错误"); - } - // 角色集合 - Set roles = permissionService.getRolePermission(sysUser); - // 权限集合 - Set permissions = permissionService.getMenuPermission(sysUser); - LoginUser sysUserVo = new LoginUser(); - sysUserVo.setSysUser(sysUser); - sysUserVo.setRoles(roles); - sysUserVo.setPermissions(permissions); - return R.ok(sysUserVo); - } - - /** - * 注册用户信息 - */ - @InnerAuth - @PostMapping("/register") - public R register(@RequestBody SysUser sysUser) - { - String username = sysUser.getUserName(); - if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) - { - return R.fail("当前系统没有开启注册功能!"); - } - if (!userService.checkUserNameUnique(sysUser)) - { - return R.fail("保存用户'" + username + "'失败,注册账号已存在"); - } - return R.ok(userService.registerUser(sysUser)); - } - - /** - *记录用户登录IP地址和登录时间 - */ - @InnerAuth - @PutMapping("/recordlogin") - public R recordlogin(@RequestBody SysUser sysUser) - { - return R.ok(userService.updateLoginInfo(sysUser)); - } - - /** - * 获取用户信息 - * - * @return 用户信息 - */ - @GetMapping("getInfo") - public AjaxResult getInfo() - { - LoginUser loginUser = SecurityUtils.getLoginUser(); - SysUser user = loginUser.getSysUser(); - // 角色集合 - Set roles = permissionService.getRolePermission(user); - // 权限集合 - Set permissions = permissionService.getMenuPermission(user); - if (!loginUser.getPermissions().equals(permissions)) - { - loginUser.setPermissions(permissions); - tokenService.refreshToken(loginUser); - } - AjaxResult ajax = AjaxResult.success(); - ajax.put("user", user); - ajax.put("roles", roles); - ajax.put("permissions", permissions); - ajax.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate())); - ajax.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate())); - return ajax; - } - - // 检查初始密码是否提醒修改 - public boolean initPasswordIsModify(Date pwdUpdateDate) - { - Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify")); - return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null; - } - - // 检查密码是否过期 - public boolean passwordIsExpiration(Date pwdUpdateDate) - { - Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays")); - if (passwordValidateDays != null && passwordValidateDays > 0) - { - if (StringUtils.isNull(pwdUpdateDate)) - { - // 如果从未修改过初始密码,直接提醒过期 - return true; - } - Date nowDate = DateUtils.getNowDate(); - return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays; - } - return false; - } - - /** - * 根据用户编号获取详细信息 - */ - @RequiresPermissions("system:user:query") - @GetMapping(value = { "/", "/{userId}" }) - public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) - { - AjaxResult ajax = AjaxResult.success(); - if (StringUtils.isNotNull(userId)) - { - userService.checkUserDataScope(userId); - SysUser sysUser = userService.selectUserById(userId); - ajax.put(AjaxResult.DATA_TAG, sysUser); - ajax.put("postIds", postService.selectPostListByUserId(userId)); - ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); - } - List roles = roleService.selectRoleAll(); - ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); - ajax.put("posts", postService.selectPostAll()); - return ajax; - } - - /** - * 新增用户 - */ - @RequiresPermissions("system:user:add") - @Log(title = "用户管理", businessType = BusinessType.INSERT) - @PostMapping - public AjaxResult add(@Validated @RequestBody SysUser user) - { - deptService.checkDeptDataScope(user.getDeptId()); - roleService.checkRoleDataScope(user.getRoleIds()); - if (!userService.checkUserNameUnique(user)) - { - return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); - } - else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) - { - return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); - } - else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) - { - return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); - } - user.setCreateBy(SecurityUtils.getUsername()); - user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); - return toAjax(userService.insertUser(user)); - } - - /** - * 修改用户 - */ - @RequiresPermissions("system:user:edit") - @Log(title = "用户管理", businessType = BusinessType.UPDATE) - @PutMapping - public AjaxResult edit(@Validated @RequestBody SysUser user) - { - userService.checkUserAllowed(user); - userService.checkUserDataScope(user.getUserId()); - deptService.checkDeptDataScope(user.getDeptId()); - roleService.checkRoleDataScope(user.getRoleIds()); - if (!userService.checkUserNameUnique(user)) - { - return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); - } - else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) - { - return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); - } - else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) - { - return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); - } - user.setUpdateBy(SecurityUtils.getUsername()); - return toAjax(userService.updateUser(user)); - } - - /** - * 删除用户 - */ - @RequiresPermissions("system:user:remove") - @Log(title = "用户管理", businessType = BusinessType.DELETE) - @DeleteMapping("/{userIds}") - public AjaxResult remove(@PathVariable Long[] userIds) - { - if (ArrayUtils.contains(userIds, SecurityUtils.getUserId())) - { - return error("当前用户不能删除"); - } - return toAjax(userService.deleteUserByIds(userIds)); - } - - /** - * 重置密码 - */ - @RequiresPermissions("system:user:edit") - @Log(title = "用户管理", businessType = BusinessType.UPDATE) - @PutMapping("/resetPwd") - public AjaxResult resetPwd(@RequestBody SysUser user) - { - userService.checkUserAllowed(user); - userService.checkUserDataScope(user.getUserId()); - user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); - user.setUpdateBy(SecurityUtils.getUsername()); - return toAjax(userService.resetPwd(user)); - } - - /** - * 状态修改 - */ - @RequiresPermissions("system:user:edit") - @Log(title = "用户管理", businessType = BusinessType.UPDATE) - @PutMapping("/changeStatus") - public AjaxResult changeStatus(@RequestBody SysUser user) - { - userService.checkUserAllowed(user); - userService.checkUserDataScope(user.getUserId()); - user.setUpdateBy(SecurityUtils.getUsername()); - return toAjax(userService.updateUserStatus(user)); - } - - /** - * 根据用户编号获取授权角色 - */ - @RequiresPermissions("system:user:query") - @GetMapping("/authRole/{userId}") - public AjaxResult authRole(@PathVariable("userId") Long userId) - { - AjaxResult ajax = AjaxResult.success(); - SysUser user = userService.selectUserById(userId); - List roles = roleService.selectRolesByUserId(userId); - ajax.put("user", user); - ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); - return ajax; - } - - /** - * 用户授权角色 - */ - @RequiresPermissions("system:user:edit") - @Log(title = "用户管理", businessType = BusinessType.GRANT) - @PutMapping("/authRole") - public AjaxResult insertAuthRole(Long userId, Long[] roleIds) - { - userService.checkUserDataScope(userId); - roleService.checkRoleDataScope(roleIds); - userService.insertUserAuth(userId, roleIds); - return success(); - } - - /** - * 获取部门树列表 - */ - @RequiresPermissions("system:user:list") - @GetMapping("/deptTree") - public AjaxResult deptTree(SysDept dept) - { - return success(deptService.selectDeptTreeList(dept)); - } -} +package com.ruoyi.system.controller; + +import java.io.IOException; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.core.utils.DateUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.poi.ExcelUtil; +import com.ruoyi.common.core.web.controller.BaseController; +import com.ruoyi.common.core.web.domain.AjaxResult; +import com.ruoyi.common.core.web.page.TableDataInfo; +import com.ruoyi.common.log.annotation.Log; +import com.ruoyi.common.log.enums.BusinessType; +import com.ruoyi.common.security.annotation.InnerAuth; +import com.ruoyi.common.security.annotation.RequiresPermissions; +import com.ruoyi.common.security.service.TokenService; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysDept; +import com.ruoyi.system.api.domain.SysRole; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.api.model.LoginUser; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysDeptService; +import com.ruoyi.system.service.ISysPermissionService; +import com.ruoyi.system.service.ISysPostService; +import com.ruoyi.system.service.ISysRoleService; +import com.ruoyi.system.service.ISysUserService; + +/** + * 用户信息 + * + * @author ruoyi + */ +@RestController +@RequestMapping("/user") +public class SysUserController extends BaseController +{ + @Autowired + private ISysUserService userService; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + private ISysPostService postService; + + @Autowired + private ISysPermissionService permissionService; + + @Autowired + private ISysConfigService configService; + + @Autowired + private TokenService tokenService; + + /** + * 获取用户列表 + */ + @RequiresPermissions("system:user:list") + @GetMapping("/list") + public TableDataInfo list(SysUser user) + { + startPage(); + List list = userService.selectUserList(user); + return getDataTable(list); + } + + @Log(title = "用户管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:user:export") + @PostMapping("/export") + public void export(HttpServletResponse response, SysUser user) + { + List list = userService.selectUserList(user); + ExcelUtil util = new ExcelUtil(SysUser.class); + util.exportExcel(response, list, "用户数据"); + } + + @Log(title = "用户管理", businessType = BusinessType.IMPORT) + @RequiresPermissions("system:user:import") + @PostMapping("/importData") + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(SysUser.class); + List userList = util.importExcel(file.getInputStream()); + String operName = SecurityUtils.getUsername(); + String message = userService.importUser(userList, updateSupport, operName); + return success(message); + } + + @PostMapping("/importTemplate") + public void importTemplate(HttpServletResponse response) throws IOException + { + ExcelUtil util = new ExcelUtil(SysUser.class); + util.importTemplateExcel(response, "用户数据"); + } + + /** + * 获取当前用户信息 + */ + @InnerAuth + @GetMapping("/info/{username}") + public R info(@PathVariable("username") String username) + { + SysUser sysUser = userService.selectUserByUserName(username); + if (StringUtils.isNull(sysUser)) + { + return R.fail("用户名或密码错误"); + } + // 角色集合 + Set roles = permissionService.getRolePermission(sysUser); + // 权限集合 + Set permissions = permissionService.getMenuPermission(sysUser); + LoginUser sysUserVo = new LoginUser(); + sysUserVo.setSysUser(sysUser); + sysUserVo.setRoles(roles); + sysUserVo.setPermissions(permissions); + return R.ok(sysUserVo); + } + + /** + * 注册用户信息 + */ + @InnerAuth + @PostMapping("/register") + public R register(@RequestBody SysUser sysUser) + { + String username = sysUser.getUserName(); + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) + { + return R.fail("当前系统没有开启注册功能!"); + } + if (!userService.checkUserNameUnique(sysUser)) + { + return R.fail("保存用户'" + username + "'失败,注册账号已存在"); + } + return R.ok(userService.registerUser(sysUser)); + } + + /** + *记录用户登录IP地址和登录时间 + */ + @InnerAuth + @PutMapping("/recordlogin") + public R recordlogin(@RequestBody SysUser sysUser) + { + return R.ok(userService.updateUserProfile(sysUser)); + } + + /** + *记录用户登录IP地址和登录时间 + */ + @InnerAuth + @PutMapping("/syncGO") + public R syncGO(@RequestBody SysUser sysUser) + { + return R.ok(userService.syncGO(sysUser)); + } + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getInfo") + public AjaxResult getInfo() + { + LoginUser loginUser = SecurityUtils.getLoginUser(); + SysUser user = loginUser.getSysUser(); + // 角色集合 + Set roles = permissionService.getRolePermission(user); + // 权限集合 + Set permissions = permissionService.getMenuPermission(user); + if (!loginUser.getPermissions().equals(permissions)) + { + loginUser.setPermissions(permissions); + tokenService.refreshToken(loginUser); + } + AjaxResult ajax = AjaxResult.success(); + ajax.put("user", user); + ajax.put("roles", roles); + ajax.put("permissions", permissions); + ajax.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate())); + ajax.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate())); + return ajax; + } + + // 检查初始密码是否提醒修改 + public boolean initPasswordIsModify(Date pwdUpdateDate) + { + Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify")); + return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null; + } + + // 检查密码是否过期 + public boolean passwordIsExpiration(Date pwdUpdateDate) + { + Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays")); + if (passwordValidateDays != null && passwordValidateDays > 0) + { + if (StringUtils.isNull(pwdUpdateDate)) + { + // 如果从未修改过初始密码,直接提醒过期 + return true; + } + Date nowDate = DateUtils.getNowDate(); + return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays; + } + return false; + } + + /** + * 根据用户编号获取详细信息 + */ + @RequiresPermissions("system:user:query") + @GetMapping(value = { "/", "/{userId}" }) + public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) + { + AjaxResult ajax = AjaxResult.success(); + if (StringUtils.isNotNull(userId)) + { + userService.checkUserDataScope(userId); + SysUser sysUser = userService.selectUserById(userId); + ajax.put(AjaxResult.DATA_TAG, sysUser); + ajax.put("postIds", postService.selectPostListByUserId(userId)); + ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); + } + List roles = roleService.selectRoleAll(); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + ajax.put("posts", postService.selectPostAll()); + return ajax; + } + + /** + * 新增用户 + */ + @RequiresPermissions("system:user:add") + @Log(title = "用户管理", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@Validated @RequestBody SysUser user) + { + deptService.checkDeptDataScope(user.getDeptId()); + roleService.checkRoleDataScope(user.getRoleIds()); + if (!userService.checkUserNameUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setCreateBy(SecurityUtils.getUsername()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + return toAjax(userService.insertUser(user)); + } + + /** + * 修改用户 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@Validated @RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + deptService.checkDeptDataScope(user.getDeptId()); + roleService.checkRoleDataScope(user.getRoleIds()); + if (!userService.checkUserNameUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) + { + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); + } + user.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(userService.updateUser(user)); + } + + /** + * 删除用户 + */ + @RequiresPermissions("system:user:remove") + @Log(title = "用户管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{userIds}") + public AjaxResult remove(@PathVariable Long[] userIds) + { + if (ArrayUtils.contains(userIds, SecurityUtils.getUserId())) + { + return error("当前用户不能删除"); + } + return toAjax(userService.deleteUserByIds(userIds)); + } + + /** + * 重置密码 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/resetPwd") + public AjaxResult resetPwd(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); + user.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(userService.resetPwd(user)); + } + + /** + * 状态修改 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PutMapping("/changeStatus") + public AjaxResult changeStatus(@RequestBody SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setUpdateBy(SecurityUtils.getUsername()); + return toAjax(userService.updateUserStatus(user)); + } + + /** + * 根据用户编号获取授权角色 + */ + @RequiresPermissions("system:user:query") + @GetMapping("/authRole/{userId}") + public AjaxResult authRole(@PathVariable("userId") Long userId) + { + AjaxResult ajax = AjaxResult.success(); + SysUser user = userService.selectUserById(userId); + List roles = roleService.selectRolesByUserId(userId); + ajax.put("user", user); + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + return ajax; + } + + /** + * 用户授权角色 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.GRANT) + @PutMapping("/authRole") + public AjaxResult insertAuthRole(Long userId, Long[] roleIds) + { + userService.checkUserDataScope(userId); + roleService.checkRoleDataScope(roleIds); + userService.insertUserAuth(userId, roleIds); + return success(); + } + + /** + * 获取部门树列表 + */ + @RequiresPermissions("system:user:list") + @GetMapping("/deptTree") + public AjaxResult deptTree(SysDept dept) + { + return success(deptService.selectDeptTreeList(dept)); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SyncGoUser.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SyncGoUser.java new file mode 100644 index 000000000..0e9b1d678 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SyncGoUser.java @@ -0,0 +1,17 @@ +package com.ruoyi.system.domain; + +import lombok.Data; + +@Data +public class SyncGoUser { + private Integer userId; + private String nickname; + private String username; + private String mobile; + private String lastIp; + private String remark; + private String avatar; + private Integer status; + private String openId; + private String unionId; +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java index ec8700d68..cabbbf89e 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java @@ -57,4 +57,12 @@ public interface SysNoticeMapper * @return 结果 */ public int deleteNoticeByIds(Long[] noticeIds); + + /** + * 查询公告信息 + * + * @param noticeTitle 公告标题 + * @return 公告信息 + */ + public SysNotice selectNoticeByNoticeTitle(String noticeTitle); } \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java index c486d804e..71bfc7d63 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java @@ -1,144 +1,145 @@ -package com.ruoyi.system.mapper; - -import java.util.List; -import org.apache.ibatis.annotations.Param; -import com.ruoyi.system.api.domain.SysUser; - -/** - * 用户表 数据层 - * - * @author ruoyi - */ -public interface SysUserMapper -{ - /** - * 根据条件分页查询用户列表 - * - * @param sysUser 用户信息 - * @return 用户信息集合信息 - */ - public List selectUserList(SysUser sysUser); - - /** - * 根据条件分页查询已配用户角色列表 - * - * @param user 用户信息 - * @return 用户信息集合信息 - */ - public List selectAllocatedList(SysUser user); - - /** - * 根据条件分页查询未分配用户角色列表 - * - * @param user 用户信息 - * @return 用户信息集合信息 - */ - public List selectUnallocatedList(SysUser user); - - /** - * 通过用户名查询用户 - * - * @param userName 用户名 - * @return 用户对象信息 - */ - public SysUser selectUserByUserName(String userName); - - /** - * 通过用户ID查询用户 - * - * @param userId 用户ID - * @return 用户对象信息 - */ - public SysUser selectUserById(Long userId); - - /** - * 新增用户信息 - * - * @param user 用户信息 - * @return 结果 - */ - public int insertUser(SysUser user); - - /** - * 修改用户信息 - * - * @param user 用户信息 - * @return 结果 - */ - public int updateUser(SysUser user); - - /** - * 修改用户头像 - * - * @param userId 用户ID - * @param avatar 头像地址 - * @return 结果 - */ - public int updateUserAvatar(@Param("userId") Long userId, @Param("avatar") String avatar); - - /** - * 修改用户状态 - * - * @param userId 用户ID - * @param status 状态 - * @return 结果 - */ - public int updateUserStatus(@Param("userId") Long userId, @Param("status") String status); - - /** - * 更新用户登录信息(IP和登录时间) - * - * @param user 用户信息 - * @return 结果 - */ - public int updateLoginInfo(SysUser user); - - /** - * 重置用户密码 - * - * @param userId 用户ID - * @param password 密码 - * @return 结果 - */ - public int resetUserPwd(@Param("userId") Long userId, @Param("password") String password); - - /** - * 通过用户ID删除用户 - * - * @param userId 用户ID - * @return 结果 - */ - public int deleteUserById(Long userId); - - /** - * 批量删除用户信息 - * - * @param userIds 需要删除的用户ID - * @return 结果 - */ - public int deleteUserByIds(Long[] userIds); - - /** - * 校验用户名称是否唯一 - * - * @param userName 用户名称 - * @return 结果 - */ - public SysUser checkUserNameUnique(String userName); - - /** - * 校验手机号码是否唯一 - * - * @param phonenumber 手机号码 - * @return 结果 - */ - public SysUser checkPhoneUnique(String phonenumber); - - /** - * 校验email是否唯一 - * - * @param email 用户邮箱 - * @return 结果 - */ - public SysUser checkEmailUnique(String email); -} +package com.ruoyi.system.mapper; + +import java.util.List; + +import com.github.pagehelper.Page; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.system.api.domain.SysUser; + +/** + * 用户表 数据层 + * + * @author ruoyi + */ +public interface SysUserMapper +{ + /** + * 根据条件分页查询用户列表 + * + * @param sysUser 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser sysUser); + + /** + * 根据条件分页查询已配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 通过手机号查询用户 + * + * @param phoneNumber 手机号 + * @return 用户对象信息 + */ + public SysUser selectUserByPhoneNumber(String phoneNumber); + + /** + * 通过手机号查询用户 + * + * @param phoneNumber 手机号 + * @return 用户对象信息 + */ + public Page findByPhoneNumberStartingWith(String phoneNumber); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar); + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + public int resetUserPwd(@Param("userName") String userName, @Param("password") String password); + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserById(Long userId); + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 校验用户名称是否唯一 + * + * @param userName 用户名称 + * @return 结果 + */ + public SysUser checkUserNameUnique(String userName); + + /** + * 校验手机号码是否唯一 + * + * @param phonenumber 手机号码 + * @return 结果 + */ + public SysUser checkPhoneUnique(String phonenumber); + + /** + * 校验email是否唯一 + * + * @param email 用户邮箱 + * @return 结果 + */ + public SysUser checkEmailUnique(String email); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java index fb1e420fd..d9d9c02a7 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java @@ -57,4 +57,12 @@ public interface ISysNoticeService * @return 结果 */ public int deleteNoticeByIds(Long[] noticeIds); + + /** + * 查询公告信息 + * + * @param noticeTitle 公告标题 + * @return 公告信息 + */ + public SysNotice selectNoticeByNoticeTitle(String noticeTitle); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java index 107fe9ef2..b7190830f 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java @@ -1,214 +1,232 @@ -package com.ruoyi.system.service; - -import java.util.List; -import com.ruoyi.system.api.domain.SysUser; - -/** - * 用户 业务层 - * - * @author ruoyi - */ -public interface ISysUserService -{ - /** - * 根据条件分页查询用户列表 - * - * @param user 用户信息 - * @return 用户信息集合信息 - */ - public List selectUserList(SysUser user); - - /** - * 根据条件分页查询已分配用户角色列表 - * - * @param user 用户信息 - * @return 用户信息集合信息 - */ - public List selectAllocatedList(SysUser user); - - /** - * 根据条件分页查询未分配用户角色列表 - * - * @param user 用户信息 - * @return 用户信息集合信息 - */ - public List selectUnallocatedList(SysUser user); - - /** - * 通过用户名查询用户 - * - * @param userName 用户名 - * @return 用户对象信息 - */ - public SysUser selectUserByUserName(String userName); - - /** - * 通过用户ID查询用户 - * - * @param userId 用户ID - * @return 用户对象信息 - */ - public SysUser selectUserById(Long userId); - - /** - * 根据用户ID查询用户所属角色组 - * - * @param userName 用户名 - * @return 结果 - */ - public String selectUserRoleGroup(String userName); - - /** - * 根据用户ID查询用户所属岗位组 - * - * @param userName 用户名 - * @return 结果 - */ - public String selectUserPostGroup(String userName); - - /** - * 校验用户名称是否唯一 - * - * @param user 用户信息 - * @return 结果 - */ - public boolean checkUserNameUnique(SysUser user); - - /** - * 校验手机号码是否唯一 - * - * @param user 用户信息 - * @return 结果 - */ - public boolean checkPhoneUnique(SysUser user); - - /** - * 校验email是否唯一 - * - * @param user 用户信息 - * @return 结果 - */ - public boolean checkEmailUnique(SysUser user); - - /** - * 校验用户是否允许操作 - * - * @param user 用户信息 - */ - public void checkUserAllowed(SysUser user); - - /** - * 校验用户是否有数据权限 - * - * @param userId 用户id - */ - public void checkUserDataScope(Long userId); - - /** - * 新增用户信息 - * - * @param user 用户信息 - * @return 结果 - */ - public int insertUser(SysUser user); - - /** - * 注册用户信息 - * - * @param user 用户信息 - * @return 结果 - */ - public boolean registerUser(SysUser user); - - /** - * 修改用户信息 - * - * @param user 用户信息 - * @return 结果 - */ - public int updateUser(SysUser user); - - /** - * 用户授权角色 - * - * @param userId 用户ID - * @param roleIds 角色组 - */ - public void insertUserAuth(Long userId, Long[] roleIds); - - /** - * 修改用户状态 - * - * @param user 用户信息 - * @return 结果 - */ - public int updateUserStatus(SysUser user); - - /** - * 修改用户基本信息 - * - * @param user 用户信息 - * @return 结果 - */ - public boolean updateUserProfile(SysUser user); - - /** - * 修改用户头像 - * - * @param userId 用户ID - * @param avatar 头像地址 - * @return 结果 - */ - public boolean updateUserAvatar(Long userId, String avatar); - - /** - * 更新用户登录信息(IP和登录时间) - * - * @param user 用户信息 - * @return 结果 - */ - public boolean updateLoginInfo(SysUser user); - - /** - * 重置用户密码 - * - * @param user 用户信息 - * @return 结果 - */ - public int resetPwd(SysUser user); - - /** - * 重置用户密码 - * - * @param userId 用户ID - * @param password 密码 - * @return 结果 - */ - public int resetUserPwd(Long userId, String password); - - /** - * 通过用户ID删除用户 - * - * @param userId 用户ID - * @return 结果 - */ - public int deleteUserById(Long userId); - - /** - * 批量删除用户信息 - * - * @param userIds 需要删除的用户ID - * @return 结果 - */ - public int deleteUserByIds(Long[] userIds); - - /** - * 导入用户数据 - * - * @param userList 用户数据列表 - * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 - * @param operName 操作用户 - * @return 结果 - */ - public String importUser(List userList, Boolean isUpdateSupport, String operName); -} +package com.ruoyi.system.service; + +import java.util.List; + +import com.github.pagehelper.Page; +import com.ruoyi.system.api.domain.SysUser; + +/** + * 用户 业务层 + * + * @author ruoyi + */ +public interface ISysUserService +{ + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUserList(SysUser user); + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectAllocatedList(SysUser user); + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + public List selectUnallocatedList(SysUser user); + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByUserName(String userName); + + /** + * 通过手机号查询用户 + * + * @param phoneNumber 用户名 + * @return 用户对象信息 + */ + public SysUser selectUserByPhoneNumber(String phoneNumber); + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + public SysUser selectUserById(Long userId); + + /** + * 通过手机号查询用户 + * + * @param phoneNumber 用户名 + * @return 用户对象信息 + */ + public Page findByPhoneNumberStartingWith(String phoneNumber); + + /** + * 根据用户ID查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserRoleGroup(String userName); + + /** + * 根据用户ID查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + public String selectUserPostGroup(String userName); + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkUserNameUnique(SysUser user); + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkPhoneUnique(SysUser user); + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean checkEmailUnique(SysUser user); + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + public void checkUserAllowed(SysUser user); + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + public void checkUserDataScope(Long userId); + + /** + * 新增用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int insertUser(SysUser user); + + /** + * 注册用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean registerUser(SysUser user); + + /** + * 修改用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUser(SysUser user); + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserAuth(Long userId, Long[] roleIds); + + /** + * 修改用户状态 + * + * @param user 用户信息 + * @return 结果 + */ + public int updateUserStatus(SysUser user); + + /** + * 修改用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean updateUserProfile(SysUser user); + + /** + * 同步用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + public boolean syncGO(SysUser user); + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + public boolean updateUserAvatar(String userName, String avatar); + + /** + * 重置用户密码 + * + * @param user 用户信息 + * @return 结果 + */ + public int resetPwd(SysUser user); + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + public int resetUserPwd(String userName, String password); + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + public int deleteUserById(Long userId); + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + public int deleteUserByIds(Long[] userIds); + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + public String importUser(List userList, Boolean isUpdateSupport, String operName); +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java index 8bebd9c69..beb6e295f 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java @@ -89,4 +89,15 @@ public class SysNoticeServiceImpl implements ISysNoticeService { return noticeMapper.deleteNoticeByIds(noticeIds); } + + /** + * 查询公告信息 + * + * @param noticeTitle 公告标题 + * @return 公告信息 + */ + @Override + public SysNotice selectNoticeByNoticeTitle(String noticeTitle) { + return noticeMapper.selectNoticeByNoticeTitle(noticeTitle); + } } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java index 4c646af8c..54d3a88b2 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -1,563 +1,637 @@ -package com.ruoyi.system.service.impl; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; -import javax.validation.Validator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.CollectionUtils; -import com.ruoyi.common.core.constant.UserConstants; -import com.ruoyi.common.core.exception.ServiceException; -import com.ruoyi.common.core.utils.SpringUtils; -import com.ruoyi.common.core.utils.StringUtils; -import com.ruoyi.common.core.utils.bean.BeanValidators; -import com.ruoyi.common.datascope.annotation.DataScope; -import com.ruoyi.common.security.utils.SecurityUtils; -import com.ruoyi.system.api.domain.SysRole; -import com.ruoyi.system.api.domain.SysUser; -import com.ruoyi.system.domain.SysPost; -import com.ruoyi.system.domain.SysUserPost; -import com.ruoyi.system.domain.SysUserRole; -import com.ruoyi.system.mapper.SysPostMapper; -import com.ruoyi.system.mapper.SysRoleMapper; -import com.ruoyi.system.mapper.SysUserMapper; -import com.ruoyi.system.mapper.SysUserPostMapper; -import com.ruoyi.system.mapper.SysUserRoleMapper; -import com.ruoyi.system.service.ISysConfigService; -import com.ruoyi.system.service.ISysDeptService; -import com.ruoyi.system.service.ISysUserService; - -/** - * 用户 业务层处理 - * - * @author ruoyi - */ -@Service -public class SysUserServiceImpl implements ISysUserService -{ - private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class); - - @Autowired - private SysUserMapper userMapper; - - @Autowired - private SysRoleMapper roleMapper; - - @Autowired - private SysPostMapper postMapper; - - @Autowired - private SysUserRoleMapper userRoleMapper; - - @Autowired - private SysUserPostMapper userPostMapper; - - @Autowired - private ISysConfigService configService; - - @Autowired - private ISysDeptService deptService; - - @Autowired - protected Validator validator; - - /** - * 根据条件分页查询用户列表 - * - * @param user 用户信息 - * @return 用户信息集合信息 - */ - @Override - @DataScope(deptAlias = "d", userAlias = "u") - public List selectUserList(SysUser user) - { - return userMapper.selectUserList(user); - } - - /** - * 根据条件分页查询已分配用户角色列表 - * - * @param user 用户信息 - * @return 用户信息集合信息 - */ - @Override - @DataScope(deptAlias = "d", userAlias = "u") - public List selectAllocatedList(SysUser user) - { - return userMapper.selectAllocatedList(user); - } - - /** - * 根据条件分页查询未分配用户角色列表 - * - * @param user 用户信息 - * @return 用户信息集合信息 - */ - @Override - @DataScope(deptAlias = "d", userAlias = "u") - public List selectUnallocatedList(SysUser user) - { - return userMapper.selectUnallocatedList(user); - } - - /** - * 通过用户名查询用户 - * - * @param userName 用户名 - * @return 用户对象信息 - */ - @Override - public SysUser selectUserByUserName(String userName) - { - return userMapper.selectUserByUserName(userName); - } - - /** - * 通过用户ID查询用户 - * - * @param userId 用户ID - * @return 用户对象信息 - */ - @Override - public SysUser selectUserById(Long userId) - { - return userMapper.selectUserById(userId); - } - - /** - * 查询用户所属角色组 - * - * @param userName 用户名 - * @return 结果 - */ - @Override - public String selectUserRoleGroup(String userName) - { - List list = roleMapper.selectRolesByUserName(userName); - if (CollectionUtils.isEmpty(list)) - { - return StringUtils.EMPTY; - } - return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(",")); - } - - /** - * 查询用户所属岗位组 - * - * @param userName 用户名 - * @return 结果 - */ - @Override - public String selectUserPostGroup(String userName) - { - List list = postMapper.selectPostsByUserName(userName); - if (CollectionUtils.isEmpty(list)) - { - return StringUtils.EMPTY; - } - return list.stream().map(SysPost::getPostName).collect(Collectors.joining(",")); - } - - /** - * 校验用户名称是否唯一 - * - * @param user 用户信息 - * @return 结果 - */ - @Override - public boolean checkUserNameUnique(SysUser user) - { - Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); - SysUser info = userMapper.checkUserNameUnique(user.getUserName()); - if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) - { - return UserConstants.NOT_UNIQUE; - } - return UserConstants.UNIQUE; - } - - /** - * 校验手机号码是否唯一 - * - * @param user 用户信息 - * @return - */ - @Override - public boolean checkPhoneUnique(SysUser user) - { - Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); - SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber()); - if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) - { - return UserConstants.NOT_UNIQUE; - } - return UserConstants.UNIQUE; - } - - /** - * 校验email是否唯一 - * - * @param user 用户信息 - * @return - */ - @Override - public boolean checkEmailUnique(SysUser user) - { - Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); - SysUser info = userMapper.checkEmailUnique(user.getEmail()); - if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) - { - return UserConstants.NOT_UNIQUE; - } - return UserConstants.UNIQUE; - } - - /** - * 校验用户是否允许操作 - * - * @param user 用户信息 - */ - @Override - public void checkUserAllowed(SysUser user) - { - if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) - { - throw new ServiceException("不允许操作超级管理员用户"); - } - } - - /** - * 校验用户是否有数据权限 - * - * @param userId 用户id - */ - @Override - public void checkUserDataScope(Long userId) - { - if (!SysUser.isAdmin(SecurityUtils.getUserId())) - { - SysUser user = new SysUser(); - user.setUserId(userId); - List users = SpringUtils.getAopProxy(this).selectUserList(user); - if (StringUtils.isEmpty(users)) - { - throw new ServiceException("没有权限访问用户数据!"); - } - } - } - - /** - * 新增保存用户信息 - * - * @param user 用户信息 - * @return 结果 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int insertUser(SysUser user) - { - // 新增用户信息 - int rows = userMapper.insertUser(user); - // 新增用户岗位关联 - insertUserPost(user); - // 新增用户与角色管理 - insertUserRole(user); - return rows; - } - - /** - * 注册用户信息 - * - * @param user 用户信息 - * @return 结果 - */ - @Override - public boolean registerUser(SysUser user) - { - return userMapper.insertUser(user) > 0; - } - - /** - * 修改保存用户信息 - * - * @param user 用户信息 - * @return 结果 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int updateUser(SysUser user) - { - Long userId = user.getUserId(); - // 删除用户与角色关联 - userRoleMapper.deleteUserRoleByUserId(userId); - // 新增用户与角色管理 - insertUserRole(user); - // 删除用户与岗位关联 - userPostMapper.deleteUserPostByUserId(userId); - // 新增用户与岗位管理 - insertUserPost(user); - return userMapper.updateUser(user); - } - - /** - * 用户授权角色 - * - * @param userId 用户ID - * @param roleIds 角色组 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public void insertUserAuth(Long userId, Long[] roleIds) - { - userRoleMapper.deleteUserRoleByUserId(userId); - insertUserRole(userId, roleIds); - } - - /** - * 修改用户状态 - * - * @param user 用户信息 - * @return 结果 - */ - @Override - public int updateUserStatus(SysUser user) - { - return userMapper.updateUserStatus(user.getUserId(), user.getStatus()); - } - - /** - * 修改用户基本信息 - * - * @param user 用户信息 - * @return 结果 - */ - @Override - public boolean updateUserProfile(SysUser user) - { - return userMapper.updateUser(user) > 0; - } - - /** - * 修改用户头像 - * - * @param userId 用户ID - * @param avatar 头像地址 - * @return 结果 - */ - @Override - public boolean updateUserAvatar(Long userId, String avatar) - { - return userMapper.updateUserAvatar(userId, avatar) > 0; - } - - /** - * 更新用户登录信息(IP和登录时间) - * - * @param user 用户信息 - * @return 结果 - */ - public boolean updateLoginInfo(SysUser user) - { - return userMapper.updateLoginInfo(user) > 0; - } - - /** - * 重置用户密码 - * - * @param user 用户信息 - * @return 结果 - */ - @Override - public int resetPwd(SysUser user) - { - return userMapper.resetUserPwd(user.getUserId(), user.getPassword()); - } - - /** - * 重置用户密码 - * - * @param userId 用户ID - * @param password 密码 - * @return 结果 - */ - @Override - public int resetUserPwd(Long userId, String password) - { - return userMapper.resetUserPwd(userId, password); - } - - /** - * 新增用户角色信息 - * - * @param user 用户对象 - */ - public void insertUserRole(SysUser user) - { - this.insertUserRole(user.getUserId(), user.getRoleIds()); - } - - /** - * 新增用户岗位信息 - * - * @param user 用户对象 - */ - public void insertUserPost(SysUser user) - { - Long[] posts = user.getPostIds(); - if (StringUtils.isNotEmpty(posts)) - { - // 新增用户与岗位管理 - List list = new ArrayList(); - for (Long postId : posts) - { - SysUserPost up = new SysUserPost(); - up.setUserId(user.getUserId()); - up.setPostId(postId); - list.add(up); - } - userPostMapper.batchUserPost(list); - } - } - - /** - * 新增用户角色信息 - * - * @param userId 用户ID - * @param roleIds 角色组 - */ - public void insertUserRole(Long userId, Long[] roleIds) - { - if (StringUtils.isNotEmpty(roleIds)) - { - // 新增用户与角色管理 - List list = new ArrayList(); - for (Long roleId : roleIds) - { - SysUserRole ur = new SysUserRole(); - ur.setUserId(userId); - ur.setRoleId(roleId); - list.add(ur); - } - userRoleMapper.batchUserRole(list); - } - } - - /** - * 通过用户ID删除用户 - * - * @param userId 用户ID - * @return 结果 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int deleteUserById(Long userId) - { - // 删除用户与角色关联 - userRoleMapper.deleteUserRoleByUserId(userId); - // 删除用户与岗位表 - userPostMapper.deleteUserPostByUserId(userId); - return userMapper.deleteUserById(userId); - } - - /** - * 批量删除用户信息 - * - * @param userIds 需要删除的用户ID - * @return 结果 - */ - @Override - @Transactional(rollbackFor = Exception.class) - public int deleteUserByIds(Long[] userIds) - { - for (Long userId : userIds) - { - checkUserAllowed(new SysUser(userId)); - checkUserDataScope(userId); - } - // 删除用户与角色关联 - userRoleMapper.deleteUserRole(userIds); - // 删除用户与岗位关联 - userPostMapper.deleteUserPost(userIds); - return userMapper.deleteUserByIds(userIds); - } - - /** - * 导入用户数据 - * - * @param userList 用户数据列表 - * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 - * @param operName 操作用户 - * @return 结果 - */ - @Override - public String importUser(List userList, Boolean isUpdateSupport, String operName) - { - if (StringUtils.isNull(userList) || userList.size() == 0) - { - throw new ServiceException("导入用户数据不能为空!"); - } - int successNum = 0; - int failureNum = 0; - StringBuilder successMsg = new StringBuilder(); - StringBuilder failureMsg = new StringBuilder(); - for (SysUser user : userList) - { - try - { - // 验证是否存在这个用户 - SysUser u = userMapper.selectUserByUserName(user.getUserName()); - if (StringUtils.isNull(u)) - { - BeanValidators.validateWithException(validator, user); - deptService.checkDeptDataScope(user.getDeptId()); - String password = configService.selectConfigByKey("sys.user.initPassword"); - user.setPassword(SecurityUtils.encryptPassword(password)); - user.setCreateBy(operName); - userMapper.insertUser(user); - successNum++; - successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 导入成功"); - } - else if (isUpdateSupport) - { - BeanValidators.validateWithException(validator, user); - checkUserAllowed(u); - checkUserDataScope(u.getUserId()); - deptService.checkDeptDataScope(user.getDeptId()); - user.setUserId(u.getUserId()); - user.setDeptId(u.getDeptId()); - user.setUpdateBy(operName); - userMapper.updateUser(user); - successNum++; - successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 更新成功"); - } - else - { - failureNum++; - failureMsg.append("
" + failureNum + "、账号 " + user.getUserName() + " 已存在"); - } - } - catch (Exception e) - { - failureNum++; - String msg = "
" + failureNum + "、账号 " + user.getUserName() + " 导入失败:"; - failureMsg.append(msg + e.getMessage()); - log.error(msg, e); - } - } - if (failureNum > 0) - { - failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); - throw new ServiceException(failureMsg.toString()); - } - else - { - successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); - } - return successMsg.toString(); - } - -} +package com.ruoyi.system.service.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import javax.validation.Validator; + +import cn.hutool.system.UserInfo; +import com.alibaba.fastjson.JSON; +import com.github.pagehelper.Page; +import com.ruoyi.system.api.domain.KSysUserAccount; +import com.ruoyi.system.domain.SyncGoUser; +import com.ruoyi.system.service.IKSysUserService; +import org.apache.http.client.methods.HttpPost; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import com.ruoyi.common.core.constant.UserConstants; +import com.ruoyi.common.core.exception.ServiceException; +import com.ruoyi.common.core.utils.SpringUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.core.utils.bean.BeanValidators; +import com.ruoyi.common.datascope.annotation.DataScope; +import com.ruoyi.common.security.utils.SecurityUtils; +import com.ruoyi.system.api.domain.SysRole; +import com.ruoyi.system.api.domain.SysUser; +import com.ruoyi.system.domain.SysPost; +import com.ruoyi.system.domain.SysUserPost; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.mapper.SysPostMapper; +import com.ruoyi.system.mapper.SysRoleMapper; +import com.ruoyi.system.mapper.SysUserMapper; +import com.ruoyi.system.mapper.SysUserPostMapper; +import com.ruoyi.system.mapper.SysUserRoleMapper; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysDeptService; +import com.ruoyi.system.service.ISysUserService; +import org.springframework.web.client.RestTemplate; + +/** + * 用户 业务层处理 + * + * @author ruoyi + */ +@Service +public class SysUserServiceImpl implements ISysUserService +{ + @Value("${go.host}") + private String goHost; + @Value("${go.accessKey}") + private String accessKey; + + private static final Logger log = LoggerFactory.getLogger(SysUserServiceImpl.class); + + @Autowired + private SysUserMapper userMapper; + + @Autowired + private IKSysUserService kSysUserService; + + @Autowired + private SysRoleMapper roleMapper; + + @Autowired + private SysPostMapper postMapper; + + @Autowired + private SysUserRoleMapper userRoleMapper; + + @Autowired + private SysUserPostMapper userPostMapper; + + @Autowired + private ISysConfigService configService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + protected Validator validator; + + + /** + * 根据条件分页查询用户列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUserList(SysUser user) + { + return userMapper.selectUserList(user); + } + + /** + * 根据条件分页查询已分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectAllocatedList(SysUser user) + { + return userMapper.selectAllocatedList(user); + } + + /** + * 根据条件分页查询未分配用户角色列表 + * + * @param user 用户信息 + * @return 用户信息集合信息 + */ + @Override + @DataScope(deptAlias = "d", userAlias = "u") + public List selectUnallocatedList(SysUser user) + { + return userMapper.selectUnallocatedList(user); + } + + /** + * 通过用户名查询用户 + * + * @param userName 用户名 + * @return 用户对象信息 + */ + @Override + public SysUser selectUserByUserName(String userName) + { + return userMapper.selectUserByUserName(userName); + } + + /** + * 通过手机号查询用户 + * + * @param phoneNumber 手机号 + * @return 用户对象信息 + */ + @Override + public SysUser selectUserByPhoneNumber(String phoneNumber) { + return userMapper.selectUserByPhoneNumber(phoneNumber); + } + + /** + * 通过手机号查询用户 + * + * @param phoneNumber 手机号 + * @return 用户对象信息 + */ + @Override + public Page findByPhoneNumberStartingWith(String phoneNumber) { + return userMapper.findByPhoneNumberStartingWith(phoneNumber); + } + + /** + * 通过用户ID查询用户 + * + * @param userId 用户ID + * @return 用户对象信息 + */ + @Override + public SysUser selectUserById(Long userId) + { + return userMapper.selectUserById(userId); + } + + /** + * 查询用户所属角色组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserRoleGroup(String userName) + { + List list = roleMapper.selectRolesByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(",")); + } + + /** + * 查询用户所属岗位组 + * + * @param userName 用户名 + * @return 结果 + */ + @Override + public String selectUserPostGroup(String userName) + { + List list = postMapper.selectPostsByUserName(userName); + if (CollectionUtils.isEmpty(list)) + { + return StringUtils.EMPTY; + } + return list.stream().map(SysPost::getPostName).collect(Collectors.joining(",")); + } + + /** + * 校验用户名称是否唯一 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean checkUserNameUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkUserNameUnique(user.getUserName()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验手机号码是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public boolean checkPhoneUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkPhoneUnique(user.getPhonenumber()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验email是否唯一 + * + * @param user 用户信息 + * @return + */ + @Override + public boolean checkEmailUnique(SysUser user) + { + Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId(); + SysUser info = userMapper.checkEmailUnique(user.getEmail()); + if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) + { + return UserConstants.NOT_UNIQUE; + } + return UserConstants.UNIQUE; + } + + /** + * 校验用户是否允许操作 + * + * @param user 用户信息 + */ + @Override + public void checkUserAllowed(SysUser user) + { + if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) + { + throw new ServiceException("不允许操作超级管理员用户"); + } + } + + /** + * 校验用户是否有数据权限 + * + * @param userId 用户id + */ + @Override + public void checkUserDataScope(Long userId) + { + if (!SysUser.isAdmin(SecurityUtils.getUserId())) + { + SysUser user = new SysUser(); + user.setUserId(userId); + List users = SpringUtils.getAopProxy(this).selectUserList(user); + if (StringUtils.isEmpty(users)) + { + throw new ServiceException("没有权限访问用户数据!"); + } + } + } + + /** + * 新增保存用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int insertUser(SysUser user) + { + // 新增用户信息 + int rows = userMapper.insertUser(user); + // 新增用户岗位关联 + insertUserPost(user); + // 新增用户与角色管理 + insertUserRole(user); + return rows; + } + + /** + * 注册用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean registerUser(SysUser user) + { + boolean res = userMapper.insertUser(user) > 0; + this.syncGO(user); + return res; + } + + /** + * 修改保存用户信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int updateUser(SysUser user) { + Long userId = user.getUserId(); + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 新增用户与角色管理 + insertUserRole(user); + // 删除用户与岗位关联 + userPostMapper.deleteUserPostByUserId(userId); + // 新增用户与岗位管理 + insertUserPost(user); + // 更新微信信息 + if (Objects.nonNull(user.getSysUserAccount())) { + if (Objects.nonNull(user.getSysUserAccount().getWxUnionId())) { + kSysUserService.updateSysUserAccount(user.getSysUserAccount()); + } + } + this.syncGO(user); + return userMapper.updateUser(user); + } + + /** + * 用户授权角色 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void insertUserAuth(Long userId, Long[] roleIds) + { + userRoleMapper.deleteUserRoleByUserId(userId); + insertUserRole(userId, roleIds); + } + + /** + * 修改用户状态 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int updateUserStatus(SysUser user) + { + this.syncGO(user); + return userMapper.updateUser(user); + } + + /** + * 修改用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean updateUserProfile(SysUser user) + { + this.syncGO(user); + return userMapper.updateUser(user) > 0; + } + + /** + * 同步用户基本信息 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public boolean syncGO(SysUser user){ + RestTemplate restTemplate = new RestTemplate(); + String url = goHost + "/api/v2/mini/user/zkSyncUser/"+accessKey; + SyncGoUser syncGoUser = new SyncGoUser(); + syncGoUser.setUserId(Math.toIntExact(user.getUserId())); + syncGoUser.setNickname(user.getNickName()); + syncGoUser.setUsername(user.getUserName()); + syncGoUser.setMobile(user.getPhonenumber()); + syncGoUser.setLastIp(user.getLoginIp()); + syncGoUser.setRemark(user.getRemark()); + syncGoUser.setAvatar(user.getAvatar()); + syncGoUser.setStatus(Objects.equals(user.getStatus(), "1") ?1:0); + if (user.getSysUserAccount() != null) { + syncGoUser.setUnionId(user.getSysUserAccount().getWxUnionId()); + syncGoUser.setOpenId(user.getSysUserAccount().getRoutineOpenid()); + } + ResponseEntity response = restTemplate.postForEntity(url, syncGoUser, String.class); + // 检查响应状态码 + if (response.getStatusCode().is2xxSuccessful()) { + System.out.println("响应内容:" + response.getBody()); + } else { + System.out.println("请求失败,状态码:" + response.getStatusCode()); + } + return true; + } + + /** + * 修改用户头像 + * + * @param userName 用户名 + * @param avatar 头像地址 + * @return 结果 + */ + @Override + public boolean updateUserAvatar(String userName, String avatar) + { + return userMapper.updateUserAvatar(userName, avatar) > 0; + } + + /** + * 重置用户密码 + * + * @param user 用户信息 + * @return 结果 + */ + @Override + public int resetPwd(SysUser user) + { + return userMapper.updateUser(user); + } + + /** + * 重置用户密码 + * + * @param userName 用户名 + * @param password 密码 + * @return 结果 + */ + @Override + public int resetUserPwd(String userName, String password) + { + return userMapper.resetUserPwd(userName, password); + } + + /** + * 新增用户角色信息 + * + * @param user 用户对象 + */ + public void insertUserRole(SysUser user) + { + this.insertUserRole(user.getUserId(), user.getRoleIds()); + } + + /** + * 新增用户岗位信息 + * + * @param user 用户对象 + */ + public void insertUserPost(SysUser user) + { + Long[] posts = user.getPostIds(); + if (StringUtils.isNotEmpty(posts)) + { + // 新增用户与岗位管理 + List list = new ArrayList(); + for (Long postId : posts) + { + SysUserPost up = new SysUserPost(); + up.setUserId(user.getUserId()); + up.setPostId(postId); + list.add(up); + } + userPostMapper.batchUserPost(list); + } + } + + /** + * 新增用户角色信息 + * + * @param userId 用户ID + * @param roleIds 角色组 + */ + public void insertUserRole(Long userId, Long[] roleIds) + { + if (StringUtils.isNotEmpty(roleIds)) + { + // 新增用户与角色管理 + List list = new ArrayList(); + for (Long roleId : roleIds) + { + SysUserRole ur = new SysUserRole(); + ur.setUserId(userId); + ur.setRoleId(roleId); + list.add(ur); + } + userRoleMapper.batchUserRole(list); + } + } + + /** + * 通过用户ID删除用户 + * + * @param userId 用户ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteUserById(Long userId) + { + // 删除用户与角色关联 + userRoleMapper.deleteUserRoleByUserId(userId); + // 删除用户与岗位表 + userPostMapper.deleteUserPostByUserId(userId); + return userMapper.deleteUserById(userId); + } + + /** + * 批量删除用户信息 + * + * @param userIds 需要删除的用户ID + * @return 结果 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public int deleteUserByIds(Long[] userIds) + { + for (Long userId : userIds) + { + checkUserAllowed(new SysUser(userId)); + checkUserDataScope(userId); + } + // 删除用户与角色关联 + userRoleMapper.deleteUserRole(userIds); + // 删除用户与岗位关联 + userPostMapper.deleteUserPost(userIds); + return userMapper.deleteUserByIds(userIds); + } + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @param operName 操作用户 + * @return 结果 + */ + @Override + public String importUser(List userList, Boolean isUpdateSupport, String operName) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new ServiceException("导入用户数据不能为空!"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + for (SysUser user : userList) + { + try + { + // 验证是否存在这个用户 + SysUser u = userMapper.selectUserByUserName(user.getUserName()); + if (StringUtils.isNull(u)) + { + BeanValidators.validateWithException(validator, user); + deptService.checkDeptDataScope(user.getDeptId()); + String password = configService.selectConfigByKey("sys.user.initPassword"); + user.setPassword(SecurityUtils.encryptPassword(password)); + user.setCreateBy(operName); + userMapper.insertUser(user); + successNum++; + successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 导入成功"); + } + else if (isUpdateSupport) + { + BeanValidators.validateWithException(validator, user); + checkUserAllowed(u); + checkUserDataScope(u.getUserId()); + deptService.checkDeptDataScope(user.getDeptId()); + user.setUserId(u.getUserId()); + user.setUpdateBy(operName); + userMapper.updateUser(user); + successNum++; + successMsg.append("
" + successNum + "、账号 " + user.getUserName() + " 更新成功"); + } + else + { + failureNum++; + failureMsg.append("
" + failureNum + "、账号 " + user.getUserName() + " 已存在"); + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "、账号 " + user.getUserName() + " 导入失败:"; + failureMsg.append(msg + e.getMessage()); + log.error(msg, e); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java b/ruoyi-modules/ruoyi-system/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java new file mode 100644 index 000000000..68e35e6b1 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointProperties.java @@ -0,0 +1,140 @@ +/* + * Copyright 2012-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.endpoint.web; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +/** + * Configuration properties for web management endpoints. + * + * @author Madhura Bhave + * @author Phillip Webb + * @since 2.0.0 + */ +@ConfigurationProperties(prefix = "management.endpoints.web") +public class WebEndpointProperties { + + private final Exposure exposure = new Exposure(); + + /** + * Base path for Web endpoints. Relative to the servlet context path + * (server.servlet.context-path) or WebFlux base path (spring.webflux.base-path) when + * the management server is sharing the main server port. Relative to the management + * server base path (management.server.base-path) when a separate management server + * port (management.server.port) is configured. + */ + private String basePath = "/actuator"; + private String baseUrl = null; + + /** + * Mapping between endpoint IDs and the path that should expose them. + */ + private final Map pathMapping = new LinkedHashMap<>(); + + private final Discovery discovery = new Discovery(); + + public Exposure getExposure() { + return this.exposure; + } + + public String getBasePath() { + return this.basePath; + } + + public void setBasePath(String basePath) { + Assert.isTrue(basePath.isEmpty() || basePath.startsWith("/"), "Base path must start with '/' or be empty"); + this.basePath = cleanBasePath(basePath); + } + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + private String cleanBasePath(String basePath) { + if (StringUtils.hasText(basePath) && basePath.endsWith("/")) { + return basePath.substring(0, basePath.length() - 1); + } + return basePath; + } + + public Map getPathMapping() { + return this.pathMapping; + } + + public Discovery getDiscovery() { + return this.discovery; + } + + public static class Exposure { + + /** + * Endpoint IDs that should be included or '*' for all. + */ + private Set include = new LinkedHashSet<>(); + + /** + * Endpoint IDs that should be excluded or '*' for all. + */ + private Set exclude = new LinkedHashSet<>(); + + public Set getInclude() { + return this.include; + } + + public void setInclude(Set include) { + this.include = include; + } + + public Set getExclude() { + return this.exclude; + } + + public void setExclude(Set exclude) { + this.exclude = exclude; + } + + } + + public static class Discovery { + + /** + * Whether the discovery page is enabled. + */ + private boolean enabled = true; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + } + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java b/ruoyi-modules/ruoyi-system/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java new file mode 100644 index 000000000..1c7dae1bb --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java @@ -0,0 +1,113 @@ +/* + * Copyright 2012-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.servlet; + +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.endpoint.web.*; +import org.springframework.context.annotation.Lazy; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.util.pattern.PathPatternParser; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +/** + * A custom {@link HandlerMapping} that makes web endpoints available over HTTP using + * Spring MVC. + * + * @author Andy Wilkinson + * @author Phillip Webb + * @since 2.0.0 + */ +public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerMapping { + + private final EndpointLinksResolver linksResolver; + @Lazy + @Resource + private WebEndpointProperties webEndpointProperties; + + /** + * Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings + * for the given endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param endpointMediaTypes media types consumed and produced by the endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered + */ + public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, + EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, + EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping) { + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping); + this.linksResolver = linksResolver; + setOrder(-100); + } + + /** + * Creates a new {@code WebMvcEndpointHandlerMapping} instance that provides mappings + * for the given endpoints. + * @param endpointMapping the base mapping for all endpoints + * @param endpoints the web endpoints + * @param endpointMediaTypes media types consumed and produced by the endpoints + * @param corsConfiguration the CORS configuration for the endpoints or {@code null} + * @param linksResolver resolver for determining links to available endpoints + * @param shouldRegisterLinksMapping whether the links endpoint should be registered + * @param pathPatternParser the path pattern parser + */ + public WebMvcEndpointHandlerMapping(EndpointMapping endpointMapping, Collection endpoints, + EndpointMediaTypes endpointMediaTypes, CorsConfiguration corsConfiguration, + EndpointLinksResolver linksResolver, boolean shouldRegisterLinksMapping, + PathPatternParser pathPatternParser) { + super(endpointMapping, endpoints, endpointMediaTypes, corsConfiguration, shouldRegisterLinksMapping, + pathPatternParser); + this.linksResolver = linksResolver; + setOrder(-100); + } + + @Override + protected LinksHandler getLinksHandler() { + return new WebMvcLinksHandler(); + } + + /** + * Handler for root endpoint providing links. + */ + class WebMvcLinksHandler implements LinksHandler { + + @Override + @ResponseBody + public Map> links(HttpServletRequest request, HttpServletResponse response) { + return Collections.singletonMap("_links", + WebMvcEndpointHandlerMapping.this.linksResolver.resolveLinks(ObjectUtils.isEmpty(webEndpointProperties.getBaseUrl())?request.getRequestURL().toString():(webEndpointProperties.getBaseUrl()+webEndpointProperties.getBasePath()))); + } + + @Override + public String toString() { + return "Actuator root web endpoint"; + } + + } + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/controller/inner/InnerSysNoticeController.kt b/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/controller/inner/InnerSysNoticeController.kt new file mode 100644 index 000000000..b9f0e13e6 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/controller/inner/InnerSysNoticeController.kt @@ -0,0 +1,30 @@ +package com.ruoyi.system.controller.inner + +import com.ruoyi.common.core.domain.R +import com.ruoyi.common.core.web.controller.BaseController +import com.ruoyi.common.security.annotation.InnerAuth +import com.ruoyi.system.service.ISysNoticeService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.bind.annotation.RestController + +/** + * 内部调用公告信息 + */ +@RestController +@RequestMapping("/inner/notice") +open class InnerSysNoticeController : BaseController() { + @Autowired + open lateinit var noticeService: ISysNoticeService + + /** + * 根据ID获取公告信息 + */ + @InnerAuth + @GetMapping("/detail") + fun infoById(@RequestParam("noticeId") noticeId: Long): R { + return R.ok(noticeService.selectNoticeById(noticeId)) + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/controller/inner/InnerSysUserController.kt b/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/controller/inner/InnerSysUserController.kt new file mode 100644 index 000000000..e125fa8a7 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/controller/inner/InnerSysUserController.kt @@ -0,0 +1,178 @@ +package com.ruoyi.system.controller.inner + +import com.github.pagehelper.Page +import com.ruoyi.common.core.domain.R +import com.ruoyi.common.core.utils.StringUtils +import com.ruoyi.common.core.utils.ip.IpUtils +import com.ruoyi.common.core.web.controller.BaseController +import com.ruoyi.common.core.web.domain.AjaxResult +import com.ruoyi.common.log.annotation.Log +import com.ruoyi.common.log.enums.BusinessType +import com.ruoyi.common.security.annotation.InnerAuth +import com.ruoyi.common.security.service.TokenService +import com.ruoyi.common.security.utils.SecurityUtils +import com.ruoyi.system.api.domain.KSysUserAccount +import com.ruoyi.system.api.domain.SysUser +import com.ruoyi.system.api.model.LoginUser +import com.ruoyi.system.service.IKSysUserService +import com.ruoyi.system.service.ISysConfigService +import com.ruoyi.system.service.ISysPermissionService +import com.ruoyi.system.service.ISysUserService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.validation.annotation.Validated +import org.springframework.web.bind.annotation.* + +/** + * 用户信息 + * + * @author hsdllcw + */ +@RestController +@RequestMapping("/inner/user") +open class InnerSysUserController : BaseController() { + + @Autowired + open lateinit var userService: ISysUserService + + @Autowired + open lateinit var kSysUserService: IKSysUserService + + @Autowired + open lateinit var permissionService: ISysPermissionService + + @Autowired + open lateinit var tokenService: TokenService + + @Autowired + open lateinit var configService: ISysConfigService + + + /** + * 获取当前用户信息 + */ + @InnerAuth + @GetMapping("/info/phoneNumber/{phoneNumber:\\d+}") + fun infoByPhone(@PathVariable("phoneNumber") phoneNumber: String?): R { + val sysUser: SysUser = userService.selectUserByPhoneNumber(phoneNumber) + if (StringUtils.isNull(sysUser)) { + return R.fail("用户名或密码错误") + } + // 角色集合 + val roles: Set = permissionService.getRolePermission(sysUser) + // 权限集合 + val permissions: Set = permissionService.getMenuPermission(sysUser) + val sysUserVo = LoginUser() + sysUserVo.sysUser = sysUser + sysUserVo.roles = roles + sysUserVo.permissions = permissions + return R.ok(sysUserVo) + } + + /** + * 获取当前用户信息 + */ + @InnerAuth + @GetMapping("/list/phoneNumber/{phoneNumber:\\d+}") + fun findByPhoneNumberStartingWith(@PathVariable("phoneNumber") phoneNumber: String?): R> { + return R.ok(userService.findByPhoneNumberStartingWith(phoneNumber)) + } + + /** + * 根据ID获取用户信息 + */ + @InnerAuth + @GetMapping("/detail/{userId}") + fun infoById(@PathVariable("userId") userId: Long): R { + val sysUser: SysUser = userService.selectUserById(userId) + // 角色集合 + val roles: Set = permissionService.getRolePermission(sysUser) + // 权限集合 + val permissions: Set = permissionService.getMenuPermission(sysUser) + val sysUserVo = LoginUser() + sysUserVo.sysUser = sysUser + sysUserVo.roles = roles + sysUserVo.permissions = permissions + return R.ok(sysUserVo) + } + + /** + * 根据微信unionid获取用户信息 + */ + @InnerAuth + @GetMapping("/detail/wx/unionid/{unionid}") + fun infoByWxUnionId(@PathVariable("unionid") unionid: String): R { + val sysUser = kSysUserService.selectUserByWxUnionId(unionid) + if (StringUtils.isNull(sysUser)) { + return R.fail("unionid错误") + } + // 角色集合 + val roles: Set = permissionService.getRolePermission(sysUser) + // 权限集合 + val permissions: Set = permissionService.getMenuPermission(sysUser) + val sysUserVo = LoginUser() + sysUserVo.userid = sysUser?.userId + sysUserVo.ipaddr = IpUtils.getIpAddr() + sysUserVo.sysUser = sysUser + sysUserVo.roles = roles + sysUserVo.permissions = permissions + return R.ok(sysUserVo) + } + + /** + * 修改用户 + */ + @InnerAuth + @PutMapping + @Log(title = "用户修改本人信息", businessType = BusinessType.UPDATE) + fun edit(@Validated @RequestBody loginUser: LoginUser): AjaxResult { + val targetUser = loginUser.sysUser + if (!userService.checkUserNameUnique(targetUser)) { + return error("修改用户'" + targetUser.userName + "'失败,登录账号已存在") + } else if (StringUtils.isNotEmpty(targetUser.phonenumber) && !userService.checkPhoneUnique(targetUser)) { + return error("修改用户'" + targetUser.userName + "'失败,手机号码已存在") + } else if (StringUtils.isNotEmpty(targetUser.email) && !userService.checkEmailUnique(targetUser)) { + return error("修改用户'" + targetUser.userName + "'失败,邮箱账号已存在") + } + val originUser = userService.selectUserById(targetUser.userId) + originUser.userName = targetUser.userName ?: originUser.userName + originUser.nickName = targetUser.nickName ?: originUser.nickName + originUser.phonenumber = targetUser.phonenumber ?: originUser.phonenumber + originUser.email = targetUser.email ?: originUser.email + originUser.avatar = targetUser.avatar ?: originUser.avatar + originUser.sex = targetUser.sex ?: originUser.sex + originUser.updateBy = originUser.userName + if (loginUser.sysUser.sysUserAccount != null){ + originUser.sysUserAccount = loginUser.sysUser.sysUserAccount.apply { this.userId = originUser.userId } + } + userService.updateUser(originUser) + // 更新缓存用户信息 + tokenService.setLoginUser(loginUser) + return success(loginUser) + } + + /** + * 注册用户信息 + */ + @InnerAuth + @PostMapping("/register/dept/{deptId}/wx/unionid") + fun registerUserBySysUserAccount(@RequestBody sysUserAccount: KSysUserAccount, @PathVariable deptId: Long): R { + if ("true" != configService.selectConfigByKey("sys.account.registerUser")) { + return R.fail("当前系统没有开启注册功能!") + } + if (sysUserAccount.wxUnionId == null) return R.fail("微信unionid不存在无法注册") + if (!kSysUserService.checkWxUnionIdUnique(sysUserAccount.wxUnionId!!)) { + return R.fail("保存用户'$sysUserAccount.wxUnionId'失败,注册账号已存在") + } + return R.ok(kSysUserService.registerUserBySysUserAccount(sysUserAccount, deptId)) + } + @InnerAuth + @PutMapping("/{userId}/unbind/weixin") + @Log(title = "解绑微信", businessType = BusinessType.UPDATE) + fun unbindWeChat(@PathVariable("userId") userId: Long): AjaxResult { + val loginUser = SecurityUtils.getLoginUser() + kSysUserService.unBindWxByUserId(userId) + // 更新缓存用户信息 + tokenService.loginUser = loginUser + return success(loginUser) + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/mapper/KSysUserMapper.kt b/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/mapper/KSysUserMapper.kt new file mode 100644 index 000000000..2ddf46e67 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/mapper/KSysUserMapper.kt @@ -0,0 +1,42 @@ +package com.ruoyi.system.mapper + +import com.ruoyi.system.api.domain.KSysUserAccount +import com.ruoyi.system.api.domain.SysUser +import org.apache.ibatis.annotations.Param + +/** + * 用户表 数据层 + * + * @author hsdllcw + */ +interface KSysUserMapper { + /** + * 通过id查询用户 + * + * @param userId + * @return 用户对象信息 + */ + fun selectUserById(userId: Long): KSysUserAccount? + + /** + * 通过用户名查询用户 + * + * @param wxUnionId 微信unionid + * @return 用户对象信息 + */ + fun selectUserByWxUnionId(wxUnionId: String): SysUser? + + /** + * 校验微信unionid是否唯一 + * + * @param wxUnionId 微信unionid + * @return 结果 + */ + fun checkWxUnionIdUnique(wxUnionId: String): SysUser? + + fun insertSysUserAccount(sysUserAccount: KSysUserAccount): Int + + fun updateSysUserAccount(sysUserAccount: KSysUserAccount): Int + + fun unBindWxByUserId(@Param("userId") userId: Long): Int +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/service/IKSysUserService.kt b/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/service/IKSysUserService.kt new file mode 100644 index 000000000..968b58603 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/service/IKSysUserService.kt @@ -0,0 +1,48 @@ +package com.ruoyi.system.service + +import com.ruoyi.system.api.domain.KSysUserAccount +import com.ruoyi.system.api.domain.SysUser + +interface IKSysUserService { + fun getISysUserService(): ISysUserService + + /** + * 通过id查询用户 + * + * @param userId + * @return 用户对象信息 + */ + fun selectUserById(userId: Long): KSysUserAccount? + + /** + * 通过微信unionid查询用户 + * + * @param wxUnionId 微信unionid + * @return 用户对象信息 + */ + fun selectUserByWxUnionId(wxUnionId: String): SysUser? + + /** + * 校验微信unionid是否唯一 + * + * @param wxUnionId 微信unionid + * @return 用户对象信息 + */ + fun checkWxUnionIdUnique(wxUnionId: String): Boolean + + /** + * 注册用户信息 + * + * @param sysUserAccount 包含微信unionId + * @return 结果 + */ + fun registerUserBySysUserAccount(sysUserAccount: KSysUserAccount, deptId: Long): Boolean + /** + * 绑定微信 + */ + fun updateSysUserAccount(sysUserAccount: KSysUserAccount): Int + /** + * 解绑微信 + */ + fun unBindWxByUserId(userId: Long): Int +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/service/impl/KSysUserServiceImpl.kt b/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/service/impl/KSysUserServiceImpl.kt new file mode 100644 index 000000000..6e00e32b6 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/kotlin/com/ruoyi/system/service/impl/KSysUserServiceImpl.kt @@ -0,0 +1,56 @@ +package com.ruoyi.system.service.impl + +import com.ruoyi.common.core.constant.UserConstants +import com.ruoyi.common.core.utils.uuid.IdUtils +import com.ruoyi.common.security.utils.SecurityUtils +import com.ruoyi.system.api.domain.KSysUserAccount +import com.ruoyi.system.api.domain.SysUser +import com.ruoyi.system.mapper.KSysUserMapper +import com.ruoyi.system.service.IKSysUserService +import com.ruoyi.system.service.ISysUserService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.annotation.Lazy +import org.springframework.stereotype.Service + +@Service +open class KSysUserServiceImpl : IKSysUserService { + @Lazy + @Autowired + lateinit var sysUserService: ISysUserService + + @Autowired + lateinit var kSysUserMapper: KSysUserMapper + override fun getISysUserService() = sysUserService + override fun selectUserById(userId: Long) = kSysUserMapper.selectUserById(userId) + override fun selectUserByWxUnionId(wxUnionId: String) = kSysUserMapper.selectUserByWxUnionId(wxUnionId) + override fun checkWxUnionIdUnique(wxUnionId: String) = + kSysUserMapper.checkWxUnionIdUnique(wxUnionId)?.run { UserConstants.NOT_UNIQUE } ?: UserConstants.UNIQUE + + /** + * 注册用户信息 + * + * @param sysUserAccount 包含微信unionId + * @param deptId 部门ID + * @return 结果 + */ + override fun registerUserBySysUserAccount(sysUserAccount: KSysUserAccount, deptId: Long): Boolean { + val user = SysUser().apply { + userName = IdUtils.randomUUID().replace("-".toRegex(), "").substring(0, 30) + nickName = "嘉迪微信用户" + password = SecurityUtils.encryptPassword(IdUtils.randomUUID()) + this.deptId = deptId + } + return sysUserService.registerUser(user).apply { + sysUserAccount.memberId = sysUserService.selectUserByUserName(user.userName).userId + kSysUserMapper.insertSysUserAccount(sysUserAccount) + } + } + + override fun updateSysUserAccount(sysUserAccount: KSysUserAccount): Int { + return kSysUserMapper.updateSysUserAccount(sysUserAccount) + } + + override fun unBindWxByUserId(userId: Long): Int { + return kSysUserMapper.unBindWxByUserId(userId) + } +} \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap-dev.yml b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap-dev.yml new file mode 100644 index 000000000..79784ca31 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap-dev.yml @@ -0,0 +1,33 @@ +# Tomcat +server: + port: 9201 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-system + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA +logging: + file: + name: dev-ruoyi-system.log + pattern: + file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx" \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap-prod.yml b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap-prod.yml new file mode 100644 index 000000000..ac0785514 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,33 @@ +# Tomcat +server: + port: 9201 +#测试环境 +spring: + application: + # 应用名称 + name: ruoyi-system + cloud: + nacos: + discovery: + ip: 8.155.60.167 + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA +logging: + file: + name: prod-ruoyi-system.log + pattern: + file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx" \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap-test.yml b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap-test.yml new file mode 100644 index 000000000..fe61111d3 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap-test.yml @@ -0,0 +1,32 @@ +# Tomcat +server: + port: 9201 +#测试环境 +spring: + application: + # 应用名称 + name: ruoyi-system + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA +logging: + file: + name: test-ruoyi-system.log + pattern: + file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx" \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml index 40ab78165..03234a17e 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml @@ -1,25 +1,4 @@ -# Tomcat -server: - port: 9201 - -# Spring -spring: - application: - # 应用名称 - name: ruoyi-system - profiles: - # 环境配置 - active: dev - cloud: - nacos: - discovery: - # 服务注册地址 - server-addr: 127.0.0.1:8848 - config: - # 配置中心地址 - server-addr: 127.0.0.1:8848 - # 配置文件格式 - file-extension: yml - # 共享配置 - shared-configs: - - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# Spring默认环境配置 +spring: + profiles: + active: dev \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/KSysUserMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/KSysUserMapper.xml new file mode 100644 index 000000000..fb8493266 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/KSysUserMapper.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select u.user_id, + u.dept_id, + u.user_name, + u.nick_name, + u.email, + u.avatar, + u.phonenumber, + u.password, + u.sex, + u.status, + u.del_flag, + u.login_ip, + u.login_date, + u.create_by, + u.create_time, + u.remark, + d.dept_id, + d.parent_id, + d.ancestors, + d.dept_name, + d.order_num, + d.leader, + d.status as dept_status, + r.role_id, + r.role_name, + r.role_key, + r.role_sort, + r.data_scope, + r.status as role_status, + umw.unionid + from sys_user u + left join ums_member_wechat umw on umw.member_id = u.user_id + left join sys_dept d on u.dept_id = d.dept_id + left join sys_user_role ur on u.user_id = ur.user_id + left join sys_role r on r.role_id = ur.role_id + + + + + + + + + + insert into ums_member_wechat(member_id, unionid, openid, routine_openid, groupid, tagid_list, subscribe, + subscribe_time, session_key, access_token, expires_in, refresh_token, expire_time) + values (#{userId}, #{wxUnionId}, #{openid}, #{routineOpenid}, #{groupid}, #{tagidList}, #{subscribe}, + #{subscribeTime}, #{sessionKey}, #{accessToken}, #{expiresIn}, #{refreshToken}, #{expireTime}) + + + update ums_member_wechat + + unionid = #{unionid}, + openid = #{openid}, + routine_openid = #{routineOpenid}, + groupid = #{groupid}, + tagid_list = #{tagidList}, + subscribe = #{subscribe}, + subscribe_time = #{subscribeTime}, + session_key = #{sessionKey}, + access_token = #{accessToken}, + expires_in = #{expiresIn}, + refresh_token = #{refreshToken}, + expire_time = #{expireTime}, + update_time = sysdate() + + where member_id = #{userId} + + + update ums_member_wechat + set unionid = null, + openid = null, + routine_openid = null + where member_id = #{userId} + + \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml index b4fef50d7..e3f22b4ca 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysConfigMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + @@ -33,12 +33,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - - @@ -69,7 +69,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where config_key = #{configKey} limit 1 - + insert into sys_config ( config_name, config_key, @@ -89,7 +89,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ) - + update sys_config config_name = #{configName}, diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml index 000166edb..ec9efa390 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + @@ -27,7 +27,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from sys_dept d - where d.del_flag = '0' @@ -85,7 +85,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where dept_name=#{deptName} and parent_id = #{parentId} and del_flag = '0' limit 1 - + insert into sys_dept( dept_id, parent_id, @@ -113,7 +113,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ) - + update sys_dept parent_id = #{parentId}, diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml index c5e1da9d0..48f04db27 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + @@ -25,7 +25,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from sys_dict_data - @@ -71,7 +71,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + update sys_dict_data dict_sort = #{dictSort}, @@ -93,7 +93,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update sys_dict_data set dict_type = #{newDictType} where dict_type = #{oldDictType} - + insert into sys_dict_data( dict_sort, dict_label, diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml index 554db5441..67ed9691f 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysDictTypeMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + @@ -20,7 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from sys_dict_type - @@ -71,7 +71,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + update sys_dict_type dict_name = #{dictName}, @@ -84,7 +84,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where dict_id = #{dictId} - + insert into sys_dict_type( dict_name, dict_type, diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml index 67a4b1c65..f40036f07 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysLogininforMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + @@ -13,12 +13,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + insert into sys_logininfor (user_name, status, ipaddr, msg, access_time) values (#{userName}, #{status}, #{ipaddr}, #{msg}, sysdate()) - select info_id, user_name, ipaddr, status, msg, access_time from sys_logininfor diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml index e6be3aefd..8f025a133 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -4,7 +4,7 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + @@ -33,7 +33,7 @@ from sys_menu - @@ -55,7 +55,7 @@ order by m.parent_id, m.order_num - select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.`query`, m.route_name, m.visible, m.status, ifnull(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time from sys_menu m left join sys_role_menu rm on m.menu_id = rm.menu_id @@ -128,12 +128,12 @@ select count(1) from sys_menu where parent_id = #{menuId} - where menu_name=#{menuName} and parent_id = #{parentId} limit 1 - + update sys_menu menu_name = #{menuName}, @@ -157,7 +157,7 @@ where menu_id = #{menuId} - + insert into sys_menu( menu_id, parent_id, diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml index 6915a1482..37638fb06 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + @@ -27,7 +27,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where notice_id = #{noticeId} - @@ -41,8 +41,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - - + + + insert into sys_notice ( notice_title, notice_type, @@ -62,7 +68,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ) - + update sys_notice notice_title = #{noticeTitle}, diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml index 8d69f736a..803663e38 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysOperLogMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + @@ -28,12 +28,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from sys_oper_log - + insert into sys_oper_log(title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_param, json_result, status, error_msg, cost_time, oper_time) values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}, #{operUrl}, #{operIp}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, #{costTime}, sysdate()) - diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml index faefb2f07..bcdd06330 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysPostMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + @@ -22,7 +22,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from sys_post - @@ -72,7 +72,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where post_code=#{postCode} limit 1 - + update sys_post post_code = #{postCode}, @@ -86,7 +86,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where post_id = #{postId} - + insert into sys_post( post_id, post_code, diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml index 700671e15..c2815f24e 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml index a3b780ff0..3b96e9676 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + @@ -30,7 +30,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" left join sys_dept d on u.dept_id = d.dept_id - where r.del_flag = '0' @@ -93,7 +93,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where r.role_key=#{roleKey} and r.del_flag = '0' limit 1 - + insert into sys_role( role_id, role_name, @@ -121,7 +121,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ) - + update sys_role role_name = #{roleName}, diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml index e75bb1744..4cc2bef86 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index 49de1cab1..eb0c9c266 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -1,227 +1,238 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.pwd_update_date, u.create_by, u.create_time, u.remark, - d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status, - r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status - from sys_user u - left join sys_dept d on u.dept_id = d.dept_id - left join sys_user_role ur on u.user_id = ur.user_id - left join sys_role r on r.role_id = ur.role_id - - - - - - - - - - - - - - - - - - - - insert into sys_user( - user_id, - dept_id, - user_name, - nick_name, - email, - avatar, - phonenumber, - sex, - password, - status, - pwd_update_date, - create_by, - remark, - create_time - )values( - #{userId}, - #{deptId}, - #{userName}, - #{nickName}, - #{email}, - #{avatar}, - #{phonenumber}, - #{sex}, - #{password}, - #{status}, - #{pwdUpdateDate}, - #{createBy}, - #{remark}, - sysdate() - ) - - - - update sys_user - - dept_id = #{deptId}, - nick_name = #{nickName}, - email = #{email}, - phonenumber = #{phonenumber}, - sex = #{sex}, - avatar = #{avatar}, - password = #{password}, - status = #{status}, - login_ip = #{loginIp}, - login_date = #{loginDate}, - update_by = #{updateBy}, - remark = #{remark}, - update_time = sysdate() - - where user_id = #{userId} - - - - update sys_user set status = #{status}, update_time = sysdate() where user_id = #{userId} - - - - update sys_user set avatar = #{avatar}, update_time = sysdate() where user_id = #{userId} - - - - update sys_user set login_ip = #{loginIp}, login_date = #{loginDate} where user_id = #{userId} - - - - update sys_user set pwd_update_date = sysdate(), password = #{password}, update_time = sysdate() where user_id = #{userId} - - - - update sys_user set del_flag = '2' where user_id = #{userId} - - - - update sys_user set del_flag = '2' where user_id in - - #{userId} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.pwd_update_date, u.create_by, u.create_time, u.remark, + d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status, + r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status, + umw.unionid + from sys_user u + left join ums_member_wechat umw on umw.member_id = u.user_id + left join sys_dept d on u.dept_id = d.dept_id + left join sys_user_role ur on u.user_id = ur.user_id + left join sys_role r on r.role_id = ur.role_id + + + + + + + + + + + + + + + + + + + + + + + insert into sys_user( + user_id, + dept_id, + user_name, + nick_name, + email, + avatar, + phonenumber, + sex, + password, + status, + create_by, + remark, + create_time + )values( + #{userId}, + #{deptId}, + #{userName}, + #{nickName}, + #{email}, + #{avatar}, + #{phonenumber}, + #{sex}, + #{password}, + #{status}, + #{createBy}, + #{remark}, + sysdate() + ) + + + + update sys_user + + dept_id = #{deptId}, + nick_name = #{nickName}, + email = #{email}, + phonenumber = #{phonenumber}, + sex = #{sex}, + avatar = #{avatar}, + password = #{password}, + status = #{status}, + login_ip = #{loginIp}, + login_date = #{loginDate}, + update_by = #{updateBy}, + remark = #{remark}, + update_time = sysdate() + + where user_id = #{userId} + + + + update sys_user set status = #{status} where user_id = #{userId} + + + + update sys_user set avatar = #{avatar} where user_name = #{userName} + + + + update sys_user set pwd_update_date = sysdate(), password = #{password} where user_name = #{userName} + + + + update sys_user set del_flag = '2' where user_id = #{userId} + + + + update sys_user set del_flag = '2' where user_id in + + #{userId} + + + \ No newline at end of file diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml index 21c40981b..0ff0cb91f 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserPostMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml index 95e07adb1..b210005d2 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserRoleMapper.xml @@ -4,7 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + @@ -31,7 +31,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + delete from sys_user_role where user_id=#{userId} and role_id=#{roleId} diff --git a/ruoyi-modules/ruoyi-system/src/test/kotlin/com/ruoyi/system/service/ISysUserServiceTest.kt b/ruoyi-modules/ruoyi-system/src/test/kotlin/com/ruoyi/system/service/ISysUserServiceTest.kt new file mode 100644 index 000000000..4b96f5e0e --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/test/kotlin/com/ruoyi/system/service/ISysUserServiceTest.kt @@ -0,0 +1,74 @@ +package com.ruoyi.system.service + +import com.alibaba.fastjson.JSONObject +import com.ruoyi.common.core.utils.StringUtils +import com.ruoyi.common.core.utils.uuid.IdUtils +import com.ruoyi.common.security.utils.SecurityUtils +import com.ruoyi.system.RuoYiSystemApplication +import com.ruoyi.system.api.domain.SysUser +import org.junit.runner.RunWith +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner +import java.io.File +import kotlin.test.Test + +@RunWith(SpringJUnit4ClassRunner::class) +@SpringBootTest(classes = [RuoYiSystemApplication::class], webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class ISysUserServiceTest { + @Autowired + lateinit var iSysUserService: ISysUserService + + @Test + fun findByPhoneNumberStartingWithTest() { + println(JSONObject.toJSONString(iSysUserService.findByPhoneNumberStartingWith("1"))) + } + + @Test + fun batchSetVIP() { + File("/home/hsdllcw/Desktop/嘉迪课堂会员登记表.csv").readLines().map { + it.split(",").let { item -> + mapOf( + "phone" to item[3], + "name" to item[1], + "date" to item[4] + ) + } + }.filter { Regex("\\d+").matches(it["phone"]!!) }.forEach { + print(it) + if (iSysUserService.findByPhoneNumberStartingWith(it["phone"]).firstOrNull()?.also { user -> + setVIP(user, it) + } == null) { + registerByPhoneNumber(it) + println("==========${it["name"]}已注册为VIP==============") + } + } + } + private fun setVIP(user:SysUser, it: Map) { + if (user.roles?.any { role -> role.roleKey == "live-vip" } == true) { + println(":vip") + if (StringUtils.isEmpty(user.remark)) { + user.remark = "${it["name"]}-会员开通时间(${it["date"]})" + iSysUserService.updateUser(user) + } + } else { + println(":普通用户") + user.roleIds = arrayOf(2, 101) + iSysUserService.updateUser(user) + println("\n==========${it["name"]}已设置为VIP==============") + } + } + + private fun registerByPhoneNumber(it: Map) { + val sysUser = SysUser() + sysUser.userName = IdUtils.randomUUID().replace("-".toRegex(), "").substring(0, 30) + sysUser.nickName = "嘉迪" + it["phone"]?.substring((it["phone"]?.length?:0) - 4) + sysUser.phonenumber = it["phone"] + sysUser.password = SecurityUtils.encryptPassword(IdUtils.randomUUID()) + sysUser.deptId = 204 + sysUser.roleIds = arrayOf(2, 101) + sysUser.remark = "${it["name"]}-会员开通时间(${it["date"]})" + iSysUserService.registerUser(sysUser) + setVIP(sysUser, it) + } +} \ No newline at end of file diff --git a/ruoyi-ui/.gitignore b/ruoyi-ui/.gitignore index 2c9b3a73f..aed792184 100644 --- a/ruoyi-ui/.gitignore +++ b/ruoyi-ui/.gitignore @@ -1,23 +1,24 @@ -.DS_Store -node_modules/ -dist/ -npm-debug.log* -yarn-debug.log* -yarn-error.log* -**/*.log - -tests/**/coverage/ -tests/e2e/reports -selenium-debug.log - -# Editor directories and files -.idea -.vscode -*.suo -*.ntvs* -*.njsproj -*.sln -*.local - -package-lock.json -yarn.lock +.DS_Store +node_modules/ +dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +**/*.log + +tests/**/coverage/ +tests/e2e/reports +selenium-debug.log + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.local + +package-lock.json +yarn.lock +pnpm-lock.yaml diff --git a/ruoyi-ui/src/views/index.vue b/ruoyi-ui/src/views/index.vue index f06fb7bd8..03ad82965 100644 --- a/ruoyi-ui/src/views/index.vue +++ b/ruoyi-ui/src/views/index.vue @@ -81,10 +81,10 @@ >

- QQ群: 满42799195 满170157040 + QQ群: 满42799195 满170157040 满130643120 满225920371 满201705537 满236543183 满213618602 满148794840 满118752664 满101038945 - 满128355254 满179219821 满158753145 112869560 + 满128355254 满179219821 158753145

微信:更新日志 - -

    -
  1. 支持防盗链功能
  2. -
  3. 菜单导航设置支持纯顶部
  4. -
  5. 用户头像更换后移除旧头像文件
  6. -
  7. 支持Excel导出对象的多个子列表
  8. -
  9. 升级druid到最新版本1.2.27
  10. -
  11. 升级fastjson到最新版2.0.60
  12. -
  13. 升级tomcat到最新版本9.0.112
  14. -
  15. 升级commons.io到最新版本2.21.0
  16. -
  17. 用户导入添加验证提示
  18. -
  19. 显示列信息支持对象格式
  20. -
  21. 网页标题设置新增SET_TITLE方法
  22. -
  23. 自动识别json对象白名单配置范围缩小
  24. -
  25. 登录/注册页面底部版权信息修改为读取配置
  26. -
  27. 修复用户归属部门无法修改为空问题
  28. -
  29. 修复固定头部时出现的导航栏偏移问题
  30. -
  31. 修复v3时间控件between选择后清空报错问题
  32. -
  33. 修复comboReadDict属性下多个sheet出现的报错
  34. -
  35. 修复表单构建移除所有控件后切换路由回来空白问题
  36. -
  37. 优化布局设置显示
  38. -
  39. 优化字典组件值宽松匹配
  40. -
  41. 优化生成代码下载的zip文件名
  42. -
  43. 优化日志记录参数拼装提升效率
  44. -
  45. 优化导入文件检查标题行不能为空
  46. -
  47. 优化表单构建关闭页签销毁复制插件
  48. -
  49. 优化Excel统计行数值的单元格样式显示
  50. -
  51. 优化数据权限控制逻辑,放开permission限制
  52. -
  53. 其他细节优化
  54. -
- - -
    -
  1. 优化菜单搜索查询页
  2. -
  3. 导航栏显示昵称&设置
  4. -
  5. 用户管理支持分栏拖动
  6. -
  7. 修改主题样式本地读取
  8. -
  9. 菜单管理新增路由名称
  10. -
  11. 添加底部版权信息&开关
  12. -
  13. 分配角色禁用不允许勾选
  14. -
  15. 添加页签图标显示开关功能
  16. -
  17. 用户管理过滤掉已禁用部门
  18. -
  19. 上传组件新增拖动排序属性
  20. -
  21. 显隐列组件支持全选/全不选
  22. -
  23. 白名单支持对通配符路径匹配
  24. -
  25. 初始密码支持自定义修改策略
  26. -
  27. 账号密码支持自定义更新周期
  28. -
  29. 菜单面包屑导航支持多层级显示
  30. -
  31. 支持富文本复制粘贴图片上传至url
  32. -
  33. 支持文件&图片组件自定义地址&参数
  34. -
  35. 更新ry-config的nacos表结构到最新版本
  36. -
  37. 代码生成新增配置是否允许文件覆盖到本地
  38. -
  39. 使用CacheRequestBody代替CacheRequestFilter
  40. -
  41. 升级tomcat到最新版本9.0.105
  42. -
  43. 升级fastjson到最新版2.0.57
  44. -
  45. 升级commons.io到最新版本2.19.0
  46. -
  47. package.json移除runjs&eslint&vue-meta依赖
  48. -
  49. 修复导出子列表对象只能在最后的问题
  50. -
  51. 修复TopNav无法正确获取active的问题
  52. -
  53. 修复默认关闭Tags-Views内链页面打不开
  54. -
  55. Excel注解支持wrapText是否允许内容换行
  56. -
  57. 优化文件上传组件新增类型
  58. -
  59. 优化导入带标题文件关闭清理
  60. -
  61. 优化参数键值更换为多行文本
  62. -
  63. 优化特殊字符密码修改失败问题
  64. -
  65. 优化代码生成列表支持按时间排序
  66. -
  67. 优化TopNav内链菜单点击没有高亮
  68. -
  69. 优化文件异常输入流未关闭的问题
  70. -
  71. 优化菜单管理切换Mini布局错乱问题
  72. -
  73. 优化空指针异常时无法获取错误信息问题
  74. -
  75. 优化文件&图片上传组件新增disabled属性
  76. -
  77. 优化isAdmin方法,避免脱敏模块security依赖
  78. -
  79. 优化定时任务字符包含多个括号导致数据错误
  80. -
  81. 优化登录&注册页表头使用VUE_APP_TITLE配置值
  82. -
  83. 优化导出Excel日期格式双击离开后与设定的格式不一致问题
  84. -
  85. 其他细节优化
  86. -
-
- +
  1. 使用SpringDoc代替Swagger
  2. 菜单管理新增路由名称
  3. @@ -987,8 +909,8 @@ export default { data() { return { // 版本号 - version: "3.6.7" - } + version: "3.6.5.0.9", + }; }, methods: { goTarget(href) { diff --git a/ruoyi-ui/vue.config.js b/ruoyi-ui/vue.config.js index afb5e8e07..c2499ffd8 100644 --- a/ruoyi-ui/vue.config.js +++ b/ruoyi-ui/vue.config.js @@ -34,7 +34,7 @@ module.exports = { proxy: { // detail: https://cli.vuejs.org/config/#devserver-proxy [process.env.VUE_APP_BASE_API]: { - target: `http://localhost:8080`, + target: `https://api.zkjiadi.cc`, changeOrigin: true, pathRewrite: { ['^' + process.env.VUE_APP_BASE_API]: '' diff --git a/ruoyi-visual/pom.xml b/ruoyi-visual/pom.xml index f5b19c8b9..4fef5d2d5 100644 --- a/ruoyi-visual/pom.xml +++ b/ruoyi-visual/pom.xml @@ -1,22 +1,22 @@ - - - - com.ruoyi - ruoyi - 3.6.7 - - 4.0.0 - - - ruoyi-monitor - - - ruoyi-visual - pom - - - ruoyi-visual图形化管理模块 - - - + + + + com.ruoyi + ruoyi + 3.6.5.0.9 + + 4.0.0 + + + ruoyi-monitor + + + ruoyi-visual + pom + + + ruoyi-visual图形化管理模块 + + + diff --git a/ruoyi-visual/ruoyi-monitor/pom.xml b/ruoyi-visual/ruoyi-monitor/pom.xml index fe40b8a8c..43c15b65d 100644 --- a/ruoyi-visual/ruoyi-monitor/pom.xml +++ b/ruoyi-visual/ruoyi-monitor/pom.xml @@ -1,75 +1,75 @@ - - - com.ruoyi - ruoyi-visual - 3.6.7 - - 4.0.0 - - ruoyi-visual-monitor - - - ruoyi-visual-monitor监控中心 - - - - - - - de.codecentric - spring-boot-admin-starter-server - ${spring-boot-admin.version} - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-discovery - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-nacos-config - - - - - com.alibaba.cloud - spring-cloud-starter-alibaba-sentinel - - - - - org.springframework.boot - spring-boot-starter-web - - - - - org.springframework.boot - spring-boot-starter-security - - - - - - ${project.artifactId} - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - - + + + com.ruoyi + ruoyi-visual + 3.6.5.0.9 + + 4.0.0 + + ruoyi-visual-monitor + + + ruoyi-visual-monitor监控中心 + + + + + + + de.codecentric + spring-boot-admin-starter-server + ${spring-boot-admin.version} + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-sentinel + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-security + + + + + + ${project.artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + \ No newline at end of file diff --git a/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap-dev.yml b/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap-dev.yml new file mode 100644 index 000000000..d3d850f79 --- /dev/null +++ b/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap-dev.yml @@ -0,0 +1,28 @@ +# Tomcat +server: + port: 9100 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-monitor + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 78a7f41e-46cc-437a-9716-735888227693 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA \ No newline at end of file diff --git a/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap-prod.yml b/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap-prod.yml new file mode 100644 index 000000000..106133ab2 --- /dev/null +++ b/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap-prod.yml @@ -0,0 +1,29 @@ +# Tomcat +server: + port: 9100 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-monitor + cloud: + nacos: + discovery: + ip: 8.155.60.167 + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: e2708b29-ca15-4f63-a919-d33932ebdfda + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA \ No newline at end of file diff --git a/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap-test.yml b/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap-test.yml new file mode 100644 index 000000000..629da202d --- /dev/null +++ b/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap-test.yml @@ -0,0 +1,28 @@ +# Tomcat +server: + port: 9100 + +# Spring +spring: + application: + # 应用名称 + name: ruoyi-monitor + cloud: + nacos: + discovery: + # 服务注册地址 + server-addr: nacos.zkjiadi.cc + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA + config: + # 配置中心地址 + server-addr: nacos.zkjiadi.cc + # 配置文件格式 + file-extension: yml + # 共享配置 + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + namespace: 45c724b0-9b42-4ff2-bff2-9220a1788392 + username: nacos + password: u0uM2RIp3Xle9VVFWtpzoz9ZdNbwG6PpWsjrOVphXzlDc0jA \ No newline at end of file diff --git a/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap.yml b/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap.yml index 13d90cd72..03234a17e 100644 --- a/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap.yml +++ b/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap.yml @@ -1,25 +1,4 @@ -# Tomcat -server: - port: 9100 - -# Spring -spring: - application: - # 应用名称 - name: ruoyi-monitor - profiles: - # 环境配置 - active: dev - cloud: - nacos: - discovery: - # 服务注册地址 - server-addr: 127.0.0.1:8848 - config: - # 配置中心地址 - server-addr: 127.0.0.1:8848 - # 配置文件格式 - file-extension: yml - # 共享配置 - shared-configs: - - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} +# Spring默认环境配置 +spring: + profiles: + active: dev \ No newline at end of file